Merge "mmc: add packed command feature of eMMC4.5"
diff --git a/AndroidKernel.mk b/AndroidKernel.mk
index 843da69..3684a3f 100644
--- a/AndroidKernel.mk
+++ b/AndroidKernel.mk
@@ -11,7 +11,7 @@
KERNEL_MODULES_OUT := $(TARGET_OUT)/lib/modules
KERNEL_IMG=$(KERNEL_OUT)/arch/arm/boot/Image
-DTS_NAMES ?= $(shell $(PERL) -e 'while (<>) {$$a = $$1 if /CONFIG_ARCH_((?:MSM|QSD)[a-zA-Z0-9]+)=y/; $$r = $$1 if /CONFIG_MSM_SOC_REV_(?!NONE)(\w+)=y/; $$arch = $$arch.lc("$$a$$r ") if /CONFIG_ARCH_((?:MSM|QSD)[a-zA-Z0-9]+)=y/} print $$arch;' $(KERNEL_CONFIG))
+DTS_NAMES ?= $(shell $(PERL) -e 'while (<>) {$$a = $$1 if /CONFIG_ARCH_((?:MSM|QSD|MPQ)[a-zA-Z0-9]+)=y/; $$r = $$1 if /CONFIG_MSM_SOC_REV_(?!NONE)(\w+)=y/; $$arch = $$arch.lc("$$a$$r ") if /CONFIG_ARCH_((?:MSM|QSD|MPQ)[a-zA-Z0-9]+)=y/} print $$arch;' $(KERNEL_CONFIG))
KERNEL_USE_OF ?= $(shell $(PERL) -e '$$of = "n"; while (<>) { if (/CONFIG_USE_OF=y/) { $$of = "y"; break; } } print $$of;' kernel/arch/arm/configs/$(KERNEL_DEFCONFIG))
ifeq "$(KERNEL_USE_OF)" "y"
diff --git a/Documentation/devicetree/bindings/coresight/coresight.txt b/Documentation/devicetree/bindings/coresight/coresight.txt
index c584073..f860618 100644
--- a/Documentation/devicetree/bindings/coresight/coresight.txt
+++ b/Documentation/devicetree/bindings/coresight/coresight.txt
@@ -31,6 +31,7 @@
component
- coresight-child-ports : list of input port numbers of the children
- coresight-default-sink : represents the default compile time CoreSight sink
+- qcom,pc-save : program counter save implemented
Examples:
@@ -103,4 +104,5 @@
coresight-outports = <0>;
coresight-child-list = <&funnel_kpss>;
coresight-child-ports = <0>;
+ qcom,pc-save;
};
diff --git a/Documentation/devicetree/bindings/input/touchscreen/atmel-mxt-ts.txt b/Documentation/devicetree/bindings/input/touchscreen/atmel-mxt-ts.txt
index a6c83d0..88fca69 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/atmel-mxt-ts.txt
+++ b/Documentation/devicetree/bindings/input/touchscreen/atmel-mxt-ts.txt
@@ -27,6 +27,8 @@
- vcc_i2c-supply : Power source required to pull up i2c bus
- atmel,dig-reg-support : specify to indicate digital regulator is
needed
+ - atmel,need-calibration : specify to indicate whether calibration is
+ needed during wakeup.
Example:
i2c@f9966000 {
diff --git a/Documentation/devicetree/bindings/pil/pil-mba.txt b/Documentation/devicetree/bindings/pil/pil-mba.txt
index 7aafd219..9692059 100644
--- a/Documentation/devicetree/bindings/pil/pil-mba.txt
+++ b/Documentation/devicetree/bindings/pil/pil-mba.txt
@@ -10,6 +10,8 @@
first corresponds to the Relay Message Buffer (RMB)
register base. The second specifies the address at which
the primary modem image metadata should be stored.
+- reg-names: Names for the above base addresses. "rmb_base" and
+ "metadata_base" are expected.
- qcom,firmware-name: Base name of the firmware image. Ex. "modem"
Optional properties:
@@ -21,6 +23,7 @@
compatible = "qcom,pil-mba";
reg = <0xfc820000 0x0020>,
<0x0d1f0000 0x4000>;
+ reg-names = "rmb_base", "metadata_base";
qcom,firmware-name = "modem";
qcom,depends-on = "mba";
diff --git a/Documentation/devicetree/bindings/pil/pil-pronto.txt b/Documentation/devicetree/bindings/pil/pil-pronto.txt
index 6193b68..e123bdb 100644
--- a/Documentation/devicetree/bindings/pil/pil-pronto.txt
+++ b/Documentation/devicetree/bindings/pil/pil-pronto.txt
@@ -7,9 +7,9 @@
Required properties:
- compatible: "pil-pronto"
-- reg: offset and length of the register set for the device. The first pair
- corresponds to PRONTO_PMU, the second pair corresponds to CLK_CTL_WCNSS
- the third pair corresponds to WCNSS_HALTREQ.
+- reg: offset and length of the register set for the device.
+- reg-names: names of the bases for the above registers. "pmu_base", "clk_base",
+ and "halt_base" are expected.
- vdd_pronto_pll-supply: regulator to supply pronto pll.
- qcom,firmware-name: Base name of the firmware image. Ex. "wcnss"
@@ -19,6 +19,7 @@
reg = <0xfb21b000 0x3000>,
<0xfc401700 0x4>,
<0xfd485300 0xc>;
+ reg-names = "pmu_base", "clk_base", "halt_base";
vdd_pronto_pll-supply = <&pm8941_l12>;
qcom,firmware-name = "wcnss";
diff --git a/Documentation/devicetree/bindings/pil/pil-q6v5-lpass.txt b/Documentation/devicetree/bindings/pil/pil-q6v5-lpass.txt
index 308f992..d39c98c 100644
--- a/Documentation/devicetree/bindings/pil/pil-q6v5-lpass.txt
+++ b/Documentation/devicetree/bindings/pil/pil-q6v5-lpass.txt
@@ -7,9 +7,10 @@
Required properties:
- compatible: Must be "qcom,pil-q6v5-lpass"
-- reg: Two pairs of physical base addresses and region sizes
- of memory mapped registers. The first region corresponds
- to QDSP6SS_PUB, and the second to LPASS_HALTREQ.
+- reg: Pairs of physical base addresses and region sizes of
+ memory mapped registers.
+- reg-names: Names of the bases for the above registers. "qdsp6_base"
+ and "halt_base" are expected.
- qcom,firmware-name: Base name of the firmware image. Ex. "lpass"
Example:
@@ -17,6 +18,7 @@
compatible = "qcom,pil-q6v5-lpass";
reg = <0xfe200000 0x00100>,
<0xfd485100 0x00010>;
+ reg-names = "qdsp6_base", "halt_base";
qcom,firmware-name = "lpass";
};
diff --git a/Documentation/devicetree/bindings/pil/pil-q6v5-mss.txt b/Documentation/devicetree/bindings/pil/pil-q6v5-mss.txt
index 32c9c35..41ffd8a 100644
--- a/Documentation/devicetree/bindings/pil/pil-q6v5-mss.txt
+++ b/Documentation/devicetree/bindings/pil/pil-q6v5-mss.txt
@@ -7,12 +7,11 @@
Required properties:
- compatible: Must be "qcom,pil-q6v5-mss"
-- reg: Five pairs of physical base addresses and region sizes of
- memory mapped registers. The first region corresponds to
- QDSP6SS_PUB, the second to the bus port halt register
- base, the third to the MSS_RELAY_MSG_BUFFER base, the
- fourth to the MSS_RESTART register, and the fifth to the
- MSS_CLAMP_IO register.
+- reg: Pairs of physical base addresses and region sizes of
+ memory mapped registers.
+- reg-names: Names of the bases for the above registers. "qdsp6_base",
+ "halt_base", "rmb_base", "restart_reg" and "clamp_reg"
+ are expected.
- vdd_mss-supply: Reference to the regulator that supplies the processor.
- qcom,firmware-name: Base name of the firmware image. Ex. "mdsp"
- qcom,pil-self-auth: <0> if the hardware does not require self-authenticating
@@ -27,6 +26,8 @@
<0xfc820000 0x020>,
<0xfc401680 0x004>,
<0xfc980008 0x004>;
+ reg-names = "qdsp6_base", "halt_base", "rmb_base",
+ "restart_reg", "clamp_reg";
vdd_mss-supply = <&pm8841_s3>;
qcom,firmware-name = "mba";
diff --git a/Documentation/devicetree/bindings/pil/pil-venus.txt b/Documentation/devicetree/bindings/pil/pil-venus.txt
index 93cba32..4b87f17 100644
--- a/Documentation/devicetree/bindings/pil/pil-venus.txt
+++ b/Documentation/devicetree/bindings/pil/pil-venus.txt
@@ -7,8 +7,9 @@
Required properties:
- compatible: "pil-venus"
-- reg: offset and length of the register set for the device. The first pair
- corresponds to VENUS_WRAPPER, the second pair corresponds to VENUS_VBIF.
+- reg: offset and length of the register set for the device.
+- reg-names: names of the bases for the above registers. "wrapper_base" and
+ "vbif_base" are expected.
- vdd-supply: regulator to supply venus.
- qcom,firmware-name: Base name of the firmware image. Ex. "venus"
- qcom,firmware-min-paddr: The lowest addr boundary for firmware image in DDR
@@ -19,6 +20,7 @@
compatible = "qcom,pil-venus";
reg = <0xfdce0000 0x4000>,
<0xfdc80208 0x8>;
+ reg-names = "wrapper_base", "vbif_base";
vdd-supply = <&gdsc_venus>;
qcom,firmware-name = "venus";
diff --git a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
index 0eb186e..2864fd1 100644
--- a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
+++ b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
@@ -48,6 +48,12 @@
- compatible : "qcom,msm-dai-fe"
+* msm-pcm-afe
+
+Required properties:
+
+ - compatible : "qcom,msm-pcm-afe"
+
* msm-dai-q6
[First Level Nodes]
@@ -63,6 +69,8 @@
- compatible : "qcom,msm-dai-q6-dev"
- qcom,msm-dai-q6-dev-id : The slimbus multi channel port ID
Value is from 16384 to 16393
+ BT SCO port ID value from 12288 to 12289
+ RT Proxy port ID values from 224 to 225 and 240 to 241
* msm-auxpcm
@@ -166,6 +174,36 @@
compatible = "qcom,msm-dai-q6-dev";
qcom,msm-dai-q6-dev-id = <16385>;
};
+
+ qcom,msm-dai-q6-bt-sco-rx {
+ compatible = "qcom,msm-dai-q6-dev";
+ qcom,msm-dai-q6-dev-id = <12288>;
+ };
+
+ qcom,msm-dai-q6-bt-sco-tx {
+ compatible = "qcom,msm-dai-q6-dev";
+ qcom,msm-dai-q6-dev-id = <12289>;
+ };
+
+ qcom,msm-dai-q6-be-afe-pcm-rx {
+ compatible = "qcom,msm-dai-q6-dev";
+ qcom,msm-dai-q6-dev-id = <224>;
+ };
+
+ qcom,msm-dai-q6-be-afe-pcm-tx {
+ compatible = "qcom,msm-dai-q6-dev";
+ qcom,msm-dai-q6-dev-id = <225>;
+ };
+
+ qcom,msm-dai-q6-afe-proxy-rx {
+ compatible = "qcom,msm-dai-q6-dev";
+ qcom,msm-dai-q6-dev-id = <241>;
+ };
+
+ qcom,msm-dai-q6-afe-proxy-tx {
+ compatible = "qcom,msm-dai-q6-dev";
+ qcom,msm-dai-q6-dev-id = <240>;
+ };
};
qcom,msm-auxpcm {
diff --git a/Documentation/devicetree/bindings/spmi/spmi-pmic-arb.txt b/Documentation/devicetree/bindings/spmi/spmi-pmic-arb.txt
index b5ca08e..63c1e87 100644
--- a/Documentation/devicetree/bindings/spmi/spmi-pmic-arb.txt
+++ b/Documentation/devicetree/bindings/spmi/spmi-pmic-arb.txt
@@ -10,6 +10,10 @@
- qcom,pmic-arb-channel : the assigned channel number for channel registers.
- qcom,pmic-arb-ppid-map : an array used to map a 12-bit PPID to 8-bit APID.
+Optional properties:
+- qcom,not-wakeup : boolean property which indicates that SPMI PMIC interrupts
+ should not be treated as wakeup sources
+
Peripherals on the SPMI bus are identified with a 12-bit identifier (PPID)
which is composed of a 4-bit slave address and an 8-bit peripheral identifier.
The PMIC Arbiter hardware uses an 8-bit APID (Arbiter Peripheral Identifier)
diff --git a/Documentation/devicetree/bindings/usb/msm-hsusb.txt b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
index 9c2ce6c..12fbfec 100644
--- a/Documentation/devicetree/bindings/usb/msm-hsusb.txt
+++ b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
@@ -6,6 +6,8 @@
- compatible : should be "qcom,hsusb-otg"
- regs : offset and length of the register set in the memory map
- interrupts: IRQ line
+- interrupt-names: OTG interrupt name(s) referenced in interrupts above
+ HSUSB OTG expects "core_irq" and optionally "async_irq".
- qcom,hsusb-otg-phy-type: PHY type can be one of
1 - Chipidea 45nm PHY
2 - Synopsis 28nm PHY
@@ -48,6 +50,7 @@
compatible = "qcom,hsusb-otg";
reg = <0xf9690000 0x400>;
interrupts = <134>;
+ interrupt-names = "core_irq";
qcom,hsusb-otg-phy-type = <2>;
qcom,hsusb-otg-mode = <1>;
diff --git a/arch/Kconfig b/arch/Kconfig
index 0d88760..0a3ffe4 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -169,13 +169,6 @@
bool
depends on PERF_EVENTS
-config HAVE_HW_BRKPT_RESERVED_RW_ACCESS
- bool
- depends on HAVE_HW_BREAKPOINT
- help
- Some of the hardware might not have r/w access beyond a certain number
- of breakpoint register access.
-
config HAVE_MIXED_BREAKPOINTS_REGS
bool
depends on HAVE_HW_BREAKPOINT
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index d7ebcfe..5d5f9de 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -29,7 +29,7 @@
select HAVE_PERF_EVENTS
select PERF_USE_VMALLOC
select HAVE_REGS_AND_STACK_ACCESS_API
- #select HAVE_HW_BREAKPOINT if (PERF_EVENTS && (CPU_V6 || CPU_V6K || CPU_V7))
+ select HAVE_HW_BREAKPOINT if (PERF_EVENTS && (CPU_V6 || CPU_V6K || CPU_V7))
select HAVE_C_RECORDMCOUNT
select HAVE_GENERIC_HARDIRQS
select GENERIC_IRQ_SHOW
diff --git a/arch/arm/boot/dts/mpq8092-iommu.dtsi b/arch/arm/boot/dts/mpq8092-iommu.dtsi
new file mode 100755
index 0000000..6a88992
--- /dev/null
+++ b/arch/arm/boot/dts/mpq8092-iommu.dtsi
@@ -0,0 +1,33 @@
+/* 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/ "msm-iommu.dtsi"
+
+&jpeg_iommu {
+ status = "ok";
+};
+
+&mdp_iommu {
+ status = "ok";
+};
+
+&venus_iommu {
+ status = "ok";
+};
+
+&kgsl_iommu {
+ status = "ok";
+};
+
+&vfe_iommu {
+ status = "ok";
+};
diff --git a/arch/arm/boot/dts/mpq8092-sim.dts b/arch/arm/boot/dts/mpq8092-sim.dts
index f73abe7..ac984a1 100644
--- a/arch/arm/boot/dts/mpq8092-sim.dts
+++ b/arch/arm/boot/dts/mpq8092-sim.dts
@@ -1,4 +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
@@ -12,37 +12,19 @@
/dts-v1/;
-/include/ "skeleton.dtsi"
+/include/ "mpq8092.dtsi"
/ {
model = "Qualcomm MPQ8092 Simulator";
compatible = "qcom,mpq8092-sim", "qcom,mpq8092";
- interrupt-parent = <&intc>;
-
- intc: interrupt-controller@f9000000 {
- compatible = "qcom,msm-qgic2";
- interrupt-controller;
- #interrupt-cells = <3>;
- reg = <0xf9000000 0x1000>,
- <0xf9002000 0x1000>;
- };
-
- timer {
- compatible = "qcom,msm-qtimer", "arm,armv7-timer";
- interrupts = <1 2 0>, <1 3 0>;
- clock-frequency = <19200000>;
- };
+ qcom,msm-id = <126 16 0>;
serial@f991f000 {
- compatible = "qcom,msm-lsuart-v14";
- reg = <0xf991f000 0x1000>;
- interrupts = <0 109 0>;
+ status = "ok";
};
serial@f995e000 {
- compatible = "qcom,msm-lsuart-v14";
- reg = <0xf995e000 0x1000>;
- interrupts = <0 114 0>;
+ status = "ok";
};
};
diff --git a/arch/arm/boot/dts/mpq8092.dtsi b/arch/arm/boot/dts/mpq8092.dtsi
new file mode 100644
index 0000000..9b51ceb
--- /dev/null
+++ b/arch/arm/boot/dts/mpq8092.dtsi
@@ -0,0 +1,58 @@
+/* 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/ "skeleton.dtsi"
+/include/ "mpq8092-iommu.dtsi"
+/include/ "msm-gdsc.dtsi"
+
+/ {
+ model = "Qualcomm MPQ8092";
+ compatible = "qcom,mpq8092";
+ interrupt-parent = <&intc>;
+
+ intc: interrupt-controller@f9000000 {
+ compatible = "qcom,msm-qgic2";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ reg = <0xf9000000 0x1000>,
+ <0xf9002000 0x1000>;
+ };
+
+ msmgpio: gpio@fd510000 {
+ compatible = "qcom,msm-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0xfd510000 0x4000>;
+ };
+
+ timer {
+ compatible = "qcom,msm-qtimer", "arm,armv7-timer";
+ interrupts = <1 2 0>, <1 3 0>;
+ clock-frequency = <19200000>;
+ };
+
+ serial@f991f000 {
+ compatible = "qcom,msm-lsuart-v14";
+ reg = <0xf991f000 0x1000>;
+ interrupts = <0 109 0>;
+ status = "disabled";
+ };
+
+ serial@f995e000 {
+ compatible = "qcom,msm-lsuart-v14";
+ reg = <0xf995e000 0x1000>;
+ interrupts = <0 114 0>;
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/boot/dts/msm-pm8019-rpm-regulator.dtsi b/arch/arm/boot/dts/msm-pm8019-rpm-regulator.dtsi
new file mode 100644
index 0000000..c48f67d
--- /dev/null
+++ b/arch/arm/boot/dts/msm-pm8019-rpm-regulator.dtsi
@@ -0,0 +1,301 @@
+/* Copyright (c) 2012, Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+&rpm_bus {
+ rpm-regulator-smpa1 {
+ qcom,resource-name = "smpa";
+ qcom,resource-id = <1>;
+ qcom,regulator-type = <1>;
+ qcom,hpm-min-load = <100000>;
+ compatible = "qcom,rpm-regulator-smd-resource";
+ status = "disabled";
+
+ regulator-s1 {
+ regulator-name = "8019_s1";
+ qcom,set = <3>;
+ status = "disabled";
+ compatible = "qcom,rpm-regulator-smd";
+ };
+ };
+
+ rpm-regulator-smpa2 {
+ qcom,resource-name = "smpa";
+ qcom,resource-id = <2>;
+ qcom,regulator-type = <1>;
+ qcom,hpm-min-load = <100000>;
+ compatible = "qcom,rpm-regulator-smd-resource";
+ status = "disabled";
+
+ regulator-s2 {
+ regulator-name = "8019_s2";
+ qcom,set = <3>;
+ status = "disabled";
+ compatible = "qcom,rpm-regulator-smd";
+ };
+ };
+
+ rpm-regulator-smpa3 {
+ qcom,resource-name = "smpa";
+ qcom,resource-id = <3>;
+ qcom,regulator-type = <1>;
+ qcom,hpm-min-load = <100000>;
+ compatible = "qcom,rpm-regulator-smd-resource";
+ status = "disabled";
+
+ regulator-s3 {
+ regulator-name = "8019_s3";
+ qcom,set = <3>;
+ status = "disabled";
+ compatible = "qcom,rpm-regulator-smd";
+ };
+ };
+
+ rpm-regulator-smpa4 {
+ qcom,resource-name = "smpa";
+ qcom,resource-id = <4>;
+ qcom,regulator-type = <1>;
+ qcom,hpm-min-load = <100000>;
+ compatible = "qcom,rpm-regulator-smd-resource";
+ status = "disabled";
+
+ regulator-s4 {
+ regulator-name = "8019_s4";
+ qcom,set = <3>;
+ status = "disabled";
+ compatible = "qcom,rpm-regulator-smd";
+ };
+ };
+
+ rpm-regulator-ldoa1 {
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <1>;
+ qcom,regulator-type = <0>;
+ qcom,hpm-min-load = <10000>;
+ compatible = "qcom,rpm-regulator-smd-resource";
+ status = "disabled";
+
+ regulator-l1 {
+ regulator-name = "8019_l1";
+ qcom,set = <3>;
+ status = "disabled";
+ compatible = "qcom,rpm-regulator-smd";
+ };
+ };
+
+ rpm-regulator-ldoa2 {
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <2>;
+ qcom,regulator-type = <0>;
+ qcom,hpm-min-load = <5000>;
+ compatible = "qcom,rpm-regulator-smd-resource";
+ status = "disabled";
+
+ regulator-l2 {
+ regulator-name = "8019_l2";
+ qcom,set = <3>;
+ status = "disabled";
+ compatible = "qcom,rpm-regulator-smd";
+ };
+ };
+
+ rpm-regulator-ldoa3 {
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <3>;
+ qcom,regulator-type = <0>;
+ qcom,hpm-min-load = <10000>;
+ compatible = "qcom,rpm-regulator-smd-resource";
+ status = "disabled";
+
+ regulator-l3 {
+ regulator-name = "8019_l3";
+ qcom,set = <3>;
+ status = "disabled";
+ compatible = "qcom,rpm-regulator-smd";
+ };
+ };
+
+ rpm-regulator-ldoa4 {
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <4>;
+ qcom,regulator-type = <0>;
+ qcom,hpm-min-load = <5000>;
+ compatible = "qcom,rpm-regulator-smd-resource";
+ status = "disabled";
+
+ regulator-l4 {
+ regulator-name = "8019_l4";
+ qcom,set = <3>;
+ status = "disabled";
+ compatible = "qcom,rpm-regulator-smd";
+ };
+ };
+
+ rpm-regulator-ldoa5 {
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <5>;
+ qcom,regulator-type = <0>;
+ qcom,hpm-min-load = <10000>;
+ compatible = "qcom,rpm-regulator-smd-resource";
+ status = "disabled";
+
+ regulator-l5 {
+ regulator-name = "8019_l5";
+ qcom,set = <3>;
+ status = "disabled";
+ compatible = "qcom,rpm-regulator-smd";
+ };
+ };
+
+ rpm-regulator-ldoa6 {
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <6>;
+ qcom,regulator-type = <0>;
+ qcom,hpm-min-load = <10000>;
+ compatible = "qcom,rpm-regulator-smd-resource";
+ status = "disabled";
+
+ regulator-l6 {
+ regulator-name = "8019_l6";
+ qcom,set = <3>;
+ status = "disabled";
+ compatible = "qcom,rpm-regulator-smd";
+ };
+ };
+
+ rpm-regulator-ldoa7 {
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <7>;
+ qcom,regulator-type = <0>;
+ qcom,hpm-min-load = <10000>;
+ compatible = "qcom,rpm-regulator-smd-resource";
+ status = "disabled";
+
+ regulator-l7 {
+ regulator-name = "8019_l7";
+ qcom,set = <3>;
+ status = "disabled";
+ compatible = "qcom,rpm-regulator-smd";
+ };
+ };
+
+ rpm-regulator-ldoa8 {
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <8>;
+ qcom,regulator-type = <0>;
+ qcom,hpm-min-load = <10000>;
+ compatible = "qcom,rpm-regulator-smd-resource";
+ status = "disabled";
+
+ regulator-l8 {
+ regulator-name = "8019_l8";
+ qcom,set = <3>;
+ status = "disabled";
+ compatible = "qcom,rpm-regulator-smd";
+ };
+ };
+
+ rpm-regulator-ldoa9 {
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <9>;
+ qcom,regulator-type = <0>;
+ qcom,hpm-min-load = <10000>;
+ compatible = "qcom,rpm-regulator-smd-resource";
+ status = "disabled";
+
+ regulator-l9 {
+ regulator-name = "8019_l9";
+ qcom,set = <3>;
+ status = "disabled";
+ compatible = "qcom,rpm-regulator-smd";
+ };
+ };
+
+ rpm-regulator-ldoa10 {
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <10>;
+ qcom,regulator-type = <0>;
+ qcom,hpm-min-load = <10000>;
+ compatible = "qcom,rpm-regulator-smd-resource";
+ status = "disabled";
+
+ regulator-l10 {
+ regulator-name = "8019_l10";
+ qcom,set = <3>;
+ status = "disabled";
+ compatible = "qcom,rpm-regulator-smd";
+ };
+ };
+
+ rpm-regulator-ldoa11 {
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <11>;
+ qcom,regulator-type = <0>;
+ qcom,hpm-min-load = <10000>;
+ compatible = "qcom,rpm-regulator-smd-resource";
+ status = "disabled";
+
+ regulator-l11 {
+ regulator-name = "8019_l11";
+ qcom,set = <3>;
+ status = "disabled";
+ compatible = "qcom,rpm-regulator-smd";
+ };
+ };
+
+ rpm-regulator-ldoa12 {
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <12>;
+ qcom,regulator-type = <0>;
+ qcom,hpm-min-load = <10000>;
+ compatible = "qcom,rpm-regulator-smd-resource";
+ status = "disabled";
+
+ regulator-l12 {
+ regulator-name = "8019_l12";
+ qcom,set = <3>;
+ status = "disabled";
+ compatible = "qcom,rpm-regulator-smd";
+ };
+ };
+
+ rpm-regulator-ldoa13 {
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <13>;
+ qcom,regulator-type = <0>;
+ qcom,hpm-min-load = <5000>;
+ compatible = "qcom,rpm-regulator-smd-resource";
+ status = "disabled";
+
+ regulator-l13 {
+ regulator-name = "8019_l13";
+ qcom,set = <3>;
+ status = "disabled";
+ compatible = "qcom,rpm-regulator-smd";
+ };
+ };
+
+ rpm-regulator-ldoa14 {
+ qcom,resource-name = "ldoa";
+ qcom,resource-id = <14>;
+ qcom,regulator-type = <0>;
+ qcom,hpm-min-load = <5000>;
+ compatible = "qcom,rpm-regulator-smd-resource";
+ status = "disabled";
+
+ regulator-l14 {
+ regulator-name = "8019_l14";
+ qcom,set = <3>;
+ status = "disabled";
+ compatible = "qcom,rpm-regulator-smd";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/msm-pm8019.dtsi b/arch/arm/boot/dts/msm-pm8019.dtsi
new file mode 100755
index 0000000..3b06450
--- /dev/null
+++ b/arch/arm/boot/dts/msm-pm8019.dtsi
@@ -0,0 +1,340 @@
+/* Copyright (c) 2012, Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+&spmi_bus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+
+ qcom,pm8019@0 {
+ spmi-slave-container;
+ reg = <0x0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ clkdiv@5b00 {
+ reg = <0x5b00 0x100>;
+ compatible = "qcom,qpnp-clkdiv";
+ qcom,cxo-freq = <19200000>;
+ };
+
+ clkdiv@5c00 {
+ reg = <0x5c00 0x100>;
+ compatible = "qcom,qpnp-clkdiv";
+ qcom,cxo-freq = <19200000>;
+ };
+
+ clkdiv@5d00 {
+ reg = <0x5d00 0x100>;
+ compatible = "qcom,qpnp-clkdiv";
+ qcom,cxo-freq = <19200000>;
+ };
+
+ rtc {
+ spmi-dev-container;
+ compatible = "qcom,qpnp-rtc";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ qcom,qpnp-rtc-write = <0>;
+ qcom,qpnp-rtc-alarm-pwrup = <0>;
+
+ qcom,pm8019_rtc_rw@6000 {
+ reg = <0x6000 0x100>;
+ };
+
+ qcom,pm8019_rtc_alarm@6100 {
+ reg = <0x6100 0x100>;
+ interrupts = <0x0 0x61 0x1>;
+ };
+ };
+
+ pm8019_gpios: gpios {
+ spmi-dev-container;
+ compatible = "qcom,qpnp-pin";
+ gpio-controller;
+ #gpio-cells = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ label = "pm8019-gpio";
+
+ gpio@c000 {
+ reg = <0xc000 0x100>;
+ qcom,pin-num = <1>;
+ };
+
+ gpio@c100 {
+ reg = <0xc100 0x100>;
+ qcom,pin-num = <2>;
+ };
+
+ gpio@c200 {
+ reg = <0xc200 0x100>;
+ qcom,pin-num = <3>;
+ };
+
+ gpio@c300 {
+ reg = <0xc300 0x100>;
+ qcom,pin-num = <4>;
+ };
+
+ gpio@c400 {
+ reg = <0xc400 0x100>;
+ qcom,pin-num = <5>;
+ };
+
+ gpio@c500 {
+ reg = <0xc500 0x100>;
+ qcom,pin-num = <6>;
+ };
+ };
+
+ pm8019_mpps: mpps {
+ spmi-dev-container;
+ compatible = "qcom,qpnp-pin";
+ gpio-controller;
+ #gpio-cells = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ label = "pm8019-mpp";
+
+ mpp@a000 {
+ reg = <0xa000 0x100>;
+ qcom,pin-num = <1>;
+ };
+
+ mpp@a100 {
+ reg = <0xa100 0x100>;
+ qcom,pin-num = <2>;
+ };
+
+ mpp@a200 {
+ reg = <0xa200 0x100>;
+ qcom,pin-num = <3>;
+ };
+
+ mpp@a300 {
+ reg = <0xa300 0x100>;
+ qcom,pin-num = <4>;
+ };
+
+ mpp@a400 {
+ reg = <0xa400 0x100>;
+ qcom,pin-num = <5>;
+ };
+
+ mpp@a500 {
+ reg = <0xa500 0x100>;
+ qcom,pin-num = <6>;
+ };
+ };
+ };
+
+ qcom,pm8019@1 {
+ spmi-slave-container;
+ reg = <0x1>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ regulator@1400 {
+ regulator-name = "8019_s1";
+ spmi-dev-container;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "qcom,qpnp-regulator";
+ reg = <0x1400 0x300>;
+ status = "disabled";
+
+ qcom,ctl@1400 {
+ reg = <0x1400 0x100>;
+ };
+ qcom,ps@1500 {
+ reg = <0x1500 0x100>;
+ };
+ qcom,freq@1600 {
+ reg = <0x1600 0x100>;
+ };
+ };
+
+ regulator@1700 {
+ regulator-name = "8019_s2";
+ spmi-dev-container;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "qcom,qpnp-regulator";
+ reg = <0x1700 0x300>;
+ status = "disabled";
+
+ qcom,ctl@1700 {
+ reg = <0x1700 0x100>;
+ };
+ qcom,ps@1800 {
+ reg = <0x1800 0x100>;
+ };
+ qcom,freq@1900 {
+ reg = <0x1900 0x100>;
+ };
+ };
+
+ regulator@1a00 {
+ regulator-name = "8019_s3";
+ spmi-dev-container;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "qcom,qpnp-regulator";
+ reg = <0x1a00 0x300>;
+ status = "disabled";
+
+ qcom,ctl@1a00 {
+ reg = <0x1a00 0x100>;
+ };
+ qcom,ps@1b00 {
+ reg = <0x1b00 0x100>;
+ };
+ qcom,freq@1c00 {
+ reg = <0x1c00 0x100>;
+ };
+ };
+
+ regulator@1d00 {
+ regulator-name = "8019_s4";
+ spmi-dev-container;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "qcom,qpnp-regulator";
+ reg = <0x1d00 0x300>;
+ status = "disabled";
+
+ qcom,ctl@1d00 {
+ reg = <0x1d00 0x100>;
+ };
+ qcom,ps@1e00 {
+ reg = <0x1e00 0x100>;
+ };
+ qcom,freq@1f00 {
+ reg = <0x1f00 0x100>;
+ };
+ };
+
+ regulator@4000 {
+ regulator-name = "8019_l1";
+ reg = <0x4000 0x100>;
+ compatible = "qcom,qpnp-regulator";
+ status = "disabled";
+ };
+
+ regulator@4100 {
+ regulator-name = "8019_l2";
+ reg = <0x4100 0x100>;
+ compatible = "qcom,qpnp-regulator";
+ status = "disabled";
+ };
+
+ regulator@4200 {
+ regulator-name = "8019_l3";
+ reg = <0x4200 0x100>;
+ compatible = "qcom,qpnp-regulator";
+ status = "disabled";
+ };
+
+ regulator@4300 {
+ regulator-name = "8019_l4";
+ reg = <0x4300 0x100>;
+ compatible = "qcom,qpnp-regulator";
+ status = "disabled";
+ };
+
+ regulator@4400 {
+ regulator-name = "8019_l5";
+ reg = <0x4400 0x100>;
+ compatible = "qcom,qpnp-regulator";
+ status = "disabled";
+ };
+
+ regulator@4500 {
+ regulator-name = "8019_l6";
+ reg = <0x4500 0x100>;
+ compatible = "qcom,qpnp-regulator";
+ status = "disabled";
+ };
+
+ regulator@4600 {
+ regulator-name = "8019_l7";
+ reg = <0x4600 0x100>;
+ compatible = "qcom,qpnp-regulator";
+ status = "disabled";
+ };
+
+ regulator@4700 {
+ regulator-name = "8019_l8";
+ reg = <0x4700 0x100>;
+ compatible = "qcom,qpnp-regulator";
+ status = "disabled";
+ };
+
+ regulator@4800 {
+ regulator-name = "8019_l9";
+ reg = <0x4800 0x100>;
+ compatible = "qcom,qpnp-regulator";
+ status = "disabled";
+ };
+
+ regulator@4900 {
+ regulator-name = "8019_l10";
+ reg = <0x4900 0x100>;
+ compatible = "qcom,qpnp-regulator";
+ status = "disabled";
+ };
+
+ regulator@4a00 {
+ regulator-name = "8019_l11";
+ reg = <0x4a00 0x100>;
+ compatible = "qcom,qpnp-regulator";
+ status = "disabled";
+ };
+
+ regulator@4b00 {
+ regulator-name = "8019_l12";
+ reg = <0x4b00 0x100>;
+ compatible = "qcom,qpnp-regulator";
+ status = "disabled";
+ };
+
+ regulator@4c00 {
+ regulator-name = "8019_l13";
+ reg = <0x4c00 0x100>;
+ compatible = "qcom,qpnp-regulator";
+ status = "disabled";
+ };
+
+ regulator@4d00 {
+ regulator-name = "8019_l14";
+ reg = <0x4d00 0x100>;
+ compatible = "qcom,qpnp-regulator";
+ status = "disabled";
+ };
+
+ regulator@4e00 {
+ regulator-name = "8019_ldo_xo";
+ reg = <0x4e00 0x100>;
+ compatible = "qcom,qpnp-regulator";
+ status = "disabled";
+ };
+
+ regulator@4f00 {
+ regulator-name = "8019_ldo_rfclk";
+ reg = <0x4f00 0x100>;
+ compatible = "qcom,qpnp-regulator";
+ status = "disabled";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/msm8974-camera.dtsi b/arch/arm/boot/dts/msm8974-camera.dtsi
index c92188a..fd652a0 100644
--- a/arch/arm/boot/dts/msm8974-camera.dtsi
+++ b/arch/arm/boot/dts/msm8974-camera.dtsi
@@ -1,5 +1,5 @@
/*
- * 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
@@ -181,7 +181,6 @@
reg = <0x6e 0x0>;
qcom,csi-if = <1>;
qcom,csid-core = <0>;
- qcom,is-vpe = <1>;
qcom,flash-type = <0>;
qcom,mount-angle = <90>;
qcom,sensor-name = "s5k3l1yx";
@@ -222,8 +221,7 @@
compatible = "qcom,ov2720";
reg = <0x6c 0x0>;
qcom,csi-if = <1>;
- qcom,csid-core = <1>;
- qcom,is-vpe = <1>;
+ qcom,csid-core = <0>;
qcom,flash-type = <0>;
qcom,mount-angle = <0>;
qcom,sensor-name = "ov2720";
@@ -257,5 +255,40 @@
qcom,camera-type = <1>;
qcom,sensor-type = <0>;
};
+
+ qcom,camera@90 {
+ compatible = "qcom,mt9m114";
+ reg = <0x90 0x0>;
+ qcom,csi-if = <1>;
+ qcom,csid-core = <0>;
+ qcom,flash-type = <0>;
+ qcom,mount-angle = <0>;
+ qcom,sensor-name = "mt9m114";
+ cam_vdig-supply = <&pm8941_l3>;
+ cam_vana-supply = <&pm8941_l17>;
+ cam_vio-supply = <&pm8941_lvs3>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vana", "cam_vio";
+ qcom,cam-vreg-type = <0 0 1>;
+ qcom,cam-vreg-min-voltage = <1225000 2850000 0>;
+ qcom,cam-vreg-max-voltage = <1225000 2850000 0>;
+ qcom,cam-vreg-op-mode = <105000 80000 0>;
+ qcom,gpio-no-mux = <0>;
+ gpios = <&msmgpio 16 0>,
+ <&msmgpio 92 0>;
+ qcom,gpio-common-tbl-num = <0>;
+ qcom,gpio-common-tbl-flags = <1>;
+ qcom,gpio-common-tbl-label = "CAMIF_MCLK";
+ qcom,gpio-req-tbl-num = <1>;
+ qcom,gpio-req-tbl-flags = <0>;
+ qcom,gpio-req-tbl-label = "CAM_RESET1";
+ qcom,gpio-set-tbl-num = <1 1>;
+ qcom,gpio-set-tbl-flags = <0 2>;
+ qcom,gpio-set-tbl-delay = <1000 4000>;
+ qcom,csi-lane-assign = <0x4320>;
+ qcom,csi-lane-mask = <0x3>;
+ qcom,csi-phy-sel = <1>;
+ qcom,camera-type = <1>;
+ qcom,sensor-type = <1>;
+ };
};
};
diff --git a/arch/arm/boot/dts/msm8974-coresight.dtsi b/arch/arm/boot/dts/msm8974-coresight.dtsi
index 0b09bc8..ee3df10 100644
--- a/arch/arm/boot/dts/msm8974-coresight.dtsi
+++ b/arch/arm/boot/dts/msm8974-coresight.dtsi
@@ -1,4 +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
@@ -141,6 +141,7 @@
coresight-outports = <0>;
coresight-child-list = <&funnel_kpss>;
coresight-child-ports = <0>;
+ qcom,pc-save;
};
etm1: etm@fc33d000 {
@@ -153,6 +154,7 @@
coresight-outports = <0>;
coresight-child-list = <&funnel_kpss>;
coresight-child-ports = <1>;
+ qcom,pc-save;
};
etm2: etm@fc33e000 {
@@ -165,6 +167,7 @@
coresight-outports = <0>;
coresight-child-list = <&funnel_kpss>;
coresight-child-ports = <2>;
+ qcom,pc-save;
};
etm3: etm@fc33f000 {
@@ -177,6 +180,7 @@
coresight-outports = <0>;
coresight-child-list = <&funnel_kpss>;
coresight-child-ports = <3>;
+ qcom,pc-save;
};
csr: csr@fc302000 {
diff --git a/arch/arm/boot/dts/msm8974-gpio.dtsi b/arch/arm/boot/dts/msm8974-gpio.dtsi
index dac87a3..fee39e9 100644
--- a/arch/arm/boot/dts/msm8974-gpio.dtsi
+++ b/arch/arm/boot/dts/msm8974-gpio.dtsi
@@ -139,22 +139,18 @@
};
gpio@d800 {
- qcom,out-strength = <1>;
status = "ok";
};
gpio@d900 {
- qcom,out-strength = <1>;
status = "ok";
};
gpio@da00 {
- qcom,out-strength = <1>;
status = "ok";
};
gpio@db00 {
- qcom,out-strength = <1>;
status = "ok";
};
@@ -166,37 +162,30 @@
};
gpio@dd00 {
- qcom,out-strength = <1>;
status = "ok";
};
gpio@de00 {
- qcom,out-strength = <1>;
status = "ok";
};
gpio@df00 {
- qcom,out-strength = <1>;
status = "ok";
};
gpio@e000 {
- qcom,out-strength = <1>;
status = "ok";
};
gpio@e100 {
- qcom,out-strength = <1>;
status = "ok";
};
gpio@e200 {
- qcom,out-strength = <1>;
status = "ok";
};
gpio@e300 {
- qcom,out-strength = <1>;
status = "ok";
};
};
diff --git a/arch/arm/boot/dts/msm8974-mdss.dtsi b/arch/arm/boot/dts/msm8974-mdss.dtsi
index 344aa7f..ee5836c 100644
--- a/arch/arm/boot/dts/msm8974-mdss.dtsi
+++ b/arch/arm/boot/dts/msm8974-mdss.dtsi
@@ -55,7 +55,7 @@
qcom,mdss_wb_panel {
compatible = "qcom,mdss_wb";
- qcom,mdss_pan_res = <640 480>;
+ qcom,mdss_pan_res = <1920 1080>;
qcom,mdss_pan_bpp = <24>;
};
};
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index 01458ae..9ed61ed 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -97,7 +97,7 @@
qcom,hsusb-otg-phy-type = <2>;
qcom,hsusb-otg-phy-init-seq = <0x63 0x81 0xffffffff>;
qcom,hsusb-otg-mode = <1>;
- qcom,hsusb-otg-otg-control = <2>;
+ qcom,hsusb-otg-otg-control = <1>;
qcom,hsusb-otg-disable-reset;
qcom,msm_bus,name = "usb2";
@@ -306,7 +306,6 @@
qcom,audio-routing =
"RX_BIAS", "MCLK",
"LDO_H", "MCLK",
- "HEADPHONE", "LDO_H",
"Ext Spk Bottom Pos", "LINEOUT1",
"Ext Spk Bottom Neg", "LINEOUT3",
"Ext Spk Top Pos", "LINEOUT2",
@@ -633,6 +632,7 @@
compatible = "qcom,pil-q6v5-lpass";
reg = <0xfe200000 0x00100>,
<0xfd485100 0x00010>;
+ reg-names = "qdsp6_base", "halt_base";
qcom,firmware-name = "adsp";
};
@@ -673,6 +673,10 @@
compatible = "qcom,msm-dai-fe";
};
+ qcom,msm-pcm-afe {
+ compatible = "qcom,msm-pcm-afe";
+ };
+
qcom,msm-dai-q6 {
compatible = "qcom,msm-dai-q6";
qcom,msm-dai-q6-sb-0-rx {
@@ -684,6 +688,36 @@
compatible = "qcom,msm-dai-q6-dev";
qcom,msm-dai-q6-dev-id = <16385>;
};
+
+ qcom,msm-dai-q6-bt-sco-rx {
+ compatible = "qcom,msm-dai-q6-dev";
+ qcom,msm-dai-q6-dev-id = <12288>;
+ };
+
+ qcom,msm-dai-q6-bt-sco-tx {
+ compatible = "qcom,msm-dai-q6-dev";
+ qcom,msm-dai-q6-dev-id = <12289>;
+ };
+
+ qcom,msm-dai-q6-be-afe-pcm-rx {
+ compatible = "qcom,msm-dai-q6-dev";
+ qcom,msm-dai-q6-dev-id = <224>;
+ };
+
+ qcom,msm-dai-q6-be-afe-pcm-tx {
+ compatible = "qcom,msm-dai-q6-dev";
+ qcom,msm-dai-q6-dev-id = <225>;
+ };
+
+ qcom,msm-dai-q6-afe-proxy-rx {
+ compatible = "qcom,msm-dai-q6-dev";
+ qcom,msm-dai-q6-dev-id = <241>;
+ };
+
+ qcom,msm-dai-q6-afe-proxy-tx {
+ compatible = "qcom,msm-dai-q6-dev";
+ qcom,msm-dai-q6-dev-id = <240>;
+ };
};
qcom,msm-auxpcm {
@@ -727,6 +761,9 @@
<0xfc820000 0x020>,
<0xfc401680 0x004>,
<0xfc980008 0x004>;
+ reg-names = "qdsp6_base", "halt_base", "rmb_base",
+ "restart_reg", "clamp_reg";
+
vdd_mss-supply = <&pm8841_s3>;
qcom,firmware-name = "mba";
@@ -737,6 +774,7 @@
compatible = "qcom,pil-mba";
reg = <0xfc820000 0x0020>,
<0x0d1fc000 0x4000>;
+ reg-names = "rmb_base", "metadata_base";
qcom,firmware-name = "modem";
qcom,depends-on = "mba";
@@ -747,6 +785,7 @@
reg = <0xfb21b000 0x3000>,
<0xfc401700 0x4>,
<0xfd485300 0xc>;
+ reg-names = "pmu_base", "clk_base", "halt_base";
vdd_pronto_pll-supply = <&pm8941_l12>;
qcom,firmware-name = "wcnss";
@@ -851,6 +890,7 @@
compatible = "qcom,pil-venus";
reg = <0xfdce0000 0x4000>,
<0xfdc80208 0x8>;
+ reg-names = "wrapper_base", "vbif_base";
vdd-supply = <&gdsc_venus>;
qcom,firmware-name = "venus";
diff --git a/arch/arm/boot/dts/msm8974_pm.dtsi b/arch/arm/boot/dts/msm8974_pm.dtsi
index 8e3f4b8..77f2532 100644
--- a/arch/arm/boot/dts/msm8974_pm.dtsi
+++ b/arch/arm/boot/dts/msm8974_pm.dtsi
@@ -385,8 +385,8 @@
<40 95>;
};
- qcom,pc-cntr@fe800000 {
+ qcom,pc-cntr@fe805664 {
compatible = "qcom,pc-cntr";
- reg = <0xfe800664 0x40>;
+ reg = <0xfe805664 0x40>;
};
};
diff --git a/arch/arm/boot/dts/msm9625-cdp.dts b/arch/arm/boot/dts/msm9625-cdp.dts
index 6733f59..aa1ec92 100644
--- a/arch/arm/boot/dts/msm9625-cdp.dts
+++ b/arch/arm/boot/dts/msm9625-cdp.dts
@@ -19,3 +19,44 @@
compatible = "qcom,msm9625-cdp", "qcom,msm9625";
qcom,msm-id = <134 1 0>;
};
+
+/* PM8019 GPIO and MPP configuration */
+&pm8019_gpios {
+ gpio@c000 { /* GPIO 1 */
+ };
+
+ gpio@c100 { /* GPIO 2 */
+ };
+
+ gpio@c200 { /* GPIO 3 */
+ };
+
+ gpio@c300 { /* GPIO 4 */
+ };
+
+ gpio@c400 { /* GPIO 5 */
+ };
+
+ gpio@c500 { /* GPIO 6 */
+ };
+};
+
+&pm8019_mpps {
+ mpp@a000 { /* MPP 1 */
+ };
+
+ mpp@a100 { /* MPP 2 */
+ };
+
+ mpp@a200 { /* MPP 3 */
+ };
+
+ mpp@a300 { /* MPP 4 */
+ };
+
+ mpp@a400 { /* MPP 5 */
+ };
+
+ mpp@a500 { /* MPP 6 */
+ };
+};
diff --git a/arch/arm/boot/dts/msm9625-mtp.dts b/arch/arm/boot/dts/msm9625-mtp.dts
index 32185dc..3ec949f 100644
--- a/arch/arm/boot/dts/msm9625-mtp.dts
+++ b/arch/arm/boot/dts/msm9625-mtp.dts
@@ -19,3 +19,44 @@
compatible = "qcom,msm9625-mtp", "qcom,msm9625";
qcom,msm-id = <134 8 0>;
};
+
+/* PM8019 GPIO and MPP configuration */
+&pm8019_gpios {
+ gpio@c000 { /* GPIO 1 */
+ };
+
+ gpio@c100 { /* GPIO 2 */
+ };
+
+ gpio@c200 { /* GPIO 3 */
+ };
+
+ gpio@c300 { /* GPIO 4 */
+ };
+
+ gpio@c400 { /* GPIO 5 */
+ };
+
+ gpio@c500 { /* GPIO 6 */
+ };
+};
+
+&pm8019_mpps {
+ mpp@a000 { /* MPP 1 */
+ };
+
+ mpp@a100 { /* MPP 2 */
+ };
+
+ mpp@a200 { /* MPP 3 */
+ };
+
+ mpp@a300 { /* MPP 4 */
+ };
+
+ mpp@a400 { /* MPP 5 */
+ };
+
+ mpp@a500 { /* MPP 6 */
+ };
+};
diff --git a/arch/arm/boot/dts/msm9625-regulator.dtsi b/arch/arm/boot/dts/msm9625-regulator.dtsi
new file mode 100644
index 0000000..c42af2c
--- /dev/null
+++ b/arch/arm/boot/dts/msm9625-regulator.dtsi
@@ -0,0 +1,164 @@
+/* Copyright (c) 2012, Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+&spmi_bus {
+ qcom,pm8019@1 {
+ pm8019_s1: regulator@1400 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1050000>;
+ qcom,enable-time = <500>;
+ status = "okay";
+ };
+
+ pm8019_s2: regulator@1700 {
+ regulator-min-microvolt = <1250000>;
+ regulator-max-microvolt = <1250000>;
+ qcom,system-load = <100000>;
+ qcom,enable-time = <500>;
+ regulator-always-on;
+ status = "okay";
+ };
+
+ pm8019_s3: regulator@1a00 {
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ qcom,system-load = <100000>;
+ qcom,enable-time = <500>;
+ regulator-always-on;
+ status = "okay";
+ };
+
+ pm8019_s4: regulator@1d00 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2075000>;
+ qcom,system-load = <100000>;
+ qcom,enable-time = <500>;
+ regulator-always-on;
+ status = "okay";
+ };
+
+ pm8019_l1: regulator@4000 {
+ parent-supply = <&pm8019_s2>;
+ regulator-min-microvolt = <1225000>;
+ regulator-max-microvolt = <1225000>;
+ qcom,enable-time = <200>;
+ status = "okay";
+ };
+
+ pm8019_l2: regulator@4100 {
+ parent-supply = <&pm8019_s4>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ qcom,enable-time = <200>;
+ status = "okay";
+ };
+
+ pm8019_l3: regulator@4200 {
+ parent-supply = <&pm8019_s4>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ qcom,enable-time = <200>;
+ status = "okay";
+ };
+
+ pm8019_l4: regulator@4300 {
+ regulator-min-microvolt = <3075000>;
+ regulator-max-microvolt = <3075000>;
+ qcom,enable-time = <200>;
+ status = "okay";
+ };
+
+ pm8019_l5: regulator@4400 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2850000>;
+ qcom,enable-time = <200>;
+ status = "okay";
+ };
+
+ pm8019_l6: regulator@4500 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2850000>;
+ qcom,enable-time = <200>;
+ status = "okay";
+ };
+
+ pm8019_l7: regulator@4600 {
+ parent-supply = <&pm8019_s4>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ qcom,enable-time = <200>;
+ status = "okay";
+ };
+
+ pm8019_l8: regulator@4700 {
+ parent-supply = <&pm8019_s4>;
+ regulator-min-microvolt = <2050000>;
+ regulator-max-microvolt = <2050000>;
+ qcom,enable-time = <200>;
+ status = "okay";
+ };
+
+ pm8019_l9: regulator@4800 {
+ parent-supply = <&pm8019_s2>;
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ qcom,system-load = <10000>;
+ qcom,enable-time = <200>;
+ regulator-always-on;
+ status = "okay";
+ };
+
+ pm8019_l10: regulator@4900 {
+ parent-supply = <&pm8019_s3>;
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ qcom,system-load = <10000>;
+ qcom,enable-time = <200>;
+ regulator-always-on;
+ status = "okay";
+ };
+
+ pm8019_l11: regulator@4a00 {
+ parent-supply = <&pm8019_s4>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ qcom,system-load = <10000>;
+ qcom,enable-time = <200>;
+ regulator-always-on;
+ status = "okay";
+ };
+
+ pm8019_l12: regulator@4b00 {
+ parent-supply = <&pm8019_s3>;
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ qcom,system-load = <10000>;
+ qcom,enable-time = <200>;
+ regulator-always-on;
+ status = "okay";
+ };
+
+ pm8019_l13: regulator@4c00 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2950000>;
+ qcom,enable-time = <200>;
+ status = "okay";
+ };
+
+ pm8019_l14: regulator@4d00 {
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <2700000>;
+ qcom,enable-time = <200>;
+ status = "okay";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/msm9625-rumi.dts b/arch/arm/boot/dts/msm9625-rumi.dts
index e4fa000..dadb3f7 100644
--- a/arch/arm/boot/dts/msm9625-rumi.dts
+++ b/arch/arm/boot/dts/msm9625-rumi.dts
@@ -18,4 +18,9 @@
model = "Qualcomm MSM 9625 RUMI";
compatible = "qcom,msm9625-rumi", "qcom,msm9625";
qcom,msm-id = <134 15 0>;
+
+ chosen{
+ bootargs = "root=/dev/ram rw init=/init console=ttyHSL0,115200n8 initrd=0x00000000,0x00000000 mem=29M@0x00200000 mem=10M@0x07600000";
+
+ };
};
diff --git a/arch/arm/boot/dts/msm9625.dtsi b/arch/arm/boot/dts/msm9625.dtsi
index 8ad3b66..f50d14f 100644
--- a/arch/arm/boot/dts/msm9625.dtsi
+++ b/arch/arm/boot/dts/msm9625.dtsi
@@ -48,7 +48,7 @@
reg = <0xF9021000 0x1000>;
interrupts = <0 7 0>;
irq-is-not-percpu;
- clock-frequency = <5000000>;
+ clock-frequency = <19200000>;
};
qcom,sps@f9980000 {
@@ -66,6 +66,26 @@
interrupts = <0 109 0>;
};
+ usb@f9a55000 {
+ compatible = "qcom,hsusb-otg";
+ reg = <0xf9a55000 0x400>;
+ interrupts = <0 134 0 0 140 0>;
+ interrupt-names = "core_irq", "async_irq";
+ HSUSB_VDDCX-supply = <&pm8019_l12>;
+ HSUSB_1p8-supply = <&pm8019_l2>;
+ HSUSB_3p3-supply = <&pm8019_l4>;
+
+ qcom,hsusb-otg-phy-type = <2>;
+ qcom,hsusb-otg-mode = <1>;
+ qcom,hsusb-otg-otg-control = <1>;
+ qcom,hsusb-otg-disable-reset;
+ };
+
+ android_usb@fc42b0c8 {
+ compatible = "qcom,android-usb";
+ reg = <0xfc42b0c8 0xc8>;
+ };
+
qcom,nand@f9ac0000 {
compatible = "qcom,msm-nand";
reg = <0xf9ac0000 0x1000>,
@@ -106,4 +126,41 @@
qcom,pet-time = <10000>;
qcom,ipi-ping = <0>;
};
+
+ rpm_bus: qcom,rpm-smd {
+ compatible = "qcom,rpm-smd";
+ rpm-channel-name = "rpm_requests";
+ rpm-channel-type = <15>; /* SMD_APPS_RPM */
+ };
+
+ spmi_bus: qcom,spmi@fc4c0000 {
+ cell-index = <0>;
+ compatible = "qcom,spmi-pmic-arb";
+ reg = <0xfc4cf000 0x1000>,
+ <0Xfc4cb000 0x1000>;
+ /* 190,ee0_krait_hlos_spmi_periph_irq */
+ /* 187,channel_0_krait_hlos_trans_done_irq */
+ interrupts = <0 190 0 0 187 0>;
+ qcom,not-wakeup;
+ qcom,pmic-arb-ee = <0>;
+ qcom,pmic-arb-channel = <0>;
+ qcom,pmic-arb-ppid-map = <0x02400000>, /* TEMP_ALARM */
+ <0x03100001>, /* VADC1_USR */
+ <0x06100002>, /* RTC_ALARM */
+ <0x06200003>, /* RTC_TIMER */
+ <0x0a000004>, /* MPP1 */
+ <0x0a100005>, /* MPP2 */
+ <0x0a200006>, /* MPP3 */
+ <0x0a300007>, /* MPP4 */
+ <0x0a400008>, /* MPP5 */
+ <0x0a500009>, /* MPP6 */
+ <0x0c20000a>, /* GPIO3 */
+ <0x0c30000b>, /* GPIO4 */
+ <0x0c50000c>, /* GPIO6 */
+ <0x0080000d>; /* PON */
+ };
};
+
+/include/ "msm-pm8019-rpm-regulator.dtsi"
+/include/ "msm-pm8019.dtsi"
+/include/ "msm9625-regulator.dtsi"
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index afe528d..3fdc804 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -347,6 +347,7 @@
CONFIG_MEDIA_CONTROLLER=y
CONFIG_VIDEO_DEV=y
CONFIG_VIDEO_V4L2_SUBDEV_API=y
+CONFIG_MSM_WFD=y
CONFIG_USER_RC_INPUT=y
CONFIG_IR_GPIO_CIR=y
# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index 4c9383d..4daaa12 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -351,6 +351,7 @@
CONFIG_MEDIA_CONTROLLER=y
CONFIG_VIDEO_DEV=y
CONFIG_VIDEO_V4L2_SUBDEV_API=y
+CONFIG_MSM_WFD=y
CONFIG_USER_RC_INPUT=y
CONFIG_IR_GPIO_CIR=y
# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
@@ -513,6 +514,7 @@
CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y
CONFIG_DEBUG_PAGEALLOC=y
CONFIG_ENABLE_DEFAULT_TRACERS=y
+CONFIG_CPU_FREQ_SWITCH_PROFILER=y
CONFIG_DYNAMIC_DEBUG=y
CONFIG_DEBUG_USER=y
CONFIG_PID_IN_CONTEXTIDR=y
diff --git a/arch/arm/configs/msm8974-perf_defconfig b/arch/arm/configs/msm8974-perf_defconfig
index 392e062..47f9ba3 100644
--- a/arch/arm/configs/msm8974-perf_defconfig
+++ b/arch/arm/configs/msm8974-perf_defconfig
@@ -57,6 +57,7 @@
CONFIG_MSM_PIL_PRONTO=y
CONFIG_MSM_MODEM_SSR_8974=y
CONFIG_MSM_ADSP_SSR_8974=y
+CONFIG_MSM_WCNSS_SSR_8974=y
CONFIG_MSM_TZ_LOG=y
CONFIG_MSM_DIRECT_SCLK_ACCESS=y
CONFIG_MSM_BUS_SCALING=y
@@ -297,6 +298,7 @@
CONFIG_MSM_CSI2_REGISTER=y
CONFIG_MSM_ISPIF=y
CONFIG_S5K3L1YX=y
+CONFIG_MT9M114=y
CONFIG_RADIO_IRIS=y
CONFIG_RADIO_IRIS_TRANSPORT=m
CONFIG_ION=y
@@ -369,6 +371,7 @@
CONFIG_QPNP_CLKDIV=y
CONFIG_MSM_IOMMU=y
CONFIG_MSM_QDSS=y
+CONFIG_MSM_QDSS_ETM_PCSAVE_DEFAULT_ENABLE=y
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT3_FS=y
diff --git a/arch/arm/configs/msm8974_defconfig b/arch/arm/configs/msm8974_defconfig
index d54e19e..f6e51af 100644
--- a/arch/arm/configs/msm8974_defconfig
+++ b/arch/arm/configs/msm8974_defconfig
@@ -49,6 +49,7 @@
CONFIG_MSM_IPC_ROUTER_SMD_XPRT=y
# CONFIG_MSM_HW3D is not set
CONFIG_MSM_SUBSYSTEM_RESTART=y
+CONFIG_MSM_SYSMON_COMM=y
CONFIG_MSM_PIL_LPASS_QDSP6V5=y
CONFIG_MSM_PIL_MSS_QDSP6V5=y
CONFIG_MSM_PIL_MBA=y
@@ -56,6 +57,7 @@
CONFIG_MSM_PIL_PRONTO=y
CONFIG_MSM_MODEM_SSR_8974=y
CONFIG_MSM_ADSP_SSR_8974=y
+CONFIG_MSM_WCNSS_SSR_8974=y
CONFIG_MSM_TZ_LOG=y
CONFIG_MSM_DIRECT_SCLK_ACCESS=y
CONFIG_MSM_BUS_SCALING=y
@@ -71,8 +73,9 @@
CONFIG_MSM_L1_ERR_PANIC=y
CONFIG_MSM_L1_ERR_LOG=y
CONFIG_MSM_L2_ERP_PRINT_ACCESS_ERRORS=y
-CONFIG_MSM_L2_ERP_1BIT_PANIC=y
CONFIG_MSM_L2_ERP_2BIT_PANIC=y
+CONFIG_MSM_CACHE_DUMP=y
+CONFIG_MSM_CACHE_DUMP_ON_PANIC=y
CONFIG_STRICT_MEMORY_RWX=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
@@ -272,9 +275,9 @@
CONFIG_GPIO_QPNP_PIN_DEBUG=y
CONFIG_POWER_SUPPLY=y
# CONFIG_BATTERY_MSM is not set
+CONFIG_QPNP_BMS=y
CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y
CONFIG_SENSORS_QPNP_ADC_CURRENT=y
-CONFIG_QPNP_BMS=y
CONFIG_THERMAL=y
CONFIG_THERMAL_TSENS8974=y
CONFIG_WCD9320_CODEC=y
@@ -288,7 +291,7 @@
CONFIG_VIDEOBUF2_MSM_MEM=y
CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_MSM_CAMERA_V4L2=y
-CONFIG_MSM_WFD=y
+CONFIG_MT9M114=y
CONFIG_OV2720=y
CONFIG_MSM_CAMERA_SENSOR=y
CONFIG_MSM_ACTUATOR=y
@@ -300,6 +303,7 @@
CONFIG_MSM_CSI2_REGISTER=y
CONFIG_MSM_ISPIF=y
CONFIG_S5K3L1YX=y
+CONFIG_MSM_WFD=y
CONFIG_RADIO_IRIS=y
CONFIG_RADIO_IRIS_TRANSPORT=m
CONFIG_ION=y
@@ -372,6 +376,7 @@
CONFIG_QPNP_CLKDIV=y
CONFIG_MSM_IOMMU=y
CONFIG_MSM_QDSS=y
+CONFIG_MSM_QDSS_ETM_PCSAVE_DEFAULT_ENABLE=y
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT3_FS=y
@@ -405,6 +410,7 @@
CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y
CONFIG_DEBUG_PAGEALLOC=y
CONFIG_ENABLE_DEFAULT_TRACERS=y
+CONFIG_CPU_FREQ_SWITCH_PROFILER=y
CONFIG_DYNAMIC_DEBUG=y
CONFIG_DEBUG_USER=y
CONFIG_PID_IN_CONTEXTIDR=y
diff --git a/arch/arm/configs/msm9625_defconfig b/arch/arm/configs/msm9625_defconfig
index 0057062..4cb3f6b 100644
--- a/arch/arm/configs/msm9625_defconfig
+++ b/arch/arm/configs/msm9625_defconfig
@@ -45,24 +45,22 @@
CONFIG_HIGHMEM=y
CONFIG_VMALLOC_RESERVE=0x19000000
CONFIG_USE_OF=y
-CONFIG_ARM_APPENDED_DTB=y
-CONFIG_ARM_ATAG_DTB_COMPAT=y
CONFIG_VFP=y
CONFIG_NEON=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
# CONFIG_SUSPEND is not set
-CONFIG_MTD=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_OF_PARTS=y
-CONFIG_MTD_BLOCK=y
-# CONFIG_MTD_MSM_NAND is not set
-CONFIG_MTD_MSM_QPIC_NAND=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
CONFIG_INET=y
CONFIG_IPV6=y
# CONFIG_WIRELESS is not set
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_OF_PARTS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_MTD_MSM_NAND is not set
+CONFIG_MTD_MSM_QPIC_NAND=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
# CONFIG_ANDROID_PMEM is not set
@@ -89,16 +87,30 @@
# CONFIG_LEGACY_PTYS is not set
CONFIG_SERIAL_MSM_HSL=y
CONFIG_SERIAL_MSM_HSL_CONSOLE=y
+CONFIG_DIAG_CHAR=y
CONFIG_HW_RANDOM=y
CONFIG_SPI=y
CONFIG_SPI_QUP=y
CONFIG_SPI_SPIDEV=m
+CONFIG_SPMI=y
+CONFIG_SPMI_MSM_PMIC_ARB=y
+CONFIG_MSM_QPNP_INT=y
CONFIG_DEBUG_GPIO=y
CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_QPNP_PIN=y
+CONFIG_GPIO_QPNP_PIN_DEBUG=y
# CONFIG_HWMON is not set
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_QPNP=y
# CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
+CONFIG_USB_GADGET=y
+CONFIG_USB_CI13XXX_MSM=y
+CONFIG_USB_G_ANDROID=y
+CONFIG_RTC_CLASS=y
+# CONFIG_RTC_DRV_MSM is not set
+CONFIG_RTC_DRV_QPNP=y
CONFIG_SPS=y
+CONFIG_USB_BAM=y
CONFIG_SPS_SUPPORT_BAMDMA=y
CONFIG_SPS_SUPPORT_NDP_BAM=y
CONFIG_VFAT_FS=y
@@ -134,3 +146,11 @@
# 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/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c
index ff2c0ad..1692129 100644
--- a/arch/arm/kernel/hw_breakpoint.c
+++ b/arch/arm/kernel/hw_breakpoint.c
@@ -216,6 +216,20 @@
return core_has_mismatch_brps() ? brps - 1 : brps;
}
+/* Determine if halting mode is enabled */
+static int halting_mode_enabled(void)
+{
+ u32 dscr;
+
+ ARM_DBG_READ(c1, 0, dscr);
+
+ if (WARN_ONCE(dscr & ARM_DSCR_HDBGEN,
+ "halting debug mode enabled. "
+ "Unable to access hardware resources.\n"))
+ return -EPERM;
+ return 0;
+}
+
/*
* In order to access the breakpoint/watchpoint control registers,
* we must be running in debug monitor mode. Unfortunately, we can
@@ -225,16 +239,14 @@
static int enable_monitor_mode(void)
{
u32 dscr;
- int ret = 0;
+ int ret;
ARM_DBG_READ(c1, 0, dscr);
/* Ensure that halting mode is disabled. */
- if (WARN_ONCE(dscr & ARM_DSCR_HDBGEN,
- "halting debug mode enabled. Unable to access hardware resources.\n")) {
- ret = -EPERM;
+ ret = halting_mode_enabled();
+ if (ret)
goto out;
- }
/* If monitor mode is already enabled, just return. */
if (dscr & ARM_DSCR_MDBGEN)
@@ -853,18 +865,6 @@
return ret;
}
-static void reset_brps_reserved_reg(int n)
-{
- int i;
-
- /* we must also reset any reserved registers. */
- for (i = 0; i < n; ++i) {
- write_wb_reg(ARM_BASE_BCR + i, 0UL);
- write_wb_reg(ARM_BASE_BVR + i, 0UL);
- }
-
-}
-
/*
* One-time initialisation.
*/
@@ -947,19 +947,21 @@
isb();
reset_regs:
- if (enable_monitor_mode())
+ if (halting_mode_enabled())
return;
-#ifdef CONFIG_HAVE_HW_BRKPT_RESERVED_RW_ACCESS
- reset_brps_reserved_reg(core_num_brps);
-#else
- reset_brps_reserved_reg(core_num_brps + core_num_reserved_brps);
-#endif
+ /* We must also reset any reserved registers. */
+ raw_num_brps = get_num_brp_resources();
+ for (i = 0; i < raw_num_brps; ++i) {
+ write_wb_reg(ARM_BASE_BCR + i, 0UL);
+ write_wb_reg(ARM_BASE_BVR + i, 0UL);
+ }
for (i = 0; i < core_num_wrps; ++i) {
write_wb_reg(ARM_BASE_WCR + i, 0UL);
write_wb_reg(ARM_BASE_WVR + i, 0UL);
}
+ enable_monitor_mode();
}
static int __cpuinit dbg_reset_notify(struct notifier_block *self,
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 6df6e13..a551d3c 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -357,6 +357,8 @@
select MSM_GPIOMUX
select MULTI_IRQ_HANDLER
select GPIO_MSM_V3
+ select MAY_HAVE_SPARSE_IRQ
+ select SPARSE_IRQ
endmenu
choice
@@ -410,7 +412,6 @@
select HAVE_ARCH_HAS_CURRENT_TIMER
select MSM_JTAG if MSM_QDSS
bool
- select HAVE_HW_BRKPT_RESERVED_RW_ACCESS
config ARCH_MSM_CORTEXMP
select MSM_SMP
@@ -424,7 +425,6 @@
config ARCH_MSM_CORTEX_A5
bool
- select HAVE_HW_BRKPT_RESERVED_RW_ACCESS
config ARCH_MSM7X27A
bool
@@ -927,7 +927,7 @@
default "0x00000000" if ARCH_MPQ8092
default "0x00000000" if ARCH_MSM8226
default "0x10000000" if ARCH_FSM9XXX
- default "0x20200000" if ARCH_MSM9625
+ default "0x00200000" if ARCH_MSM9625
default "0x00200000" if !MSM_STACKED_MEMORY
default "0x00000000" if ARCH_QSD8X50 && MSM_SOC_REV_A
default "0x20000000" if ARCH_QSD8X50
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 3c44a06..a2151d5 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -274,7 +274,7 @@
obj-$(CONFIG_MACH_MSM8930_CDP) += board-8930-all.o board-8930-regulator-pm8038.o board-8930-regulator-pm8917.o
obj-$(CONFIG_MACH_MSM8930_MTP) += board-8930-all.o board-8930-regulator-pm8038.o board-8930-regulator-pm8917.o
obj-$(CONFIG_MACH_MSM8930_FLUID) += board-8930-all.o board-8930-regulator-pm8038.o board-8930-regulator-pm8917.o
-obj-$(CONFIG_PM8921_BMS) += bms-batterydata.o bms-batterydata-desay.o
+obj-$(CONFIG_PM8921_BMS) += bms-batterydata.o bms-batterydata-desay.o batterydata-lib.o
obj-$(CONFIG_MACH_APQ8064_CDP) += board-8064-all.o board-8064-regulator.o
obj-$(CONFIG_MACH_APQ8064_MTP) += board-8064-all.o board-8064-regulator.o
obj-$(CONFIG_MACH_APQ8064_LIQUID) += board-8064-all.o board-8064-regulator.o
@@ -288,6 +288,7 @@
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
diff --git a/arch/arm/mach-msm/Makefile.boot b/arch/arm/mach-msm/Makefile.boot
index 526616a..9234b2c 100644
--- a/arch/arm/mach-msm/Makefile.boot
+++ b/arch/arm/mach-msm/Makefile.boot
@@ -52,7 +52,7 @@
zreladdr-$(CONFIG_ARCH_MSM9615) := 0x40808000
# MSM9625
- zreladdr-$(CONFIG_ARCH_MSM9625) := 0x20208000
+ zreladdr-$(CONFIG_ARCH_MSM9625) := 0x00208000
# MSM8226
zreladdr-$(CONFIG_ARCH_MSM8226) := 0x00008000
diff --git a/arch/arm/mach-msm/acpuclock-7627.c b/arch/arm/mach-msm/acpuclock-7627.c
index 6788cbe..5c4a923 100644
--- a/arch/arm/mach-msm/acpuclock-7627.c
+++ b/arch/arm/mach-msm/acpuclock-7627.c
@@ -719,6 +719,7 @@
*/
clk_enable(pll_clk[backup_s->pll].clk);
acpuclk_set_div(backup_s);
+ update_jiffies(cpu, backup_s->lpj);
}
/* Make sure PLL4 is off before reprogramming */
if ((plls_enabled & (1 << tgt_s->pll))) {
@@ -736,6 +737,7 @@
*/
clk_enable(pll_clk[backup_s->pll].clk);
acpuclk_set_div(backup_s);
+ update_jiffies(cpu, backup_s->lpj);
}
}
diff --git a/arch/arm/mach-msm/acpuclock-8064.c b/arch/arm/mach-msm/acpuclock-8064.c
index 06c2579..d0de62b 100644
--- a/arch/arm/mach-msm/acpuclock-8064.c
+++ b/arch/arm/mach-msm/acpuclock-8064.c
@@ -44,6 +44,7 @@
.hfpll_phys_base = 0x00903200,
.aux_clk_sel_phys = 0x02088014,
.aux_clk_sel = 3,
+ .sec_clk_sel = 2,
.l2cpmr_iaddr = 0x4501,
.vreg[VREG_CORE] = { "krait0", 1300000 },
.vreg[VREG_MEM] = { "krait0_mem", 1150000 },
@@ -54,6 +55,7 @@
.hfpll_phys_base = 0x00903240,
.aux_clk_sel_phys = 0x02098014,
.aux_clk_sel = 3,
+ .sec_clk_sel = 2,
.l2cpmr_iaddr = 0x5501,
.vreg[VREG_CORE] = { "krait1", 1300000 },
.vreg[VREG_MEM] = { "krait1_mem", 1150000 },
@@ -64,6 +66,7 @@
.hfpll_phys_base = 0x00903280,
.aux_clk_sel_phys = 0x020A8014,
.aux_clk_sel = 3,
+ .sec_clk_sel = 2,
.l2cpmr_iaddr = 0x6501,
.vreg[VREG_CORE] = { "krait2", 1300000 },
.vreg[VREG_MEM] = { "krait2_mem", 1150000 },
@@ -74,6 +77,7 @@
.hfpll_phys_base = 0x009032C0,
.aux_clk_sel_phys = 0x020B8014,
.aux_clk_sel = 3,
+ .sec_clk_sel = 2,
.l2cpmr_iaddr = 0x7501,
.vreg[VREG_CORE] = { "krait3", 1300000 },
.vreg[VREG_MEM] = { "krait3_mem", 1150000 },
@@ -84,6 +88,7 @@
.hfpll_phys_base = 0x00903300,
.aux_clk_sel_phys = 0x02011028,
.aux_clk_sel = 3,
+ .sec_clk_sel = 2,
.l2cpmr_iaddr = 0x0500,
.vreg[VREG_HFPLL_A] = { "l2_hfpll", 1800000 },
},
@@ -106,100 +111,100 @@
};
static struct l2_level l2_freq_tbl[] __initdata __initdata = {
- [0] = { { 384000, PLL_8, 0, 2, 0x00 }, 1050000, 1050000, 1 },
- [1] = { { 432000, HFPLL, 2, 0, 0x20 }, 1050000, 1050000, 2 },
- [2] = { { 486000, HFPLL, 2, 0, 0x24 }, 1050000, 1050000, 2 },
- [3] = { { 540000, HFPLL, 2, 0, 0x28 }, 1050000, 1050000, 2 },
- [4] = { { 594000, HFPLL, 1, 0, 0x16 }, 1050000, 1050000, 2 },
- [5] = { { 648000, HFPLL, 1, 0, 0x18 }, 1050000, 1050000, 4 },
- [6] = { { 702000, HFPLL, 1, 0, 0x1A }, 1050000, 1050000, 4 },
- [7] = { { 756000, HFPLL, 1, 0, 0x1C }, 1150000, 1150000, 4 },
- [8] = { { 810000, HFPLL, 1, 0, 0x1E }, 1150000, 1150000, 4 },
- [9] = { { 864000, HFPLL, 1, 0, 0x20 }, 1150000, 1150000, 4 },
- [10] = { { 918000, HFPLL, 1, 0, 0x22 }, 1150000, 1150000, 5 },
- [11] = { { 972000, HFPLL, 1, 0, 0x24 }, 1150000, 1150000, 5 },
- [12] = { { 1026000, HFPLL, 1, 0, 0x26 }, 1150000, 1150000, 5 },
- [13] = { { 1080000, HFPLL, 1, 0, 0x28 }, 1150000, 1150000, 5 },
- [14] = { { 1134000, HFPLL, 1, 0, 0x2A }, 1150000, 1150000, 5 },
- [15] = { { 1188000, HFPLL, 1, 0, 0x2C }, 1150000, 1150000, 5 },
+ [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 },
+ [3] = { { 540000, HFPLL, 2, 0x28 }, 1050000, 1050000, 2 },
+ [4] = { { 594000, HFPLL, 1, 0x16 }, 1050000, 1050000, 2 },
+ [5] = { { 648000, HFPLL, 1, 0x18 }, 1050000, 1050000, 4 },
+ [6] = { { 702000, HFPLL, 1, 0x1A }, 1050000, 1050000, 4 },
+ [7] = { { 756000, HFPLL, 1, 0x1C }, 1150000, 1150000, 4 },
+ [8] = { { 810000, HFPLL, 1, 0x1E }, 1150000, 1150000, 4 },
+ [9] = { { 864000, HFPLL, 1, 0x20 }, 1150000, 1150000, 4 },
+ [10] = { { 918000, HFPLL, 1, 0x22 }, 1150000, 1150000, 5 },
+ [11] = { { 972000, HFPLL, 1, 0x24 }, 1150000, 1150000, 5 },
+ [12] = { { 1026000, HFPLL, 1, 0x26 }, 1150000, 1150000, 5 },
+ [13] = { { 1080000, HFPLL, 1, 0x28 }, 1150000, 1150000, 5 },
+ [14] = { { 1134000, HFPLL, 1, 0x2A }, 1150000, 1150000, 5 },
+ [15] = { { 1188000, HFPLL, 1, 0x2C }, 1150000, 1150000, 5 },
{ }
};
static struct acpu_level acpu_freq_tbl_slow[] __initdata = {
- { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(0), 950000 },
- { 0, { 432000, HFPLL, 2, 0, 0x20 }, L2(6), 975000 },
- { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(6), 975000 },
- { 0, { 540000, HFPLL, 2, 0, 0x28 }, L2(6), 1000000 },
- { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(6), 1000000 },
- { 0, { 648000, HFPLL, 1, 0, 0x18 }, L2(6), 1025000 },
- { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(6), 1025000 },
- { 0, { 756000, HFPLL, 1, 0, 0x1C }, L2(6), 1075000 },
- { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(6), 1075000 },
- { 0, { 864000, HFPLL, 1, 0, 0x20 }, L2(6), 1100000 },
- { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(6), 1100000 },
- { 0, { 972000, HFPLL, 1, 0, 0x24 }, L2(6), 1125000 },
- { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(6), 1125000 },
- { 0, { 1080000, HFPLL, 1, 0, 0x28 }, L2(15), 1175000 },
- { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(15), 1175000 },
- { 0, { 1188000, HFPLL, 1, 0, 0x2C }, L2(15), 1200000 },
- { 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(15), 1200000 },
- { 0, { 1296000, HFPLL, 1, 0, 0x30 }, L2(15), 1225000 },
- { 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(15), 1225000 },
- { 0, { 1404000, HFPLL, 1, 0, 0x34 }, L2(15), 1237500 },
- { 1, { 1458000, HFPLL, 1, 0, 0x36 }, L2(15), 1237500 },
- { 1, { 1512000, HFPLL, 1, 0, 0x38 }, L2(15), 1250000 },
+ { 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 },
{ 0, { 0 } }
};
static struct acpu_level acpu_freq_tbl_nom[] __initdata = {
- { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(0), 900000 },
- { 0, { 432000, HFPLL, 2, 0, 0x20 }, L2(6), 925000 },
- { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(6), 925000 },
- { 0, { 540000, HFPLL, 2, 0, 0x28 }, L2(6), 950000 },
- { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(6), 950000 },
- { 0, { 648000, HFPLL, 1, 0, 0x18 }, L2(6), 975000 },
- { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(6), 975000 },
- { 0, { 756000, HFPLL, 1, 0, 0x1C }, L2(6), 1025000 },
- { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(6), 1025000 },
- { 0, { 864000, HFPLL, 1, 0, 0x20 }, L2(6), 1050000 },
- { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(6), 1050000 },
- { 0, { 972000, HFPLL, 1, 0, 0x24 }, L2(6), 1075000 },
- { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(6), 1075000 },
- { 0, { 1080000, HFPLL, 1, 0, 0x28 }, L2(15), 1125000 },
- { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(15), 1125000 },
- { 0, { 1188000, HFPLL, 1, 0, 0x2C }, L2(15), 1150000 },
- { 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(15), 1150000 },
- { 0, { 1296000, HFPLL, 1, 0, 0x30 }, L2(15), 1175000 },
- { 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(15), 1175000 },
- { 0, { 1404000, HFPLL, 1, 0, 0x34 }, L2(15), 1187500 },
- { 1, { 1458000, HFPLL, 1, 0, 0x36 }, L2(15), 1187500 },
- { 1, { 1512000, HFPLL, 1, 0, 0x38 }, L2(15), 1200000 },
+ { 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 },
+ { 0, { 540000, HFPLL, 2, 0x28 }, L2(6), 950000 },
+ { 1, { 594000, HFPLL, 1, 0x16 }, L2(6), 950000 },
+ { 0, { 648000, HFPLL, 1, 0x18 }, L2(6), 975000 },
+ { 1, { 702000, HFPLL, 1, 0x1A }, L2(6), 975000 },
+ { 0, { 756000, HFPLL, 1, 0x1C }, L2(6), 1025000 },
+ { 1, { 810000, HFPLL, 1, 0x1E }, L2(6), 1025000 },
+ { 0, { 864000, HFPLL, 1, 0x20 }, L2(6), 1050000 },
+ { 1, { 918000, HFPLL, 1, 0x22 }, L2(6), 1050000 },
+ { 0, { 972000, HFPLL, 1, 0x24 }, L2(6), 1075000 },
+ { 1, { 1026000, HFPLL, 1, 0x26 }, L2(6), 1075000 },
+ { 0, { 1080000, HFPLL, 1, 0x28 }, L2(15), 1125000 },
+ { 1, { 1134000, HFPLL, 1, 0x2A }, L2(15), 1125000 },
+ { 0, { 1188000, HFPLL, 1, 0x2C }, L2(15), 1150000 },
+ { 1, { 1242000, HFPLL, 1, 0x2E }, L2(15), 1150000 },
+ { 0, { 1296000, HFPLL, 1, 0x30 }, L2(15), 1175000 },
+ { 1, { 1350000, HFPLL, 1, 0x32 }, L2(15), 1175000 },
+ { 0, { 1404000, HFPLL, 1, 0x34 }, L2(15), 1187500 },
+ { 1, { 1458000, HFPLL, 1, 0x36 }, L2(15), 1187500 },
+ { 1, { 1512000, HFPLL, 1, 0x38 }, L2(15), 1200000 },
{ 0, { 0 } }
};
static struct acpu_level acpu_freq_tbl_fast[] __initdata = {
- { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(0), 850000 },
- { 0, { 432000, HFPLL, 2, 0, 0x20 }, L2(6), 875000 },
- { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(6), 875000 },
- { 0, { 540000, HFPLL, 2, 0, 0x28 }, L2(6), 900000 },
- { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(6), 900000 },
- { 0, { 648000, HFPLL, 1, 0, 0x18 }, L2(6), 925000 },
- { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(6), 925000 },
- { 0, { 756000, HFPLL, 1, 0, 0x1C }, L2(6), 975000 },
- { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(6), 975000 },
- { 0, { 864000, HFPLL, 1, 0, 0x20 }, L2(6), 1000000 },
- { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(6), 1000000 },
- { 0, { 972000, HFPLL, 1, 0, 0x24 }, L2(6), 1025000 },
- { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(6), 1025000 },
- { 0, { 1080000, HFPLL, 1, 0, 0x28 }, L2(15), 1075000 },
- { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(15), 1075000 },
- { 0, { 1188000, HFPLL, 1, 0, 0x2C }, L2(15), 1100000 },
- { 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(15), 1100000 },
- { 0, { 1296000, HFPLL, 1, 0, 0x30 }, L2(15), 1125000 },
- { 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(15), 1125000 },
- { 0, { 1404000, HFPLL, 1, 0, 0x34 }, L2(15), 1137500 },
- { 1, { 1458000, HFPLL, 1, 0, 0x36 }, L2(15), 1137500 },
- { 1, { 1512000, HFPLL, 1, 0, 0x38 }, L2(15), 1150000 },
+ { 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 },
+ { 0, { 540000, HFPLL, 2, 0x28 }, L2(6), 900000 },
+ { 1, { 594000, HFPLL, 1, 0x16 }, L2(6), 900000 },
+ { 0, { 648000, HFPLL, 1, 0x18 }, L2(6), 925000 },
+ { 1, { 702000, HFPLL, 1, 0x1A }, L2(6), 925000 },
+ { 0, { 756000, HFPLL, 1, 0x1C }, L2(6), 975000 },
+ { 1, { 810000, HFPLL, 1, 0x1E }, L2(6), 975000 },
+ { 0, { 864000, HFPLL, 1, 0x20 }, L2(6), 1000000 },
+ { 1, { 918000, HFPLL, 1, 0x22 }, L2(6), 1000000 },
+ { 0, { 972000, HFPLL, 1, 0x24 }, L2(6), 1025000 },
+ { 1, { 1026000, HFPLL, 1, 0x26 }, L2(6), 1025000 },
+ { 0, { 1080000, HFPLL, 1, 0x28 }, L2(15), 1075000 },
+ { 1, { 1134000, HFPLL, 1, 0x2A }, L2(15), 1075000 },
+ { 0, { 1188000, HFPLL, 1, 0x2C }, L2(15), 1100000 },
+ { 1, { 1242000, HFPLL, 1, 0x2E }, L2(15), 1100000 },
+ { 0, { 1296000, HFPLL, 1, 0x30 }, L2(15), 1125000 },
+ { 1, { 1350000, HFPLL, 1, 0x32 }, L2(15), 1125000 },
+ { 0, { 1404000, HFPLL, 1, 0x34 }, L2(15), 1137500 },
+ { 1, { 1458000, HFPLL, 1, 0x36 }, L2(15), 1137500 },
+ { 1, { 1512000, HFPLL, 1, 0x38 }, L2(15), 1150000 },
{ 0, { 0 } }
};
diff --git a/arch/arm/mach-msm/acpuclock-8627.c b/arch/arm/mach-msm/acpuclock-8627.c
index 9e6662d..da49656 100644
--- a/arch/arm/mach-msm/acpuclock-8627.c
+++ b/arch/arm/mach-msm/acpuclock-8627.c
@@ -50,6 +50,7 @@
.hfpll_phys_base = 0x00903200,
.aux_clk_sel_phys = 0x02088014,
.aux_clk_sel = 3,
+ .sec_clk_sel = 2,
.l2cpmr_iaddr = 0x4501,
.vreg[VREG_CORE] = { "krait0", 1300000 },
.vreg[VREG_MEM] = { "krait0_mem", 1150000 },
@@ -60,6 +61,7 @@
.hfpll_phys_base = 0x00903300,
.aux_clk_sel_phys = 0x02098014,
.aux_clk_sel = 3,
+ .sec_clk_sel = 2,
.l2cpmr_iaddr = 0x5501,
.vreg[VREG_CORE] = { "krait1", 1300000 },
.vreg[VREG_MEM] = { "krait1_mem", 1150000 },
@@ -70,6 +72,7 @@
.hfpll_phys_base = 0x00903400,
.aux_clk_sel_phys = 0x02011028,
.aux_clk_sel = 3,
+ .sec_clk_sel = 2,
.l2cpmr_iaddr = 0x0500,
.vreg[VREG_HFPLL_A] = { "l2_hfpll", 1800000 },
},
@@ -92,35 +95,35 @@
/* TODO: Update vdd_dig, vdd_mem and bw when data is available. */
static struct l2_level l2_freq_tbl[] __initdata = {
- [0] = { { 384000, PLL_8, 0, 2, 0x00 }, LVL_NOM, 1050000, 1 },
- [1] = { { 432000, HFPLL, 2, 0, 0x20 }, LVL_NOM, 1050000, 1 },
- [2] = { { 486000, HFPLL, 2, 0, 0x24 }, LVL_NOM, 1050000, 1 },
- [3] = { { 540000, HFPLL, 2, 0, 0x28 }, LVL_NOM, 1050000, 2 },
- [4] = { { 594000, HFPLL, 1, 0, 0x16 }, LVL_NOM, 1050000, 2 },
- [5] = { { 648000, HFPLL, 1, 0, 0x18 }, LVL_NOM, 1050000, 2 },
- [6] = { { 702000, HFPLL, 1, 0, 0x1A }, LVL_NOM, 1050000, 3 },
- [7] = { { 756000, HFPLL, 1, 0, 0x1C }, LVL_HIGH, 1150000, 3 },
- [8] = { { 810000, HFPLL, 1, 0, 0x1E }, LVL_HIGH, 1150000, 3 },
- [9] = { { 864000, HFPLL, 1, 0, 0x20 }, LVL_HIGH, 1150000, 4 },
- [10] = { { 918000, HFPLL, 1, 0, 0x22 }, LVL_HIGH, 1150000, 4 },
- [11] = { { 972000, HFPLL, 1, 0, 0x24 }, LVL_HIGH, 1150000, 4 },
+ [0] = { { 384000, PLL_8, 0, 0x00 }, LVL_NOM, 1050000, 1 },
+ [1] = { { 432000, HFPLL, 2, 0x20 }, LVL_NOM, 1050000, 1 },
+ [2] = { { 486000, HFPLL, 2, 0x24 }, LVL_NOM, 1050000, 1 },
+ [3] = { { 540000, HFPLL, 2, 0x28 }, LVL_NOM, 1050000, 2 },
+ [4] = { { 594000, HFPLL, 1, 0x16 }, LVL_NOM, 1050000, 2 },
+ [5] = { { 648000, HFPLL, 1, 0x18 }, LVL_NOM, 1050000, 2 },
+ [6] = { { 702000, HFPLL, 1, 0x1A }, LVL_NOM, 1050000, 3 },
+ [7] = { { 756000, HFPLL, 1, 0x1C }, LVL_HIGH, 1150000, 3 },
+ [8] = { { 810000, HFPLL, 1, 0x1E }, LVL_HIGH, 1150000, 3 },
+ [9] = { { 864000, HFPLL, 1, 0x20 }, LVL_HIGH, 1150000, 4 },
+ [10] = { { 918000, HFPLL, 1, 0x22 }, LVL_HIGH, 1150000, 4 },
+ [11] = { { 972000, HFPLL, 1, 0x24 }, LVL_HIGH, 1150000, 4 },
{ }
};
/* TODO: Update core voltages when data is available. */
static struct acpu_level acpu_freq_tbl[] __initdata = {
- { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(0), 900000 },
- { 1, { 432000, HFPLL, 2, 0, 0x20 }, L2(4), 925000 },
- { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(4), 925000 },
- { 1, { 540000, HFPLL, 2, 0, 0x28 }, L2(4), 937500 },
- { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(4), 962500 },
- { 1, { 648000, HFPLL, 1, 0, 0x18 }, L2(8), 987500 },
- { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(8), 1000000 },
- { 1, { 756000, HFPLL, 1, 0, 0x1C }, L2(8), 1025000 },
- { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(8), 1062500 },
- { 1, { 864000, HFPLL, 1, 0, 0x20 }, L2(11), 1062500 },
- { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(11), 1087500 },
- { 1, { 972000, HFPLL, 1, 0, 0x24 }, L2(11), 1100000 },
+ { 1, { 384000, PLL_8, 0, 0x00 }, L2(0), 900000 },
+ { 1, { 432000, HFPLL, 2, 0x20 }, L2(4), 925000 },
+ { 1, { 486000, HFPLL, 2, 0x24 }, L2(4), 925000 },
+ { 1, { 540000, HFPLL, 2, 0x28 }, L2(4), 937500 },
+ { 1, { 594000, HFPLL, 1, 0x16 }, L2(4), 962500 },
+ { 1, { 648000, HFPLL, 1, 0x18 }, L2(8), 987500 },
+ { 1, { 702000, HFPLL, 1, 0x1A }, L2(8), 1000000 },
+ { 1, { 756000, HFPLL, 1, 0x1C }, L2(8), 1025000 },
+ { 1, { 810000, HFPLL, 1, 0x1E }, L2(8), 1062500 },
+ { 1, { 864000, HFPLL, 1, 0x20 }, L2(11), 1062500 },
+ { 1, { 918000, HFPLL, 1, 0x22 }, L2(11), 1087500 },
+ { 1, { 972000, HFPLL, 1, 0x24 }, L2(11), 1100000 },
{ 0, { 0 } }
};
diff --git a/arch/arm/mach-msm/acpuclock-8930.c b/arch/arm/mach-msm/acpuclock-8930.c
index b8ca865..b4f2a1e 100644
--- a/arch/arm/mach-msm/acpuclock-8930.c
+++ b/arch/arm/mach-msm/acpuclock-8930.c
@@ -50,6 +50,7 @@
.hfpll_phys_base = 0x00903200,
.aux_clk_sel_phys = 0x02088014,
.aux_clk_sel = 3,
+ .sec_clk_sel = 2,
.l2cpmr_iaddr = 0x4501,
.vreg[VREG_CORE] = { "krait0", 1300000 },
.vreg[VREG_MEM] = { "krait0_mem", 1150000 },
@@ -61,6 +62,7 @@
.hfpll_phys_base = 0x00903300,
.aux_clk_sel_phys = 0x02098014,
.aux_clk_sel = 3,
+ .sec_clk_sel = 2,
.l2cpmr_iaddr = 0x5501,
.vreg[VREG_CORE] = { "krait1", 1300000 },
.vreg[VREG_MEM] = { "krait1_mem", 1150000 },
@@ -72,6 +74,7 @@
.hfpll_phys_base = 0x00903400,
.aux_clk_sel_phys = 0x02011028,
.aux_clk_sel = 3,
+ .sec_clk_sel = 2,
.l2cpmr_iaddr = 0x0500,
.vreg[VREG_HFPLL_A] = { "l2_s8", 2050000 },
.vreg[VREG_HFPLL_B] = { "l2_l23", 1800000 },
@@ -83,6 +86,7 @@
.hfpll_phys_base = 0x00903200,
.aux_clk_sel_phys = 0x02088014,
.aux_clk_sel = 3,
+ .sec_clk_sel = 2,
.l2cpmr_iaddr = 0x4501,
.vreg[VREG_CORE] = { "krait0", 1300000 },
.vreg[VREG_MEM] = { "krait0_mem", 1150000 },
@@ -93,6 +97,7 @@
.hfpll_phys_base = 0x00903300,
.aux_clk_sel_phys = 0x02098014,
.aux_clk_sel = 3,
+ .sec_clk_sel = 2,
.l2cpmr_iaddr = 0x5501,
.vreg[VREG_CORE] = { "krait1", 1300000 },
.vreg[VREG_MEM] = { "krait1_mem", 1150000 },
@@ -103,6 +108,7 @@
.hfpll_phys_base = 0x00903400,
.aux_clk_sel_phys = 0x02011028,
.aux_clk_sel = 3,
+ .sec_clk_sel = 2,
.l2cpmr_iaddr = 0x0500,
.vreg[VREG_HFPLL_A] = { "l2_hfpll", 1800000 },
},
@@ -128,82 +134,82 @@
/* TODO: Update vdd_dig, vdd_mem and bw when data is available. */
static struct l2_level l2_freq_tbl[] __initdata = {
- [0] = { { 384000, PLL_8, 0, 2, 0x00 }, LVL_NOM, 1050000, 1 },
- [1] = { { 432000, HFPLL, 2, 0, 0x20 }, LVL_NOM, 1050000, 2 },
- [2] = { { 486000, HFPLL, 2, 0, 0x24 }, LVL_NOM, 1050000, 2 },
- [3] = { { 540000, HFPLL, 2, 0, 0x28 }, LVL_NOM, 1050000, 2 },
- [4] = { { 594000, HFPLL, 1, 0, 0x16 }, LVL_NOM, 1050000, 2 },
- [5] = { { 648000, HFPLL, 1, 0, 0x18 }, LVL_NOM, 1050000, 4 },
- [6] = { { 702000, HFPLL, 1, 0, 0x1A }, LVL_NOM, 1050000, 4 },
- [7] = { { 756000, HFPLL, 1, 0, 0x1C }, LVL_HIGH, 1150000, 4 },
- [8] = { { 810000, HFPLL, 1, 0, 0x1E }, LVL_HIGH, 1150000, 4 },
- [9] = { { 864000, HFPLL, 1, 0, 0x20 }, LVL_HIGH, 1150000, 4 },
- [10] = { { 918000, HFPLL, 1, 0, 0x22 }, LVL_HIGH, 1150000, 7 },
- [11] = { { 972000, HFPLL, 1, 0, 0x24 }, LVL_HIGH, 1150000, 7 },
- [12] = { { 1026000, HFPLL, 1, 0, 0x26 }, LVL_HIGH, 1150000, 7 },
- [13] = { { 1080000, HFPLL, 1, 0, 0x28 }, LVL_HIGH, 1150000, 7 },
- [14] = { { 1134000, HFPLL, 1, 0, 0x2A }, LVL_HIGH, 1150000, 7 },
- [15] = { { 1188000, HFPLL, 1, 0, 0x2C }, LVL_HIGH, 1150000, 7 },
+ [0] = { { 384000, PLL_8, 0, 0x00 }, LVL_NOM, 1050000, 1 },
+ [1] = { { 432000, HFPLL, 2, 0x20 }, LVL_NOM, 1050000, 2 },
+ [2] = { { 486000, HFPLL, 2, 0x24 }, LVL_NOM, 1050000, 2 },
+ [3] = { { 540000, HFPLL, 2, 0x28 }, LVL_NOM, 1050000, 2 },
+ [4] = { { 594000, HFPLL, 1, 0x16 }, LVL_NOM, 1050000, 2 },
+ [5] = { { 648000, HFPLL, 1, 0x18 }, LVL_NOM, 1050000, 4 },
+ [6] = { { 702000, HFPLL, 1, 0x1A }, LVL_NOM, 1050000, 4 },
+ [7] = { { 756000, HFPLL, 1, 0x1C }, LVL_HIGH, 1150000, 4 },
+ [8] = { { 810000, HFPLL, 1, 0x1E }, LVL_HIGH, 1150000, 4 },
+ [9] = { { 864000, HFPLL, 1, 0x20 }, LVL_HIGH, 1150000, 4 },
+ [10] = { { 918000, HFPLL, 1, 0x22 }, LVL_HIGH, 1150000, 7 },
+ [11] = { { 972000, HFPLL, 1, 0x24 }, LVL_HIGH, 1150000, 7 },
+ [12] = { { 1026000, HFPLL, 1, 0x26 }, LVL_HIGH, 1150000, 7 },
+ [13] = { { 1080000, HFPLL, 1, 0x28 }, LVL_HIGH, 1150000, 7 },
+ [14] = { { 1134000, HFPLL, 1, 0x2A }, LVL_HIGH, 1150000, 7 },
+ [15] = { { 1188000, HFPLL, 1, 0x2C }, LVL_HIGH, 1150000, 7 },
{ }
};
static struct acpu_level acpu_freq_tbl_slow[] __initdata = {
- { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(0), 950000 },
- { 1, { 432000, HFPLL, 2, 0, 0x20 }, L2(5), 975000 },
- { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(5), 975000 },
- { 1, { 540000, HFPLL, 2, 0, 0x28 }, L2(5), 1000000 },
- { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(5), 1000000 },
- { 1, { 648000, HFPLL, 1, 0, 0x18 }, L2(5), 1025000 },
- { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(5), 1025000 },
- { 1, { 756000, HFPLL, 1, 0, 0x1C }, L2(10), 1075000 },
- { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(10), 1075000 },
- { 1, { 864000, HFPLL, 1, 0, 0x20 }, L2(10), 1100000 },
- { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(10), 1100000 },
- { 1, { 972000, HFPLL, 1, 0, 0x24 }, L2(10), 1125000 },
- { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(10), 1125000 },
- { 1, { 1080000, HFPLL, 1, 0, 0x28 }, L2(15), 1175000 },
- { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(15), 1175000 },
- { 1, { 1188000, HFPLL, 1, 0, 0x2C }, L2(15), 1200000 },
+ { 1, { 384000, PLL_8, 0, 0x00 }, L2(0), 950000 },
+ { 1, { 432000, HFPLL, 2, 0x20 }, L2(5), 975000 },
+ { 1, { 486000, HFPLL, 2, 0x24 }, L2(5), 975000 },
+ { 1, { 540000, HFPLL, 2, 0x28 }, L2(5), 1000000 },
+ { 1, { 594000, HFPLL, 1, 0x16 }, L2(5), 1000000 },
+ { 1, { 648000, HFPLL, 1, 0x18 }, L2(5), 1025000 },
+ { 1, { 702000, HFPLL, 1, 0x1A }, L2(5), 1025000 },
+ { 1, { 756000, HFPLL, 1, 0x1C }, L2(10), 1075000 },
+ { 1, { 810000, HFPLL, 1, 0x1E }, L2(10), 1075000 },
+ { 1, { 864000, HFPLL, 1, 0x20 }, L2(10), 1100000 },
+ { 1, { 918000, HFPLL, 1, 0x22 }, L2(10), 1100000 },
+ { 1, { 972000, HFPLL, 1, 0x24 }, L2(10), 1125000 },
+ { 1, { 1026000, HFPLL, 1, 0x26 }, L2(10), 1125000 },
+ { 1, { 1080000, HFPLL, 1, 0x28 }, L2(15), 1175000 },
+ { 1, { 1134000, HFPLL, 1, 0x2A }, L2(15), 1175000 },
+ { 1, { 1188000, HFPLL, 1, 0x2C }, L2(15), 1200000 },
{ 0, { 0 } }
};
static struct acpu_level acpu_freq_tbl_nom[] __initdata = {
- { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(0), 925000 },
- { 1, { 432000, HFPLL, 2, 0, 0x20 }, L2(5), 950000 },
- { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(5), 950000 },
- { 1, { 540000, HFPLL, 2, 0, 0x28 }, L2(5), 975000 },
- { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(5), 975000 },
- { 1, { 648000, HFPLL, 1, 0, 0x18 }, L2(5), 1000000 },
- { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(5), 1000000 },
- { 1, { 756000, HFPLL, 1, 0, 0x1C }, L2(10), 1050000 },
- { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(10), 1050000 },
- { 1, { 864000, HFPLL, 1, 0, 0x20 }, L2(10), 1075000 },
- { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(10), 1075000 },
- { 1, { 972000, HFPLL, 1, 0, 0x24 }, L2(10), 1100000 },
- { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(10), 1100000 },
- { 1, { 1080000, HFPLL, 1, 0, 0x28 }, L2(15), 1150000 },
- { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(15), 1150000 },
- { 1, { 1188000, HFPLL, 1, 0, 0x2C }, L2(15), 1175000 },
+ { 1, { 384000, PLL_8, 0, 0x00 }, L2(0), 925000 },
+ { 1, { 432000, HFPLL, 2, 0x20 }, L2(5), 950000 },
+ { 1, { 486000, HFPLL, 2, 0x24 }, L2(5), 950000 },
+ { 1, { 540000, HFPLL, 2, 0x28 }, L2(5), 975000 },
+ { 1, { 594000, HFPLL, 1, 0x16 }, L2(5), 975000 },
+ { 1, { 648000, HFPLL, 1, 0x18 }, L2(5), 1000000 },
+ { 1, { 702000, HFPLL, 1, 0x1A }, L2(5), 1000000 },
+ { 1, { 756000, HFPLL, 1, 0x1C }, L2(10), 1050000 },
+ { 1, { 810000, HFPLL, 1, 0x1E }, L2(10), 1050000 },
+ { 1, { 864000, HFPLL, 1, 0x20 }, L2(10), 1075000 },
+ { 1, { 918000, HFPLL, 1, 0x22 }, L2(10), 1075000 },
+ { 1, { 972000, HFPLL, 1, 0x24 }, L2(10), 1100000 },
+ { 1, { 1026000, HFPLL, 1, 0x26 }, L2(10), 1100000 },
+ { 1, { 1080000, HFPLL, 1, 0x28 }, L2(15), 1150000 },
+ { 1, { 1134000, HFPLL, 1, 0x2A }, L2(15), 1150000 },
+ { 1, { 1188000, HFPLL, 1, 0x2C }, L2(15), 1175000 },
{ 0, { 0 } }
};
static struct acpu_level acpu_freq_tbl_fast[] __initdata = {
- { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(0), 900000 },
- { 1, { 432000, HFPLL, 2, 0, 0x20 }, L2(5), 900000 },
- { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(5), 900000 },
- { 1, { 540000, HFPLL, 2, 0, 0x28 }, L2(5), 925000 },
- { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(5), 925000 },
- { 1, { 648000, HFPLL, 1, 0, 0x18 }, L2(5), 950000 },
- { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(5), 950000 },
- { 1, { 756000, HFPLL, 1, 0, 0x1C }, L2(10), 1000000 },
- { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(10), 1000000 },
- { 1, { 864000, HFPLL, 1, 0, 0x20 }, L2(10), 1025000 },
- { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(10), 1025000 },
- { 1, { 972000, HFPLL, 1, 0, 0x24 }, L2(10), 1050000 },
- { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(10), 1050000 },
- { 1, { 1080000, HFPLL, 1, 0, 0x28 }, L2(15), 1100000 },
- { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(15), 1100000 },
- { 1, { 1188000, HFPLL, 1, 0, 0x2C }, L2(15), 1125000 },
+ { 1, { 384000, PLL_8, 0, 0x00 }, L2(0), 900000 },
+ { 1, { 432000, HFPLL, 2, 0x20 }, L2(5), 900000 },
+ { 1, { 486000, HFPLL, 2, 0x24 }, L2(5), 900000 },
+ { 1, { 540000, HFPLL, 2, 0x28 }, L2(5), 925000 },
+ { 1, { 594000, HFPLL, 1, 0x16 }, L2(5), 925000 },
+ { 1, { 648000, HFPLL, 1, 0x18 }, L2(5), 950000 },
+ { 1, { 702000, HFPLL, 1, 0x1A }, L2(5), 950000 },
+ { 1, { 756000, HFPLL, 1, 0x1C }, L2(10), 1000000 },
+ { 1, { 810000, HFPLL, 1, 0x1E }, L2(10), 1000000 },
+ { 1, { 864000, HFPLL, 1, 0x20 }, L2(10), 1025000 },
+ { 1, { 918000, HFPLL, 1, 0x22 }, L2(10), 1025000 },
+ { 1, { 972000, HFPLL, 1, 0x24 }, L2(10), 1050000 },
+ { 1, { 1026000, HFPLL, 1, 0x26 }, L2(10), 1050000 },
+ { 1, { 1080000, HFPLL, 1, 0x28 }, L2(15), 1100000 },
+ { 1, { 1134000, HFPLL, 1, 0x2A }, L2(15), 1100000 },
+ { 1, { 1188000, HFPLL, 1, 0x2C }, L2(15), 1125000 },
{ 0, { 0 } }
};
diff --git a/arch/arm/mach-msm/acpuclock-8930aa.c b/arch/arm/mach-msm/acpuclock-8930aa.c
index d589f1a..bcb00ea 100644
--- a/arch/arm/mach-msm/acpuclock-8930aa.c
+++ b/arch/arm/mach-msm/acpuclock-8930aa.c
@@ -50,6 +50,7 @@
.hfpll_phys_base = 0x00903200,
.aux_clk_sel_phys = 0x02088014,
.aux_clk_sel = 3,
+ .sec_clk_sel = 2,
.l2cpmr_iaddr = 0x4501,
.vreg[VREG_CORE] = { "krait0", 1300000 },
.vreg[VREG_MEM] = { "krait0_mem", 1150000 },
@@ -60,6 +61,7 @@
.hfpll_phys_base = 0x00903300,
.aux_clk_sel_phys = 0x02098014,
.aux_clk_sel = 3,
+ .sec_clk_sel = 2,
.l2cpmr_iaddr = 0x5501,
.vreg[VREG_CORE] = { "krait1", 1300000 },
.vreg[VREG_MEM] = { "krait1_mem", 1150000 },
@@ -70,6 +72,7 @@
.hfpll_phys_base = 0x00903400,
.aux_clk_sel_phys = 0x02011028,
.aux_clk_sel = 3,
+ .sec_clk_sel = 2,
.l2cpmr_iaddr = 0x0500,
.vreg[VREG_HFPLL_A] = { "l2_hfpll", 1800000 },
},
@@ -95,94 +98,94 @@
/* TODO: Update vdd_dig, vdd_mem and bw when data is available. */
static struct l2_level l2_freq_tbl[] __initdata = {
- [0] = { { 384000, PLL_8, 0, 2, 0x00 }, LVL_NOM, 1050000, 1 },
- [1] = { { 432000, HFPLL, 2, 0, 0x20 }, LVL_NOM, 1050000, 2 },
- [2] = { { 486000, HFPLL, 2, 0, 0x24 }, LVL_NOM, 1050000, 2 },
- [3] = { { 540000, HFPLL, 2, 0, 0x28 }, LVL_NOM, 1050000, 2 },
- [4] = { { 594000, HFPLL, 1, 0, 0x16 }, LVL_NOM, 1050000, 2 },
- [5] = { { 648000, HFPLL, 1, 0, 0x18 }, LVL_NOM, 1050000, 4 },
- [6] = { { 702000, HFPLL, 1, 0, 0x1A }, LVL_NOM, 1050000, 4 },
- [7] = { { 756000, HFPLL, 1, 0, 0x1C }, LVL_HIGH, 1150000, 4 },
- [8] = { { 810000, HFPLL, 1, 0, 0x1E }, LVL_HIGH, 1150000, 4 },
- [9] = { { 864000, HFPLL, 1, 0, 0x20 }, LVL_HIGH, 1150000, 4 },
- [10] = { { 918000, HFPLL, 1, 0, 0x22 }, LVL_HIGH, 1150000, 7 },
- [11] = { { 972000, HFPLL, 1, 0, 0x24 }, LVL_HIGH, 1150000, 7 },
- [12] = { { 1026000, HFPLL, 1, 0, 0x26 }, LVL_HIGH, 1150000, 7 },
- [13] = { { 1080000, HFPLL, 1, 0, 0x28 }, LVL_HIGH, 1150000, 7 },
- [14] = { { 1134000, HFPLL, 1, 0, 0x2A }, LVL_HIGH, 1150000, 7 },
- [15] = { { 1188000, HFPLL, 1, 0, 0x2C }, LVL_HIGH, 1150000, 7 },
+ [0] = { { 384000, PLL_8, 0, 0x00 }, LVL_NOM, 1050000, 1 },
+ [1] = { { 432000, HFPLL, 2, 0x20 }, LVL_NOM, 1050000, 2 },
+ [2] = { { 486000, HFPLL, 2, 0x24 }, LVL_NOM, 1050000, 2 },
+ [3] = { { 540000, HFPLL, 2, 0x28 }, LVL_NOM, 1050000, 2 },
+ [4] = { { 594000, HFPLL, 1, 0x16 }, LVL_NOM, 1050000, 2 },
+ [5] = { { 648000, HFPLL, 1, 0x18 }, LVL_NOM, 1050000, 4 },
+ [6] = { { 702000, HFPLL, 1, 0x1A }, LVL_NOM, 1050000, 4 },
+ [7] = { { 756000, HFPLL, 1, 0x1C }, LVL_HIGH, 1150000, 4 },
+ [8] = { { 810000, HFPLL, 1, 0x1E }, LVL_HIGH, 1150000, 4 },
+ [9] = { { 864000, HFPLL, 1, 0x20 }, LVL_HIGH, 1150000, 4 },
+ [10] = { { 918000, HFPLL, 1, 0x22 }, LVL_HIGH, 1150000, 7 },
+ [11] = { { 972000, HFPLL, 1, 0x24 }, LVL_HIGH, 1150000, 7 },
+ [12] = { { 1026000, HFPLL, 1, 0x26 }, LVL_HIGH, 1150000, 7 },
+ [13] = { { 1080000, HFPLL, 1, 0x28 }, LVL_HIGH, 1150000, 7 },
+ [14] = { { 1134000, HFPLL, 1, 0x2A }, LVL_HIGH, 1150000, 7 },
+ [15] = { { 1188000, HFPLL, 1, 0x2C }, LVL_HIGH, 1150000, 7 },
{ }
};
static struct acpu_level acpu_freq_tbl_slow[] __initdata = {
- { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(0), 950000 },
- { 1, { 432000, HFPLL, 2, 0, 0x20 }, L2(5), 975000 },
- { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(5), 975000 },
- { 1, { 540000, HFPLL, 2, 0, 0x28 }, L2(5), 1000000 },
- { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(5), 1000000 },
- { 1, { 648000, HFPLL, 1, 0, 0x18 }, L2(5), 1025000 },
- { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(5), 1025000 },
- { 1, { 756000, HFPLL, 1, 0, 0x1C }, L2(10), 1075000 },
- { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(10), 1075000 },
- { 1, { 864000, HFPLL, 1, 0, 0x20 }, L2(10), 1100000 },
- { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(10), 1100000 },
- { 1, { 972000, HFPLL, 1, 0, 0x24 }, L2(10), 1125000 },
- { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(10), 1125000 },
- { 1, { 1080000, HFPLL, 1, 0, 0x28 }, L2(15), 1175000 },
- { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(15), 1175000 },
- { 1, { 1188000, HFPLL, 1, 0, 0x2C }, L2(15), 1200000 },
- { 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(15), 1200000 },
- { 1, { 1296000, HFPLL, 1, 0, 0x30 }, L2(15), 1225000 },
- { 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(15), 1225000 },
- { 1, { 1404000, HFPLL, 1, 0, 0x34 }, L2(15), 1237500 },
+ { 1, { 384000, PLL_8, 0, 0x00 }, L2(0), 950000 },
+ { 1, { 432000, HFPLL, 2, 0x20 }, L2(5), 975000 },
+ { 1, { 486000, HFPLL, 2, 0x24 }, L2(5), 975000 },
+ { 1, { 540000, HFPLL, 2, 0x28 }, L2(5), 1000000 },
+ { 1, { 594000, HFPLL, 1, 0x16 }, L2(5), 1000000 },
+ { 1, { 648000, HFPLL, 1, 0x18 }, L2(5), 1025000 },
+ { 1, { 702000, HFPLL, 1, 0x1A }, L2(5), 1025000 },
+ { 1, { 756000, HFPLL, 1, 0x1C }, L2(10), 1075000 },
+ { 1, { 810000, HFPLL, 1, 0x1E }, L2(10), 1075000 },
+ { 1, { 864000, HFPLL, 1, 0x20 }, L2(10), 1100000 },
+ { 1, { 918000, HFPLL, 1, 0x22 }, L2(10), 1100000 },
+ { 1, { 972000, HFPLL, 1, 0x24 }, L2(10), 1125000 },
+ { 1, { 1026000, HFPLL, 1, 0x26 }, L2(10), 1125000 },
+ { 1, { 1080000, HFPLL, 1, 0x28 }, L2(15), 1175000 },
+ { 1, { 1134000, HFPLL, 1, 0x2A }, L2(15), 1175000 },
+ { 1, { 1188000, HFPLL, 1, 0x2C }, L2(15), 1200000 },
+ { 1, { 1242000, HFPLL, 1, 0x2E }, L2(15), 1200000 },
+ { 1, { 1296000, HFPLL, 1, 0x30 }, L2(15), 1225000 },
+ { 1, { 1350000, HFPLL, 1, 0x32 }, L2(15), 1225000 },
+ { 1, { 1404000, HFPLL, 1, 0x34 }, L2(15), 1237500 },
{ 0, { 0 } }
};
static struct acpu_level acpu_freq_tbl_nom[] __initdata = {
- { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(0), 925000 },
- { 1, { 432000, HFPLL, 2, 0, 0x20 }, L2(5), 950000 },
- { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(5), 950000 },
- { 1, { 540000, HFPLL, 2, 0, 0x28 }, L2(5), 975000 },
- { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(5), 975000 },
- { 1, { 648000, HFPLL, 1, 0, 0x18 }, L2(5), 1000000 },
- { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(5), 1000000 },
- { 1, { 756000, HFPLL, 1, 0, 0x1C }, L2(10), 1050000 },
- { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(10), 1050000 },
- { 1, { 864000, HFPLL, 1, 0, 0x20 }, L2(10), 1075000 },
- { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(10), 1075000 },
- { 1, { 972000, HFPLL, 1, 0, 0x24 }, L2(10), 1100000 },
- { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(10), 1100000 },
- { 1, { 1080000, HFPLL, 1, 0, 0x28 }, L2(15), 1150000 },
- { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(15), 1150000 },
- { 1, { 1188000, HFPLL, 1, 0, 0x2C }, L2(15), 1175000 },
- { 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(15), 1175000 },
- { 1, { 1296000, HFPLL, 1, 0, 0x30 }, L2(15), 1200000 },
- { 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(15), 1200000 },
- { 1, { 1404000, HFPLL, 1, 0, 0x34 }, L2(15), 1212500 },
+ { 1, { 384000, PLL_8, 0, 0x00 }, L2(0), 925000 },
+ { 1, { 432000, HFPLL, 2, 0x20 }, L2(5), 950000 },
+ { 1, { 486000, HFPLL, 2, 0x24 }, L2(5), 950000 },
+ { 1, { 540000, HFPLL, 2, 0x28 }, L2(5), 975000 },
+ { 1, { 594000, HFPLL, 1, 0x16 }, L2(5), 975000 },
+ { 1, { 648000, HFPLL, 1, 0x18 }, L2(5), 1000000 },
+ { 1, { 702000, HFPLL, 1, 0x1A }, L2(5), 1000000 },
+ { 1, { 756000, HFPLL, 1, 0x1C }, L2(10), 1050000 },
+ { 1, { 810000, HFPLL, 1, 0x1E }, L2(10), 1050000 },
+ { 1, { 864000, HFPLL, 1, 0x20 }, L2(10), 1075000 },
+ { 1, { 918000, HFPLL, 1, 0x22 }, L2(10), 1075000 },
+ { 1, { 972000, HFPLL, 1, 0x24 }, L2(10), 1100000 },
+ { 1, { 1026000, HFPLL, 1, 0x26 }, L2(10), 1100000 },
+ { 1, { 1080000, HFPLL, 1, 0x28 }, L2(15), 1150000 },
+ { 1, { 1134000, HFPLL, 1, 0x2A }, L2(15), 1150000 },
+ { 1, { 1188000, HFPLL, 1, 0x2C }, L2(15), 1175000 },
+ { 1, { 1242000, HFPLL, 1, 0x2E }, L2(15), 1175000 },
+ { 1, { 1296000, HFPLL, 1, 0x30 }, L2(15), 1200000 },
+ { 1, { 1350000, HFPLL, 1, 0x32 }, L2(15), 1200000 },
+ { 1, { 1404000, HFPLL, 1, 0x34 }, L2(15), 1212500 },
{ 0, { 0 } }
};
static struct acpu_level acpu_freq_tbl_fast[] __initdata = {
- { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(0), 900000 },
- { 1, { 432000, HFPLL, 2, 0, 0x20 }, L2(5), 900000 },
- { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(5), 900000 },
- { 1, { 540000, HFPLL, 2, 0, 0x28 }, L2(5), 925000 },
- { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(5), 925000 },
- { 1, { 648000, HFPLL, 1, 0, 0x18 }, L2(5), 950000 },
- { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(5), 950000 },
- { 1, { 756000, HFPLL, 1, 0, 0x1C }, L2(10), 1000000 },
- { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(10), 1000000 },
- { 1, { 864000, HFPLL, 1, 0, 0x20 }, L2(10), 1025000 },
- { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(10), 1025000 },
- { 1, { 972000, HFPLL, 1, 0, 0x24 }, L2(10), 1050000 },
- { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(10), 1050000 },
- { 1, { 1080000, HFPLL, 1, 0, 0x28 }, L2(15), 1100000 },
- { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(15), 1100000 },
- { 1, { 1188000, HFPLL, 1, 0, 0x2C }, L2(15), 1125000 },
- { 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(15), 1125000 },
- { 1, { 1296000, HFPLL, 1, 0, 0x30 }, L2(15), 1150000 },
- { 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(15), 1150000 },
- { 1, { 1404000, HFPLL, 1, 0, 0x34 }, L2(15), 1162500 },
+ { 1, { 384000, PLL_8, 0, 0x00 }, L2(0), 900000 },
+ { 1, { 432000, HFPLL, 2, 0x20 }, L2(5), 900000 },
+ { 1, { 486000, HFPLL, 2, 0x24 }, L2(5), 900000 },
+ { 1, { 540000, HFPLL, 2, 0x28 }, L2(5), 925000 },
+ { 1, { 594000, HFPLL, 1, 0x16 }, L2(5), 925000 },
+ { 1, { 648000, HFPLL, 1, 0x18 }, L2(5), 950000 },
+ { 1, { 702000, HFPLL, 1, 0x1A }, L2(5), 950000 },
+ { 1, { 756000, HFPLL, 1, 0x1C }, L2(10), 1000000 },
+ { 1, { 810000, HFPLL, 1, 0x1E }, L2(10), 1000000 },
+ { 1, { 864000, HFPLL, 1, 0x20 }, L2(10), 1025000 },
+ { 1, { 918000, HFPLL, 1, 0x22 }, L2(10), 1025000 },
+ { 1, { 972000, HFPLL, 1, 0x24 }, L2(10), 1050000 },
+ { 1, { 1026000, HFPLL, 1, 0x26 }, L2(10), 1050000 },
+ { 1, { 1080000, HFPLL, 1, 0x28 }, L2(15), 1100000 },
+ { 1, { 1134000, HFPLL, 1, 0x2A }, L2(15), 1100000 },
+ { 1, { 1188000, HFPLL, 1, 0x2C }, L2(15), 1125000 },
+ { 1, { 1242000, HFPLL, 1, 0x2E }, L2(15), 1125000 },
+ { 1, { 1296000, HFPLL, 1, 0x30 }, L2(15), 1150000 },
+ { 1, { 1350000, HFPLL, 1, 0x32 }, L2(15), 1150000 },
+ { 1, { 1404000, HFPLL, 1, 0x34 }, L2(15), 1162500 },
{ 0, { 0 } }
};
diff --git a/arch/arm/mach-msm/acpuclock-8960.c b/arch/arm/mach-msm/acpuclock-8960.c
index e16c6b6..cf6a6c2 100644
--- a/arch/arm/mach-msm/acpuclock-8960.c
+++ b/arch/arm/mach-msm/acpuclock-8960.c
@@ -44,6 +44,7 @@
.hfpll_phys_base = 0x00903200,
.aux_clk_sel_phys = 0x02088014,
.aux_clk_sel = 3,
+ .sec_clk_sel = 2,
.l2cpmr_iaddr = 0x4501,
.vreg[VREG_CORE] = { "krait0", 1300000 },
.vreg[VREG_MEM] = { "krait0_mem", 1150000 },
@@ -55,6 +56,7 @@
.hfpll_phys_base = 0x00903300,
.aux_clk_sel_phys = 0x02098014,
.aux_clk_sel = 3,
+ .sec_clk_sel = 2,
.l2cpmr_iaddr = 0x5501,
.vreg[VREG_CORE] = { "krait1", 1300000 },
.vreg[VREG_MEM] = { "krait1_mem", 1150000 },
@@ -66,6 +68,7 @@
.hfpll_phys_base = 0x00903400,
.aux_clk_sel_phys = 0x02011028,
.aux_clk_sel = 3,
+ .sec_clk_sel = 2,
.l2cpmr_iaddr = 0x0500,
.vreg[VREG_HFPLL_A] = { "l2_s8", 2050000 },
.vreg[VREG_HFPLL_B] = { "l2_l23", 1800000 },
@@ -90,105 +93,105 @@
};
static struct l2_level l2_freq_tbl[] __initdata = {
- [0] = { { 384000, PLL_8, 0, 2, 0x00 }, 1050000, 1050000, 1 },
- [1] = { { 432000, HFPLL, 2, 0, 0x20 }, 1050000, 1050000, 2 },
- [2] = { { 486000, HFPLL, 2, 0, 0x24 }, 1050000, 1050000, 2 },
- [3] = { { 540000, HFPLL, 2, 0, 0x28 }, 1050000, 1050000, 2 },
- [4] = { { 594000, HFPLL, 1, 0, 0x16 }, 1050000, 1050000, 2 },
- [5] = { { 648000, HFPLL, 1, 0, 0x18 }, 1050000, 1050000, 4 },
- [6] = { { 702000, HFPLL, 1, 0, 0x1A }, 1050000, 1050000, 4 },
- [7] = { { 756000, HFPLL, 1, 0, 0x1C }, 1150000, 1150000, 4 },
- [8] = { { 810000, HFPLL, 1, 0, 0x1E }, 1150000, 1150000, 4 },
- [9] = { { 864000, HFPLL, 1, 0, 0x20 }, 1150000, 1150000, 4 },
- [10] = { { 918000, HFPLL, 1, 0, 0x22 }, 1150000, 1150000, 6 },
- [11] = { { 972000, HFPLL, 1, 0, 0x24 }, 1150000, 1150000, 6 },
- [12] = { { 1026000, HFPLL, 1, 0, 0x26 }, 1150000, 1150000, 6 },
- [13] = { { 1080000, HFPLL, 1, 0, 0x28 }, 1150000, 1150000, 6 },
- [14] = { { 1134000, HFPLL, 1, 0, 0x2A }, 1150000, 1150000, 6 },
- [15] = { { 1188000, HFPLL, 1, 0, 0x2C }, 1150000, 1150000, 6 },
- [16] = { { 1242000, HFPLL, 1, 0, 0x2E }, 1150000, 1150000, 6 },
- [17] = { { 1296000, HFPLL, 1, 0, 0x30 }, 1150000, 1150000, 6 },
- [18] = { { 1350000, HFPLL, 1, 0, 0x32 }, 1150000, 1150000, 6 },
+ [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 },
+ [3] = { { 540000, HFPLL, 2, 0x28 }, 1050000, 1050000, 2 },
+ [4] = { { 594000, HFPLL, 1, 0x16 }, 1050000, 1050000, 2 },
+ [5] = { { 648000, HFPLL, 1, 0x18 }, 1050000, 1050000, 4 },
+ [6] = { { 702000, HFPLL, 1, 0x1A }, 1050000, 1050000, 4 },
+ [7] = { { 756000, HFPLL, 1, 0x1C }, 1150000, 1150000, 4 },
+ [8] = { { 810000, HFPLL, 1, 0x1E }, 1150000, 1150000, 4 },
+ [9] = { { 864000, HFPLL, 1, 0x20 }, 1150000, 1150000, 4 },
+ [10] = { { 918000, HFPLL, 1, 0x22 }, 1150000, 1150000, 6 },
+ [11] = { { 972000, HFPLL, 1, 0x24 }, 1150000, 1150000, 6 },
+ [12] = { { 1026000, HFPLL, 1, 0x26 }, 1150000, 1150000, 6 },
+ [13] = { { 1080000, HFPLL, 1, 0x28 }, 1150000, 1150000, 6 },
+ [14] = { { 1134000, HFPLL, 1, 0x2A }, 1150000, 1150000, 6 },
+ [15] = { { 1188000, HFPLL, 1, 0x2C }, 1150000, 1150000, 6 },
+ [16] = { { 1242000, HFPLL, 1, 0x2E }, 1150000, 1150000, 6 },
+ [17] = { { 1296000, HFPLL, 1, 0x30 }, 1150000, 1150000, 6 },
+ [18] = { { 1350000, HFPLL, 1, 0x32 }, 1150000, 1150000, 6 },
{ }
};
#define AVS(x) .avsdscr_setting = (x)
static struct acpu_level acpu_freq_tbl_slow[] __initdata = {
- { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(0), 950000, AVS(0x40001F) },
- { 0, { 432000, HFPLL, 2, 0, 0x20 }, L2(6), 975000 },
- { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(6), 975000 },
- { 0, { 540000, HFPLL, 2, 0, 0x28 }, L2(6), 1000000 },
- { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(6), 1000000 },
- { 0, { 648000, HFPLL, 1, 0, 0x18 }, L2(6), 1025000 },
- { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(6), 1025000 },
- { 0, { 756000, HFPLL, 1, 0, 0x1C }, L2(6), 1075000 },
- { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(6), 1075000 },
- { 0, { 864000, HFPLL, 1, 0, 0x20 }, L2(6), 1100000 },
- { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(6), 1100000 },
- { 0, { 972000, HFPLL, 1, 0, 0x24 }, L2(6), 1125000 },
- { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(6), 1125000 },
- { 0, { 1080000, HFPLL, 1, 0, 0x28 }, L2(18), 1175000, AVS(0x400015) },
- { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(18), 1175000, AVS(0x400015) },
- { 0, { 1188000, HFPLL, 1, 0, 0x2C }, L2(18), 1200000, AVS(0x400015) },
- { 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(18), 1200000, AVS(0x400015) },
- { 0, { 1296000, HFPLL, 1, 0, 0x30 }, L2(18), 1225000, AVS(0x400015) },
- { 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(18), 1225000, AVS(0x400015) },
- { 0, { 1404000, HFPLL, 1, 0, 0x34 }, L2(18), 1237500, AVS(0x400015) },
- { 1, { 1458000, HFPLL, 1, 0, 0x36 }, L2(18), 1237500, AVS(0x100018) },
- { 1, { 1512000, HFPLL, 1, 0, 0x38 }, L2(18), 1250000, AVS(0x400012) },
+ { 1, { 384000, PLL_8, 0, 0x00 }, L2(0), 950000, AVS(0x40001F) },
+ { 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(18), 1175000, AVS(0x400015) },
+ { 1, { 1134000, HFPLL, 1, 0x2A }, L2(18), 1175000, AVS(0x400015) },
+ { 0, { 1188000, HFPLL, 1, 0x2C }, L2(18), 1200000, AVS(0x400015) },
+ { 1, { 1242000, HFPLL, 1, 0x2E }, L2(18), 1200000, AVS(0x400015) },
+ { 0, { 1296000, HFPLL, 1, 0x30 }, L2(18), 1225000, AVS(0x400015) },
+ { 1, { 1350000, HFPLL, 1, 0x32 }, L2(18), 1225000, AVS(0x400015) },
+ { 0, { 1404000, HFPLL, 1, 0x34 }, L2(18), 1237500, AVS(0x400015) },
+ { 1, { 1458000, HFPLL, 1, 0x36 }, L2(18), 1237500, AVS(0x100018) },
+ { 1, { 1512000, HFPLL, 1, 0x38 }, L2(18), 1250000, AVS(0x400012) },
{ 0, { 0 } }
};
static struct acpu_level acpu_freq_tbl_nom[] __initdata = {
- { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(0), 900000, AVS(0x40007F) },
- { 0, { 432000, HFPLL, 2, 0, 0x20 }, L2(6), 925000 },
- { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(6), 925000 },
- { 0, { 540000, HFPLL, 2, 0, 0x28 }, L2(6), 950000 },
- { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(6), 950000 },
- { 0, { 648000, HFPLL, 1, 0, 0x18 }, L2(6), 975000 },
- { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(6), 975000 },
- { 0, { 756000, HFPLL, 1, 0, 0x1C }, L2(6), 1025000 },
- { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(6), 1025000 },
- { 0, { 864000, HFPLL, 1, 0, 0x20 }, L2(6), 1050000 },
- { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(6), 1050000 },
- { 0, { 972000, HFPLL, 1, 0, 0x24 }, L2(6), 1075000 },
- { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(6), 1075000 },
- { 0, { 1080000, HFPLL, 1, 0, 0x28 }, L2(18), 1125000, AVS(0x400015) },
- { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(18), 1125000, AVS(0x400015) },
- { 0, { 1188000, HFPLL, 1, 0, 0x2C }, L2(18), 1150000, AVS(0x400015) },
- { 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(18), 1150000, AVS(0x400015) },
- { 0, { 1296000, HFPLL, 1, 0, 0x30 }, L2(18), 1175000, AVS(0x400015) },
- { 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(18), 1175000, AVS(0x400015) },
- { 0, { 1404000, HFPLL, 1, 0, 0x34 }, L2(18), 1187500, AVS(0x400015) },
- { 1, { 1458000, HFPLL, 1, 0, 0x36 }, L2(18), 1187500, AVS(0x100018) },
- { 1, { 1512000, HFPLL, 1, 0, 0x38 }, L2(18), 1200000, AVS(0x400012) },
+ { 1, { 384000, PLL_8, 0, 0x00 }, L2(0), 900000, AVS(0x40007F) },
+ { 0, { 432000, HFPLL, 2, 0x20 }, L2(6), 925000 },
+ { 1, { 486000, HFPLL, 2, 0x24 }, L2(6), 925000 },
+ { 0, { 540000, HFPLL, 2, 0x28 }, L2(6), 950000 },
+ { 1, { 594000, HFPLL, 1, 0x16 }, L2(6), 950000 },
+ { 0, { 648000, HFPLL, 1, 0x18 }, L2(6), 975000 },
+ { 1, { 702000, HFPLL, 1, 0x1A }, L2(6), 975000 },
+ { 0, { 756000, HFPLL, 1, 0x1C }, L2(6), 1025000 },
+ { 1, { 810000, HFPLL, 1, 0x1E }, L2(6), 1025000 },
+ { 0, { 864000, HFPLL, 1, 0x20 }, L2(6), 1050000 },
+ { 1, { 918000, HFPLL, 1, 0x22 }, L2(6), 1050000 },
+ { 0, { 972000, HFPLL, 1, 0x24 }, L2(6), 1075000 },
+ { 1, { 1026000, HFPLL, 1, 0x26 }, L2(6), 1075000 },
+ { 0, { 1080000, HFPLL, 1, 0x28 }, L2(18), 1125000, AVS(0x400015) },
+ { 1, { 1134000, HFPLL, 1, 0x2A }, L2(18), 1125000, AVS(0x400015) },
+ { 0, { 1188000, HFPLL, 1, 0x2C }, L2(18), 1150000, AVS(0x400015) },
+ { 1, { 1242000, HFPLL, 1, 0x2E }, L2(18), 1150000, AVS(0x400015) },
+ { 0, { 1296000, HFPLL, 1, 0x30 }, L2(18), 1175000, AVS(0x400015) },
+ { 1, { 1350000, HFPLL, 1, 0x32 }, L2(18), 1175000, AVS(0x400015) },
+ { 0, { 1404000, HFPLL, 1, 0x34 }, L2(18), 1187500, AVS(0x400015) },
+ { 1, { 1458000, HFPLL, 1, 0x36 }, L2(18), 1187500, AVS(0x100018) },
+ { 1, { 1512000, HFPLL, 1, 0x38 }, L2(18), 1200000, AVS(0x400012) },
{ 0, { 0 } }
};
static struct acpu_level acpu_freq_tbl_fast[] __initdata = {
- { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(0), 850000, AVS(0x4000FF) },
- { 0, { 432000, HFPLL, 2, 0, 0x20 }, L2(6), 875000 },
- { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(6), 875000 },
- { 0, { 540000, HFPLL, 2, 0, 0x28 }, L2(6), 900000 },
- { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(6), 900000 },
- { 0, { 648000, HFPLL, 1, 0, 0x18 }, L2(6), 925000 },
- { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(6), 925000 },
- { 0, { 756000, HFPLL, 1, 0, 0x1C }, L2(6), 975000 },
- { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(6), 975000 },
- { 0, { 864000, HFPLL, 1, 0, 0x20 }, L2(6), 1000000 },
- { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(6), 1000000 },
- { 0, { 972000, HFPLL, 1, 0, 0x24 }, L2(6), 1025000 },
- { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(6), 1025000 },
- { 0, { 1080000, HFPLL, 1, 0, 0x28 }, L2(18), 1075000, AVS(0x10001B) },
- { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(18), 1075000, AVS(0x10001B) },
- { 0, { 1188000, HFPLL, 1, 0, 0x2C }, L2(18), 1100000, AVS(0x10001B) },
- { 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(18), 1100000, AVS(0x10001B) },
- { 0, { 1296000, HFPLL, 1, 0, 0x30 }, L2(18), 1125000, AVS(0x10001B) },
- { 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(18), 1125000, AVS(0x400012) },
- { 0, { 1404000, HFPLL, 1, 0, 0x34 }, L2(18), 1137500, AVS(0x400012) },
- { 1, { 1458000, HFPLL, 1, 0, 0x36 }, L2(18), 1137500, AVS(0x400012) },
- { 1, { 1512000, HFPLL, 1, 0, 0x38 }, L2(18), 1150000, AVS(0x400012) },
+ { 1, { 384000, PLL_8, 0, 0x00 }, L2(0), 850000, AVS(0x4000FF) },
+ { 0, { 432000, HFPLL, 2, 0x20 }, L2(6), 875000 },
+ { 1, { 486000, HFPLL, 2, 0x24 }, L2(6), 875000 },
+ { 0, { 540000, HFPLL, 2, 0x28 }, L2(6), 900000 },
+ { 1, { 594000, HFPLL, 1, 0x16 }, L2(6), 900000 },
+ { 0, { 648000, HFPLL, 1, 0x18 }, L2(6), 925000 },
+ { 1, { 702000, HFPLL, 1, 0x1A }, L2(6), 925000 },
+ { 0, { 756000, HFPLL, 1, 0x1C }, L2(6), 975000 },
+ { 1, { 810000, HFPLL, 1, 0x1E }, L2(6), 975000 },
+ { 0, { 864000, HFPLL, 1, 0x20 }, L2(6), 1000000 },
+ { 1, { 918000, HFPLL, 1, 0x22 }, L2(6), 1000000 },
+ { 0, { 972000, HFPLL, 1, 0x24 }, L2(6), 1025000 },
+ { 1, { 1026000, HFPLL, 1, 0x26 }, L2(6), 1025000 },
+ { 0, { 1080000, HFPLL, 1, 0x28 }, L2(18), 1075000, AVS(0x10001B) },
+ { 1, { 1134000, HFPLL, 1, 0x2A }, L2(18), 1075000, AVS(0x10001B) },
+ { 0, { 1188000, HFPLL, 1, 0x2C }, L2(18), 1100000, AVS(0x10001B) },
+ { 1, { 1242000, HFPLL, 1, 0x2E }, L2(18), 1100000, AVS(0x10001B) },
+ { 0, { 1296000, HFPLL, 1, 0x30 }, L2(18), 1125000, AVS(0x10001B) },
+ { 1, { 1350000, HFPLL, 1, 0x32 }, L2(18), 1125000, AVS(0x400012) },
+ { 0, { 1404000, HFPLL, 1, 0x34 }, L2(18), 1137500, AVS(0x400012) },
+ { 1, { 1458000, HFPLL, 1, 0x36 }, L2(18), 1137500, AVS(0x400012) },
+ { 1, { 1512000, HFPLL, 1, 0x38 }, L2(18), 1150000, AVS(0x400012) },
{ 0, { 0 } }
};
diff --git a/arch/arm/mach-msm/acpuclock-8960ab.c b/arch/arm/mach-msm/acpuclock-8960ab.c
index 628e1ba..91ccd37 100644
--- a/arch/arm/mach-msm/acpuclock-8960ab.c
+++ b/arch/arm/mach-msm/acpuclock-8960ab.c
@@ -44,6 +44,7 @@
.hfpll_phys_base = 0x00903200,
.aux_clk_sel_phys = 0x02088014,
.aux_clk_sel = 3,
+ .sec_clk_sel = 2,
.l2cpmr_iaddr = 0x4501,
.vreg[VREG_CORE] = { "krait0", 1300000 },
.vreg[VREG_MEM] = { "krait0_mem", 1150000 },
@@ -55,6 +56,7 @@
.hfpll_phys_base = 0x00903300,
.aux_clk_sel_phys = 0x02098014,
.aux_clk_sel = 3,
+ .sec_clk_sel = 2,
.l2cpmr_iaddr = 0x5501,
.vreg[VREG_CORE] = { "krait1", 1300000 },
.vreg[VREG_MEM] = { "krait1_mem", 1150000 },
@@ -66,6 +68,7 @@
.hfpll_phys_base = 0x00903400,
.aux_clk_sel_phys = 0x02011028,
.aux_clk_sel = 3,
+ .sec_clk_sel = 2,
.l2cpmr_iaddr = 0x0500,
.vreg[VREG_HFPLL_A] = { "l2_s8", 2050000 },
.vreg[VREG_HFPLL_B] = { "l2_l23", 1800000 },
@@ -89,46 +92,46 @@
};
static struct l2_level l2_freq_tbl[] __initdata = {
- [0] = { { 384000, PLL_8, 0, 2, 0x00 }, 1050000, 1050000, 1 },
- [1] = { { 486000, HFPLL, 2, 0, 0x24 }, 1050000, 1050000, 2 },
- [2] = { { 594000, HFPLL, 1, 0, 0x16 }, 1050000, 1050000, 2 },
- [3] = { { 702000, HFPLL, 1, 0, 0x1A }, 1050000, 1050000, 4 },
- [4] = { { 810000, HFPLL, 1, 0, 0x1E }, 1050000, 1050000, 4 },
- [5] = { { 918000, HFPLL, 1, 0, 0x22 }, 1150000, 1150000, 5 },
- [6] = { { 1026000, HFPLL, 1, 0, 0x26 }, 1150000, 1150000, 5 },
- [7] = { { 1134000, HFPLL, 1, 0, 0x2A }, 1150000, 1150000, 5 },
- [8] = { { 1242000, HFPLL, 1, 0, 0x2E }, 1150000, 1150000, 5 },
- [9] = { { 1350000, HFPLL, 1, 0, 0x32 }, 1150000, 1150000, 5 },
+ [0] = { { 384000, PLL_8, 0, 0x00 }, 1050000, 1050000, 1 },
+ [1] = { { 486000, HFPLL, 2, 0x24 }, 1050000, 1050000, 2 },
+ [2] = { { 594000, HFPLL, 1, 0x16 }, 1050000, 1050000, 2 },
+ [3] = { { 702000, HFPLL, 1, 0x1A }, 1050000, 1050000, 4 },
+ [4] = { { 810000, HFPLL, 1, 0x1E }, 1050000, 1050000, 4 },
+ [5] = { { 918000, HFPLL, 1, 0x22 }, 1150000, 1150000, 5 },
+ [6] = { { 1026000, HFPLL, 1, 0x26 }, 1150000, 1150000, 5 },
+ [7] = { { 1134000, HFPLL, 1, 0x2A }, 1150000, 1150000, 5 },
+ [8] = { { 1242000, HFPLL, 1, 0x2E }, 1150000, 1150000, 5 },
+ [9] = { { 1350000, HFPLL, 1, 0x32 }, 1150000, 1150000, 5 },
{ }
};
static struct acpu_level acpu_freq_tbl_slow[] __initdata = {
- { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(0), 950000 },
- { 0, { 432000, HFPLL, 2, 0, 0x20 }, L2(3), 975000 },
- { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(3), 975000 },
- { 0, { 540000, HFPLL, 2, 0, 0x28 }, L2(3), 1000000 },
- { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(3), 1000000 },
- { 0, { 648000, HFPLL, 1, 0, 0x18 }, L2(3), 1025000 },
- { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(3), 1025000 },
- { 0, { 756000, HFPLL, 1, 0, 0x1C }, L2(3), 1075000 },
- { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(3), 1075000 },
- { 0, { 864000, HFPLL, 1, 0, 0x20 }, L2(3), 1100000 },
- { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(3), 1100000 },
- { 0, { 972000, HFPLL, 1, 0, 0x24 }, L2(3), 1125000 },
- { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(3), 1125000 },
- { 0, { 1080000, HFPLL, 1, 0, 0x28 }, L2(9), 1175000 },
- { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(9), 1175000 },
- { 0, { 1188000, HFPLL, 1, 0, 0x2C }, L2(9), 1200000 },
- { 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(9), 1200000 },
- { 0, { 1296000, HFPLL, 1, 0, 0x30 }, L2(9), 1225000 },
- { 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(9), 1225000 },
- { 0, { 1404000, HFPLL, 1, 0, 0x34 }, L2(9), 1237500 },
- { 1, { 1458000, HFPLL, 1, 0, 0x36 }, L2(9), 1237500 },
- { 1, { 1512000, HFPLL, 1, 0, 0x38 }, L2(9), 1250000 },
- { 1, { 1566000, HFPLL, 1, 0, 0x3A }, L2(9), 1250000 },
- { 1, { 1620000, HFPLL, 1, 0, 0x3C }, L2(9), 1250000 },
- { 1, { 1674000, HFPLL, 1, 0, 0x3E }, L2(9), 1250000 },
- { 1, { 1728000, HFPLL, 1, 0, 0x40 }, L2(9), 1250000 },
+ { 1, { 384000, PLL_8, 0, 0x00 }, L2(0), 950000 },
+ { 0, { 432000, HFPLL, 2, 0x20 }, L2(3), 975000 },
+ { 1, { 486000, HFPLL, 2, 0x24 }, L2(3), 975000 },
+ { 0, { 540000, HFPLL, 2, 0x28 }, L2(3), 1000000 },
+ { 1, { 594000, HFPLL, 1, 0x16 }, L2(3), 1000000 },
+ { 0, { 648000, HFPLL, 1, 0x18 }, L2(3), 1025000 },
+ { 1, { 702000, HFPLL, 1, 0x1A }, L2(3), 1025000 },
+ { 0, { 756000, HFPLL, 1, 0x1C }, L2(3), 1075000 },
+ { 1, { 810000, HFPLL, 1, 0x1E }, L2(3), 1075000 },
+ { 0, { 864000, HFPLL, 1, 0x20 }, L2(3), 1100000 },
+ { 1, { 918000, HFPLL, 1, 0x22 }, L2(3), 1100000 },
+ { 0, { 972000, HFPLL, 1, 0x24 }, L2(3), 1125000 },
+ { 1, { 1026000, HFPLL, 1, 0x26 }, L2(3), 1125000 },
+ { 0, { 1080000, HFPLL, 1, 0x28 }, L2(9), 1175000 },
+ { 1, { 1134000, HFPLL, 1, 0x2A }, L2(9), 1175000 },
+ { 0, { 1188000, HFPLL, 1, 0x2C }, L2(9), 1200000 },
+ { 1, { 1242000, HFPLL, 1, 0x2E }, L2(9), 1200000 },
+ { 0, { 1296000, HFPLL, 1, 0x30 }, L2(9), 1225000 },
+ { 1, { 1350000, HFPLL, 1, 0x32 }, L2(9), 1225000 },
+ { 0, { 1404000, HFPLL, 1, 0x34 }, L2(9), 1237500 },
+ { 1, { 1458000, HFPLL, 1, 0x36 }, L2(9), 1237500 },
+ { 1, { 1512000, HFPLL, 1, 0x38 }, L2(9), 1250000 },
+ { 1, { 1566000, HFPLL, 1, 0x3A }, L2(9), 1250000 },
+ { 1, { 1620000, HFPLL, 1, 0x3C }, L2(9), 1250000 },
+ { 1, { 1674000, HFPLL, 1, 0x3E }, L2(9), 1250000 },
+ { 1, { 1728000, HFPLL, 1, 0x40 }, L2(9), 1250000 },
{ 0, { 0 } }
};
diff --git a/arch/arm/mach-msm/acpuclock-8974.c b/arch/arm/mach-msm/acpuclock-8974.c
index ee2ca45..4a755bd 100644
--- a/arch/arm/mach-msm/acpuclock-8974.c
+++ b/arch/arm/mach-msm/acpuclock-8974.c
@@ -36,8 +36,8 @@
.has_user_reg = true,
.user_offset = 0x10,
.config_offset = 0x14,
- /* TODO: Verify magic numbers when final values are available. */
.user_val = 0x8,
+ .user_vco_mask = BIT(20),
.config_val = 0x04D0405D,
.low_vco_l_max = 65,
.low_vdd_l_max = 52,
@@ -52,6 +52,7 @@
[CPU0] = {
.hfpll_phys_base = 0xF908A000,
.l2cpmr_iaddr = 0x4501,
+ .sec_clk_sel = 2,
.vreg[VREG_CORE] = { "krait0", 1050000 },
.vreg[VREG_MEM] = { "krait0_mem", 1050000 },
.vreg[VREG_DIG] = { "krait0_dig", LVL_HIGH },
@@ -61,6 +62,7 @@
[CPU1] = {
.hfpll_phys_base = 0xF909A000,
.l2cpmr_iaddr = 0x5501,
+ .sec_clk_sel = 2,
.vreg[VREG_CORE] = { "krait1", 1050000 },
.vreg[VREG_MEM] = { "krait1_mem", 1050000 },
.vreg[VREG_DIG] = { "krait1_dig", LVL_HIGH },
@@ -70,6 +72,7 @@
[CPU2] = {
.hfpll_phys_base = 0xF90AA000,
.l2cpmr_iaddr = 0x6501,
+ .sec_clk_sel = 2,
.vreg[VREG_CORE] = { "krait2", 1050000 },
.vreg[VREG_MEM] = { "krait2_mem", 1050000 },
.vreg[VREG_DIG] = { "krait2_dig", LVL_HIGH },
@@ -79,6 +82,7 @@
[CPU3] = {
.hfpll_phys_base = 0xF90BA000,
.l2cpmr_iaddr = 0x7501,
+ .sec_clk_sel = 2,
.vreg[VREG_CORE] = { "krait3", 1050000 },
.vreg[VREG_MEM] = { "krait3_mem", 1050000 },
.vreg[VREG_DIG] = { "krait3_dig", LVL_HIGH },
@@ -88,6 +92,7 @@
[L2] = {
.hfpll_phys_base = 0xF9016000,
.l2cpmr_iaddr = 0x0500,
+ .sec_clk_sel = 2,
.vreg[VREG_HFPLL_A] = { "l2_hfpll_a", 2150000 },
.vreg[VREG_HFPLL_B] = { "l2_hfpll_b", 1800000 },
},
@@ -108,60 +113,60 @@
};
static struct l2_level l2_freq_tbl[] __initdata = {
- [0] = { { 300000, PLL_0, 0, 2, 0 }, LVL_LOW, 950000, 0 },
- [1] = { { 384000, HFPLL, 2, 0, 40 }, LVL_NOM, 950000, 1 },
- [2] = { { 460800, HFPLL, 2, 0, 48 }, LVL_NOM, 950000, 1 },
- [3] = { { 537600, HFPLL, 1, 0, 28 }, LVL_NOM, 950000, 2 },
- [4] = { { 576000, HFPLL, 1, 0, 30 }, LVL_NOM, 950000, 2 },
- [5] = { { 652800, HFPLL, 1, 0, 34 }, LVL_NOM, 950000, 2 },
- [6] = { { 729600, HFPLL, 1, 0, 38 }, LVL_NOM, 950000, 2 },
- [7] = { { 806400, HFPLL, 1, 0, 42 }, LVL_NOM, 950000, 2 },
- [8] = { { 883200, HFPLL, 1, 0, 46 }, LVL_HIGH, 1050000, 2 },
- [9] = { { 960000, HFPLL, 1, 0, 50 }, LVL_HIGH, 1050000, 2 },
- [10] = { { 1036800, HFPLL, 1, 0, 54 }, LVL_HIGH, 1050000, 3 },
- [11] = { { 1113600, HFPLL, 1, 0, 58 }, LVL_HIGH, 1050000, 3 },
- [12] = { { 1190400, HFPLL, 1, 0, 62 }, LVL_HIGH, 1050000, 3 },
- [13] = { { 1267200, HFPLL, 1, 0, 66 }, LVL_HIGH, 1050000, 3 },
- [14] = { { 1344000, HFPLL, 1, 0, 70 }, LVL_HIGH, 1050000, 3 },
- [15] = { { 1420800, HFPLL, 1, 0, 74 }, LVL_HIGH, 1050000, 3 },
- [16] = { { 1497600, HFPLL, 1, 0, 78 }, LVL_HIGH, 1050000, 3 },
- [17] = { { 1574400, HFPLL, 1, 0, 82 }, LVL_HIGH, 1050000, 3 },
- [18] = { { 1651200, HFPLL, 1, 0, 86 }, LVL_HIGH, 1050000, 3 },
- [19] = { { 1728000, HFPLL, 1, 0, 90 }, LVL_HIGH, 1050000, 3 },
- [20] = { { 1804800, HFPLL, 1, 0, 94 }, LVL_HIGH, 1050000, 3 },
- [21] = { { 1881600, HFPLL, 1, 0, 98 }, LVL_HIGH, 1050000, 3 },
- [22] = { { 1958400, HFPLL, 1, 0, 102 }, LVL_HIGH, 1050000, 3 },
- [23] = { { 2035200, HFPLL, 1, 0, 106 }, LVL_HIGH, 1050000, 3 },
- [24] = { { 2112000, HFPLL, 1, 0, 110 }, LVL_HIGH, 1050000, 3 },
- [25] = { { 2188800, HFPLL, 1, 0, 114 }, LVL_HIGH, 1050000, 3 },
+ [0] = { { 300000, PLL_0, 0, 0 }, LVL_LOW, 950000, 0 },
+ [1] = { { 384000, HFPLL, 2, 40 }, LVL_NOM, 950000, 1 },
+ [2] = { { 460800, HFPLL, 2, 48 }, LVL_NOM, 950000, 1 },
+ [3] = { { 537600, HFPLL, 1, 28 }, LVL_NOM, 950000, 2 },
+ [4] = { { 576000, HFPLL, 1, 30 }, LVL_NOM, 950000, 2 },
+ [5] = { { 652800, HFPLL, 1, 34 }, LVL_NOM, 950000, 2 },
+ [6] = { { 729600, HFPLL, 1, 38 }, LVL_NOM, 950000, 2 },
+ [7] = { { 806400, HFPLL, 1, 42 }, LVL_NOM, 950000, 2 },
+ [8] = { { 883200, HFPLL, 1, 46 }, LVL_HIGH, 1050000, 2 },
+ [9] = { { 960000, HFPLL, 1, 50 }, LVL_HIGH, 1050000, 2 },
+ [10] = { { 1036800, HFPLL, 1, 54 }, LVL_HIGH, 1050000, 3 },
+ [11] = { { 1113600, HFPLL, 1, 58 }, LVL_HIGH, 1050000, 3 },
+ [12] = { { 1190400, HFPLL, 1, 62 }, LVL_HIGH, 1050000, 3 },
+ [13] = { { 1267200, HFPLL, 1, 66 }, LVL_HIGH, 1050000, 3 },
+ [14] = { { 1344000, HFPLL, 1, 70 }, LVL_HIGH, 1050000, 3 },
+ [15] = { { 1420800, HFPLL, 1, 74 }, LVL_HIGH, 1050000, 3 },
+ [16] = { { 1497600, HFPLL, 1, 78 }, LVL_HIGH, 1050000, 3 },
+ [17] = { { 1574400, HFPLL, 1, 82 }, LVL_HIGH, 1050000, 3 },
+ [18] = { { 1651200, HFPLL, 1, 86 }, LVL_HIGH, 1050000, 3 },
+ [19] = { { 1728000, HFPLL, 1, 90 }, LVL_HIGH, 1050000, 3 },
+ [20] = { { 1804800, HFPLL, 1, 94 }, LVL_HIGH, 1050000, 3 },
+ [21] = { { 1881600, HFPLL, 1, 98 }, LVL_HIGH, 1050000, 3 },
+ [22] = { { 1958400, HFPLL, 1, 102 }, LVL_HIGH, 1050000, 3 },
+ [23] = { { 2035200, HFPLL, 1, 106 }, LVL_HIGH, 1050000, 3 },
+ [24] = { { 2112000, HFPLL, 1, 110 }, LVL_HIGH, 1050000, 3 },
+ [25] = { { 2188800, HFPLL, 1, 114 }, LVL_HIGH, 1050000, 3 },
{ }
};
static struct acpu_level acpu_freq_tbl[] __initdata = {
- { 1, { 300000, PLL_0, 0, 2, 0 }, L2(0), 950000, 3200000 },
- { 1, { 384000, HFPLL, 2, 0, 40 }, L2(3), 950000, 3200000 },
- { 1, { 460800, HFPLL, 2, 0, 48 }, L2(3), 950000, 3200000 },
- { 1, { 537600, HFPLL, 1, 0, 28 }, L2(5), 950000, 3200000 },
- { 1, { 576000, HFPLL, 1, 0, 30 }, L2(5), 950000, 3200000 },
- { 1, { 652800, HFPLL, 1, 0, 34 }, L2(5), 950000, 3200000 },
- { 1, { 729600, HFPLL, 1, 0, 38 }, L2(5), 950000, 3200000 },
- { 1, { 806400, HFPLL, 1, 0, 42 }, L2(7), 950000, 3200000 },
- { 1, { 883200, HFPLL, 1, 0, 46 }, L2(7), 950000, 3200000 },
- { 1, { 960000, HFPLL, 1, 0, 50 }, L2(7), 950000, 3200000 },
- { 1, { 1036800, HFPLL, 1, 0, 54 }, L2(7), 950000, 3200000 },
- { 1, { 1113600, HFPLL, 1, 0, 58 }, L2(12), 1050000, 3200000 },
- { 1, { 1190400, HFPLL, 1, 0, 62 }, L2(12), 1050000, 3200000 },
- { 1, { 1267200, HFPLL, 1, 0, 66 }, L2(12), 1050000, 3200000 },
- { 1, { 1344000, HFPLL, 1, 0, 70 }, L2(15), 1050000, 3200000 },
- { 1, { 1420800, HFPLL, 1, 0, 74 }, L2(15), 1050000, 3200000 },
- { 1, { 1497600, HFPLL, 1, 0, 78 }, L2(16), 1050000, 3200000 },
- { 0, { 1574400, HFPLL, 1, 0, 82 }, L2(20), 1050000, 3200000 },
- { 0, { 1651200, HFPLL, 1, 0, 86 }, L2(20), 1050000, 3200000 },
- { 0, { 1728000, HFPLL, 1, 0, 90 }, L2(20), 1050000, 3200000 },
- { 0, { 1804800, HFPLL, 1, 0, 94 }, L2(25), 1050000, 3200000 },
- { 0, { 1881600, HFPLL, 1, 0, 98 }, L2(25), 1050000, 3200000 },
- { 0, { 1958400, HFPLL, 1, 0, 102 }, L2(25), 1050000, 3200000 },
- { 0, { 1996800, HFPLL, 1, 0, 104 }, L2(25), 1050000, 3200000 },
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 950000, 3200000 },
+ { 1, { 384000, HFPLL, 2, 40 }, L2(3), 950000, 3200000 },
+ { 1, { 460800, HFPLL, 2, 48 }, L2(3), 950000, 3200000 },
+ { 1, { 537600, HFPLL, 1, 28 }, L2(5), 950000, 3200000 },
+ { 1, { 576000, HFPLL, 1, 30 }, L2(5), 950000, 3200000 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(5), 950000, 3200000 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(5), 950000, 3200000 },
+ { 1, { 806400, HFPLL, 1, 42 }, L2(7), 950000, 3200000 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(7), 950000, 3200000 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(7), 950000, 3200000 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(7), 950000, 3200000 },
+ { 1, { 1113600, HFPLL, 1, 58 }, L2(12), 1050000, 3200000 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(12), 1050000, 3200000 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(12), 1050000, 3200000 },
+ { 1, { 1344000, HFPLL, 1, 70 }, L2(15), 1050000, 3200000 },
+ { 1, { 1420800, HFPLL, 1, 74 }, L2(15), 1050000, 3200000 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 1050000, 3200000 },
+ { 0, { 1574400, HFPLL, 1, 82 }, L2(20), 1050000, 3200000 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(20), 1050000, 3200000 },
+ { 0, { 1728000, HFPLL, 1, 90 }, L2(20), 1050000, 3200000 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(25), 1050000, 3200000 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(25), 1050000, 3200000 },
+ { 0, { 1958400, HFPLL, 1, 102 }, L2(25), 1050000, 3200000 },
+ { 0, { 1996800, HFPLL, 1, 104 }, L2(25), 1050000, 3200000 },
{ 0, { 0 } }
};
diff --git a/arch/arm/mach-msm/acpuclock-krait.c b/arch/arm/mach-msm/acpuclock-krait.c
index 2951c1a..79c01b2 100644
--- a/arch/arm/mach-msm/acpuclock-krait.c
+++ b/arch/arm/mach-msm/acpuclock-krait.c
@@ -42,8 +42,8 @@
#define PRI_SRC_SEL_SEC_SRC 0
#define PRI_SRC_SEL_HFPLL 1
#define PRI_SRC_SEL_HFPLL_DIV2 2
-#define SEC_SRC_SEL_L2PLL 1
-#define SEC_SRC_SEL_AUX 2
+
+#define SECCLKAGD BIT(4)
static DEFINE_MUTEX(driver_lock);
static DEFINE_SPINLOCK(l2_lock);
@@ -79,14 +79,24 @@
}
/* Select a source on the secondary MUX. */
-static void set_sec_clk_src(struct scalable *sc, u32 sec_src_sel)
+static void __cpuinit set_sec_clk_src(struct scalable *sc, u32 sec_src_sel)
{
u32 regval;
+ /* 8064 Errata: disable sec_src clock gating during switch. */
regval = get_l2_indirect_reg(sc->l2cpmr_iaddr);
+ regval |= SECCLKAGD;
+ set_l2_indirect_reg(sc->l2cpmr_iaddr, regval);
+
+ /* Program the MUX */
regval &= ~(0x3 << 2);
regval |= ((sec_src_sel & 0x3) << 2);
set_l2_indirect_reg(sc->l2cpmr_iaddr, regval);
+
+ /* 8064 Errata: re-enabled sec_src clock gating. */
+ regval &= ~SECCLKAGD;
+ set_l2_indirect_reg(sc->l2cpmr_iaddr, regval);
+
/* Wait for switch to complete. */
mb();
udelay(1);
@@ -220,7 +230,6 @@
* Move to an always-on source running at a frequency
* that does not require an elevated CPU voltage.
*/
- set_sec_clk_src(sc, SEC_SRC_SEL_AUX);
set_pri_clk_src(sc, PRI_SRC_SEL_SEC_SRC);
/* Re-program HFPLL. */
@@ -231,15 +240,12 @@
/* Move to HFPLL. */
set_pri_clk_src(sc, tgt_s->pri_src_sel);
} else if (strt_s->src == HFPLL && tgt_s->src != HFPLL) {
- set_sec_clk_src(sc, tgt_s->sec_src_sel);
set_pri_clk_src(sc, tgt_s->pri_src_sel);
hfpll_disable(sc, false);
} else if (strt_s->src != HFPLL && tgt_s->src == HFPLL) {
hfpll_set_rate(sc, tgt_s);
hfpll_enable(sc, false);
set_pri_clk_src(sc, tgt_s->pri_src_sel);
- } else {
- set_sec_clk_src(sc, tgt_s->sec_src_sel);
}
sc->cur_speed = tgt_s;
@@ -709,7 +715,7 @@
}
/* Switch away from the HFPLL while it's re-initialized. */
- set_sec_clk_src(sc, SEC_SRC_SEL_AUX);
+ set_sec_clk_src(sc, sc->sec_clk_sel);
set_pri_clk_src(sc, PRI_SRC_SEL_SEC_SRC);
hfpll_init(sc, tgt_s);
@@ -719,7 +725,6 @@
set_l2_indirect_reg(sc->l2cpmr_iaddr, regval);
/* Switch to the target clock source. */
- set_sec_clk_src(sc, tgt_s->sec_src_sel);
set_pri_clk_src(sc, tgt_s->pri_src_sel);
sc->cur_speed = tgt_s;
@@ -730,7 +735,6 @@
struct scalable *sc)
{
s->pri_src_sel = get_l2_indirect_reg(sc->l2cpmr_iaddr) & 0x3;
- s->sec_src_sel = (get_l2_indirect_reg(sc->l2cpmr_iaddr) >> 2) & 0x3;
s->pll_l_val = readl_relaxed(sc->hfpll_base + drv.hfpll_data->l_offset);
}
@@ -738,7 +742,6 @@
const struct core_speed *s2)
{
return (s1->pri_src_sel == s2->pri_src_sel &&
- s1->sec_src_sel == s2->sec_src_sel &&
s1->pll_l_val == s2->pll_l_val);
}
diff --git a/arch/arm/mach-msm/acpuclock-krait.h b/arch/arm/mach-msm/acpuclock-krait.h
index d615b85..84a5b5e 100644
--- a/arch/arm/mach-msm/acpuclock-krait.h
+++ b/arch/arm/mach-msm/acpuclock-krait.h
@@ -111,14 +111,12 @@
* @khz: Clock rate in KHz.
* @src: Clock source ID.
* @pri_src_sel: Input to select on the primary MUX.
- * @sec_src_sel: Input to select on the secondary MUX.
* @pll_l_val: HFPLL "L" value to be applied when an HFPLL source is selected.
*/
struct core_speed {
unsigned long khz;
int src;
u32 pri_src_sel;
- u32 sec_src_sel;
u32 pll_l_val;
};
@@ -200,6 +198,7 @@
* @hfpll_base: Virtual base address of HFPLL registers.
* @aux_clk_sel_phys: Physical address of auxiliary MUX.
* @aux_clk_sel: Auxiliary mux input to select at boot.
+ * @sec_clk_sel: Secondary mux input to select at boot.
* @l2cpmr_iaddr: Indirect address of the CPMR MUX/divider CP15 register.
* @cur_speed: Pointer to currently-set speed.
* @l2_vote: L2 performance level vote associate with the current CPU speed.
@@ -212,6 +211,7 @@
void __iomem *hfpll_base;
const phys_addr_t aux_clk_sel_phys;
const u32 aux_clk_sel;
+ const u32 sec_clk_sel;
const u32 l2cpmr_iaddr;
const struct core_speed *cur_speed;
unsigned int l2_vote;
diff --git a/arch/arm/mach-msm/adsp-8974.c b/arch/arm/mach-msm/adsp-8974.c
index 050a24b..fa7d9d4 100644
--- a/arch/arm/mach-msm/adsp-8974.c
+++ b/arch/arm/mach-msm/adsp-8974.c
@@ -119,12 +119,17 @@
wmb();
}
+static void restart_adsp(void)
+{
+ adsp_log_failure_reason();
+ subsystem_restart("adsp");
+}
+
static void adsp_fatal_fn(struct work_struct *work)
{
pr_err("%s %s: Watchdog bite received from Q6!\n", MODULE_NAME,
__func__);
- adsp_log_failure_reason();
- panic(MODULE_NAME ": Resetting the SoC");
+ restart_adsp();
}
static void adsp_smsm_state_cb(void *data, uint32_t old_state,
@@ -137,8 +142,7 @@
if (new_state & SMSM_RESET) {
pr_debug("%s: ADSP SMSM state changed to SMSM_RESET, new_state= 0x%x, old_state = 0x%x\n",
__func__, new_state, old_state);
- adsp_log_failure_reason();
- panic(MODULE_NAME ": Resetting the SoC");
+ restart_adsp();
}
}
@@ -156,7 +160,7 @@
/* The write needs to go through before the q6 is shutdown. */
mb();
- pil_force_shutdown("q6");
+ pil_force_shutdown("adsp");
disable_irq_nosync(ADSP_Q6SS_WDOG_EXPIRED);
return 0;
@@ -171,7 +175,7 @@
msleep(10000);
}
- ret = pil_force_boot("q6");
+ ret = pil_force_boot("adsp");
enable_irq(ADSP_Q6SS_WDOG_EXPIRED);
return ret;
}
diff --git a/arch/arm/mach-msm/batterydata-lib.c b/arch/arm/mach-msm/batterydata-lib.c
new file mode 100644
index 0000000..2be591c
--- /dev/null
+++ b/arch/arm/mach-msm/batterydata-lib.c
@@ -0,0 +1,338 @@
+/* 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.
+ */
+
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
+#include <linux/module.h>
+#include <linux/mfd/pm8xxx/batterydata-lib.h>
+
+int linear_interpolate(int y0, int x0, int y1, int x1, int x)
+{
+ if (y0 == y1 || x == x0)
+ return y0;
+ if (x1 == x0 || x == x1)
+ return y1;
+
+ return y0 + ((y1 - y0) * (x - x0) / (x1 - x0));
+}
+
+int is_between(int left, int right, int value)
+{
+ if (left >= right && left >= value && value >= right)
+ return 1;
+ if (left <= right && left <= value && value <= right)
+ return 1;
+ return 0;
+}
+
+static int interpolate_single_lut(struct single_row_lut *lut, int x)
+{
+ int i, result;
+
+ if (x < lut->x[0]) {
+ pr_debug("x %d less than known range return y = %d lut = %pS\n",
+ x, lut->y[0], lut);
+ return lut->y[0];
+ }
+ if (x > lut->x[lut->cols - 1]) {
+ pr_debug("x %d more than known range return y = %d lut = %pS\n",
+ x, lut->y[lut->cols - 1], lut);
+ return lut->y[lut->cols - 1];
+ }
+
+ for (i = 0; i < lut->cols; i++)
+ if (x <= lut->x[i])
+ break;
+ if (x == lut->x[i]) {
+ result = lut->y[i];
+ } else {
+ result = linear_interpolate(
+ lut->y[i - 1],
+ lut->x[i - 1],
+ lut->y[i],
+ lut->x[i],
+ x);
+ }
+ return result;
+}
+
+int interpolate_fcc(struct single_row_lut *fcc_temp_lut, int batt_temp)
+{
+ /* batt_temp is in tenths of degC - convert it to degC for lookups */
+ batt_temp = batt_temp/10;
+ return interpolate_single_lut(fcc_temp_lut, batt_temp);
+}
+
+int interpolate_scalingfactor_fcc(struct single_row_lut *fcc_sf_lut,
+ int cycles)
+{
+ /*
+ * sf table could be null when no battery aging data is available, in
+ * that case return 100%
+ */
+ if (fcc_sf_lut)
+ return interpolate_single_lut(fcc_sf_lut, cycles);
+ else
+ return 100;
+}
+
+int interpolate_scalingfactor(struct sf_lut *sf_lut, int row_entry, int pc)
+{
+ int i, scalefactorrow1, scalefactorrow2, scalefactor, rows, cols;
+ int row1 = 0;
+ int row2 = 0;
+
+ /*
+ * sf table could be null when no battery aging data is available, in
+ * that case return 100%
+ */
+ if (!sf_lut)
+ return 100;
+
+ rows = sf_lut->rows;
+ cols = sf_lut->cols;
+ if (pc > sf_lut->percent[0]) {
+ pr_debug("pc %d greater than known pc ranges for sfd\n", pc);
+ row1 = 0;
+ row2 = 0;
+ }
+ if (pc < sf_lut->percent[rows - 1]) {
+ pr_debug("pc %d less than known pc ranges for sf\n", pc);
+ row1 = rows - 1;
+ row2 = rows - 1;
+ }
+ for (i = 0; i < rows; i++) {
+ if (pc == sf_lut->percent[i]) {
+ row1 = i;
+ row2 = i;
+ break;
+ }
+ if (pc > sf_lut->percent[i]) {
+ row1 = i - 1;
+ row2 = i;
+ break;
+ }
+ }
+
+ if (row_entry < sf_lut->row_entries[0])
+ row_entry = sf_lut->row_entries[0];
+ if (row_entry > sf_lut->row_entries[cols - 1])
+ row_entry = sf_lut->row_entries[cols - 1];
+
+ for (i = 0; i < cols; i++)
+ if (row_entry <= sf_lut->row_entries[i])
+ break;
+ if (row_entry == sf_lut->row_entries[i]) {
+ scalefactor = linear_interpolate(
+ sf_lut->sf[row1][i],
+ sf_lut->percent[row1],
+ sf_lut->sf[row2][i],
+ sf_lut->percent[row2],
+ pc);
+ return scalefactor;
+ }
+
+ scalefactorrow1 = linear_interpolate(
+ sf_lut->sf[row1][i - 1],
+ sf_lut->row_entries[i - 1],
+ sf_lut->sf[row1][i],
+ sf_lut->row_entries[i],
+ row_entry);
+
+ scalefactorrow2 = linear_interpolate(
+ sf_lut->sf[row2][i - 1],
+ sf_lut->row_entries[i - 1],
+ sf_lut->sf[row2][i],
+ sf_lut->row_entries[i],
+ row_entry);
+
+ scalefactor = linear_interpolate(
+ scalefactorrow1,
+ sf_lut->percent[row1],
+ scalefactorrow2,
+ sf_lut->percent[row2],
+ pc);
+
+ return scalefactor;
+}
+
+/* get ocv given a soc -- reverse lookup */
+int interpolate_ocv(struct pc_temp_ocv_lut *pc_temp_ocv,
+ int batt_temp_degc, int pc)
+{
+ int i, ocvrow1, ocvrow2, ocv, rows, cols;
+ int row1 = 0;
+ int row2 = 0;
+
+ rows = pc_temp_ocv->rows;
+ cols = pc_temp_ocv->cols;
+ if (pc > pc_temp_ocv->percent[0]) {
+ pr_debug("pc %d greater than known pc ranges for sfd\n", pc);
+ row1 = 0;
+ row2 = 0;
+ }
+ if (pc < pc_temp_ocv->percent[rows - 1]) {
+ pr_debug("pc %d less than known pc ranges for sf\n", pc);
+ row1 = rows - 1;
+ row2 = rows - 1;
+ }
+ for (i = 0; i < rows; i++) {
+ if (pc == pc_temp_ocv->percent[i]) {
+ row1 = i;
+ row2 = i;
+ break;
+ }
+ if (pc > pc_temp_ocv->percent[i]) {
+ row1 = i - 1;
+ row2 = i;
+ break;
+ }
+ }
+
+ if (batt_temp_degc < pc_temp_ocv->temp[0])
+ batt_temp_degc = pc_temp_ocv->temp[0];
+ if (batt_temp_degc > pc_temp_ocv->temp[cols - 1])
+ batt_temp_degc = pc_temp_ocv->temp[cols - 1];
+
+ for (i = 0; i < cols; i++)
+ if (batt_temp_degc <= pc_temp_ocv->temp[i])
+ break;
+ if (batt_temp_degc == pc_temp_ocv->temp[i]) {
+ ocv = linear_interpolate(
+ pc_temp_ocv->ocv[row1][i],
+ pc_temp_ocv->percent[row1],
+ pc_temp_ocv->ocv[row2][i],
+ pc_temp_ocv->percent[row2],
+ pc);
+ return ocv;
+ }
+
+ ocvrow1 = linear_interpolate(
+ pc_temp_ocv->ocv[row1][i - 1],
+ pc_temp_ocv->temp[i - 1],
+ pc_temp_ocv->ocv[row1][i],
+ pc_temp_ocv->temp[i],
+ batt_temp_degc);
+
+ ocvrow2 = linear_interpolate(
+ pc_temp_ocv->ocv[row2][i - 1],
+ pc_temp_ocv->temp[i - 1],
+ pc_temp_ocv->ocv[row2][i],
+ pc_temp_ocv->temp[i],
+ batt_temp_degc);
+
+ ocv = linear_interpolate(
+ ocvrow1,
+ pc_temp_ocv->percent[row1],
+ ocvrow2,
+ pc_temp_ocv->percent[row2],
+ pc);
+
+ return ocv;
+}
+
+int interpolate_pc(struct pc_temp_ocv_lut *pc_temp_ocv,
+ int batt_temp_degc, int ocv)
+{
+ int i, j, pcj, pcj_minus_one, pc;
+ int rows = pc_temp_ocv->rows;
+ int cols = pc_temp_ocv->cols;
+
+ if (batt_temp_degc < pc_temp_ocv->temp[0]) {
+ pr_debug("batt_temp %d < known temp range\n", batt_temp_degc);
+ batt_temp_degc = pc_temp_ocv->temp[0];
+ }
+
+ if (batt_temp_degc > pc_temp_ocv->temp[cols - 1]) {
+ pr_debug("batt_temp %d > known temp range\n", batt_temp_degc);
+ batt_temp_degc = pc_temp_ocv->temp[cols - 1];
+ }
+
+ for (j = 0; j < cols; j++)
+ if (batt_temp_degc <= pc_temp_ocv->temp[j])
+ break;
+ if (batt_temp_degc == pc_temp_ocv->temp[j]) {
+ /* found an exact match for temp in the table */
+ if (ocv >= pc_temp_ocv->ocv[0][j])
+ return pc_temp_ocv->percent[0];
+ if (ocv <= pc_temp_ocv->ocv[rows - 1][j])
+ return pc_temp_ocv->percent[rows - 1];
+ for (i = 0; i < rows; i++) {
+ if (ocv >= pc_temp_ocv->ocv[i][j]) {
+ if (ocv == pc_temp_ocv->ocv[i][j])
+ return pc_temp_ocv->percent[i];
+ pc = linear_interpolate(
+ pc_temp_ocv->percent[i],
+ pc_temp_ocv->ocv[i][j],
+ pc_temp_ocv->percent[i - 1],
+ pc_temp_ocv->ocv[i - 1][j],
+ ocv);
+ return pc;
+ }
+ }
+ }
+
+ /*
+ * batt_temp_degc is within temperature for
+ * column j-1 and j
+ */
+ if (ocv >= pc_temp_ocv->ocv[0][j])
+ return pc_temp_ocv->percent[0];
+ if (ocv <= pc_temp_ocv->ocv[rows - 1][j - 1])
+ return pc_temp_ocv->percent[rows - 1];
+
+ pcj_minus_one = 0;
+ pcj = 0;
+ for (i = 0; i < rows-1; i++) {
+ if (pcj == 0
+ && is_between(pc_temp_ocv->ocv[i][j],
+ pc_temp_ocv->ocv[i+1][j], ocv)) {
+ pcj = linear_interpolate(
+ pc_temp_ocv->percent[i],
+ pc_temp_ocv->ocv[i][j],
+ pc_temp_ocv->percent[i + 1],
+ pc_temp_ocv->ocv[i+1][j],
+ ocv);
+ }
+
+ if (pcj_minus_one == 0
+ && is_between(pc_temp_ocv->ocv[i][j-1],
+ pc_temp_ocv->ocv[i+1][j-1], ocv)) {
+ pcj_minus_one = linear_interpolate(
+ pc_temp_ocv->percent[i],
+ pc_temp_ocv->ocv[i][j-1],
+ pc_temp_ocv->percent[i + 1],
+ pc_temp_ocv->ocv[i+1][j-1],
+ ocv);
+ }
+
+ if (pcj && pcj_minus_one) {
+ pc = linear_interpolate(
+ pcj_minus_one,
+ pc_temp_ocv->temp[j-1],
+ pcj,
+ pc_temp_ocv->temp[j],
+ batt_temp_degc);
+ return pc;
+ }
+ }
+
+ if (pcj)
+ return pcj;
+
+ if (pcj_minus_one)
+ return pcj_minus_one;
+
+ pr_debug("%d ocv wasn't found for temp %d in the LUT returning 100%%\n",
+ ocv, batt_temp_degc);
+ return 100;
+}
diff --git a/arch/arm/mach-msm/bms-batterydata-desay.c b/arch/arm/mach-msm/bms-batterydata-desay.c
index f362a72..d9fa061 100644
--- a/arch/arm/mach-msm/bms-batterydata-desay.c
+++ b/arch/arm/mach-msm/bms-batterydata-desay.c
@@ -10,7 +10,7 @@
* GNU General Public License for more details.
*/
-#include <linux/mfd/pm8xxx/pm8921-bms.h>
+#include <linux/mfd/pm8xxx/batterydata-lib.h>
static struct single_row_lut desay_5200_fcc_temp = {
.x = {-20, 0, 25, 40},
@@ -76,7 +76,7 @@
},
};
-struct pm8921_bms_battery_data desay_5200_data = {
+struct bms_battery_data desay_5200_data = {
.fcc = 5200,
.fcc_temp_lut = &desay_5200_fcc_temp,
.fcc_sf_lut = &desay_5200_fcc_sf,
diff --git a/arch/arm/mach-msm/bms-batterydata.c b/arch/arm/mach-msm/bms-batterydata.c
index 81ab121..fb4f967 100644
--- a/arch/arm/mach-msm/bms-batterydata.c
+++ b/arch/arm/mach-msm/bms-batterydata.c
@@ -10,7 +10,7 @@
* GNU General Public License for more details.
*/
-#include <linux/mfd/pm8xxx/pm8921-bms.h>
+#include <linux/mfd/pm8xxx/batterydata-lib.h>
static struct single_row_lut fcc_temp = {
.x = {-20, 0, 25, 40, 65},
@@ -99,7 +99,7 @@
}
};
-struct pm8921_bms_battery_data palladium_1500_data = {
+struct bms_battery_data palladium_1500_data = {
.fcc = 1500,
.fcc_temp_lut = &fcc_temp,
.pc_temp_ocv_lut = &pc_temp_ocv,
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 07acac6..1bac198 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -1930,6 +1930,7 @@
.ramdump_delay_ms = 2000,
.early_power_on = 1,
.sfr_query = 1,
+ .send_shdn = 1,
.vddmin_resource = &mdm_vddmin_rscs,
.peripheral_platform_device = &apq8064_device_hsic_host,
.ramdump_timeout_ms = 120000,
@@ -2575,6 +2576,7 @@
#ifdef CONFIG_MSM_ROTATOR
&msm_rotator_device,
#endif
+ &msm8064_pc_cntr,
};
static struct platform_device
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index ab35948..05592c2 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -2398,6 +2398,7 @@
&msm8930_iommu_domain_device,
&msm_tsens_device,
&msm8930_cache_dump_device,
+ &msm8930_pc_cntr,
};
static struct platform_device *cdp_devices[] __initdata = {
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index 8ed9666..710b10f 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -2744,6 +2744,7 @@
&msm8960_cache_dump_device,
&msm8960_iommu_domain_device,
&msm_tsens_device,
+ &msm8960_pc_cntr,
};
static struct platform_device *cdp_devices[] __initdata = {
@@ -3158,13 +3159,22 @@
#endif
}
+static void __init msm8960_tsens_init(void)
+{
+ if (cpu_is_msm8960())
+ if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) == 1)
+ return;
+
+ msm_tsens_early_init(&msm_tsens_pdata);
+}
+
static void __init msm8960_cdp_init(void)
{
if (meminfo_init(SYS_MEMORY, SZ_256M) < 0)
pr_err("meminfo_init() failed!\n");
platform_device_register(&msm_gpio_device);
- msm_tsens_early_init(&msm_tsens_pdata);
+ msm8960_tsens_init();
msm_thermal_init(&msm_thermal_pdata);
BUG_ON(msm_rpm_init(&msm8960_rpm_data));
BUG_ON(msm_rpmrs_levels_init(&msm_rpmrs_data));
diff --git a/arch/arm/mach-msm/board-8974-gpiomux.c b/arch/arm/mach-msm/board-8974-gpiomux.c
index 479dec6..1577a2b 100644
--- a/arch/arm/mach-msm/board-8974-gpiomux.c
+++ b/arch/arm/mach-msm/board-8974-gpiomux.c
@@ -290,22 +290,34 @@
static struct gpiomux_setting cam_settings[] = {
{
- .func = GPIOMUX_FUNC_1, /*active 1*/
+ .func = GPIOMUX_FUNC_1, /*active 1*/ /* 0 */
.drv = GPIOMUX_DRV_2MA,
.pull = GPIOMUX_PULL_NONE,
},
{
- .func = GPIOMUX_FUNC_1, /*suspend*/
+ .func = GPIOMUX_FUNC_1, /*suspend*/ /* 1 */
.drv = GPIOMUX_DRV_2MA,
.pull = GPIOMUX_PULL_DOWN,
},
{
- .func = GPIOMUX_FUNC_1, /*i2c suspend*/
+ .func = GPIOMUX_FUNC_1, /*i2c suspend*/ /* 2 */
.drv = GPIOMUX_DRV_2MA,
.pull = GPIOMUX_PULL_KEEPER,
},
+
+ {
+ .func = GPIOMUX_FUNC_GPIO, /*active 0*/ /* 3 */
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_NONE,
+ },
+
+ {
+ .func = GPIOMUX_FUNC_GPIO, /*suspend 0*/ /* 4 */
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_DOWN,
+ },
};
static struct msm_gpiomux_config msm_sensor_configs[] __initdata = {
@@ -333,8 +345,8 @@
{
.gpio = 18, /* WEBCAM1_RESET_N / CAM_MCLK3 */
.settings = {
- [GPIOMUX_ACTIVE] = &cam_settings[0],
- [GPIOMUX_SUSPENDED] = &cam_settings[1],
+ [GPIOMUX_ACTIVE] = &cam_settings[3],
+ [GPIOMUX_SUSPENDED] = &cam_settings[4],
},
},
{
diff --git a/arch/arm/mach-msm/board-9625-gpiomux.c b/arch/arm/mach-msm/board-9625-gpiomux.c
index 2919f06..fe7670b 100644
--- a/arch/arm/mach-msm/board-9625-gpiomux.c
+++ b/arch/arm/mach-msm/board-9625-gpiomux.c
@@ -18,8 +18,8 @@
#include <mach/gpiomux.h>
static struct gpiomux_setting gpio_uart_config = {
- .func = GPIOMUX_FUNC_2,
- .drv = GPIOMUX_DRV_16MA,
+ .func = GPIOMUX_FUNC_1,
+ .drv = GPIOMUX_DRV_8MA,
.pull = GPIOMUX_PULL_NONE,
.dir = GPIOMUX_OUT_HIGH,
};
@@ -38,13 +38,13 @@
static struct msm_gpiomux_config msm_blsp_configs[] __initdata = {
{
- .gpio = 45, /* BLSP1 UART TX */
+ .gpio = 8, /* BLSP1 UART TX */
.settings = {
[GPIOMUX_SUSPENDED] = &gpio_uart_config,
},
},
{
- .gpio = 46, /* BLSP1 UART RX */
+ .gpio = 9, /* BLSP1 UART RX */
.settings = {
[GPIOMUX_SUSPENDED] = &gpio_uart_config,
},
diff --git a/arch/arm/mach-msm/board-9625.c b/arch/arm/mach-msm/board-9625.c
index 99b9f16..5f556fb 100644
--- a/arch/arm/mach-msm/board-9625.c
+++ b/arch/arm/mach-msm/board-9625.c
@@ -30,6 +30,7 @@
#include <mach/board.h>
#include <mach/gpio.h>
#include <mach/clk-provider.h>
+#include <mach/qpnp-int.h>
#include "clock.h"
#define L2CC_AUX_CTRL ((0x1 << L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT) | \
@@ -62,6 +63,7 @@
static struct of_device_id irq_match[] __initdata = {
{ .compatible = "qcom,msm-qgic2", .data = gic_of_init, },
{ .compatible = "qcom,msm-gpio", .data = msm_gpio_of_init, },
+ { .compatible = "qcom,spmi-pmic-arb", .data = qpnpint_of_init, },
{}
};
@@ -75,6 +77,8 @@
"msm_serial_hsl.0", NULL),
OF_DEV_AUXDATA("qcom,spi-qup-v2", 0xF9928000, \
"spi_qsd.1", NULL),
+ OF_DEV_AUXDATA("qcom,spmi-pmic-arb", 0xFC4C0000, \
+ "spmi-pmic-arb.0", NULL),
{}
};
@@ -99,7 +103,7 @@
pr_err("%s: socinfo_init() failed\n", __func__);
msm9625_init_gpiomux();
- msm_clock_init(&msm_dummy_clock_init_data);
+ msm_clock_init(&msm9625_clock_init_data);
of_platform_populate(NULL, of_default_bus_match_table,
msm9625_auxdata_lookup, NULL);
}
@@ -111,5 +115,4 @@
.handle_irq = gic_handle_irq,
.timer = &msm_dt_timer,
.dt_compat = msm9625_dt_match,
- .nr_irqs = -1,
MACHINE_END
diff --git a/arch/arm/mach-msm/board-msm7627a-io.c b/arch/arm/mach-msm/board-msm7627a-io.c
index 47e8381..6e3d10a 100644
--- a/arch/arm/mach-msm/board-msm7627a-io.c
+++ b/arch/arm/mach-msm/board-msm7627a-io.c
@@ -266,16 +266,16 @@
/* T6 Object */
0, 0, 0, 0, 0, 0,
/* T38 Object */
- 20, 0, 0, 0, 0, 0, 0, 0,
+ 20, 1, 0, 25, 9, 12, 0, 0,
/* T7 Object */
24, 12, 10,
/* T8 Object */
- 30, 0, 20, 20, 0, 0, 9, 45, 10, 192,
+ 30, 0, 20, 20, 0, 0, 0, 0, 10, 192,
/* T9 Object */
- 3, 0, 0, 18, 11, 0, 16, 60, 3, 1,
- 0, 1, 1, 0, 10, 10, 10, 10, 107, 3,
- 223, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 20, 15, 0, 0, 2,
+ 131, 0, 0, 18, 11, 0, 16, 70, 2, 1,
+ 0, 2, 1, 62, 10, 10, 10, 10, 107, 3,
+ 223, 1, 2, 2, 20, 20, 172, 40, 139, 110,
+ 10, 15, 0, 0, 0,
/* T15 Object */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0,
@@ -291,7 +291,7 @@
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0,
/* T40 Object */
- 17, 0, 0, 30, 30,
+ 0, 0, 0, 0, 0,
/* T42 Object */
3, 20, 45, 40, 128, 0, 0, 0,
/* T46 Object */
@@ -299,12 +299,12 @@
/* T47 Object */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* T48 Object */
- 1, 128, 96, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 6, 6, 0, 0, 63, 4, 64,
- 10, 0, 32, 5, 0, 38, 0, 8, 0, 0,
+ 1, 12, 64, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 6, 6, 0, 0, 100, 4, 64,
+ 10, 0, 20, 5, 0, 38, 0, 20, 0, 0,
0, 0, 0, 0, 16, 65, 3, 1, 1, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,
+ 10, 10, 10, 0, 0, 15, 15, 154, 58, 145,
+ 80, 100, 15, 3,
};
static struct mxt_config_info mxt_config_array[] = {
@@ -822,6 +822,7 @@
mxt_config_array[0].config_length =
ARRAY_SIZE(mxt_config_data_evt);
mxt_platform_data.panel_maxy = 875;
+ mxt_platform_data.need_calibration = true;
mxt_vkey_setup();
}
diff --git a/arch/arm/mach-msm/board-qrd7627a.c b/arch/arm/mach-msm/board-qrd7627a.c
index f6b0c4f..ed1fafc 100644
--- a/arch/arm/mach-msm/board-qrd7627a.c
+++ b/arch/arm/mach-msm/board-qrd7627a.c
@@ -276,6 +276,7 @@
static struct msm_hsusb_gadget_platform_data msm_gadget_pdata = {
.is_phy_status_timer_on = 1,
+ .prop_chg = 0,
};
#ifdef CONFIG_SERIAL_MSM_HS
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 9ff039f0..b60f693 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -5450,6 +5450,10 @@
CLK_LOOKUP("osr_clk", spare_i2s_mic_osr_clk.c,
"msm-dai-q6.5"),
CLK_LOOKUP("bit_clk", codec_i2s_spkr_bit_clk.c,
+ "msm-dai-q6.0"),
+ CLK_LOOKUP("osr_clk", codec_i2s_spkr_osr_clk.c,
+ "msm-dai-q6.0"),
+ CLK_LOOKUP("bit_clk", codec_i2s_spkr_bit_clk.c,
"msm-dai-q6.16384"),
CLK_LOOKUP("osr_clk", codec_i2s_spkr_osr_clk.c,
"msm-dai-q6.16384"),
@@ -5793,6 +5797,10 @@
CLK_LOOKUP("osr_clk", spare_i2s_mic_osr_clk.c,
"msm-dai-q6.5"),
CLK_LOOKUP("bit_clk", codec_i2s_spkr_bit_clk.c,
+ "msm-dai-q6.0"),
+ CLK_LOOKUP("osr_clk", codec_i2s_spkr_osr_clk.c,
+ "msm-dai-q6.0"),
+ CLK_LOOKUP("bit_clk", codec_i2s_spkr_bit_clk.c,
"msm-dai-q6.16384"),
CLK_LOOKUP("osr_clk", codec_i2s_spkr_osr_clk.c,
"msm-dai-q6.16384"),
@@ -6125,6 +6133,10 @@
CLK_LOOKUP("osr_clk", spare_i2s_mic_osr_clk.c,
"msm-dai-q6.5"),
CLK_LOOKUP("bit_clk", codec_i2s_spkr_bit_clk.c,
+ "msm-dai-q6.0"),
+ CLK_LOOKUP("osr_clk", codec_i2s_spkr_osr_clk.c,
+ "msm-dai-q6.0"),
+ CLK_LOOKUP("bit_clk", codec_i2s_spkr_bit_clk.c,
"msm-dai-q6.16384"),
CLK_LOOKUP("osr_clk", codec_i2s_spkr_osr_clk.c,
"msm-dai-q6.16384"),
diff --git a/arch/arm/mach-msm/clock-8974.c b/arch/arm/mach-msm/clock-8974.c
index 26e6ca6..a64e6a5 100644
--- a/arch/arm/mach-msm/clock-8974.c
+++ b/arch/arm/mach-msm/clock-8974.c
@@ -1,4 +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
@@ -5128,7 +5128,9 @@
CLK_LOOKUP("core_clk", mdss_esc1_clk.c, ""),
CLK_LOOKUP("pixel_clk", mdss_pclk0_clk.c, "fd922800.qcom,mdss_dsi"),
CLK_LOOKUP("pixel_clk", mdss_pclk1_clk.c, ""),
- CLK_LOOKUP("iface_clk", mdss_hdmi_ahb_clk.c, "fd922100.qcom,hdmi_tx"),
+ CLK_LOOKUP("iface_clk", mdss_ahb_clk.c, "fd922100.qcom,hdmi_tx"),
+ CLK_LOOKUP("alt_iface_clk", mdss_hdmi_ahb_clk.c,
+ "fd922100.qcom,hdmi_tx"),
CLK_LOOKUP("core_clk", mdss_hdmi_clk.c, "fd922100.qcom,hdmi_tx"),
CLK_LOOKUP("extp_clk", mdss_extpclk_clk.c, "fd922100.qcom,hdmi_tx"),
CLK_LOOKUP("core_clk", mdss_mdp_clk.c, "mdp.0"),
@@ -5139,8 +5141,10 @@
/* MM sensor clocks */
CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "6e.qcom,camera"),
CLK_LOOKUP("cam_src_clk", mclk1_clk_src.c, "6c.qcom,camera"),
+ CLK_LOOKUP("cam_src_clk", mclk1_clk_src.c, "90.qcom,camera"),
CLK_LOOKUP("cam_clk", camss_mclk0_clk.c, "6e.qcom,camera"),
CLK_LOOKUP("cam_clk", camss_mclk1_clk.c, "6c.qcom,camera"),
+ CLK_LOOKUP("cam_clk", camss_mclk1_clk.c, "90.qcom,camera"),
CLK_LOOKUP("cam_clk", camss_mclk1_clk.c, ""),
CLK_LOOKUP("cam_clk", camss_mclk2_clk.c, ""),
CLK_LOOKUP("cam_clk", camss_mclk3_clk.c, ""),
diff --git a/arch/arm/mach-msm/clock-9625.c b/arch/arm/mach-msm/clock-9625.c
new file mode 100644
index 0000000..a07eebb
--- /dev/null
+++ b/arch/arm/mach-msm/clock-9625.c
@@ -0,0 +1,2278 @@
+/* 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.c b/arch/arm/mach-msm/clock.c
index 1ea18f4..eead627 100644
--- a/arch/arm/mach-msm/clock.c
+++ b/arch/arm/mach-msm/clock.c
@@ -72,15 +72,14 @@
/* Vote for a voltage level. */
int vote_vdd_level(struct clk_vdd_class *vdd_class, int level)
{
- unsigned long flags;
int rc;
- spin_lock_irqsave(&vdd_class->lock, flags);
+ mutex_lock(&vdd_class->lock);
vdd_class->level_votes[level]++;
rc = update_vdd(vdd_class);
if (rc)
vdd_class->level_votes[level]--;
- spin_unlock_irqrestore(&vdd_class->lock, flags);
+ mutex_unlock(&vdd_class->lock);
return rc;
}
@@ -88,10 +87,9 @@
/* Remove vote for a voltage level. */
int unvote_vdd_level(struct clk_vdd_class *vdd_class, int level)
{
- unsigned long flags;
int rc = 0;
- spin_lock_irqsave(&vdd_class->lock, flags);
+ mutex_lock(&vdd_class->lock);
if (WARN(!vdd_class->level_votes[level],
"Reference counts are incorrect for %s level %d\n",
vdd_class->class_name, level))
@@ -101,7 +99,7 @@
if (rc)
vdd_class->level_votes[level]++;
out:
- spin_unlock_irqrestore(&vdd_class->lock, flags);
+ mutex_unlock(&vdd_class->lock);
return rc;
}
diff --git a/arch/arm/mach-msm/clock.h b/arch/arm/mach-msm/clock.h
index 48f897b..8a75d390 100644
--- a/arch/arm/mach-msm/clock.h
+++ b/arch/arm/mach-msm/clock.h
@@ -34,6 +34,7 @@
};
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-8064.c b/arch/arm/mach-msm/devices-8064.c
index e66881b..c0461e1 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -99,6 +99,23 @@
/* Address of PCIE20 */
#define PCIE20_PHYS 0x1b500000
#define PCIE20_SIZE SZ_4K
+#define MSM8064_PC_CNTR_PHYS (APQ8064_IMEM_PHYS + 0x664)
+#define MSM8064_PC_CNTR_SIZE 0x40
+
+static struct resource msm8064_resources_pccntr[] = {
+ {
+ .start = MSM8064_PC_CNTR_PHYS,
+ .end = MSM8064_PC_CNTR_PHYS + MSM8064_PC_CNTR_SIZE,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct platform_device msm8064_pc_cntr = {
+ .name = "pc-cntr",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(msm8064_resources_pccntr),
+ .resource = msm8064_resources_pccntr,
+};
static struct msm_watchdog_pdata msm_watchdog_pdata = {
.pet_time = 10000,
@@ -2350,17 +2367,18 @@
/* Sensors DSPS platform data */
-#define PPSS_DSPS_TCM_CODE_BASE 0x12000000
-#define PPSS_DSPS_TCM_CODE_SIZE 0x28000
-#define PPSS_DSPS_TCM_BUF_BASE 0x12040000
-#define PPSS_DSPS_TCM_BUF_SIZE 0x4000
-#define PPSS_DSPS_PIPE_BASE 0x12800000
-#define PPSS_DSPS_PIPE_SIZE 0x4000
-#define PPSS_DSPS_DDR_BASE 0x8fe00000
-#define PPSS_DSPS_DDR_SIZE 0x100000
-#define PPSS_SMEM_BASE 0x80000000
-#define PPSS_SMEM_SIZE 0x200000
-#define PPSS_REG_PHYS_BASE 0x12080000
+#define PPSS_DSPS_TCM_CODE_BASE 0x12000000
+#define PPSS_DSPS_TCM_CODE_SIZE 0x28000
+#define PPSS_DSPS_TCM_BUF_BASE 0x12040000
+#define PPSS_DSPS_TCM_BUF_SIZE 0x4000
+#define PPSS_DSPS_PIPE_BASE 0x12800000
+#define PPSS_DSPS_PIPE_SIZE 0x4000
+#define PPSS_DSPS_DDR_BASE 0x8fe00000
+#define PPSS_DSPS_DDR_SIZE 0x100000
+#define PPSS_SMEM_BASE 0x80000000
+#define PPSS_SMEM_SIZE 0x200000
+#define PPSS_REG_PHYS_BASE 0x12080000
+#define PPSS_WDOG_UNMASKED_INT_EN 0x1808
static struct dsps_clk_info dsps_clks[] = {};
static struct dsps_regulator_info dsps_regs[] = {};
@@ -2388,6 +2406,7 @@
.ddr_size = PPSS_DSPS_DDR_SIZE,
.smem_start = PPSS_SMEM_BASE,
.smem_size = PPSS_SMEM_SIZE,
+ .ppss_wdog_unmasked_int_en_reg = PPSS_WDOG_UNMASKED_INT_EN,
.signature = DSPS_SIGNATURE,
};
@@ -2715,8 +2734,8 @@
{
.src = MSM_BUS_MASTER_VIDEO_CAP,
.dst = MSM_BUS_SLAVE_EBI_CH0,
- .ab = 1920 * 1080 * 3 * 60,
- .ib = 1920 * 1080 * 3 * 60 * 1.5,
+ .ab = 1920 * 1080 * 10 * 60,
+ .ib = 1920 * 1080 * 10 * 60 * 1.5,
},
};
diff --git a/arch/arm/mach-msm/devices-8930.c b/arch/arm/mach-msm/devices-8930.c
index ad89a86..f52ee18 100644
--- a/arch/arm/mach-msm/devices-8930.c
+++ b/arch/arm/mach-msm/devices-8930.c
@@ -37,6 +37,23 @@
#ifdef CONFIG_MSM_MPM
#include <mach/mpm.h>
#endif
+#define MSM8930_PC_CNTR_PHYS (MSM8930_IMEM_PHYS + 0x664)
+#define MSM8930_PC_CNTR_SIZE 0x40
+
+static struct resource msm8930_resources_pccntr[] = {
+ {
+ .start = MSM8930_PC_CNTR_PHYS,
+ .end = MSM8930_PC_CNTR_PHYS + MSM8930_PC_CNTR_SIZE,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct platform_device msm8930_pc_cntr = {
+ .name = "pc-cntr",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(msm8930_resources_pccntr),
+ .resource = msm8930_resources_pccntr,
+};
struct msm_rpm_platform_data msm8930_rpm_data __initdata = {
.reg_base_addrs = {
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index 64b901f..5cbfb5b 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -103,6 +103,24 @@
#define MSM8960_HSUSB_PHYS 0x12500000
#define MSM8960_HSUSB_SIZE SZ_4K
+#define MSM8960_PC_CNTR_PHYS (MSM8960_IMEM_PHYS + 0x664)
+#define MSM8960_PC_CNTR_SIZE 0x40
+
+static struct resource msm8960_resources_pccntr[] = {
+ {
+ .start = MSM8960_PC_CNTR_PHYS,
+ .end = MSM8960_PC_CNTR_PHYS + MSM8960_PC_CNTR_SIZE,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct platform_device msm8960_pc_cntr = {
+ .name = "pc-cntr",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(msm8960_resources_pccntr),
+ .resource = msm8960_resources_pccntr,
+};
+
static struct resource resources_otg[] = {
{
.start = MSM8960_HSUSB_PHYS,
@@ -3705,17 +3723,18 @@
/* Sensors DSPS platform data */
#ifdef CONFIG_MSM_DSPS
-#define PPSS_DSPS_TCM_CODE_BASE 0x12000000
-#define PPSS_DSPS_TCM_CODE_SIZE 0x28000
-#define PPSS_DSPS_TCM_BUF_BASE 0x12040000
-#define PPSS_DSPS_TCM_BUF_SIZE 0x4000
-#define PPSS_DSPS_PIPE_BASE 0x12800000
-#define PPSS_DSPS_PIPE_SIZE 0x4000
-#define PPSS_DSPS_DDR_BASE 0x8fe00000
-#define PPSS_DSPS_DDR_SIZE 0x100000
-#define PPSS_SMEM_BASE 0x80000000
-#define PPSS_SMEM_SIZE 0x200000
-#define PPSS_REG_PHYS_BASE 0x12080000
+#define PPSS_DSPS_TCM_CODE_BASE 0x12000000
+#define PPSS_DSPS_TCM_CODE_SIZE 0x28000
+#define PPSS_DSPS_TCM_BUF_BASE 0x12040000
+#define PPSS_DSPS_TCM_BUF_SIZE 0x4000
+#define PPSS_DSPS_PIPE_BASE 0x12800000
+#define PPSS_DSPS_PIPE_SIZE 0x4000
+#define PPSS_DSPS_DDR_BASE 0x8fe00000
+#define PPSS_DSPS_DDR_SIZE 0x100000
+#define PPSS_SMEM_BASE 0x80000000
+#define PPSS_SMEM_SIZE 0x200000
+#define PPSS_REG_PHYS_BASE 0x12080000
+#define PPSS_WDOG_UNMASKED_INT_EN 0x1808
static struct dsps_clk_info dsps_clks[] = {};
static struct dsps_regulator_info dsps_regs[] = {};
@@ -3743,6 +3762,7 @@
.ddr_size = PPSS_DSPS_DDR_SIZE,
.smem_start = PPSS_SMEM_BASE,
.smem_size = PPSS_SMEM_SIZE,
+ .ppss_wdog_unmasked_int_en_reg = PPSS_WDOG_UNMASKED_INT_EN,
.signature = DSPS_SIGNATURE,
};
diff --git a/arch/arm/mach-msm/devices-msm7x27a.c b/arch/arm/mach-msm/devices-msm7x27a.c
index 343ea76..65dfc31 100644
--- a/arch/arm/mach-msm/devices-msm7x27a.c
+++ b/arch/arm/mach-msm/devices-msm7x27a.c
@@ -2022,6 +2022,7 @@
static struct notifier_block panic_handler = {
.notifier_call = msm7627a_panic_handler,
+ .priority = INT_MAX,
};
static int __init panic_register(void)
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index e66bf27..0506217 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -109,6 +109,10 @@
extern struct platform_device msm_device_sdc3;
extern struct platform_device msm_device_sdc4;
+extern struct platform_device msm8960_pc_cntr;
+extern struct platform_device msm8064_pc_cntr;
+extern struct platform_device msm8930_pc_cntr;
+
extern struct platform_device msm_device_gadget_peripheral;
extern struct platform_device msm_device_hsusb_host;
extern struct platform_device msm_device_hsusb_host2;
diff --git a/arch/arm/mach-msm/include/mach/camera.h b/arch/arm/mach-msm/include/mach/camera.h
index cf36388..f5a158f 100644
--- a/arch/arm/mach-msm/include/mach/camera.h
+++ b/arch/arm/mach-msm/include/mach/camera.h
@@ -95,6 +95,7 @@
VFE_MSG_OUTPUT_SECONDARY,
VFE_MSG_OUTPUT_TERTIARY1,
VFE_MSG_OUTPUT_TERTIARY2,
+ VFE_MSG_V2X_LIVESHOT_PRIMARY,
};
enum vpe_resp_msg {
diff --git a/arch/arm/mach-msm/include/mach/clk-provider.h b/arch/arm/mach-msm/include/mach/clk-provider.h
index 0da0b33..770713d 100644
--- a/arch/arm/mach-msm/include/mach/clk-provider.h
+++ b/arch/arm/mach-msm/include/mach/clk-provider.h
@@ -20,6 +20,7 @@
#include <linux/list.h>
#include <linux/clkdev.h>
#include <linux/spinlock.h>
+#include <linux/mutex.h>
#include <mach/clk.h>
/*
@@ -53,7 +54,7 @@
int (*set_vdd)(struct clk_vdd_class *v_class, int level);
int level_votes[MAX_VDD_LEVELS];
unsigned long cur_level;
- spinlock_t lock;
+ struct mutex lock;
};
#define DEFINE_VDD_CLASS(_name, _set_vdd) \
@@ -61,7 +62,7 @@
.class_name = #_name, \
.set_vdd = _set_vdd, \
.cur_level = ARRAY_SIZE(_name.level_votes), \
- .lock = __SPIN_LOCK_UNLOCKED(lock) \
+ .lock = __MUTEX_INITIALIZER(_name.lock) \
}
enum handoff {
diff --git a/arch/arm/mach-msm/include/mach/irqs-8974.h b/arch/arm/mach-msm/include/mach/irqs-8974.h
index d10b537..8152eca 100644
--- a/arch/arm/mach-msm/include/mach/irqs-8974.h
+++ b/arch/arm/mach-msm/include/mach/irqs-8974.h
@@ -24,9 +24,7 @@
#define GIC_PPI_START 16
#define GIC_SPI_START 32
-#define AVS_SVICINT (GIC_PPI_START + 6)
-#define AVS_SVICINTSWDONE (GIC_PPI_START + 7)
-#define INT_ARMQC_PERFMON (GIC_PPI_START + 10)
+#define INT_ARMQC_PERFMON (GIC_PPI_START + 7)
/* PPI 15 is unused */
#define APCC_QGICL2PERFMONIRPTREQ (GIC_SPI_START + 1)
diff --git a/arch/arm/mach-msm/include/mach/mdm2.h b/arch/arm/mach-msm/include/mach/mdm2.h
index 6ec12c1..fd63fd2 100644
--- a/arch/arm/mach-msm/include/mach/mdm2.h
+++ b/arch/arm/mach-msm/include/mach/mdm2.h
@@ -33,6 +33,7 @@
const unsigned int ramdump_timeout_ms;
int image_upgrade_supported;
struct gpiomux_setting *mdm2ap_status_gpio_run_cfg;
+ int send_shdn;
};
#endif
diff --git a/arch/arm/mach-msm/include/mach/msm_dsps.h b/arch/arm/mach-msm/include/mach/msm_dsps.h
index 0f9dba6..a876798 100644
--- a/arch/arm/mach-msm/include/mach/msm_dsps.h
+++ b/arch/arm/mach-msm/include/mach/msm_dsps.h
@@ -86,6 +86,7 @@
* @smem_start - start of the smem region as physical address
* @smem_size - size of the smem region in bytes
* @ppss_pause_reg - Offset to the PPSS_PAUSE register
+ * @ppss_wdog_unmasked_int_en_reg - Offset to PPSS_WDOG_UNMASKED_INT_EN register
* @signature - signature for validity check.
*/
struct msm_dsps_platform_data {
@@ -109,6 +110,7 @@
int smem_start;
int smem_size;
int ppss_pause_reg;
+ int ppss_wdog_unmasked_int_en_reg;
u32 signature;
};
diff --git a/arch/arm/mach-msm/include/mach/msm_hsusb.h b/arch/arm/mach-msm/include/mach/msm_hsusb.h
index 4e22b0f..c6eb527 100644
--- a/arch/arm/mach-msm/include/mach/msm_hsusb.h
+++ b/arch/arm/mach-msm/include/mach/msm_hsusb.h
@@ -138,6 +138,7 @@
int self_powered;
int is_phy_status_timer_on;
+ bool prop_chg;
};
struct msm_otg_platform_data {
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8092.h b/arch/arm/mach-msm/include/mach/msm_iomap-8092.h
index dec8a58..732aaff 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8092.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8092.h
@@ -23,7 +23,7 @@
*
*/
-#define MPQ8092_SHARED_RAM_PHYS 0x0FA00000
+#define MPQ8092_MSM_SHARED_RAM_PHYS 0x0FA00000
#define MPQ8092_QGIC_DIST_PHYS 0xF9000000
#define MPQ8092_QGIC_DIST_SIZE SZ_4K
diff --git a/arch/arm/mach-msm/include/mach/msm_smsm.h b/arch/arm/mach-msm/include/mach/msm_smsm.h
index 133a1b3..be8f6c1 100644
--- a/arch/arm/mach-msm/include/mach/msm_smsm.h
+++ b/arch/arm/mach-msm/include/mach/msm_smsm.h
@@ -97,47 +97,6 @@
#define SMSM_SUBSYS2AP_STATUS 0x00008000
-#ifdef CONFIG_MSM_SMD
-void *smem_alloc(unsigned id, unsigned size);
-#else
-void *smem_alloc(unsigned id, unsigned size)
-{
- return NULL;
-}
-#endif
-void *smem_alloc2(unsigned id, unsigned size_in);
-void *smem_get_entry(unsigned id, unsigned *size);
-int smsm_change_state(uint32_t smsm_entry,
- uint32_t clear_mask, uint32_t set_mask);
-
-/*
- * Changes the global interrupt mask. The set and clear masks are re-applied
- * every time the global interrupt mask is updated for callback registration
- * and de-registration.
- *
- * The clear mask is applied first, so if a bit is set to 1 in both the clear
- * mask and the set mask, the result will be that the interrupt is set.
- *
- * @smsm_entry SMSM entry to change
- * @clear_mask 1 = clear bit, 0 = no-op
- * @set_mask 1 = set bit, 0 = no-op
- *
- * @returns 0 for success, < 0 for error
- */
-int smsm_change_intr_mask(uint32_t smsm_entry,
- uint32_t clear_mask, uint32_t set_mask);
-int smsm_get_intr_mask(uint32_t smsm_entry, uint32_t *intr_mask);
-uint32_t smsm_get_state(uint32_t smsm_entry);
-int smsm_state_cb_register(uint32_t smsm_entry, uint32_t mask,
- void (*notify)(void *, uint32_t old_state, uint32_t new_state),
- void *data);
-int smsm_state_cb_deregister(uint32_t smsm_entry, uint32_t mask,
- void (*notify)(void *, uint32_t, uint32_t), void *data);
-void smsm_print_sleep_info(uint32_t sleep_delay, uint32_t sleep_limit,
- uint32_t irq_mask, uint32_t wakeup_reason, uint32_t pending_irqs);
-void smsm_reset_modem(unsigned mode);
-void smsm_reset_modem_cont(void);
-void smd_sleep_exit(void);
#define SMEM_NUM_SMD_STREAM_CHANNELS 64
#define SMEM_NUM_SMD_BLOCK_CHANNELS 64
@@ -250,8 +209,128 @@
SMSM_NUM_INTR_MUX = 8,
};
+#ifdef CONFIG_MSM_SMD
+void *smem_alloc(unsigned id, unsigned size);
+void *smem_alloc2(unsigned id, unsigned size_in);
+void *smem_get_entry(unsigned id, unsigned *size);
+int smsm_change_state(uint32_t smsm_entry,
+ uint32_t clear_mask, uint32_t set_mask);
+
+/*
+ * Changes the global interrupt mask. The set and clear masks are re-applied
+ * every time the global interrupt mask is updated for callback registration
+ * and de-registration.
+ *
+ * The clear mask is applied first, so if a bit is set to 1 in both the clear
+ * mask and the set mask, the result will be that the interrupt is set.
+ *
+ * @smsm_entry SMSM entry to change
+ * @clear_mask 1 = clear bit, 0 = no-op
+ * @set_mask 1 = set bit, 0 = no-op
+ *
+ * @returns 0 for success, < 0 for error
+ */
+int smsm_change_intr_mask(uint32_t smsm_entry,
+ uint32_t clear_mask, uint32_t set_mask);
+int smsm_get_intr_mask(uint32_t smsm_entry, uint32_t *intr_mask);
+uint32_t smsm_get_state(uint32_t smsm_entry);
+int smsm_state_cb_register(uint32_t smsm_entry, uint32_t mask,
+ void (*notify)(void *, uint32_t old_state, uint32_t new_state),
+ void *data);
+int smsm_state_cb_deregister(uint32_t smsm_entry, uint32_t mask,
+ void (*notify)(void *, uint32_t, uint32_t), void *data);
+void smsm_print_sleep_info(uint32_t sleep_delay, uint32_t sleep_limit,
+ uint32_t irq_mask, uint32_t wakeup_reason, uint32_t pending_irqs);
+void smsm_reset_modem(unsigned mode);
+void smsm_reset_modem_cont(void);
+void smd_sleep_exit(void);
+
+
int smsm_check_for_modem_crash(void);
void *smem_find(unsigned id, unsigned size);
void *smem_get_entry(unsigned id, unsigned *size);
+#else
+static inline void *smem_alloc(unsigned id, unsigned size)
+{
+ return NULL;
+}
+static inline void *smem_alloc2(unsigned id, unsigned size_in)
+{
+ return NULL;
+}
+
+static inline void *smem_get_entry(unsigned id, unsigned *size)
+{
+ return NULL;
+}
+
+static inline int smsm_change_state(uint32_t smsm_entry,
+ uint32_t clear_mask, uint32_t set_mask)
+{
+ return -ENODEV;
+}
+
+/*
+ * Changes the global interrupt mask. The set and clear masks are re-applied
+ * every time the global interrupt mask is updated for callback registration
+ * and de-registration.
+ *
+ * The clear mask is applied first, so if a bit is set to 1 in both the clear
+ * mask and the set mask, the result will be that the interrupt is set.
+ *
+ * @smsm_entry SMSM entry to change
+ * @clear_mask 1 = clear bit, 0 = no-op
+ * @set_mask 1 = set bit, 0 = no-op
+ *
+ * @returns 0 for success, < 0 for error
+ */
+static inline int smsm_change_intr_mask(uint32_t smsm_entry,
+ uint32_t clear_mask, uint32_t set_mask)
+{
+ return -ENODEV;
+}
+
+static inline int smsm_get_intr_mask(uint32_t smsm_entry, uint32_t *intr_mask)
+{
+ return -ENODEV;
+}
+static inline uint32_t smsm_get_state(uint32_t smsm_entry)
+{
+ return 0;
+}
+static inline int smsm_state_cb_register(uint32_t smsm_entry, uint32_t mask,
+ void (*notify)(void *, uint32_t old_state, uint32_t new_state),
+ void *data)
+{
+ return -ENODEV;
+}
+static inline int smsm_state_cb_deregister(uint32_t smsm_entry, uint32_t mask,
+ void (*notify)(void *, uint32_t, uint32_t), void *data)
+{
+ return -ENODEV;
+}
+static inline void smsm_print_sleep_info(uint32_t sleep_delay,
+ uint32_t sleep_limit, uint32_t irq_mask, uint32_t wakeup_reason,
+ uint32_t pending_irqs)
+{
+}
+static inline void smsm_reset_modem(unsigned mode)
+{
+}
+static inline void smsm_reset_modem_cont(void)
+{
+}
+static inline void smd_sleep_exit(void)
+{
+}
+static inline int smsm_check_for_modem_crash(void)
+{
+ return -ENODEV;
+}
+static inline void *smem_find(unsigned id, unsigned size)
+{
+ return NULL;
+}
+#endif
#endif
diff --git a/arch/arm/mach-msm/qdsp6v2/q6core.h b/arch/arm/mach-msm/include/mach/qdsp6v2/q6core.h
similarity index 81%
rename from arch/arm/mach-msm/qdsp6v2/q6core.h
rename to arch/arm/mach-msm/include/mach/qdsp6v2/q6core.h
index cb25d6b..ea345fb 100644
--- a/arch/arm/mach-msm/qdsp6v2/q6core.h
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/q6core.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
@@ -45,8 +45,18 @@
uint32_t power_collapse;
};
+#define ADSP_CMD_SET_DTS_MODEL_ID 0x00012917
+
+struct adsp_dts_modelid {
+ struct apr_hdr hdr;
+ uint32_t model_ID_size;
+ uint8_t model_ID[128];
+};
+
int core_req_bus_bandwith(u16 bus_id, u32 ab_bps, u32 ib_bps);
uint32_t core_get_adsp_version(void);
+uint32_t core_set_dts_model_id(uint32_t id_size, uint8_t *id);
+
#endif /* __Q6CORE_H__ */
diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c
index e0fec65..5ee7068 100644
--- a/arch/arm/mach-msm/io.c
+++ b/arch/arm/mach-msm/io.c
@@ -497,7 +497,7 @@
void __init msm_map_mpq8092_io(void)
{
- msm_shared_ram_phys = MSM8092_MSM_SHARED_RAM_PHYS;
+ msm_shared_ram_phys = MPQ8092_MSM_SHARED_RAM_PHYS;
msm_map_io(mpq8092_io_desc, ARRAY_SIZE(mpq8092_io_desc));
}
#endif /* CONFIG_ARCH_MPQ8092 */
diff --git a/arch/arm/mach-msm/mdm2.c b/arch/arm/mach-msm/mdm2.c
index f548417..77eeb53 100644
--- a/arch/arm/mach-msm/mdm2.c
+++ b/arch/arm/mach-msm/mdm2.c
@@ -110,8 +110,12 @@
/* Wait for the modem to complete its power down actions. */
for (i = 20; i > 0; i--) {
- if (gpio_get_value(mdm_drv->mdm2ap_status_gpio) == 0)
+ if (gpio_get_value(mdm_drv->mdm2ap_status_gpio) == 0) {
+ if (mdm_debug_mask & MDM_DEBUG_MASK_SHDN_LOG)
+ pr_info("%s: mdm2ap_status went low, i = %d\n",
+ __func__, i);
break;
+ }
msleep(100);
}
if (i == 0) {
diff --git a/arch/arm/mach-msm/mdm_common.c b/arch/arm/mach-msm/mdm_common.c
index ea15a17..58b26f2 100644
--- a/arch/arm/mach-msm/mdm_common.c
+++ b/arch/arm/mach-msm/mdm_common.c
@@ -290,6 +290,17 @@
} else
pr_debug("%s Image upgrade not supported\n", __func__);
break;
+ case SHUTDOWN_CHARM:
+ if (!mdm_drv->pdata->send_shdn)
+ break;
+ mdm_drv->mdm_ready = 0;
+ if (mdm_debug_mask & MDM_DEBUG_MASK_SHDN_LOG)
+ pr_info("Sending shutdown request to mdm\n");
+ ret = sysmon_send_shutdown(SYSMON_SS_EXT_MODEM);
+ if (ret)
+ pr_err("%s: Graceful shutdown of the external modem failed, ret = %d\n",
+ __func__, ret);
+ break;
default:
pr_err("%s: invalid ioctl cmd = %d\n", __func__, _IOC_NR(cmd));
ret = -EINVAL;
@@ -382,6 +393,9 @@
{
int value = gpio_get_value(mdm_drv->mdm2ap_status_gpio);
+ if ((mdm_debug_mask & MDM_DEBUG_MASK_SHDN_LOG) && (value == 0))
+ pr_info("%s: mdm2ap_status went low\n", __func__);
+
pr_debug("%s: mdm sent status change interrupt\n", __func__);
if (value == 0 && mdm_drv->mdm_ready == 1) {
pr_info("%s: unexpected reset external modem\n", __func__);
diff --git a/arch/arm/mach-msm/mdm_private.h b/arch/arm/mach-msm/mdm_private.h
index c406b89a..9e865c5 100644
--- a/arch/arm/mach-msm/mdm_private.h
+++ b/arch/arm/mach-msm/mdm_private.h
@@ -14,6 +14,7 @@
#define _ARCH_ARM_MACH_MSM_MDM_PRIVATE_H
#define MDM_DEBUG_MASK_VDDMIN_SETUP (0x00000002)
+#define MDM_DEBUG_MASK_SHDN_LOG (0x00000004)
#define GPIO_IS_VALID(gpio) \
(gpio != -1)
struct mdm_modem_drv;
diff --git a/arch/arm/mach-msm/modem-ssr-8974.c b/arch/arm/mach-msm/modem-ssr-8974.c
index fec578f..942eca5 100644
--- a/arch/arm/mach-msm/modem-ssr-8974.c
+++ b/arch/arm/mach-msm/modem-ssr-8974.c
@@ -15,10 +15,14 @@
#include <linux/module.h>
#include <linux/err.h>
+#include <mach/peripheral-loader.h>
#include <mach/subsystem_restart.h>
#include <mach/msm_smsm.h>
+#include "ramdump.h"
+
static int crash_shutdown;
+static int modem_ssr_ignore_errors;
static struct subsys_device *modem_ssr_dev;
#define MAX_SSR_REASON_LEN 81U
@@ -50,6 +54,7 @@
static void restart_modem(void)
{
log_modem_sfr();
+ modem_ssr_ignore_errors = 1;
subsystem_restart("modem");
}
@@ -67,11 +72,21 @@
static int modem_shutdown(const struct subsys_desc *subsys)
{
+ pil_force_shutdown("modem");
+ pil_force_shutdown("mba");
return 0;
}
static int modem_powerup(const struct subsys_desc *subsys)
{
+ /*
+ * At this time, the modem is shutdown. Therefore this function cannot
+ * run concurrently with either the watchdog bite error handler or the
+ * SMSM callback, making it safe to unset the flag below.
+ */
+ modem_ssr_ignore_errors = 0;
+ pil_force_boot("mba");
+ pil_force_boot("modem");
return 0;
}
@@ -81,15 +96,53 @@
smsm_reset_modem(SMSM_RESET);
}
-static int modem_ramdump(int enable,
- const struct subsys_desc *crashed_subsys)
+static struct ramdump_segment modem_segments[] = {
+ {0x08400000, 0x0D100000 - 0x08400000},
+};
+
+static struct ramdump_segment smem_segments[] = {
+ {0x0FA00000, 0x0FC00000 - 0x0FA00000},
+};
+
+static void *modem_ramdump_dev;
+static void *smem_ramdump_dev;
+
+static int modem_ramdump(int enable, const struct subsys_desc *crashed_subsys)
{
- return 0;
+ int ret = 0;
+
+ if (!enable)
+ return ret;
+
+ pil_force_boot("mba");
+
+ ret = do_ramdump(modem_ramdump_dev, modem_segments,
+ ARRAY_SIZE(modem_segments));
+
+ if (ret < 0) {
+ pr_err("Unable to dump modem fw memory (rc = %d).\n",
+ ret);
+ goto out;
+ }
+
+ ret = do_ramdump(smem_ramdump_dev, smem_segments,
+ ARRAY_SIZE(smem_segments));
+
+ if (ret < 0) {
+ pr_err("Unable to dump smem memory (rc = %d).\n", ret);
+ goto out;
+ }
+
+out:
+ pil_force_shutdown("mba");
+ return ret;
}
static irqreturn_t modem_wdog_bite_irq(int irq, void *dev_id)
{
- pr_err("Watchdog bite received from modem software!\n");
+ if (modem_ssr_ignore_errors)
+ return IRQ_HANDLED;
+ pr_err("Watchdog bite received from the modem!\n");
restart_modem();
return IRQ_HANDLED;
}
@@ -133,9 +186,27 @@
goto out;
}
+ modem_ramdump_dev = create_ramdump_device("modem");
+
+ if (!modem_ramdump_dev) {
+ pr_err("%s: Unable to create a modem ramdump device.\n",
+ __func__);
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ smem_ramdump_dev = create_ramdump_device("smem-modem");
+
+ if (!smem_ramdump_dev) {
+ pr_err("%s: Unable to create an smem ramdump device.\n",
+ __func__);
+ ret = -ENOMEM;
+ goto out;
+ }
+
pr_info("%s: modem subsystem restart driver init'ed.\n", __func__);
out:
return ret;
}
-arch_initcall(modem_8974_init);
+module_init(modem_8974_init);
diff --git a/arch/arm/mach-msm/mpm.c b/arch/arm/mach-msm/mpm.c
index 1c39415..5127607 100644
--- a/arch/arm/mach-msm/mpm.c
+++ b/arch/arm/mach-msm/mpm.c
@@ -388,6 +388,7 @@
{
unsigned long *apps_irq_bitmap;
int debug_mask;
+ int i = 0;
if (from_idle) {
apps_irq_bitmap = msm_mpm_enabled_apps_irqs;
@@ -400,15 +401,17 @@
}
if (debug_mask) {
- static char buf[DIV_ROUND_UP(MSM_MPM_NR_APPS_IRQS, 32)*9+1];
+ i = find_first_bit(apps_irq_bitmap, MSM_MPM_NR_APPS_IRQS);
+ while (i < MSM_MPM_NR_APPS_IRQS) {
+ struct irq_desc *desc = i ?
+ irq_to_desc(i) : NULL;
+ pr_info("%s: cannot monitor irq=%d %s\n",
+ __func__, i, desc->name);
+ i = find_next_bit(apps_irq_bitmap,
+ MSM_MPM_NR_APPS_IRQS, i + 1);
+ }
- bitmap_scnprintf(buf, sizeof(buf), apps_irq_bitmap,
- MSM_MPM_NR_APPS_IRQS);
- buf[sizeof(buf) - 1] = '\0';
-
- pr_info("%s: cannot monitor %s", __func__, buf);
}
-
return (bool)__bitmap_empty(apps_irq_bitmap, MSM_MPM_NR_APPS_IRQS);
}
diff --git a/arch/arm/mach-msm/msm_dsps.c b/arch/arm/mach-msm/msm_dsps.c
index 6dde576..c39829b 100644
--- a/arch/arm/mach-msm/msm_dsps.c
+++ b/arch/arm/mach-msm/msm_dsps.c
@@ -45,7 +45,7 @@
#include "timer.h"
#define DRV_NAME "msm_dsps"
-#define DRV_VERSION "4.02"
+#define DRV_VERSION "4.03"
#define PPSS_TIMER0_32KHZ_REG 0x1004
@@ -771,6 +771,11 @@
{
pr_debug("%s\n", __func__);
disable_irq_nosync(drv->wdog_irq);
+ if (drv->pdata->ppss_wdog_unmasked_int_en_reg) {
+ writel_relaxed(0, (drv->ppss_base+
+ drv->pdata->ppss_wdog_unmasked_int_en_reg));
+ mb(); /* Make sure wdog is disabled before shutting down */
+ }
pil_force_shutdown(drv->pdata->pil_name);
dsps_power_off_handler();
return 0;
@@ -799,6 +804,7 @@
static void dsps_crash_shutdown(const struct subsys_desc *subsys)
{
pr_debug("%s\n", __func__);
+ disable_irq_nosync(drv->wdog_irq);
dsps_crash_shutdown_g = 1;
smsm_change_state(SMSM_DSPS_STATE, SMSM_RESET, SMSM_RESET);
}
diff --git a/arch/arm/mach-msm/ocmem_core.c b/arch/arm/mach-msm/ocmem_core.c
index 5a85eec..9a85a17 100644
--- a/arch/arm/mach-msm/ocmem_core.c
+++ b/arch/arm/mach-msm/ocmem_core.c
@@ -856,7 +856,7 @@
/* Interfaces invoked from the scheduler */
int ocmem_memory_off(int id, unsigned long offset, unsigned long len)
{
- return switch_power_state(id, offset, len, REGION_DEFAULT_OFF);
+ return switch_power_state(id, offset, len, REGION_DEFAULT_ON);
}
int ocmem_memory_on(int id, unsigned long offset, unsigned long len)
@@ -866,7 +866,7 @@
int ocmem_memory_retain(int id, unsigned long offset, unsigned long len)
{
- return switch_power_state(id, offset, len, REGION_DEFAULT_RETENTION);
+ return switch_power_state(id, offset, len, REGION_DEFAULT_ON);
}
static int ocmem_power_show_sw_state(struct seq_file *f, void *dummy)
diff --git a/arch/arm/mach-msm/pil-mba.c b/arch/arm/mach-msm/pil-mba.c
index 5e67d4f..0207f0b 100644
--- a/arch/arm/mach-msm/pil-mba.c
+++ b/arch/arm/mach-msm/pil-mba.c
@@ -172,7 +172,7 @@
return -ENOMEM;
platform_set_drvdata(pdev, drv);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rmb_base");
if (!res)
return -EINVAL;
drv->reg_base = devm_ioremap(&pdev->dev, res->start,
@@ -180,7 +180,8 @@
if (!drv->reg_base)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+ "metadata_base");
if (res) {
drv->metadata_base = devm_ioremap(&pdev->dev, res->start,
resource_size(res));
diff --git a/arch/arm/mach-msm/pil-pronto.c b/arch/arm/mach-msm/pil-pronto.c
index 01cdb0b..1e39043 100644
--- a/arch/arm/mach-msm/pil-pronto.c
+++ b/arch/arm/mach-msm/pil-pronto.c
@@ -233,7 +233,7 @@
int ret;
uint32_t regval;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pmu_base");
if (!res)
return -EINVAL;
@@ -246,14 +246,14 @@
if (!drv->base)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "clk_base");
if (!res)
return -EINVAL;
drv->reset_base = devm_ioremap(&pdev->dev, res->start,
resource_size(res));
- res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "halt_base");
if (!res)
return -EINVAL;
diff --git a/arch/arm/mach-msm/pil-q6v5-mss.c b/arch/arm/mach-msm/pil-q6v5-mss.c
index 1fdd342..7b45a0e 100644
--- a/arch/arm/mach-msm/pil-q6v5-mss.c
+++ b/arch/arm/mach-msm/pil-q6v5-mss.c
@@ -266,20 +266,21 @@
of_property_read_u32(pdev->dev.of_node, "qcom,pil-self-auth",
&drv->self_auth);
if (drv->self_auth) {
- res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+ "rmb_base");
drv->rmb_base = devm_ioremap(&pdev->dev, res->start,
resource_size(res));
if (!drv->rmb_base)
return -ENOMEM;
}
- res = platform_get_resource(pdev, IORESOURCE_MEM, 3);
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "restart_reg");
drv->restart_reg = devm_ioremap(&pdev->dev, res->start,
resource_size(res));
if (!drv->restart_reg)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 4);
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "clamp_reg");
drv->io_clamp_reg = devm_ioremap(&pdev->dev, res->start,
resource_size(res));
if (!drv->io_clamp_reg)
diff --git a/arch/arm/mach-msm/pil-q6v5.c b/arch/arm/mach-msm/pil-q6v5.c
index 772031b..f4e8844 100644
--- a/arch/arm/mach-msm/pil-q6v5.c
+++ b/arch/arm/mach-msm/pil-q6v5.c
@@ -205,14 +205,14 @@
return ERR_PTR(-ENOMEM);
platform_set_drvdata(pdev, drv);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qdsp6_base");
if (!res)
return ERR_PTR(-EINVAL);
drv->reg_base = devm_ioremap(&pdev->dev, res->start,
resource_size(res));
if (!drv->reg_base)
return ERR_PTR(-ENOMEM);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "halt_base");
drv->axi_halt_base = devm_ioremap(&pdev->dev, res->start,
resource_size(res));
if (!drv->axi_halt_base)
diff --git a/arch/arm/mach-msm/pil-venus.c b/arch/arm/mach-msm/pil-venus.c
index 1ccde72..e331296 100644
--- a/arch/arm/mach-msm/pil-venus.c
+++ b/arch/arm/mach-msm/pil-venus.c
@@ -388,7 +388,8 @@
struct pil_desc *desc;
int rc;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+ "wrapper_base");
if (!res)
return -EINVAL;
@@ -402,7 +403,7 @@
if (!drv->venus_wrapper_base)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vbif_base");
if (!res)
return -EINVAL;
diff --git a/arch/arm/mach-msm/qdsp5/adsp_driver.c b/arch/arm/mach-msm/qdsp5/adsp_driver.c
index 9d261ae..6419bd0 100644
--- a/arch/arm/mach-msm/qdsp5/adsp_driver.c
+++ b/arch/arm/mach-msm/qdsp5/adsp_driver.c
@@ -139,7 +139,7 @@
pr_err("%s: could not get flags for the handle\n", __func__);
goto flag_error;
}
- temp_ptr = ion_map_kernel(region->client, region->handle, ionflag);
+ temp_ptr = ion_map_kernel(region->client, region->handle);
if (IS_ERR_OR_NULL(temp_ptr)) {
pr_err("%s: could not get virtual address\n", __func__);
goto map_error;
@@ -267,7 +267,7 @@
module->name, vaddr, len);
return ret;
}
- if ((region->ion_flag == CACHED) && region->handle) {
+ if ((region->ion_flag == ION_FLAG_CACHED) && region->handle) {
len = ((((len) + 31) & (~31)) + 32);
ret = msm_ion_do_cache_op(region->client, region->handle,
(void *)paddr, len, cmd);
diff --git a/arch/arm/mach-msm/qdsp5/audio_aac.c b/arch/arm/mach-msm/qdsp5/audio_aac.c
index ac7cca3..46a80d7 100644
--- a/arch/arm/mach-msm/qdsp5/audio_aac.c
+++ b/arch/arm/mach-msm/qdsp5/audio_aac.c
@@ -1716,7 +1716,7 @@
MM_DBG("allocating mem sz = %d\n", mem_sz);
handle = ion_alloc(client, mem_sz, SZ_4K,
- ION_HEAP(ION_AUDIO_HEAP_ID));
+ ION_HEAP(ION_AUDIO_HEAP_ID), 0);
if (IS_ERR_OR_NULL(handle)) {
MM_ERR("Unable to create allocate O/P buffers\n");
rc = -ENOMEM;
@@ -1742,7 +1742,7 @@
goto output_buff_get_flags_error;
}
- audio->map_v_write = ion_map_kernel(client, handle, ionflag);
+ audio->map_v_write = ion_map_kernel(client, handle);
if (IS_ERR(audio->map_v_write)) {
MM_ERR("could not map write buffers,freeing instance 0x%08x\n",
(int)audio);
@@ -1758,7 +1758,7 @@
mem_sz = (PCM_BUFSZ_MIN * PCM_BUF_MAX_COUNT);
MM_DBG("allocating mem sz = %d\n", mem_sz);
handle = ion_alloc(client, mem_sz,
- SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID));
+ SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID), 0);
if (IS_ERR_OR_NULL(handle)) {
MM_ERR("Unable to create allocate I/P buffers\n");
rc = -ENOMEM;
@@ -1785,8 +1785,7 @@
goto input_buff_get_flags_error;
}
- audio->map_v_read = ion_map_kernel(client,
- handle, ionflag);
+ audio->map_v_read = ion_map_kernel(client, handle);
if (IS_ERR(audio->map_v_read)) {
MM_ERR("could not map read buffers, freeing instance \
0x%08x\n", (int)audio);
diff --git a/arch/arm/mach-msm/qdsp5/audio_aac_in.c b/arch/arm/mach-msm/qdsp5/audio_aac_in.c
index 2e64a09..c86c1dd 100644
--- a/arch/arm/mach-msm/qdsp5/audio_aac_in.c
+++ b/arch/arm/mach-msm/qdsp5/audio_aac_in.c
@@ -1370,7 +1370,7 @@
MM_DBG("allocating mem sz = %d\n", dma_size);
handle = ion_alloc(client, dma_size, SZ_4K,
- ION_HEAP(ION_AUDIO_HEAP_ID));
+ ION_HEAP(ION_AUDIO_HEAP_ID), 0);
if (IS_ERR_OR_NULL(handle)) {
MM_ERR("Unable to create allocate O/P buffers\n");
rc = -ENOMEM;
@@ -1398,7 +1398,7 @@
goto output_buff_get_flags_error;
}
- audio->map_v_read = ion_map_kernel(client, handle, ionflag);
+ audio->map_v_read = ion_map_kernel(client, handle);
if (IS_ERR(audio->map_v_read)) {
MM_ERR("could not map read buffers,freeing instance 0x%08x\n",
(int)audio);
@@ -1414,7 +1414,7 @@
MM_DBG("allocating BUFFER_SIZE %d\n", BUFFER_SIZE);
handle = ion_alloc(client, BUFFER_SIZE,
- SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID));
+ SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID), 0);
if (IS_ERR_OR_NULL(handle)) {
MM_ERR("Unable to create allocate I/P buffers\n");
rc = -ENOMEM;
@@ -1444,8 +1444,7 @@
goto input_buff_get_flags_error;
}
- audio->map_v_write = ion_map_kernel(client,
- handle, ionflag);
+ audio->map_v_write = ion_map_kernel(client, handle);
if (IS_ERR(audio->map_v_write)) {
MM_ERR("could not map write buffers\n");
rc = -ENOMEM;
diff --git a/arch/arm/mach-msm/qdsp5/audio_ac3.c b/arch/arm/mach-msm/qdsp5/audio_ac3.c
index 63904fb..e453ec5 100644
--- a/arch/arm/mach-msm/qdsp5/audio_ac3.c
+++ b/arch/arm/mach-msm/qdsp5/audio_ac3.c
@@ -1029,7 +1029,7 @@
handle = ion_alloc(audio->client,
(config.buffer_size *
config.buffer_count),
- SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID));
+ SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID), 0);
if (IS_ERR_OR_NULL(handle)) {
MM_ERR("Unable to alloc I/P buffs\n");
audio->input_buff_handle = NULL;
@@ -1067,8 +1067,7 @@
}
audio->map_v_read = ion_map_kernel(
- audio->client,
- handle, ionflag);
+ audio->client, handle);
if (IS_ERR(audio->map_v_read)) {
MM_ERR("map of read buf failed\n");
ion_free(audio->client, handle);
@@ -1588,7 +1587,7 @@
audio->client = client;
handle = ion_alloc(client, DMASZ, SZ_4K,
- ION_HEAP(ION_AUDIO_HEAP_ID));
+ ION_HEAP(ION_AUDIO_HEAP_ID), 0);
if (IS_ERR_OR_NULL(handle)) {
MM_ERR("Unable to create allocate O/P buffers\n");
rc = -ENOMEM;
@@ -1614,7 +1613,7 @@
goto output_buff_get_flags_error;
}
- audio->map_v_write = ion_map_kernel(client, handle, ionflag);
+ audio->map_v_write = ion_map_kernel(client, handle);
if (IS_ERR(audio->map_v_write)) {
MM_ERR("could not map write buffers,freeing instance 0x%08x\n",
(int)audio);
diff --git a/arch/arm/mach-msm/qdsp5/audio_amrnb.c b/arch/arm/mach-msm/qdsp5/audio_amrnb.c
index 8aa102a..0792e3f 100644
--- a/arch/arm/mach-msm/qdsp5/audio_amrnb.c
+++ b/arch/arm/mach-msm/qdsp5/audio_amrnb.c
@@ -981,7 +981,7 @@
handle = ion_alloc(audio->client,
(config.buffer_size *
config.buffer_count),
- SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID));
+ SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID), 0);
if (IS_ERR_OR_NULL(handle)) {
MM_ERR("Unable to alloc I/P buffs\n");
audio->input_buff_handle = NULL;
@@ -1018,8 +1018,7 @@
break;
}
audio->map_v_read = ion_map_kernel(
- audio->client,
- handle, ionflag);
+ audio->client, handle);
if (IS_ERR(audio->map_v_read)) {
MM_ERR("failed to map read buf\n");
ion_free(audio->client, handle);
@@ -1536,7 +1535,7 @@
audio->client = client;
handle = ion_alloc(client, mem_sz, SZ_4K,
- ION_HEAP(ION_AUDIO_HEAP_ID));
+ ION_HEAP(ION_AUDIO_HEAP_ID), 0);
if (IS_ERR_OR_NULL(handle)) {
MM_ERR("Unable to create allocate O/P buffers\n");
rc = -ENOMEM;
@@ -1562,7 +1561,7 @@
goto output_buff_get_flags_error;
}
- audio->map_v_write = ion_map_kernel(client, handle, ionflag);
+ audio->map_v_write = ion_map_kernel(client, handle);
if (IS_ERR(audio->map_v_write)) {
MM_ERR("could not map write buffers\n");
rc = -ENOMEM;
diff --git a/arch/arm/mach-msm/qdsp5/audio_amrnb_in.c b/arch/arm/mach-msm/qdsp5/audio_amrnb_in.c
index 4effc8e..0742686 100644
--- a/arch/arm/mach-msm/qdsp5/audio_amrnb_in.c
+++ b/arch/arm/mach-msm/qdsp5/audio_amrnb_in.c
@@ -1336,7 +1336,7 @@
if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) {
MM_DBG("allocating BUFFER_SIZE %d\n", BUFFER_SIZE);
handle = ion_alloc(client, BUFFER_SIZE,
- SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID));
+ SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID), 0);
if (IS_ERR_OR_NULL(handle)) {
MM_ERR("Unable to create allocate write buffers\n");
rc = -ENOMEM;
@@ -1366,8 +1366,7 @@
goto input_buff_get_flags_error;
}
- audio->map_v_write = ion_map_kernel(client,
- handle, ionflag);
+ audio->map_v_write = ion_map_kernel(client, handle);
if (IS_ERR(audio->map_v_write)) {
MM_ERR("could not map write buffers\n");
rc = -ENOMEM;
diff --git a/arch/arm/mach-msm/qdsp5/audio_amrwb.c b/arch/arm/mach-msm/qdsp5/audio_amrwb.c
index 83320f3..7d37cea 100644
--- a/arch/arm/mach-msm/qdsp5/audio_amrwb.c
+++ b/arch/arm/mach-msm/qdsp5/audio_amrwb.c
@@ -977,7 +977,7 @@
handle = ion_alloc(audio->client,
(config.buffer_size *
config.buffer_count),
- SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID));
+ SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID), 0);
if (IS_ERR_OR_NULL(handle)) {
MM_ERR("Unable to alloc I/P buffs\n");
audio->input_buff_handle = NULL;
@@ -1014,8 +1014,7 @@
break;
}
audio->map_v_read = ion_map_kernel(
- audio->client,
- handle, ionflag);
+ audio->client, handle);
if (IS_ERR(audio->map_v_read)) {
MM_ERR("failed to map mem for read buf\n");
ion_free(audio->client, handle);
@@ -1600,7 +1599,7 @@
audio->client = client;
handle = ion_alloc(client, mem_sz, SZ_4K,
- ION_HEAP(ION_AUDIO_HEAP_ID));
+ ION_HEAP(ION_AUDIO_HEAP_ID), 0);
if (IS_ERR_OR_NULL(handle)) {
MM_ERR("Unable to create allocate O/P buffers\n");
goto output_buff_alloc_error;
@@ -1625,7 +1624,7 @@
goto output_buff_get_flags_error;
}
- audio->map_v_write = ion_map_kernel(client, handle, ionflag);
+ audio->map_v_write = ion_map_kernel(client, handle);
if (IS_ERR(audio->map_v_write)) {
MM_ERR("could not map write buffers\n");
rc = -ENOMEM;
diff --git a/arch/arm/mach-msm/qdsp5/audio_evrc.c b/arch/arm/mach-msm/qdsp5/audio_evrc.c
index c0486db..155b0e1 100644
--- a/arch/arm/mach-msm/qdsp5/audio_evrc.c
+++ b/arch/arm/mach-msm/qdsp5/audio_evrc.c
@@ -966,7 +966,7 @@
handle = ion_alloc(audio->client,
(config.buffer_size *
config.buffer_count),
- SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID));
+ SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID), 0);
if (IS_ERR_OR_NULL(handle)) {
MM_ERR("Unable to alloc I/P buffs\n");
audio->input_buff_handle = NULL;
@@ -1003,8 +1003,7 @@
break;
}
audio->map_v_read = ion_map_kernel(
- audio->client,
- handle, ionflag);
+ audio->client, handle);
if (IS_ERR(audio->map_v_read)) {
MM_ERR("failed to map mem"
" for read buf\n");
@@ -1527,7 +1526,7 @@
audio->client = client;
handle = ion_alloc(client, mem_sz, SZ_4K,
- ION_HEAP(ION_AUDIO_HEAP_ID));
+ ION_HEAP(ION_AUDIO_HEAP_ID), 0);
if (IS_ERR_OR_NULL(handle)) {
MM_ERR("Unable to create allocate O/P buffers\n");
rc = -ENOMEM;
@@ -1553,7 +1552,7 @@
goto output_buff_get_flags_error;
}
- audio->map_v_write = ion_map_kernel(client, handle, ionflag);
+ audio->map_v_write = ion_map_kernel(client, handle);
if (IS_ERR(audio->map_v_write)) {
MM_ERR("could not map write buffers\n");
rc = -ENOMEM;
diff --git a/arch/arm/mach-msm/qdsp5/audio_evrc_in.c b/arch/arm/mach-msm/qdsp5/audio_evrc_in.c
index 9bf0e83..89ad974 100644
--- a/arch/arm/mach-msm/qdsp5/audio_evrc_in.c
+++ b/arch/arm/mach-msm/qdsp5/audio_evrc_in.c
@@ -1310,7 +1310,7 @@
MM_DBG("allocating mem sz = %d\n", dma_size);
handle = ion_alloc(client, dma_size, SZ_4K,
- ION_HEAP(ION_AUDIO_HEAP_ID));
+ ION_HEAP(ION_AUDIO_HEAP_ID), 0);
if (IS_ERR_OR_NULL(handle)) {
MM_ERR("Unable to create allocate O/P buffers\n");
rc = -ENOMEM;
@@ -1338,7 +1338,7 @@
goto output_buff_get_flags_error;
}
- audio->map_v_read = ion_map_kernel(client, handle, ionflag);
+ audio->map_v_read = ion_map_kernel(client, handle);
if (IS_ERR(audio->map_v_read)) {
MM_ERR("could not map read buffers,freeing instance 0x%08x\n",
(int)audio);
@@ -1353,7 +1353,7 @@
if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) {
MM_DBG("allocating BUFFER_SIZE %d\n", BUFFER_SIZE);
handle = ion_alloc(client, BUFFER_SIZE,
- SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID));
+ SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID), 0);
if (IS_ERR_OR_NULL(handle)) {
MM_ERR("Unable to create allocate I/P buffers\n");
rc = -ENOMEM;
@@ -1383,8 +1383,7 @@
goto input_buff_alloc_error;
}
- audio->map_v_write = ion_map_kernel(client,
- handle, ionflag);
+ audio->map_v_write = ion_map_kernel(client, handle);
if (IS_ERR(audio->map_v_write)) {
MM_ERR("could not map write buffers\n");
rc = -ENOMEM;
diff --git a/arch/arm/mach-msm/qdsp5/audio_lpa.c b/arch/arm/mach-msm/qdsp5/audio_lpa.c
index a067b83..8120d7b 100644
--- a/arch/arm/mach-msm/qdsp5/audio_lpa.c
+++ b/arch/arm/mach-msm/qdsp5/audio_lpa.c
@@ -741,7 +741,7 @@
pr_err("%s: could not get flags for the handle\n", __func__);
goto flag_error;
}
- kvaddr = (unsigned long)ion_map_kernel(audio->client, handle, ionflag);
+ kvaddr = (unsigned long)ion_map_kernel(audio->client, handle);
if (IS_ERR_OR_NULL((void *)kvaddr)) {
pr_err("%s: could not get virtual address\n", __func__);
goto map_error;
diff --git a/arch/arm/mach-msm/qdsp5/audio_mp3.c b/arch/arm/mach-msm/qdsp5/audio_mp3.c
index cef3d99..b8c64be 100644
--- a/arch/arm/mach-msm/qdsp5/audio_mp3.c
+++ b/arch/arm/mach-msm/qdsp5/audio_mp3.c
@@ -1095,7 +1095,7 @@
goto flag_error;
}
- temp_ptr = ion_map_kernel(audio->client, handle, ionflag);
+ temp_ptr = ion_map_kernel(audio->client, handle);
if (IS_ERR_OR_NULL(temp_ptr)) {
pr_err("%s: could not get virtual address\n", __func__);
goto map_error;
@@ -1525,7 +1525,7 @@
handle = ion_alloc(audio->client,
(config.buffer_size *
config.buffer_count),
- SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID));
+ SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID), 0);
if (IS_ERR_OR_NULL(handle)) {
MM_ERR("Unable to alloc I/P buffs\n");
rc = -ENOMEM;
@@ -1558,8 +1558,7 @@
}
audio->map_v_read = ion_map_kernel(
- audio->client,
- handle, ionflag);
+ audio->client, handle);
if (IS_ERR(audio->map_v_read)) {
MM_ERR("map of read buf failed\n");
@@ -2254,7 +2253,7 @@
MM_DBG("memsz = %d\n", mem_sz);
handle = ion_alloc(client, mem_sz, SZ_4K,
- ION_HEAP(ION_AUDIO_HEAP_ID));
+ ION_HEAP(ION_AUDIO_HEAP_ID), 0);
if (IS_ERR_OR_NULL(handle)) {
MM_ERR("Unable to create allocate O/P buffers\n");
rc = -ENOMEM;
@@ -2280,7 +2279,7 @@
goto output_buff_get_flags_error;
}
- audio->map_v_write = ion_map_kernel(client, handle, ionflag);
+ audio->map_v_write = ion_map_kernel(client, handle);
if (IS_ERR(audio->map_v_write)) {
MM_ERR("could not map write buffers\n");
rc = -ENOMEM;
diff --git a/arch/arm/mach-msm/qdsp5/audio_mvs.c b/arch/arm/mach-msm/qdsp5/audio_mvs.c
index 158dd46..c0e670c 100644
--- a/arch/arm/mach-msm/qdsp5/audio_mvs.c
+++ b/arch/arm/mach-msm/qdsp5/audio_mvs.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* 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
@@ -1187,6 +1187,9 @@
rpc_hdr_len);
break;
+ } else if ((rpc_hdr_len == 0) &&
+ (audio->state == AUDIO_MVS_CLOSED)) {
+ break;
} else if (rpc_hdr_len < RPC_COMMON_HDR_SZ) {
continue;
} else {
@@ -1353,8 +1356,11 @@
mutex_lock(&audio->lock);
if (audio->state == AUDIO_MVS_STARTED)
audio_mvs_stop(audio);
- audio_mvs_free_buf(audio);
audio->state = AUDIO_MVS_CLOSED;
+ msm_rpc_read_wakeup(audio->rpc_endpt);
+ msm_rpc_close(audio->rpc_endpt);
+ audio->task = NULL;
+ audio_mvs_free_buf(audio);
mutex_unlock(&audio->lock);
MM_DBG("Release done\n");
diff --git a/arch/arm/mach-msm/qdsp5/audio_pcm.c b/arch/arm/mach-msm/qdsp5/audio_pcm.c
index 340bcc6..3eb72c8 100644
--- a/arch/arm/mach-msm/qdsp5/audio_pcm.c
+++ b/arch/arm/mach-msm/qdsp5/audio_pcm.c
@@ -823,7 +823,7 @@
pr_err("%s: could not get flags for the handle\n", __func__);
goto flag_error;
}
- kvaddr = (unsigned long)ion_map_kernel(audio->client, handle, ionflag);
+ kvaddr = (unsigned long)ion_map_kernel(audio->client, handle);
if (IS_ERR_OR_NULL((void *)kvaddr)) {
pr_err("%s: could not get virtual address\n", __func__);
goto map_error;
@@ -1576,7 +1576,7 @@
MM_DBG("memsz = %d\n", mem_sz);
handle = ion_alloc(client, mem_sz, SZ_4K,
- ION_HEAP(ION_AUDIO_HEAP_ID));
+ ION_HEAP(ION_AUDIO_HEAP_ID), 0);
if (IS_ERR_OR_NULL(handle)) {
MM_ERR("Unable to create allocate O/P buffers\n");
rc = -ENOMEM;
@@ -1602,7 +1602,7 @@
goto output_buff_get_flags_error;
}
- audio->map_v_write = ion_map_kernel(client, handle, ionflag);
+ audio->map_v_write = ion_map_kernel(client, handle);
if (IS_ERR(audio->map_v_write)) {
MM_ERR("could not map write buffers\n");
rc = -ENOMEM;
diff --git a/arch/arm/mach-msm/qdsp5/audio_pcm_in.c b/arch/arm/mach-msm/qdsp5/audio_pcm_in.c
index 2da1f19..68ffcfef 100644
--- a/arch/arm/mach-msm/qdsp5/audio_pcm_in.c
+++ b/arch/arm/mach-msm/qdsp5/audio_pcm_in.c
@@ -843,7 +843,7 @@
MM_DBG("allocating mem sz = %d\n", DMASZ);
handle = ion_alloc(client, DMASZ, SZ_4K,
- ION_HEAP(ION_AUDIO_HEAP_ID));
+ ION_HEAP(ION_AUDIO_HEAP_ID), 0);
if (IS_ERR_OR_NULL(handle)) {
MM_ERR("Unable to create allocate O/P buffers\n");
rc = -ENOMEM;
@@ -871,7 +871,7 @@
goto output_buff_get_flags_error;
}
- audio->data = ion_map_kernel(client, handle, ionflag);
+ audio->data = ion_map_kernel(client, handle);
if (IS_ERR(audio->data)) {
MM_ERR("could not map read buffers,freeing instance 0x%08x\n",
(int)audio);
diff --git a/arch/arm/mach-msm/qdsp5/audio_qcelp.c b/arch/arm/mach-msm/qdsp5/audio_qcelp.c
index 1a0c333..876c909 100644
--- a/arch/arm/mach-msm/qdsp5/audio_qcelp.c
+++ b/arch/arm/mach-msm/qdsp5/audio_qcelp.c
@@ -967,7 +967,7 @@
handle = ion_alloc(audio->client,
(config.buffer_size *
config.buffer_count),
- SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID));
+ SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID), 0);
if (IS_ERR_OR_NULL(handle)) {
MM_ERR("Unable to alloc I/P buffs\n");
audio->input_buff_handle = NULL;
@@ -1004,8 +1004,7 @@
break;
}
audio->map_v_read = ion_map_kernel(
- audio->client,
- handle, ionflag);
+ audio->client, handle);
if (IS_ERR(audio->map_v_read)) {
MM_ERR("failed to map read buf\n");
ion_free(audio->client, handle);
@@ -1525,7 +1524,7 @@
audio->client = client;
handle = ion_alloc(client, mem_sz, SZ_4K,
- ION_HEAP(ION_AUDIO_HEAP_ID));
+ ION_HEAP(ION_AUDIO_HEAP_ID), 0);
if (IS_ERR_OR_NULL(handle)) {
MM_ERR("Unable to create allocate O/P buffers\n");
rc = -ENOMEM;
@@ -1551,7 +1550,7 @@
goto output_buff_get_flags_error;
}
- audio->map_v_write = ion_map_kernel(client, handle, ionflag);
+ audio->map_v_write = ion_map_kernel(client, handle);
if (IS_ERR(audio->map_v_write)) {
MM_ERR("could not map write buffers\n");
rc = -ENOMEM;
diff --git a/arch/arm/mach-msm/qdsp5/audio_qcelp_in.c b/arch/arm/mach-msm/qdsp5/audio_qcelp_in.c
index ee079bc..6ca3382 100644
--- a/arch/arm/mach-msm/qdsp5/audio_qcelp_in.c
+++ b/arch/arm/mach-msm/qdsp5/audio_qcelp_in.c
@@ -1312,7 +1312,7 @@
MM_DBG("allocating mem sz = %d\n", dma_size);
handle = ion_alloc(client, dma_size, SZ_4K,
- ION_HEAP(ION_AUDIO_HEAP_ID));
+ ION_HEAP(ION_AUDIO_HEAP_ID), 0);
if (IS_ERR_OR_NULL(handle)) {
MM_ERR("Unable to create allocate O/P buffers\n");
rc = -ENOMEM;
@@ -1340,7 +1340,7 @@
goto output_buff_get_flags_error;
}
- audio->map_v_read = ion_map_kernel(client, handle, ionflag);
+ audio->map_v_read = ion_map_kernel(client, handle);
if (IS_ERR(audio->map_v_read)) {
MM_ERR("could not map read buffers,freeing instance 0x%08x\n",
(int)audio);
@@ -1355,7 +1355,7 @@
if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) {
MM_DBG("allocating BUFFER_SIZE %d\n", BUFFER_SIZE);
handle = ion_alloc(client, BUFFER_SIZE,
- SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID));
+ SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID), 0);
if (IS_ERR_OR_NULL(handle)) {
MM_ERR("Unable to create allocate I/P buffers\n");
rc = -ENOMEM;
@@ -1385,8 +1385,7 @@
goto input_buff_get_flags_error;
}
- audio->map_v_write = ion_map_kernel(client,
- handle, ionflag);
+ audio->map_v_write = ion_map_kernel(client, handle);
if (IS_ERR(audio->map_v_write)) {
MM_ERR("could not map write buffers\n");
rc = -ENOMEM;
diff --git a/arch/arm/mach-msm/qdsp5/audio_wma.c b/arch/arm/mach-msm/qdsp5/audio_wma.c
index 0a77b58..6d520b4 100644
--- a/arch/arm/mach-msm/qdsp5/audio_wma.c
+++ b/arch/arm/mach-msm/qdsp5/audio_wma.c
@@ -1045,7 +1045,7 @@
handle = ion_alloc(audio->client,
(config.buffer_size *
config.buffer_count),
- SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID));
+ SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID), 0);
if (IS_ERR_OR_NULL(handle)) {
MM_ERR("Unable to alloc I/P buffs\n");
audio->input_buff_handle = NULL;
@@ -1083,8 +1083,7 @@
}
audio->map_v_read = ion_map_kernel(
- audio->client,
- handle, ionflag);
+ audio->client, handle);
if (IS_ERR(audio->map_v_read)) {
MM_ERR("map of read buf failed\n");
ion_free(audio->client, handle);
@@ -1678,7 +1677,7 @@
audio->client = client;
handle = ion_alloc(client, mem_sz, SZ_4K,
- ION_HEAP(ION_AUDIO_HEAP_ID));
+ ION_HEAP(ION_AUDIO_HEAP_ID), 0);
if (IS_ERR_OR_NULL(handle)) {
MM_ERR("Unable to create allocate O/P buffers\n");
rc = -ENOMEM;
@@ -1704,7 +1703,7 @@
goto output_buff_get_flags_error;
}
- audio->map_v_write = ion_map_kernel(client, handle, ionflag);
+ audio->map_v_write = ion_map_kernel(client, handle);
if (IS_ERR(audio->map_v_write)) {
MM_ERR("could not map write buffers\n");
rc = -ENOMEM;
diff --git a/arch/arm/mach-msm/qdsp5/audio_wmapro.c b/arch/arm/mach-msm/qdsp5/audio_wmapro.c
index 82fc3f9..a08f3c9 100644
--- a/arch/arm/mach-msm/qdsp5/audio_wmapro.c
+++ b/arch/arm/mach-msm/qdsp5/audio_wmapro.c
@@ -1042,7 +1042,7 @@
handle = ion_alloc(audio->client,
(config.buffer_size *
config.buffer_count),
- SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID));
+ SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID), 0);
if (IS_ERR_OR_NULL(handle)) {
MM_ERR("Unable to alloc I/P buffs\n");
audio->input_buff_handle = NULL;
@@ -1080,8 +1080,7 @@
}
audio->map_v_read = ion_map_kernel(
- audio->client,
- handle, ionflag);
+ audio->client, handle);
if (IS_ERR(audio->map_v_read)) {
MM_ERR("map of read buf failed\n");
ion_free(audio->client, handle);
@@ -1673,7 +1672,7 @@
audio->client = client;
handle = ion_alloc(client, mem_sz, SZ_4K,
- ION_HEAP(ION_AUDIO_HEAP_ID));
+ ION_HEAP(ION_AUDIO_HEAP_ID), 0);
if (IS_ERR_OR_NULL(handle)) {
MM_ERR("Unable to create allocate O/P buffers\n");
rc = -ENOMEM;
@@ -1699,7 +1698,7 @@
goto output_buff_get_flags_error;
}
- audio->map_v_write = ion_map_kernel(client, handle, ionflag);
+ audio->map_v_write = ion_map_kernel(client, handle);
if (IS_ERR(audio->map_v_write)) {
MM_ERR("could not map write buffers\n");
rc = -ENOMEM;
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_amrnb_in.c b/arch/arm/mach-msm/qdsp5v2/audio_amrnb_in.c
index 2f03cd0..f1951f7 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_amrnb_in.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_amrnb_in.c
@@ -803,7 +803,7 @@
audio->client = client;
handle = ion_alloc(client, DMASZ, SZ_4K,
- ION_HEAP(ION_AUDIO_HEAP_ID));
+ ION_HEAP(ION_AUDIO_HEAP_ID), 0);
if (IS_ERR_OR_NULL(handle)) {
MM_ERR("Unable to create allocate O/P buffers\n");
rc = -ENOMEM;
@@ -828,7 +828,7 @@
goto buff_get_flags_error;
}
- audio->map_v_read = ion_map_kernel(client, handle, ionflag);
+ audio->map_v_read = ion_map_kernel(client, handle);
if (IS_ERR(audio->map_v_read)) {
MM_ERR("could not map write buffers\n");
rc = -ENOMEM;
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_evrc_in.c b/arch/arm/mach-msm/qdsp5v2/audio_evrc_in.c
index 1180e8d..6e95dc5 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_evrc_in.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_evrc_in.c
@@ -1363,7 +1363,7 @@
MM_DBG("allocating mem sz = %d\n", DMASZ);
handle = ion_alloc(client, DMASZ, SZ_4K,
- ION_HEAP(ION_AUDIO_HEAP_ID));
+ ION_HEAP(ION_AUDIO_HEAP_ID), 0);
if (IS_ERR_OR_NULL(handle)) {
MM_ERR("Unable to create allocate O/P buffers\n");
rc = -ENOMEM;
@@ -1391,7 +1391,7 @@
goto output_buff_get_flags_error;
}
- audio->map_v_read = ion_map_kernel(client, handle, ionflag);
+ audio->map_v_read = ion_map_kernel(client, handle);
if (IS_ERR(audio->map_v_read)) {
MM_ERR("could not map read buffers,freeing instance 0x%08x\n",
(int)audio);
@@ -1458,7 +1458,7 @@
MM_DBG("allocating BUFFER_SIZE %d\n", BUFFER_SIZE);
handle = ion_alloc(client, BUFFER_SIZE,
- SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID));
+ SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID), 0);
if (IS_ERR_OR_NULL(handle)) {
MM_ERR("Unable to create allocate I/P buffers\n");
rc = -ENOMEM;
@@ -1488,8 +1488,7 @@
goto input_buff_alloc_error;
}
- audio->map_v_write = ion_map_kernel(client,
- handle, ionflag);
+ audio->map_v_write = ion_map_kernel(client, handle);
if (IS_ERR(audio->map_v_write)) {
MM_ERR("could not map write buffers\n");
rc = -ENOMEM;
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_qcelp_in.c b/arch/arm/mach-msm/qdsp5v2/audio_qcelp_in.c
index 7fac2ea..8ad738e 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_qcelp_in.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_qcelp_in.c
@@ -1368,7 +1368,7 @@
MM_DBG("allocating mem sz = %d\n", DMASZ);
handle = ion_alloc(client, DMASZ, SZ_4K,
- ION_HEAP(ION_AUDIO_HEAP_ID));
+ ION_HEAP(ION_AUDIO_HEAP_ID), 0);
if (IS_ERR_OR_NULL(handle)) {
MM_ERR("Unable to create allocate O/P buffers\n");
rc = -ENOMEM;
@@ -1396,7 +1396,7 @@
goto output_buff_get_flags_error;
}
- audio->map_v_read = ion_map_kernel(client, handle, ionflag);
+ audio->map_v_read = ion_map_kernel(client, handle);
if (IS_ERR(audio->map_v_read)) {
MM_ERR("could not map read buffers,freeing instance 0x%08x\n",
(int)audio);
@@ -1465,7 +1465,7 @@
MM_DBG("allocating BUFFER_SIZE %d\n", BUFFER_SIZE);
handle = ion_alloc(client, BUFFER_SIZE,
- SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID));
+ SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID), 0);
if (IS_ERR_OR_NULL(handle)) {
MM_ERR("Unable to create allocate I/P buffers\n");
rc = -ENOMEM;
@@ -1495,8 +1495,7 @@
goto input_buff_alloc_error;
}
- audio->map_v_write = ion_map_kernel(client,
- handle, ionflag);
+ audio->map_v_write = ion_map_kernel(client, handle);
if (IS_ERR(audio->map_v_write)) {
MM_ERR("could not map write buffers\n");
rc = -ENOMEM;
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_wma.c b/arch/arm/mach-msm/qdsp5v2/audio_wma.c
index 4ba5821..8562020 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_wma.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_wma.c
@@ -1061,7 +1061,7 @@
handle = ion_alloc(audio->client,
(config.buffer_size *
config.buffer_count),
- SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID));
+ SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID), 0);
if (IS_ERR_OR_NULL(handle)) {
MM_ERR("Unable to alloc I/P buffs\n");
audio->input_buff_handle = NULL;
@@ -1099,8 +1099,7 @@
}
audio->map_v_read = ion_map_kernel(
- audio->client,
- handle, ionflag);
+ audio->client, handle);
if (IS_ERR(audio->map_v_read)) {
MM_ERR("map of read buf failed\n");
ion_free(audio->client, handle);
@@ -1696,7 +1695,7 @@
audio->client = client;
handle = ion_alloc(client, mem_sz, SZ_4K,
- ION_HEAP(ION_AUDIO_HEAP_ID));
+ ION_HEAP(ION_AUDIO_HEAP_ID), 0);
if (IS_ERR_OR_NULL(handle)) {
MM_ERR("Unable to create allocate O/P buffers\n");
rc = -ENOMEM;
@@ -1722,7 +1721,7 @@
goto output_buff_get_flags_error;
}
- audio->map_v_write = ion_map_kernel(client, handle, ionflag);
+ audio->map_v_write = ion_map_kernel(client, handle);
if (IS_ERR(audio->map_v_write)) {
MM_ERR("could not map write buffers\n");
rc = -ENOMEM;
diff --git a/arch/arm/mach-msm/qdsp6v2/adsprpc.c b/arch/arm/mach-msm/qdsp6v2/adsprpc.c
index 6e6f8e8..49008de 100644
--- a/arch/arm/mach-msm/qdsp6v2/adsprpc.c
+++ b/arch/arm/mach-msm/qdsp6v2/adsprpc.c
@@ -73,11 +73,10 @@
int err = 0;
buf->handle = ion_alloc(clnt, buf->size, SZ_4K,
- ION_HEAP(ION_AUDIO_HEAP_ID));
+ ION_HEAP(ION_AUDIO_HEAP_ID), 0);
VERIFY(0 == IS_ERR_OR_NULL(buf->handle));
buf->virt = 0;
- VERIFY(0 != (buf->virt = ion_map_kernel(clnt, buf->handle,
- ION_SET_CACHE(CACHED))));
+ VERIFY(0 != (buf->virt = ion_map_kernel(clnt, buf->handle)));
VERIFY(0 == ion_phys(clnt, buf->handle, &buf->phys, &buf->size));
bail:
if (err && !IS_ERR_OR_NULL(buf->handle))
diff --git a/arch/arm/mach-msm/qdsp6v2/adsprpc.h b/arch/arm/mach-msm/qdsp6v2/adsprpc.h
index 368b8e6..c6c7d23 100644
--- a/arch/arm/mach-msm/qdsp6v2/adsprpc.h
+++ b/arch/arm/mach-msm/qdsp6v2/adsprpc.h
@@ -24,7 +24,7 @@
#include <linux/cdev.h>
#include <linux/list.h>
#include <linux/hash.h>
-#include <linux/ion.h>
+#include <linux/msm_ion.h>
#include <mach/msm_smd.h>
#include <mach/ion.h>
#include "adsprpc_shared.h"
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_acdb.c b/arch/arm/mach-msm/qdsp6v2/audio_acdb.c
index 7298fa1..7272f97 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_acdb.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_acdb.c
@@ -662,7 +662,7 @@
}
kvptr = ion_map_kernel(acdb_data.ion_client,
- acdb_data.ion_handle, 0);
+ acdb_data.ion_handle);
if (IS_ERR_OR_NULL(kvptr)) {
pr_err("%s: Could not get kernel virt addr!!!\n", __func__);
result = PTR_ERR(kvptr);
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_lpa.c b/arch/arm/mach-msm/qdsp6v2/audio_lpa.c
index b5a382e..176f364 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_lpa.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_lpa.c
@@ -486,7 +486,7 @@
goto flag_error;
}
- temp_ptr = ion_map_kernel(audio->client, handle, ionflag);
+ temp_ptr = ion_map_kernel(audio->client, handle);
if (IS_ERR_OR_NULL(temp_ptr)) {
pr_err("%s: could not get virtual address\n", __func__);
goto map_error;
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c b/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
index 84a79cd..28bf5c6 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
@@ -676,7 +676,7 @@
goto flag_error;
}
- temp_ptr = ion_map_kernel(audio->client, handle, ionflag);
+ temp_ptr = ion_map_kernel(audio->client, handle);
if (IS_ERR_OR_NULL(temp_ptr)) {
pr_err("%s: could not get virtual address\n", __func__);
goto map_error;
diff --git a/arch/arm/mach-msm/qdsp6v2/lpa_if_hdmi.c b/arch/arm/mach-msm/qdsp6v2/lpa_if_hdmi.c
index c19fd85..63b3064 100644
--- a/arch/arm/mach-msm/qdsp6v2/lpa_if_hdmi.c
+++ b/arch/arm/mach-msm/qdsp6v2/lpa_if_hdmi.c
@@ -26,7 +26,7 @@
#include <mach/msm_hdmi_audio.h>
#include <mach/audio_dma_msm8k.h>
#include <sound/dai.h>
-#include "q6core.h"
+#include <mach/qdsp6v2/q6core.h>
#define DMA_ALLOC_BUF_SZ (SZ_4K * 16)
diff --git a/arch/arm/mach-msm/qdsp6v2/q6core.c b/arch/arm/mach-msm/qdsp6v2/q6core.c
index d7de50e..9dd66e1 100644
--- a/arch/arm/mach-msm/qdsp6v2/q6core.c
+++ b/arch/arm/mach-msm/qdsp6v2/q6core.c
@@ -26,7 +26,7 @@
#include <linux/delay.h>
#include <mach/msm_smd.h>
#include <mach/qdsp6v2/apr.h>
-#include "q6core.h"
+#include <mach/qdsp6v2/q6core.h>
#define TIMEOUT_MS 1000
@@ -79,6 +79,10 @@
bus_bw_resp_received = 1;
wake_up(&bus_bw_req_wait);
break;
+ case ADSP_CMD_SET_DTS_MODEL_ID:
+ pr_debug("ADSP_CMD_SET_DTS_MODEL_ID status[0x%x]\n",
+ payload1[1]);
+ break;
default:
pr_err("Invalid cmd rsp[0x%x][0x%x]\n",
payload1[0], payload1[1]);
@@ -382,6 +386,35 @@
return count;
}
+uint32_t core_set_dts_model_id(uint32_t id_size, uint8_t *id)
+{
+ struct adsp_dts_modelid payload;
+ int rc = 0;
+ pr_debug("core_set_dts_model_id(): Enter\n");
+ core_open();
+ if (core_handle_q) {
+ payload.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_EVENT,
+ APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+ payload.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
+ sizeof(uint32_t)+id_size);
+ payload.hdr.src_port = 0;
+ payload.hdr.dest_port = 0;
+ payload.hdr.token = 0;
+ payload.hdr.opcode = ADSP_CMD_SET_DTS_MODEL_ID;
+ payload.model_ID_size = id_size;
+ memcpy(payload.model_ID, id, id_size+1);
+ pr_debug("Send DTS sec opcode=%x modelID = %s, size=%d\n",
+ payload.hdr.opcode, (char *)payload.model_ID,
+ payload.model_ID_size);
+ rc = apr_send_pkt(core_handle_q, (uint32_t *)&payload);
+ if (rc < 0)
+ pr_err("%s: SET_DTS_DTS_MODEL_ID failed op[0x%x]rc[%d]\n",
+ __func__, payload.hdr.opcode, rc);
+ }
+ pr_debug("core_set_dts_model_id(): Exit\n");
+ return rc;
+}
+
static const struct file_operations apr_debug_fops = {
.write = apr_debug_write,
.open = apr_debug_open,
diff --git a/arch/arm/mach-msm/qdsp6v2/q6voice.c b/arch/arm/mach-msm/qdsp6v2/q6voice.c
index 12a02c5..7464ed7 100644
--- a/arch/arm/mach-msm/qdsp6v2/q6voice.c
+++ b/arch/arm/mach-msm/qdsp6v2/q6voice.c
@@ -30,7 +30,7 @@
#include <mach/qdsp6v2/rtac.h>
#include <mach/qdsp6v2/audio_acdb.h>
-#include "q6core.h"
+#include <mach/qdsp6v2/q6core.h>
#define TIMEOUT_MS 3000
diff --git a/arch/arm/mach-msm/rpm_resources.c b/arch/arm/mach-msm/rpm_resources.c
index 2a835f7..3ab5a98 100644
--- a/arch/arm/mach-msm/rpm_resources.c
+++ b/arch/arm/mach-msm/rpm_resources.c
@@ -945,7 +945,8 @@
irqs_detectable, gpio_detectable))
continue;
- if (MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE == sleep_mode)
+ if ((MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE == sleep_mode)
+ || (MSM_PM_SLEEP_MODE_POWER_COLLAPSE == sleep_mode))
if (!cpu && msm_rpm_local_request_is_outstanding())
break;
diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c
index e33f87b..b228147 100644
--- a/arch/arm/mach-msm/smd.c
+++ b/arch/arm/mach-msm/smd.c
@@ -3516,6 +3516,7 @@
{SMD_WCNSS, "riva", .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},
};
static int restart_notifier_cb(struct notifier_block *this,
diff --git a/arch/arm/mach-msm/smd_rpcrouter.c b/arch/arm/mach-msm/smd_rpcrouter.c
index 983d0c1..68c3dd3 100644
--- a/arch/arm/mach-msm/smd_rpcrouter.c
+++ b/arch/arm/mach-msm/smd_rpcrouter.c
@@ -2421,6 +2421,7 @@
{
struct rpcrouter_xprt_info *xprt_info;
struct rpcrouter_xprt_work *xprt_work;
+ unsigned long flags;
/* Workqueue is created in init function which works for all existing
* clients. If this fails in the future, then it will need to be
@@ -2452,11 +2453,13 @@
xprt_info = xprt->priv;
if (xprt_info) {
+ spin_lock_irqsave(&xprt_info->lock, flags);
/* Check read_avail even for OPEN event to handle missed
DATA events while processing the OPEN event*/
if (xprt->read_avail() >= xprt_info->need_len)
wake_lock(&xprt_info->wakelock);
wake_up(&xprt_info->read_wait);
+ spin_unlock_irqrestore(&xprt_info->lock, flags);
}
}
diff --git a/arch/arm/mach-msm/sysmon.c b/arch/arm/mach-msm/sysmon.c
index 1305bd1..02ba5ea 100644
--- a/arch/arm/mach-msm/sysmon.c
+++ b/arch/arm/mach-msm/sysmon.c
@@ -159,6 +159,41 @@
}
/**
+ * sysmon_send_shutdown() - send shutdown command to a
+ * subsystem.
+ * @dest_ss: ID of subsystem to send to.
+ *
+ * Returns 0 for success, -EINVAL for an invalid destination, -ENODEV if
+ * the SMD transport channel is not open, -ETIMEDOUT if the destination
+ * subsystem does not respond, and -ENOSYS if the destination subsystem
+ * responds with something unexpected.
+ *
+ * If CONFIG_MSM_SYSMON_COMM is not defined, always return success (0).
+ */
+int sysmon_send_shutdown(enum subsys_id dest_ss)
+{
+ struct sysmon_subsys *ss = &subsys[dest_ss];
+ const char tx_buf[] = "system:shutdown";
+ const char expect[] = "system:ack";
+ size_t prefix_len = ARRAY_SIZE(expect) - 1;
+ int ret;
+
+ if (dest_ss < 0 || dest_ss >= SYSMON_NUM_SS)
+ return -EINVAL;
+
+ mutex_lock(&ss->lock);
+ ret = sysmon_send_msg(ss, tx_buf, ARRAY_SIZE(tx_buf));
+ if (ret)
+ goto out;
+
+ if (strncmp(ss->rx_buf, expect, prefix_len))
+ ret = -ENOSYS;
+out:
+ mutex_unlock(&ss->lock);
+ return ret;
+}
+
+/**
* sysmon_get_reason() - Retrieve failure reason from a subsystem.
* @dest_ss: ID of subsystem to query
* @buf: Caller-allocated buffer for the returned NUL-terminated reason
diff --git a/arch/arm/mach-msm/sysmon.h b/arch/arm/mach-msm/sysmon.h
index 77c3329..8c2f6ea 100644
--- a/arch/arm/mach-msm/sysmon.h
+++ b/arch/arm/mach-msm/sysmon.h
@@ -38,6 +38,7 @@
int sysmon_send_event(enum subsys_id dest_ss, const char *event_ss,
enum subsys_notif_type notif);
int sysmon_get_reason(enum subsys_id dest_ss, char *buf, size_t len);
+int sysmon_send_shutdown(enum subsys_id dest_ss);
#else
static inline int sysmon_send_event(enum subsys_id dest_ss,
const char *event_ss,
@@ -50,6 +51,10 @@
{
return 0;
}
+static inline int sysmon_send_shutdown(enum subsys_id dest_ss)
+{
+ return 0;
+}
#endif
#endif
diff --git a/arch/arm/mach-msm/wcnss-ssr-8974.c b/arch/arm/mach-msm/wcnss-ssr-8974.c
index d8745fc..b837efc 100644
--- a/arch/arm/mach-msm/wcnss-ssr-8974.c
+++ b/arch/arm/mach-msm/wcnss-ssr-8974.c
@@ -25,7 +25,7 @@
static int wcnss_crash;
static struct subsys_device *wcnss_ssr_dev;
-#define WCNSS_APSS_WDOG_BITE_RESET_RDY_IRQ 231
+#define WCNSS_APSS_WDOG_BITE_RESET_RDY_IRQ 181
static void log_wcnss_sfr(void)
{
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 47dab27..ba93e68 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -393,6 +393,16 @@
.size __v7_ca15mp_proc_info, . - __v7_ca15mp_proc_info
/*
+ * Qualcomm Inc. Krait processors.
+ */
+ .type __krait_proc_info, #object
+__krait_proc_info:
+ .long 0x510f0400 @ Required ID value
+ .long 0xff0ffc00 @ Mask for ID
+ __v7_proc __v7_setup, hwcaps = HWCAP_IDIV
+ .size __krait_proc_info, . - __krait_proc_info
+
+ /*
* Match any ARMv7 processor core.
*/
.type __v7_proc_info, #object
diff --git a/drivers/char/diag/diagfwd_cntl.c b/drivers/char/diag/diagfwd_cntl.c
index 9fc1164..3bbd3fb 100644
--- a/drivers/char/diag/diagfwd_cntl.c
+++ b/drivers/char/diag/diagfwd_cntl.c
@@ -221,6 +221,8 @@
pr_err("diag: drop reg proc %d\n",
proc_num);
kfree(temp);
+ } else if (type != DIAG_CTRL_MSG_REG) {
+ flag = 1;
}
buf = buf + HDR_SIZ + data_len;
}
diff --git a/drivers/coresight/Kconfig b/drivers/coresight/Kconfig
index a23fff0..ea4ad4f 100644
--- a/drivers/coresight/Kconfig
+++ b/drivers/coresight/Kconfig
@@ -31,6 +31,16 @@
For production builds, you should probably say 'N' here to avoid
potential power, performance and memory penalty.
+config MSM_QDSS_ETM_PCSAVE_DEFAULT_ENABLE
+ bool "Turn on PC saving by default"
+ depends on MSM_QDSS
+ help
+ Turns on program counter saving on reset by default. Otherwise,
+ PC saving is disabled by default but can be enabled via sysfs.
+
+ For production builds, you should probably say 'N' here to avoid
+ potential power penalty.
+
config CONTROL_TRACE
tristate "Turn on to control tracing"
help
diff --git a/drivers/coresight/Makefile b/drivers/coresight/Makefile
index a2815de..033e5a0 100644
--- a/drivers/coresight/Makefile
+++ b/drivers/coresight/Makefile
@@ -1,3 +1,3 @@
obj-$(CONFIG_CONTROL_TRACE) += control_trace.o
obj-$(CONFIG_OF) += of_coresight.o
-obj-$(CONFIG_MSM_QDSS) += coresight.o coresight-csr.o coresight-tmc.o coresight-tpiu.o coresight-etb.o coresight-funnel.o coresight-replicator.o coresight-stm.o coresight-etm.o
+obj-$(CONFIG_MSM_QDSS) += coresight.o coresight-csr.o coresight-tmc.o coresight-tpiu.o coresight-etb.o coresight-funnel.o coresight-replicator.o coresight-stm.o coresight-etm.o coresight-etm-cp14.o
diff --git a/drivers/coresight/coresight-etm-cp14.c b/drivers/coresight/coresight-etm-cp14.c
new file mode 100644
index 0000000..9a6c13a
--- /dev/null
+++ b/drivers/coresight/coresight-etm-cp14.c
@@ -0,0 +1,510 @@
+/* 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/types.h>
+#include <asm/hardware/cp14.h>
+
+static unsigned int etm_read_reg(uint32_t reg)
+{
+ switch (reg) {
+ case 0x0:
+ return etm_read(ETMCR);
+ case 0x1:
+ return etm_read(ETMCCR);
+ case 0x2:
+ return etm_read(ETMTRIGGER);
+ case 0x4:
+ return etm_read(ETMSR);
+ case 0x5:
+ return etm_read(ETMSCR);
+ case 0x6:
+ return etm_read(ETMTSSCR);
+ case 0x8:
+ return etm_read(ETMTEEVR);
+ case 0x9:
+ return etm_read(ETMTECR1);
+ case 0xB:
+ return etm_read(ETMFFLR);
+ case 0x10:
+ return etm_read(ETMACVR0);
+ case 0x11:
+ return etm_read(ETMACVR1);
+ case 0x12:
+ return etm_read(ETMACVR2);
+ case 0x13:
+ return etm_read(ETMACVR3);
+ case 0x14:
+ return etm_read(ETMACVR4);
+ case 0x15:
+ return etm_read(ETMACVR5);
+ case 0x16:
+ return etm_read(ETMACVR6);
+ case 0x17:
+ return etm_read(ETMACVR7);
+ case 0x18:
+ return etm_read(ETMACVR8);
+ case 0x19:
+ return etm_read(ETMACVR9);
+ case 0x1A:
+ return etm_read(ETMACVR10);
+ case 0x1B:
+ return etm_read(ETMACVR11);
+ case 0x1C:
+ return etm_read(ETMACVR12);
+ case 0x1D:
+ return etm_read(ETMACVR13);
+ case 0x1E:
+ return etm_read(ETMACVR14);
+ case 0x1F:
+ return etm_read(ETMACVR15);
+ case 0x20:
+ return etm_read(ETMACTR0);
+ case 0x21:
+ return etm_read(ETMACTR1);
+ case 0x22:
+ return etm_read(ETMACTR2);
+ case 0x23:
+ return etm_read(ETMACTR3);
+ case 0x24:
+ return etm_read(ETMACTR4);
+ case 0x25:
+ return etm_read(ETMACTR5);
+ case 0x26:
+ return etm_read(ETMACTR6);
+ case 0x27:
+ return etm_read(ETMACTR7);
+ case 0x28:
+ return etm_read(ETMACTR8);
+ case 0x29:
+ return etm_read(ETMACTR9);
+ case 0x2A:
+ return etm_read(ETMACTR10);
+ case 0x2B:
+ return etm_read(ETMACTR11);
+ case 0x2C:
+ return etm_read(ETMACTR12);
+ case 0x2D:
+ return etm_read(ETMACTR13);
+ case 0x2E:
+ return etm_read(ETMACTR14);
+ case 0x2F:
+ return etm_read(ETMACTR15);
+ case 0x50:
+ return etm_read(ETMCNTRLDVR0);
+ case 0x51:
+ return etm_read(ETMCNTRLDVR1);
+ case 0x52:
+ return etm_read(ETMCNTRLDVR2);
+ case 0x53:
+ return etm_read(ETMCNTRLDVR3);
+ case 0x54:
+ return etm_read(ETMCNTENR0);
+ case 0x55:
+ return etm_read(ETMCNTENR1);
+ case 0x56:
+ return etm_read(ETMCNTENR2);
+ case 0x57:
+ return etm_read(ETMCNTENR3);
+ case 0x58:
+ return etm_read(ETMCNTRLDEVR0);
+ case 0x59:
+ return etm_read(ETMCNTRLDEVR1);
+ case 0x5A:
+ return etm_read(ETMCNTRLDEVR2);
+ case 0x5B:
+ return etm_read(ETMCNTRLDEVR3);
+ case 0x5C:
+ return etm_read(ETMCNTVR0);
+ case 0x5D:
+ return etm_read(ETMCNTVR1);
+ case 0x5E:
+ return etm_read(ETMCNTVR2);
+ case 0x5F:
+ return etm_read(ETMCNTVR3);
+ case 0x60:
+ return etm_read(ETMSQ12EVR);
+ case 0x61:
+ return etm_read(ETMSQ21EVR);
+ case 0x62:
+ return etm_read(ETMSQ23EVR);
+ case 0x63:
+ return etm_read(ETMSQ31EVR);
+ case 0x64:
+ return etm_read(ETMSQ32EVR);
+ case 0x65:
+ return etm_read(ETMSQ13EVR);
+ case 0x67:
+ return etm_read(ETMSQR);
+ case 0x68:
+ return etm_read(ETMEXTOUTEVR0);
+ case 0x69:
+ return etm_read(ETMEXTOUTEVR1);
+ case 0x6A:
+ return etm_read(ETMEXTOUTEVR2);
+ case 0x6B:
+ return etm_read(ETMEXTOUTEVR3);
+ case 0x6C:
+ return etm_read(ETMCIDCVR0);
+ case 0x6D:
+ return etm_read(ETMCIDCVR1);
+ case 0x6E:
+ return etm_read(ETMCIDCVR2);
+ case 0x6F:
+ return etm_read(ETMCIDCMR);
+ case 0x70:
+ return etm_read(ETMIMPSPEC0);
+ case 0x71:
+ return etm_read(ETMIMPSPEC1);
+ case 0x72:
+ return etm_read(ETMIMPSPEC2);
+ case 0x73:
+ return etm_read(ETMIMPSPEC3);
+ case 0x74:
+ return etm_read(ETMIMPSPEC4);
+ case 0x75:
+ return etm_read(ETMIMPSPEC5);
+ case 0x76:
+ return etm_read(ETMIMPSPEC6);
+ case 0x77:
+ return etm_read(ETMIMPSPEC7);
+ case 0x78:
+ return etm_read(ETMSYNCFR);
+ case 0x79:
+ return etm_read(ETMIDR);
+ case 0x7A:
+ return etm_read(ETMCCER);
+ case 0x7B:
+ return etm_read(ETMEXTINSELR);
+ case 0x7C:
+ return etm_read(ETMTESSEICR);
+ case 0x7D:
+ return etm_read(ETMEIBCR);
+ case 0x7E:
+ return etm_read(ETMTSEVR);
+ case 0x7F:
+ return etm_read(ETMAUXCR);
+ case 0x80:
+ return etm_read(ETMTRACEIDR);
+ case 0x90:
+ return etm_read(ETMVMIDCVR);
+ case 0xC1:
+ return etm_read(ETMOSLSR);
+ case 0xC2:
+ return etm_read(ETMOSSRR);
+ case 0xC4:
+ return etm_read(ETMPDCR);
+ case 0xC5:
+ return etm_read(ETMPDSR);
+ default:
+ WARN(1, "invalid CP14 access to ETM reg: %lx",
+ (unsigned long)reg);
+ return 0;
+ }
+}
+
+static void etm_write_reg(uint32_t val, uint32_t reg)
+{
+ switch (reg) {
+ case 0x0:
+ etm_write(val, ETMCR);
+ return;
+ case 0x2:
+ etm_write(val, ETMTRIGGER);
+ return;
+ case 0x4:
+ etm_write(val, ETMSR);
+ return;
+ case 0x6:
+ etm_write(val, ETMTSSCR);
+ return;
+ case 0x8:
+ etm_write(val, ETMTEEVR);
+ return;
+ case 0x9:
+ etm_write(val, ETMTECR1);
+ return;
+ case 0xB:
+ etm_write(val, ETMFFLR);
+ return;
+ case 0x10:
+ etm_write(val, ETMACVR0);
+ return;
+ case 0x11:
+ etm_write(val, ETMACVR1);
+ return;
+ case 0x12:
+ etm_write(val, ETMACVR2);
+ return;
+ case 0x13:
+ etm_write(val, ETMACVR3);
+ return;
+ case 0x14:
+ etm_write(val, ETMACVR4);
+ return;
+ case 0x15:
+ etm_write(val, ETMACVR5);
+ return;
+ case 0x16:
+ etm_write(val, ETMACVR6);
+ return;
+ case 0x17:
+ etm_write(val, ETMACVR7);
+ return;
+ case 0x18:
+ etm_write(val, ETMACVR8);
+ return;
+ case 0x19:
+ etm_write(val, ETMACVR9);
+ return;
+ case 0x1A:
+ etm_write(val, ETMACVR10);
+ return;
+ case 0x1B:
+ etm_write(val, ETMACVR11);
+ return;
+ case 0x1C:
+ etm_write(val, ETMACVR12);
+ return;
+ case 0x1D:
+ etm_write(val, ETMACVR13);
+ return;
+ case 0x1E:
+ etm_write(val, ETMACVR14);
+ return;
+ case 0x1F:
+ etm_write(val, ETMACVR15);
+ return;
+ case 0x20:
+ etm_write(val, ETMACTR0);
+ return;
+ case 0x21:
+ etm_write(val, ETMACTR1);
+ return;
+ case 0x22:
+ etm_write(val, ETMACTR2);
+ return;
+ case 0x23:
+ etm_write(val, ETMACTR3);
+ return;
+ case 0x24:
+ etm_write(val, ETMACTR4);
+ return;
+ case 0x25:
+ etm_write(val, ETMACTR5);
+ return;
+ case 0x26:
+ etm_write(val, ETMACTR6);
+ return;
+ case 0x27:
+ etm_write(val, ETMACTR7);
+ return;
+ case 0x28:
+ etm_write(val, ETMACTR8);
+ return;
+ case 0x29:
+ etm_write(val, ETMACTR9);
+ return;
+ case 0x2A:
+ etm_write(val, ETMACTR10);
+ return;
+ case 0x2B:
+ etm_write(val, ETMACTR11);
+ return;
+ case 0x2C:
+ etm_write(val, ETMACTR12);
+ return;
+ case 0x2D:
+ etm_write(val, ETMACTR13);
+ return;
+ case 0x2E:
+ etm_write(val, ETMACTR14);
+ return;
+ case 0x2F:
+ etm_write(val, ETMACTR15);
+ return;
+ case 0x50:
+ etm_write(val, ETMCNTRLDVR0);
+ return;
+ case 0x51:
+ etm_write(val, ETMCNTRLDVR1);
+ return;
+ case 0x52:
+ etm_write(val, ETMCNTRLDVR2);
+ return;
+ case 0x53:
+ etm_write(val, ETMCNTRLDVR3);
+ return;
+ case 0x54:
+ etm_write(val, ETMCNTENR0);
+ return;
+ case 0x55:
+ etm_write(val, ETMCNTENR1);
+ return;
+ case 0x56:
+ etm_write(val, ETMCNTENR2);
+ return;
+ case 0x57:
+ etm_write(val, ETMCNTENR3);
+ return;
+ case 0x58:
+ etm_write(val, ETMCNTRLDEVR0);
+ return;
+ case 0x59:
+ etm_write(val, ETMCNTRLDEVR1);
+ return;
+ case 0x5A:
+ etm_write(val, ETMCNTRLDEVR2);
+ return;
+ case 0x5B:
+ etm_write(val, ETMCNTRLDEVR3);
+ return;
+ case 0x5C:
+ etm_write(val, ETMCNTVR0);
+ return;
+ case 0x5D:
+ etm_write(val, ETMCNTVR1);
+ return;
+ case 0x5E:
+ etm_write(val, ETMCNTVR2);
+ return;
+ case 0x5F:
+ etm_write(val, ETMCNTVR3);
+ return;
+ case 0x60:
+ etm_write(val, ETMSQ12EVR);
+ return;
+ case 0x61:
+ etm_write(val, ETMSQ21EVR);
+ return;
+ case 0x62:
+ etm_write(val, ETMSQ23EVR);
+ return;
+ case 0x63:
+ etm_write(val, ETMSQ31EVR);
+ return;
+ case 0x64:
+ etm_write(val, ETMSQ32EVR);
+ return;
+ case 0x65:
+ etm_write(val, ETMSQ13EVR);
+ return;
+ case 0x67:
+ etm_write(val, ETMSQR);
+ return;
+ case 0x68:
+ etm_write(val, ETMEXTOUTEVR0);
+ return;
+ case 0x69:
+ etm_write(val, ETMEXTOUTEVR1);
+ return;
+ case 0x6A:
+ etm_write(val, ETMEXTOUTEVR2);
+ return;
+ case 0x6B:
+ etm_write(val, ETMEXTOUTEVR3);
+ return;
+ case 0x6C:
+ etm_write(val, ETMCIDCVR0);
+ return;
+ case 0x6D:
+ etm_write(val, ETMCIDCVR1);
+ return;
+ case 0x6E:
+ etm_write(val, ETMCIDCVR2);
+ return;
+ case 0x6F:
+ etm_write(val, ETMCIDCMR);
+ return;
+ case 0x70:
+ etm_write(val, ETMIMPSPEC0);
+ return;
+ case 0x71:
+ etm_write(val, ETMIMPSPEC1);
+ return;
+ case 0x72:
+ etm_write(val, ETMIMPSPEC2);
+ return;
+ case 0x73:
+ etm_write(val, ETMIMPSPEC3);
+ return;
+ case 0x74:
+ etm_write(val, ETMIMPSPEC4);
+ return;
+ case 0x75:
+ etm_write(val, ETMIMPSPEC5);
+ return;
+ case 0x76:
+ etm_write(val, ETMIMPSPEC6);
+ return;
+ case 0x77:
+ etm_write(val, ETMIMPSPEC7);
+ return;
+ case 0x78:
+ etm_write(val, ETMSYNCFR);
+ return;
+ case 0x7B:
+ etm_write(val, ETMEXTINSELR);
+ return;
+ case 0x7C:
+ etm_write(val, ETMTESSEICR);
+ return;
+ case 0x7D:
+ etm_write(val, ETMEIBCR);
+ return;
+ case 0x7E:
+ etm_write(val, ETMTSEVR);
+ return;
+ case 0x7F:
+ etm_write(val, ETMAUXCR);
+ return;
+ case 0x80:
+ etm_write(val, ETMTRACEIDR);
+ return;
+ case 0x90:
+ etm_write(val, ETMVMIDCVR);
+ return;
+ case 0xC0:
+ etm_write(val, ETMOSLAR);
+ return;
+ case 0xC2:
+ etm_write(val, ETMOSSRR);
+ return;
+ case 0xC4:
+ etm_write(val, ETMPDCR);
+ return;
+ case 0xC5:
+ etm_write(val, ETMPDSR);
+ return;
+ default:
+ WARN(1, "invalid CP14 access to ETM reg: %lx",
+ (unsigned long)reg);
+ return;
+ }
+}
+
+static inline uint32_t offset_to_reg_num(uint32_t off)
+{
+ return off >> 2;
+}
+
+unsigned int etm_readl_cp14(uint32_t off)
+{
+ uint32_t reg = offset_to_reg_num(off);
+ return etm_read_reg(reg);
+}
+
+void etm_writel_cp14(uint32_t val, uint32_t off)
+{
+ uint32_t reg = offset_to_reg_num(off);
+ etm_write_reg(val, reg);
+}
diff --git a/drivers/coresight/coresight-etm.c b/drivers/coresight/coresight-etm.c
index 427cd7d..50bae55 100644
--- a/drivers/coresight/coresight-etm.c
+++ b/drivers/coresight/coresight-etm.c
@@ -35,20 +35,45 @@
#include "coresight-priv.h"
-#define etm_writel(drvdata, val, off) \
+#define etm_writel_mm(drvdata, val, off) \
__raw_writel((val), drvdata->base + off)
-#define etm_readl(drvdata, off) \
+#define etm_readl_mm(drvdata, off) \
__raw_readl(drvdata->base + off)
+#define etm_writel(drvdata, val, off) \
+({ \
+ if (cpu_is_krait_v3()) \
+ etm_writel_cp14(val, off); \
+ else \
+ etm_writel_mm(drvdata, val, off); \
+})
+#define etm_readl(drvdata, off) \
+({ \
+ uint32_t val; \
+ if (cpu_is_krait_v3()) \
+ val = etm_readl_cp14(off); \
+ else \
+ val = etm_readl_mm(drvdata, off); \
+ val; \
+})
+
#define ETM_LOCK(drvdata) \
do { \
+ /* recommended by spec to ensure ETM writes are committed prior
+ * to resuming execution
+ */ \
mb(); \
- etm_writel(drvdata, 0x0, CORESIGHT_LAR); \
+ isb(); \
+ etm_writel_mm(drvdata, 0x0, CORESIGHT_LAR); \
} while (0)
#define ETM_UNLOCK(drvdata) \
do { \
- etm_writel(drvdata, CORESIGHT_UNLOCK, CORESIGHT_LAR); \
+ etm_writel_mm(drvdata, CORESIGHT_UNLOCK, CORESIGHT_LAR); \
+ /* ensure unlock and any pending writes are committed prior to
+ * programming ETM registers
+ */ \
mb(); \
+ isb(); \
} while (0)
/*
@@ -152,6 +177,15 @@
boot_enable, boot_enable, int, S_IRUGO
);
+#ifdef CONFIG_MSM_QDSS_ETM_PCSAVE_DEFAULT_ENABLE
+static int boot_pcsave_enable = 1;
+#else
+static int boot_pcsave_enable;
+#endif
+module_param_named(
+ boot_pcsave_enable, boot_pcsave_enable, int, S_IRUGO
+);
+
struct etm_drvdata {
void __iomem *base;
struct device *dev;
@@ -169,6 +203,7 @@
uint8_t reset;
uint32_t mode;
uint32_t ctrl;
+ uint8_t ctrl_pwrdwn;
uint32_t trigger_event;
uint32_t startstop_ctrl;
uint32_t enable_event;
@@ -195,12 +230,16 @@
uint32_t ctxid_mask;
uint32_t sync_freq;
uint32_t timestamp_event;
+ uint8_t pdcr_pwrup;
+ bool pcsave_impl;
+ bool pcsave_enable;
};
static struct etm_drvdata *etm0drvdata;
-/* ETM clock is derived from the processor clock and gets enabled on a
- * logical OR of below items on Krait (pass2 onwards):
+/*
+ * ETM clock is derived from the processor clock and gets enabled on a
+ * logical OR of below items on Krait (v2 onwards):
* 1.CPMR[ETMCLKEN] is 1
* 2.ETMCR[PD] is 0
* 3.ETMPDCR[PU] is 1
@@ -210,26 +249,56 @@
* 1., 2. and 3. above are permanent enables whereas 4. and 5. are temporary
* enables
*
- * We rely on 5. to be able to access ETMCR and then use 2. above for ETM
- * clock vote in the driver and the save-restore code uses 1. above
+ * We rely on 5. to be able to access ETMCR/ETMPDCR and then use 2./3. above
+ * for ETM clock vote in the driver and the save-restore code uses 1. above
* for its vote
*/
+static void etm_set_pwrdwn(struct etm_drvdata *drvdata)
+{
+ uint32_t etmcr;
+
+ /* ensure pending cp14 accesses complete before setting pwrdwn */
+ mb();
+ isb();
+ etmcr = etm_readl(drvdata, ETMCR);
+ etmcr |= BIT(0);
+ etm_writel(drvdata, etmcr, ETMCR);
+}
+
+static void etm_clr_pwrdwn(struct etm_drvdata *drvdata)
+{
+ uint32_t etmcr;
+
+ etmcr = etm_readl(drvdata, ETMCR);
+ etmcr &= ~BIT(0);
+ etm_writel(drvdata, etmcr, ETMCR);
+ /* ensure pwrup completes before subsequent cp14 accesses */
+ mb();
+ isb();
+}
+
static void etm_set_pwrup(struct etm_drvdata *drvdata)
{
uint32_t etmpdcr;
- etmpdcr = etm_readl(drvdata, ETMPDCR);
+ etmpdcr = etm_readl_mm(drvdata, ETMPDCR);
etmpdcr |= BIT(3);
- etm_writel(drvdata, etmpdcr, ETMPDCR);
+ etm_writel_mm(drvdata, etmpdcr, ETMPDCR);
+ /* ensure pwrup completes before subsequent cp14 accesses */
+ mb();
+ isb();
}
static void etm_clr_pwrup(struct etm_drvdata *drvdata)
{
uint32_t etmpdcr;
- etmpdcr = etm_readl(drvdata, ETMPDCR);
+ /* ensure pending cp14 accesses complete before clearing pwrup */
+ mb();
+ isb();
+ etmpdcr = etm_readl_mm(drvdata, ETMPDCR);
etmpdcr &= ~BIT(3);
- etm_writel(drvdata, etmpdcr, ETMPDCR);
+ etm_writel_mm(drvdata, etmpdcr, ETMPDCR);
}
static void etm_set_prog(struct etm_drvdata *drvdata)
@@ -240,6 +309,10 @@
etmcr = etm_readl(drvdata, ETMCR);
etmcr |= BIT(10);
etm_writel(drvdata, etmcr, ETMCR);
+ /* recommended by spec for cp14 accesses to ensure etmcr write is
+ * complete before polling etmsr
+ */
+ isb();
for (count = TIMEOUT_US; BVAL(etm_readl(drvdata, ETMSR), 1) != 1
&& count > 0; count--)
udelay(1);
@@ -255,6 +328,10 @@
etmcr = etm_readl(drvdata, ETMCR);
etmcr &= ~BIT(10);
etm_writel(drvdata, etmcr, ETMCR);
+ /* recommended by spec for cp14 accesses to ensure etmcr write is
+ * complete before polling etmsr
+ */
+ isb();
for (count = TIMEOUT_US; BVAL(etm_readl(drvdata, ETMSR), 1) != 0
&& count > 0; count--)
udelay(1);
@@ -262,17 +339,94 @@
etm_readl(drvdata, ETMSR));
}
-static void __etm_enable(void *info)
+static void etm_save_pwrdwn(struct etm_drvdata *drvdata)
{
- int i;
+ drvdata->ctrl_pwrdwn = BVAL(etm_readl(drvdata, ETMCR), 0);
+}
+
+static void etm_restore_pwrdwn(struct etm_drvdata *drvdata)
+{
+ uint32_t etmcr;
+
+ etmcr = etm_readl(drvdata, ETMCR);
+ etmcr = (etmcr & ~BIT(0)) | drvdata->ctrl_pwrdwn;
+ etm_writel(drvdata, etmcr, ETMCR);
+}
+
+static void etm_save_pwrup(struct etm_drvdata *drvdata)
+{
+ drvdata->pdcr_pwrup = BVAL(etm_readl_mm(drvdata, ETMPDCR), 3);
+}
+
+static void etm_restore_pwrup(struct etm_drvdata *drvdata)
+{
+ uint32_t etmpdcr;
+
+ etmpdcr = etm_readl_mm(drvdata, ETMPDCR);
+ etmpdcr = (etmpdcr & ~BIT(3)) | (drvdata->pdcr_pwrup << 3);
+ etm_writel_mm(drvdata, etmpdcr, ETMPDCR);
+}
+
+static void etm_enable_pcsave(void *info)
+{
struct etm_drvdata *drvdata = info;
ETM_UNLOCK(drvdata);
- /* Vote for ETM power/clock enable */
+
+ etm_save_pwrup(drvdata);
+ /*
+ * ETMPDCR is only accessible via memory mapped interface and so use
+ * it first to enable power/clock to allow subsequent cp14 accesses.
+ */
etm_set_pwrup(drvdata);
+ etm_clr_pwrdwn(drvdata);
+ etm_restore_pwrup(drvdata);
+
+ ETM_LOCK(drvdata);
+}
+
+static void etm_disable_pcsave(void *info)
+{
+ struct etm_drvdata *drvdata = info;
+
+ ETM_UNLOCK(drvdata);
+
+ etm_save_pwrup(drvdata);
+ /*
+ * ETMPDCR is only accessible via memory mapped interface and so use
+ * it first to enable power/clock to allow subsequent cp14 accesses.
+ */
+ etm_set_pwrup(drvdata);
+ etm_set_pwrdwn(drvdata);
+ etm_restore_pwrup(drvdata);
+
+ ETM_LOCK(drvdata);
+}
+
+static void __etm_enable(void *info)
+{
+ int i;
+ uint32_t etmcr;
+ struct etm_drvdata *drvdata = info;
+
+ ETM_UNLOCK(drvdata);
+ /*
+ * Vote for ETM power/clock enable. ETMPDCR is only accessible via
+ * memory mapped interface and so use it first to enable power/clock
+ * to allow subsequent cp14 accesses.
+ */
+ etm_set_pwrup(drvdata);
+ etm_save_pwrdwn(drvdata);
+ /*
+ * Clear power down bit since when this bit is set writes to
+ * certain registers might be ignored.
+ */
+ etm_clr_pwrdwn(drvdata);
etm_set_prog(drvdata);
- etm_writel(drvdata, drvdata->ctrl | BIT(10), ETMCR);
+ etmcr = etm_readl(drvdata, ETMCR);
+ etmcr &= (BIT(10) | BIT(0));
+ etm_writel(drvdata, drvdata->ctrl | etmcr, ETMCR);
etm_writel(drvdata, drvdata->trigger_event, ETMTRIGGER);
etm_writel(drvdata, drvdata->startstop_ctrl, ETMTSSCR);
etm_writel(drvdata, drvdata->enable_event, ETMTEEVR);
@@ -309,6 +463,7 @@
etm_writel(drvdata, 0x00000000, ETMVMIDCVR);
etm_clr_prog(drvdata);
+ etm_restore_pwrdwn(drvdata);
ETM_LOCK(drvdata);
dev_dbg(drvdata->dev, "cpu: %d enable smp call done\n", drvdata->cpu);
@@ -346,11 +501,18 @@
struct etm_drvdata *drvdata = info;
ETM_UNLOCK(drvdata);
+ etm_save_pwrdwn(drvdata);
+ /*
+ * Clear power down bit since when this bit is set writes to
+ * certain registers might be ignored.
+ */
+ etm_clr_pwrdwn(drvdata);
etm_set_prog(drvdata);
/* program trace enable to low by using always false event */
etm_writel(drvdata, 0x6F | BIT(14), ETMTEEVR);
+ etm_restore_pwrdwn(drvdata);
/* Vote for ETM power/clock disable */
etm_clr_pwrup(drvdata);
ETM_LOCK(drvdata);
@@ -1307,6 +1469,7 @@
{
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
unsigned long val = drvdata->sync_freq;
+
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
@@ -1352,6 +1515,60 @@
static DEVICE_ATTR(timestamp_event, S_IRUGO | S_IWUSR, etm_show_timestamp_event,
etm_store_timestamp_event);
+static ssize_t etm_show_pcsave(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ unsigned long val;
+
+ val = drvdata->pcsave_enable;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static int __etm_store_pcsave(struct etm_drvdata *drvdata, unsigned long val)
+{
+ int ret;
+
+ ret = clk_prepare_enable(drvdata->clk);
+ if (ret)
+ return ret;
+
+ mutex_lock(&drvdata->mutex);
+ if (val) {
+ smp_call_function_single(drvdata->cpu, etm_enable_pcsave,
+ drvdata, 1);
+ drvdata->pcsave_enable = true;
+ } else {
+ smp_call_function_single(drvdata->cpu, etm_disable_pcsave,
+ drvdata, 1);
+ drvdata->pcsave_enable = false;
+ }
+ mutex_unlock(&drvdata->mutex);
+
+ clk_disable_unprepare(drvdata->clk);
+ return 0;
+}
+
+static ssize_t etm_store_pcsave(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ unsigned long val;
+ int ret;
+
+ if (sscanf(buf, "%lx", &val) != 1)
+ return -EINVAL;
+
+ ret = __etm_store_pcsave(drvdata, val);
+ if (ret)
+ return ret;
+
+ return size;
+}
+static DEVICE_ATTR(pcsave, S_IRUGO | S_IWUSR, etm_show_pcsave,
+ etm_store_pcsave);
+
static struct attribute *etm_attrs[] = {
&dev_attr_nr_addr_cmp.attr,
&dev_attr_nr_cntr.attr,
@@ -1416,17 +1633,33 @@
return true;
}
-static void __devinit etm_init_arch_data(struct etm_drvdata *drvdata)
+static void __devinit etm_prepare_arch(struct etm_drvdata *drvdata)
+{
+ /* Unlock OS lock first to allow memory mapped reads and writes. This
+ * is required for Krait pass1
+ * */
+ etm_os_unlock(NULL);
+ smp_call_function(etm_os_unlock, NULL, 1);
+}
+
+static void __devinit etm_init_arch_data(void *info)
{
uint32_t etmidr;
uint32_t etmccr;
+ struct etm_drvdata *drvdata = info;
- /* Unlock OS lock first to allow memory mapped reads and writes */
- etm_os_unlock(NULL);
- smp_call_function(etm_os_unlock, NULL, 1);
ETM_UNLOCK(drvdata);
- /* Vote for ETM power/clock enable */
+ /*
+ * Vote for ETM power/clock enable. ETMPDCR is only accessible via
+ * memory mapped interface and so use it first to enable power/clock
+ * to allow subsequent cp14 accesses.
+ */
etm_set_pwrup(drvdata);
+ /*
+ * Clear power down bit since when this bit is set writes to
+ * certain registers might be ignored.
+ */
+ etm_clr_pwrdwn(drvdata);
/* Set prog bit. It will be set from reset but this is included to
* ensure it is set
*/
@@ -1443,6 +1676,7 @@
drvdata->nr_ext_out = BMVAL(etmccr, 20, 22);
drvdata->nr_ctxid_cmp = BMVAL(etmccr, 24, 25);
+ etm_set_pwrdwn(drvdata);
/* Vote for ETM power/clock disable */
etm_clr_pwrup(drvdata);
ETM_LOCK(drvdata);
@@ -1518,12 +1752,6 @@
struct msm_client_dump dump;
struct coresight_desc *desc;
- /* Fail probe for Krait pass3 until supported */
- if (cpu_is_krait_v3()) {
- dev_info(dev, "ETM: failing probe for Krait pass3\n");
- return -EINVAL;
- }
-
if (pdev->dev.of_node) {
pdata = of_get_coresight_platform_data(dev, pdev->dev.of_node);
if (IS_ERR(pdata))
@@ -1569,7 +1797,9 @@
* ETMs copy it over from ETM0.
*/
if (drvdata->cpu == 0) {
- etm_init_arch_data(drvdata);
+ etm_prepare_arch(drvdata);
+ smp_call_function_single(drvdata->cpu, etm_init_arch_data,
+ drvdata, 1);
etm0drvdata = drvdata;
} else {
etm_copy_arch_data(drvdata);
@@ -1615,11 +1845,24 @@
goto err0;
}
+ if (pdev->dev.of_node)
+ drvdata->pcsave_impl = of_property_read_bool(pdev->dev.of_node,
+ "qcom,pc-save");
+ if (drvdata->pcsave_impl) {
+ ret = device_create_file(&drvdata->csdev->dev,
+ &dev_attr_pcsave);
+ if (ret)
+ dev_err(dev, "ETM pcsave dev node creation failed\n");
+ }
+
dev_info(dev, "ETM initialized\n");
if (boot_enable)
coresight_enable(drvdata->csdev);
+ if (drvdata->pcsave_impl && boot_pcsave_enable)
+ __etm_store_pcsave(drvdata, true);
+
return 0;
err1:
clk_disable_unprepare(drvdata->clk);
@@ -1633,6 +1876,7 @@
{
struct etm_drvdata *drvdata = platform_get_drvdata(pdev);
+ device_remove_file(&drvdata->csdev->dev, &dev_attr_pcsave);
coresight_unregister(drvdata->csdev);
wake_lock_destroy(&drvdata->wake_lock);
mutex_destroy(&drvdata->mutex);
diff --git a/drivers/coresight/coresight-priv.h b/drivers/coresight/coresight-priv.h
index 2b00242..0cf2b3d 100644
--- a/drivers/coresight/coresight-priv.h
+++ b/drivers/coresight/coresight-priv.h
@@ -39,9 +39,13 @@
#ifdef CONFIG_MSM_QDSS
extern void msm_qdss_csr_enable_bam_to_usb(void);
extern void msm_qdss_csr_disable_bam_to_usb(void);
+extern unsigned int etm_readl_cp14(uint32_t off);
+extern void etm_writel_cp14(uint32_t val, uint32_t off);
#else
static inline void msm_qdss_csr_enable_bam_to_usb(void) {}
static inline void msm_qdss_csr_disable_bam_to_usb(void) {}
+static inline unsigned int etm_readl_cp14(uint32_t off) { return 0; }
+static inline void etm_writel_cp14(uint32_t val, uint32_t off) {}
#endif
#endif
diff --git a/drivers/coresight/coresight-stm.c b/drivers/coresight/coresight-stm.c
index 70b2c43..f6a948b 100644
--- a/drivers/coresight/coresight-stm.c
+++ b/drivers/coresight/coresight-stm.c
@@ -724,6 +724,13 @@
dev_info(drvdata->dev, "STM initialized\n");
+ /*
+ * Enable and disable STM to undo the temporary default STM enable
+ * done by RPM.
+ */
+ coresight_enable(drvdata->csdev);
+ coresight_disable(drvdata->csdev);
+
if (boot_enable)
coresight_enable(drvdata->csdev);
diff --git a/drivers/coresight/coresight-tmc.c b/drivers/coresight/coresight-tmc.c
index 0be5882..13f69cd 100644
--- a/drivers/coresight/coresight-tmc.c
+++ b/drivers/coresight/coresight-tmc.c
@@ -1060,6 +1060,7 @@
goto err0;
}
memset(drvdata->vaddr, 0, drvdata->size);
+ drvdata->buf = drvdata->vaddr;
drvdata->out_mode = TMC_ETR_OUT_MODE_MEM;
ret = tmc_etr_bam_init(pdev, drvdata);
diff --git a/drivers/coresight/coresight.c b/drivers/coresight/coresight.c
index cccb5a7..3974f2e 100644
--- a/drivers/coresight/coresight.c
+++ b/drivers/coresight/coresight.c
@@ -377,8 +377,10 @@
list_for_each_entry(cd, &coresight_devs, dev_link) {
if (cd->id == curr_sink) {
- if (cd->enable && cd->ops->sink_ops->abort)
+ if (cd->enable && cd->ops->sink_ops->abort) {
cd->ops->sink_ops->abort(cd);
+ cd->enable = false;
+ }
}
}
out:
diff --git a/drivers/gpu/ion/ion.c b/drivers/gpu/ion/ion.c
index 7f760ed..b23181f 100644
--- a/drivers/gpu/ion/ion.c
+++ b/drivers/gpu/ion/ion.c
@@ -107,24 +107,6 @@
static void ion_iommu_release(struct kref *kref);
-static int ion_validate_buffer_flags(struct ion_buffer *buffer,
- unsigned long flags)
-{
- if (buffer->kmap_cnt || buffer->dmap_cnt || buffer->umap_cnt ||
- buffer->iommu_map_cnt) {
- if (buffer->flags != flags) {
- pr_err("%s: buffer was already mapped with flags %lx,"
- " cannot map with flags %lx\n", __func__,
- buffer->flags, flags);
- return 1;
- }
-
- } else {
- buffer->flags = flags;
- }
- return 0;
-}
-
/* this function should only be called while dev->lock is held */
static void ion_buffer_add(struct ion_device *dev,
struct ion_buffer *buffer)
@@ -232,6 +214,7 @@
buffer->dev = dev;
buffer->size = len;
+ buffer->flags = flags;
table = buffer->heap->ops->map_dma(buffer->heap, buffer);
if (IS_ERR_OR_NULL(table)) {
@@ -412,7 +395,8 @@
}
struct ion_handle *ion_alloc(struct ion_client *client, size_t len,
- size_t align, unsigned int flags)
+ size_t align, unsigned int heap_mask,
+ unsigned int flags)
{
struct rb_node *n;
struct ion_handle *handle;
@@ -443,7 +427,7 @@
if (!((1 << heap->type) & client->heap_mask))
continue;
/* if the caller didn't specify this heap type */
- if (!((1 << heap->id) & flags))
+ if (!((1 << heap->id) & heap_mask))
continue;
/* Do not allow un-secure heap if secure is specified */
if (secure_allocation && (heap->type != ION_HEAP_TYPE_CP))
@@ -773,8 +757,7 @@
}
EXPORT_SYMBOL(ion_unmap_iommu);
-void *ion_map_kernel(struct ion_client *client, struct ion_handle *handle,
- unsigned long flags)
+void *ion_map_kernel(struct ion_client *client, struct ion_handle *handle)
{
struct ion_buffer *buffer;
void *vaddr;
@@ -796,11 +779,6 @@
return ERR_PTR(-ENODEV);
}
- if (ion_validate_buffer_flags(buffer, flags)) {
- mutex_unlock(&client->lock);
- return ERR_PTR(-EEXIST);
- }
-
mutex_lock(&buffer->lock);
vaddr = ion_handle_kmap_get(handle);
mutex_unlock(&buffer->lock);
@@ -1228,36 +1206,6 @@
.kunmap = ion_dma_buf_kunmap,
};
-static int ion_share_set_flags(struct ion_client *client,
- struct ion_handle *handle,
- unsigned long flags)
-{
- struct ion_buffer *buffer;
- bool valid_handle;
- unsigned long ion_flags = ION_SET_CACHE(CACHED);
- if (flags & O_DSYNC)
- ion_flags = ION_SET_CACHE(UNCACHED);
-
- mutex_lock(&client->lock);
- valid_handle = ion_handle_validate(client, handle);
- mutex_unlock(&client->lock);
- if (!valid_handle) {
- WARN(1, "%s: invalid handle passed to set_flags.\n", __func__);
- return -EINVAL;
- }
-
- buffer = handle->buffer;
-
- mutex_lock(&buffer->lock);
- if (ion_validate_buffer_flags(buffer, ion_flags)) {
- mutex_unlock(&buffer->lock);
- return -EEXIST;
- }
- mutex_unlock(&buffer->lock);
- return 0;
-}
-
-
int ion_share_dma_buf(struct ion_client *client, struct ion_handle *handle)
{
struct ion_buffer *buffer;
@@ -1337,7 +1285,7 @@
if (copy_from_user(&data, (void __user *)arg, sizeof(data)))
return -EFAULT;
data.handle = ion_alloc(client, data.len, data.align,
- data.flags);
+ data.heap_mask, data.flags);
if (IS_ERR(data.handle))
return PTR_ERR(data.handle);
@@ -1368,14 +1316,9 @@
case ION_IOC_SHARE:
{
struct ion_fd_data data;
- int ret;
if (copy_from_user(&data, (void __user *)arg, sizeof(data)))
return -EFAULT;
- ret = ion_share_set_flags(client, data.handle, filp->f_flags);
- if (ret)
- return ret;
-
data.fd = ion_share_dma_buf(client, data.handle);
if (copy_to_user((void __user *)arg, &data, sizeof(data)))
return -EFAULT;
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 5904abb..ccc6119 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -357,7 +357,7 @@
/* MAX - 1, there is one memdesc in memstore for device info */
if (id >= KGSL_MEMSTORE_MAX) {
- KGSL_DRV_ERR(dev_priv->device, "cannot have more than %d "
+ KGSL_DRV_INFO(dev_priv->device, "cannot have more than %d "
"ctxts due to memstore limitation\n",
KGSL_MEMSTORE_MAX);
idr_remove(&dev_priv->device->context_idr, id);
@@ -1080,11 +1080,8 @@
int result;
context = kgsl_find_context(dev_priv, param->context_id);
- if (context == NULL) {
- KGSL_DRV_ERR(dev_priv->device, "invalid context_id %d\n",
- param->context_id);
+ if (context == NULL)
return -EINVAL;
- }
/*
* A reference count is needed here, because waittimestamp may
* block with the device mutex unlocked and userspace could
@@ -1108,17 +1105,11 @@
context = kgsl_find_context(dev_priv, param->drawctxt_id);
if (context == NULL) {
result = -EINVAL;
- KGSL_DRV_ERR(dev_priv->device,
- "invalid context_id %d\n",
- param->drawctxt_id);
goto done;
}
if (param->flags & KGSL_CONTEXT_SUBMIT_IB_LIST) {
if (!param->numibs) {
- KGSL_DRV_ERR(dev_priv->device,
- "Invalid numibs as parameter: %d\n",
- param->numibs);
result = -EINVAL;
goto done;
}
@@ -1129,9 +1120,6 @@
*/
if (param->numibs > 10000) {
- KGSL_DRV_ERR(dev_priv->device,
- "Too many IBs submitted. count: %d max 10000\n",
- param->numibs);
result = -EINVAL;
goto done;
}
@@ -1218,11 +1206,8 @@
struct kgsl_context *context;
context = kgsl_find_context(dev_priv, param->context_id);
- if (context == NULL) {
- KGSL_DRV_ERR(dev_priv->device, "invalid context_id %d\n",
- param->context_id);
+ if (context == NULL)
return -EINVAL;
- }
return _cmdstream_readtimestamp(dev_priv, context,
param->type, ¶m->timestamp);
@@ -1287,11 +1272,8 @@
struct kgsl_context *context;
context = kgsl_find_context(dev_priv, param->context_id);
- if (context == NULL) {
- KGSL_DRV_ERR(dev_priv->device,
- "invalid drawctxt context_id %d\n", param->context_id);
+ if (context == NULL)
return -EINVAL;
- }
return _cmdstream_freememontimestamp(dev_priv, param->gpuaddr,
context, param->timestamp, param->type);
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index f10f433..f671806 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -1389,7 +1389,8 @@
}
data->t9_max_reportid = t9_object->max_reportid;
data->t9_min_reportid = t9_object->max_reportid -
- t9_object->num_report_ids + 1;
+ (t9_object->num_report_ids *
+ (t9_object->instances + 1)) + 1;
if (data->pdata->key_codes) {
t15_object = mxt_get_object(data, MXT_TOUCH_KEYARRAY_T15);
@@ -1398,7 +1399,8 @@
else {
data->t15_max_reportid = t15_object->max_reportid;
data->t15_min_reportid = t15_object->max_reportid -
- t15_object->num_report_ids + 1;
+ (t15_object->num_report_ids *
+ (t15_object->instances + 1)) + 1;
}
}
@@ -1409,7 +1411,8 @@
else {
data->t42_max_reportid = t42_object->max_reportid;
data->t42_min_reportid = t42_object->max_reportid -
- t42_object->num_report_ids + 1;
+ (t42_object->num_report_ids *
+ (t42_object->instances + 1)) + 1;
}
return 0;
@@ -2231,6 +2234,14 @@
}
}
+ /* calibrate */
+ if (data->pdata->need_calibration) {
+ error = mxt_write_object(data, MXT_GEN_COMMAND_T6,
+ MXT_COMMAND_CALIBRATE, 1);
+ if (error < 0)
+ dev_dbg(dev, "sending calibration command failed\n");
+ }
+
mutex_unlock(&input_dev->mutex);
return 0;
@@ -2447,6 +2458,9 @@
return -EINVAL;
}
+ /* need calibration during wakeup? */
+ pdata->need_calibration = of_property_read_bool(np,
+ "atmel,need-calibration");
/* config array size */
pdata->config_array_size = 0;
temp = NULL;
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index f867dcb..ec3429b 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -16,7 +16,7 @@
# MSM IOMMU support
config MSM_IOMMU
bool "MSM IOMMU Support"
- depends on ARCH_MSM8X60 || ARCH_MSM8960 || ARCH_APQ8064 || ARCH_MSM8974
+ depends on ARCH_MSM8X60 || ARCH_MSM8960 || ARCH_APQ8064 || ARCH_MSM8974 || ARCH_MPQ8092
select IOMMU_API
help
Support for the IOMMUs found on certain Qualcomm SOCs.
diff --git a/drivers/leds/leds-qpnp.c b/drivers/leds/leds-qpnp.c
index f42fb5e..13493b8 100644
--- a/drivers/leds/leds-qpnp.c
+++ b/drivers/leds/leds-qpnp.c
@@ -17,6 +17,7 @@
#include <linux/slab.h>
#include <linux/leds.h>
#include <linux/err.h>
+#include <linux/spinlock.h>
#include <linux/of_platform.h>
#include <linux/of_device.h>
#include <linux/spmi.h>
@@ -163,7 +164,7 @@
int id;
u16 base;
u8 reg;
- struct mutex lock;
+ spinlock_t lock;
struct wled_config_data *wled_cfg;
int max_current;
bool default_on;
@@ -299,7 +300,7 @@
return;
}
- mutex_lock(&led->lock);
+ spin_lock(&led->lock);
led->cdev.brightness = value;
switch (led->id) {
@@ -313,7 +314,7 @@
dev_err(led->cdev.dev, "Invalid LED(%d)\n", led->id);
break;
}
- mutex_unlock(&led->lock);
+ spin_unlock(&led->lock);
}
static int __devinit qpnp_led_set_max_brightness(struct qpnp_led_data *led)
@@ -653,7 +654,7 @@
return -EINVAL;
}
- mutex_init(&led->lock);
+ spin_lock_init(&led->lock);
rc = qpnp_led_initialize(led);
if (rc < 0)
@@ -680,7 +681,6 @@
return 0;
fail_id_check:
- mutex_destroy(&led->lock);
led_classdev_unregister(&led->cdev);
return rc;
}
@@ -689,7 +689,6 @@
{
struct qpnp_led_data *led = dev_get_drvdata(&spmi->dev);
- mutex_destroy(&led->lock);
led_classdev_unregister(&led->cdev);
return 0;
diff --git a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.c b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.c
index 836ca65..18c3767 100644
--- a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.c
+++ b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.c
@@ -812,7 +812,7 @@
*kernel_mem = NULL;
} else {
*kernel_mem = ion_map_kernel(mpq_demux->ion_client,
- ion_handle, ionflag);
+ ion_handle);
if (*kernel_mem == NULL) {
MPQ_DVB_ERR_PRINT("%s: ion_map_kernel failed\n",
__func__);
@@ -932,7 +932,8 @@
ion_alloc(mpq_demux->ion_client,
actual_buffer_size,
SZ_4K,
- (ION_HEAP(ION_CP_MM_HEAP_ID) | CACHED));
+ ION_HEAP(ION_CP_MM_HEAP_ID),
+ ION_FLAG_CACHED);
if (IS_ERR_OR_NULL(feed_data->payload_buff_handle)) {
ret = PTR_ERR(feed_data->payload_buff_handle);
@@ -948,8 +949,7 @@
payload_buffer =
ion_map_kernel(mpq_demux->ion_client,
- feed_data->payload_buff_handle,
- 0);
+ feed_data->payload_buff_handle);
if (IS_ERR_OR_NULL(payload_buffer)) {
ret = PTR_ERR(payload_buffer);
diff --git a/drivers/media/dvb/mpq/video/mpq_dvb_video.c b/drivers/media/dvb/mpq/video/mpq_dvb_video.c
index 4b3fb0c..bd8c4a4 100644
--- a/drivers/media/dvb/mpq/video/mpq_dvb_video.c
+++ b/drivers/media/dvb/mpq/video/mpq_dvb_video.c
@@ -572,7 +572,7 @@
ion_flag = vidc_get_fd_info(client_ctx, BUFFER_TYPE_OUTPUT,
pmem_fd, kernel_vaddr, buffer_index,
&buff_handle);
- if (ion_flag == CACHED && buff_handle) {
+ if (ion_flag == ION_FLAG_CACHED && buff_handle) {
msm_ion_do_cache_op(
client_ctx->user_ion_client,
buff_handle,
@@ -1133,8 +1133,7 @@
}
vcd_h264_mv_buffer->kernel_virtual_addr =
(u8 *) ion_map_kernel(client_ctx->user_ion_client,
- client_ctx->h264_mv_ion_handle,
- ionflag);
+ client_ctx->h264_mv_ion_handle);
if (!vcd_h264_mv_buffer->kernel_virtual_addr) {
DBG("%s(): get_ION_kernel virtual addr failed\n",
__func__);
@@ -1146,7 +1145,7 @@
VIDEO_DOMAIN, VIDEO_MAIN_POOL,
SZ_4K, 0, (unsigned long *)&iova,
(unsigned long *)&buffer_size,
- UNCACHED, 0);
+ 0, 0);
if (rc) {
DBG("%s():get_ION_kernel physical addr fail\n",
__func__);
@@ -1503,7 +1502,7 @@
kernel_vaddr,
buffer_index,
&buff_handle);
- if (ion_flag == CACHED && buff_handle) {
+ if (ion_flag == ION_FLAG_CACHED && buff_handle) {
msm_ion_do_cache_op(
client_ctx->user_ion_client,
buff_handle,
diff --git a/drivers/media/radio/radio-tavarua.c b/drivers/media/radio/radio-tavarua.c
index af4c2c9..eb16f2d 100644
--- a/drivers/media/radio/radio-tavarua.c
+++ b/drivers/media/radio/radio-tavarua.c
@@ -1940,7 +1940,7 @@
}
/* Check for Bahama V2 variant*/
- if (bahama_version == 0x09) {
+ if ((bahama_version == 0x09) || (bahama_version == 0x0a)) {
/* In case of Bahama v2, forcefully enable the
* internal analog and digital voltage controllers
@@ -2179,7 +2179,8 @@
/* Set the index based on the bt status*/
index = bt_status ? 1 : 0;
/* Check for Bahama's existance and Bahama V2 variant*/
- if (bahama_present && (bahama_version == 0x09)) {
+ if (bahama_present
+ && (bahama_version == 0x09 || bahama_version == 0x0a)) {
radio->marimba->mod_id = SLAVE_ID_BAHAMA;
/* actual value itself used as mask*/
retval = marimba_write_bit_mask(radio->marimba,
@@ -4149,7 +4150,7 @@
/* use xfr for interrupt setup */
if (radio->chipID == MARIMBA_2_1 || radio->chipID == BAHAMA_1_0
- || radio->chipID == BAHAMA_2_0) {
+ || radio->chipID == BAHAMA_2_0 || radio->chipID == BAHAMA_2_1) {
FMDBG("Setting interrupts\n");
retval = sync_write_xfr(radio, INT_CTRL, int_ctrl);
/* use register write to setup interrupts */
@@ -4175,7 +4176,8 @@
* registers and it is not valid for MBA 2.1
*/
if ((radio->chipID != MARIMBA_2_1) && (radio->chipID != BAHAMA_1_0)
- && (radio->chipID != BAHAMA_2_0))
+ && (radio->chipID != BAHAMA_2_0)
+ && (radio->chipID != BAHAMA_2_1))
tavarua_handle_interrupts(radio);
return retval;
@@ -4208,7 +4210,7 @@
/* use xfr for interrupt setup */
wait_timeout = 100;
if (radio->chipID == MARIMBA_2_1 || radio->chipID == BAHAMA_1_0
- || radio->chipID == BAHAMA_2_0)
+ || radio->chipID == BAHAMA_2_0 || radio->chipID == BAHAMA_2_1)
retval = sync_write_xfr(radio, INT_CTRL, lpm_buf);
/* use register write to setup interrupts */
else
diff --git a/drivers/media/video/msm/gemini/msm_gemini_platform.c b/drivers/media/video/msm/gemini/msm_gemini_platform.c
index 28d2439..111402b 100644
--- a/drivers/media/video/msm/gemini/msm_gemini_platform.c
+++ b/drivers/media/video/msm/gemini/msm_gemini_platform.c
@@ -52,7 +52,7 @@
return 0;
rc = ion_map_iommu(gemini_client, *ionhandle, CAMERA_DOMAIN, GEN_POOL,
- SZ_4K, 0, &paddr, (unsigned long *)&size, UNCACHED, 0);
+ SZ_4K, 0, &paddr, (unsigned long *)&size, 0, 0);
#elif CONFIG_ANDROID_PMEM
unsigned long kvstart;
rc = get_pmem_file(fd, &paddr, &kvstart, &size, file_p);
diff --git a/drivers/media/video/msm/io/msm_camera_i2c.c b/drivers/media/video/msm/io/msm_camera_i2c.c
index 27ebac5..9e4fcd1 100644
--- a/drivers/media/video/msm/io/msm_camera_i2c.c
+++ b/drivers/media/video/msm/io/msm_camera_i2c.c
@@ -376,81 +376,67 @@
{
int i;
int32_t rc = -EFAULT;
- if (client->cci_client) {
- struct msm_camera_cci_ctrl cci_ctrl;
- cci_ctrl.cmd = MSM_CCI_I2C_WRITE;
- cci_ctrl.cci_info = client->cci_client;
- cci_ctrl.cfg.cci_i2c_write_cfg.reg_conf_tbl = reg_conf_tbl;
- cci_ctrl.cfg.cci_i2c_write_cfg.data_type = data_type;
- cci_ctrl.cfg.cci_i2c_write_cfg.addr_type = client->addr_type;
- cci_ctrl.cfg.cci_i2c_write_cfg.size = size;
- rc = v4l2_subdev_call(client->cci_client->cci_subdev,
- core, ioctl, VIDIOC_MSM_CCI_CFG, &cci_ctrl);
- CDBG("%s line %d rc = %d\n", __func__, __LINE__, rc);
- rc = cci_ctrl.status;
- } else {
- for (i = 0; i < size; i++) {
- enum msm_camera_i2c_data_type dt;
- if (reg_conf_tbl->cmd_type == MSM_CAMERA_I2C_CMD_POLL) {
- rc = msm_camera_i2c_poll(client,
+ for (i = 0; i < size; i++) {
+ enum msm_camera_i2c_data_type dt;
+ if (reg_conf_tbl->cmd_type == MSM_CAMERA_I2C_CMD_POLL) {
+ rc = msm_camera_i2c_poll(client,
+ reg_conf_tbl->reg_addr,
+ reg_conf_tbl->reg_data,
+ reg_conf_tbl->dt);
+ } else {
+ if (reg_conf_tbl->dt == 0)
+ dt = data_type;
+ else
+ dt = reg_conf_tbl->dt;
+ switch (dt) {
+ case MSM_CAMERA_I2C_BYTE_DATA:
+ case MSM_CAMERA_I2C_WORD_DATA:
+ rc = msm_camera_i2c_write(
+ client,
+ reg_conf_tbl->reg_addr,
+ reg_conf_tbl->reg_data, dt);
+ break;
+ case MSM_CAMERA_I2C_SET_BYTE_MASK:
+ rc = msm_camera_i2c_set_mask(client,
reg_conf_tbl->reg_addr,
reg_conf_tbl->reg_data,
- reg_conf_tbl->dt);
- } else {
- if (reg_conf_tbl->dt == 0)
- dt = data_type;
- else
- dt = reg_conf_tbl->dt;
- switch (dt) {
- case MSM_CAMERA_I2C_BYTE_DATA:
- case MSM_CAMERA_I2C_WORD_DATA:
- rc = msm_camera_i2c_write(
- client,
- reg_conf_tbl->reg_addr,
- reg_conf_tbl->reg_data, dt);
- break;
- case MSM_CAMERA_I2C_SET_BYTE_MASK:
- rc = msm_camera_i2c_set_mask(client,
- reg_conf_tbl->reg_addr,
- reg_conf_tbl->reg_data,
- MSM_CAMERA_I2C_BYTE_DATA, 1);
- break;
- case MSM_CAMERA_I2C_UNSET_BYTE_MASK:
- rc = msm_camera_i2c_set_mask(client,
- reg_conf_tbl->reg_addr,
- reg_conf_tbl->reg_data,
- MSM_CAMERA_I2C_BYTE_DATA, 0);
- break;
- case MSM_CAMERA_I2C_SET_WORD_MASK:
- rc = msm_camera_i2c_set_mask(client,
- reg_conf_tbl->reg_addr,
- reg_conf_tbl->reg_data,
- MSM_CAMERA_I2C_WORD_DATA, 1);
- break;
- case MSM_CAMERA_I2C_UNSET_WORD_MASK:
- rc = msm_camera_i2c_set_mask(client,
- reg_conf_tbl->reg_addr,
- reg_conf_tbl->reg_data,
- MSM_CAMERA_I2C_WORD_DATA, 0);
- break;
- case MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA:
- rc = msm_camera_i2c_set_write_mask_data(
- client,
- reg_conf_tbl->reg_addr,
- reg_conf_tbl->reg_data,
- reg_conf_tbl->mask,
- MSM_CAMERA_I2C_BYTE_DATA);
- break;
- default:
- pr_err("%s: Unsupport data type: %d\n",
- __func__, dt);
- break;
- }
- }
- if (rc < 0)
+ MSM_CAMERA_I2C_BYTE_DATA, 1);
break;
- reg_conf_tbl++;
+ case MSM_CAMERA_I2C_UNSET_BYTE_MASK:
+ rc = msm_camera_i2c_set_mask(client,
+ reg_conf_tbl->reg_addr,
+ reg_conf_tbl->reg_data,
+ MSM_CAMERA_I2C_BYTE_DATA, 0);
+ break;
+ case MSM_CAMERA_I2C_SET_WORD_MASK:
+ rc = msm_camera_i2c_set_mask(client,
+ reg_conf_tbl->reg_addr,
+ reg_conf_tbl->reg_data,
+ MSM_CAMERA_I2C_WORD_DATA, 1);
+ break;
+ case MSM_CAMERA_I2C_UNSET_WORD_MASK:
+ rc = msm_camera_i2c_set_mask(client,
+ reg_conf_tbl->reg_addr,
+ reg_conf_tbl->reg_data,
+ MSM_CAMERA_I2C_WORD_DATA, 0);
+ break;
+ case MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA:
+ rc = msm_camera_i2c_set_write_mask_data(
+ client,
+ reg_conf_tbl->reg_addr,
+ reg_conf_tbl->reg_data,
+ reg_conf_tbl->mask,
+ MSM_CAMERA_I2C_BYTE_DATA);
+ break;
+ default:
+ pr_err("%s: Unsupport data type: %d\n",
+ __func__, dt);
+ break;
+ }
}
+ if (rc < 0)
+ break;
+ reg_conf_tbl++;
}
return rc;
}
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_platform.c b/drivers/media/video/msm/jpeg_10/msm_jpeg_platform.c
index 0370f63..06135ec 100644
--- a/drivers/media/video/msm/jpeg_10/msm_jpeg_platform.c
+++ b/drivers/media/video/msm/jpeg_10/msm_jpeg_platform.c
@@ -50,7 +50,7 @@
return 0;
rc = ion_map_iommu(pgmn_dev->jpeg_client, *ionhandle, domain_num, 0,
- SZ_4K, 0, &paddr, (unsigned long *)&size, UNCACHED,
+ SZ_4K, 0, &paddr, (unsigned long *)&size, 0,
0); JPEG_DBG("%s:%d] addr 0x%x size %ld", __func__, __LINE__,
(uint32_t)paddr, size);
diff --git a/drivers/media/video/msm/mercury/msm_mercury_platform.c b/drivers/media/video/msm/mercury/msm_mercury_platform.c
index e90c63c..3dc7f4b 100644
--- a/drivers/media/video/msm/mercury/msm_mercury_platform.c
+++ b/drivers/media/video/msm/mercury/msm_mercury_platform.c
@@ -58,7 +58,7 @@
rc = ion_map_iommu(mercury_client, *ionhandle, CAMERA_DOMAIN,
GEN_POOL, SZ_4K, 0, &paddr,
- (unsigned long *)&size, UNCACHED, 0);
+ (unsigned long *)&size, 0, 0);
#elif CONFIG_ANDROID_PMEM
unsigned long kvstart;
rc = get_pmem_file(fd, &paddr, &kvstart, &size, file_p);
diff --git a/drivers/media/video/msm/msm_isp.c b/drivers/media/video/msm/msm_isp.c
index 1e17c5c..2c95ef5 100644
--- a/drivers/media/video/msm/msm_isp.c
+++ b/drivers/media/video/msm/msm_isp.c
@@ -148,6 +148,8 @@
image_mode = MSM_V4L2_EXT_CAPTURE_MODE_RDI1;
else
image_mode = -1;
+ } else if (VFE_MSG_V2X_LIVESHOT_PRIMARY == vfe_msg) {
+ image_mode = MSM_V4L2_EXT_CAPTURE_MODE_V2X_LIVESHOT;
} else
image_mode = -1;
diff --git a/drivers/media/video/msm/msm_mctl_buf.c b/drivers/media/video/msm/msm_mctl_buf.c
index 953f042..a3c7243 100644
--- a/drivers/media/video/msm/msm_mctl_buf.c
+++ b/drivers/media/video/msm/msm_mctl_buf.c
@@ -557,37 +557,53 @@
struct msm_cam_v4l2_device *pcam = pmctl->pcam_ptr;
int idx;
- /* Valid image mode. Search the mctl node first.
- * If mctl node doesnt have the instance, then
- * search in the user's video node */
- if (pmctl->vfe_output_mode == VFE_OUTPUTS_MAIN_AND_THUMB
- || pmctl->vfe_output_mode == VFE_OUTPUTS_THUMB_AND_MAIN
- || pmctl->vfe_output_mode == VFE_OUTPUTS_MAIN_AND_PREVIEW) {
- if (pcam->mctl_node.dev_inst_map[img_mode]
- && is_buffer_queued(pcam, img_mode)) {
- idx = pcam->mctl_node.dev_inst_map[img_mode]->my_index;
- pcam_inst = pcam->mctl_node.dev_inst[idx];
- D("%s Found instance %p in mctl node device\n",
+ /* Valid image mode. Search the mctl node first.
+ * If mctl node doesnt have the instance, then
+ * search in the user's video node */
+ if (pmctl->vfe_output_mode == VFE_OUTPUTS_MAIN_AND_THUMB
+ || pmctl->vfe_output_mode == VFE_OUTPUTS_THUMB_AND_MAIN) {
+ if (pcam->mctl_node.dev_inst_map[img_mode]
+ && is_buffer_queued(pcam, img_mode)) {
+ idx = pcam->mctl_node.dev_inst_map[img_mode]
+ ->my_index;
+ pcam_inst = pcam->mctl_node.dev_inst[idx];
+ D("%s Found instance %p in mctl node device\n",
+ __func__, pcam_inst);
+ } else if (pcam->dev_inst_map[img_mode]) {
+ idx = pcam->dev_inst_map[img_mode]->my_index;
+ pcam_inst = pcam->dev_inst[idx];
+ D("%s Found instance %p in video device\n",
__func__, pcam_inst);
- } else if (pcam->dev_inst_map[img_mode]) {
- idx = pcam->dev_inst_map[img_mode]->my_index;
- pcam_inst = pcam->dev_inst[idx];
- D("%s Found instance %p in video device\n",
+ }
+ } else if (img_mode == MSM_V4L2_EXT_CAPTURE_MODE_V2X_LIVESHOT) {
+ img_mode = MSM_V4L2_EXT_CAPTURE_MODE_MAIN;
+ if (pcam->mctl_node.dev_inst_map[img_mode] &&
+ is_buffer_queued(pcam, img_mode)) {
+ idx = pcam->mctl_node.dev_inst_map[img_mode]
+ ->my_index;
+ pcam_inst = pcam->mctl_node.dev_inst[idx];
+ D("%s Found instance %p in mctl node device\n",
+ __func__, pcam_inst);
+ } else if (pcam->dev_inst_map[img_mode]) {
+ idx = pcam->dev_inst_map[img_mode]->my_index;
+ pcam_inst = pcam->dev_inst[idx];
+ D("%s Found instance %p in video device\n",
__func__, pcam_inst);
+ }
+ } else {
+ if (pcam->mctl_node.dev_inst_map[img_mode]) {
+ idx = pcam->mctl_node.dev_inst_map[img_mode]
+ ->my_index;
+ pcam_inst = pcam->mctl_node.dev_inst[idx];
+ D("%s Found instance %p in mctl node device\n",
+ __func__, pcam_inst);
+ } else if (pcam->dev_inst_map[img_mode]) {
+ idx = pcam->dev_inst_map[img_mode]->my_index;
+ pcam_inst = pcam->dev_inst[idx];
+ D("%s Found instance %p in video device\n",
+ __func__, pcam_inst);
+ }
}
- } else {
- if (pcam->mctl_node.dev_inst_map[img_mode]) {
- idx = pcam->mctl_node.dev_inst_map[img_mode]->my_index;
- pcam_inst = pcam->mctl_node.dev_inst[idx];
- D("%s Found instance %p in mctl node device\n",
- __func__, pcam_inst);
- } else if (pcam->dev_inst_map[img_mode]) {
- idx = pcam->dev_inst_map[img_mode]->my_index;
- pcam_inst = pcam->dev_inst[idx];
- D("%s Found instance %p in video device\n",
- __func__, pcam_inst);
- }
- }
return pcam_inst;
}
@@ -898,7 +914,7 @@
meta_frame->map[i].handle);
if (ion_map_iommu(client, meta_frame->map[i].handle,
domain_num, 0, SZ_4K,
- 0, &paddr, &len, UNCACHED, 0) < 0) {
+ 0, &paddr, &len, 0, 0) < 0) {
pr_err("%s: cannot map address plane %d", __func__, i);
ion_free(client, meta_frame->map[i].handle);
/* Roll back previous plane mappings, if any */
diff --git a/drivers/media/video/msm/msm_mem.c b/drivers/media/video/msm/msm_mem.c
index 5136d9d..1875df2 100644
--- a/drivers/media/video/msm/msm_mem.c
+++ b/drivers/media/video/msm/msm_mem.c
@@ -136,7 +136,7 @@
if (IS_ERR_OR_NULL(region->handle))
goto out1;
if (ion_map_iommu(client, region->handle, domain_num, 0,
- SZ_4K, 0, &paddr, &len, UNCACHED, 0) < 0)
+ SZ_4K, 0, &paddr, &len, 0, 0) < 0)
goto out2;
#elif CONFIG_ANDROID_PMEM
rc = get_pmem_file(info->fd, &paddr, &kvstart, &len, &file);
diff --git a/drivers/media/video/msm/sensors/msm_sensor.c b/drivers/media/video/msm/sensors/msm_sensor.c
index f5c9a73..63cf38e 100644
--- a/drivers/media/video/msm/sensors/msm_sensor.c
+++ b/drivers/media/video/msm/sensors/msm_sensor.c
@@ -1143,18 +1143,6 @@
sensordata->pdata[i].csid_core);
}
- rc = of_property_read_u32_array(of_node, "qcom,is-vpe", val_array,
- count);
- if (rc < 0) {
- pr_err("%s failed %d\n", __func__, __LINE__);
- goto ERROR2;
- }
- for (i = 0; i < count; i++) {
- sensordata->pdata[i].is_vpe = val_array[i];
- CDBG("%s csi_data[%d].is_vpe = %d\n", __func__, i,
- sensordata->pdata[i].is_vpe);
- }
-
pinfo->csi_lane_params = kzalloc(
sizeof(struct msm_camera_csi_lane_params), GFP_KERNEL);
if (!pinfo->csi_lane_params) {
diff --git a/drivers/media/video/msm/sensors/mt9m114_v4l2.c b/drivers/media/video/msm/sensors/mt9m114_v4l2.c
index cba9538..c952f7b 100644
--- a/drivers/media/video/msm/sensors/mt9m114_v4l2.c
+++ b/drivers/media/video/msm/sensors/mt9m114_v4l2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -1219,11 +1219,52 @@
.addr_type = MSM_CAMERA_I2C_WORD_ADDR,
};
+static const struct of_device_id mt9m114_dt_match[] = {
+ {.compatible = "qcom,mt9m114", .data = &mt9m114_s_ctrl},
+ {}
+};
+
+MODULE_DEVICE_TABLE(of, mt9m114_dt_match);
+
+static struct platform_driver mt9m114_platform_driver = {
+ .driver = {
+ .name = "qcom,mt9m114",
+ .owner = THIS_MODULE,
+ .of_match_table = mt9m114_dt_match,
+ },
+};
+
+static int32_t mt9m114_platform_probe(struct platform_device *pdev)
+{
+ int32_t rc = 0;
+ const struct of_device_id *match;
+ match = of_match_device(mt9m114_dt_match, &pdev->dev);
+ rc = msm_sensor_platform_probe(pdev, match->data);
+ return rc;
+}
+
static int __init msm_sensor_init_module(void)
{
+ int32_t rc = 0;
+ rc = platform_driver_probe(&mt9m114_platform_driver,
+ mt9m114_platform_probe);
+ if (!rc)
+ return rc;
return i2c_add_driver(&mt9m114_i2c_driver);
}
+
+static void __exit msm_sensor_exit_module(void)
+{
+ if (mt9m114_s_ctrl.pdev) {
+ msm_sensor_free_sensor_data(&mt9m114_s_ctrl);
+ platform_driver_unregister(&mt9m114_platform_driver);
+ } else {
+ i2c_del_driver(&mt9m114_i2c_driver);
+ }
+ return;
+}
+
static struct v4l2_subdev_core_ops mt9m114_subdev_core_ops = {
.s_ctrl = msm_sensor_v4l2_s_ctrl,
.queryctrl = msm_sensor_v4l2_query_ctrl,
@@ -1286,5 +1327,6 @@
};
module_init(msm_sensor_init_module);
+module_exit(msm_sensor_exit_module);
MODULE_DESCRIPTION("Aptina 1.26MP YUV sensor driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/server/msm_cam_server.c b/drivers/media/video/msm/server/msm_cam_server.c
index 74dd3f2..84aaa69 100644
--- a/drivers/media/video/msm/server/msm_cam_server.c
+++ b/drivers/media/video/msm/server/msm_cam_server.c
@@ -311,7 +311,7 @@
if (command->length > 0) {
command->value =
g_server_dev.server_queue[command->queue_idx].ctrl_data;
- if (command->length > max_control_command_size) {
+ if (command->length > MAX_SERVER_PAYLOAD_LENGTH) {
pr_err("%s: user data %d is too big (max %d)\n",
__func__, command->length,
max_control_command_size);
@@ -476,20 +476,22 @@
struct msm_camera_v4l2_ioctl_t *ioctl_ptr)
{
struct msm_ctrl_cmd ctrlcmd;
- void *temp_data;
+ void *temp_data = NULL;
int rc;
- temp_data = kzalloc(ioctl_ptr->len, GFP_KERNEL);
- if (!temp_data) {
- pr_err("%s could not allocate memory\n", __func__);
- rc = -ENOMEM;
- goto end;
- }
- if (copy_from_user((void *)temp_data,
- (void __user *)ioctl_ptr->ioctl_ptr,
- ioctl_ptr->len)) {
- ERR_COPY_FROM_USER();
- rc = -EFAULT;
- goto copy_from_user_failed;
+ if (ioctl_ptr->len > 0) {
+ temp_data = kzalloc(ioctl_ptr->len, GFP_KERNEL);
+ if (!temp_data) {
+ pr_err("%s could not allocate memory\n", __func__);
+ rc = -ENOMEM;
+ goto end;
+ }
+ if (copy_from_user((void *)temp_data,
+ (void __user *)ioctl_ptr->ioctl_ptr,
+ ioctl_ptr->len)) {
+ ERR_COPY_FROM_USER();
+ rc = -EFAULT;
+ goto copy_from_user_failed;
+ }
}
mutex_lock(&pcam->vid_lock);
@@ -505,6 +507,16 @@
rc = msm_server_control(&g_server_dev, 0, &ctrlcmd);
if (rc < 0)
pr_err("%s: send event failed\n", __func__);
+ else {
+ if (ioctl_ptr->len > 0) {
+ if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr,
+ (void *)temp_data,
+ ioctl_ptr->len)) {
+ ERR_COPY_TO_USER();
+ rc = -EFAULT;
+ }
+ }
+ }
mutex_unlock(&pcam->vid_lock);
kfree(temp_data);
@@ -1519,7 +1531,12 @@
pcam->server_queue_idx = server_q_idx;
queue = &g_server_dev.server_queue[server_q_idx];
queue->ctrl_data = kzalloc(sizeof(uint8_t) *
- max_control_command_size, GFP_KERNEL);
+ MAX_SERVER_PAYLOAD_LENGTH, GFP_KERNEL);
+ if (queue->ctrl_data == NULL) {
+ pr_err("%s: Could not allocate memory\n", __func__);
+ rc = -ENOMEM;
+ goto error;
+ }
msm_queue_init(&queue->ctrl_q, "control");
msm_queue_init(&queue->eventData_q, "eventdata");
queue->queue_active = 1;
@@ -2523,7 +2540,11 @@
*p_qidx = server_q_idx;
queue = &g_server_dev.server_queue[server_q_idx];
queue->ctrl_data = kzalloc(sizeof(uint8_t) *
- max_control_command_size, GFP_KERNEL);
+ MAX_SERVER_PAYLOAD_LENGTH, GFP_KERNEL);
+ if (!queue->ctrl_data) {
+ pr_err("%s: Could not find memory\n", __func__);
+ return -ENOMEM;
+ }
msm_queue_init(&queue->ctrl_q, "control");
msm_queue_init(&queue->eventData_q, "eventdata");
queue->queue_active = 1;
diff --git a/drivers/media/video/msm/vfe/msm_vfe7x27a_v4l2.c b/drivers/media/video/msm/vfe/msm_vfe7x27a_v4l2.c
index 9deae65..6440b8e 100644
--- a/drivers/media/video/msm/vfe/msm_vfe7x27a_v4l2.c
+++ b/drivers/media/video/msm/vfe/msm_vfe7x27a_v4l2.c
@@ -836,7 +836,12 @@
kfree(data);
return;
}
- free_buf = vfe2x_check_free_buffer(
+ if (vfe2x_ctrl->liveshot_enabled)
+ free_buf = vfe2x_check_free_buffer(
+ VFE_MSG_OUTPUT_IRQ,
+ VFE_MSG_V2X_LIVESHOT_PRIMARY);
+ else
+ free_buf = vfe2x_check_free_buffer(
VFE_MSG_OUTPUT_IRQ,
VFE_MSG_OUTPUT_PRIMARY);
CDBG("free_buf = %x\n",
@@ -1353,12 +1358,14 @@
vfe2x_subdev_notify(id, path);
if (op_mode & SNAPSHOT_MASK_MODE) {
- if (path == VFE_MSG_OUTPUT_PRIMARY)
+ if (path == VFE_MSG_OUTPUT_PRIMARY ||
+ path == VFE_MSG_V2X_LIVESHOT_PRIMARY)
outch = &vfe2x_ctrl->snap;
else if (path == VFE_MSG_OUTPUT_SECONDARY)
outch = &vfe2x_ctrl->thumb;
} else {
- if (path == VFE_MSG_OUTPUT_PRIMARY) {
+ if (path == VFE_MSG_OUTPUT_PRIMARY ||
+ path == VFE_MSG_V2X_LIVESHOT_PRIMARY) {
if (vfe2x_ctrl->zsl_mode)
outch = &vfe2x_ctrl->zsl_prim;
else
@@ -1380,12 +1387,14 @@
vfe2x_subdev_notify(id, path);
CDBG("Opmode = %d\n", op_mode);
if (op_mode & SNAPSHOT_MASK_MODE) {
- if (path == VFE_MSG_OUTPUT_PRIMARY)
+ if (path == VFE_MSG_OUTPUT_PRIMARY ||
+ path == VFE_MSG_V2X_LIVESHOT_PRIMARY)
outch = &vfe2x_ctrl->snap;
else if (path == VFE_MSG_OUTPUT_SECONDARY)
outch = &vfe2x_ctrl->thumb;
} else {
- if (path == VFE_MSG_OUTPUT_PRIMARY) {
+ if (path == VFE_MSG_OUTPUT_PRIMARY ||
+ path == VFE_MSG_V2X_LIVESHOT_PRIMARY) {
if (vfe2x_ctrl->zsl_mode)
outch = &vfe2x_ctrl->zsl_prim;
else
@@ -1413,10 +1422,12 @@
if (op_mode & SNAPSHOT_MASK_MODE) {
if (path == VFE_MSG_OUTPUT_SECONDARY)
ch = &vfe2x_ctrl->thumb;
- else if (path == VFE_MSG_OUTPUT_PRIMARY)
+ else if (path == VFE_MSG_OUTPUT_PRIMARY ||
+ path == VFE_MSG_V2X_LIVESHOT_PRIMARY)
ch = &vfe2x_ctrl->snap;
} else {
- if (path == VFE_MSG_OUTPUT_PRIMARY) {
+ if (path == VFE_MSG_OUTPUT_PRIMARY ||
+ path == VFE_MSG_V2X_LIVESHOT_PRIMARY) {
if (vfe2x_ctrl->zsl_mode)
ch = &vfe2x_ctrl->zsl_prim;
else
diff --git a/drivers/media/video/msm/vfe/msm_vfe_stats_buf.c b/drivers/media/video/msm/vfe/msm_vfe_stats_buf.c
index a813e09..36f8b11 100644
--- a/drivers/media/video/msm/vfe/msm_vfe_stats_buf.c
+++ b/drivers/media/video/msm/vfe/msm_vfe_stats_buf.c
@@ -221,7 +221,7 @@
}
if (ion_map_iommu(client, stats_buf->handle,
domain_num, 0, SZ_4K,
- 0, &paddr, &len, UNCACHED, 0) < 0) {
+ 0, &paddr, &len, 0, 0) < 0) {
rc = -EINVAL;
pr_err("%s: cannot map address", __func__);
goto out2;
diff --git a/drivers/media/video/msm_vidc/msm_smem.c b/drivers/media/video/msm_vidc/msm_smem.c
index 156a721..3dd2193 100644
--- a/drivers/media/video/msm_vidc/msm_smem.c
+++ b/drivers/media/video/msm_vidc/msm_smem.c
@@ -24,7 +24,7 @@
static int get_device_address(struct ion_client *clnt,
struct ion_handle *hndl, int domain_num, int partition_num,
unsigned long align, unsigned long *iova,
- unsigned long *buffer_size, unsigned long flags)
+ unsigned long *buffer_size)
{
int rc;
if (!iova || !buffer_size || !hndl || !clnt) {
@@ -37,7 +37,7 @@
dprintk(VIDC_DBG, "domain: %d, partition: %d\n",
domain_num, partition_num);
rc = ion_map_iommu(clnt, hndl, domain_num, partition_num, align,
- 0, iova, buffer_size, UNCACHED, 0);
+ 0, iova, buffer_size, 0, 0);
if (rc)
dprintk(VIDC_ERR,
"ion_map_iommu failed(%d).domain: %d,partition: %d\n",
@@ -57,7 +57,6 @@
struct msm_smem *mem)
{
struct ion_handle *hndl;
- unsigned long ionflag;
unsigned long iova = 0;
unsigned long buffer_size = 0;
int rc = 0;
@@ -68,16 +67,11 @@
rc = -ENOMEM;
goto fail_import_fd;
}
- rc = ion_handle_get_flags(client->clnt, hndl, &ionflag);
- if (rc) {
- dprintk(VIDC_ERR, "Failed to get ion flags: %d", rc);
- goto fail_map;
- }
mem->kvaddr = NULL;
mem->domain = domain;
mem->partition_num = partition;
rc = get_device_address(client->clnt, hndl, mem->domain,
- mem->partition_num, 4096, &iova, &buffer_size, ionflag);
+ mem->partition_num, 4096, &iova, &buffer_size);
if (rc) {
dprintk(VIDC_ERR, "Failed to get device address: %d\n", rc);
goto fail_device_address;
@@ -92,7 +86,6 @@
return rc;
fail_device_address:
ion_unmap_kernel(client->clnt, hndl);
-fail_map:
ion_free(client->clnt, hndl);
fail_import_fd:
return rc;
@@ -106,19 +99,20 @@
unsigned long iova = 0;
unsigned long buffer_size = 0;
unsigned long ionflags = 0;
+ unsigned long heap_mask = 0;
int rc = 0;
if (flags == SMEM_CACHED)
- ionflags |= ION_SET_CACHE(CACHED);
+ ionflags = ION_SET_CACHED(ionflags);
else
- ionflags |= ION_SET_CACHE(UNCACHED);
+ ionflags = ION_SET_UNCACHED(ionflags);
- ionflags = ionflags | ION_HEAP(ION_CP_MM_HEAP_ID);
+ heap_mask = ION_HEAP(ION_CP_MM_HEAP_ID);
if (align < 4096)
align = 4096;
size = (size + 4095) & (~4095);
dprintk(VIDC_DBG, "domain: %d, partition: %d\n",
domain, partition);
- hndl = ion_alloc(client->clnt, size, align, ionflags);
+ hndl = ion_alloc(client->clnt, size, align, heap_mask, ionflags);
if (IS_ERR_OR_NULL(hndl)) {
dprintk(VIDC_ERR,
"Failed to allocate shared memory = %p, %d, %d, 0x%lx\n",
@@ -131,7 +125,7 @@
mem->domain = domain;
mem->partition_num = partition;
if (map_kernel) {
- mem->kvaddr = ion_map_kernel(client->clnt, hndl, 0);
+ mem->kvaddr = ion_map_kernel(client->clnt, hndl);
if (!mem->kvaddr) {
dprintk(VIDC_ERR,
"Failed to map shared mem in kernel\n");
@@ -142,7 +136,7 @@
mem->kvaddr = NULL;
rc = get_device_address(client->clnt, hndl, mem->domain,
- mem->partition_num, align, &iova, &buffer_size, UNCACHED);
+ mem->partition_num, align, &iova, &buffer_size);
if (rc) {
dprintk(VIDC_ERR, "Failed to get device address: %d\n",
rc);
diff --git a/drivers/media/video/msm_vidc/msm_v4l2_vidc.c b/drivers/media/video/msm_vidc/msm_v4l2_vidc.c
index 7fa4f26..fda03de 100644
--- a/drivers/media/video/msm_vidc/msm_v4l2_vidc.c
+++ b/drivers/media/video/msm_vidc/msm_v4l2_vidc.c
@@ -583,7 +583,7 @@
buffer_info.m.planes[0].reserved[0],
buffer_info.m.planes[0].reserved[1],
buffer_info.m.planes[0].length);
- rc = msm_vidc_release_buf(&v4l2_inst->vidc_inst,
+ rc = msm_vidc_release_buf(v4l2_inst->vidc_inst,
&buffer_info);
if (rc)
dprintk(VIDC_ERR,
diff --git a/drivers/media/video/msm_vidc/msm_vdec.c b/drivers/media/video/msm_vidc/msm_vdec.c
index ead118d..d843d87 100644
--- a/drivers/media/video/msm_vidc/msm_vdec.c
+++ b/drivers/media/video/msm_vidc/msm_vdec.c
@@ -281,7 +281,7 @@
int msm_vdec_streamon(struct msm_vidc_inst *inst, enum v4l2_buf_type i)
{
int rc = 0;
- struct vb2_queue *q;
+ struct buf_queue *q;
q = msm_comm_get_vb2q(inst, i);
if (!q) {
dprintk(VIDC_ERR,
@@ -289,7 +289,9 @@
return -EINVAL;
}
dprintk(VIDC_DBG, "Calling streamon\n");
- rc = vb2_streamon(q, i);
+ mutex_lock(&q->lock);
+ rc = vb2_streamon(&q->vb2_bufq, i);
+ mutex_unlock(&q->lock);
if (rc)
dprintk(VIDC_ERR, "streamon failed on port: %d\n", i);
return rc;
@@ -298,7 +300,7 @@
int msm_vdec_streamoff(struct msm_vidc_inst *inst, enum v4l2_buf_type i)
{
int rc = 0;
- struct vb2_queue *q;
+ struct buf_queue *q;
q = msm_comm_get_vb2q(inst, i);
if (!q) {
@@ -307,7 +309,9 @@
return -EINVAL;
}
dprintk(VIDC_DBG, "Calling streamoff\n");
- rc = vb2_streamoff(q, i);
+ mutex_lock(&q->lock);
+ rc = vb2_streamoff(&q->vb2_bufq, i);
+ mutex_unlock(&q->lock);
if (rc)
dprintk(VIDC_ERR, "streamoff failed on port: %d\n", i);
return rc;
@@ -403,7 +407,7 @@
int msm_vdec_qbuf(struct msm_vidc_inst *inst, struct v4l2_buffer *b)
{
- struct vb2_queue *q = NULL;
+ struct buf_queue *q = NULL;
int rc = 0;
q = msm_comm_get_vb2q(inst, b->type);
if (!q) {
@@ -411,14 +415,16 @@
, b->type);
return -EINVAL;
}
- rc = vb2_qbuf(q, b);
+ mutex_lock(&q->lock);
+ rc = vb2_qbuf(&q->vb2_bufq, b);
+ mutex_unlock(&q->lock);
if (rc)
dprintk(VIDC_ERR, "Failed to qbuf, %d\n", rc);
return rc;
}
int msm_vdec_dqbuf(struct msm_vidc_inst *inst, struct v4l2_buffer *b)
{
- struct vb2_queue *q = NULL;
+ struct buf_queue *q = NULL;
int rc = 0;
q = msm_comm_get_vb2q(inst, b->type);
if (!q) {
@@ -426,7 +432,9 @@
, b->type);
return -EINVAL;
}
- rc = vb2_dqbuf(q, b, true);
+ mutex_lock(&q->lock);
+ rc = vb2_dqbuf(&q->vb2_bufq, b, true);
+ mutex_unlock(&q->lock);
if (rc)
dprintk(VIDC_WARN, "Failed to dqbuf, %d\n", rc);
return rc;
@@ -434,7 +442,7 @@
int msm_vdec_reqbufs(struct msm_vidc_inst *inst, struct v4l2_requestbuffers *b)
{
- struct vb2_queue *q = NULL;
+ struct buf_queue *q = NULL;
int rc = 0;
if (!inst || !b) {
dprintk(VIDC_ERR,
@@ -448,7 +456,9 @@
return -EINVAL;
}
- rc = vb2_reqbufs(q, b);
+ mutex_lock(&q->lock);
+ rc = vb2_reqbufs(&q->vb2_bufq, b);
+ mutex_unlock(&q->lock);
if (rc)
dprintk(VIDC_ERR, "Failed to get reqbufs, %d\n", rc);
return rc;
@@ -770,11 +780,11 @@
"Streamon called on: %d capability\n", q->type);
switch (q->type) {
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
- if (inst->vb2_bufq[CAPTURE_PORT].streaming)
+ if (inst->bufq[CAPTURE_PORT].vb2_bufq.streaming)
rc = start_streaming(inst);
break;
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
- if (inst->vb2_bufq[OUTPUT_PORT].streaming)
+ if (inst->bufq[OUTPUT_PORT].vb2_bufq.streaming)
rc = start_streaming(inst);
break;
default:
@@ -797,11 +807,11 @@
dprintk(VIDC_DBG, "Streamoff called on: %d capability\n", q->type);
switch (q->type) {
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
- if (!inst->vb2_bufq[CAPTURE_PORT].streaming)
+ if (!inst->bufq[CAPTURE_PORT].vb2_bufq.streaming)
rc = stop_streaming(inst);
break;
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
- if (!inst->vb2_bufq[OUTPUT_PORT].streaming)
+ if (!inst->bufq[OUTPUT_PORT].vb2_bufq.streaming)
rc = stop_streaming(inst);
break;
default:
diff --git a/drivers/media/video/msm_vidc/msm_venc.c b/drivers/media/video/msm_vidc/msm_venc.c
index 8071191..948676a 100644
--- a/drivers/media/video/msm_vidc/msm_venc.c
+++ b/drivers/media/video/msm_vidc/msm_venc.c
@@ -711,11 +711,11 @@
dprintk(VIDC_DBG, "Streamon called on: %d capability\n", q->type);
switch (q->type) {
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
- if (inst->vb2_bufq[CAPTURE_PORT].streaming)
+ if (inst->bufq[CAPTURE_PORT].vb2_bufq.streaming)
rc = start_streaming(inst);
break;
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
- if (inst->vb2_bufq[OUTPUT_PORT].streaming)
+ if (inst->bufq[OUTPUT_PORT].vb2_bufq.streaming)
rc = start_streaming(inst);
break;
default:
@@ -1437,7 +1437,7 @@
int msm_venc_reqbufs(struct msm_vidc_inst *inst, struct v4l2_requestbuffers *b)
{
- struct vb2_queue *q = NULL;
+ struct buf_queue *q = NULL;
int rc = 0;
if (!inst || !b) {
dprintk(VIDC_ERR,
@@ -1451,7 +1451,9 @@
return -EINVAL;
}
- rc = vb2_reqbufs(q, b);
+ mutex_lock(&q->lock);
+ rc = vb2_reqbufs(&q->vb2_bufq, b);
+ mutex_unlock(&q->lock);
if (rc)
dprintk(VIDC_ERR, "Failed to get reqbufs, %d\n", rc);
return rc;
@@ -1497,7 +1499,7 @@
int msm_venc_qbuf(struct msm_vidc_inst *inst, struct v4l2_buffer *b)
{
- struct vb2_queue *q = NULL;
+ struct buf_queue *q = NULL;
int rc = 0;
q = msm_comm_get_vb2q(inst, b->type);
if (!q) {
@@ -1505,7 +1507,9 @@
"Failed to find buffer queue for type = %d\n", b->type);
return -EINVAL;
}
- rc = vb2_qbuf(q, b);
+ mutex_lock(&q->lock);
+ rc = vb2_qbuf(&q->vb2_bufq, b);
+ mutex_unlock(&q->lock);
if (rc)
dprintk(VIDC_ERR, "Failed to qbuf, %d\n", rc);
return rc;
@@ -1513,7 +1517,7 @@
int msm_venc_dqbuf(struct msm_vidc_inst *inst, struct v4l2_buffer *b)
{
- struct vb2_queue *q = NULL;
+ struct buf_queue *q = NULL;
int rc = 0;
q = msm_comm_get_vb2q(inst, b->type);
if (!q) {
@@ -1521,7 +1525,9 @@
"Failed to find buffer queue for type = %d\n", b->type);
return -EINVAL;
}
- rc = vb2_dqbuf(q, b, true);
+ mutex_lock(&q->lock);
+ rc = vb2_dqbuf(&q->vb2_bufq, b, true);
+ mutex_unlock(&q->lock);
if (rc)
dprintk(VIDC_DBG, "Failed to dqbuf, %d\n", rc);
return rc;
@@ -1530,7 +1536,7 @@
int msm_venc_streamon(struct msm_vidc_inst *inst, enum v4l2_buf_type i)
{
int rc = 0;
- struct vb2_queue *q;
+ struct buf_queue *q;
q = msm_comm_get_vb2q(inst, i);
if (!q) {
dprintk(VIDC_ERR,
@@ -1538,7 +1544,9 @@
return -EINVAL;
}
dprintk(VIDC_DBG, "Calling streamon\n");
- rc = vb2_streamon(q, i);
+ mutex_lock(&q->lock);
+ rc = vb2_streamon(&q->vb2_bufq, i);
+ mutex_unlock(&q->lock);
if (rc)
dprintk(VIDC_ERR, "streamon failed on port: %d\n", i);
return rc;
@@ -1547,7 +1555,7 @@
int msm_venc_streamoff(struct msm_vidc_inst *inst, enum v4l2_buf_type i)
{
int rc = 0;
- struct vb2_queue *q;
+ struct buf_queue *q;
q = msm_comm_get_vb2q(inst, i);
if (!q) {
dprintk(VIDC_ERR,
@@ -1555,7 +1563,9 @@
return -EINVAL;
}
dprintk(VIDC_DBG, "Calling streamoff on port: %d\n", i);
- rc = vb2_streamoff(q, i);
+ mutex_lock(&q->lock);
+ rc = vb2_streamoff(&q->vb2_bufq, i);
+ mutex_unlock(&q->lock);
if (rc)
dprintk(VIDC_ERR, "streamoff failed on port: %d\n", i);
return rc;
diff --git a/drivers/media/video/msm_vidc/msm_vidc.c b/drivers/media/video/msm_vidc/msm_vidc.c
index ec9dac8..8ff7714 100644
--- a/drivers/media/video/msm_vidc/msm_vidc.c
+++ b/drivers/media/video/msm_vidc/msm_vidc.c
@@ -27,8 +27,8 @@
static int get_poll_flags(void *instance)
{
struct msm_vidc_inst *inst = instance;
- struct vb2_queue *outq = &inst->vb2_bufq[OUTPUT_PORT];
- struct vb2_queue *capq = &inst->vb2_bufq[CAPTURE_PORT];
+ struct vb2_queue *outq = &inst->bufq[OUTPUT_PORT].vb2_bufq;
+ struct vb2_queue *capq = &inst->bufq[CAPTURE_PORT].vb2_bufq;
struct vb2_buffer *out_vb = NULL;
struct vb2_buffer *cap_vb = NULL;
unsigned long flags;
@@ -62,8 +62,8 @@
struct poll_table_struct *wait)
{
struct msm_vidc_inst *inst = instance;
- struct vb2_queue *outq = &inst->vb2_bufq[OUTPUT_PORT];
- struct vb2_queue *capq = &inst->vb2_bufq[CAPTURE_PORT];
+ struct vb2_queue *outq = &inst->bufq[OUTPUT_PORT].vb2_bufq;
+ struct vb2_queue *capq = &inst->bufq[CAPTURE_PORT].vb2_bufq;
poll_wait(filp, &inst->event_handler.wait, wait);
poll_wait(filp, &capq->done_wq, wait);
@@ -306,9 +306,9 @@
{
struct vb2_queue *q = NULL;
if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
- q = &inst->vb2_bufq[CAPTURE_PORT];
+ q = &inst->bufq[CAPTURE_PORT].vb2_bufq;
} else if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
- q = &inst->vb2_bufq[OUTPUT_PORT];
+ q = &inst->bufq[OUTPUT_PORT].vb2_bufq;
} else {
dprintk(VIDC_ERR, "buf_type = %d not recognised\n", type);
return -EINVAL;
@@ -404,6 +404,8 @@
}
mutex_init(&inst->sync_lock);
+ mutex_init(&inst->bufq[CAPTURE_PORT].lock);
+ mutex_init(&inst->bufq[OUTPUT_PORT].lock);
spin_lock_init(&inst->lock);
inst->session_type = session_type;
INIT_LIST_HEAD(&inst->pendingq);
@@ -489,8 +491,10 @@
buf = list_entry(ptr, struct internal_buf,
list);
list_del(&buf->list);
+ spin_unlock_irqrestore(&inst->lock, flags);
msm_smem_free(inst->mem_client, buf->handle);
kfree(buf);
+ spin_lock_irqsave(&inst->lock, flags);
}
}
if (!list_empty(&inst->persistbufs)) {
@@ -498,12 +502,17 @@
buf = list_entry(ptr, struct internal_buf,
list);
list_del(&buf->list);
+ spin_unlock_irqrestore(&inst->lock, flags);
msm_smem_free(inst->mem_client, buf->handle);
kfree(buf);
+ spin_lock_irqsave(&inst->lock, flags);
}
}
- if (inst->extradata_handle)
+ if (inst->extradata_handle) {
+ spin_unlock_irqrestore(&inst->lock, flags);
msm_smem_free(inst->mem_client, inst->extradata_handle);
+ spin_lock_irqsave(&inst->lock, flags);
+ }
spin_unlock_irqrestore(&inst->lock, flags);
msm_smem_delete_client(inst->mem_client);
debugfs_remove_recursive(inst->debugfs_root);
diff --git a/drivers/media/video/msm_vidc/msm_vidc_common.c b/drivers/media/video/msm_vidc/msm_vidc_common.c
index ede41d1..1cad40f 100644
--- a/drivers/media/video/msm_vidc/msm_vidc_common.c
+++ b/drivers/media/video/msm_vidc/msm_vidc_common.c
@@ -258,13 +258,13 @@
return &fmt[i];
}
-struct vb2_queue *msm_comm_get_vb2q(
+struct buf_queue *msm_comm_get_vb2q(
struct msm_vidc_inst *inst, enum v4l2_buf_type type)
{
if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
- return &inst->vb2_bufq[CAPTURE_PORT];
+ return &inst->bufq[CAPTURE_PORT];
if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
- return &inst->vb2_bufq[OUTPUT_PORT];
+ return &inst->bufq[OUTPUT_PORT];
return NULL;
}
@@ -527,21 +527,25 @@
}
}
-static struct vb2_buffer *get_vb_from_device_addr(struct vb2_queue *q,
+static struct vb2_buffer *get_vb_from_device_addr(struct buf_queue *bufq,
u32 dev_addr)
{
struct vb2_buffer *vb = NULL;
+ struct vb2_queue *q = NULL;
int found = 0;
- if (!q) {
+ if (!bufq) {
dprintk(VIDC_ERR, "Invalid parameter\n");
return NULL;
}
+ q = &bufq->vb2_bufq;
+ mutex_lock(&bufq->lock);
list_for_each_entry(vb, &q->queued_list, queued_entry) {
if (vb->v4l2_planes[0].m.userptr == dev_addr) {
found = 1;
break;
}
}
+ mutex_unlock(&bufq->lock);
if (!found) {
dprintk(VIDC_ERR,
"Failed to find the buffer in queued list: %d, %d\n",
@@ -563,7 +567,9 @@
vb = response->clnt_data;
inst = (struct msm_vidc_inst *)response->session_id;
if (vb) {
+ mutex_lock(&inst->bufq[OUTPUT_PORT].lock);
vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
+ mutex_unlock(&inst->bufq[OUTPUT_PORT].lock);
wake_up(&inst->kernel_event_queue);
}
}
@@ -580,7 +586,7 @@
}
inst = (struct msm_vidc_inst *)response->session_id;
fill_buf_done = (struct vidc_hal_fbd *)&response->output_done;
- vb = get_vb_from_device_addr(&inst->vb2_bufq[CAPTURE_PORT],
+ vb = get_vb_from_device_addr(&inst->bufq[CAPTURE_PORT],
(u32)fill_buf_done->packet_buffer1);
if (vb) {
vb->v4l2_planes[0].bytesused = fill_buf_done->filled_len1;
@@ -626,7 +632,9 @@
dprintk(VIDC_DBG, "Filled length = %d; flags %x\n",
vb->v4l2_planes[0].bytesused,
vb->v4l2_buf.flags);
+ mutex_lock(&inst->bufq[CAPTURE_PORT].lock);
vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
+ mutex_unlock(&inst->bufq[CAPTURE_PORT].lock);
wake_up(&inst->kernel_event_queue);
} else {
/*
@@ -643,18 +651,19 @@
*/
if (fill_buf_done->flags1 & HAL_BUFFERFLAG_EOS
&& fill_buf_done->filled_len1 == 0) {
- struct vb2_queue *q = &inst->vb2_bufq[CAPTURE_PORT];
+ struct buf_queue *q = &inst->bufq[CAPTURE_PORT];
- if (!list_empty(&q->queued_list)) {
- vb = list_first_entry(&q->queued_list,
+ if (!list_empty(&q->vb2_bufq.queued_list)) {
+ vb = list_first_entry(&q->vb2_bufq.queued_list,
struct vb2_buffer, queued_entry);
vb->v4l2_planes[0].bytesused = 0;
vb->v4l2_buf.flags |= V4L2_BUF_FLAG_EOS;
+ mutex_lock(&q->lock);
vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
+ mutex_unlock(&q->lock);
}
}
-
}
}
@@ -670,7 +679,7 @@
}
inst = (struct msm_vidc_inst *)response->session_id;
fill_buf_done = (struct vidc_hal_fbd *)&response->output_done;
- vb = get_vb_from_device_addr(&inst->vb2_bufq[CAPTURE_PORT],
+ vb = get_vb_from_device_addr(&inst->bufq[CAPTURE_PORT],
(u32)fill_buf_done->packet_buffer1);
if (vb)
vb->v4l2_planes[0].bytesused = fill_buf_done->filled_len1;
@@ -680,7 +689,9 @@
dprintk(VIDC_DBG, "Filled length = %d; flags %x\n",
vb->v4l2_planes[0].bytesused,
vb->v4l2_buf.flags);
+ mutex_lock(&inst->bufq[CAPTURE_PORT].lock);
vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
+ mutex_unlock(&inst->bufq[CAPTURE_PORT].lock);
}
void handle_cmd_response(enum command_response cmd, void *data)
@@ -1583,9 +1594,16 @@
buffer_info.align_device_addr = handle->device_addr;
rc = vidc_hal_session_release_buffers(
(void *) inst->session, &buffer_info);
+ if (rc)
+ dprintk(VIDC_WARN,
+ "Failed to release scratch buffer: 0x%x, %d",
+ buffer_info.align_device_addr,
+ buffer_info.buffer_size);
list_del(&buf->list);
+ spin_unlock_irqrestore(&inst->lock, flags);
msm_smem_free(inst->mem_client, buf->handle);
kfree(buf);
+ spin_lock_irqsave(&inst->lock, flags);
}
}
spin_unlock_irqrestore(&inst->lock, flags);
@@ -1614,11 +1632,14 @@
(void *) inst->session, &buffer_info);
if (rc)
dprintk(VIDC_WARN,
- "Failed in %s for buffer %ld\n",
- __func__, handle->device_addr);
+ "Failed to release persist buffer 0x%x, %d\n",
+ buffer_info.align_device_addr,
+ buffer_info.buffer_size);
list_del(&buf->list);
+ spin_unlock_irqrestore(&inst->lock, flags);
msm_smem_free(inst->mem_client, buf->handle);
kfree(buf);
+ spin_lock_irqsave(&inst->lock, flags);
}
}
spin_unlock_irqrestore(&inst->lock, flags);
@@ -1630,7 +1651,6 @@
int rc = 0;
struct msm_smem *handle;
struct internal_buf *binfo;
- struct list_head *ptr, *next;
struct vidc_buffer_addr_info buffer_info;
unsigned long flags;
struct hal_buffer_requirements *scratch_buf =
@@ -1640,28 +1660,9 @@
"scratch: num = %d, size = %d\n",
scratch_buf->buffer_count_actual,
scratch_buf->buffer_size);
- spin_lock_irqsave(&inst->lock, flags);
- if (!list_empty(&inst->internalbufs)) {
- list_for_each_safe(ptr, next, &inst->internalbufs) {
- binfo = list_entry(ptr, struct internal_buf,
- list);
- handle = binfo->handle;
- buffer_info.buffer_size = handle->size;
- buffer_info.buffer_type = HAL_BUFFER_INTERNAL_SCRATCH;
- buffer_info.num_buffers = 1;
- buffer_info.align_device_addr = handle->device_addr;
- rc = vidc_hal_session_release_buffers(
- (void *) inst->session, &buffer_info);
- if (rc)
- dprintk(VIDC_WARN,
- "Failed in release %s for buffer %ld\n",
- __func__, handle->device_addr);
- list_del(&binfo->list);
- msm_smem_free(inst->mem_client, binfo->handle);
- kfree(binfo);
- }
- }
- spin_unlock_irqrestore(&inst->lock, flags);
+ if (msm_comm_release_scratch_buffers(inst))
+ dprintk(VIDC_WARN, "Failed to release scratch buffers\n");
+
if (scratch_buf->buffer_size) {
for (i = 0; i < scratch_buf->buffer_count_actual;
i++) {
diff --git a/drivers/media/video/msm_vidc/msm_vidc_common.h b/drivers/media/video/msm_vidc/msm_vidc_common.h
index 1301e5c..0708724 100644
--- a/drivers/media/video/msm_vidc/msm_vidc_common.h
+++ b/drivers/media/video/msm_vidc/msm_vidc_common.h
@@ -23,7 +23,7 @@
const struct msm_vidc_format fmt[], int size, int index, int fmt_type);
const struct msm_vidc_format *msm_comm_get_pixel_fmt_fourcc(
const struct msm_vidc_format fmt[], int size, int fourcc, int fmt_type);
-struct vb2_queue *msm_comm_get_vb2q(
+struct buf_queue *msm_comm_get_vb2q(
struct msm_vidc_inst *inst, enum v4l2_buf_type type);
int msm_comm_try_state(struct msm_vidc_inst *inst, int state);
int msm_comm_try_get_bufreqs(struct msm_vidc_inst *inst);
diff --git a/drivers/media/video/msm_vidc/msm_vidc_internal.h b/drivers/media/video/msm_vidc/msm_vidc_internal.h
index 0f28c8d..1ea92fc 100644
--- a/drivers/media/video/msm_vidc/msm_vidc_internal.h
+++ b/drivers/media/video/msm_vidc/msm_vidc_internal.h
@@ -188,6 +188,11 @@
u32 bitrate;
};
+struct buf_queue {
+ struct vb2_queue vb2_bufq;
+ struct mutex lock;
+};
+
struct msm_vidc_core {
struct list_head list;
struct mutex sync_lock;
@@ -216,7 +221,7 @@
struct session_prop prop;
int state;
const struct msm_vidc_format *fmts[MAX_PORT_NUM];
- struct vb2_queue vb2_bufq[MAX_PORT_NUM];
+ struct buf_queue bufq[MAX_PORT_NUM];
spinlock_t lock;
struct list_head pendingq;
struct list_head internalbufs;
diff --git a/drivers/media/video/msm_wfd/enc-mfc-subdev.c b/drivers/media/video/msm_wfd/enc-mfc-subdev.c
index 5997345..3292d78 100644
--- a/drivers/media/video/msm_wfd/enc-mfc-subdev.c
+++ b/drivers/media/video/msm_wfd/enc-mfc-subdev.c
@@ -1352,6 +1352,48 @@
err_set_perf_level:
return rc;
}
+
+static long venc_set_avc_delimiter(struct video_client_ctx *client_ctx,
+ __s32 flag)
+{
+ struct vcd_property_hdr vcd_property_hdr;
+ struct vcd_property_avc_delimiter_enable delimiter_flag;
+ if (!client_ctx)
+ return -EINVAL;
+
+ vcd_property_hdr.prop_id = VCD_I_ENABLE_DELIMITER_FLAG;
+ vcd_property_hdr.sz =
+ sizeof(struct vcd_property_avc_delimiter_enable);
+ delimiter_flag.avc_delimiter_enable_flag = flag;
+ return vcd_set_property(client_ctx->vcd_handle,
+ &vcd_property_hdr, &delimiter_flag);
+}
+
+static long venc_get_avc_delimiter(struct video_client_ctx *client_ctx,
+ __s32 *flag)
+{
+ struct vcd_property_hdr vcd_property_hdr;
+ struct vcd_property_avc_delimiter_enable delimiter_flag;
+ int rc = 0;
+
+ if (!client_ctx || !flag)
+ return -EINVAL;
+
+ vcd_property_hdr.prop_id = VCD_I_ENABLE_DELIMITER_FLAG;
+ vcd_property_hdr.sz =
+ sizeof(struct vcd_property_avc_delimiter_enable);
+ rc = vcd_get_property(client_ctx->vcd_handle,
+ &vcd_property_hdr, &delimiter_flag);
+
+ if (rc < 0) {
+ WFD_MSG_ERR("Failed getting property for delimiter");
+ return rc;
+ }
+
+ *flag = delimiter_flag.avc_delimiter_enable_flag;
+ return rc;
+}
+
static long venc_set_header_mode(struct video_client_ctx *client_ctx,
__s32 mode)
{
@@ -1932,7 +1974,7 @@
struct vcd_property_enc_recon_buffer *ctrl = NULL;
unsigned long phy_addr;
int i = 0;
- int flags = 0;
+ int heap_mask = 0;
u32 len;
control.width = inst->width;
control.height = inst->height;
@@ -1945,8 +1987,8 @@
WFD_MSG_ERR("Failed to get recon buf size\n");
goto err;
}
- flags = ION_HEAP(ION_CP_MM_HEAP_ID);
- flags |= inst->secure ? ION_SECURE : ION_HEAP(ION_IOMMU_HEAP_ID);
+ heap_mask = ION_HEAP(ION_CP_MM_HEAP_ID);
+ heap_mask |= inst->secure ? ION_SECURE : ION_HEAP(ION_IOMMU_HEAP_ID);
if (vcd_get_ion_status()) {
for (i = 0; i < 4; ++i) {
@@ -1957,11 +1999,11 @@
ctrl->user_virtual_addr = (void *)i;
client_ctx->recon_buffer_ion_handle[i]
= ion_alloc(client_ctx->user_ion_client,
- control.size, SZ_8K, flags);
+ control.size, SZ_8K, heap_mask, 0);
ctrl->kernel_virtual_addr = ion_map_kernel(
client_ctx->user_ion_client,
- client_ctx->recon_buffer_ion_handle[i], 0);
+ client_ctx->recon_buffer_ion_handle[i]);
if (IS_ERR_OR_NULL(ctrl->kernel_virtual_addr)) {
WFD_MSG_ERR("ion map kernel failed\n");
@@ -2232,6 +2274,9 @@
case V4L2_CID_MPEG_QCOM_SET_PERF_LEVEL:
rc = venc_set_max_perf_level(client_ctx, ctrl->value);
break;
+ case V4L2_CID_MPEG_VIDC_VIDEO_H264_AU_DELIMITER:
+ rc = venc_set_avc_delimiter(client_ctx, ctrl->value);
+ break;
case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:
rc = venc_set_entropy_mode(client_ctx, ctrl->value);
break;
@@ -2303,6 +2348,9 @@
case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB:
rc = venc_get_cyclic_intra_refresh_mb(client_ctx, &ctrl->value);
break;
+ case V4L2_CID_MPEG_VIDC_VIDEO_H264_AU_DELIMITER:
+ rc = venc_get_avc_delimiter(client_ctx, &ctrl->value);
+ break;
default:
WFD_MSG_ERR("Get property not suported: %d\n", ctrl->id);
rc = -ENOTSUPP;
diff --git a/drivers/media/video/msm_wfd/enc-venus-subdev.c b/drivers/media/video/msm_wfd/enc-venus-subdev.c
index 04e42f5..89ad6c7 100644
--- a/drivers/media/video/msm_wfd/enc-venus-subdev.c
+++ b/drivers/media/video/msm_wfd/enc-venus-subdev.c
@@ -617,7 +617,7 @@
}
mregion->kvaddr = ion_map_kernel(venc_ion_client,
- mregion->ion_handle, flags);
+ mregion->ion_handle);
if (IS_ERR_OR_NULL(mregion->kvaddr)) {
WFD_MSG_ERR("Failed to map buffer into kernel\n");
diff --git a/drivers/media/video/msm_wfd/wfd-ioctl.c b/drivers/media/video/msm_wfd/wfd-ioctl.c
index d3c5936..04b787a 100644
--- a/drivers/media/video/msm_wfd/wfd-ioctl.c
+++ b/drivers/media/video/msm_wfd/wfd-ioctl.c
@@ -160,7 +160,7 @@
alloc_regions |= secure ? ION_SECURE :
ION_HEAP(ION_IOMMU_HEAP_ID);
handle = ion_alloc(client,
- mregion->size, SZ_4K, alloc_regions);
+ mregion->size, SZ_4K, alloc_regions, 0);
if (IS_ERR_OR_NULL(handle)) {
WFD_MSG_ERR("Failed to allocate input buffer\n");
@@ -168,7 +168,7 @@
goto alloc_fail;
}
- kvaddr = ion_map_kernel(client, handle, secure ? UNCACHED : CACHED);
+ kvaddr = ion_map_kernel(client, handle);
if (IS_ERR_OR_NULL(kvaddr)) {
WFD_MSG_ERR("Failed to get virtual addr\n");
diff --git a/drivers/media/video/vcap_v4l2.c b/drivers/media/video/vcap_v4l2.c
index e6cbae3..7ac78cb 100644
--- a/drivers/media/video/vcap_v4l2.c
+++ b/drivers/media/video/vcap_v4l2.c
@@ -1265,6 +1265,9 @@
}
rate = c_data->vc_format.clk_freq / 100 * 102;
+ if ((c_data->vc_format.hactive_end -
+ c_data->vc_format.hactive_start) > 539)
+ rate = 200000000;
rate_rc = clk_round_rate(dev->vcap_clk, rate);
if (rate_rc <= 0) {
pr_err("%s: Failed core rnd_rate\n", __func__);
diff --git a/drivers/media/video/vcap_vp.c b/drivers/media/video/vcap_vp.c
index 4c3ff16..aa39aad 100644
--- a/drivers/media/video/vcap_vp.c
+++ b/drivers/media/video/vcap_vp.c
@@ -464,7 +464,7 @@
}
handle = ion_alloc(dev->ion_client, size, SZ_4K,
- ION_HEAP(ION_CP_MM_HEAP_ID));
+ ION_HEAP(ION_CP_MM_HEAP_ID), 0);
if (IS_ERR_OR_NULL(handle)) {
pr_err("%s: ion_alloc failed\n", __func__);
return -ENOMEM;
@@ -483,7 +483,7 @@
return rc;
}
- vaddr = ion_map_kernel(dev->ion_client, handle, ionflag);
+ vaddr = ion_map_kernel(dev->ion_client, handle);
if (IS_ERR(vaddr)) {
pr_err("%s: Map motion buffer failed\n", __func__);
ion_free(dev->ion_client, handle);
@@ -535,7 +535,7 @@
tot_size = frame_size / 2 * 3;
handle = ion_alloc(dev->ion_client, tot_size, SZ_4K,
- ION_HEAP(ION_CP_MM_HEAP_ID));
+ ION_HEAP(ION_CP_MM_HEAP_ID), 0);
if (IS_ERR_OR_NULL(handle)) {
pr_err("%s: ion_alloc failed\n", __func__);
return -ENOMEM;
@@ -665,7 +665,7 @@
dprintk(2, "%s: Start VP dummy event\n", __func__);
handle = ion_alloc(dev->ion_client, 0x1200, SZ_4K,
- ION_HEAP(ION_CP_MM_HEAP_ID));
+ ION_HEAP(ION_CP_MM_HEAP_ID), 0);
if (IS_ERR_OR_NULL(handle)) {
pr_err("%s: ion_alloc failed\n", __func__);
return -ENOMEM;
diff --git a/drivers/media/video/videobuf2-core.c b/drivers/media/video/videobuf2-core.c
index a7d13a8..668cc73 100644
--- a/drivers/media/video/videobuf2-core.c
+++ b/drivers/media/video/videobuf2-core.c
@@ -1330,14 +1330,11 @@
return -EINVAL;
}
- mutex_lock(&q->q_lock);
ret = __vb2_get_done_vb(q, &vb, nonblocking);
if (ret < 0) {
dprintk(1, "dqbuf: error getting next done buffer\n");
- mutex_unlock(&q->q_lock);
return ret;
}
- mutex_unlock(&q->q_lock);
ret = call_qop(q, buf_finish, vb);
if (ret) {
dprintk(1, "dqbuf: buffer finish failed\n");
@@ -1449,17 +1446,14 @@
/*
* Let driver notice that streaming state has been enabled.
*/
- mutex_lock(&q->q_lock);
ret = call_qop(q, start_streaming, q, atomic_read(&q->queued_count));
if (ret) {
dprintk(1, "streamon: driver refused to start streaming\n");
__vb2_queue_cancel(q);
- mutex_unlock(&q->q_lock);
return ret;
}
q->streaming = 1;
- mutex_unlock(&q->q_lock);
dprintk(3, "Streamon successful\n");
return 0;
}
@@ -1733,7 +1727,6 @@
INIT_LIST_HEAD(&q->queued_list);
INIT_LIST_HEAD(&q->done_list);
spin_lock_init(&q->done_lock);
- mutex_init(&q->q_lock);
init_waitqueue_head(&q->done_wq);
if (q->buf_struct_size == 0)
diff --git a/drivers/media/video/videobuf2-msm-mem.c b/drivers/media/video/videobuf2-msm-mem.c
index c1a392e2..97bc7c3 100644
--- a/drivers/media/video/videobuf2-msm-mem.c
+++ b/drivers/media/video/videobuf2-msm-mem.c
@@ -56,7 +56,7 @@
goto client_failed;
}
mem->ion_handle = ion_alloc(mem->client, mem->size, SZ_4K,
- (0x1 << ION_CP_MM_HEAP_ID | 0x1 << ION_IOMMU_HEAP_ID));
+ (0x1 << ION_CP_MM_HEAP_ID | 0x1 << ION_IOMMU_HEAP_ID), 0);
if (IS_ERR((void *)mem->ion_handle)) {
pr_err("%s Could not allocate\n", __func__);
goto alloc_failed;
@@ -64,7 +64,7 @@
rc = ion_map_iommu(mem->client, mem->ion_handle,
-1, 0, SZ_4K, 0,
(unsigned long *)&phyaddr,
- (unsigned long *)&len, UNCACHED, 0);
+ (unsigned long *)&len, 0, 0);
if (rc < 0) {
pr_err("%s Could not get physical address\n", __func__);
goto phys_failed;
@@ -192,7 +192,7 @@
return PTR_ERR(mem->ion_handle);
}
rc = ion_map_iommu(client, mem->ion_handle, domain_num, 0,
- SZ_4K, 0, (unsigned long *)&mem->phyaddr, &len, UNCACHED, 0);
+ SZ_4K, 0, (unsigned long *)&mem->phyaddr, &len, 0, 0);
if (rc < 0)
ion_free(client, mem->ion_handle);
#elif CONFIG_ANDROID_PMEM
diff --git a/drivers/mfd/marimba-core.c b/drivers/mfd/marimba-core.c
index 70ec2ec..6a8ea6e 100644
--- a/drivers/mfd/marimba-core.c
+++ b/drivers/mfd/marimba-core.c
@@ -76,12 +76,16 @@
rc = marimba_read_bit_mask(marimba, 0x00, &bahama_version, 1, 0x1F);
if (rc < 0)
return rc;
+ pr_debug("%s: Bahama version: 0x%x\n", __func__, bahama_version);
switch (bahama_version) {
case 0x08: /* varient of bahama v1 */
case 0x10:
case 0x00:
return BAHAMA_VER_1_0;
case 0x09: /* variant of bahama v2 */
+ case 0x0a: /* variant of bahama v2.1 */
+ /* Falling through because initialization */
+ /* and configuration for 2.0 and 2.1 are same */
return BAHAMA_VER_2_0;
default:
return BAHAMA_VER_UNSUPPORTED;
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index d6d209b..4840e64 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -254,7 +254,6 @@
struct qseecom_register_listener_req *listener)
{
int ret = 0;
- unsigned int flags = 0;
struct qseecom_register_listener_ireq req;
struct qseecom_command_scm_resp resp;
ion_phys_addr_t pa;
@@ -271,8 +270,7 @@
ret = ion_phys(qseecom.ion_clnt, svc->ihandle, &pa, &svc->sb_length);
/* Populate the structure for sending scm call to load image */
- svc->sb_virt = (char *) ion_map_kernel(qseecom.ion_clnt,
- svc->ihandle, flags);
+ svc->sb_virt = (char *) ion_map_kernel(qseecom.ion_clnt, svc->ihandle);
svc->sb_phys = pa;
if (qseecom.qseos_version == QSEOS_VERSION_14) {
@@ -494,7 +492,6 @@
{
ion_phys_addr_t pa;
int32_t ret;
- unsigned int flags = 0;
struct qseecom_set_sb_mem_param_req req;
uint32_t len;
@@ -513,8 +510,7 @@
ret = ion_phys(qseecom.ion_clnt, data->client.ihandle, &pa, &len);
/* Populate the structure for sending scm call to load image */
data->client.sb_virt = (char *) ion_map_kernel(qseecom.ion_clnt,
- data->client.ihandle,
- flags);
+ data->client.ihandle);
data->client.sb_phys = pa;
data->client.sb_length = req.sb_len;
data->client.user_virt_sb_base = req.virt_sb_base;
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index c5e16d4..e2172c5 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -469,6 +469,16 @@
card->ext_csd.bkops_en = ext_csd[EXT_CSD_BKOPS_EN];
card->ext_csd.raw_bkops_status =
ext_csd[EXT_CSD_BKOPS_STATUS];
+ if (!card->ext_csd.bkops_en &&
+ card->host->caps2 & MMC_CAP2_INIT_BKOPS) {
+ err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+ EXT_CSD_BKOPS_EN, 1, 0);
+ if (err)
+ pr_warn("%s: Enabling BKOPS failed\n",
+ mmc_hostname(card->host));
+ else
+ card->ext_csd.bkops_en = 1;
+ }
if (!card->ext_csd.bkops_en)
pr_info("%s: BKOPS_EN bit is not set\n",
mmc_hostname(card->host));
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 2391360..2c98816 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -79,7 +79,6 @@
#if defined(CONFIG_DEBUG_FS)
static void msmsdcc_dbg_createhost(struct msmsdcc_host *);
static struct dentry *debugfs_dir;
-static struct dentry *debugfs_file;
static int msmsdcc_dbg_init(void);
#endif
@@ -874,6 +873,10 @@
bool ret = true;
u32 xfer_size = data->blksz * data->blocks;
+ if (host->enforce_pio_mode) {
+ ret = false;
+ goto out;
+ }
if (is_sps_mode(host)) {
/*
* BAM Mode: Fall back on PIO if size is less
@@ -892,7 +895,7 @@
/* PIO Mode */
ret = false;
}
-
+ out:
return ret;
}
@@ -3463,7 +3466,6 @@
{
struct device *dev = mmc->parent;
struct msmsdcc_host *host = mmc_priv(mmc);
- unsigned long flags;
int rc = 0;
msmsdcc_pm_qos_update_latency(host, 1);
@@ -3497,7 +3499,6 @@
static int msmsdcc_disable(struct mmc_host *mmc)
{
struct msmsdcc_host *host = mmc_priv(mmc);
- unsigned long flags;
int rc = 0;
msmsdcc_pm_qos_update_latency(host, 0);
@@ -4806,7 +4807,7 @@
struct msmsdcc_host *host = mmc_priv(mmc);
return snprintf(buf, PAGE_SIZE, "%u (Min 5 sec)\n",
- host->idle_tout_ms / 1000);
+ host->idle_tout / 1000);
}
static ssize_t
@@ -4821,7 +4822,7 @@
if (!kstrtou32(buf, 0, &timeout)
&& (timeout > MSM_MMC_DEFAULT_IDLE_TIMEOUT / 1000)) {
spin_lock_irqsave(&host->lock, flags);
- host->idle_tout_ms = timeout * 1000;
+ host->idle_tout = timeout * 1000;
spin_unlock_irqrestore(&host->lock, flags);
}
return count;
@@ -5804,6 +5805,7 @@
mmc->caps2 |= (MMC_CAP2_BOOTPART_NOACC | MMC_CAP2_DETECT_ON_ERR);
mmc->caps2 |= MMC_CAP2_SANITIZE;
mmc->caps2 |= MMC_CAP2_CACHE_CTRL;
+ mmc->caps2 |= MMC_CAP2_INIT_BKOPS;
if (plat->nonremovable)
mmc->caps |= MMC_CAP_NONREMOVABLE;
@@ -5945,7 +5947,7 @@
pm_runtime_enable(&(pdev)->dev);
}
#endif
- host->idle_tout_ms = MSM_MMC_DEFAULT_IDLE_TIMEOUT;
+ host->idle_tout = MSM_MMC_DEFAULT_IDLE_TIMEOUT;
setup_timer(&host->req_tout_timer, msmsdcc_req_tout_timer_hdlr,
(unsigned long)host);
@@ -6124,6 +6126,16 @@
return ret;
}
+#ifdef CONFIG_DEBUG_FS
+static void msmsdcc_remove_debugfs(struct msmsdcc_host *host)
+{
+ debugfs_remove_recursive(host->debugfs_host_dir);
+ host->debugfs_host_dir = NULL;
+}
+#else
+static void msmsdcc_remove_debugfs(msmsdcc_host *host) {}
+#endif
+
static int msmsdcc_remove(struct platform_device *pdev)
{
struct mmc_host *mmc = mmc_get_drvdata(pdev);
@@ -6150,6 +6162,8 @@
device_remove_file(&pdev->dev, &host->polling);
device_remove_file(&pdev->dev, &host->idle_timeout);
+ msmsdcc_remove_debugfs(host);
+
del_timer_sync(&host->req_tout_timer);
tasklet_kill(&host->dma_tlet);
tasklet_kill(&host->sps.tlet);
@@ -6326,6 +6340,23 @@
}
#endif
+#if CONFIG_DEBUG_FS
+static void msmsdcc_print_pm_stats(struct msmsdcc_host *host, ktime_t start,
+ const char *func)
+{
+ ktime_t diff;
+
+ if (host->print_pm_stats) {
+ diff = ktime_sub(ktime_get(), start);
+ pr_info("%s: %s: Completed in %llu usec\n", func,
+ mmc_hostname(host->mmc), (u64)ktime_to_us(diff));
+ }
+}
+#else
+static void msmsdcc_print_pm_stats(struct msmsdcc_host *host, ktime_t start,
+ const char *func) {}
+#endif
+
static int
msmsdcc_runtime_suspend(struct device *dev)
{
@@ -6333,6 +6364,7 @@
struct msmsdcc_host *host = mmc_priv(mmc);
int rc = 0;
unsigned long flags;
+ ktime_t start = ktime_get();
if (host->plat->is_sdio_al_client) {
rc = 0;
@@ -6389,6 +6421,7 @@
out:
/* set bus bandwidth to 0 immediately */
msmsdcc_msm_bus_cancel_work_and_set_vote(host, NULL);
+ msmsdcc_print_pm_stats(host, start, __func__);
return rc;
}
@@ -6398,9 +6431,10 @@
struct mmc_host *mmc = dev_get_drvdata(dev);
struct msmsdcc_host *host = mmc_priv(mmc);
unsigned long flags;
+ ktime_t start = ktime_get();
if (host->plat->is_sdio_al_client)
- return 0;
+ goto out;
pr_debug("%s: %s: start\n", mmc_hostname(mmc), __func__);
if (mmc) {
@@ -6435,6 +6469,8 @@
}
host->pending_resume = false;
pr_debug("%s: %s: end\n", mmc_hostname(mmc), __func__);
+out:
+ msmsdcc_print_pm_stats(host, start, __func__);
return 0;
}
@@ -6447,7 +6483,7 @@
return 0;
/* Idle timeout is not configurable for now */
- pm_schedule_suspend(dev, host->idle_tout_ms);
+ pm_schedule_suspend(dev, host->idle_tout);
return -EAGAIN;
}
@@ -6457,17 +6493,19 @@
struct mmc_host *mmc = dev_get_drvdata(dev);
struct msmsdcc_host *host = mmc_priv(mmc);
int rc = 0;
+ ktime_t start = ktime_get();
- if (host->plat->is_sdio_al_client)
- return 0;
-
-
+ if (host->plat->is_sdio_al_client) {
+ rc = 0;
+ goto out;
+ }
if (host->plat->status_irq)
disable_irq(host->plat->status_irq);
if (!pm_runtime_suspended(dev))
rc = msmsdcc_runtime_suspend(dev);
-
+ out:
+ msmsdcc_print_pm_stats(host, start, __func__);
return rc;
}
@@ -6500,10 +6538,12 @@
struct mmc_host *mmc = dev_get_drvdata(dev);
struct msmsdcc_host *host = mmc_priv(mmc);
int rc = 0;
+ ktime_t start = ktime_get();
- if (host->plat->is_sdio_al_client)
- return 0;
-
+ if (host->plat->is_sdio_al_client) {
+ rc = 0;
+ goto out;
+ }
if (mmc->card && mmc_card_sdio(mmc->card))
rc = msmsdcc_runtime_resume(dev);
/*
@@ -6519,7 +6559,8 @@
msmsdcc_check_status((unsigned long)host);
enable_irq(host->plat->status_irq);
}
-
+out:
+ msmsdcc_print_pm_stats(host, start, __func__);
return rc;
}
@@ -6593,7 +6634,6 @@
platform_driver_unregister(&msmsdcc_driver);
#if defined(CONFIG_DEBUG_FS)
- debugfs_remove(debugfs_file);
debugfs_remove(debugfs_dir);
#endif
}
@@ -6605,59 +6645,128 @@
MODULE_LICENSE("GPL");
#if defined(CONFIG_DEBUG_FS)
-
-static int
-msmsdcc_dbg_state_open(struct inode *inode, struct file *file)
+static int msmsdcc_dbg_idle_tout_get(void *data, u64 *val)
{
- file->private_data = inode->i_private;
+ struct msmsdcc_host *host = data;
+
+ *val = host->idle_tout / 1000L;
return 0;
}
-static ssize_t
-msmsdcc_dbg_state_read(struct file *file, char __user *ubuf,
- size_t count, loff_t *ppos)
+static int msmsdcc_dbg_idle_tout_set(void *data, u64 val)
{
- struct msmsdcc_host *host = (struct msmsdcc_host *) file->private_data;
- char buf[200];
- int max, i;
+ struct msmsdcc_host *host = data;
+ unsigned long flags;
- i = 0;
- max = sizeof(buf) - 1;
+ spin_lock_irqsave(&host->lock, flags);
+ host->idle_tout = (u32)val * 1000;
+ spin_unlock_irqrestore(&host->lock, flags);
- i += scnprintf(buf + i, max - i, "STAT: %p %p %p\n", host->curr.mrq,
- host->curr.cmd, host->curr.data);
- if (host->curr.cmd) {
- struct mmc_command *cmd = host->curr.cmd;
-
- i += scnprintf(buf + i, max - i, "CMD : %.8x %.8x %.8x\n",
- cmd->opcode, cmd->arg, cmd->flags);
- }
- if (host->curr.data) {
- struct mmc_data *data = host->curr.data;
- i += scnprintf(buf + i, max - i,
- "DAT0: %.8x %.8x %.8x %.8x %.8x %.8x\n",
- data->timeout_ns, data->timeout_clks,
- data->blksz, data->blocks, data->error,
- data->flags);
- i += scnprintf(buf + i, max - i, "DAT1: %.8x %.8x %.8x %p\n",
- host->curr.xfer_size, host->curr.xfer_remain,
- host->curr.data_xfered, host->dma.sg);
- }
-
- return simple_read_from_buffer(ubuf, count, ppos, buf, i);
+ return 0;
}
-static const struct file_operations msmsdcc_dbg_state_ops = {
- .read = msmsdcc_dbg_state_read,
- .open = msmsdcc_dbg_state_open,
-};
+DEFINE_SIMPLE_ATTRIBUTE(msmsdcc_dbg_idle_tout_ops,
+ msmsdcc_dbg_idle_tout_get,
+ msmsdcc_dbg_idle_tout_set,
+ "%llu\n");
+
+static int msmsdcc_dbg_pio_mode_get(void *data, u64 *val)
+{
+ struct msmsdcc_host *host = data;
+
+ *val = (u64) host->enforce_pio_mode;
+ return 0;
+}
+
+static int msmsdcc_dbg_pio_mode_set(void *data, u64 val)
+{
+ struct msmsdcc_host *host = data;
+ unsigned long flags;
+
+ spin_lock_irqsave(&host->lock, flags);
+ host->enforce_pio_mode = !!val;
+ spin_unlock_irqrestore(&host->lock, flags);
+
+ return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(msmsdcc_dbg_pio_mode_ops,
+ msmsdcc_dbg_pio_mode_get,
+ msmsdcc_dbg_pio_mode_set,
+ "%llu\n");
+
+static int msmsdcc_dbg_pm_stats_get(void *data, u64 *val)
+{
+ struct msmsdcc_host *host = data;
+
+ *val = !!host->print_pm_stats;
+ return 0;
+}
+
+static int msmsdcc_dbg_pm_stats_set(void *data, u64 val)
+{
+ struct msmsdcc_host *host = data;
+ unsigned long flags;
+
+ spin_lock_irqsave(&host->lock, flags);
+ host->print_pm_stats = !!val;
+ spin_unlock_irqrestore(&host->lock, flags);
+
+ return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(msmsdcc_dbg_pm_stats_ops,
+ msmsdcc_dbg_pm_stats_get,
+ msmsdcc_dbg_pm_stats_set,
+ "%llu\n");
static void msmsdcc_dbg_createhost(struct msmsdcc_host *host)
{
- if (debugfs_dir) {
- debugfs_file = debugfs_create_file(mmc_hostname(host->mmc),
- 0644, debugfs_dir, host,
- &msmsdcc_dbg_state_ops);
+ int err = 0;
+
+ if (!debugfs_dir)
+ return;
+
+ host->debugfs_host_dir = debugfs_create_dir(
+ mmc_hostname(host->mmc), debugfs_dir);
+ if (IS_ERR(host->debugfs_host_dir)) {
+ err = PTR_ERR(host->debugfs_host_dir);
+ host->debugfs_host_dir = NULL;
+ pr_err("%s: Failed to create debugfs dir for host with err=%d\n",
+ mmc_hostname(host->mmc), err);
+ return;
+ }
+
+ host->debugfs_idle_tout = debugfs_create_file("idle_tout",
+ S_IRUSR | S_IWUSR, host->debugfs_host_dir, host,
+ &msmsdcc_dbg_idle_tout_ops);
+
+ if (IS_ERR(host->debugfs_idle_tout)) {
+ err = PTR_ERR(host->debugfs_idle_tout);
+ host->debugfs_idle_tout = NULL;
+ pr_err("%s: Failed to create idle_tout debugfs entry with err=%d\n",
+ mmc_hostname(host->mmc), err);
+ }
+
+ host->debugfs_pio_mode = debugfs_create_file("pio_mode",
+ S_IRUSR | S_IWUSR, host->debugfs_host_dir, host,
+ &msmsdcc_dbg_pio_mode_ops);
+
+ if (IS_ERR(host->debugfs_pio_mode)) {
+ err = PTR_ERR(host->debugfs_pio_mode);
+ host->debugfs_pio_mode = NULL;
+ pr_err("%s: Failed to create pio_mode debugfs entry with err=%d\n",
+ mmc_hostname(host->mmc), err);
+ }
+
+ host->debugfs_pm_stats = debugfs_create_file("pm_stats",
+ S_IRUSR | S_IWUSR, host->debugfs_host_dir, host,
+ &msmsdcc_dbg_pm_stats_ops);
+ if (IS_ERR(host->debugfs_pm_stats)) {
+ err = PTR_ERR(host->debugfs_pm_stats);
+ host->debugfs_pm_stats = NULL;
+ pr_err("%s: Failed to create pm_stats debugfs entry with err=%d\n",
+ mmc_hostname(host->mmc), err);
}
}
@@ -6665,7 +6774,7 @@
{
int err;
- debugfs_dir = debugfs_create_dir("msmsdcc", 0);
+ debugfs_dir = debugfs_create_dir("msm_sdcc", 0);
if (IS_ERR(debugfs_dir)) {
err = PTR_ERR(debugfs_dir);
debugfs_dir = NULL;
diff --git a/drivers/mmc/host/msm_sdcc.h b/drivers/mmc/host/msm_sdcc.h
index 5779491..c66d1a5 100644
--- a/drivers/mmc/host/msm_sdcc.h
+++ b/drivers/mmc/host/msm_sdcc.h
@@ -414,14 +414,20 @@
bool sdio_wakeupirq_disabled;
struct mutex clk_mutex;
bool pending_resume;
- unsigned int idle_tout_ms; /* Timeout in msecs */
+ unsigned int idle_tout; /* Timeout in msecs */
bool pending_dpsm_reset;
+ bool enforce_pio_mode;
+ bool print_pm_stats;
struct msmsdcc_msm_bus_vote msm_bus_vote;
struct device_attribute max_bus_bw;
struct device_attribute polling;
struct device_attribute idle_timeout;
struct device_attribute auto_cmd19_attr;
struct device_attribute auto_cmd21_attr;
+ struct dentry *debugfs_host_dir;
+ struct dentry *debugfs_idle_tout;
+ struct dentry *debugfs_pio_mode;
+ struct dentry *debugfs_pm_stats;
};
#define MSMSDCC_VERSION_STEP_MASK 0x0000FFFF
@@ -483,7 +489,7 @@
if ((step == 0x18) && (minor >= 3))
host->hw_caps |= MSMSDCC_AUTO_CMD21;
- if (version >= 0x2b) /* SDCC v4 2.1.0 and greater */
+ if (step >= 0x2b) /* SDCC v4 2.1.0 and greater */
host->hw_caps |= MSMSDCC_SW_RST | MSMSDCC_AUTO_CMD21;
}
diff --git a/drivers/net/ethernet/msm/msm_rmnet_smux.c b/drivers/net/ethernet/msm/msm_rmnet_smux.c
index fbb3489..5f29406 100644
--- a/drivers/net/ethernet/msm/msm_rmnet_smux.c
+++ b/drivers/net/ethernet/msm/msm_rmnet_smux.c
@@ -79,6 +79,7 @@
unsigned long timeout_us;
#endif
spinlock_t lock;
+ spinlock_t tx_queue_lock;
struct tasklet_struct tsklt;
/* IOCTL specified mode (protocol, QoS header) */
u32 operation_mode;
@@ -346,12 +347,15 @@
((struct net_device *)(dev))->name, p->stats.tx_packets,
skb->len, skb->mark);
dev_kfree_skb_any(skb);
+
+ spin_lock_irqsave(&p->tx_queue_lock, flags);
if (netif_queue_stopped(dev) &&
msm_smux_is_ch_low(p->ch_id)) {
DBG0("%s: Low WM hit, waking queue=%p\n",
__func__, skb);
netif_wake_queue(dev);
}
+ spin_unlock_irqrestore(&p->tx_queue_lock, flags);
}
void rmnet_smux_notify(void *priv, int event_type, const void *metadata)
@@ -475,14 +479,20 @@
case SMUX_LOW_WM_HIT:
dev = priv;
+ p = netdev_priv(priv);
DBG0("[%s] Low WM hit dev:%s\n", __func__, dev->name);
+ spin_lock_irqsave(&p->tx_queue_lock, flags);
netif_start_queue(dev);
+ spin_unlock_irqrestore(&p->tx_queue_lock, flags);
break;
case SMUX_HIGH_WM_HIT:
dev = priv;
- DBG0("[%s] Low WM hit dev:%s\n", __func__, dev->name);
+ p = netdev_priv(priv);
+ DBG0("[%s] High WM hit dev:%s\n", __func__, dev->name);
+ spin_lock_irqsave(&p->tx_queue_lock, flags);
netif_stop_queue(dev);
+ spin_unlock_irqrestore(&p->tx_queue_lock, flags);
break;
default:
@@ -573,7 +583,6 @@
static int _rmnet_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct rmnet_private *p = netdev_priv(dev);
- int smux_ret;
struct QMI_QOS_HDR_S *qmih;
u32 opmode;
unsigned long flags;
@@ -593,21 +602,13 @@
dev->trans_start = jiffies;
- /* if write() succeeds, skb access is unsafe in this process */
- smux_ret = msm_smux_write(p->ch_id, skb, skb->data, skb->len);
-
- if (smux_ret != 0 && smux_ret != -EAGAIN) {
- pr_err("[%s] %s: write returned error %d",
- dev->name, __func__, smux_ret);
- return -EPERM;
- }
-
- return smux_ret;
+ return msm_smux_write(p->ch_id, skb, skb->data, skb->len);
}
static int rmnet_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct rmnet_private *p = netdev_priv(dev);
+ unsigned long flags;
int ret = 0;
if (netif_queue_stopped(dev) || (p->device_state == DEVICE_INACTIVE)) {
@@ -616,17 +617,10 @@
return 0;
}
+ spin_lock_irqsave(&p->tx_queue_lock, flags);
ret = _rmnet_xmit(skb, dev);
- if (ret == -EPERM) {
- /* Do not stop the queue here.
- * It will lead to ir-recoverable state.
- */
- ret = NETDEV_TX_BUSY;
- goto exit;
- }
-
- if (msm_smux_is_ch_full(p->ch_id) || (ret == -EAGAIN)) {
+ if (ret == -EAGAIN) {
/*
* EAGAIN means we attempted to overflow the high watermark
* Clearly the queue is not stopped like it should be, so
@@ -636,9 +630,9 @@
*/
netif_stop_queue(dev);
ret = NETDEV_TX_BUSY;
- goto exit;
}
-exit:
+ spin_unlock_irqrestore(&p->tx_queue_lock, flags);
+
return ret;
}
@@ -892,6 +886,7 @@
p->ch_id = n;
p->in_reset = 0;
spin_lock_init(&p->lock);
+ spin_lock_init(&p->tx_queue_lock);
#ifdef CONFIG_MSM_RMNET_DEBUG
p->timeout_us = timeout_us;
p->wakeups_xmit = p->wakeups_rcv = 0;
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 1867fe2..6de0a77 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -1529,6 +1529,7 @@
spin_lock_irq(&dev->txq.lock);
/* don't autosuspend while transmitting */
if (dev->txq.qlen && PMSG_IS_AUTO(message)) {
+ dev->suspend_count--;
spin_unlock_irq(&dev->txq.lock);
return -EBUSY;
} else {
diff --git a/drivers/net/wireless/wcnss/wcnss_wlan.c b/drivers/net/wireless/wcnss/wcnss_wlan.c
index ac0a2fd..2bf857c 100644
--- a/drivers/net/wireless/wcnss/wcnss_wlan.c
+++ b/drivers/net/wireless/wcnss/wcnss_wlan.c
@@ -27,6 +27,7 @@
#include <linux/of_gpio.h>
#include <mach/peripheral-loader.h>
#include <mach/msm_smd.h>
+#include <mach/msm_iomap.h>
#ifdef CONFIG_WCNSS_MEM_PRE_ALLOC
#include "wcnss_prealloc.h"
#endif
@@ -159,6 +160,18 @@
static DEVICE_ATTR(wcnss_version, S_IRUSR,
wcnss_version_show, NULL);
+/* interface to reset Riva by sending the reset interrupt */
+void wcnss_reset_intr(void)
+{
+ if (wcnss_hardware_type() == WCNSS_RIVA_HW) {
+ wmb();
+ __raw_writel(1 << 24, MSM_APCS_GCC_BASE + 0x8);
+ } else {
+ pr_err("%s: reset interrupt not supported\n", __func__);
+ }
+}
+EXPORT_SYMBOL(wcnss_reset_intr);
+
static int wcnss_create_sysfs(struct device *dev)
{
int ret;
diff --git a/drivers/platform/msm/usb_bam.c b/drivers/platform/msm/usb_bam.c
index 551c0a7..bf78b1c 100644
--- a/drivers/platform/msm/usb_bam.c
+++ b/drivers/platform/msm/usb_bam.c
@@ -258,6 +258,11 @@
struct usb_bam_connect_info *connection = &usb_bam_connections[idx];
int ret;
+ if (!usb_bam_pdev) {
+ pr_err("%s: usb_bam device not found\n", __func__);
+ return -ENODEV;
+ }
+
if (idx >= CONNECTIONS_NUM) {
pr_err("%s: Invalid connection index\n",
__func__);
@@ -715,12 +720,9 @@
usb_bam_show_enable(struct device *dev, struct device_attribute *attr,
char *buf)
{
- struct platform_device *pdev =
- container_of(dev, struct platform_device, dev);
- struct msm_usb_bam_platform_data *pdata =
- usb_bam_pdev->dev.platform_data;
+ struct msm_usb_bam_platform_data *pdata = dev->platform_data;
- if (!pdev || !pdata)
+ if (!pdata)
return 0;
return scnprintf(buf, PAGE_SIZE, "%s\n",
bam_enable_strings[pdata->usb_active_bam]);
@@ -730,13 +732,15 @@
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct platform_device *pdev = container_of(dev,
- struct platform_device, dev);
- struct msm_usb_bam_platform_data *pdata =
- usb_bam_pdev->dev.platform_data;
+ struct msm_usb_bam_platform_data *pdata = dev->platform_data;
char str[10], *pstr;
int ret, i;
+ if (!pdata) {
+ dev_err(dev, "no usb_bam pdata found\n");
+ return -ENODEV;
+ }
+
strlcpy(str, buf, sizeof(str));
pstr = strim(str);
@@ -745,12 +749,12 @@
pdata->usb_active_bam = i;
}
- dev_dbg(&pdev->dev, "active_bam=%s\n",
+ dev_dbg(dev, "active_bam=%s\n",
bam_enable_strings[pdata->usb_active_bam]);
ret = usb_bam_init();
if (ret) {
- dev_err(&pdev->dev, "failed to initialize usb bam\n");
+ dev_err(dev, "failed to initialize usb bam\n");
return ret;
}
diff --git a/drivers/power/pm8921-bms.c b/drivers/power/pm8921-bms.c
index c63c99f..b107040 100644
--- a/drivers/power/pm8921-bms.c
+++ b/drivers/power/pm8921-bms.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -10,8 +10,8 @@
* GNU General Public License for more details.
*
*/
-#define pr_fmt(fmt) "%s: " fmt, __func__
+#define pr_fmt(fmt) "%s: " fmt, __func__
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/platform_device.h>
@@ -22,6 +22,7 @@
#include <linux/mfd/pm8xxx/pm8xxx-adc.h>
#include <linux/mfd/pm8xxx/pm8921-charger.h>
#include <linux/mfd/pm8xxx/ccadc.h>
+#include <linux/mfd/pm8xxx/batterydata-lib.h>
#include <linux/interrupt.h>
#include <linux/bitops.h>
#include <linux/debugfs.h>
@@ -224,7 +225,6 @@
module_param_cb(bms_end_ocv_uv, &bms_ro_param_ops, &bms_end_ocv_uv, 0644);
module_param_cb(bms_end_cc_uah, &bms_ro_param_ops, &bms_end_cc_uah, 0644);
-static int interpolate_fcc(struct pm8921_bms_chip *chip, int batt_temp);
static void readjust_fcc_table(void)
{
struct single_row_lut *temp, *old;
@@ -241,7 +241,7 @@
return;
}
- fcc = interpolate_fcc(the_chip, last_real_fcc_batt_temp);
+ fcc = interpolate_fcc(the_chip->fcc_temp_lut, last_real_fcc_batt_temp);
temp->cols = the_chip->fcc_temp_lut->cols;
for (i = 0; i < the_chip->fcc_temp_lut->cols; i++) {
@@ -583,342 +583,6 @@
return 0;
}
-static int linear_interpolate(int y0, int x0, int y1, int x1, int x)
-{
- if (y0 == y1 || x == x0)
- return y0;
- if (x1 == x0 || x == x1)
- return y1;
-
- return y0 + ((y1 - y0) * (x - x0) / (x1 - x0));
-}
-
-static int interpolate_single_lut(struct single_row_lut *lut, int x)
-{
- int i, result;
-
- if (x < lut->x[0]) {
- pr_debug("x %d less than known range return y = %d lut = %pS\n",
- x, lut->y[0], lut);
- return lut->y[0];
- }
- if (x > lut->x[lut->cols - 1]) {
- pr_debug("x %d more than known range return y = %d lut = %pS\n",
- x, lut->y[lut->cols - 1], lut);
- return lut->y[lut->cols - 1];
- }
-
- for (i = 0; i < lut->cols; i++)
- if (x <= lut->x[i])
- break;
- if (x == lut->x[i]) {
- result = lut->y[i];
- } else {
- result = linear_interpolate(
- lut->y[i - 1],
- lut->x[i - 1],
- lut->y[i],
- lut->x[i],
- x);
- }
- return result;
-}
-
-static int interpolate_fcc(struct pm8921_bms_chip *chip, int batt_temp)
-{
- /* batt_temp is in tenths of degC - convert it to degC for lookups */
- batt_temp = batt_temp/10;
- return interpolate_single_lut(chip->fcc_temp_lut, batt_temp);
-}
-
-static int interpolate_fcc_adjusted(struct pm8921_bms_chip *chip, int batt_temp)
-{
- /* batt_temp is in tenths of degC - convert it to degC for lookups */
- batt_temp = batt_temp/10;
- return interpolate_single_lut(chip->adjusted_fcc_temp_lut, batt_temp);
-}
-
-static int interpolate_scalingfactor_fcc(struct pm8921_bms_chip *chip,
- int cycles)
-{
- /*
- * sf table could be null when no battery aging data is available, in
- * that case return 100%
- */
- if (chip->fcc_sf_lut)
- return interpolate_single_lut(chip->fcc_sf_lut, cycles);
- else
- return 100;
-}
-
-static int interpolate_scalingfactor(struct pm8921_bms_chip *chip,
- struct sf_lut *sf_lut,
- int row_entry, int pc)
-{
- int i, scalefactorrow1, scalefactorrow2, scalefactor;
- int rows, cols;
- int row1 = 0;
- int row2 = 0;
-
- /*
- * sf table could be null when no battery aging data is available, in
- * that case return 100%
- */
- if (!sf_lut)
- return 100;
-
- rows = sf_lut->rows;
- cols = sf_lut->cols;
- if (pc > sf_lut->percent[0]) {
- pr_debug("pc %d greater than known pc ranges for sfd\n", pc);
- row1 = 0;
- row2 = 0;
- }
- if (pc < sf_lut->percent[rows - 1]) {
- pr_debug("pc %d less than known pc ranges for sf", pc);
- row1 = rows - 1;
- row2 = rows - 1;
- }
- for (i = 0; i < rows; i++) {
- if (pc == sf_lut->percent[i]) {
- row1 = i;
- row2 = i;
- break;
- }
- if (pc > sf_lut->percent[i]) {
- row1 = i - 1;
- row2 = i;
- break;
- }
- }
-
- if (row_entry < sf_lut->row_entries[0])
- row_entry = sf_lut->row_entries[0];
- if (row_entry > sf_lut->row_entries[cols - 1])
- row_entry = sf_lut->row_entries[cols - 1];
-
- for (i = 0; i < cols; i++)
- if (row_entry <= sf_lut->row_entries[i])
- break;
- if (row_entry == sf_lut->row_entries[i]) {
- scalefactor = linear_interpolate(
- sf_lut->sf[row1][i],
- sf_lut->percent[row1],
- sf_lut->sf[row2][i],
- sf_lut->percent[row2],
- pc);
- return scalefactor;
- }
-
- scalefactorrow1 = linear_interpolate(
- sf_lut->sf[row1][i - 1],
- sf_lut->row_entries[i - 1],
- sf_lut->sf[row1][i],
- sf_lut->row_entries[i],
- row_entry);
-
- scalefactorrow2 = linear_interpolate(
- sf_lut->sf[row2][i - 1],
- sf_lut->row_entries[i - 1],
- sf_lut->sf[row2][i],
- sf_lut->row_entries[i],
- row_entry);
-
- scalefactor = linear_interpolate(
- scalefactorrow1,
- sf_lut->percent[row1],
- scalefactorrow2,
- sf_lut->percent[row2],
- pc);
-
- return scalefactor;
-}
-
-static int is_between(int left, int right, int value)
-{
- if (left >= right && left >= value && value >= right)
- return 1;
- if (left <= right && left <= value && value <= right)
- return 1;
-
- return 0;
-}
-
-/* get ocv given a soc -- reverse lookup */
-static int interpolate_ocv(struct pm8921_bms_chip *chip,
- int batt_temp_degc, int pc)
-{
- int i, ocvrow1, ocvrow2, ocv;
- int rows, cols;
- int row1 = 0;
- int row2 = 0;
-
- rows = chip->pc_temp_ocv_lut->rows;
- cols = chip->pc_temp_ocv_lut->cols;
- if (pc > chip->pc_temp_ocv_lut->percent[0]) {
- pr_debug("pc %d greater than known pc ranges for sfd\n", pc);
- row1 = 0;
- row2 = 0;
- }
- if (pc < chip->pc_temp_ocv_lut->percent[rows - 1]) {
- pr_debug("pc %d less than known pc ranges for sf\n", pc);
- row1 = rows - 1;
- row2 = rows - 1;
- }
- for (i = 0; i < rows; i++) {
- if (pc == chip->pc_temp_ocv_lut->percent[i]) {
- row1 = i;
- row2 = i;
- break;
- }
- if (pc > chip->pc_temp_ocv_lut->percent[i]) {
- row1 = i - 1;
- row2 = i;
- break;
- }
- }
-
- if (batt_temp_degc < chip->pc_temp_ocv_lut->temp[0])
- batt_temp_degc = chip->pc_temp_ocv_lut->temp[0];
- if (batt_temp_degc > chip->pc_temp_ocv_lut->temp[cols - 1])
- batt_temp_degc = chip->pc_temp_ocv_lut->temp[cols - 1];
-
- for (i = 0; i < cols; i++)
- if (batt_temp_degc <= chip->pc_temp_ocv_lut->temp[i])
- break;
- if (batt_temp_degc == chip->pc_temp_ocv_lut->temp[i]) {
- ocv = linear_interpolate(
- chip->pc_temp_ocv_lut->ocv[row1][i],
- chip->pc_temp_ocv_lut->percent[row1],
- chip->pc_temp_ocv_lut->ocv[row2][i],
- chip->pc_temp_ocv_lut->percent[row2],
- pc);
- return ocv;
- }
-
- ocvrow1 = linear_interpolate(
- chip->pc_temp_ocv_lut->ocv[row1][i - 1],
- chip->pc_temp_ocv_lut->temp[i - 1],
- chip->pc_temp_ocv_lut->ocv[row1][i],
- chip->pc_temp_ocv_lut->temp[i],
- batt_temp_degc);
-
- ocvrow2 = linear_interpolate(
- chip->pc_temp_ocv_lut->ocv[row2][i - 1],
- chip->pc_temp_ocv_lut->temp[i - 1],
- chip->pc_temp_ocv_lut->ocv[row2][i],
- chip->pc_temp_ocv_lut->temp[i],
- batt_temp_degc);
-
- ocv = linear_interpolate(
- ocvrow1,
- chip->pc_temp_ocv_lut->percent[row1],
- ocvrow2,
- chip->pc_temp_ocv_lut->percent[row2],
- pc);
-
- return ocv;
-}
-
-static int interpolate_pc(struct pm8921_bms_chip *chip,
- int batt_temp_degc, int ocv)
-{
- int i, j, pcj, pcj_minus_one, pc;
- int rows = chip->pc_temp_ocv_lut->rows;
- int cols = chip->pc_temp_ocv_lut->cols;
-
-
- if (batt_temp_degc < chip->pc_temp_ocv_lut->temp[0]) {
- pr_debug("batt_temp %d < known temp range\n", batt_temp_degc);
- batt_temp_degc = chip->pc_temp_ocv_lut->temp[0];
- }
- if (batt_temp_degc > chip->pc_temp_ocv_lut->temp[cols - 1]) {
- pr_debug("batt_temp %d > known temp range\n", batt_temp_degc);
- batt_temp_degc = chip->pc_temp_ocv_lut->temp[cols - 1];
- }
-
- for (j = 0; j < cols; j++)
- if (batt_temp_degc <= chip->pc_temp_ocv_lut->temp[j])
- break;
- if (batt_temp_degc == chip->pc_temp_ocv_lut->temp[j]) {
- /* found an exact match for temp in the table */
- if (ocv >= chip->pc_temp_ocv_lut->ocv[0][j])
- return chip->pc_temp_ocv_lut->percent[0];
- if (ocv <= chip->pc_temp_ocv_lut->ocv[rows - 1][j])
- return chip->pc_temp_ocv_lut->percent[rows - 1];
- for (i = 0; i < rows; i++) {
- if (ocv >= chip->pc_temp_ocv_lut->ocv[i][j]) {
- if (ocv == chip->pc_temp_ocv_lut->ocv[i][j])
- return
- chip->pc_temp_ocv_lut->percent[i];
- pc = linear_interpolate(
- chip->pc_temp_ocv_lut->percent[i],
- chip->pc_temp_ocv_lut->ocv[i][j],
- chip->pc_temp_ocv_lut->percent[i - 1],
- chip->pc_temp_ocv_lut->ocv[i - 1][j],
- ocv);
- return pc;
- }
- }
- }
-
- /*
- * batt_temp_degc is within temperature for
- * column j-1 and j
- */
- if (ocv >= chip->pc_temp_ocv_lut->ocv[0][j])
- return chip->pc_temp_ocv_lut->percent[0];
- if (ocv <= chip->pc_temp_ocv_lut->ocv[rows - 1][j - 1])
- return chip->pc_temp_ocv_lut->percent[rows - 1];
-
- pcj_minus_one = 0;
- pcj = 0;
- for (i = 0; i < rows-1; i++) {
- if (pcj == 0
- && is_between(chip->pc_temp_ocv_lut->ocv[i][j],
- chip->pc_temp_ocv_lut->ocv[i+1][j], ocv)) {
- pcj = linear_interpolate(
- chip->pc_temp_ocv_lut->percent[i],
- chip->pc_temp_ocv_lut->ocv[i][j],
- chip->pc_temp_ocv_lut->percent[i + 1],
- chip->pc_temp_ocv_lut->ocv[i+1][j],
- ocv);
- }
-
- if (pcj_minus_one == 0
- && is_between(chip->pc_temp_ocv_lut->ocv[i][j-1],
- chip->pc_temp_ocv_lut->ocv[i+1][j-1], ocv)) {
-
- pcj_minus_one = linear_interpolate(
- chip->pc_temp_ocv_lut->percent[i],
- chip->pc_temp_ocv_lut->ocv[i][j-1],
- chip->pc_temp_ocv_lut->percent[i + 1],
- chip->pc_temp_ocv_lut->ocv[i+1][j-1],
- ocv);
- }
-
- if (pcj && pcj_minus_one) {
- pc = linear_interpolate(
- pcj_minus_one,
- chip->pc_temp_ocv_lut->temp[j-1],
- pcj,
- chip->pc_temp_ocv_lut->temp[j],
- batt_temp_degc);
- return pc;
- }
- }
-
- if (pcj)
- return pcj;
-
- if (pcj_minus_one)
- return pcj_minus_one;
-
- pr_debug("%d ocv wasn't found for temp %d in the LUT returning 100%%",
- ocv, batt_temp_degc);
- return 100;
-}
-
#define BMS_MODE_BIT BIT(6)
#define EN_VBAT_BIT BIT(5)
#define OVERRIDE_MODE_DELAY_MS 20
@@ -1042,7 +706,7 @@
}
/* Convert the batt_temp to DegC from deciDegC */
batt_temp = batt_temp / 10;
- scalefactor = interpolate_scalingfactor(chip, chip->rbatt_sf_lut,
+ scalefactor = interpolate_scalingfactor(chip->rbatt_sf_lut,
batt_temp, soc_rbatt);
pr_debug("rbatt sf = %d for batt_temp = %d, soc_rbatt = %d\n",
scalefactor, batt_temp, soc_rbatt);
@@ -1069,16 +733,18 @@
int initfcc, result, scalefactor = 0;
if (chip->adjusted_fcc_temp_lut == NULL) {
- initfcc = interpolate_fcc(chip, batt_temp);
+ initfcc = interpolate_fcc(chip->fcc_temp_lut, batt_temp);
- scalefactor = interpolate_scalingfactor_fcc(chip, chargecycles);
+ scalefactor = interpolate_scalingfactor_fcc(chip->fcc_sf_lut,
+ chargecycles);
/* Multiply the initial FCC value by the scale factor. */
result = (initfcc * scalefactor * 1000) / 100;
pr_debug("fcc = %d uAh\n", result);
return result;
} else {
- return 1000 * interpolate_fcc_adjusted(chip, batt_temp);
+ return 1000 * interpolate_fcc(chip->adjusted_fcc_temp_lut,
+ batt_temp);
}
}
@@ -1120,17 +786,18 @@
return 0;
}
-static int calculate_pc(struct pm8921_bms_chip *chip, int ocv_uv, int batt_temp,
- int chargecycles)
+static int calculate_pc(struct pm8921_bms_chip *chip, int ocv_uv,
+ int batt_temp, int chargecycles)
{
int pc, scalefactor;
- pc = interpolate_pc(chip, batt_temp / 10, ocv_uv / 1000);
+ pc = interpolate_pc(chip->pc_temp_ocv_lut,
+ batt_temp / 10, ocv_uv / 1000);
pr_debug("pc = %u for ocv = %dmicroVolts batt_temp = %d\n",
pc, ocv_uv, batt_temp);
- scalefactor = interpolate_scalingfactor(chip,
- chip->pc_sf_lut, chargecycles, pc);
+ scalefactor = interpolate_scalingfactor(chip->pc_sf_lut,
+ chargecycles, pc);
pr_debug("scalefactor = %u batt_temp = %d\n", scalefactor, batt_temp);
/* Multiply the initial FCC value by the scale factor. */
@@ -1183,7 +850,8 @@
int uuc_rbatt_uv;
for (i = 0; i <= 100; i++) {
- ocv_mv = interpolate_ocv(chip, batt_temp_degc, i);
+ ocv_mv = interpolate_ocv(chip->pc_temp_ocv_lut,
+ batt_temp_degc, i);
rbatt_mohm = get_rbatt(chip, i, batt_temp);
unusable_uv = (rbatt_mohm * i_ma) + (chip->v_cutoff * 1000);
delta_uv = ocv_mv * 1000 - unusable_uv;
@@ -1239,8 +907,8 @@
new_uuc = (fcc_uah * chip->prev_pc_unusable) / 100;
/* also find update the iavg_ma accordingly */
- new_unusable_mv = interpolate_ocv(chip, batt_temp_degc,
- chip->prev_pc_unusable);
+ new_unusable_mv = interpolate_ocv(chip->pc_temp_ocv_lut,
+ batt_temp_degc, chip->prev_pc_unusable);
if (new_unusable_mv < chip->v_cutoff)
new_unusable_mv = chip->v_cutoff;
@@ -1531,11 +1199,11 @@
pc = DIV_ROUND_CLOSEST((int)rc * 100, fcc_uah);
pc = clamp(pc, 0, 100);
- ocv = interpolate_ocv(chip, batt_temp_degc, pc);
+ ocv = interpolate_ocv(chip->pc_temp_ocv_lut, batt_temp_degc, pc);
pr_debug("s_soc = %d, fcc = %d uuc = %d rc = %d, pc = %d, ocv mv = %d\n",
shutdown_soc, fcc_uah, uuc_uah, (int)rc, pc, ocv);
- new_pc = interpolate_pc(chip, batt_temp_degc, ocv);
+ new_pc = interpolate_pc(chip->pc_temp_ocv_lut, batt_temp_degc, ocv);
pr_debug("test revlookup pc = %d for ocv = %d\n", new_pc, ocv);
while (abs(new_pc - pc) > 1) {
@@ -1545,7 +1213,8 @@
delta_mv = -1 * delta_mv;
ocv = ocv + delta_mv;
- new_pc = interpolate_pc(chip, batt_temp_degc, ocv);
+ new_pc = interpolate_pc(chip->pc_temp_ocv_lut,
+ batt_temp_degc, ocv);
pr_debug("test revlookup pc = %d for ocv = %d\n", new_pc, ocv);
}
diff --git a/drivers/power/pm8921-charger.c b/drivers/power/pm8921-charger.c
index e4e0004..e983081 100644
--- a/drivers/power/pm8921-charger.c
+++ b/drivers/power/pm8921-charger.c
@@ -2308,12 +2308,6 @@
return IRQ_HANDLED;
}
-static irqreturn_t usbin_ov_irq_handler(int irq, void *data)
-{
- pr_err("USB OverVoltage\n");
- return IRQ_HANDLED;
-}
-
static irqreturn_t batt_inserted_irq_handler(int irq, void *data)
{
struct pm8921_chg_chip *chip = data;
@@ -2358,12 +2352,6 @@
return IRQ_HANDLED;
}
-static irqreturn_t usbin_uv_irq_handler(int irq, void *data)
-{
- pr_err("USB UnderVoltage\n");
- return IRQ_HANDLED;
-}
-
static irqreturn_t vbat_ov_irq_handler(int irq, void *data)
{
pr_debug("fsm_state=%d\n", pm_chg_get_fsm_state(data));
@@ -3325,8 +3313,6 @@
pm8921_chg_enable_irq(chip, USBIN_VALID_IRQ);
pm8921_chg_enable_irq(chip, BATT_REMOVED_IRQ);
pm8921_chg_enable_irq(chip, BATT_INSERTED_IRQ);
- pm8921_chg_enable_irq(chip, USBIN_OV_IRQ);
- pm8921_chg_enable_irq(chip, USBIN_UV_IRQ);
pm8921_chg_enable_irq(chip, DCIN_OV_IRQ);
pm8921_chg_enable_irq(chip, DCIN_UV_IRQ);
pm8921_chg_enable_irq(chip, CHGFAIL_IRQ);
@@ -3374,13 +3360,10 @@
struct pm_chg_irq_init_data chg_irq_data[] = {
CHG_IRQ(USBIN_VALID_IRQ, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
usbin_valid_irq_handler),
- CHG_IRQ(USBIN_OV_IRQ, IRQF_TRIGGER_RISING, usbin_ov_irq_handler),
CHG_IRQ(BATT_INSERTED_IRQ, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
batt_inserted_irq_handler),
CHG_IRQ(VBATDET_LOW_IRQ, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
vbatdet_low_irq_handler),
- CHG_IRQ(USBIN_UV_IRQ, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
- usbin_uv_irq_handler),
CHG_IRQ(VBAT_OV_IRQ, IRQF_TRIGGER_RISING, vbat_ov_irq_handler),
CHG_IRQ(CHGWDOG_IRQ, IRQF_TRIGGER_RISING, chgwdog_irq_handler),
CHG_IRQ(VCP_IRQ, IRQF_TRIGGER_RISING, vcp_irq_handler),
@@ -4149,8 +4132,6 @@
enable_irq_wake(chip->pmic_chg_irq[USBIN_VALID_IRQ]);
enable_irq_wake(chip->pmic_chg_irq[DCIN_VALID_IRQ]);
- enable_irq_wake(chip->pmic_chg_irq[USBIN_OV_IRQ]);
- enable_irq_wake(chip->pmic_chg_irq[USBIN_UV_IRQ]);
enable_irq_wake(chip->pmic_chg_irq[BAT_TEMP_OK_IRQ]);
enable_irq_wake(chip->pmic_chg_irq[VBATDET_LOW_IRQ]);
enable_irq_wake(chip->pmic_chg_irq[FASTCHG_IRQ]);
diff --git a/drivers/power/power_supply_core.c b/drivers/power/power_supply_core.c
index 24918ca..352e60e 100644
--- a/drivers/power/power_supply_core.c
+++ b/drivers/power/power_supply_core.c
@@ -51,23 +51,6 @@
* @psy: the power supply to control
* @enable: sets online property of power supply
*/
-int power_supply_set_present(struct power_supply *psy, bool enable)
-{
- const union power_supply_propval ret = {enable,};
-
- if (psy->set_property)
- return psy->set_property(psy, POWER_SUPPLY_PROP_PRESENT,
- &ret);
-
- return -ENXIO;
-}
-EXPORT_SYMBOL_GPL(power_supply_set_present);
-
-/**
- * power_supply_set_online - set online state of the power supply
- * @psy: the power supply to control
- * @enable: sets online property of power supply
- */
int power_supply_set_online(struct power_supply *psy, bool enable)
{
const union power_supply_propval ret = {enable,};
diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index 45429a1..d099074 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -100,6 +100,7 @@
void __iomem *base;
void __iomem *intr;
int pic_irq;
+ bool allow_wakeup;
spinlock_t lock;
u8 owner;
u8 channel;
@@ -638,10 +639,14 @@
return -ENODEV;
pmic_arb->channel = (u8)prop;
- ret = irq_set_irq_wake(pmic_arb->pic_irq, 1);
- if (unlikely(ret)) {
- pr_err("Unable to set wakeup irq, err=%d\n", ret);
- return -ENODEV;
+ pmic_arb->allow_wakeup = !of_property_read_bool(pdev->dev.of_node,
+ "qcom,not-wakeup");
+ if (pmic_arb->allow_wakeup) {
+ ret = irq_set_irq_wake(pmic_arb->pic_irq, 1);
+ if (unlikely(ret)) {
+ pr_err("Unable to set wakeup irq, err=%d\n", ret);
+ return -ENODEV;
+ }
}
pmic_arb->dev = &pdev->dev;
@@ -685,7 +690,8 @@
spmi_del_controller(&pmic_arb->controller);
err_add_controller:
platform_set_drvdata(pdev, NULL);
- irq_set_irq_wake(pmic_arb->pic_irq, 0);
+ if (pmic_arb->allow_wakeup)
+ irq_set_irq_wake(pmic_arb->pic_irq, 0);
return ret;
}
@@ -693,7 +699,8 @@
{
struct spmi_pmic_arb_dev *pmic_arb = platform_get_drvdata(pdev);
- irq_set_irq_wake(pmic_arb->pic_irq, 0);
+ if (pmic_arb->allow_wakeup)
+ irq_set_irq_wake(pmic_arb->pic_irq, 0);
platform_set_drvdata(pdev, NULL);
spmi_del_controller(&pmic_arb->controller);
return 0;
diff --git a/drivers/thermal/msm8960_tsens.c b/drivers/thermal/msm8960_tsens.c
index 0c49a89..f60e318 100644
--- a/drivers/thermal/msm8960_tsens.c
+++ b/drivers/thermal/msm8960_tsens.c
@@ -907,17 +907,6 @@
return 0;
}
-static int tsens_check_version_support(void)
-{
- int rc = 0;
-
- if (tmdev->hw_type == MSM_8960)
- if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) == 1)
- rc = -ENODEV;
-
- return rc;
-}
-
static int tsens_calib_sensors(void)
{
int rc = -ENODEV;
@@ -955,13 +944,6 @@
tmdev->tsens_num_sensor = pdata->tsens_num_sensor;
tmdev->hw_type = pdata->hw_type;
- rc = tsens_check_version_support();
- if (rc < 0) {
- kfree(tmdev);
- tmdev = NULL;
- return rc;
- }
-
rc = tsens_calib_sensors();
if (rc < 0) {
kfree(tmdev);
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 19e1244..a292416 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -1357,6 +1357,9 @@
{
struct usb_device *udev = to_usb_device(dev);
+ if (udev->bus->skip_resume && udev->state == USB_STATE_SUSPENDED)
+ return 0;
+
unbind_no_pm_drivers_interfaces(udev);
/* From now on we are sure all drivers support suspend/resume
@@ -1386,6 +1389,15 @@
struct usb_device *udev = to_usb_device(dev);
int status;
+ /*
+ * Some buses would like to keep their devices in suspend
+ * state after system resume. Their resume happen when
+ * a remote wakeup is detected or interface driver start
+ * I/O.
+ */
+ if (udev->bus->skip_resume)
+ return 0;
+
/* For all calls, take the device back to full power and
* tell the PM core in case it was autosuspended previously.
* Unbind the interfaces that will need rebinding later,
diff --git a/drivers/usb/gadget/android.c b/drivers/usb/gadget/android.c
index 0fbe397..817bfbb 100644
--- a/drivers/usb/gadget/android.c
+++ b/drivers/usb/gadget/android.c
@@ -71,17 +71,19 @@
#define USB_ETH_RNDIS y
#include "f_rndis.c"
#include "rndis.c"
-#include "u_ether.c"
#include "u_bam_data.c"
#include "f_mbim.c"
#include "f_qc_ecm.c"
#include "f_qc_rndis.c"
+#include "u_ether.c"
#include "u_qc_ether.c"
#ifdef CONFIG_TARGET_CORE
#include "f_tcm.c"
#endif
+#ifdef CONFIG_SND_PCM
#include "u_uac1.c"
#include "f_uac1.c"
+#endif
MODULE_AUTHOR("Mike Lockwood");
MODULE_DESCRIPTION("Android Composite USB Driver");
@@ -704,6 +706,7 @@
.init = mbim_function_init,
};
+#ifdef CONFIG_SND_PCM
/* PERIPHERAL AUDIO */
static int audio_function_bind_config(struct android_usb_function *f,
struct usb_configuration *c)
@@ -715,6 +718,7 @@
.name = "audio",
.bind_config = audio_function_bind_config,
};
+#endif
/* DIAG */
@@ -1520,7 +1524,9 @@
static struct android_usb_function *supported_functions[] = {
&mbim_function,
&ecm_qc_function,
+#ifdef CONFIG_SND_PCM
&audio_function,
+#endif
&rmnet_smd_function,
&rmnet_sdio_function,
&rmnet_smd_sdio_function,
diff --git a/drivers/usb/gadget/f_qc_ecm.c b/drivers/usb/gadget/f_qc_ecm.c
index 7fedaf6..1c64955 100644
--- a/drivers/usb/gadget/f_qc_ecm.c
+++ b/drivers/usb/gadget/f_qc_ecm.c
@@ -403,6 +403,8 @@
static void ecm_qc_notify_complete(struct usb_ep *ep, struct usb_request *req)
{
struct f_ecm_qc *ecm = req->context;
+ struct usb_composite_dev *cdev = ecm->port.func.config->cdev;
+ struct usb_cdc_notification *event = req->buf;
switch (req->status) {
case 0:
@@ -584,6 +586,7 @@
static void ecm_qc_disable(struct usb_function *f)
{
struct f_ecm_qc *ecm = func_to_ecm_qc(f);
+ struct usb_composite_dev *cdev = ecm->port.func.config->cdev;
DBG(cdev, "ecm deactivated\n");
diff --git a/drivers/usb/gadget/f_qc_rndis.c b/drivers/usb/gadget/f_qc_rndis.c
index 60b96fe..7a181eb 100644
--- a/drivers/usb/gadget/f_qc_rndis.c
+++ b/drivers/usb/gadget/f_qc_rndis.c
@@ -512,8 +512,9 @@
static void rndis_qc_response_complete(struct usb_ep *ep,
struct usb_request *req)
{
- struct f_rndis_qc *rndis = req->context;
+ struct f_rndis_qc *rndis = req->context;
int status = req->status;
+ struct usb_composite_dev *cdev = rndis->port.func.config->cdev;
/* after TX:
* - USB_CDC_GET_ENCAPSULATED_RESPONSE (ep0/control)
diff --git a/drivers/usb/gadget/msm72k_udc.c b/drivers/usb/gadget/msm72k_udc.c
index 55fd59e..3f4e428 100644
--- a/drivers/usb/gadget/msm72k_udc.c
+++ b/drivers/usb/gadget/msm72k_udc.c
@@ -294,15 +294,17 @@
static inline enum chg_type usb_get_chg_type(struct usb_info *ui)
{
- if ((readl(USB_PORTSC) & PORTSC_LS) == PORTSC_LS)
+ if ((readl_relaxed(USB_PORTSC) & PORTSC_LS) == PORTSC_LS) {
return USB_CHG_TYPE__WALLCHARGER;
- else {
+ } else if (ui->pdata->prop_chg) {
if (ui->gadget.speed == USB_SPEED_LOW ||
ui->gadget.speed == USB_SPEED_FULL ||
ui->gadget.speed == USB_SPEED_HIGH)
return USB_CHG_TYPE__SDP;
else
return USB_CHG_TYPE__INVALID;
+ } else {
+ return USB_CHG_TYPE__SDP;
}
}
@@ -332,7 +334,7 @@
if (temp == USB_CHG_TYPE__WALLCHARGER && !ui->proprietary_chg)
return USB_WALLCHARGER_CHG_CURRENT;
- else
+ else if (ui->pdata->prop_chg)
return USB_PROPRIETARY_CHG_CURRENT;
if (suspended || !configured)
@@ -2049,6 +2051,54 @@
.write = debug_reprime_ep,
};
+static ssize_t debug_prop_chg_write(struct file *file,
+ const char __user *buf, size_t count, loff_t *ppos)
+{
+ struct usb_info *ui = file->private_data;
+ char kbuf[2];
+
+ memset(kbuf, 0, sizeof(kbuf));
+
+ if (copy_from_user(kbuf, buf, sizeof(kbuf)))
+ return -EFAULT;
+
+ if (!strncmp(kbuf, "1", 1))
+ ui->pdata->prop_chg = 1;
+ else
+ ui->pdata->prop_chg = 0;
+
+ return count;
+}
+
+static ssize_t debug_prop_chg_read(struct file *file, char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ struct usb_info *ui = file->private_data;
+ char kbuf[2];
+ size_t c = 0;
+
+ memset(kbuf, 0, sizeof(kbuf));
+
+ c = scnprintf(kbuf, sizeof(kbuf), "%d\n", ui->pdata->prop_chg);
+
+ if (copy_to_user(ubuf, kbuf, c))
+ return -EFAULT;
+
+ return simple_read_from_buffer(ubuf, count, ppos, kbuf, c);
+}
+
+static int debug_prop_chg_open(struct inode *inode, struct file *file)
+{
+ file->private_data = inode->i_private;
+ return 0;
+}
+
+const struct file_operations debug_prop_chg_ops = {
+ .open = debug_prop_chg_open,
+ .read = debug_prop_chg_read,
+ .write = debug_prop_chg_write,
+};
+
static void usb_debugfs_init(struct usb_info *ui)
{
struct dentry *dent;
@@ -2063,6 +2113,8 @@
&debug_wlocks_ops);
debugfs_create_file("prime_fail_countt", 0666, dent, ui,
&prime_fail_ops);
+ debugfs_create_file("proprietary_chg", 0666, dent, ui,
+ &debug_prop_chg_ops);
}
#else
static void usb_debugfs_init(struct usb_info *ui) {}
diff --git a/drivers/usb/gadget/u_data_hsuart.c b/drivers/usb/gadget/u_data_hsuart.c
index 74bb93f..4d88ea5 100644
--- a/drivers/usb/gadget/u_data_hsuart.c
+++ b/drivers/usb/gadget/u_data_hsuart.c
@@ -244,9 +244,7 @@
pr_debug("%s: port:%p tom:%lu pno:%d\n", __func__,
port, port->to_modem, port->port_num);
- spin_unlock_irqrestore(&port->rx_lock, flags);
ret = msm_smux_write(port->ch_id, skb, skb->data, skb->len);
- spin_lock_irqsave(&port->rx_lock, flags);
if (ret < 0) {
if (ret == -EAGAIN) {
/*flow control*/
diff --git a/drivers/usb/host/ehci-msm-hsic.c b/drivers/usb/host/ehci-msm-hsic.c
index b7f1878..6fe9e58 100644
--- a/drivers/usb/host/ehci-msm-hsic.c
+++ b/drivers/usb/host/ehci-msm-hsic.c
@@ -926,6 +926,8 @@
return 0;
}
+#ifdef CONFIG_PM
+
static int ehci_hsic_bus_suspend(struct usb_hcd *hcd)
{
struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
@@ -1135,6 +1137,13 @@
return 0;
}
+#else
+
+#define ehci_hsic_bus_suspend NULL
+#define ehci_hsic_bus_resume NULL
+
+#endif /* CONFIG_PM */
+
static struct hc_driver msm_hsic_driver = {
.description = hcd_name,
.product_desc = "Qualcomm EHCI Host Controller using HSIC",
@@ -1279,6 +1288,7 @@
static irqreturn_t msm_hsic_wakeup_irq(int irq, void *data)
{
struct msm_hsic_hcd *mehci = data;
+ int ret;
mehci->wakeup_int_cnt++;
dbg_log_event(NULL, "Remote Wakeup IRQ", mehci->wakeup_int_cnt);
@@ -1296,8 +1306,17 @@
spin_unlock(&mehci->wakeup_lock);
if (!atomic_read(&mehci->pm_usage_cnt)) {
- atomic_set(&mehci->pm_usage_cnt, 1);
- pm_runtime_get(mehci->dev);
+ ret = pm_runtime_get(mehci->dev);
+ /*
+ * HSIC runtime resume can race with us.
+ * if we are active (ret == 1) or resuming
+ * (ret == -EINPROGRESS), decrement the
+ * PM usage counter before returning.
+ */
+ if ((ret == 1) || (ret == -EINPROGRESS))
+ pm_runtime_put_noidle(mehci->dev);
+ else
+ atomic_set(&mehci->pm_usage_cnt, 1);
}
return IRQ_HANDLED;
@@ -1522,6 +1541,8 @@
return -ENOMEM;
}
+ hcd_to_bus(hcd)->skip_resume = true;
+
hcd->irq = platform_get_irq(pdev, 0);
if (hcd->irq < 0) {
dev_err(&pdev->dev, "Unable to get IRQ resource\n");
@@ -1791,6 +1812,15 @@
if (device_may_wakeup(dev))
disable_irq_wake(hcd->irq);
+ /*
+ * Keep HSIC in Low Power Mode if system is resumed
+ * by any other wakeup source. HSIC is resumed later
+ * when remote wakeup is received or interface driver
+ * start I/O.
+ */
+ if (!atomic_read(&mehci->pm_usage_cnt))
+ return 0;
+
ret = msm_hsic_resume(mehci);
if (ret)
return ret;
diff --git a/drivers/usb/misc/ks_bridge.c b/drivers/usb/misc/ks_bridge.c
index 87f43e1c..656e379 100644
--- a/drivers/usb/misc/ks_bridge.c
+++ b/drivers/usb/misc/ks_bridge.c
@@ -168,11 +168,10 @@
size_t len;
pkt = list_first_entry(&ksb->to_ks_list, struct data_pkt, list);
- len = min_t(size_t, space, pkt->len);
- pkt->n_read += len;
+ len = min_t(size_t, space, pkt->len - pkt->n_read);
spin_unlock_irqrestore(&ksb->lock, flags);
- ret = copy_to_user(buf + copied, pkt->buf, len);
+ ret = copy_to_user(buf + copied, pkt->buf + pkt->n_read, len);
if (ret) {
pr_err("copy_to_user failed err:%d\n", ret);
ksb_free_data_pkt(pkt);
@@ -180,6 +179,7 @@
return ret;
}
+ pkt->n_read += len;
space -= len;
copied += len;
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index f1cbce3..60018bf 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -39,6 +39,7 @@
#include <linux/regulator/consumer.h>
#include <linux/mfd/pm8xxx/pm8921-charger.h>
#include <linux/mfd/pm8xxx/misc.h>
+#include <linux/power_supply.h>
#include <linux/mhl_8334.h>
#include <mach/clk.h>
@@ -51,6 +52,7 @@
#define DRIVER_NAME "msm_otg"
#define ID_TIMER_FREQ (jiffies + msecs_to_jiffies(500))
+#define CHG_RECHECK_DELAY (jiffies + msecs_to_jiffies(2000))
#define ULPI_IO_TIMEOUT_USEC (10 * 1000)
#define USB_PHY_3P3_VOL_MIN 3050000 /* uV */
#define USB_PHY_3P3_VOL_MAX 3300000 /* uV */
@@ -89,7 +91,6 @@
static struct power_supply *psy;
static bool aca_id_turned_on;
-static bool legacy_power_supply;
static inline bool aca_enabled(void)
{
#ifdef CONFIG_USB_MSM_ACA
@@ -1090,25 +1091,24 @@
}
#endif
-static void msm_otg_notify_host_mode(struct msm_otg *motg, bool host_mode)
+static int msm_otg_notify_host_mode(struct msm_otg *motg, bool host_mode)
{
- if (psy) {
- /* legacy support */
- if (host_mode)
- power_supply_set_scope(psy, POWER_SUPPLY_SCOPE_SYSTEM);
- else
- power_supply_set_scope(psy, POWER_SUPPLY_SCOPE_DEVICE);
- return;
- } else {
- motg->host_mode = host_mode;
- power_supply_changed(&motg->usb_psy);
- }
+ if (!psy)
+ goto psy_not_supported;
+
+ if (host_mode)
+ power_supply_set_scope(psy, POWER_SUPPLY_SCOPE_SYSTEM);
+ else
+ power_supply_set_scope(psy, POWER_SUPPLY_SCOPE_DEVICE);
+
+psy_not_supported:
+ dev_dbg(motg->phy.dev, "Power Supply doesn't support USB charger\n");
+ return -ENXIO;
}
static int msm_otg_notify_chg_type(struct msm_otg *motg)
{
static int charger_type;
- struct power_supply *usb = psy ? psy : &motg->usb_psy;
/*
* TODO
@@ -1132,45 +1132,40 @@
else
charger_type = POWER_SUPPLY_TYPE_BATTERY;
- if (!usb) {
+ if (!psy) {
pr_err("No USB power supply registered!\n");
return -EINVAL;
}
pr_debug("setting usb power supply type %d\n", charger_type);
- power_supply_set_supply_type(usb, charger_type);
+ power_supply_set_supply_type(psy, charger_type);
return 0;
}
static int msm_otg_notify_power_supply(struct msm_otg *motg, unsigned mA)
{
- struct power_supply *usb = psy ? psy : &motg->usb_psy;
- if (!usb) {
- dev_dbg(motg->phy.dev, "no usb power supply registered\n");
- goto psy_error;
- }
+ if (!psy)
+ goto psy_not_supported;
- if (motg->cur_power == 0 && mA > 2) {
+ if (motg->cur_power == 0 && mA > 0) {
/* Enable charging */
- if (power_supply_set_online(usb, true))
- goto psy_error;
- if (power_supply_set_current_limit(usb, 1000*mA))
- goto psy_error;
- } else if (motg->cur_power > 0 && (mA == 0 || mA == 2)) {
+ if (power_supply_set_online(psy, true))
+ goto psy_not_supported;
+ } else if (motg->cur_power > 0 && mA == 0) {
/* Disable charging */
- if (power_supply_set_online(usb, false))
- goto psy_error;
- /* Set max current limit */
- if (power_supply_set_current_limit(usb, 0))
- goto psy_error;
+ if (power_supply_set_online(psy, false))
+ goto psy_not_supported;
+ return 0;
}
+ /* Set max current limit */
+ if (power_supply_set_current_limit(psy, 1000*mA))
+ goto psy_not_supported;
- power_supply_changed(usb);
return 0;
-psy_error:
- dev_dbg(motg->phy.dev, "power supply error when setting property\n");
+psy_not_supported:
+ dev_dbg(motg->phy.dev, "Power Supply doesn't support USB charger\n");
return -ENXIO;
}
@@ -1635,6 +1630,26 @@
return ret;
}
+static void msm_otg_chg_check_timer_func(unsigned long data)
+{
+ struct msm_otg *motg = (struct msm_otg *) data;
+ struct usb_otg *otg = motg->phy.otg;
+
+ if (atomic_read(&motg->in_lpm) ||
+ !test_bit(B_SESS_VLD, &motg->inputs) ||
+ otg->phy->state != OTG_STATE_B_PERIPHERAL ||
+ otg->gadget->speed != USB_SPEED_UNKNOWN) {
+ dev_dbg(otg->phy->dev, "Nothing to do in chg_check_timer\n");
+ return;
+ }
+
+ if ((readl_relaxed(USB_PORTSC) & PORTSC_LS) == PORTSC_LS) {
+ dev_dbg(otg->phy->dev, "DCP is detected as SDP\n");
+ set_bit(B_FALSE_SDP, &motg->inputs);
+ queue_work(system_nrt_wq, &motg->sm_work);
+ }
+}
+
static bool msm_chg_aca_detect(struct msm_otg *motg)
{
struct usb_phy *phy = &motg->phy;
@@ -2282,13 +2297,9 @@
case OTG_STATE_UNDEFINED:
msm_otg_reset(otg->phy);
msm_otg_init_sm(motg);
- if (!psy && legacy_power_supply) {
- psy = power_supply_get_by_name("usb");
-
- if (!psy)
- pr_err("couldn't get usb power supply\n");
- }
-
+ psy = power_supply_get_by_name("usb");
+ if (!psy)
+ pr_err("couldn't get usb power supply\n");
otg->phy->state = OTG_STATE_B_IDLE;
if (!test_bit(B_SESS_VLD, &motg->inputs) &&
test_bit(ID, &motg->inputs)) {
@@ -2357,6 +2368,8 @@
msm_otg_start_peripheral(otg, 1);
otg->phy->state =
OTG_STATE_B_PERIPHERAL;
+ mod_timer(&motg->chg_check_timer,
+ CHG_RECHECK_DELAY);
break;
default:
break;
@@ -2377,6 +2390,8 @@
break;
} else {
pr_debug("chg_work cancel");
+ del_timer_sync(&motg->chg_check_timer);
+ clear_bit(B_FALSE_SDP, &motg->inputs);
cancel_delayed_work_sync(&motg->chg_work);
motg->chg_state = USB_CHG_STATE_UNDEFINED;
motg->chg_type = USB_INVALID_CHARGER;
@@ -2414,7 +2429,15 @@
}
break;
case OTG_STATE_B_PERIPHERAL:
- if (!test_bit(ID, &motg->inputs) ||
+ if (test_bit(B_SESS_VLD, &motg->inputs) &&
+ test_bit(B_FALSE_SDP, &motg->inputs)) {
+ pr_debug("B_FALSE_SDP\n");
+ msm_otg_start_peripheral(otg, 0);
+ motg->chg_type = USB_DCP_CHARGER;
+ clear_bit(B_FALSE_SDP, &motg->inputs);
+ otg->phy->state = OTG_STATE_B_IDLE;
+ work = 1;
+ } else if (!test_bit(ID, &motg->inputs) ||
test_bit(ID_A, &motg->inputs) ||
test_bit(ID_B, &motg->inputs) ||
!test_bit(B_SESS_VLD, &motg->inputs)) {
@@ -3317,71 +3340,6 @@
return count;
}
-static int otg_power_get_property_usb(struct power_supply *psy,
- enum power_supply_property psp,
- union power_supply_propval *val)
-{
- struct msm_otg *motg = container_of(psy, struct msm_otg,
- usb_psy);
- switch (psp) {
- case POWER_SUPPLY_PROP_SCOPE:
- if (motg->host_mode)
- val->intval = POWER_SUPPLY_SCOPE_SYSTEM;
- else
- val->intval = POWER_SUPPLY_SCOPE_DEVICE;
- break;
- case POWER_SUPPLY_PROP_CURRENT_MAX:
- val->intval = motg->current_max;
- break;
- /* Reflect USB enumeration */
- case POWER_SUPPLY_PROP_PRESENT:
- case POWER_SUPPLY_PROP_ONLINE:
- val->intval = motg->online;
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int otg_power_set_property_usb(struct power_supply *psy,
- enum power_supply_property psp,
- const union power_supply_propval *val)
-{
- struct msm_otg *motg = container_of(psy, struct msm_otg,
- usb_psy);
-
- switch (psp) {
- /* Process PMIC notification in PRESENT prop */
- case POWER_SUPPLY_PROP_PRESENT:
- msm_otg_set_vbus_state(val->intval);
- break;
- /* The ONLINE property reflects if usb has enumerated */
- case POWER_SUPPLY_PROP_ONLINE:
- motg->online = val->intval;
- break;
- case POWER_SUPPLY_PROP_CURRENT_MAX:
- motg->current_max = val->intval;
- break;
- default:
- return -EINVAL;
- }
-
- power_supply_changed(&motg->usb_psy);
- return 0;
-}
-
-static char *otg_pm_power_supplied_to[] = {
- "battery",
-};
-
-static enum power_supply_property otg_pm_power_props_usb[] = {
- POWER_SUPPLY_PROP_PRESENT,
- POWER_SUPPLY_PROP_ONLINE,
- POWER_SUPPLY_PROP_CURRENT_MAX,
- POWER_SUPPLY_PROP_SCOPE,
-};
-
const struct file_operations msm_otg_bus_fops = {
.open = msm_otg_bus_open,
.read = seq_read,
@@ -3784,6 +3742,8 @@
INIT_DELAYED_WORK(&motg->suspend_work, msm_otg_suspend_work);
setup_timer(&motg->id_timer, msm_otg_id_timer_func,
(unsigned long) motg);
+ setup_timer(&motg->chg_check_timer, msm_otg_chg_check_timer_func,
+ (unsigned long) motg);
ret = request_irq(motg->irq, msm_otg_irq, IRQF_SHARED,
"msm_otg", motg);
if (ret) {
@@ -3852,6 +3812,9 @@
dev_dbg(&pdev->dev, "mode debugfs file is"
"not available\n");
+ if (motg->pdata->otg_control == OTG_PMIC_CONTROL)
+ pm8921_charger_register_vbus_sn(&msm_otg_set_vbus_state);
+
if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY) {
if (motg->pdata->otg_control == OTG_PMIC_CONTROL &&
(!(motg->pdata->mode == USB_OTG) ||
@@ -3881,34 +3844,6 @@
debug_bus_voting_enabled = true;
}
- motg->usb_psy.name = "usb";
- motg->usb_psy.type = POWER_SUPPLY_TYPE_USB;
- motg->usb_psy.supplied_to = otg_pm_power_supplied_to;
- motg->usb_psy.num_supplicants = ARRAY_SIZE(otg_pm_power_supplied_to);
- motg->usb_psy.properties = otg_pm_power_props_usb;
- motg->usb_psy.num_properties = ARRAY_SIZE(otg_pm_power_props_usb);
- motg->usb_psy.get_property = otg_power_get_property_usb;
- motg->usb_psy.set_property = otg_power_set_property_usb;
-
-
- if (motg->pdata->otg_control == OTG_PMIC_CONTROL) {
- /* if pm8921 use legacy implementation */
- if (!pm8921_charger_register_vbus_sn(&msm_otg_set_vbus_state)) {
- dev_dbg(motg->phy.dev, "%s: legacy support\n",
- __func__);
- legacy_power_supply = true;
- } else {
- ret = power_supply_register(&pdev->dev, &motg->usb_psy);
- if (ret < 0) {
- dev_err(motg->phy.dev,
- "%s:power_supply_register usb failed\n",
- __func__);
- goto remove_phy;
- }
- legacy_power_supply = false;
- }
- }
-
return 0;
remove_phy:
diff --git a/drivers/video/msm/hdmi_msm.c b/drivers/video/msm/hdmi_msm.c
index 902e92c..3b1610a 100644
--- a/drivers/video/msm/hdmi_msm.c
+++ b/drivers/video/msm/hdmi_msm.c
@@ -60,6 +60,9 @@
struct workqueue_struct *hdmi_work_queue;
struct hdmi_msm_state_type *hdmi_msm_state;
+/* Enable HDCP by default */
+static bool hdcp_feature_on = true;
+
DEFINE_MUTEX(hdmi_msm_state_mutex);
EXPORT_SYMBOL(hdmi_msm_state_mutex);
static DEFINE_MUTEX(hdcp_auth_state_mutex);
@@ -4874,6 +4877,27 @@
platform_driver_unregister(&this_driver);
}
+static int set_hdcp_feature_on(const char *val, const struct kernel_param *kp)
+{
+ int rv = param_set_bool(val, kp);
+
+ if (rv)
+ return rv;
+
+ pr_debug("%s: HDCP feature = %d\n", __func__, hdcp_feature_on);
+
+ return 0;
+}
+
+static struct kernel_param_ops hdcp_feature_on_param_ops = {
+ .set = set_hdcp_feature_on,
+ .get = param_get_bool,
+};
+
+module_param_cb(hdcp, &hdcp_feature_on_param_ops, &hdcp_feature_on,
+ S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(hdcp, "Enable or Disable HDCP");
+
module_init(hdmi_msm_init);
module_exit(hdmi_msm_exit);
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index f6d9eb7..c36e4b4 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -35,6 +35,7 @@
#include <asm/mach-types.h>
#include <linux/semaphore.h>
#include <linux/uaccess.h>
+#include <mach/event_timer.h>
#include <mach/clk.h>
#include "mdp.h"
#include "msm_fb.h"
@@ -518,7 +519,9 @@
int ret;
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+ mdp_clk_ctrl(1);
ret = mdp_lut_hw_update(cmap);
+ mdp_clk_ctrl(0);
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
if (ret)
@@ -540,9 +543,11 @@
uint32_t out;
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+ mdp_clk_ctrl(1);
ret = mdp_lut_hw_update(cmap);
if (ret) {
+ mdp_clk_ctrl(0);
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
return ret;
}
@@ -550,6 +555,7 @@
/*mask off non LUT select bits*/
out = inpdw(MDP_BASE + 0x90070);
MDP_OUTP(MDP_BASE + 0x90070, (mdp_lut_i << 10) | 0x7 | out);
+ mdp_clk_ctrl(0);
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
mdp_lut_i = (mdp_lut_i + 1)%2;
@@ -1066,6 +1072,7 @@
}
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+ mdp_clk_ctrl(1);
for (i = 0; i < mgmt->num_bins; i++) {
mgmt->c0[i] = inpdw(mdp_hist_base + r_data_offset + (4*i));
mgmt->c1[i] = inpdw(mdp_hist_base + g_data_offset + (4*i));
@@ -1081,6 +1088,7 @@
} else
ret = -ENOMEM;
}
+ mdp_clk_ctrl(0);
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
if (!ret)
@@ -1116,6 +1124,7 @@
}
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+ mdp_clk_ctrl(1);
for (i = 0; i < mgmt->num_bins; i++)
mgmt->c0[i] = inpdw(mdp_hist_base + MDP_HIST_DATA_LUMA_OFF +
(4*i));
@@ -1127,6 +1136,7 @@
} else
ret = -ENOMEM;
}
+ mdp_clk_ctrl(0);
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
if (!ret)
@@ -1315,27 +1325,32 @@
}
#endif
-static void send_vsync_work(struct work_struct *work)
-{
- char buf[64];
- char *envp[2];
-
- snprintf(buf, sizeof(buf), "VSYNC=%llu",
- ktime_to_ns(vsync_cntrl.vsync_time));
- envp[0] = buf;
- envp[1] = NULL;
- kobject_uevent_env(&(vsync_cntrl.dev->kobj), KOBJ_CHANGE, envp);
-}
-
#ifdef CONFIG_FB_MSM_MDP303
/* vsync_isr_handler: Called from isr context*/
static void vsync_isr_handler(void)
{
vsync_cntrl.vsync_time = ktime_get();
- schedule_work(&(vsync_cntrl.vsync_work));
}
#endif
+static ssize_t vsync_show_event(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ ssize_t ret = 0;
+
+ if (atomic_read(&vsync_cntrl.suspend) > 0 ||
+ atomic_read(&vsync_cntrl.vsync_resume) == 0)
+ return 0;
+
+ INIT_COMPLETION(vsync_cntrl.vsync_wait);
+
+ wait_for_completion(&vsync_cntrl.vsync_wait);
+ ret = snprintf(buf, PAGE_SIZE, "VSYNC=%llu",
+ ktime_to_ns(vsync_cntrl.vsync_time));
+ buf[strlen(buf) + 1] = '\0';
+ return ret;
+}
+
/* Returns < 0 on error, 0 on timeout, or > 0 on successful wait */
int mdp_ppp_pipe_wait(void)
{
@@ -1352,15 +1367,95 @@
if (wait == TRUE) {
ret = wait_for_completion_interruptible_timeout(&mdp_ppp_comp,
5 * HZ);
-
if (!ret)
printk(KERN_ERR "%s: Timed out waiting for the MDP.\n",
- __func__);
+ __func__);
}
return ret;
}
+#define MAX_VSYNC_GAP 4
+#define DEFAULT_FRAME_RATE 60
+
+static u32 mdp_get_panel_framerate(struct msm_fb_data_type *mfd)
+{
+ u32 frame_rate = 0, total_pixel;
+ struct msm_panel_info *panel_info = &mfd->panel_info;
+ if (mfd->dest == DISPLAY_LCD) {
+ if (panel_info->type == MDDI_PANEL && panel_info->mddi.is_type1)
+ frame_rate = panel_info->lcd.refx100 / (100 * 2);
+ else
+ frame_rate = panel_info->lcd.refx100 / 100;
+ } else {
+ if (panel_info->type == MIPI_VIDEO_PANEL) {
+ frame_rate = panel_info->mipi.frame_rate;
+ } else {
+ total_pixel = (panel_info->lcdc.h_back_porch +
+ panel_info->lcdc.h_front_porch +
+ panel_info->lcdc.h_pulse_width +
+ panel_info->xres) *
+ (panel_info->lcdc.v_back_porch +
+ panel_info->lcdc.v_front_porch +
+ panel_info->lcdc.v_pulse_width +
+ panel_info->yres);
+ if (total_pixel)
+ frame_rate = panel_info->clk_rate /
+ total_pixel;
+ }
+ }
+ if (frame_rate == 0)
+ frame_rate = DEFAULT_FRAME_RATE;
+ return frame_rate;
+}
+
+static int mdp_diff_to_next_vsync(ktime_t cur_time,
+ ktime_t last_vsync, u32 vsync_period)
+{
+ int diff_from_last, diff_to_next;
+ /*
+ * Get interval beween last vsync and current time
+ * Current time = CPU programming MDP for next Vsync
+ */
+ diff_from_last =
+ (ktime_to_us(ktime_sub(cur_time, last_vsync)));
+ diff_from_last /= USEC_PER_MSEC;
+ /*
+ * If the last Vsync occurred too long ago, skip programming
+ * the timer
+ */
+ if (diff_from_last < (vsync_period * MAX_VSYNC_GAP)) {
+ if (diff_from_last > vsync_period)
+ diff_to_next =
+ (diff_from_last - vsync_period) % vsync_period;
+ else
+ diff_to_next = vsync_period - diff_from_last;
+ } else {
+ /* mark it out of range */
+ diff_to_next = vsync_period + 1;
+ }
+ return diff_to_next;
+}
+
+void mdp_update_pm(struct msm_fb_data_type *mfd, ktime_t pre_vsync)
+{
+ u32 vsync_period;
+ int diff_to_next;
+ ktime_t cur_time, wakeup_time;
+
+ if (!mfd->cpu_pm_hdl)
+ return;
+ vsync_period = mfd->panel_info.frame_interval;
+ cur_time = ktime_get();
+ diff_to_next = mdp_diff_to_next_vsync(cur_time,
+ pre_vsync,
+ vsync_period);
+ if (diff_to_next > vsync_period)
+ return;
+ wakeup_time = ktime_add_ns(cur_time, diff_to_next * NSEC_PER_MSEC);
+ activate_event_timer(mfd->cpu_pm_hdl, wakeup_time);
+}
+
static DEFINE_SPINLOCK(mdp_lock);
static int mdp_irq_mask;
static int mdp_irq_enabled;
@@ -1782,7 +1877,7 @@
unsigned long flag;
struct mdp_hist_mgmt *mgmt = NULL;
int i, ret;
- int vsync_isr;
+ int vsync_isr, disabled_clocks;
/* Ensure all the register write are complete */
mb();
@@ -1805,19 +1900,25 @@
if (mdp_interrupt & MDP_PRIM_RDPTR) {
spin_lock_irqsave(&mdp_spin_lock, flag);
vsync_isr = vsync_cntrl.vsync_irq_enabled;
- if (!vsync_isr) {
+ disabled_clocks = vsync_cntrl.disabled_clocks;
+ if ((!vsync_isr && !vsync_cntrl.disabled_clocks)
+ || (!vsync_isr && vsync_cntrl.vsync_dma_enabled)) {
mdp_intr_mask &= ~MDP_PRIM_RDPTR;
outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+ mdp_disable_irq_nosync(MDP_VSYNC_TERM);
+ vsync_cntrl.disabled_clocks = 1;
+ } else if (vsync_isr) {
+ vsync_isr_handler();
}
+ vsync_cntrl.vsync_dma_enabled = 0;
spin_unlock_irqrestore(&mdp_spin_lock, flag);
- if (vsync_isr) {
- vsync_isr_handler();
- } else {
+ complete(&vsync_cntrl.vsync_comp);
+ if (!vsync_isr && !disabled_clocks)
mdp_pipe_ctrl(MDP_CMD_BLOCK,
MDP_BLOCK_POWER_OFF, TRUE);
- complete(&vsync_cntrl.vsync_wait);
- }
+
+ complete_all(&vsync_cntrl.vsync_wait);
}
/* DMA3 TV-Out Start */
@@ -1870,16 +1971,18 @@
if (!vsync_isr) {
mdp_intr_mask &= ~LCDC_FRAME_START;
outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+ mdp_disable_irq_nosync(MDP_VSYNC_TERM);
+ vsync_cntrl.disabled_clocks = 1;
+ } else {
+ vsync_isr_handler();
}
spin_unlock_irqrestore(&mdp_spin_lock, flag);
- if (vsync_isr) {
- vsync_isr_handler();
- } else {
+ if (!vsync_isr)
mdp_pipe_ctrl(MDP_CMD_BLOCK,
MDP_BLOCK_POWER_OFF, TRUE);
- complete(&vsync_cntrl.vsync_wait);
- }
+
+ complete_all(&vsync_cntrl.vsync_wait);
}
/* DMA2 LCD-Out Complete */
@@ -1927,6 +2030,7 @@
spin_unlock_irqrestore(&mdp_spin_lock, flag);
mdp_pipe_ctrl(MDP_DMA2_BLOCK, MDP_BLOCK_POWER_OFF,
TRUE);
+ mdp_disable_irq_nosync(MDP_DMA2_TERM);
complete(&dma->comp);
}
#endif
@@ -1978,6 +2082,7 @@
dma2_data.dmap_busy = FALSE;
dma2_data.waiting = FALSE;
init_completion(&dma2_data.comp);
+ init_completion(&vsync_cntrl.vsync_comp);
init_completion(&dma2_data.dmap_comp);
sema_init(&dma2_data.mutex, 1);
mutex_init(&dma2_data.ov_mutex);
@@ -2009,8 +2114,9 @@
for (i = 0; i < MDP_MAX_BLOCK; i++) {
atomic_set(&mdp_block_power_cnt[i], 0);
}
- INIT_WORK(&(vsync_cntrl.vsync_work), send_vsync_work);
+ vsync_cntrl.disabled_clocks = 1;
init_completion(&vsync_cntrl.vsync_wait);
+ atomic_set(&vsync_cntrl.vsync_resume, 1);
#ifdef MSM_FB_ENABLE_DBGFS
{
struct dentry *root;
@@ -2096,7 +2202,9 @@
pr_debug("%s:+\n", __func__);
mdp_histogram_ctrl_all(FALSE);
-
+ atomic_set(&vsync_cntrl.suspend, 1);
+ atomic_set(&vsync_cntrl.vsync_resume, 0);
+ complete_all(&vsync_cntrl.vsync_wait);
mdp_clk_ctrl(1);
if (mfd->panel.type == MIPI_CMD_PANEL)
mdp4_dsi_cmd_off(pdev);
@@ -2127,7 +2235,16 @@
{
/* empty */
}
+
#endif
+static DEVICE_ATTR(vsync_event, S_IRUGO, vsync_show_event, NULL);
+static struct attribute *vsync_fs_attrs[] = {
+ &dev_attr_vsync_event.attr,
+ NULL,
+};
+static struct attribute_group vsync_fs_attr_group = {
+ .attrs = vsync_fs_attrs,
+};
static int mdp_on(struct platform_device *pdev)
{
@@ -2157,10 +2274,26 @@
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
}
- if ((mdp_rev == MDP_REV_303) &&
- (mfd->panel.type == MIPI_CMD_PANEL))
+ if (mdp_rev == MDP_REV_303 && mfd->panel.type == MIPI_CMD_PANEL) {
+
vsync_cntrl.dev = mfd->fbi->dev;
+ if (!vsync_cntrl.sysfs_created) {
+ ret = sysfs_create_group(&vsync_cntrl.dev->kobj,
+ &vsync_fs_attr_group);
+ if (ret) {
+ pr_err("%s: sysfs creation failed, ret=%d\n",
+ __func__, ret);
+ return ret;
+ }
+
+ kobject_uevent(&vsync_cntrl.dev->kobj, KOBJ_ADD);
+ pr_debug("%s: kobject_uevent(KOBJ_ADD)\n", __func__);
+ vsync_cntrl.sysfs_created = 1;
+ }
+ atomic_set(&vsync_cntrl.suspend, 0);
+ }
+
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
ret = panel_next_on(pdev);
@@ -2383,6 +2516,7 @@
int rc;
resource_size_t size ;
unsigned long flag;
+ u32 frame_rate;
#ifdef CONFIG_FB_MSM_MDP40
int intf, if_no;
#endif
@@ -2434,7 +2568,9 @@
#ifdef CONFIG_FB_MSM_OVERLAY
mdp_hw_cursor_init();
#endif
- mdp_clk_ctrl(0);
+
+ if (!(mdp_pdata->cont_splash_enabled))
+ mdp_clk_ctrl(0);
mdp_resource_initialized = 1;
return 0;
@@ -2823,6 +2959,11 @@
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
}
+ frame_rate = mdp_get_panel_framerate(mfd);
+ if (frame_rate) {
+ mfd->panel_info.frame_interval = 1000 / frame_rate;
+ mfd->cpu_pm_hdl = add_event_timer(NULL, (void *)mfd);
+ }
mdp_clk_ctrl(0);
#ifdef CONFIG_MSM_BUS_SCALING
diff --git a/drivers/video/msm/mdp.h b/drivers/video/msm/mdp.h
index 371174c..d939c62 100644
--- a/drivers/video/msm/mdp.h
+++ b/drivers/video/msm/mdp.h
@@ -94,10 +94,16 @@
struct vsync {
ktime_t vsync_time;
+ struct completion vsync_comp;
struct device *dev;
struct work_struct vsync_work;
int vsync_irq_enabled;
+ int vsync_dma_enabled;
+ int disabled_clocks;
struct completion vsync_wait;
+ atomic_t suspend;
+ atomic_t vsync_resume;
+ int sysfs_created;
};
extern struct vsync vsync_cntrl;
@@ -901,6 +907,7 @@
int mdp_ppp_v4l2_overlay_play(struct fb_info *info,
unsigned long srcp0_addr, unsigned long srcp0_size,
unsigned long srcp1_addr, unsigned long srcp1_size);
+void mdp_update_pm(struct msm_fb_data_type *mfd, ktime_t pre_vsync);
#ifdef CONFIG_FB_MSM_DTV
void mdp_vid_quant_set(void);
diff --git a/drivers/video/msm/mdp4_overlay.c b/drivers/video/msm/mdp4_overlay.c
index 18cf817..b154a3b 100644
--- a/drivers/video/msm/mdp4_overlay.c
+++ b/drivers/video/msm/mdp4_overlay.c
@@ -735,37 +735,53 @@
*luma_off = 0;
*chroma_off = 0;
- if (pipe->src_x && (pipe->frame_format ==
+ if ((pipe->src_x || pipe->src_y) && (pipe->frame_format ==
MDP4_FRAME_FORMAT_LINEAR)) {
- src_xy = (pipe->src_y << 16) | pipe->src_x;
- src_xy &= 0xffff0000;
+ src_xy = 0;
outpdw(vg_base + 0x0004, src_xy); /* MDP_RGB_SRC_XY */
switch (pipe->src_format) {
case MDP_Y_CR_CB_H2V2:
case MDP_Y_CR_CB_GH2V2:
case MDP_Y_CB_CR_H2V2:
- *luma_off = pipe->src_x;
- *chroma_off = pipe->src_x/2;
+ *luma_off = pipe->src_x +
+ (pipe->src_y * pipe->srcp0_ystride);
+ *chroma_off = pipe->src_x / 2 +
+ ((pipe->src_y / 2) * pipe->srcp1_ystride);
break;
case MDP_Y_CBCR_H2V2_TILE:
case MDP_Y_CRCB_H2V2_TILE:
case MDP_Y_CBCR_H2V2:
case MDP_Y_CRCB_H2V2:
+ *luma_off = pipe->src_x +
+ (pipe->src_y * pipe->srcp0_ystride);
+ *chroma_off = pipe->src_x +
+ ((pipe->src_y / 2) * pipe->srcp1_ystride);
+ break;
+
case MDP_Y_CRCB_H1V1:
case MDP_Y_CBCR_H1V1:
+ *luma_off = pipe->src_x +
+ (pipe->src_y * pipe->srcp0_ystride);
+ *chroma_off = pipe->src_x +
+ ((pipe->src_y * 2) * pipe->srcp1_ystride);
+ break;
+
case MDP_Y_CRCB_H2V1:
case MDP_Y_CBCR_H2V1:
case MDP_Y_CRCB_H1V2:
- *luma_off = pipe->src_x;
- *chroma_off = pipe->src_x;
+ *luma_off = pipe->src_x +
+ (pipe->src_y * pipe->srcp0_ystride);
+ *chroma_off = pipe->src_x +
+ (pipe->src_y * pipe->srcp1_ystride);
break;
case MDP_YCRYCB_H2V1:
if (pipe->src_x & 0x1)
pipe->src_x += 1;
- *luma_off += pipe->src_x * 2;
+ *luma_off += pipe->src_x * 2 +
+ ((pipe->src_y * 2) * pipe->srcp0_ystride);
break;
case MDP_ARGB_8888:
@@ -778,7 +794,8 @@
case MDP_RGB_888:
case MDP_YCBCR_H1V1:
case MDP_YCRCB_H1V1:
- *luma_off = pipe->src_x * pipe->bpp;
+ *luma_off = (pipe->src_x * pipe->bpp) +
+ (pipe->src_y * pipe->srcp0_ystride);
break;
default:
@@ -1619,6 +1636,8 @@
data |= stage;
}
+ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+ mdp_clk_ctrl(1);
mdp4_mixer_blend_setup(mixer);
off = 0;
@@ -1638,7 +1657,6 @@
mixer, data, ctrl->flush[mixer], current->pid);
}
- mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
local_irq_save(flags);
if (off)
outpdw(MDP_BASE + off, data);
@@ -1649,6 +1667,7 @@
}
local_irq_restore(flags);
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+ mdp_clk_ctrl(0);
}
@@ -2314,6 +2333,18 @@
return -ERANGE;
}
+ if (mdp_rev <= MDP_REV_41) {
+ if ((mdp4_overlay_format2type(req->src.format) ==
+ OVERLAY_TYPE_RGB) &&
+ !(req->flags & MDP_OV_PIPE_SHARE) &&
+ ((req->src_rect.w > req->dst_rect.w) ||
+ (req->src_rect.h > req->dst_rect.h))) {
+ mdp4_stat.err_size++;
+ pr_err("%s: downscale on RGB pipe!\n", __func__);
+ return -EINVAL;
+ }
+ }
+
if (mdp_hw_revision == MDP4_REVISION_V1) {
/* non integer down saceling ratio smaller than 1/4
* is not supportted
diff --git a/drivers/video/msm/mdp4_overlay_atv.c b/drivers/video/msm/mdp4_overlay_atv.c
index e67b244..90c3da9 100644
--- a/drivers/video/msm/mdp4_overlay_atv.c
+++ b/drivers/video/msm/mdp4_overlay_atv.c
@@ -184,6 +184,8 @@
} else {
pipe->srcp0_addr = (uint32)(buf + buf_offset);
}
+ mdp_update_pm(mfd, vsync_ctrl_db[0].vsync_time);
+
mdp4_overlay_mdp_perf_req(pipe, mfd);
mdp4_overlay_mdp_perf_upd(mfd, 1);
mdp4_overlay_rgb_setup(pipe);
diff --git a/drivers/video/msm/mdp4_overlay_dsi_cmd.c b/drivers/video/msm/mdp4_overlay_dsi_cmd.c
index 3320d11..488f2af 100644
--- a/drivers/video/msm/mdp4_overlay_dsi_cmd.c
+++ b/drivers/video/msm/mdp4_overlay_dsi_cmd.c
@@ -39,7 +39,7 @@
static int vsync_start_y_adjust = 4;
#define MAX_CONTROLLER 1
-#define VSYNC_EXPIRE_TICK 8
+#define VSYNC_EXPIRE_TICK 4
static struct vsycn_ctrl {
struct device *dev;
@@ -54,11 +54,12 @@
uint32 rdptr_intr_tot;
uint32 rdptr_sirq_tot;
atomic_t suspend;
+ atomic_t vsync_resume;
int wait_vsync_cnt;
int blt_change;
int blt_free;
int blt_end;
- int uevent;
+ int sysfs_created;
struct mutex update_lock;
struct completion ov_comp;
struct completion dmap_comp;
@@ -72,7 +73,6 @@
int clk_control;
int new_update;
ktime_t vsync_time;
- struct work_struct vsync_work;
struct work_struct clk_work;
} vsync_ctrl_db[MAX_CONTROLLER];
@@ -384,7 +384,6 @@
void mdp4_dsi_cmd_vsync_ctrl(struct fb_info *info, int enable)
{
- struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
struct vsycn_ctrl *vctrl;
unsigned long flags;
int clk_set_on = 0;
@@ -415,24 +414,23 @@
spin_lock_irqsave(&vctrl->spin_lock, flags);
vctrl->clk_control = 0;
vctrl->expire_tick = 0;
- vctrl->uevent = 1;
vctrl->new_update = 1;
if (clk_set_on) {
vsync_irq_enable(INTR_PRIMARY_RDPTR,
MDP_PRIM_RDPTR_TERM);
}
spin_unlock_irqrestore(&vctrl->spin_lock, flags);
-
- mdp4_overlay_update_dsi_cmd(mfd);
} else {
spin_lock_irqsave(&vctrl->spin_lock, flags);
vctrl->clk_control = 1;
- vctrl->uevent = 0;
if (vctrl->clk_enabled)
vctrl->expire_tick = VSYNC_EXPIRE_TICK;
spin_unlock_irqrestore(&vctrl->spin_lock, flags);
}
mutex_unlock(&vctrl->update_lock);
+
+ if (vctrl->vsync_enabled && atomic_read(&vctrl->suspend) == 0)
+ atomic_set(&vctrl->vsync_resume, 1);
}
void mdp4_dsi_cmd_wait4vsync(int cndx, long long *vtime)
@@ -515,13 +513,9 @@
vctrl->vsync_time = ktime_get();
spin_lock(&vctrl->spin_lock);
- if (vctrl->uevent)
- schedule_work(&vctrl->vsync_work);
- if (vctrl->wait_vsync_cnt) {
- complete(&vctrl->vsync_comp);
- vctrl->wait_vsync_cnt = 0;
- }
+ complete_all(&vctrl->vsync_comp);
+ vctrl->wait_vsync_cnt = 0;
if (vctrl->expire_tick) {
vctrl->expire_tick--;
@@ -636,21 +630,35 @@
mutex_unlock(&vctrl->update_lock);
}
-static void send_vsync_work(struct work_struct *work)
+static ssize_t vsync_show_event(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
- struct vsycn_ctrl *vctrl =
- container_of(work, typeof(*vctrl), vsync_work);
- char buf[64];
- char *envp[2];
+ int cndx;
+ struct vsycn_ctrl *vctrl;
+ ssize_t ret = 0;
+ unsigned long flags;
- snprintf(buf, sizeof(buf), "VSYNC=%llu",
+ cndx = 0;
+ vctrl = &vsync_ctrl_db[0];
+
+ if (atomic_read(&vctrl->suspend) > 0 ||
+ atomic_read(&vctrl->vsync_resume) == 0)
+ return 0;
+
+ spin_lock_irqsave(&vctrl->spin_lock, flags);
+ if (vctrl->wait_vsync_cnt == 0)
+ INIT_COMPLETION(vctrl->vsync_comp);
+ vctrl->wait_vsync_cnt++;
+ spin_unlock_irqrestore(&vctrl->spin_lock, flags);
+
+ wait_for_completion(&vctrl->vsync_comp);
+
+ ret = snprintf(buf, PAGE_SIZE, "VSYNC=%llu",
ktime_to_ns(vctrl->vsync_time));
- envp[0] = buf;
- envp[1] = NULL;
- kobject_uevent_env(&vctrl->dev->kobj, KOBJ_CHANGE, envp);
+ buf[strlen(buf) + 1] = '\0';
+ return ret;
}
-
void mdp4_dsi_rdptr_init(int cndx)
{
struct vsycn_ctrl *vctrl;
@@ -671,7 +679,7 @@
init_completion(&vctrl->dmap_comp);
init_completion(&vctrl->vsync_comp);
spin_lock_init(&vctrl->spin_lock);
- INIT_WORK(&vctrl->vsync_work, send_vsync_work);
+ atomic_set(&vctrl->vsync_resume, 1);
INIT_WORK(&vctrl->clk_work, clk_ctrl_work);
}
@@ -952,6 +960,14 @@
mdp4_dsi_cmd_do_blt(mfd, req->enable);
}
+static DEVICE_ATTR(vsync_event, S_IRUGO, vsync_show_event, NULL);
+static struct attribute *vsync_fs_attrs[] = {
+ &dev_attr_vsync_event.attr,
+ NULL,
+};
+static struct attribute_group vsync_fs_attr_group = {
+ .attrs = vsync_fs_attrs,
+};
int mdp4_dsi_cmd_on(struct platform_device *pdev)
{
int ret = 0;
@@ -976,6 +992,19 @@
atomic_set(&vctrl->suspend, 0);
pr_debug("%s-:\n", __func__);
+ if (!vctrl->sysfs_created) {
+ ret = sysfs_create_group(&vctrl->dev->kobj,
+ &vsync_fs_attr_group);
+ if (ret) {
+ pr_err("%s: sysfs group creation failed, ret=%d\n",
+ __func__, ret);
+ return ret;
+ }
+
+ kobject_uevent(&vctrl->dev->kobj, KOBJ_ADD);
+ pr_debug("%s: kobject_uevent(KOBJ_ADD)\n", __func__);
+ vctrl->sysfs_created = 1;
+ }
return ret;
}
@@ -1000,6 +1029,9 @@
}
atomic_set(&vctrl->suspend, 1);
+ atomic_set(&vctrl->vsync_resume, 0);
+
+ complete_all(&vctrl->vsync_comp);
/* sanity check, free pipes besides base layer */
mdp4_overlay_unset_mixer(pipe->mixer_num);
@@ -1020,7 +1052,6 @@
vctrl->vsync_enabled = 0;
vctrl->clk_control = 0;
vctrl->expire_tick = 0;
- vctrl->uevent = 0;
vsync_irq_disable(INTR_PRIMARY_RDPTR, MDP_PRIM_RDPTR_TERM);
@@ -1068,7 +1099,6 @@
struct vsycn_ctrl *vctrl;
struct mdp4_overlay_pipe *pipe;
unsigned long flags;
- long long xx;
vctrl = &vsync_ctrl_db[cndx];
@@ -1112,7 +1142,5 @@
mdp4_dsi_cmd_pipe_commit();
mutex_unlock(&mfd->dma->ov_mutex);
- mdp4_dsi_cmd_wait4vsync(0, &xx);
-
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 2d21929..6c9edb5 100644
--- a/drivers/video/msm/mdp4_overlay_dsi_video.c
+++ b/drivers/video/msm/mdp4_overlay_dsi_video.c
@@ -52,10 +52,11 @@
int ov_koff;
int ov_done;
atomic_t suspend;
+ atomic_t vsync_resume;
int wait_vsync_cnt;
int blt_change;
int blt_free;
- int fake_vsync;
+ int sysfs_created;
struct mutex update_lock;
struct completion ov_comp;
struct completion dmap_comp;
@@ -66,7 +67,6 @@
struct vsync_update vlist[2];
int vsync_irq_enabled;
ktime_t vsync_time;
- struct work_struct vsync_work;
} vsync_ctrl_db[MAX_CONTROLLER];
static void vsync_irq_enable(int intr, int term)
@@ -263,11 +263,6 @@
vctrl = &vsync_ctrl_db[cndx];
- if (vctrl->fake_vsync) {
- vctrl->fake_vsync = 0;
- schedule_work(&vctrl->vsync_work);
- }
-
if (vctrl->vsync_irq_enabled == enable)
return;
@@ -279,6 +274,9 @@
vsync_irq_enable(INTR_PRIMARY_VSYNC, MDP_PRIM_VSYNC_TERM);
else
vsync_irq_disable(INTR_PRIMARY_VSYNC, MDP_PRIM_VSYNC_TERM);
+
+ if (vctrl->vsync_irq_enabled && atomic_read(&vctrl->suspend) == 0)
+ atomic_set(&vctrl->vsync_resume, 1);
}
void mdp4_dsi_video_wait4vsync(int cndx, long long *vtime)
@@ -350,7 +348,6 @@
vsync_irq_enable(INTR_DMA_P_DONE, MDP_DMAP_TERM);
spin_unlock_irqrestore(&vctrl->spin_lock, flags);
mdp4_dsi_video_wait4dmap(cndx);
- vsync_irq_disable(INTR_DMA_P_DONE, MDP_DMAP_TERM);
}
@@ -371,18 +368,32 @@
wait_for_completion(&vctrl->ov_comp);
}
-static void send_vsync_work(struct work_struct *work)
+static ssize_t vsync_show_event(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
- struct vsycn_ctrl *vctrl =
- container_of(work, typeof(*vctrl), vsync_work);
- char buf[64];
- char *envp[2];
+ int cndx;
+ struct vsycn_ctrl *vctrl;
+ ssize_t ret = 0;
+ unsigned long flags;
- snprintf(buf, sizeof(buf), "VSYNC=%llu",
+ cndx = 0;
+ vctrl = &vsync_ctrl_db[0];
+
+ if (atomic_read(&vctrl->suspend) > 0 ||
+ atomic_read(&vctrl->vsync_resume) == 0)
+ return 0;
+
+ spin_lock_irqsave(&vctrl->spin_lock, flags);
+ if (vctrl->wait_vsync_cnt == 0)
+ INIT_COMPLETION(vctrl->vsync_comp);
+ vctrl->wait_vsync_cnt++;
+ spin_unlock_irqrestore(&vctrl->spin_lock, flags);
+ wait_for_completion(&vctrl->vsync_comp);
+
+ ret = snprintf(buf, PAGE_SIZE, "VSYNC=%llu",
ktime_to_ns(vctrl->vsync_time));
- envp[0] = buf;
- envp[1] = NULL;
- kobject_uevent_env(&vctrl->dev->kobj, KOBJ_CHANGE, envp);
+ buf[strlen(buf) + 1] = '\0';
+ return ret;
}
void mdp4_dsi_vsync_init(int cndx)
@@ -407,8 +418,8 @@
init_completion(&vctrl->dmap_comp);
init_completion(&vctrl->ov_comp);
atomic_set(&vctrl->suspend, 0);
+ atomic_set(&vctrl->vsync_resume, 1);
spin_lock_init(&vctrl->spin_lock);
- INIT_WORK(&vctrl->vsync_work, send_vsync_work);
}
void mdp4_dsi_video_base_swap(int cndx, struct mdp4_overlay_pipe *pipe)
@@ -424,6 +435,16 @@
vctrl->base_pipe = pipe;
}
+static DEVICE_ATTR(vsync_event, S_IRUGO, vsync_show_event, NULL);
+
+static struct attribute *vsync_fs_attrs[] = {
+ &dev_attr_vsync_event.attr,
+ NULL,
+};
+
+static struct attribute_group vsync_fs_attr_group = {
+ .attrs = vsync_fs_attrs,
+};
int mdp4_dsi_video_on(struct platform_device *pdev)
{
int dsi_width;
@@ -478,7 +499,6 @@
vctrl->mfd = mfd;
vctrl->dev = mfd->fbi->dev;
- vctrl->fake_vsync = 1;
/* mdp clock on */
mdp_clk_ctrl(1);
@@ -522,6 +542,9 @@
mdp4_dsi_video_wait4dmap_done(0);
MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE, 0);
mipi_dsi_controller_cfg(0);
+ /* Clks are enabled in probe.
+ Disabling clocks now */
+ mdp_clk_ctrl(0);
}
pipe->src_height = fbi->var.yres;
@@ -634,6 +657,21 @@
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
mdp_histogram_ctrl_all(TRUE);
+
+ if (!vctrl->sysfs_created) {
+ ret = sysfs_create_group(&vctrl->dev->kobj,
+ &vsync_fs_attr_group);
+ if (ret) {
+ pr_err("%s: sysfs group creation failed, ret=%d\n",
+ __func__, ret);
+ return ret;
+ }
+
+ kobject_uevent(&vctrl->dev->kobj, KOBJ_ADD);
+ pr_debug("%s: kobject_uevent(KOBJ_ADD)\n", __func__);
+ vctrl->sysfs_created = 1;
+ }
+
return ret;
}
@@ -652,9 +690,12 @@
pipe = vctrl->base_pipe;
atomic_set(&vctrl->suspend, 1);
+ atomic_set(&vctrl->vsync_resume, 0);
msleep(20); /* >= 17 ms */
+ complete_all(&vctrl->vsync_comp);
+
if (pipe->ov_blt_addr) {
spin_lock_irqsave(&vctrl->spin_lock, flags);
if (vctrl->ov_koff != vctrl->ov_done)
@@ -670,6 +711,11 @@
dsi_video_enabled = 0;
+ if (vctrl->vsync_irq_enabled) {
+ vctrl->vsync_irq_enabled = 0;
+ vsync_irq_disable(INTR_PRIMARY_VSYNC, MDP_PRIM_VSYNC_TERM);
+ }
+
if (pipe) {
/* sanity check, free pipes besides base layer */
mdp4_overlay_unset_mixer(pipe->mixer_num);
@@ -691,8 +737,6 @@
}
}
- vctrl->fake_vsync = 1;
-
/* mdp clock off */
mdp_clk_ctrl(0);
mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
@@ -857,7 +901,6 @@
vctrl = &vsync_ctrl_db[cndx];
pr_debug("%s: cpu=%d\n", __func__, smp_processor_id());
vctrl->vsync_time = ktime_get();
- schedule_work(&vctrl->vsync_work);
spin_lock(&vctrl->spin_lock);
if (vctrl->wait_vsync_cnt) {
@@ -1028,6 +1071,7 @@
mdp4_dsi_video_pipe_queue(0, pipe);
}
+ mdp_update_pm(mfd, vsync_ctrl_db[0].vsync_time);
mdp4_overlay_mdp_perf_upd(mfd, 1);
mutex_lock(&mfd->dma->ov_mutex);
diff --git a/drivers/video/msm/mdp4_overlay_dtv.c b/drivers/video/msm/mdp4_overlay_dtv.c
index f01543b..a89b5be 100644
--- a/drivers/video/msm/mdp4_overlay_dtv.c
+++ b/drivers/video/msm/mdp4_overlay_dtv.c
@@ -29,6 +29,7 @@
#include "mdp.h"
#include "msm_fb.h"
+#include "hdmi_msm.h"
#include "mdp4.h"
#define DTV_BASE 0xD0000
@@ -70,10 +71,11 @@
int update_ndx;
int dmae_intr_cnt;
atomic_t suspend;
+ atomic_t vsync_resume;
int dmae_wait_cnt;
int wait_vsync_cnt;
int blt_change;
- int fake_vsync;
+ int sysfs_created;
struct mutex update_lock;
struct completion ov_comp;
struct completion dmae_comp;
@@ -83,7 +85,6 @@
struct vsync_update vlist[2];
int vsync_irq_enabled;
ktime_t vsync_time;
- struct work_struct vsync_work;
} vsync_ctrl_db[MAX_CONTROLLER];
static void vsync_irq_enable(int intr, int term)
@@ -245,10 +246,8 @@
vctrl = &vsync_ctrl_db[cndx];
- if (vctrl->fake_vsync) {
- vctrl->fake_vsync = 0;
- schedule_work(&vctrl->vsync_work);
- }
+ if (!external_common_state->hpd_state)
+ complete_all(&vctrl->vsync_comp);
if (vctrl->vsync_irq_enabled == enable)
return;
@@ -261,6 +260,9 @@
vsync_irq_enable(INTR_EXTERNAL_VSYNC, MDP_EXTER_VSYNC_TERM);
else
vsync_irq_disable(INTR_EXTERNAL_VSYNC, MDP_EXTER_VSYNC_TERM);
+
+ if (vctrl->vsync_irq_enabled && atomic_read(&vctrl->suspend) == 0)
+ atomic_set(&vctrl->vsync_resume, 1);
}
void mdp4_dtv_wait4vsync(int cndx, long long *vtime)
@@ -310,20 +312,34 @@
wait_for_completion(&vctrl->dmae_comp);
}
-static void send_vsync_work(struct work_struct *work)
+static ssize_t vsync_show_event(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
- struct vsycn_ctrl *vctrl =
- container_of(work, typeof(*vctrl), vsync_work);
- char buf[64];
- char *envp[2];
+ int cndx;
+ struct vsycn_ctrl *vctrl;
+ ssize_t ret = 0;
+ unsigned long flags;
- snprintf(buf, sizeof(buf), "VSYNC=%llu",
+ cndx = 0;
+ vctrl = &vsync_ctrl_db[0];
+
+ if (atomic_read(&vctrl->suspend) > 0 ||
+ !external_common_state->hpd_state ||
+ atomic_read(&vctrl->vsync_resume) == 0)
+ return 0;
+
+ spin_lock_irqsave(&vctrl->spin_lock, flags);
+ if (vctrl->wait_vsync_cnt == 0)
+ INIT_COMPLETION(vctrl->vsync_comp);
+ vctrl->wait_vsync_cnt++;
+ spin_unlock_irqrestore(&vctrl->spin_lock, flags);
+ wait_for_completion(&vctrl->vsync_comp);
+
+ ret = snprintf(buf, PAGE_SIZE, "VSYNC=%llu",
ktime_to_ns(vctrl->vsync_time));
- envp[0] = buf;
- envp[1] = NULL;
- kobject_uevent_env(&vctrl->dev->kobj, KOBJ_CHANGE, envp);
+ buf[strlen(buf) + 1] = '\0';
+ return ret;
}
-
void mdp4_dtv_vsync_init(int cndx)
{
struct vsycn_ctrl *vctrl;
@@ -346,8 +362,8 @@
init_completion(&vctrl->ov_comp);
init_completion(&vctrl->dmae_comp);
atomic_set(&vctrl->suspend, 0);
+ atomic_set(&vctrl->vsync_resume, 1);
spin_lock_init(&vctrl->spin_lock);
- INIT_WORK(&vctrl->vsync_work, send_vsync_work);
}
static int mdp4_dtv_start(struct msm_fb_data_type *mfd)
@@ -506,6 +522,15 @@
return 0;
}
+static DEVICE_ATTR(vsync_event, S_IRUGO, vsync_show_event, NULL);
+static struct attribute *vsync_fs_attrs[] = {
+ &dev_attr_vsync_event.attr,
+ NULL,
+};
+static struct attribute_group vsync_fs_attr_group = {
+ .attrs = vsync_fs_attrs,
+};
+
int mdp4_dtv_on(struct platform_device *pdev)
{
struct msm_fb_data_type *mfd;
@@ -524,7 +549,6 @@
return -EINVAL;
vctrl->dev = mfd->fbi->dev;
- vctrl->fake_vsync = 1;
mdp_footswitch_ctrl(TRUE);
/* Mdp clock enable */
@@ -547,6 +571,19 @@
atomic_set(&vctrl->suspend, 0);
+ if (!vctrl->sysfs_created) {
+ ret = sysfs_create_group(&vctrl->dev->kobj,
+ &vsync_fs_attr_group);
+ if (ret) {
+ pr_err("%s: sysfs group creation failed, ret=%d\n",
+ __func__, ret);
+ return ret;
+ }
+
+ kobject_uevent(&vctrl->dev->kobj, KOBJ_ADD);
+ pr_debug("%s: kobject_uevent(KOBJ_ADD)\n", __func__);
+ vctrl->sysfs_created = 1;
+ }
pr_info("%s:\n", __func__);
return ret;
@@ -565,9 +602,14 @@
vctrl = &vsync_ctrl_db[cndx];
atomic_set(&vctrl->suspend, 1);
+ atomic_set(&vctrl->vsync_resume, 0);
- while (vctrl->wait_vsync_cnt)
- msleep(20); /* >= 17 ms */
+ if (vctrl->vsync_irq_enabled) {
+ while (vctrl->wait_vsync_cnt)
+ msleep(20); /* >= 17 ms */
+ }
+
+ complete_all(&vctrl->vsync_comp);
pipe = vctrl->base_pipe;
if (pipe != NULL) {
@@ -594,9 +636,13 @@
mdp4_overlay_panel_mode_unset(MDP4_MIXER1, MDP4_PANEL_DTV);
+ if (vctrl->vsync_irq_enabled) {
+ vctrl->vsync_irq_enabled = 0;
+ vsync_irq_disable(INTR_PRIMARY_VSYNC, MDP_PRIM_VSYNC_TERM);
+ }
+
ret = panel_next_off(pdev);
mdp_footswitch_ctrl(FALSE);
- vctrl->fake_vsync = 1;
/* Mdp clock disable */
mdp_clk_ctrl(0);
@@ -795,7 +841,6 @@
vctrl = &vsync_ctrl_db[cndx];
pr_debug("%s: cpu=%d\n", __func__, smp_processor_id());
vctrl->vsync_time = ktime_get();
- schedule_work(&vctrl->vsync_work);
spin_lock(&vctrl->spin_lock);
if (vctrl->wait_vsync_cnt) {
@@ -1011,6 +1056,7 @@
pipe->srcp0_addr = (uint32)mfd->ibuf.buf;
mdp4_dtv_pipe_queue(0, pipe);
}
+ mdp_update_pm(mfd, vsync_ctrl_db[0].vsync_time);
mutex_lock(&mfd->dma->ov_mutex);
mdp4_overlay_mdp_perf_upd(mfd, 1);
diff --git a/drivers/video/msm/mdp4_overlay_lcdc.c b/drivers/video/msm/mdp4_overlay_lcdc.c
index bc8ded5..78c69b8 100644
--- a/drivers/video/msm/mdp4_overlay_lcdc.c
+++ b/drivers/video/msm/mdp4_overlay_lcdc.c
@@ -53,10 +53,11 @@
int ov_koff;
int ov_done;
atomic_t suspend;
+ atomic_t vsync_resume;
int wait_vsync_cnt;
int blt_change;
int blt_free;
- int fake_vsync;
+ int sysfs_created;
struct mutex update_lock;
struct completion ov_comp;
struct completion dmap_comp;
@@ -67,7 +68,6 @@
struct vsync_update vlist[2];
int vsync_irq_enabled;
ktime_t vsync_time;
- struct work_struct vsync_work;
} vsync_ctrl_db[MAX_CONTROLLER];
@@ -267,11 +267,6 @@
vctrl = &vsync_ctrl_db[cndx];
- if (vctrl->fake_vsync) {
- vctrl->fake_vsync = 0;
- schedule_work(&vctrl->vsync_work);
- }
-
if (vctrl->vsync_irq_enabled == enable)
return;
@@ -283,6 +278,9 @@
vsync_irq_enable(INTR_PRIMARY_VSYNC, MDP_PRIM_VSYNC_TERM);
else
vsync_irq_disable(INTR_PRIMARY_VSYNC, MDP_PRIM_VSYNC_TERM);
+
+ if (vctrl->vsync_irq_enabled && atomic_read(&vctrl->suspend) == 0)
+ atomic_set(&vctrl->vsync_resume, 1);
}
void mdp4_lcdc_wait4vsync(int cndx, long long *vtime)
@@ -354,18 +352,32 @@
wait_for_completion(&vctrl->ov_comp);
}
-static void send_vsync_work(struct work_struct *work)
+static ssize_t vsync_show_event(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
- struct vsycn_ctrl *vctrl =
- container_of(work, typeof(*vctrl), vsync_work);
- char buf[64];
- char *envp[2];
+ int cndx;
+ struct vsycn_ctrl *vctrl;
+ ssize_t ret = 0;
+ unsigned long flags;
- snprintf(buf, sizeof(buf), "VSYNC=%llu",
- ktime_to_ns(vctrl->vsync_time));
- envp[0] = buf;
- envp[1] = NULL;
- kobject_uevent_env(&vctrl->dev->kobj, KOBJ_CHANGE, envp);
+ cndx = 0;
+ vctrl = &vsync_ctrl_db[0];
+
+ if (atomic_read(&vctrl->suspend) > 0 ||
+ atomic_read(&vctrl->vsync_resume) == 0)
+ return 0;
+
+ spin_lock_irqsave(&vctrl->spin_lock, flags);
+ if (vctrl->wait_vsync_cnt == 0)
+ INIT_COMPLETION(vctrl->vsync_comp);
+ vctrl->wait_vsync_cnt++;
+ spin_unlock_irqrestore(&vctrl->spin_lock, flags);
+ wait_for_completion(&vctrl->vsync_comp);
+
+ ret = snprintf(buf, PAGE_SIZE, "VSYNC=%llu",
+ ktime_to_ns(vctrl->vsync_time));
+ buf[strlen(buf) + 1] = '\0';
+ return ret;
}
void mdp4_lcdc_vsync_init(int cndx)
@@ -390,8 +402,8 @@
init_completion(&vctrl->dmap_comp);
init_completion(&vctrl->ov_comp);
atomic_set(&vctrl->suspend, 0);
+ atomic_set(&vctrl->vsync_resume, 1);
spin_lock_init(&vctrl->spin_lock);
- INIT_WORK(&vctrl->vsync_work, send_vsync_work);
}
void mdp4_lcdc_base_swap(int cndx, struct mdp4_overlay_pipe *pipe)
@@ -407,6 +419,15 @@
vctrl->base_pipe = pipe;
}
+static DEVICE_ATTR(vsync_event, S_IRUGO, vsync_show_event, NULL);
+static struct attribute *vsync_fs_attrs[] = {
+ &dev_attr_vsync_event.attr,
+ NULL,
+};
+static struct attribute_group vsync_fs_attr_group = {
+ .attrs = vsync_fs_attrs,
+};
+
int mdp4_lcdc_on(struct platform_device *pdev)
{
int lcdc_width;
@@ -461,7 +482,6 @@
vctrl->mfd = mfd;
vctrl->dev = mfd->fbi->dev;
- vctrl->fake_vsync = 1;
/* mdp clock on */
mdp_clk_ctrl(1);
@@ -621,6 +641,21 @@
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
mdp_histogram_ctrl_all(TRUE);
+
+ if (!vctrl->sysfs_created) {
+ ret = sysfs_create_group(&vctrl->dev->kobj,
+ &vsync_fs_attr_group);
+ if (ret) {
+ pr_err("%s: sysfs group creation failed, ret=%d\n",
+ __func__, ret);
+ return ret;
+ }
+
+ kobject_uevent(&vctrl->dev->kobj, KOBJ_ADD);
+ pr_debug("%s: kobject_uevent(KOBJ_ADD)\n", __func__);
+ vctrl->sysfs_created = 1;
+ }
+
return ret;
}
@@ -639,9 +674,12 @@
pipe = vctrl->base_pipe;
atomic_set(&vctrl->suspend, 1);
+ atomic_set(&vctrl->vsync_resume, 0);
msleep(20); /* >= 17 ms */
+ complete_all(&vctrl->vsync_comp);
+
if (pipe->ov_blt_addr) {
spin_lock_irqsave(&vctrl->spin_lock, flags);
if (vctrl->ov_koff != vctrl->ov_done)
@@ -657,6 +695,11 @@
lcdc_enabled = 0;
+ if (vctrl->vsync_irq_enabled) {
+ vctrl->vsync_irq_enabled = 0;
+ vsync_irq_disable(INTR_PRIMARY_VSYNC, MDP_PRIM_VSYNC_TERM);
+ }
+
if (pipe) {
/* sanity check, free pipes besides base layer */
mdp4_overlay_unset_mixer(pipe->mixer_num);
@@ -678,8 +721,6 @@
}
}
- vctrl->fake_vsync = 1;
-
/* MDP clock disable */
mdp_clk_ctrl(0);
mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
@@ -746,7 +787,6 @@
vctrl = &vsync_ctrl_db[cndx];
pr_debug("%s: cpu=%d\n", __func__, smp_processor_id());
vctrl->vsync_time = ktime_get();
- schedule_work(&vctrl->vsync_work);
spin_lock(&vctrl->spin_lock);
if (vctrl->wait_vsync_cnt) {
@@ -917,6 +957,7 @@
mdp4_lcdc_pipe_queue(0, pipe);
}
+ mdp_update_pm(mfd, vsync_ctrl_db[0].vsync_time);
mdp4_overlay_mdp_perf_upd(mfd, 1);
diff --git a/drivers/video/msm/mdp4_util.c b/drivers/video/msm/mdp4_util.c
index b35acfb..80ef22a 100644
--- a/drivers/video/msm/mdp4_util.c
+++ b/drivers/video/msm/mdp4_util.c
@@ -2309,7 +2309,7 @@
pr_info("%s:%d ion based allocation mfd->mem_hid 0x%x\n",
__func__, __LINE__, mfd->mem_hid);
buf->ihdl = ion_alloc(mfd->iclient, buffer_size, SZ_4K,
- mfd->mem_hid);
+ mfd->mem_hid, 0);
if (!IS_ERR_OR_NULL(buf->ihdl)) {
if (mdp_iommu_split_domain) {
if (ion_map_iommu(mfd->iclient, buf->ihdl,
diff --git a/drivers/video/msm/mdp_dma.c b/drivers/video/msm/mdp_dma.c
index 4b76e72..4d4b05f 100644
--- a/drivers/video/msm/mdp_dma.c
+++ b/drivers/video/msm/mdp_dma.c
@@ -482,10 +482,22 @@
#endif
{
unsigned long flag;
+ static int first_vsync;
+ int need_wait = 0;
down(&mfd->dma->mutex);
- if ((mfd) && (!mfd->dma->busy) && (mfd->panel_power_on)) {
+ if ((mfd) && (mfd->panel_power_on)) {
down(&mfd->sem);
+ spin_lock_irqsave(&mdp_spin_lock, flag);
+ if (mfd->dma->busy == TRUE)
+ need_wait++;
+ spin_unlock_irqrestore(&mdp_spin_lock, flag);
+
+ if (need_wait)
+ wait_for_completion_killable(&mfd->dma->comp);
+
+ /* schedule DMA to start */
+ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
mfd->ibuf_flushed = TRUE;
mdp_dma2_update_lcd(mfd);
@@ -493,15 +505,31 @@
mdp_enable_irq(MDP_DMA2_TERM);
mfd->dma->busy = TRUE;
INIT_COMPLETION(mfd->dma->comp);
-
+ INIT_COMPLETION(vsync_cntrl.vsync_comp);
+ if (!vsync_cntrl.vsync_irq_enabled &&
+ vsync_cntrl.disabled_clocks) {
+ MDP_OUTP(MDP_BASE + 0x021c, 0x10); /* read pointer */
+ outp32(MDP_INTR_CLEAR, MDP_PRIM_RDPTR);
+ mdp_intr_mask |= MDP_PRIM_RDPTR;
+ outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+ mdp_enable_irq(MDP_VSYNC_TERM);
+ vsync_cntrl.vsync_dma_enabled = 1;
+ }
spin_unlock_irqrestore(&mdp_spin_lock, flag);
/* schedule DMA to start */
mdp_dma_schedule(mfd, MDP_DMA2_TERM);
up(&mfd->sem);
- /* wait until DMA finishes the current job */
- wait_for_completion_killable(&mfd->dma->comp);
- mdp_disable_irq(MDP_DMA2_TERM);
+ /* wait until Vsync finishes the current job */
+ if (first_vsync) {
+ if (!wait_for_completion_killable_timeout
+ (&vsync_cntrl.vsync_comp, HZ/10))
+ pr_err("Timedout DMA %s %d", __func__,
+ __LINE__);
+ } else {
+ first_vsync = 1;
+ }
+ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
/* signal if pan function is waiting for the update completion */
if (mfd->pan_waiting) {
@@ -515,28 +543,37 @@
void mdp_dma_vsync_ctrl(int enable)
{
unsigned long flag;
+ int disabled_clocks;
if (vsync_cntrl.vsync_irq_enabled == enable)
return;
spin_lock_irqsave(&mdp_spin_lock, flag);
if (!enable)
INIT_COMPLETION(vsync_cntrl.vsync_wait);
+
vsync_cntrl.vsync_irq_enabled = enable;
+ disabled_clocks = vsync_cntrl.disabled_clocks;
spin_unlock_irqrestore(&mdp_spin_lock, flag);
- if (enable) {
+ if (enable && disabled_clocks)
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
+ spin_lock_irqsave(&mdp_spin_lock, flag);
+ if (enable && vsync_cntrl.disabled_clocks &&
+ !vsync_cntrl.vsync_dma_enabled) {
MDP_OUTP(MDP_BASE + 0x021c, 0x10); /* read pointer */
- spin_lock_irqsave(&mdp_spin_lock, flag);
outp32(MDP_INTR_CLEAR, MDP_PRIM_RDPTR);
mdp_intr_mask |= MDP_PRIM_RDPTR;
outp32(MDP_INTR_ENABLE, mdp_intr_mask);
mdp_enable_irq(MDP_VSYNC_TERM);
- spin_unlock_irqrestore(&mdp_spin_lock, flag);
- } else {
- wait_for_completion(&vsync_cntrl.vsync_wait);
- mdp_disable_irq(MDP_VSYNC_TERM);
+ vsync_cntrl.disabled_clocks = 0;
+ } else if (enable && vsync_cntrl.disabled_clocks) {
+ vsync_cntrl.disabled_clocks = 0;
}
+ spin_unlock_irqrestore(&mdp_spin_lock, flag);
+ if (vsync_cntrl.vsync_irq_enabled &&
+ atomic_read(&vsync_cntrl.suspend) == 0)
+ atomic_set(&vsync_cntrl.vsync_resume, 1);
}
void mdp_lcd_update_workqueue_handler(struct work_struct *work)
diff --git a/drivers/video/msm/mdp_dma_dsi_video.c b/drivers/video/msm/mdp_dma_dsi_video.c
index a1f2b65..e2fb8ba 100644
--- a/drivers/video/msm/mdp_dma_dsi_video.c
+++ b/drivers/video/msm/mdp_dma_dsi_video.c
@@ -34,6 +34,33 @@
static int first_pixel_start_x;
static int first_pixel_start_y;
+static ssize_t vsync_show_event(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ ssize_t ret = 0;
+
+ INIT_COMPLETION(vsync_cntrl.vsync_wait);
+
+ if (atomic_read(&vsync_cntrl.suspend) > 0 ||
+ atomic_read(&vsync_cntrl.vsync_resume) == 0)
+ return 0;
+
+ wait_for_completion(&vsync_cntrl.vsync_wait);
+ ret = snprintf(buf, PAGE_SIZE, "VSYNC=%llu",
+ ktime_to_ns(vsync_cntrl.vsync_time));
+ buf[strlen(buf) + 1] = '\0';
+ return ret;
+}
+
+static DEVICE_ATTR(vsync_event, S_IRUGO, vsync_show_event, NULL);
+static struct attribute *vsync_fs_attrs[] = {
+ &dev_attr_vsync_event.attr,
+ NULL,
+};
+static struct attribute_group vsync_fs_attr_group = {
+ .attrs = vsync_fs_attrs,
+};
+
int mdp_dsi_video_on(struct platform_device *pdev)
{
int dsi_width;
@@ -88,6 +115,7 @@
var = &fbi->var;
vsync_cntrl.dev = mfd->fbi->dev;
+ atomic_set(&vsync_cntrl.suspend, 0);
bpp = fbi->var.bits_per_pixel / 8;
buf = (uint8 *) fbi->fix.smem_start;
@@ -226,6 +254,20 @@
/* MDP cmd block disable */
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+ if (!vsync_cntrl.sysfs_created) {
+ ret = sysfs_create_group(&vsync_cntrl.dev->kobj,
+ &vsync_fs_attr_group);
+ if (ret) {
+ pr_err("%s: sysfs creation failed, ret=%d\n",
+ __func__, ret);
+ return ret;
+ }
+
+ kobject_uevent(&vsync_cntrl.dev->kobj, KOBJ_ADD);
+ pr_debug("%s: kobject_uevent(KOBJ_ADD)\n", __func__);
+ vsync_cntrl.sysfs_created = 1;
+ }
+
return ret;
}
@@ -241,6 +283,10 @@
mdp_pipe_ctrl(MDP_DMA2_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
ret = panel_next_off(pdev);
+
+ atomic_set(&vsync_cntrl.suspend, 1);
+ atomic_set(&vsync_cntrl.vsync_resume, 0);
+ complete_all(&vsync_cntrl.vsync_wait);
/* delay to make sure the last frame finishes */
msleep(20);
@@ -250,16 +296,21 @@
void mdp_dma_video_vsync_ctrl(int enable)
{
unsigned long flag;
+ int disabled_clocks;
if (vsync_cntrl.vsync_irq_enabled == enable)
return;
spin_lock_irqsave(&mdp_spin_lock, flag);
if (!enable)
INIT_COMPLETION(vsync_cntrl.vsync_wait);
+
vsync_cntrl.vsync_irq_enabled = enable;
+ if (!enable)
+ vsync_cntrl.disabled_clocks = 0;
+ disabled_clocks = vsync_cntrl.disabled_clocks;
spin_unlock_irqrestore(&mdp_spin_lock, flag);
- if (enable) {
+ if (enable && disabled_clocks) {
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
spin_lock_irqsave(&mdp_spin_lock, flag);
outp32(MDP_INTR_CLEAR, LCDC_FRAME_START);
@@ -267,10 +318,10 @@
outp32(MDP_INTR_ENABLE, mdp_intr_mask);
mdp_enable_irq(MDP_VSYNC_TERM);
spin_unlock_irqrestore(&mdp_spin_lock, flag);
- } else {
- wait_for_completion(&vsync_cntrl.vsync_wait);
- mdp_disable_irq(MDP_VSYNC_TERM);
}
+ if (vsync_cntrl.vsync_irq_enabled &&
+ atomic_read(&vsync_cntrl.suspend) == 0)
+ atomic_set(&vsync_cntrl.vsync_resume, 1);
}
void mdp_dsi_video_update(struct msm_fb_data_type *mfd)
diff --git a/drivers/video/msm/mdp_dma_lcdc.c b/drivers/video/msm/mdp_dma_lcdc.c
index 10d60ab..fbfe35f 100644
--- a/drivers/video/msm/mdp_dma_lcdc.c
+++ b/drivers/video/msm/mdp_dma_lcdc.c
@@ -51,6 +51,33 @@
int first_pixel_start_x;
int first_pixel_start_y;
+static ssize_t vsync_show_event(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ ssize_t ret = 0;
+
+ if (atomic_read(&vsync_cntrl.suspend) > 0 ||
+ atomic_read(&vsync_cntrl.vsync_resume) == 0)
+ return 0;
+
+ INIT_COMPLETION(vsync_cntrl.vsync_wait);
+
+ wait_for_completion(&vsync_cntrl.vsync_wait);
+ ret = snprintf(buf, PAGE_SIZE, "VSYNC=%llu",
+ ktime_to_ns(vsync_cntrl.vsync_time));
+ buf[strlen(buf) + 1] = '\0';
+ return ret;
+}
+
+static DEVICE_ATTR(vsync_event, S_IRUGO, vsync_show_event, NULL);
+static struct attribute *vsync_fs_attrs[] = {
+ &dev_attr_vsync_event.attr,
+ NULL,
+};
+static struct attribute_group vsync_fs_attr_group = {
+ .attrs = vsync_fs_attrs,
+};
+
int mdp_lcdc_on(struct platform_device *pdev)
{
int lcdc_width;
@@ -106,6 +133,7 @@
fbi = mfd->fbi;
var = &fbi->var;
vsync_cntrl.dev = mfd->fbi->dev;
+ atomic_set(&vsync_cntrl.suspend, 0);
/* MDP cmd block enable */
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
@@ -292,6 +320,20 @@
/* MDP cmd block disable */
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+ if (!vsync_cntrl.sysfs_created) {
+ ret = sysfs_create_group(&vsync_cntrl.dev->kobj,
+ &vsync_fs_attr_group);
+ if (ret) {
+ pr_err("%s: sysfs creation failed, ret=%d\n",
+ __func__, ret);
+ return ret;
+ }
+
+ kobject_uevent(&vsync_cntrl.dev->kobj, KOBJ_ADD);
+ pr_debug("%s: kobject_uevent(KOBJ_ADD)\n", __func__);
+ vsync_cntrl.sysfs_created = 1;
+ }
+
return ret;
}
@@ -321,6 +363,9 @@
ret = panel_next_off(pdev);
up(&mfd->dma->mutex);
+ atomic_set(&vsync_cntrl.suspend, 1);
+ atomic_set(&vsync_cntrl.vsync_resume, 0);
+ complete_all(&vsync_cntrl.vsync_wait);
/* delay to make sure the last frame finishes */
msleep(16);
@@ -331,16 +376,21 @@
void mdp_dma_lcdc_vsync_ctrl(int enable)
{
unsigned long flag;
+ int disabled_clocks;
if (vsync_cntrl.vsync_irq_enabled == enable)
return;
spin_lock_irqsave(&mdp_spin_lock, flag);
if (!enable)
INIT_COMPLETION(vsync_cntrl.vsync_wait);
+
vsync_cntrl.vsync_irq_enabled = enable;
+ if (!enable)
+ vsync_cntrl.disabled_clocks = 0;
+ disabled_clocks = vsync_cntrl.disabled_clocks;
spin_unlock_irqrestore(&mdp_spin_lock, flag);
- if (enable) {
+ if (enable && disabled_clocks) {
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
spin_lock_irqsave(&mdp_spin_lock, flag);
outp32(MDP_INTR_CLEAR, LCDC_FRAME_START);
@@ -348,10 +398,11 @@
outp32(MDP_INTR_ENABLE, mdp_intr_mask);
mdp_enable_irq(MDP_VSYNC_TERM);
spin_unlock_irqrestore(&mdp_spin_lock, flag);
- } else {
- wait_for_completion(&vsync_cntrl.vsync_wait);
- mdp_disable_irq(MDP_VSYNC_TERM);
}
+
+ if (vsync_cntrl.vsync_irq_enabled &&
+ atomic_read(&vsync_cntrl.suspend) == 0)
+ atomic_set(&vsync_cntrl.vsync_resume, 1);
}
void mdp_lcdc_update(struct msm_fb_data_type *mfd)
diff --git a/drivers/video/msm/mdss/mdss.h b/drivers/video/msm/mdss/mdss.h
index 758f074..3c60c2b 100644
--- a/drivers/video/msm/mdss/mdss.h
+++ b/drivers/video/msm/mdss/mdss.h
@@ -24,8 +24,6 @@
#define MDSS_REG_WRITE(addr, val) writel_relaxed(val, mdss_res->mdp_base + addr)
#define MDSS_REG_READ(addr) readl_relaxed(mdss_res->mdp_base + addr)
-extern spinlock_t dsi_clk_lock;
-
enum mdss_mdp_clk_type {
MDSS_CLK_AHB,
MDSS_CLK_AXI,
@@ -54,6 +52,7 @@
u32 irq_buzy;
u32 mdp_irq_mask;
+ u32 mdp_hist_irq_mask;
u32 suspend;
u32 timeout;
diff --git a/drivers/video/msm/mdss/mdss_dsi.c b/drivers/video/msm/mdss/mdss_dsi.c
index e409a0b..8f4f4d5 100644
--- a/drivers/video/msm/mdss/mdss_dsi.c
+++ b/drivers/video/msm/mdss/mdss_dsi.c
@@ -199,11 +199,7 @@
{
int ret = 0;
- spin_lock_bh(&dsi_clk_lock);
mdss_dsi_clk_disable(pdata);
-
- spin_unlock_bh(&dsi_clk_lock);
-
mdss_dsi_unprepare_clocks();
/* disable DSI controller */
@@ -250,11 +246,7 @@
mdss_dsi_phy_init(pdata);
mdss_dsi_prepare_clocks();
-
- spin_lock_bh(&dsi_clk_lock);
-
mdss_dsi_clk_enable(pdata);
- spin_unlock_bh(&dsi_clk_lock);
clk_rate = pdata->panel_info.clk_rate;
clk_rate = min(clk_rate, pdata->panel_info.clk_max);
@@ -311,6 +303,7 @@
MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x5C, data);
}
+ mdss_dsi_sw_reset(pdata);
mdss_dsi_host_init(mipi, pdata);
if (mipi->force_clk_lane_hs) {
diff --git a/drivers/video/msm/mdss/mdss_dsi_host.c b/drivers/video/msm/mdss/mdss_dsi_host.c
index 5d0d578..125644e 100644
--- a/drivers/video/msm/mdss/mdss_dsi_host.c
+++ b/drivers/video/msm/mdss/mdss_dsi_host.c
@@ -32,8 +32,6 @@
static spinlock_t dsi_mdp_lock;
static int dsi_mdp_busy;
-spinlock_t dsi_clk_lock;
-
struct mdss_hw mdss_dsi_hw = {
.hw_ndx = MDSS_HW_DSI0,
.ptr = NULL,
@@ -45,7 +43,6 @@
init_completion(&dsi_dma_comp);
spin_lock_init(&dsi_irq_lock);
spin_lock_init(&dsi_mdp_lock);
- spin_lock_init(&dsi_clk_lock);
}
void mdss_dsi_irq_handler_config(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
@@ -816,6 +813,7 @@
void mdss_dsi_sw_reset(struct mdss_panel_data *pdata)
{
struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
+ u32 dsi_ctrl;
ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
panel_data);
@@ -824,6 +822,16 @@
return;
}
+ dsi_ctrl = MIPI_INP((ctrl_pdata->ctrl_base) + 0x0004);
+ dsi_ctrl &= ~0x01;
+ MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x0004, dsi_ctrl);
+ wmb();
+
+ /* turn esc, byte, dsi, pclk, sclk, hclk on */
+ MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x11c,
+ 0x23f); /* DSI_CLK_CTRL */
+ wmb();
+
MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x118, 0x01);
wmb();
MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x118, 0x00);
diff --git a/drivers/video/msm/mdss/mdss_dsi_panel.c b/drivers/video/msm/mdss/mdss_dsi_panel.c
index b247e4d..fd52e1c 100644
--- a/drivers/video/msm/mdss/mdss_dsi_panel.c
+++ b/drivers/video/msm/mdss/mdss_dsi_panel.c
@@ -106,8 +106,6 @@
pr_debug("%s:%d, debug info (mode) : %d\n", __func__, __LINE__,
mipi->mode);
- mdss_dsi_sw_reset(pdata);
-
if (mipi->mode == DSI_VIDEO_MODE) {
mdss_dsi_cmds_tx(pdata, &dsi_panel_tx_buf, dsi_panel_on_cmds,
num_of_on_cmds);
diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c
index 396407d..efb4da6 100644
--- a/drivers/video/msm/mdss/mdss_fb.c
+++ b/drivers/video/msm/mdss/mdss_fb.c
@@ -601,14 +601,14 @@
if (iclient) {
mfd->ihdl = ion_alloc(iclient, size, SZ_4K,
ION_HEAP(ION_CP_MM_HEAP_ID) |
- ION_HEAP(ION_SF_HEAP_ID));
+ ION_HEAP(ION_SF_HEAP_ID), 0);
if (IS_ERR_OR_NULL(mfd->ihdl)) {
pr_err("unable to alloc fbmem from ion (%p)\n",
mfd->ihdl);
return -ENOMEM;
}
- virt = ion_map_kernel(iclient, mfd->ihdl, 0);
+ virt = ion_map_kernel(iclient, mfd->ihdl);
ion_phys(iclient, mfd->ihdl, &phys, &size);
if (is_mdss_iommu_attached()) {
@@ -946,7 +946,6 @@
struct fb_info *info)
{
struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
- u32 len;
if (var->rotate != FB_ROTATE_UR)
return -EINVAL;
@@ -1025,9 +1024,12 @@
if ((var->xres_virtual <= 0) || (var->yres_virtual <= 0))
return -EINVAL;
- len = var->xres_virtual * var->yres_virtual * (var->bits_per_pixel / 8);
- if (len > info->fix.smem_len)
- return -EINVAL;
+ if (info->fix.smem_start) {
+ u32 len = var->xres_virtual * var->yres_virtual *
+ (var->bits_per_pixel / 8);
+ if (len > info->fix.smem_len)
+ return -EINVAL;
+ }
if ((var->xres == 0) || (var->yres == 0))
return -EINVAL;
@@ -1151,6 +1153,46 @@
ret = mdss_mdp_pa_config(&mdp_pp.data.pa_cfg_data,
©back);
break;
+
+ case mdp_op_pcc_cfg:
+ ret = mdss_mdp_pcc_config(&mdp_pp.data.pcc_cfg_data,
+ ©back);
+ break;
+
+ case mdp_op_lut_cfg:
+ switch (mdp_pp.data.lut_cfg_data.lut_type) {
+ case mdp_lut_igc:
+ ret = mdss_mdp_igc_lut_config(
+ (struct mdp_igc_lut_data *)
+ &mdp_pp.data.lut_cfg_data.data,
+ ©back);
+ break;
+
+ case mdp_lut_pgc:
+ ret = mdss_mdp_argc_config(
+ &mdp_pp.data.lut_cfg_data.data.pgc_lut_data,
+ ©back);
+ break;
+
+ case mdp_lut_hist:
+ ret = mdss_mdp_hist_lut_config(
+ (struct mdp_hist_lut_data *)
+ &mdp_pp.data.lut_cfg_data.data, ©back);
+ break;
+
+ default:
+ ret = -ENOTSUPP;
+ break;
+ }
+ break;
+ case mdp_op_dither_cfg:
+ ret = mdss_mdp_dither_config(&mdp_pp.data.dither_cfg_data,
+ ©back);
+ break;
+ case mdp_op_gamut_cfg:
+ ret = mdss_mdp_gamut_config(&mdp_pp.data.gamut_cfg_data,
+ ©back);
+ break;
default:
pr_err("Unsupported request to MDP_PP IOCTL.\n");
ret = -EINVAL;
@@ -1166,6 +1208,9 @@
{
struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
void __user *argp = (void __user *)arg;
+ struct mdp_histogram_data hist;
+ struct mdp_histogram_start_req hist_req;
+ u32 block, hist_data_addr = 0;
struct mdp_page_protection fb_page_protection;
int ret = -ENOSYS;
@@ -1178,6 +1223,43 @@
ret = mdss_fb_set_lut(info, argp);
break;
+ case MSMFB_HISTOGRAM:
+ if (!mfd->panel_power_on)
+ return -EPERM;
+
+ ret = copy_from_user(&hist, argp, sizeof(hist));
+ if (ret)
+ return ret;
+
+ ret = mdss_mdp_hist_collect(info, &hist, &hist_data_addr);
+ if ((ret == 0) && hist_data_addr) {
+ ret = copy_to_user(hist.c0, (u32 *)hist_data_addr,
+ sizeof(u32) * hist.bin_cnt);
+ if (ret == 0)
+ ret = copy_to_user(argp, &hist,
+ sizeof(hist));
+ }
+ break;
+
+ case MSMFB_HISTOGRAM_START:
+ if (!mfd->panel_power_on)
+ return -EPERM;
+
+ ret = copy_from_user(&hist_req, argp, sizeof(hist_req));
+ if (ret)
+ return ret;
+
+ ret = mdss_mdp_histogram_start(&hist_req);
+ break;
+
+ case MSMFB_HISTOGRAM_STOP:
+ ret = copy_from_user(&block, argp, sizeof(int));
+ if (ret)
+ return ret;
+
+ ret = mdss_mdp_histogram_stop(block);
+ break;
+
case MSMFB_GET_PAGE_PROTECTION:
fb_page_protection.page_protection =
mfd->mdp_fb_page_protection;
diff --git a/drivers/video/msm/mdss/mdss_hdmi_edid.c b/drivers/video/msm/mdss/mdss_hdmi_edid.c
index f720a2f..8db38d6 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_edid.c
+++ b/drivers/video/msm/mdss/mdss_hdmi_edid.c
@@ -358,34 +358,25 @@
DEV_DBG("EDID: reading block(%d) with block-size=%d\n",
block, block_size);
for (i = 0; i < 0x80; i += block_size) {
- /*Read EDID twice with 32bit alighnment too */
- if (block < 2) {
- memset(&ddc_data, 0, sizeof(ddc_data));
- ddc_data.dev_addr = 0xA0;
- ddc_data.offset = block*0x80 + i;
- ddc_data.data_buf = edid_buf+i;
- ddc_data.data_len = block_size;
- ddc_data.retry = 1;
- ddc_data.what = "EDID";
- ddc_data.no_align = false;
+ memset(&ddc_data, 0, sizeof(ddc_data));
+ ddc_data.dev_addr = 0xA0;
+ ddc_data.offset = block*0x80 + i;
+ ddc_data.data_buf = edid_buf+i;
+ ddc_data.data_len = block_size;
+ ddc_data.request_len = block_size;
+ ddc_data.retry = 1;
+ ddc_data.what = "EDID";
+ ddc_data.no_align = false;
+ /*Read EDID twice with 32bit alighnment too */
+ if (block < 2)
status = hdmi_ddc_read(
edid_ctrl->init_data.ddc_ctrl,
&ddc_data);
- } else {
- memset(&ddc_data, 0, sizeof(ddc_data));
- ddc_data.dev_addr = 0xA0;
- ddc_data.offset = block*0x80 + i;
- ddc_data.data_buf = edid_buf+i;
- ddc_data.data_len = block_size;
- ddc_data.request_len = block_size;
- ddc_data.retry = 1;
- ddc_data.what = "EDID";
-
+ else
status = hdmi_ddc_read_seg(
edid_ctrl->init_data.ddc_ctrl,
&ddc_data);
- }
if (status)
break;
}
@@ -413,7 +404,7 @@
}
print_len = 0x80;
- for (ndx = 0; ndx < print_len; ndx += 16)
+ for (ndx = 0; ndx < print_len; ndx += 4)
DEV_DBG("EDID[%02x-%02x] %02x %02x %02x %02x\n",
ndx, ndx+3,
b[ndx+0], b[ndx+1], b[ndx+2], b[ndx+3]);
@@ -1392,7 +1383,7 @@
{
struct hdmi_edid_ctrl *edid_ctrl = NULL;
- if (!init_data || !init_data->base ||
+ if (!init_data || !init_data->io ||
!init_data->mutex || !init_data->sysfs_kobj ||
!init_data->ddc_ctrl) {
DEV_ERR("%s: invalid input\n", __func__);
diff --git a/drivers/video/msm/mdss/mdss_hdmi_edid.h b/drivers/video/msm/mdss/mdss_hdmi_edid.h
index d10ae49..5c51e7e 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_edid.h
+++ b/drivers/video/msm/mdss/mdss_hdmi_edid.h
@@ -16,7 +16,7 @@
#include "mdss_hdmi_util.h"
struct hdmi_edid_init_data {
- void __iomem *base;
+ struct dss_io_data *io;
struct mutex *mutex;
struct kobject *sysfs_kobj;
diff --git a/drivers/video/msm/mdss/mdss_hdmi_tx.c b/drivers/video/msm/mdss/mdss_hdmi_tx.c
index 9278029..7f41221 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_tx.c
+++ b/drivers/video/msm/mdss/mdss_hdmi_tx.c
@@ -12,7 +12,6 @@
*/
#include <linux/bitops.h>
-#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/mutex.h>
@@ -20,7 +19,7 @@
#include <linux/of_gpio.h>
#include <linux/types.h>
-/* #define DEBUG */
+#define REG_DUMP 0
#include "mdss_fb.h"
#include "mdss_hdmi_tx.h"
@@ -91,19 +90,19 @@
0x07, 0x07, 0x07, 0x07, 0x02, 0x02, 0x02} /*12*/
};
-static const char *hdmi_tx_clk_name(u32 clk)
+const char *hdmi_tx_pm_name(enum hdmi_tx_power_module_type module)
{
- switch (clk) {
- case HDMI_TX_AHB_CLK: return "hdmi_ahb_clk";
- case HDMI_TX_APP_CLK: return "hdmi_app_clk";
- case HDMI_TX_EXTP_CLK: return "hdmi_extp_clk";
- default: return "???";
+ switch (module) {
+ case HDMI_TX_HPD_PM: return "HDMI_TX_HPD_PM";
+ case HDMI_TX_CORE_PM: return "HDMI_TX_CORE_PM";
+ case HDMI_TX_CEC_PM: return "HDMI_TX_CEC_PM";
+ default: return "???";
}
-} /* hdmi_tx_clk_name */
+} /* hdmi_tx_pm_name */
-static const char *hdmi_tx_io_name(u32 io)
+static const char *hdmi_tx_io_name(u32 type)
{
- switch (io) {
+ switch (type) {
case HDMI_TX_CORE_IO: return "core_physical";
case HDMI_TX_PHY_IO: return "phy_physical";
case HDMI_TX_QFPROM_IO: return "qfprom_physical";
@@ -190,75 +189,6 @@
return ret;
} /* hdmi_tx_sysfs_rda_connected */
-static ssize_t hdmi_tx_sysfs_rda_fake_hpd(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- ssize_t ret;
- struct hdmi_tx_ctrl *hdmi_ctrl =
- hdmi_tx_get_drvdata_from_sysfs_dev(dev);
-
- if (!hdmi_ctrl) {
- DEV_ERR("%s: invalid input\n", __func__);
- return -EINVAL;
- }
-
- mutex_lock(&hdmi_ctrl->mutex);
- ret = snprintf(buf, PAGE_SIZE, "%d\n", hdmi_ctrl->hpd_state);
- DEV_DBG("%s: '%d'\n", __func__, hdmi_ctrl->hpd_state);
- mutex_unlock(&hdmi_ctrl->mutex);
-
- return ret;
-} /* hdmi_tx_sysfs_rda_fake_hpd */
-
-static ssize_t hdmi_tx_sysfs_wta_fake_hpd(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- int fake_hpd, rc = 0;
- ssize_t ret = strnlen(buf, PAGE_SIZE);
- struct hdmi_tx_ctrl *hdmi_ctrl = NULL;
-
- DEV_DBG("%s:\n", __func__);
- hdmi_ctrl = hdmi_tx_get_drvdata_from_sysfs_dev(dev);
-
- if (!hdmi_ctrl) {
- DEV_ERR("%s: invalid input\n", __func__);
- return -EINVAL;
- }
-
- rc = kstrtoint(buf, 10, &fake_hpd);
- if (rc) {
- DEV_ERR("%s: kstrtoint failed. rc=%d\n", __func__, rc);
- return rc;
- }
-
- mutex_lock(&hdmi_ctrl->mutex);
- DEV_INFO("%s: fake_hpd=%d\n", __func__, fake_hpd);
- if (fake_hpd) {
- hdmi_ctrl->hpd_state = true;
-
- /* todo: Remove this once HPD line is available in HW */
- DEV_INFO("HDMI HPD: sense CONNECTED: send ONLINE\n");
- if (kobject_uevent(hdmi_ctrl->kobj, KOBJ_ONLINE))
- DEV_ERR("%s: failed sending online event\n", __func__);
- switch_set_state(&hdmi_ctrl->sdev, 1);
- DEV_INFO("%s: Hdmi state switch to %d\n", __func__,
- hdmi_ctrl->sdev.state);
- } else {
- hdmi_ctrl->hpd_state = false;
-
- /* todo: Remove this once HPD line is available in HW */
- DEV_INFO("HDMI HPD: sense CONNECTED: send ONLINE\n");
- if (kobject_uevent(hdmi_ctrl->kobj, KOBJ_OFFLINE))
- DEV_ERR("%s: failed sending online event\n", __func__);
- switch_set_state(&hdmi_ctrl->sdev, 0);
- DEV_INFO("%s: Hdmi state switch to %d\n", __func__,
- hdmi_ctrl->sdev.state);
- }
- mutex_unlock(&hdmi_ctrl->mutex);
-
- return ret;
-} /* hdmi_tx_sysfs_wta_fake_hpd */
-
static ssize_t hdmi_tx_sysfs_rda_hpd(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -298,16 +228,13 @@
return rc;
}
- /* todo: Remove this once HPD line is available in HW */
- if (0) {
- if (0 == hpd && hdmi_ctrl->hpd_feature_on) {
- rc = hdmi_tx_sysfs_enable_hpd(hdmi_ctrl, false);
- } else if (1 == hpd && !hdmi_ctrl->hpd_feature_on) {
- rc = hdmi_tx_sysfs_enable_hpd(hdmi_ctrl, true);
- } else {
- rc = -EPERM;
- ret = rc;
- }
+ if (0 == hpd && hdmi_ctrl->hpd_feature_on) {
+ rc = hdmi_tx_sysfs_enable_hpd(hdmi_ctrl, false);
+ } else if (1 == hpd && !hdmi_ctrl->hpd_feature_on) {
+ rc = hdmi_tx_sysfs_enable_hpd(hdmi_ctrl, true);
+ } else {
+ rc = -EPERM;
+ ret = rc;
}
if (!rc) {
@@ -325,13 +252,10 @@
static DEVICE_ATTR(connected, S_IRUGO, hdmi_tx_sysfs_rda_connected, NULL);
static DEVICE_ATTR(hpd, S_IRUGO | S_IWUSR, hdmi_tx_sysfs_rda_hpd,
hdmi_tx_sysfs_wta_hpd);
-static DEVICE_ATTR(fake_hpd, S_IRUGO | S_IWUSR, hdmi_tx_sysfs_rda_fake_hpd,
- hdmi_tx_sysfs_wta_fake_hpd);
static struct attribute *hdmi_tx_fs_attrs[] = {
&dev_attr_connected.attr,
&dev_attr_hpd.attr,
- &dev_attr_fake_hpd.attr,
NULL,
};
static struct attribute_group hdmi_tx_fs_attrs_group = {
@@ -385,7 +309,7 @@
return -EINVAL;
}
- edid_init_data.base = hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO].base;
+ edid_init_data.io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
edid_init_data.mutex = &hdmi_ctrl->mutex;
edid_init_data.sysfs_kobj = hdmi_ctrl->kobj;
edid_init_data.ddc_ctrl = &hdmi_ctrl->ddc_ctrl;
@@ -405,14 +329,14 @@
static inline u32 hdmi_tx_is_controller_on(struct hdmi_tx_ctrl *hdmi_ctrl)
{
- return HDMI_REG_R_ND(hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO].base,
- HDMI_CTRL) & BIT(0);
+ struct dss_io_data *io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
+ return DSS_REG_R_ND(io, HDMI_CTRL) & BIT(0);
} /* hdmi_tx_is_controller_on */
static inline u32 hdmi_tx_is_dvi_mode(struct hdmi_tx_ctrl *hdmi_ctrl)
{
- return !(HDMI_REG_R_ND(hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO].base,
- HDMI_CTRL) & BIT(1));
+ struct dss_io_data *io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
+ return !(DSS_REG_R_ND(io, HDMI_CTRL) & BIT(1));
} /* hdmi_tx_is_dvi_mode */
static int hdmi_tx_init_panel_info(uint32_t resolution,
@@ -473,44 +397,6 @@
hdmi_set_supported_mode(HDMI_VFRMT_1920x1080p60_16_9);
} /* hdmi_tx_setup_video_mode_lut */
-static inline struct clk *hdmi_tx_get_clk(struct hdmi_tx_platform_data *pdata,
- u32 clk_idx)
-{
- if (!pdata || clk_idx > HDMI_TX_MAX_CLK) {
- DEV_ERR("%s: invalid input\n", __func__);
- return NULL;
- }
-
- return pdata->clk[clk_idx];
-} /* hdmi_tx_get_clk */
-
-static int hdmi_tx_clk_set_rate(struct hdmi_tx_platform_data *pdata,
- u32 clk_idx, unsigned long clk_rate)
-{
- int rc = 0;
- struct clk *clk = NULL;
-
- if (!pdata) {
- DEV_ERR("%s: invalid input\n", __func__);
- return -EINVAL;
- }
-
- clk = hdmi_tx_get_clk(pdata, clk_idx);
- if (clk) {
- rc = clk_set_rate(clk, clk_rate);
- if (IS_ERR_VALUE(rc))
- DEV_ERR("%s: failed rc=%d\n", __func__, rc);
- else
- DEV_DBG("%s: name='%s' rate=%lu\n", __func__,
- hdmi_tx_clk_name(clk_idx), clk_rate);
- } else {
- DEV_ERR("%s: FAILED: invalid clk_idx=%d\n", __func__, clk_idx);
- rc = -EINVAL;
- }
-
- return rc;
-} /* hdmi_tx_clk_set_rate */
-
static int hdmi_tx_read_sink_info(struct hdmi_tx_ctrl *hdmi_ctrl)
{
int status;
@@ -551,9 +437,14 @@
}
io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
+ if (!io->base) {
+ DEV_ERR("%s: Core io is not initialized\n", __func__);
+ return;
+ }
+
DEV_DBG("%s: Got HPD interrupt\n", __func__);
- hpd_state = (HDMI_REG_R(io->base, HDMI_HPD_INT_STATUS) & BIT(1)) >> 1;
+ hpd_state = (DSS_REG_R(io, HDMI_HPD_INT_STATUS) & BIT(1)) >> 1;
mutex_lock(&hdmi_ctrl->mutex);
if ((hdmi_ctrl->hpd_prev_state != hdmi_ctrl->hpd_state) ||
(hdmi_ctrl->hpd_state != hpd_state)) {
@@ -605,22 +496,62 @@
}
/* Set IRQ for HPD */
- HDMI_REG_W(io->base, HDMI_HPD_INT_CTRL, 4 | (hpd_state ? 0 : 2));
+ DSS_REG_W(io, HDMI_HPD_INT_CTRL, 4 | (hpd_state ? 0 : 2));
} /* hdmi_tx_hpd_state_work */
-static int hdmi_tx_check_capability(void __iomem *base)
+static void hdmi_tx_hpd_int_work(struct work_struct *work)
+{
+ u32 hpd_int_status;
+ u32 hpd_int_ctrl;
+ u32 cable_detected;
+ struct hdmi_tx_ctrl *hdmi_ctrl = NULL;
+ struct dss_io_data *io = NULL;
+
+ hdmi_ctrl = container_of(work, struct hdmi_tx_ctrl, hpd_int_work);
+ if (!hdmi_ctrl || !hdmi_ctrl->hpd_initialized) {
+ DEV_DBG("%s: invalid input\n", __func__);
+ return;
+ }
+
+ io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
+ if (!io->base) {
+ DEV_ERR("%s: Core io is not initialized\n", __func__);
+ return;
+ }
+
+ /* Process HPD Interrupt */
+ hpd_int_status = DSS_REG_R(io, HDMI_HPD_INT_STATUS);
+ hpd_int_ctrl = DSS_REG_R(io, HDMI_HPD_INT_CTRL);
+
+ DSS_REG_W(io, HDMI_HPD_INT_CTRL, BIT(2));
+
+ cable_detected = hpd_int_status & BIT(1);
+ mutex_lock(&hdmi_ctrl->mutex);
+ hdmi_ctrl->hpd_cable_chg_detected = true;
+ hdmi_ctrl->hpd_prev_state = cable_detected ? 0 : 1;
+ hdmi_ctrl->hpd_stable = 0;
+ mutex_unlock(&hdmi_ctrl->mutex);
+
+ mod_timer(&hdmi_ctrl->hpd_state_timer, jiffies + HZ/2);
+
+ DEV_DBG("%s: HPD<Ctrl=%04x, State=%04x>\n", __func__, hpd_int_ctrl,
+ hpd_int_status);
+} /* hdmi_tx_hpd_int_work */
+
+static int hdmi_tx_check_capability(struct dss_io_data *io)
{
u32 hdmi_disabled, hdcp_disabled;
- if (!base) {
+ if (!io) {
DEV_ERR("%s: invalid input\n", __func__);
return -EINVAL;
}
- /* QFPROM_RAW_FEAT_CONFIG_ROW0_LSB */
- hdcp_disabled = HDMI_REG_R_ND(base, 0x000000F8) & BIT(31);
- /* QFPROM_RAW_FEAT_CONFIG_ROW0_MSB */
- hdmi_disabled = HDMI_REG_R_ND(base, 0x000000FC) & BIT(0);
+ hdcp_disabled = DSS_REG_R_ND(io,
+ QFPROM_RAW_FEAT_CONFIG_ROW0_LSB) & BIT(31);
+
+ hdmi_disabled = DSS_REG_R_ND(io,
+ QFPROM_RAW_FEAT_CONFIG_ROW0_MSB) & BIT(0);
DEV_DBG("%s: Features <HDMI:%s, HDCP:%s>\n", __func__,
hdmi_disabled ? "OFF" : "ON", hdcp_disabled ? "OFF" : "ON");
@@ -710,25 +641,9 @@
goto end;
}
- /*
- * extpclk is driven by hdmi phy pll. This phy pll programming requires
- * hdmi_ahb_clk. So enable it and then disable.
- */
- rc = clk_prepare_enable(pdata->clk[HDMI_TX_AHB_CLK]);
- if (rc) {
- DEV_ERR("%s: failed to enable '%s' clk\n", __func__,
- hdmi_tx_clk_name(HDMI_TX_AHB_CLK));
- goto end;
- }
- rc = hdmi_tx_clk_set_rate(pdata, HDMI_TX_EXTP_CLK,
- timing->pixel_freq * 1000);
- if (rc) {
- DEV_ERR("%s: FAILED: '%s' clk set rate\n", __func__,
- hdmi_tx_clk_name(HDMI_TX_EXTP_CLK));
- clk_disable_unprepare(pdata->clk[HDMI_TX_AHB_CLK]);
- goto end;
- }
- clk_disable_unprepare(pdata->clk[HDMI_TX_AHB_CLK]);
+ /* todo: find a better way */
+ hdmi_ctrl->pdata.power_data[HDMI_TX_CORE_PM].clk_config[0].rate =
+ timing->pixel_freq * 1000;
hdmi_ctrl->video_resolution = format;
hdmi_edid_set_video_resolution(
@@ -772,35 +687,35 @@
timing->back_porch_h + timing->pulse_width_h - 1;
total_v = timing->active_v + timing->front_porch_v +
timing->back_porch_v + timing->pulse_width_v - 1;
- HDMI_REG_W(io->base, HDMI_TOTAL,
+ DSS_REG_W(io, HDMI_TOTAL,
((total_v << 16) & 0x0FFF0000) |
((total_h << 0) & 0x00000FFF));
start_h = timing->back_porch_h + timing->pulse_width_h;
end_h = (total_h + 1) - timing->front_porch_h;
- HDMI_REG_W(io->base, HDMI_ACTIVE_H,
+ DSS_REG_W(io, HDMI_ACTIVE_H,
((end_h << 16) & 0x0FFF0000) |
((start_h << 0) & 0x00000FFF));
start_v = timing->back_porch_v + timing->pulse_width_v - 1;
end_v = total_v - timing->front_porch_v;
- HDMI_REG_W(io->base, HDMI_ACTIVE_V,
+ DSS_REG_W(io, HDMI_ACTIVE_V,
((end_v << 16) & 0x0FFF0000) |
((start_v << 0) & 0x00000FFF));
if (timing->interlaced) {
- HDMI_REG_W(io->base, HDMI_V_TOTAL_F2,
+ DSS_REG_W(io, HDMI_V_TOTAL_F2,
((total_v + 1) << 0) & 0x00000FFF);
- HDMI_REG_W(io->base, HDMI_ACTIVE_V_F2,
+ DSS_REG_W(io, HDMI_ACTIVE_V_F2,
(((start_v + 1) << 0) & 0x00000FFF) |
(((end_v + 1) << 16) & 0x0FFF0000));
} else {
- HDMI_REG_W(io->base, HDMI_V_TOTAL_F2, 0);
- HDMI_REG_W(io->base, HDMI_ACTIVE_V_F2, 0);
+ DSS_REG_W(io, HDMI_V_TOTAL_F2, 0);
+ DSS_REG_W(io, HDMI_ACTIVE_V_F2, 0);
}
- HDMI_REG_W(io->base, HDMI_FRAME_CTRL,
+ DSS_REG_W(io, HDMI_FRAME_CTRL,
((timing->interlaced << 31) & 0x80000000) |
((timing->active_low_h << 29) & 0x20000000) |
((timing->active_low_v << 28) & 0x10000000));
@@ -929,28 +844,28 @@
regVal = regVal << 8 | avi_iframe[4];
regVal = regVal << 8 | avi_iframe[3];
regVal = regVal << 8 | checksum;
- HDMI_REG_W(io->base, HDMI_AVI_INFO0, regVal);
+ DSS_REG_W(io, HDMI_AVI_INFO0, regVal);
regVal = avi_iframe[9];
regVal = regVal << 8 | avi_iframe[8];
regVal = regVal << 8 | avi_iframe[7];
regVal = regVal << 8 | avi_iframe[6];
- HDMI_REG_W(io->base, HDMI_AVI_INFO1, regVal);
+ DSS_REG_W(io, HDMI_AVI_INFO1, regVal);
regVal = avi_iframe[13];
regVal = regVal << 8 | avi_iframe[12];
regVal = regVal << 8 | avi_iframe[11];
regVal = regVal << 8 | avi_iframe[10];
- HDMI_REG_W(io->base, HDMI_AVI_INFO2, regVal);
+ DSS_REG_W(io, HDMI_AVI_INFO2, regVal);
regVal = avi_iframe[1];
regVal = regVal << 16 | avi_iframe[15];
regVal = regVal << 8 | avi_iframe[14];
- HDMI_REG_W(io->base, HDMI_AVI_INFO3, regVal);
+ DSS_REG_W(io, HDMI_AVI_INFO3, regVal);
/* 0x3 for AVI InfFrame enable (every frame) */
- HDMI_REG_W(io->base, HDMI_INFOFRAME_CTRL0,
- HDMI_REG_R(io->base, HDMI_INFOFRAME_CTRL0) |
+ DSS_REG_W(io, HDMI_INFOFRAME_CTRL0,
+ DSS_REG_R(io, HDMI_INFOFRAME_CTRL0) |
0x00000003L);
} /* hdmi_tx_set_avi_infoframe */
@@ -986,14 +901,14 @@
* 0x19 Length of Source Product Description InfoFrame
*/
packet_header = 0x83 | (0x01 << 8) | (0x19 << 16);
- HDMI_REG_W(io->base, HDMI_GENERIC1_HDR, packet_header);
+ DSS_REG_W(io, HDMI_GENERIC1_HDR, packet_header);
check_sum += IFRAME_CHECKSUM_32(packet_header);
packet_payload = (vendor_name[3] & 0x7f)
| ((vendor_name[4] & 0x7f) << 8)
| ((vendor_name[5] & 0x7f) << 16)
| ((vendor_name[6] & 0x7f) << 24);
- HDMI_REG_W(io->base, HDMI_GENERIC1_1, packet_payload);
+ DSS_REG_W(io, HDMI_GENERIC1_1, packet_payload);
check_sum += IFRAME_CHECKSUM_32(packet_payload);
/* Product Description (7-bit ASCII code) */
@@ -1001,28 +916,28 @@
| ((product_description[0] & 0x7f) << 8)
| ((product_description[1] & 0x7f) << 16)
| ((product_description[2] & 0x7f) << 24);
- HDMI_REG_W(io->base, HDMI_GENERIC1_2, packet_payload);
+ DSS_REG_W(io, HDMI_GENERIC1_2, packet_payload);
check_sum += IFRAME_CHECKSUM_32(packet_payload);
packet_payload = (product_description[3] & 0x7f)
| ((product_description[4] & 0x7f) << 8)
| ((product_description[5] & 0x7f) << 16)
| ((product_description[6] & 0x7f) << 24);
- HDMI_REG_W(io->base, HDMI_GENERIC1_3, packet_payload);
+ DSS_REG_W(io, HDMI_GENERIC1_3, packet_payload);
check_sum += IFRAME_CHECKSUM_32(packet_payload);
packet_payload = (product_description[7] & 0x7f)
| ((product_description[8] & 0x7f) << 8)
| ((product_description[9] & 0x7f) << 16)
| ((product_description[10] & 0x7f) << 24);
- HDMI_REG_W(io->base, HDMI_GENERIC1_4, packet_payload);
+ DSS_REG_W(io, HDMI_GENERIC1_4, packet_payload);
check_sum += IFRAME_CHECKSUM_32(packet_payload);
packet_payload = (product_description[11] & 0x7f)
| ((product_description[12] & 0x7f) << 8)
| ((product_description[13] & 0x7f) << 16)
| ((product_description[14] & 0x7f) << 24);
- HDMI_REG_W(io->base, HDMI_GENERIC1_5, packet_payload);
+ DSS_REG_W(io, HDMI_GENERIC1_5, packet_payload);
check_sum += IFRAME_CHECKSUM_32(packet_payload);
/*
@@ -1039,7 +954,7 @@
* 09h PC general
*/
packet_payload = (product_description[15] & 0x7f) | 0x00 << 8;
- HDMI_REG_W(io->base, HDMI_GENERIC1_6, packet_payload);
+ DSS_REG_W(io, HDMI_GENERIC1_6, packet_payload);
check_sum += IFRAME_CHECKSUM_32(packet_payload);
/* Vendor Name (7bit ASCII code) */
@@ -1048,7 +963,7 @@
| ((vendor_name[2] & 0x7f) << 24);
check_sum += IFRAME_CHECKSUM_32(packet_payload);
packet_payload |= ((0x100 - (0xff & check_sum)) & 0xff);
- HDMI_REG_W(io->base, HDMI_GENERIC1_0, packet_payload);
+ DSS_REG_W(io, HDMI_GENERIC1_0, packet_payload);
/*
* GENERIC1_LINE | GENERIC1_CONT | GENERIC1_SEND
@@ -1056,9 +971,9 @@
* Enable this packet to transmit every frame
* Enable HDMI TX engine to transmit Generic packet 1
*/
- packet_control = HDMI_REG_R_ND(io->base, HDMI_GEN_PKT_CTRL);
+ packet_control = DSS_REG_R_ND(io, HDMI_GEN_PKT_CTRL);
packet_control |= ((0x1 << 24) | (1 << 5) | (1 << 4));
- HDMI_REG_W(io->base, HDMI_GEN_PKT_CTRL, packet_control);
+ DSS_REG_W(io, HDMI_GEN_PKT_CTRL, packet_control);
} /* hdmi_tx_set_spd_infoframe */
/* todo: revisit when new HPD debouncing logic is avialble */
@@ -1075,11 +990,17 @@
static void hdmi_tx_set_mode(struct hdmi_tx_ctrl *hdmi_ctrl, u32 power_on)
{
u32 reg_val = 0;
+ struct dss_io_data *io = NULL;
if (!hdmi_ctrl) {
DEV_ERR("%s: invalid input\n", __func__);
return;
}
+ io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
+ if (!io->base) {
+ DEV_ERR("%s: Core io is not initialized\n", __func__);
+ return;
+ }
if (power_on) {
/* ENABLE */
@@ -1101,77 +1022,12 @@
reg_val = BIT(1);
}
- HDMI_REG_W(hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO].base, HDMI_CTRL,
- reg_val);
+ DSS_REG_W(io, HDMI_CTRL, reg_val);
DEV_DBG("HDMI Core: %s, HDMI_CTRL=0x%08x\n",
power_on ? "Enable" : "Disable", reg_val);
} /* hdmi_tx_set_mode */
-static int hdmi_tx_clk_update(struct hdmi_tx_platform_data *pdata, u32 clk_idx,
- u32 enable)
-{
- int rc = 0;
- struct clk *clk = hdmi_tx_get_clk(pdata, clk_idx);
-
- if (clk) {
- DEV_DBG("%s: clk=%d en=%d\n", __func__, clk_idx, enable);
- if (enable) {
- rc = clk_prepare_enable(clk);
- if (rc)
- DEV_ERR("%s: clk=%d enable failed\n",
- __func__, clk_idx);
- } else {
- clk_disable_unprepare(clk);
- }
- } else {
- DEV_ERR("%s: FAILED: invalid input for clk='%s'\n", __func__,
- hdmi_tx_clk_name(clk_idx));
- rc = -EINVAL;
- }
-
- return rc;
-} /* hdmi_tx_clk_update */
-
-/* Note: Before accessing extpclk, always make sure that hdmi_ahb_clk is on */
-static int hdmi_tx_clk_ctrl_update(struct hdmi_tx_platform_data *pdata, int on)
-{
- int rc = 0;
- DEV_DBG("%s: HDMI Clk: %s\n", __func__, on ? "Enable" : "Disable");
-
- rc = hdmi_tx_clk_update(pdata, HDMI_TX_APP_CLK, on);
- if (on && rc) {
- DEV_ERR("%s: '%s' on failed\n", __func__,
- hdmi_tx_clk_name(HDMI_TX_APP_CLK));
- goto fail_hdmi_app_clk;
- }
- if (on) {
- rc = hdmi_tx_clk_update(pdata, HDMI_TX_AHB_CLK, on);
- if (rc) {
- DEV_ERR("%s: '%s' on failed\n", __func__,
- hdmi_tx_clk_name(HDMI_TX_AHB_CLK));
- goto fail_hdmi_ahb_clk;
- }
- rc = hdmi_tx_clk_update(pdata, HDMI_TX_EXTP_CLK, on);
- if (rc) {
- DEV_ERR("%s: '%s' on failed\n", __func__,
- hdmi_tx_clk_name(HDMI_TX_EXTP_CLK));
- goto fail_hdmi_extp_clk;
- }
- } else {
- hdmi_tx_clk_update(pdata, HDMI_TX_EXTP_CLK, on);
- hdmi_tx_clk_update(pdata, HDMI_TX_AHB_CLK, on);
- }
- return rc;
-
-fail_hdmi_extp_clk:
- hdmi_tx_clk_update(pdata, HDMI_TX_AHB_CLK, 0);
-fail_hdmi_ahb_clk:
- hdmi_tx_clk_update(pdata, HDMI_TX_APP_CLK, 0);
-fail_hdmi_app_clk:
- return rc;
-} /* hdmi_tx_clk_ctrl_update */
-
static int hdmi_tx_config_power(struct hdmi_tx_ctrl *hdmi_ctrl,
enum hdmi_tx_power_module_type module, int config)
{
@@ -1191,17 +1047,33 @@
goto exit;
}
- if (config)
+ if (config) {
rc = msm_dss_config_vreg(&hdmi_ctrl->pdev->dev,
power_data->vreg_config, power_data->num_vreg, 1);
- else
+ if (rc) {
+ DEV_ERR("%s: Failed to config %s vreg. Err=%d\n",
+ __func__, hdmi_tx_pm_name(module), rc);
+ goto exit;
+ }
+
+ rc = msm_dss_get_clk(&hdmi_ctrl->pdev->dev,
+ power_data->clk_config, power_data->num_clk);
+ if (rc) {
+ DEV_ERR("%s: Failed to get %s clk. Err=%d\n",
+ __func__, hdmi_tx_pm_name(module), rc);
+
+ msm_dss_config_vreg(&hdmi_ctrl->pdev->dev,
+ power_data->vreg_config, power_data->num_vreg, 0);
+ }
+ } else {
+ msm_dss_put_clk(power_data->clk_config, power_data->num_clk);
+
rc = msm_dss_config_vreg(&hdmi_ctrl->pdev->dev,
power_data->vreg_config, power_data->num_vreg, 0);
-
- if (rc)
- DEV_ERR("%s: Failed to %s %s vreg. Error=%d\n",
- __func__, config ? "config" : "deconfig",
- hdmi_pm_name(module), rc);
+ if (rc)
+ DEV_ERR("%s: Fail to deconfig %s vreg. Err=%d\n",
+ __func__, hdmi_tx_pm_name(module), rc);
+ }
exit:
return rc;
@@ -1231,18 +1103,36 @@
power_data->num_vreg, 1);
if (rc) {
DEV_ERR("%s: Failed to enable %s vreg. Error=%d\n",
- __func__, hdmi_pm_name(module), rc);
+ __func__, hdmi_tx_pm_name(module), rc);
goto error;
}
rc = msm_dss_enable_gpio(power_data->gpio_config,
- power_data->num_gpio, enable);
+ power_data->num_gpio, 1);
if (rc) {
DEV_ERR("%s: Failed to enable %s gpio. Error=%d\n",
- __func__, hdmi_pm_name(module), rc);
+ __func__, hdmi_tx_pm_name(module), rc);
goto disable_vreg;
}
+
+ rc = msm_dss_clk_set_rate(power_data->clk_config,
+ power_data->num_clk);
+ if (rc) {
+ DEV_ERR("%s: failed to set clks rate for %s. err=%d\n",
+ __func__, hdmi_tx_pm_name(module), rc);
+ goto disable_gpio;
+ }
+
+ rc = msm_dss_enable_clk(power_data->clk_config,
+ power_data->num_clk, 1);
+ if (rc) {
+ DEV_ERR("%s: Failed to enable clks for %s. Error=%d\n",
+ __func__, hdmi_tx_pm_name(module), rc);
+ goto disable_gpio;
+ }
} else {
+ msm_dss_enable_clk(power_data->clk_config,
+ power_data->num_clk, 0);
msm_dss_enable_gpio(power_data->gpio_config,
power_data->num_gpio, 0);
msm_dss_enable_vreg(power_data->vreg_config,
@@ -1251,6 +1141,8 @@
return rc;
+disable_gpio:
+ msm_dss_enable_gpio(power_data->gpio_config, power_data->num_gpio, 0);
disable_vreg:
msm_dss_enable_vreg(power_data->vreg_config, power_data->num_vreg, 0);
error:
@@ -1281,7 +1173,7 @@
if (rc) {
DEV_ERR("%s: core hdmi_msm_enable_power failed rc = %d\n",
__func__, rc);
- goto error;
+ goto disable_hpd_power;
}
rc = hdmi_tx_enable_power(hdmi_ctrl, HDMI_TX_CEC_PM, 1);
if (rc) {
@@ -1293,7 +1185,8 @@
return rc;
disable_core_power:
hdmi_tx_enable_power(hdmi_ctrl, HDMI_TX_CORE_PM, 0);
-error:
+disable_hpd_power:
+ hdmi_tx_enable_power(hdmi_ctrl, HDMI_TX_HPD_PM, 0);
return rc;
} /* hdmi_tx_core_on */
@@ -1311,36 +1204,34 @@
io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
if (!io->base) {
- DEV_ERR("%s: io not inititalized\n", __func__);
+ DEV_ERR("%s: core io not inititalized\n", __func__);
return;
}
- val = HDMI_REG_R_ND(io->base, HDMI_PHY_CTRL);
+ val = DSS_REG_R_ND(io, HDMI_PHY_CTRL);
phy_reset_polarity = val >> 3 & 0x1;
pll_reset_polarity = val >> 1 & 0x1;
if (phy_reset_polarity == 0)
- HDMI_REG_W_ND(io->base, HDMI_PHY_CTRL, val | SW_RESET);
+ DSS_REG_W_ND(io, HDMI_PHY_CTRL, val | SW_RESET);
else
- HDMI_REG_W_ND(io->base, HDMI_PHY_CTRL, val & (~SW_RESET));
+ DSS_REG_W_ND(io, HDMI_PHY_CTRL, val & (~SW_RESET));
if (pll_reset_polarity == 0)
- HDMI_REG_W_ND(io->base, HDMI_PHY_CTRL, val | SW_RESET_PLL);
+ DSS_REG_W_ND(io, HDMI_PHY_CTRL, val | SW_RESET_PLL);
else
- HDMI_REG_W_ND(io->base,
- HDMI_PHY_CTRL, val & (~SW_RESET_PLL));
+ DSS_REG_W_ND(io, HDMI_PHY_CTRL, val & (~SW_RESET_PLL));
if (phy_reset_polarity == 0)
- HDMI_REG_W_ND(io->base, HDMI_PHY_CTRL, val & (~SW_RESET));
+ DSS_REG_W_ND(io, HDMI_PHY_CTRL, val & (~SW_RESET));
else
- HDMI_REG_W_ND(io->base, HDMI_PHY_CTRL, val | SW_RESET);
+ DSS_REG_W_ND(io, HDMI_PHY_CTRL, val | SW_RESET);
if (pll_reset_polarity == 0)
- HDMI_REG_W_ND(io->base,
- HDMI_PHY_CTRL, val & (~SW_RESET_PLL));
+ DSS_REG_W_ND(io, HDMI_PHY_CTRL, val & (~SW_RESET_PLL));
else
- HDMI_REG_W_ND(io->base, HDMI_PHY_CTRL, val | SW_RESET_PLL);
+ DSS_REG_W_ND(io, HDMI_PHY_CTRL, val | SW_RESET_PLL);
} /* hdmi_tx_phy_reset */
static void hdmi_tx_init_phy(struct hdmi_tx_ctrl *hdmi_ctrl)
@@ -1354,55 +1245,58 @@
io = &hdmi_ctrl->pdata.io[HDMI_TX_PHY_IO];
if (!io->base) {
- DEV_ERR("%s: Core io is not initialized\n", __func__);
+ DEV_ERR("%s: phy io is not initialized\n", __func__);
return;
}
- HDMI_REG_W_ND(io->base, HDMI_PHY_ANA_CFG0, 0x1B);
- HDMI_REG_W_ND(io->base, HDMI_PHY_ANA_CFG1, 0xF2);
- HDMI_REG_W_ND(io->base, HDMI_PHY_BIST_CFG0, 0x0);
- HDMI_REG_W_ND(io->base, HDMI_PHY_BIST_PATN0, 0x0);
- HDMI_REG_W_ND(io->base, HDMI_PHY_BIST_PATN1, 0x0);
- HDMI_REG_W_ND(io->base, HDMI_PHY_BIST_PATN2, 0x0);
- HDMI_REG_W_ND(io->base, HDMI_PHY_BIST_PATN3, 0x0);
+ DSS_REG_W_ND(io, HDMI_PHY_ANA_CFG0, 0x1B);
+ DSS_REG_W_ND(io, HDMI_PHY_ANA_CFG1, 0xF2);
+ DSS_REG_W_ND(io, HDMI_PHY_BIST_CFG0, 0x0);
+ DSS_REG_W_ND(io, HDMI_PHY_BIST_PATN0, 0x0);
+ DSS_REG_W_ND(io, HDMI_PHY_BIST_PATN1, 0x0);
+ DSS_REG_W_ND(io, HDMI_PHY_BIST_PATN2, 0x0);
+ DSS_REG_W_ND(io, HDMI_PHY_BIST_PATN3, 0x0);
- HDMI_REG_W_ND(io->base, HDMI_PHY_PD_CTRL1, 0x20);
+ DSS_REG_W_ND(io, HDMI_PHY_PD_CTRL1, 0x20);
} /* hdmi_tx_init_phy */
static void hdmi_tx_powerdown_phy(struct hdmi_tx_ctrl *hdmi_ctrl)
{
+ struct dss_io_data *io = NULL;
+
if (!hdmi_ctrl) {
DEV_ERR("%s: invalid input\n", __func__);
return;
}
+ io = &hdmi_ctrl->pdata.io[HDMI_TX_PHY_IO];
+ if (!io->base) {
+ DEV_ERR("%s: phy io is not initialized\n", __func__);
+ return;
+ }
- HDMI_REG_W_ND(hdmi_ctrl->pdata.io[HDMI_TX_PHY_IO].base,
- HDMI_PHY_PD_CTRL0, 0x7F);
+ DSS_REG_W_ND(io, HDMI_PHY_PD_CTRL0, 0x7F);
} /* hdmi_tx_powerdown_phy */
static int hdmi_tx_start(struct hdmi_tx_ctrl *hdmi_ctrl)
{
int rc = 0;
+ struct dss_io_data *io = NULL;
if (!hdmi_ctrl) {
DEV_ERR("%s: invalid input\n", __func__);
return -EINVAL;
}
+ io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
+ if (!io->base) {
+ DEV_ERR("%s: core io is not initialized\n", __func__);
+ return -EINVAL;
+ }
+
/* todo: Audio */
hdmi_tx_set_mode(hdmi_ctrl, false);
- mutex_lock(&hdmi_ctrl->mutex);
- rc = hdmi_tx_clk_ctrl_update(&hdmi_ctrl->pdata, 1);
- if (rc) {
- DEV_ERR("%s: hdmi_tx_clk_enable failed.\n", __func__);
- mutex_unlock(&hdmi_ctrl->mutex);
- return rc;
- }
- mutex_unlock(&hdmi_ctrl->mutex);
-
hdmi_tx_init_phy(hdmi_ctrl);
- HDMI_REG_W(hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO].base,
- HDMI_USEC_REFTIMER, 0x0001001B);
+ DSS_REG_W(io, HDMI_USEC_REFTIMER, 0x0001001B);
hdmi_tx_set_mode(hdmi_ctrl, true);
@@ -1413,8 +1307,7 @@
hdmi_tx_set_spd_infoframe(hdmi_ctrl);
/* Set IRQ for HPD */
- HDMI_REG_W(hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO].base,
- HDMI_HPD_INT_CTRL, 4 | (hdmi_ctrl->hpd_state ? 0 : 2));
+ DSS_REG_W(io, HDMI_HPD_INT_CTRL, 4 | (hdmi_ctrl->hpd_state ? 0 : 2));
/* todo: HDCP/CEC */
@@ -1437,12 +1330,6 @@
/* todo: Audio */
hdmi_tx_powerdown_phy(hdmi_ctrl);
hdmi_ctrl->panel_power_on = false;
-
- mutex_lock(&hdmi_ctrl->mutex);
- if (hdmi_tx_clk_ctrl_update(&hdmi_ctrl->pdata, 0))
- DEV_ERR("%s: hdmi_tx_clk_disable failed.\n", __func__);
- mutex_unlock(&hdmi_ctrl->mutex);
-
hdmi_tx_core_off(hdmi_ctrl);
return 0;
@@ -1451,6 +1338,7 @@
static int hdmi_tx_power_on(struct mdss_panel_data *panel_data)
{
int rc = 0;
+ struct dss_io_data *io = NULL;
struct hdmi_tx_ctrl *hdmi_ctrl =
hdmi_tx_get_drvdata_from_panel_data(panel_data);
@@ -1458,11 +1346,10 @@
DEV_ERR("%s: invalid input\n", __func__);
return -EINVAL;
}
-
- rc = hdmi_tx_core_on(hdmi_ctrl);
- if (rc) {
- DEV_ERR("%s: hdmi_msm_core_on failed\n", __func__);
- return rc;
+ io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
+ if (!io->base) {
+ DEV_ERR("%s: core io is not initialized\n", __func__);
+ return -EINVAL;
}
DEV_INFO("power: ON (%dx%d %ld)\n", hdmi_ctrl->xres, hdmi_ctrl->yres,
@@ -1471,7 +1358,12 @@
rc = hdmi_tx_set_video_fmt(hdmi_ctrl);
if (rc) {
DEV_ERR("%s: cannot set video_fmt.rc=%d\n", __func__, rc);
- hdmi_tx_core_off(hdmi_ctrl);
+ return rc;
+ }
+
+ rc = hdmi_tx_core_on(hdmi_ctrl);
+ if (rc) {
+ DEV_ERR("%s: hdmi_msm_core_on failed\n", __func__);
return rc;
}
@@ -1494,8 +1386,7 @@
mutex_unlock(&hdmi_ctrl->mutex);
}
- hdmi_reg_dump(hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO].base,
- hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO].len, "HDMI-ON: ");
+ dss_reg_dump(io->base, io->len, "HDMI-ON: ", REG_DUMP);
DEV_INFO("%s: HDMI=%s DVI= %s\n", __func__,
hdmi_tx_is_controller_on(hdmi_ctrl) ? "ON" : "OFF" ,
@@ -1524,13 +1415,6 @@
hdmi_tx_set_mode(hdmi_ctrl, false);
- mutex_lock(&hdmi_ctrl->mutex);
- rc = hdmi_tx_clk_ctrl_update(&hdmi_ctrl->pdata, 0);
- if (rc)
- DEV_INFO("%s: Failed to disable clock. Error=%d\n",
- __func__, rc);
- mutex_unlock(&hdmi_ctrl->mutex);
-
rc = hdmi_tx_enable_power(hdmi_ctrl, HDMI_TX_HPD_PM, 0);
if (rc)
DEV_INFO("%s: Failed to disable hpd power. Error=%d\n",
@@ -1552,7 +1436,7 @@
io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
if (!io->base) {
- DEV_ERR("%s: io not inititalized\n", __func__);
+ DEV_ERR("%s: core io not inititalized\n", __func__);
return -EINVAL;
}
@@ -1566,31 +1450,21 @@
return rc;
}
- mutex_lock(&hdmi_ctrl->mutex);
- rc = hdmi_tx_clk_ctrl_update(&hdmi_ctrl->pdata, true);
- if (rc) {
- DEV_ERR("%s: Failed to enable clocks. rc=%d\n",
- __func__, rc);
- mutex_unlock(&hdmi_ctrl->mutex);
- goto disable_hpd_power;
- }
- mutex_unlock(&hdmi_ctrl->mutex);
-
- hdmi_reg_dump(io->base, io->len, "HDMI-INIT: ");
+ dss_reg_dump(io->base, io->len, "HDMI-INIT: ", REG_DUMP);
hdmi_tx_set_mode(hdmi_ctrl, false);
hdmi_tx_phy_reset(hdmi_ctrl);
hdmi_tx_set_mode(hdmi_ctrl, true);
- HDMI_REG_W(io->base, HDMI_USEC_REFTIMER, 0x0001001B);
+ DSS_REG_W(io, HDMI_USEC_REFTIMER, 0x0001001B);
/* set timeout to 4.1ms (max) for hardware debounce */
- reg_val = HDMI_REG_R(io->base, HDMI_HPD_CTRL) | 0x1FFF;
+ reg_val = DSS_REG_R(io, HDMI_HPD_CTRL) | 0x1FFF;
/* Toggle HPD circuit to trigger HPD sense */
- HDMI_REG_W(io->base, HDMI_HPD_CTRL,
+ DSS_REG_W(io, HDMI_HPD_CTRL,
~(1 << 28) & reg_val);
- HDMI_REG_W(io->base, HDMI_HPD_CTRL, (1 << 28) | reg_val);
+ DSS_REG_W(io, HDMI_HPD_CTRL, (1 << 28) | reg_val);
hdmi_ctrl->hpd_initialized = true;
@@ -1607,11 +1481,6 @@
mutex_unlock(&hdmi_ctrl->mutex);
mod_timer(&hdmi_ctrl->hpd_state_timer, jiffies + HZ/2);
- return 0;
-
-disable_hpd_power:
- hdmi_tx_enable_power(hdmi_ctrl, HDMI_TX_HPD_PM, false);
-
return rc;
} /* hdmi_tx_hpd_on */
@@ -1629,7 +1498,6 @@
rc = hdmi_tx_hpd_on(hdmi_ctrl);
} else {
hdmi_tx_hpd_off(hdmi_ctrl);
- /* Set HDMI switch node to 0 on HPD feature disable */
switch_set_state(&hdmi_ctrl->sdev, 0);
DEV_INFO("%s: Hdmi state switch to %d\n", __func__,
hdmi_ctrl->sdev.state);
@@ -1640,8 +1508,6 @@
static irqreturn_t hdmi_tx_isr(int irq, void *data)
{
- u32 hpd_int_status;
- u32 hpd_int_ctrl;
struct dss_io_data *io = NULL;
struct hdmi_tx_ctrl *hdmi_ctrl = (struct hdmi_tx_ctrl *)data;
@@ -1652,108 +1518,26 @@
io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
if (!io->base) {
- DEV_WARN("%s: io not initialized, ISR ignored\n", __func__);
+ DEV_WARN("%s: core io not initialized, ISR ignored\n",
+ __func__);
return IRQ_HANDLED;
}
- /* Process HPD Interrupt */
- hpd_int_status = HDMI_REG_R(io->base, HDMI_HPD_INT_STATUS);
- hpd_int_ctrl = HDMI_REG_R(io->base, HDMI_HPD_INT_CTRL);
- if ((hpd_int_ctrl & BIT(2)) && (hpd_int_status & BIT(0))) {
- u32 cable_detected = hpd_int_status & BIT(1);
-
+ if (DSS_REG_R(io, HDMI_HPD_INT_STATUS) & BIT(0)) {
/*
- * Clear all interrupts, timer will turn IRQ back on
- * Leaving the bit[2] on, else core goes off
- * on getting HPD during power off.
+ * Turn off HPD irq and clear all interrupts,
+ * worker will turn IRQ back on
*/
- HDMI_REG_W(io->base, HDMI_HPD_INT_CTRL, BIT(2) | BIT(0));
-
- DEV_DBG("%s: HPD IRQ, Ctrl=%04x, State=%04x\n", __func__,
- hpd_int_ctrl, hpd_int_status);
-
- mutex_lock(&hdmi_ctrl->mutex);
- hdmi_ctrl->hpd_cable_chg_detected = true;
- hdmi_ctrl->hpd_prev_state = cable_detected ? 0 : 1;
- hdmi_ctrl->hpd_stable = 0;
- mutex_unlock(&hdmi_ctrl->mutex);
-
- mod_timer(&hdmi_ctrl->hpd_state_timer, jiffies + HZ/2);
-
- return IRQ_HANDLED;
+ DSS_REG_W(io, HDMI_HPD_INT_CTRL, ~BIT(2) | BIT(0));
+ queue_work(hdmi_ctrl->workq, &hdmi_ctrl->hpd_int_work);
}
- if (!hdmi_ddc_isr(&hdmi_ctrl->ddc_ctrl))
- return IRQ_HANDLED;
-
- DEV_DBG("%s: HPD<Ctrl=%04x, State=%04x>\n", __func__, hpd_int_ctrl,
- hpd_int_status);
+ if (hdmi_ddc_isr(&hdmi_ctrl->ddc_ctrl) < 0)
+ DEV_ERR("%s: hdmi_ddc_isr failed\n", __func__);
return IRQ_HANDLED;
} /* hdmi_tx_isr */
-static void hdmi_tx_clk_deinit(struct hdmi_tx_platform_data *pdata)
-{
- int i;
- if (!pdata) {
- DEV_ERR("%s: invalid input\n", __func__);
- return;
- }
-
- for (i = HDMI_TX_MAX_CLK - 1; i >= 0; i--) {
- if (pdata->clk[i])
- clk_put(pdata->clk[i]);
- pdata->clk[i] = NULL;
- }
-} /* hdmi_tx_clk_deinit */
-
-static int hdmi_tx_clk_init(struct platform_device *pdev,
- struct hdmi_tx_platform_data *pdata)
-{
- int rc = 0;
- struct device *dev = NULL;
- struct clk *clk = NULL;
-
- if (!pdev || !pdata) {
- DEV_ERR("%s: invalid input\n", __func__);
- return -EINVAL;
- }
- dev = &pdev->dev;
-
- clk = clk_get(dev, "iface_clk");
- rc = IS_ERR(clk);
- if (rc) {
- DEV_ERR("%s: ERROR: '%s' clk not found\n", __func__,
- hdmi_tx_clk_name(HDMI_TX_AHB_CLK));
- goto error;
- }
- pdata->clk[HDMI_TX_AHB_CLK] = clk;
-
- clk = clk_get(dev, "core_clk");
- rc = IS_ERR(clk);
- if (rc) {
- DEV_ERR("%s: ERROR: '%s' clk not found\n", __func__,
- hdmi_tx_clk_name(HDMI_TX_APP_CLK));
- goto error;
- }
- pdata->clk[HDMI_TX_APP_CLK] = clk;
-
- clk = clk_get(dev, "extp_clk");
- rc = IS_ERR(clk);
- if (rc) {
- DEV_ERR("%s: ERROR: '%s' clk not found\n", __func__,
- hdmi_tx_clk_name(HDMI_TX_EXTP_CLK));
- goto error;
- }
- pdata->clk[HDMI_TX_EXTP_CLK] = clk;
-
- return rc;
-
-error:
- hdmi_tx_clk_deinit(pdata);
- return rc;
-} /* hdmi_tx_clk_init */
-
static void hdmi_tx_dev_deinit(struct hdmi_tx_ctrl *hdmi_ctrl)
{
if (!hdmi_ctrl) {
@@ -1785,7 +1569,7 @@
pdata = &hdmi_ctrl->pdata;
- rc = hdmi_tx_check_capability(pdata->io[HDMI_TX_QFPROM_IO].base);
+ rc = hdmi_tx_check_capability(&pdata->io[HDMI_TX_QFPROM_IO]);
if (rc) {
DEV_ERR("%s: no HDMI device\n", __func__);
goto fail_no_hdmi;
@@ -1802,11 +1586,11 @@
goto fail_create_workq;
}
- /* todo: May be move this ? */
- hdmi_ctrl->ddc_ctrl.base = pdata->io[HDMI_TX_CORE_IO].base;
+ hdmi_ctrl->ddc_ctrl.io = &pdata->io[HDMI_TX_CORE_IO];
init_completion(&hdmi_ctrl->ddc_ctrl.ddc_sw_done);
INIT_WORK(&hdmi_ctrl->hpd_state_work, hdmi_tx_hpd_state_work);
+ INIT_WORK(&hdmi_ctrl->hpd_int_work, hdmi_tx_hpd_int_work);
init_timer(&hdmi_ctrl->hpd_state_timer);
hdmi_ctrl->hpd_state_timer.function = hdmi_tx_hpd_state_timer;
hdmi_ctrl->hpd_state_timer.data = (u32)hdmi_ctrl;
@@ -1868,23 +1652,16 @@
return;
}
- /* CLK */
- hdmi_tx_clk_deinit(&hdmi_ctrl->pdata);
-
- /* VREG */
+ /* VREG & CLK */
for (i = HDMI_TX_MAX_PM - 1; i >= 0; i--) {
if (hdmi_tx_config_power(hdmi_ctrl, i, 0))
DEV_ERR("%s: '%s' power deconfig fail\n",
- __func__, hdmi_pm_name(i));
+ __func__, hdmi_tx_pm_name(i));
}
/* IO */
- for (i = HDMI_TX_MAX_IO - 1; i >= 0; i--) {
- if (hdmi_ctrl->pdata.io[i].base)
- iounmap(hdmi_ctrl->pdata.io[i].base);
- hdmi_ctrl->pdata.io[i].base = NULL;
- hdmi_ctrl->pdata.io[i].len = 0;
- }
+ for (i = HDMI_TX_MAX_IO - 1; i >= 0; i--)
+ msm_dss_iounmap(&hdmi_ctrl->pdata.io[i]);
} /* hdmi_tx_deinit_resource */
static int hdmi_tx_init_resource(struct hdmi_tx_ctrl *hdmi_ctrl)
@@ -1913,23 +1690,16 @@
pdata->io[i].len);
}
- /* VREG */
+ /* VREG & CLK */
for (i = 0; i < HDMI_TX_MAX_PM; i++) {
rc = hdmi_tx_config_power(hdmi_ctrl, i, 1);
if (rc) {
DEV_ERR("%s: '%s' power config failed.rc=%d\n",
- __func__, hdmi_pm_name(i), rc);
+ __func__, hdmi_tx_pm_name(i), rc);
goto error;
}
}
- /* CLK */
- rc = hdmi_tx_clk_init(hdmi_ctrl->pdev, pdata);
- if (rc) {
- DEV_ERR("%s: FAILED: clk init. rc=%d\n", __func__, rc);
- goto error;
- }
-
return rc;
error:
@@ -1937,6 +1707,98 @@
return rc;
} /* hdmi_tx_init_resource */
+static void hdmi_tx_put_dt_clk_data(struct device *dev,
+ struct dss_module_power *module_power)
+{
+ if (!module_power) {
+ DEV_ERR("%s: invalid input\n", __func__);
+ return;
+ }
+
+ if (module_power->clk_config) {
+ devm_kfree(dev, module_power->clk_config);
+ module_power->clk_config = NULL;
+ }
+ module_power->num_clk = 0;
+} /* hdmi_tx_put_dt_clk_data */
+
+/* todo: once clk are moved to device tree then change this implementation */
+static int hdmi_tx_get_dt_clk_data(struct device *dev,
+ struct dss_module_power *mp, u32 module_type)
+{
+ int rc = 0;
+
+ if (!dev || !mp) {
+ DEV_ERR("%s: invalid input\n", __func__);
+ rc = -EINVAL;
+ goto error;
+ }
+
+ DEV_DBG("%s: module: '%s'\n", __func__, hdmi_tx_pm_name(module_type));
+
+ switch (module_type) {
+ case HDMI_TX_HPD_PM:
+ mp->num_clk = 2;
+ mp->clk_config = devm_kzalloc(dev, sizeof(struct dss_clk) *
+ mp->num_clk, GFP_KERNEL);
+ if (!mp->clk_config) {
+ DEV_ERR("%s: can't alloc '%s' clk mem\n", __func__,
+ hdmi_tx_pm_name(module_type));
+ goto error;
+ }
+
+ snprintf(mp->clk_config[0].clk_name, 32, "%s", "iface_clk");
+ mp->clk_config[0].type = DSS_CLK_AHB;
+ mp->clk_config[0].rate = 0;
+
+ snprintf(mp->clk_config[1].clk_name, 32, "%s", "core_clk");
+ mp->clk_config[1].type = DSS_CLK_OTHER;
+ mp->clk_config[1].rate = 19200000;
+ break;
+
+ case HDMI_TX_CORE_PM:
+ mp->num_clk = 2;
+ mp->clk_config = devm_kzalloc(dev, sizeof(struct dss_clk) *
+ mp->num_clk, GFP_KERNEL);
+ if (!mp->clk_config) {
+ DEV_ERR("%s: can't alloc '%s' clk mem\n", __func__,
+ hdmi_tx_pm_name(module_type));
+ goto error;
+ }
+
+ snprintf(mp->clk_config[0].clk_name, 32, "%s", "extp_clk");
+ mp->clk_config[0].type = DSS_CLK_PCLK;
+ /* This rate will be overwritten when core is powered on */
+ mp->clk_config[0].rate = 148500000;
+
+ snprintf(mp->clk_config[1].clk_name, 32, "%s", "alt_iface_clk");
+ mp->clk_config[1].type = DSS_CLK_AHB;
+ mp->clk_config[1].rate = 0;
+ break;
+
+ case HDMI_TX_CEC_PM:
+ mp->num_clk = 0;
+ DEV_DBG("%s: no clk\n", __func__);
+ break;
+
+ default:
+ DEV_ERR("%s: invalid module type=%d\n", __func__,
+ module_type);
+ return -EINVAL;
+ }
+
+ return rc;
+
+error:
+ if (mp->clk_config) {
+ devm_kfree(dev, mp->clk_config);
+ mp->clk_config = NULL;
+ }
+ mp->num_clk = 0;
+
+ return rc;
+} /* hdmi_tx_get_dt_clk_data */
+
static void hdmi_tx_put_dt_vreg_data(struct device *dev,
struct dss_module_power *module_power)
{
@@ -1985,7 +1847,7 @@
return -EINVAL;
}
- DEV_DBG("%s: module: '%s'\n", __func__, hdmi_pm_name(module_type));
+ DEV_DBG("%s: module: '%s'\n", __func__, hdmi_tx_pm_name(module_type));
of_node = dev->of_node;
@@ -2025,7 +1887,7 @@
mod_vreg_total, GFP_KERNEL);
if (!mp->vreg_config) {
DEV_ERR("%s: can't alloc '%s' vreg mem\n", __func__,
- hdmi_pm_name(module_type));
+ hdmi_tx_pm_name(module_type));
goto error;
}
} else {
@@ -2070,7 +1932,7 @@
prop_name, val_array, dt_vreg_total);
if (rc) {
DEV_ERR("%s: error read '%s' vreg type. rc=%d\n",
- __func__, hdmi_pm_name(module_type), rc);
+ __func__, hdmi_tx_pm_name(module_type), rc);
goto error;
}
mp->vreg_config[j].type = val_array[i];
@@ -2085,7 +1947,7 @@
dt_vreg_total);
if (rc) {
DEV_ERR("%s: error read '%s' min volt. rc=%d\n",
- __func__, hdmi_pm_name(module_type), rc);
+ __func__, hdmi_tx_pm_name(module_type), rc);
goto error;
}
mp->vreg_config[j].min_voltage = val_array[i];
@@ -2100,7 +1962,7 @@
dt_vreg_total);
if (rc) {
DEV_ERR("%s: error read '%s' max volt. rc=%d\n",
- __func__, hdmi_pm_name(module_type), rc);
+ __func__, hdmi_tx_pm_name(module_type), rc);
goto error;
}
mp->vreg_config[j].max_voltage = val_array[i];
@@ -2115,7 +1977,7 @@
dt_vreg_total);
if (rc) {
DEV_ERR("%s: error read '%s' min volt. rc=%d\n",
- __func__, hdmi_pm_name(module_type), rc);
+ __func__, hdmi_tx_pm_name(module_type), rc);
goto error;
}
mp->vreg_config[j].optimum_voltage = val_array[i];
@@ -2136,8 +1998,12 @@
return rc;
error:
- for (i = HDMI_TX_MAX_PM - 1; i >= 0; i--)
- hdmi_tx_put_dt_vreg_data(dev, mp);
+ if (mp->vreg_config) {
+ devm_kfree(dev, mp->vreg_config);
+ mp->vreg_config = NULL;
+ }
+ mp->num_vreg = 0;
+
if (val_array)
devm_kfree(dev, val_array);
return rc;
@@ -2191,7 +2057,7 @@
return -EINVAL;
}
- DEV_DBG("%s: module: '%s'\n", __func__, hdmi_pm_name(module_type));
+ DEV_DBG("%s: module: '%s'\n", __func__, hdmi_tx_pm_name(module_type));
of_node = dev->of_node;
@@ -2227,7 +2093,7 @@
mod_gpio_total, GFP_KERNEL);
if (!mp->gpio_config) {
DEV_ERR("%s: can't alloc '%s' gpio mem\n", __func__,
- hdmi_pm_name(module_type));
+ hdmi_tx_pm_name(module_type));
goto error;
}
} else {
@@ -2268,8 +2134,11 @@
return rc;
error:
- for (i = HDMI_TX_MAX_PM - 1; i >= 0; i--)
- hdmi_tx_put_dt_gpio_data(dev, mp);
+ if (mp->gpio_config) {
+ devm_kfree(dev, mp->gpio_config);
+ mp->gpio_config = NULL;
+ }
+ mp->num_gpio = 0;
return rc;
} /* hdmi_tx_get_dt_gpio_data */
@@ -2284,6 +2153,9 @@
}
for (i = HDMI_TX_MAX_PM - 1; i >= 0; i--)
+ hdmi_tx_put_dt_clk_data(dev, &pdata->power_data[i]);
+
+ for (i = HDMI_TX_MAX_PM - 1; i >= 0; i--)
hdmi_tx_put_dt_vreg_data(dev, &pdata->power_data[i]);
for (i = HDMI_TX_MAX_PM - 1; i >= 0; i--)
@@ -2317,7 +2189,7 @@
&pdata->power_data[i], i);
if (rc) {
DEV_ERR("%s: '%s' get_dt_gpio_data failed.rc=%d\n",
- __func__, hdmi_pm_name(i), rc);
+ __func__, hdmi_tx_pm_name(i), rc);
goto error;
}
}
@@ -2328,7 +2200,18 @@
&pdata->power_data[i], i);
if (rc) {
DEV_ERR("%s: '%s' get_dt_vreg_data failed.rc=%d\n",
- __func__, hdmi_pm_name(i), rc);
+ __func__, hdmi_tx_pm_name(i), rc);
+ goto error;
+ }
+ }
+
+ /* CLK */
+ for (i = 0; i < HDMI_TX_MAX_PM; i++) {
+ rc = hdmi_tx_get_dt_clk_data(&pdev->dev,
+ &pdata->power_data[i], i);
+ if (rc) {
+ DEV_ERR("%s: '%s' get_dt_clk_data failed.rc=%d\n",
+ __func__, hdmi_tx_pm_name(i), rc);
goto error;
}
}
diff --git a/drivers/video/msm/mdss/mdss_hdmi_tx.h b/drivers/video/msm/mdss/mdss_hdmi_tx.h
index 7e37d28..94e0fda 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_tx.h
+++ b/drivers/video/msm/mdss/mdss_hdmi_tx.h
@@ -15,14 +15,6 @@
#include <linux/switch.h>
#include "mdss_hdmi_util.h"
-#include "mdss_io_util.h"
-
-enum hdmi_tx_clk_type {
- HDMI_TX_AHB_CLK,
- HDMI_TX_APP_CLK,
- HDMI_TX_EXTP_CLK,
- HDMI_TX_MAX_CLK
-};
enum hdmi_tx_io_type {
HDMI_TX_CORE_IO,
@@ -42,9 +34,6 @@
/* Data filled from device tree nodes */
struct dss_io_data io[HDMI_TX_MAX_IO];
struct dss_module_power power_data[HDMI_TX_MAX_PM];
-
- /* clk and regulator handles */
- struct clk *clk[HDMI_TX_MAX_CLK];
};
struct hdmi_tx_ctrl {
@@ -67,6 +56,7 @@
u32 hpd_state;
u32 hpd_feature_on;
struct work_struct hpd_state_work;
+ struct work_struct hpd_int_work;
struct timer_list hpd_state_timer;
unsigned long pixel_clk;
diff --git a/drivers/video/msm/mdss/mdss_hdmi_util.c b/drivers/video/msm/mdss/mdss_hdmi_util.c
index 3ba9f89..e7ea8c9 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_util.c
+++ b/drivers/video/msm/mdss/mdss_hdmi_util.c
@@ -15,226 +15,6 @@
#include <mach/board.h>
#include "mdss_hdmi_util.h"
-const char *hdmi_reg_name(u32 offset)
-{
- switch (offset) {
- case 0x00000000: return "HDMI_CTRL";
- case 0x00000010: return "HDMI_TEST_PATTERN";
- case 0x00000014: return "HDMI_RANDOM_PATTERN";
- case 0x00000018: return "HDMI_PKT_BLK_CTRL";
- case 0x0000001C: return "HDMI_STATUS";
- case 0x00000020: return "HDMI_AUDIO_PKT_CTRL";
- case 0x00000024: return "HDMI_ACR_PKT_CTRL";
- case 0x00000028: return "HDMI_VBI_PKT_CTRL";
- case 0x0000002C: return "HDMI_INFOFRAME_CTRL0";
- case 0x00000030: return "HDMI_INFOFRAME_CTRL1";
- case 0x00000034: return "HDMI_GEN_PKT_CTRL";
- case 0x0000003C: return "HDMI_ACP";
- case 0x00000040: return "HDMI_GC";
- case 0x00000044: return "HDMI_AUDIO_PKT_CTRL2";
- case 0x00000048: return "HDMI_ISRC1_0";
- case 0x0000004C: return "HDMI_ISRC1_1";
- case 0x00000050: return "HDMI_ISRC1_2";
- case 0x00000054: return "HDMI_ISRC1_3";
- case 0x00000058: return "HDMI_ISRC1_4";
- case 0x0000005C: return "HDMI_ISRC2_0";
- case 0x00000060: return "HDMI_ISRC2_1";
- case 0x00000064: return "HDMI_ISRC2_2";
- case 0x00000068: return "HDMI_ISRC2_3";
- case 0x0000006C: return "HDMI_AVI_INFO0";
- case 0x00000070: return "HDMI_AVI_INFO1";
- case 0x00000074: return "HDMI_AVI_INFO2";
- case 0x00000078: return "HDMI_AVI_INFO3";
- case 0x0000007C: return "HDMI_MPEG_INFO0";
- case 0x00000080: return "HDMI_MPEG_INFO1";
- case 0x00000084: return "HDMI_GENERIC0_HDR";
- case 0x00000088: return "HDMI_GENERIC0_0";
- case 0x0000008C: return "HDMI_GENERIC0_1";
- case 0x00000090: return "HDMI_GENERIC0_2";
- case 0x00000094: return "HDMI_GENERIC0_3";
- case 0x00000098: return "HDMI_GENERIC0_4";
- case 0x0000009C: return "HDMI_GENERIC0_5";
- case 0x000000A0: return "HDMI_GENERIC0_6";
- case 0x000000A4: return "HDMI_GENERIC1_HDR";
- case 0x000000A8: return "HDMI_GENERIC1_0";
- case 0x000000AC: return "HDMI_GENERIC1_1";
- case 0x000000B0: return "HDMI_GENERIC1_2";
- case 0x000000B4: return "HDMI_GENERIC1_3";
- case 0x000000B8: return "HDMI_GENERIC1_4";
- case 0x000000BC: return "HDMI_GENERIC1_5";
- case 0x000000C0: return "HDMI_GENERIC1_6";
- case 0x000000C4: return "HDMI_ACR_32_0";
- case 0x000000C8: return "HDMI_ACR_32_1";
- case 0x000000CC: return "HDMI_ACR_44_0";
- case 0x000000D0: return "HDMI_ACR_44_1";
- case 0x000000D4: return "HDMI_ACR_48_0";
- case 0x000000D8: return "HDMI_ACR_48_1";
- case 0x000000DC: return "HDMI_ACR_STATUS_0";
- case 0x000000E0: return "HDMI_ACR_STATUS_1";
- case 0x000000E4: return "HDMI_AUDIO_INFO0";
- case 0x000000E8: return "HDMI_AUDIO_INFO1";
- case 0x000000EC: return "HDMI_CS_60958_0";
- case 0x000000F0: return "HDMI_CS_60958_1";
- case 0x000000F8: return "HDMI_RAMP_CTRL0";
- case 0x000000FC: return "HDMI_RAMP_CTRL1";
- case 0x00000100: return "HDMI_RAMP_CTRL2";
- case 0x00000104: return "HDMI_RAMP_CTRL3";
- case 0x00000108: return "HDMI_CS_60958_2";
- case 0x00000110: return "HDMI_HDCP_CTRL";
- case 0x00000114: return "HDMI_HDCP_DEBUG_CTRL";
- case 0x00000118: return "HDMI_HDCP_INT_CTRL";
- case 0x0000011C: return "HDMI_HDCP_LINK0_STATUS";
- case 0x00000120: return "HDMI_HDCP_DDC_CTRL_0";
- case 0x00000124: return "HDMI_HDCP_DDC_CTRL_1";
- case 0x00000128: return "HDMI_HDCP_DDC_STATUS";
- case 0x0000012C: return "HDMI_HDCP_ENTROPY_CTRL0";
- case 0x00000130: return "HDMI_HDCP_RESET";
- case 0x00000134: return "HDMI_HDCP_RCVPORT_DATA0";
- case 0x00000138: return "HDMI_HDCP_RCVPORT_DATA1";
- case 0x0000013C: return "HDMI_HDCP_RCVPORT_DATA2_0";
- case 0x00000140: return "HDMI_HDCP_RCVPORT_DATA2_1";
- case 0x00000144: return "HDMI_HDCP_RCVPORT_DATA3";
- case 0x00000148: return "HDMI_HDCP_RCVPORT_DATA4";
- case 0x0000014C: return "HDMI_HDCP_RCVPORT_DATA5";
- case 0x00000150: return "HDMI_HDCP_RCVPORT_DATA6";
- case 0x00000154: return "HDMI_HDCP_RCVPORT_DATA7";
- case 0x00000158: return "HDMI_HDCP_RCVPORT_DATA8";
- case 0x0000015C: return "HDMI_HDCP_RCVPORT_DATA9";
- case 0x00000160: return "HDMI_HDCP_RCVPORT_DATA10";
- case 0x00000164: return "HDMI_HDCP_RCVPORT_DATA11";
- case 0x00000168: return "HDMI_HDCP_RCVPORT_DATA12";
- case 0x0000016C: return "HDMI_VENSPEC_INFO0";
- case 0x00000170: return "HDMI_VENSPEC_INFO1";
- case 0x00000174: return "HDMI_VENSPEC_INFO2";
- case 0x00000178: return "HDMI_VENSPEC_INFO3";
- case 0x0000017C: return "HDMI_VENSPEC_INFO4";
- case 0x00000180: return "HDMI_VENSPEC_INFO5";
- case 0x00000184: return "HDMI_VENSPEC_INFO6";
- case 0x00000194: return "HDMI_HDCP_DEBUG";
- case 0x0000019C: return "HDMI_TMDS_CTRL_CHAR";
- case 0x000001A4: return "HDMI_TMDS_CTRL_SEL";
- case 0x000001A8: return "HDMI_TMDS_SYNCCHAR01";
- case 0x000001AC: return "HDMI_TMDS_SYNCCHAR23";
- case 0x000001B4: return "HDMI_TMDS_DEBUG";
- case 0x000001B8: return "HDMI_TMDS_CTL_BITS";
- case 0x000001BC: return "HDMI_TMDS_DCBAL_CTRL";
- case 0x000001C0: return "HDMI_TMDS_DCBAL_CHAR";
- case 0x000001C8: return "HDMI_TMDS_CTL01_GEN";
- case 0x000001CC: return "HDMI_TMDS_CTL23_GEN";
- case 0x000001D0: return "HDMI_AUDIO_CFG";
- case 0x00000204: return "HDMI_DEBUG";
- case 0x00000208: return "HDMI_USEC_REFTIMER";
- case 0x0000020C: return "HDMI_DDC_CTRL";
- case 0x00000210: return "HDMI_DDC_ARBITRATION";
- case 0x00000214: return "HDMI_DDC_INT_CTRL";
- case 0x00000218: return "HDMI_DDC_SW_STATUS";
- case 0x0000021C: return "HDMI_DDC_HW_STATUS";
- case 0x00000220: return "HDMI_DDC_SPEED";
- case 0x00000224: return "HDMI_DDC_SETUP";
- case 0x00000228: return "HDMI_DDC_TRANS0";
- case 0x0000022C: return "HDMI_DDC_TRANS1";
- case 0x00000230: return "HDMI_DDC_TRANS2";
- case 0x00000234: return "HDMI_DDC_TRANS3";
- case 0x00000238: return "HDMI_DDC_DATA";
- case 0x0000023C: return "HDMI_HDCP_SHA_CTRL";
- case 0x00000240: return "HDMI_HDCP_SHA_STATUS";
- case 0x00000244: return "HDMI_HDCP_SHA_DATA";
- case 0x00000248: return "HDMI_HDCP_SHA_DBG_M0_0";
- case 0x0000024C: return "HDMI_HDCP_SHA_DBG_M0_1";
- case 0x00000250: return "HDMI_HPD_INT_STATUS";
- case 0x00000254: return "HDMI_HPD_INT_CTRL";
- case 0x00000258: return "HDMI_HPD_CTRL";
- case 0x0000025C: return "HDMI_HDCP_ENTROPY_CTRL1";
- case 0x00000260: return "HDMI_HDCP_SW_UPPER_AN";
- case 0x00000264: return "HDMI_HDCP_SW_LOWER_AN";
- case 0x00000268: return "HDMI_CRC_CTRL";
- case 0x0000026C: return "HDMI_VID_CRC";
- case 0x00000270: return "HDMI_AUD_CRC";
- case 0x00000274: return "HDMI_VBI_CRC";
- case 0x0000027C: return "HDMI_DDC_REF";
- case 0x00000284: return "HDMI_HDCP_SW_UPPER_AKSV";
- case 0x00000288: return "HDMI_HDCP_SW_LOWER_AKSV";
- case 0x0000028C: return "HDMI_CEC_CTRL";
- case 0x00000290: return "HDMI_CEC_WR_DATA";
- case 0x00000294: return "HDMI_CEC_RETRANSMIT";
- case 0x00000298: return "HDMI_CEC_STATUS";
- case 0x0000029C: return "HDMI_CEC_INT";
- case 0x000002A0: return "HDMI_CEC_ADDR";
- case 0x000002A4: return "HDMI_CEC_TIME";
- case 0x000002A8: return "HDMI_CEC_REFTIMER";
- case 0x000002AC: return "HDMI_CEC_RD_DATA";
- case 0x000002B0: return "HDMI_CEC_RD_FILTER";
- case 0x000002B4: return "HDMI_ACTIVE_H";
- case 0x000002B8: return "HDMI_ACTIVE_V";
- case 0x000002BC: return "HDMI_ACTIVE_V_F2";
- case 0x000002C0: return "HDMI_TOTAL";
- case 0x000002C4: return "HDMI_V_TOTAL_F2";
- case 0x000002C8: return "HDMI_FRAME_CTRL";
- case 0x000002CC: return "HDMI_AUD_INT";
- case 0x000002D0: return "HDMI_DEBUG_BUS_CTRL";
- case 0x000002D4: return "HDMI_PHY_CTRL";
- case 0x000002DC: return "HDMI_CEC_WR_RANGE";
- case 0x000002E0: return "HDMI_CEC_RD_RANGE";
- case 0x000002E4: return "HDMI_VERSION";
- case 0x000002F4: return "HDMI_BIST_ENABLE";
- case 0x000002F8: return "HDMI_TIMING_ENGINE_EN";
- case 0x000002FC: return "HDMI_INTF_CONFIG";
- case 0x00000300: return "HDMI_HSYNC_CTL";
- case 0x00000304: return "HDMI_VSYNC_PERIOD_F0";
- case 0x00000308: return "HDMI_VSYNC_PERIOD_F1";
- case 0x0000030C: return "HDMI_VSYNC_PULSE_WIDTH_F0";
- case 0x00000310: return "HDMI_VSYNC_PULSE_WIDTH_F1";
- case 0x00000314: return "HDMI_DISPLAY_V_START_F0";
- case 0x00000318: return "HDMI_DISPLAY_V_START_F1";
- case 0x0000031C: return "HDMI_DISPLAY_V_END_F0";
- case 0x00000320: return "HDMI_DISPLAY_V_END_F1";
- case 0x00000324: return "HDMI_ACTIVE_V_START_F0";
- case 0x00000328: return "HDMI_ACTIVE_V_START_F1";
- case 0x0000032C: return "HDMI_ACTIVE_V_END_F0";
- case 0x00000330: return "HDMI_ACTIVE_V_END_F1";
- case 0x00000334: return "HDMI_DISPLAY_HCTL";
- case 0x00000338: return "HDMI_ACTIVE_HCTL";
- case 0x0000033C: return "HDMI_HSYNC_SKEW";
- case 0x00000340: return "HDMI_POLARITY_CTL";
- case 0x00000344: return "HDMI_TPG_MAIN_CONTROL";
- case 0x00000348: return "HDMI_TPG_VIDEO_CONFIG";
- case 0x0000034C: return "HDMI_TPG_COMPONENT_LIMITS";
- case 0x00000350: return "HDMI_TPG_RECTANGLE";
- case 0x00000354: return "HDMI_TPG_INITIAL_VALUE";
- case 0x00000358: return "HDMI_TPG_BLK_WHT_PATTERN_FRAMES";
- case 0x0000035C: return "HDMI_TPG_RGB_MAPPING";
- default: return "???";
- }
-} /* hdmi_reg_name */
-
-void hdmi_reg_w(void __iomem *addr, u32 offset, u32 value, u32 debug)
-{
- u32 in_val;
-
- writel_relaxed(value, addr+offset);
- if (debug && PORT_DEBUG) {
- in_val = readl_relaxed(addr+offset);
- DEV_DBG("HDMI[%04x] => %08x [%08x] %s\n", offset, value,
- in_val, hdmi_reg_name(offset));
- }
-} /* hdmi_reg_w */
-
-u32 hdmi_reg_r(void __iomem *addr, u32 offset, u32 debug)
-{
- u32 value = readl_relaxed(addr+offset);
- if (debug && PORT_DEBUG)
- DEV_DBG("HDMI[%04x] <= %08x %s\n", offset, value,
- hdmi_reg_name(offset));
- return value;
-} /* hdmi_reg_r */
-
-void hdmi_reg_dump(void __iomem *base, u32 length, const char *prefix)
-{
- if (REG_DUMP)
- print_hex_dump(KERN_INFO, prefix, DUMP_PREFIX_OFFSET, 32, 4,
- (void *)base, length, false);
-} /* hdmi_reg_dump */
-
static struct hdmi_disp_mode_timing_type
hdmi_supported_video_mode_lut[HDMI_VFRMT_MAX] = {
HDMI_SETTINGS_640x480p60_4_3,
@@ -505,7 +285,7 @@
{
u32 reg_val, time_out_count;
- if (!ddc_ctrl || !ddc_ctrl->base) {
+ if (!ddc_ctrl || !ddc_ctrl->io) {
DEV_ERR("%s: invalid input\n", __func__);
return -EINVAL;
}
@@ -515,9 +295,9 @@
do {
--time_out_count;
/* Clear and Enable DDC interrupt */
- HDMI_REG_W_ND(ddc_ctrl->base, HDMI_DDC_INT_CTRL,
+ DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_INT_CTRL,
BIT(2) | BIT(1));
- reg_val = HDMI_REG_R_ND(ddc_ctrl->base, HDMI_DDC_INT_CTRL);
+ reg_val = DSS_REG_R_ND(ddc_ctrl->io, HDMI_DDC_INT_CTRL);
} while ((reg_val & BIT(0)) && time_out_count);
if (!time_out_count) {
@@ -535,7 +315,7 @@
int status = 0;
int log_retry_fail;
- if (!ddc_ctrl || !ddc_ctrl->base || !ddc_data) {
+ if (!ddc_ctrl || !ddc_ctrl->io || !ddc_data) {
DEV_ERR("%s: invalid input\n", __func__);
return -EINVAL;
}
@@ -565,7 +345,7 @@
* INDEX = 0x0 (initial offset into buffer)
* INDEX_WRITE = 0x1 (setting initial offset)
*/
- HDMI_REG_W_ND(ddc_ctrl->base, HDMI_DDC_DATA,
+ DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_DATA,
BIT(31) | (ddc_data->dev_addr << 8));
/*
@@ -576,7 +356,7 @@
* INDEX = 0x0
* INDEX_WRITE = 0x0 (auto-increment by hardware)
*/
- HDMI_REG_W_ND(ddc_ctrl->base, HDMI_DDC_DATA, ddc_data->offset << 8);
+ DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_DATA, ddc_data->offset << 8);
/*
* 3. Write to HDMI_I2C_DATA with the following fields set in order to
@@ -586,7 +366,7 @@
* INDEX = 0x0
* INDEX_WRITE = 0x0 (auto-increment by hardware)
*/
- HDMI_REG_W_ND(ddc_ctrl->base, HDMI_DDC_DATA,
+ DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_DATA,
(ddc_data->dev_addr | BIT(0)) << 8);
/* Data setup is complete, now setup the transaction characteristics */
@@ -599,7 +379,7 @@
* STOP0 = 0x0 (do NOT insert STOP bit)
* CNT0 = 0x1 (single byte transaction excluding address)
*/
- HDMI_REG_W_ND(ddc_ctrl->base, HDMI_DDC_TRANS0, BIT(12) | BIT(16));
+ DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_TRANS0, BIT(12) | BIT(16));
/*
* 5. Write to HDMI_I2C_TRANSACTION1 with the following fields set in
@@ -609,7 +389,7 @@
* STOP1 = 0x1 (insert STOP bit)
* CNT1 = data_len (it's 128 (0x80) for a blk read)
*/
- HDMI_REG_W_ND(ddc_ctrl->base, HDMI_DDC_TRANS1,
+ DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_TRANS1,
BIT(0) | BIT(12) | BIT(13) | (ddc_data->request_len << 16));
/* Trigger the I2C transfer */
@@ -624,11 +404,11 @@
* GO = 0x1 (kicks off hardware)
*/
INIT_COMPLETION(ddc_ctrl->ddc_sw_done);
- HDMI_REG_W_ND(ddc_ctrl->base, HDMI_DDC_CTRL, BIT(0) | BIT(20));
+ DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_CTRL, BIT(0) | BIT(20));
time_out_count = wait_for_completion_interruptible_timeout(
&ddc_ctrl->ddc_sw_done, HZ/2);
- HDMI_REG_W_ND(ddc_ctrl->base, HDMI_DDC_INT_CTRL, BIT(1));
+ DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_INT_CTRL, BIT(1));
if (!time_out_count) {
if (ddc_data->retry-- > 0) {
DEV_INFO("%s: failed timout, retry=%d\n", __func__,
@@ -637,26 +417,26 @@
}
status = -ETIMEDOUT;
DEV_ERR("%s: timedout(7), Int Ctrl=%08x\n", __func__,
- HDMI_REG_R(ddc_ctrl->base, HDMI_DDC_INT_CTRL));
+ DSS_REG_R(ddc_ctrl->io, HDMI_DDC_INT_CTRL));
DEV_ERR("%s: DDC SW Status=%08x, HW Status=%08x\n",
__func__,
- HDMI_REG_R(ddc_ctrl->base, HDMI_DDC_SW_STATUS),
- HDMI_REG_R(ddc_ctrl->base, HDMI_DDC_HW_STATUS));
+ DSS_REG_R(ddc_ctrl->io, HDMI_DDC_SW_STATUS),
+ DSS_REG_R(ddc_ctrl->io, HDMI_DDC_HW_STATUS));
goto error;
}
/* Read DDC status */
- reg_val = HDMI_REG_R(ddc_ctrl->base, HDMI_DDC_SW_STATUS);
+ reg_val = DSS_REG_R(ddc_ctrl->io, HDMI_DDC_SW_STATUS);
reg_val &= BIT(12) | BIT(13) | BIT(14) | BIT(15);
/* Check if any NACK occurred */
if (reg_val) {
/* SW_STATUS_RESET */
- HDMI_REG_W_ND(ddc_ctrl->base, HDMI_DDC_CTRL, BIT(3));
+ DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_CTRL, BIT(3));
if (ddc_data->retry == 1)
/* SOFT_RESET */
- HDMI_REG_W_ND(ddc_ctrl->base, HDMI_DDC_CTRL, BIT(1));
+ DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_CTRL, BIT(1));
if (ddc_data->retry-- > 0) {
DEV_DBG("%s(%s): failed NACK=0x%08x, retry=%d\n",
@@ -687,13 +467,13 @@
* INDEX_WRITE = 0x1 (explicitly define offset)
*/
/* Write this data to DDC buffer */
- HDMI_REG_W_ND(ddc_ctrl->base, HDMI_DDC_DATA,
+ DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_DATA,
BIT(0) | (3 << 16) | BIT(31));
/* Discard first byte */
- HDMI_REG_R_ND(ddc_ctrl->base, HDMI_DDC_DATA);
+ DSS_REG_R_ND(ddc_ctrl->io, HDMI_DDC_DATA);
for (ndx = 0; ndx < ddc_data->data_len; ++ndx) {
- reg_val = HDMI_REG_R_ND(ddc_ctrl->base, HDMI_DDC_DATA);
+ reg_val = DSS_REG_R_ND(ddc_ctrl->io, HDMI_DDC_DATA);
ddc_data->data_buf[ndx] = (u8)((reg_val & 0x0000FF00) >> 8);
}
@@ -705,46 +485,44 @@
void hdmi_ddc_config(struct hdmi_tx_ddc_ctrl *ddc_ctrl)
{
- if (!ddc_ctrl || !ddc_ctrl->base) {
+ if (!ddc_ctrl || !ddc_ctrl->io) {
DEV_ERR("%s: invalid input\n", __func__);
return;
}
/* Configure Pre-Scale multiplier & Threshold */
- HDMI_REG_W_ND(ddc_ctrl->base, HDMI_DDC_SPEED, (10 << 16) | (2 << 0));
+ DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_SPEED, (10 << 16) | (2 << 0));
/*
* Setting 31:24 bits : Time units to wait before timeout
* when clock is being stalled by external sink device
*/
- HDMI_REG_W_ND(ddc_ctrl->base, HDMI_DDC_SETUP, 0xFF000000);
+ DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_SETUP, 0xFF000000);
/* Enable reference timer to 27 micro-seconds */
- HDMI_REG_W_ND(ddc_ctrl->base, HDMI_DDC_REF, (1 << 16) | (27 << 0));
+ DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_REF, (1 << 16) | (27 << 0));
} /* hdmi_ddc_config */
int hdmi_ddc_isr(struct hdmi_tx_ddc_ctrl *ddc_ctrl)
{
- int rc = -1;
u32 ddc_int_ctrl;
- if (!ddc_ctrl || !ddc_ctrl->base) {
+ if (!ddc_ctrl || !ddc_ctrl->io) {
DEV_ERR("%s: invalid input\n", __func__);
return -EINVAL;
}
- ddc_int_ctrl = HDMI_REG_R_ND(ddc_ctrl->base, HDMI_DDC_INT_CTRL);
+ ddc_int_ctrl = DSS_REG_R_ND(ddc_ctrl->io, HDMI_DDC_INT_CTRL);
if ((ddc_int_ctrl & BIT(2)) && (ddc_int_ctrl & BIT(0))) {
/* SW_DONE INT occured, clr it */
- HDMI_REG_W_ND(ddc_ctrl->base, HDMI_DDC_INT_CTRL,
+ DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_INT_CTRL,
ddc_int_ctrl | BIT(1));
complete(&ddc_ctrl->ddc_sw_done);
- return 0;
}
DEV_DBG("%s: ddc_int_ctrl=%04x\n", __func__, ddc_int_ctrl);
- return rc;
+ return 0;
} /* hdmi_ddc_isr */
int hdmi_ddc_read(struct hdmi_tx_ddc_ctrl *ddc_ctrl,
@@ -779,7 +557,7 @@
int log_retry_fail;
int seg_addr = 0x60, seg_num = 0x01;
- if (!ddc_ctrl || !ddc_ctrl->base || !ddc_data) {
+ if (!ddc_ctrl || !ddc_ctrl->io || !ddc_data) {
DEV_ERR("%s: invalid input\n", __func__);
return -EINVAL;
}
@@ -808,7 +586,7 @@
* INDEX = 0x0 (initial offset into buffer)
* INDEX_WRITE = 0x1 (setting initial offset)
*/
- HDMI_REG_W_ND(ddc_ctrl->base, HDMI_DDC_DATA, BIT(31) | (seg_addr << 8));
+ DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_DATA, BIT(31) | (seg_addr << 8));
/*
* 2. Write to HDMI_I2C_DATA with the following fields set in order to
@@ -818,7 +596,7 @@
* INDEX = 0x0
* INDEX_WRITE = 0x0 (auto-increment by hardware)
*/
- HDMI_REG_W_ND(ddc_ctrl->base, HDMI_DDC_DATA, seg_num << 8);
+ DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_DATA, seg_num << 8);
/*
* 3. Write to HDMI_I2C_DATA with the following fields set in order to
@@ -828,9 +606,9 @@
* INDEX = 0x0
* INDEX_WRITE = 0x0 (auto-increment by hardware)
*/
- HDMI_REG_W_ND(ddc_ctrl->base, HDMI_DDC_DATA, ddc_data->dev_addr << 8);
- HDMI_REG_W_ND(ddc_ctrl->base, HDMI_DDC_DATA, ddc_data->offset << 8);
- HDMI_REG_W_ND(ddc_ctrl->base, HDMI_DDC_DATA,
+ DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_DATA, ddc_data->dev_addr << 8);
+ DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_DATA, ddc_data->offset << 8);
+ DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_DATA,
(ddc_data->dev_addr | BIT(0)) << 8);
/* Data setup is complete, now setup the transaction characteristics */
@@ -843,7 +621,7 @@
* STOP0 = 0x0 (do NOT insert STOP bit)
* CNT0 = 0x1 (single byte transaction excluding address)
*/
- HDMI_REG_W_ND(ddc_ctrl->base, HDMI_DDC_TRANS0, BIT(12) | BIT(16));
+ DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_TRANS0, BIT(12) | BIT(16));
/*
* 5. Write to HDMI_I2C_TRANSACTION1 with the following fields set in
@@ -853,7 +631,7 @@
* STOP1 = 0x1 (insert STOP bit)
* CNT1 = data_len (it's 128 (0x80) for a blk read)
*/
- HDMI_REG_W_ND(ddc_ctrl->base, HDMI_DDC_TRANS1, BIT(12) | BIT(16));
+ DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_TRANS1, BIT(12) | BIT(16));
/*
* 5. Write to HDMI_I2C_TRANSACTION1 with the following fields set in
@@ -863,7 +641,7 @@
* STOP1 = 0x1 (insert STOP bit)
* CNT1 = data_len (it's 128 (0x80) for a blk read)
*/
- HDMI_REG_W_ND(ddc_ctrl->base, HDMI_DDC_TRANS2,
+ DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_TRANS2,
BIT(0) | BIT(12) | BIT(13) | (ddc_data->request_len << 16));
/* Trigger the I2C transfer */
@@ -877,13 +655,13 @@
* GO = 0x1 (kicks off hardware)
*/
INIT_COMPLETION(ddc_ctrl->ddc_sw_done);
- HDMI_REG_W_ND(ddc_ctrl->base, HDMI_DDC_CTRL, BIT(0) | BIT(21));
+ DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_CTRL, BIT(0) | BIT(21));
time_out_count = wait_for_completion_interruptible_timeout(
&ddc_ctrl->ddc_sw_done, HZ/2);
- reg_val = HDMI_REG_R(ddc_ctrl->base, HDMI_DDC_INT_CTRL);
- HDMI_REG_W_ND(ddc_ctrl->base, HDMI_DDC_INT_CTRL, reg_val & (~BIT(2)));
+ reg_val = DSS_REG_R(ddc_ctrl->io, HDMI_DDC_INT_CTRL);
+ DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_INT_CTRL, reg_val & (~BIT(2)));
if (!time_out_count) {
if (ddc_data->retry-- > 0) {
DEV_INFO("%s: failed timout, retry=%d\n", __func__,
@@ -892,25 +670,25 @@
}
status = -ETIMEDOUT;
DEV_ERR("%s: timedout(7), Int Ctrl=%08x\n", __func__,
- HDMI_REG_R(ddc_ctrl->base, HDMI_DDC_INT_CTRL));
+ DSS_REG_R(ddc_ctrl->io, HDMI_DDC_INT_CTRL));
DEV_ERR("%s: DDC SW Status=%08x, HW Status=%08x\n",
__func__,
- HDMI_REG_R(ddc_ctrl->base, HDMI_DDC_SW_STATUS),
- HDMI_REG_R(ddc_ctrl->base, HDMI_DDC_HW_STATUS));
+ DSS_REG_R(ddc_ctrl->io, HDMI_DDC_SW_STATUS),
+ DSS_REG_R(ddc_ctrl->io, HDMI_DDC_HW_STATUS));
goto error;
}
/* Read DDC status */
- reg_val = HDMI_REG_R(ddc_ctrl->base, HDMI_DDC_SW_STATUS);
+ reg_val = DSS_REG_R(ddc_ctrl->io, HDMI_DDC_SW_STATUS);
reg_val &= BIT(12) | BIT(13) | BIT(14) | BIT(15);
/* Check if any NACK occurred */
if (reg_val) {
/* SW_STATUS_RESET */
- HDMI_REG_W_ND(ddc_ctrl->base, HDMI_DDC_CTRL, BIT(3));
+ DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_CTRL, BIT(3));
if (ddc_data->retry == 1)
/* SOFT_RESET */
- HDMI_REG_W_ND(ddc_ctrl->base, HDMI_DDC_CTRL, BIT(1));
+ DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_CTRL, BIT(1));
if (ddc_data->retry-- > 0) {
DEV_DBG("%s(%s): failed NACK=0x%08x, retry=%d\n",
__func__, ddc_data->what, reg_val,
@@ -940,14 +718,14 @@
* INDEX_WRITE = 0x1 (explicitly define offset)
*/
/* Write this data to DDC buffer */
- HDMI_REG_W_ND(ddc_ctrl->base, HDMI_DDC_DATA,
+ DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_DATA,
BIT(0) | (5 << 16) | BIT(31));
/* Discard first byte */
- HDMI_REG_R_ND(ddc_ctrl->base, HDMI_DDC_DATA);
+ DSS_REG_R_ND(ddc_ctrl->io, HDMI_DDC_DATA);
for (ndx = 0; ndx < ddc_data->data_len; ++ndx) {
- reg_val = HDMI_REG_R_ND(ddc_ctrl->base, HDMI_DDC_DATA);
+ reg_val = DSS_REG_R_ND(ddc_ctrl->io, HDMI_DDC_DATA);
ddc_data->data_buf[ndx] = (u8) ((reg_val & 0x0000FF00) >> 8);
}
@@ -964,7 +742,7 @@
int status = 0, retry = 10;
u32 time_out_count;
- if (!ddc_ctrl || !ddc_ctrl->base || !ddc_data) {
+ if (!ddc_ctrl || !ddc_ctrl->io || !ddc_data) {
DEV_ERR("%s: invalid input\n", __func__);
return -EINVAL;
}
@@ -991,7 +769,7 @@
* INDEX = 0x0 (initial offset into buffer)
* INDEX_WRITE = 0x1 (setting initial offset)
*/
- HDMI_REG_W_ND(ddc_ctrl->base, HDMI_DDC_DATA,
+ DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_DATA,
BIT(31) | (ddc_data->dev_addr << 8));
/*
@@ -1002,7 +780,7 @@
* INDEX = 0x0
* INDEX_WRITE = 0x0 (auto-increment by hardware)
*/
- HDMI_REG_W_ND(ddc_ctrl->base, HDMI_DDC_DATA, ddc_data->offset << 8);
+ DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_DATA, ddc_data->offset << 8);
/*
* 3. Write to HDMI_I2C_DATA with the following fields set in order to
@@ -1013,7 +791,7 @@
* INDEX_WRITE = 0x0 (auto-increment by hardware)
*/
for (ndx = 0; ndx < ddc_data->data_len; ++ndx)
- HDMI_REG_W_ND(ddc_ctrl->base, HDMI_DDC_DATA,
+ DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_DATA,
((u32)ddc_data->data_buf[ndx]) << 8);
/* Data setup is complete, now setup the transaction characteristics */
@@ -1026,7 +804,7 @@
* STOP0 = 0x0 (do NOT insert STOP bit)
* CNT0 = 0x1 (single byte transaction excluding address)
*/
- HDMI_REG_W_ND(ddc_ctrl->base, HDMI_DDC_TRANS0, BIT(12) | BIT(16));
+ DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_TRANS0, BIT(12) | BIT(16));
/*
* 5. Write to HDMI_I2C_TRANSACTION1 with the following fields set in
@@ -1038,7 +816,7 @@
* Byte count for second transition (excluding the first
* Byte which is usually the address)
*/
- HDMI_REG_W_ND(ddc_ctrl->base, HDMI_DDC_TRANS1,
+ DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_TRANS1,
BIT(13) | ((ddc_data->data_len-1) << 16));
/* Trigger the I2C transfer */
@@ -1051,13 +829,13 @@
* GO = 0x1 (kicks off hardware)
*/
INIT_COMPLETION(ddc_ctrl->ddc_sw_done);
- HDMI_REG_W_ND(ddc_ctrl->base, HDMI_DDC_CTRL, BIT(0) | BIT(20));
+ DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_CTRL, BIT(0) | BIT(20));
time_out_count = wait_for_completion_interruptible_timeout(
&ddc_ctrl->ddc_sw_done, HZ/2);
- reg_val = HDMI_REG_R(ddc_ctrl->base, HDMI_DDC_INT_CTRL);
- HDMI_REG_W_ND(ddc_ctrl->base, HDMI_DDC_INT_CTRL, reg_val & (~BIT(2)));
+ reg_val = DSS_REG_R(ddc_ctrl->io, HDMI_DDC_INT_CTRL);
+ DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_INT_CTRL, reg_val & (~BIT(2)));
if (!time_out_count) {
if (retry-- > 0) {
DEV_INFO("%s[%s]: failed timout, retry=%d\n", __func__,
@@ -1067,26 +845,26 @@
status = -ETIMEDOUT;
DEV_ERR("%s[%s]: timedout, Int Ctrl=%08x\n",
__func__, ddc_data->what,
- HDMI_REG_R(ddc_ctrl->base, HDMI_DDC_INT_CTRL));
+ DSS_REG_R(ddc_ctrl->io, HDMI_DDC_INT_CTRL));
DEV_ERR("%s: DDC SW Status=%08x, HW Status=%08x\n",
__func__,
- HDMI_REG_R(ddc_ctrl->base, HDMI_DDC_SW_STATUS),
- HDMI_REG_R(ddc_ctrl->base, HDMI_DDC_HW_STATUS));
+ DSS_REG_R(ddc_ctrl->io, HDMI_DDC_SW_STATUS),
+ DSS_REG_R(ddc_ctrl->io, HDMI_DDC_HW_STATUS));
goto error;
}
/* Read DDC status */
- reg_val = HDMI_REG_R_ND(ddc_ctrl->base, HDMI_DDC_SW_STATUS);
+ reg_val = DSS_REG_R_ND(ddc_ctrl->io, HDMI_DDC_SW_STATUS);
reg_val &= 0x00001000 | 0x00002000 | 0x00004000 | 0x00008000;
/* Check if any NACK occurred */
if (reg_val) {
if (retry > 1)
/* SW_STATUS_RESET */
- HDMI_REG_W_ND(ddc_ctrl->base, HDMI_DDC_CTRL, BIT(3));
+ DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_CTRL, BIT(3));
else
/* SOFT_RESET */
- HDMI_REG_W_ND(ddc_ctrl->base, HDMI_DDC_CTRL, BIT(1));
+ DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_CTRL, BIT(1));
if (retry-- > 0) {
DEV_DBG("%s[%s]: failed NACK=%08x, retry=%d\n",
diff --git a/drivers/video/msm/mdss/mdss_hdmi_util.h b/drivers/video/msm/mdss/mdss_hdmi_util.h
index 47515ba..852a93c 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_util.h
+++ b/drivers/video/msm/mdss/mdss_hdmi_util.h
@@ -12,26 +12,7 @@
#ifndef __HDMI_UTIL_H__
#define __HDMI_UTIL_H__
-
-#define DEV_INFO(fmt, args...) pr_info(fmt, ##args)
-#define DEV_WARN(fmt, args...) pr_warn(fmt, ##args)
-#define DEV_ERR(fmt, args...) pr_err(fmt, ##args)
-
-#ifdef DEBUG
-#define DEV_DBG(fmt, args...) pr_err(fmt, ##args)
-#else
-#define DEV_DBG(args...) (void)0
-#endif
-
-#define PORT_DEBUG 0
-#define REG_DUMP 0
-void hdmi_reg_w(void __iomem *addr, u32 offset, u32 value, u32 debug);
-u32 hdmi_reg_r(void __iomem *addr, u32 offset, u32 debug);
-
-#define HDMI_REG_W_ND(addr, offset, val) hdmi_reg_w(addr, offset, val, false)
-#define HDMI_REG_W(addr, offset, val) hdmi_reg_w(addr, offset, val, true)
-#define HDMI_REG_R_ND(addr, offset) hdmi_reg_r(addr, offset, false)
-#define HDMI_REG_R(addr, offset) hdmi_reg_r(addr, offset, true)
+#include "mdss_io_util.h"
/* HDMI_TX Registers */
#define HDMI_CTRL (0x00000000)
@@ -220,7 +201,7 @@
#define HDMI_TPG_BLK_WHT_PATTERN_FRAMES (0x00000358)
#define HDMI_TPG_RGB_MAPPING (0x0000035C)
-/* HDMI PHY Registers, use them with PHY base and _ND macro */
+/* HDMI PHY Registers */
#define HDMI_PHY_ANA_CFG0 (0x00000000)
#define HDMI_PHY_ANA_CFG1 (0x00000004)
#define HDMI_PHY_PD_CTRL0 (0x00000010)
@@ -231,6 +212,10 @@
#define HDMI_PHY_BIST_PATN2 (0x00000044)
#define HDMI_PHY_BIST_PATN3 (0x00000048)
+/* QFPROM Registers for HDMI/HDCP */
+#define QFPROM_RAW_FEAT_CONFIG_ROW0_LSB (0x000000F8)
+#define QFPROM_RAW_FEAT_CONFIG_ROW0_MSB (0x000000FC)
+
/* all video formats defined by EIA CEA 861D */
#define HDMI_VFRMT_640x480p60_4_3 0
#define HDMI_VFRMT_720x480p60_4_3 1
@@ -397,7 +382,7 @@
};
struct hdmi_tx_ddc_ctrl {
- void __iomem *base;
+ struct dss_io_data *io;
struct completion ddc_sw_done;
};
@@ -412,9 +397,6 @@
int retry;
};
-void hdmi_reg_dump(void __iomem *base, u32 length, const char *prefix);
-const char *hdmi_reg_name(u32 offset);
-
const struct hdmi_disp_mode_timing_type *hdmi_get_supported_mode(u32 mode);
void hdmi_set_supported_mode(u32 mode);
const char *hdmi_get_video_fmt_2string(u32 format);
diff --git a/drivers/video/msm/mdss/mdss_io_util.c b/drivers/video/msm/mdss/mdss_io_util.c
index 65d08d3..5778525 100644
--- a/drivers/video/msm/mdss/mdss_io_util.c
+++ b/drivers/video/msm/mdss/mdss_io_util.c
@@ -10,10 +10,65 @@
* GNU General Public License for more details.
*/
+#include <linux/clk.h>
#include <linux/err.h>
#include <linux/io.h>
#include "mdss_io_util.h"
+void dss_reg_w(struct dss_io_data *io, u32 offset, u32 value, u32 debug)
+{
+ u32 in_val;
+
+ if (!io || !io->base) {
+ DEV_ERR("%pS->%s: invalid input\n",
+ __builtin_return_address(0), __func__);
+ return;
+ }
+
+ if (offset > io->len) {
+ DEV_ERR("%pS->%s: offset out of range\n",
+ __builtin_return_address(0), __func__);
+ return;
+ }
+
+ writel_relaxed(value, io->base + offset);
+ if (debug) {
+ in_val = readl_relaxed(io->base + offset);
+ DEV_DBG("[%08x] => %08x [%08x]\n", (u32)(io->base + offset),
+ value, in_val);
+ }
+} /* dss_reg_w */
+
+u32 dss_reg_r(struct dss_io_data *io, u32 offset, u32 debug)
+{
+ u32 value;
+ if (!io || !io->base) {
+ DEV_ERR("%pS->%s: invalid input\n",
+ __builtin_return_address(0), __func__);
+ return -EINVAL;
+ }
+
+ if (offset > io->len) {
+ DEV_ERR("%pS->%s: offset out of range\n",
+ __builtin_return_address(0), __func__);
+ return -EINVAL;
+ }
+
+ value = readl_relaxed(io->base + offset);
+ if (debug)
+ DEV_DBG("[%08x] <= %08x\n", (u32)(io->base + offset), value);
+
+ return value;
+} /* dss_reg_r */
+
+void dss_reg_dump(void __iomem *base, u32 length, const char *prefix,
+ u32 debug)
+{
+ if (debug)
+ print_hex_dump(KERN_INFO, prefix, DUMP_PREFIX_OFFSET, 32, 4,
+ (void *)base, length, false);
+} /* dss_reg_dump */
+
static struct resource *msm_dss_get_res_byname(struct platform_device *pdev,
unsigned int type, const char *name)
{
@@ -21,11 +76,10 @@
res = platform_get_resource_byname(pdev, type, name);
if (!res)
- pr_err("%s: '%s' resource not found\n", __func__, name);
+ DEV_ERR("%s: '%s' resource not found\n", __func__, name);
return res;
-}
-
+} /* msm_dss_get_res_byname */
int msm_dss_ioremap_byname(struct platform_device *pdev,
struct dss_io_data *io_data, const char *name)
@@ -33,32 +87,49 @@
struct resource *res = NULL;
if (!pdev || !io_data) {
- pr_err("%s: invalid input\n", __func__);
+ DEV_ERR("%pS->%s: invalid input\n",
+ __builtin_return_address(0), __func__);
return -EINVAL;
}
res = msm_dss_get_res_byname(pdev, IORESOURCE_MEM, name);
if (!res) {
- pr_err("%s: '%s' msm_dss_get_res_byname failed\n",
- __func__, name);
+ DEV_ERR("%pS->%s: '%s' msm_dss_get_res_byname failed\n",
+ __builtin_return_address(0), __func__, name);
return -ENODEV;
}
io_data->len = resource_size(res);
io_data->base = ioremap(res->start, io_data->len);
if (!io_data->base) {
- pr_err("%s: '%s' ioremap failed\n", __func__, name);
+ DEV_ERR("%pS->%s: '%s' ioremap failed\n",
+ __builtin_return_address(0), __func__, name);
return -EIO;
}
return 0;
-}
+} /* msm_dss_ioremap_byname */
+
+void msm_dss_iounmap(struct dss_io_data *io_data)
+{
+ if (!io_data) {
+ DEV_ERR("%pS->%s: invalid input\n",
+ __builtin_return_address(0), __func__);
+ return;
+ }
+
+ if (io_data->base) {
+ iounmap(io_data->base);
+ io_data->base = NULL;
+ }
+ io_data->len = 0;
+} /* msm_dss_iounmap */
int msm_dss_config_vreg(struct device *dev, struct dss_vreg *in_vreg,
int num_vreg, int config)
{
int i = 0, rc = 0;
- struct dss_vreg *curr_vreg;
+ struct dss_vreg *curr_vreg = NULL;
if (config) {
for (i = 0; i < num_vreg; i++) {
@@ -67,8 +138,8 @@
curr_vreg->vreg_name);
rc = IS_ERR(curr_vreg->vreg);
if (rc) {
- pr_err("%s: %s get failed. rc=%d\n",
- __func__,
+ DEV_ERR("%pS->%s: %s get failed. rc=%d\n",
+ __builtin_return_address(0), __func__,
curr_vreg->vreg_name, rc);
curr_vreg->vreg = NULL;
goto vreg_get_fail;
@@ -79,7 +150,8 @@
curr_vreg->min_voltage,
curr_vreg->max_voltage);
if (rc < 0) {
- pr_err("%s: %s set voltage failed\n",
+ DEV_ERR("%pS->%s: %s set vltg fail\n",
+ __builtin_return_address(0),
__func__,
curr_vreg->vreg_name);
goto vreg_set_voltage_fail;
@@ -89,8 +161,9 @@
curr_vreg->vreg,
curr_vreg->optimum_voltage);
if (rc < 0) {
- pr_err(
- "%s: %s set opt mode failed\n",
+ DEV_ERR(
+ "%pS->%s: %s set opt m fail\n",
+ __builtin_return_address(0),
__func__,
curr_vreg->vreg_name);
goto vreg_set_opt_mode_fail;
@@ -144,14 +217,16 @@
for (i = 0; i < num_vreg; i++) {
rc = IS_ERR(in_vreg[i].vreg);
if (rc) {
- pr_err("%s: %s regulator error. rc=%d\n",
- __func__, in_vreg[i].vreg_name, rc);
+ DEV_ERR("%pS->%s: %s regulator error. rc=%d\n",
+ __builtin_return_address(0), __func__,
+ in_vreg[i].vreg_name, rc);
goto disable_vreg;
}
rc = regulator_enable(in_vreg[i].vreg);
if (rc < 0) {
- pr_err("%s: %s enable failed\n",
- __func__, in_vreg[i].vreg_name);
+ DEV_ERR("%pS->%s: %s enable failed\n",
+ __builtin_return_address(0), __func__,
+ in_vreg[i].vreg_name);
goto disable_vreg;
}
}
@@ -176,8 +251,9 @@
rc = gpio_request(in_gpio[i].gpio,
in_gpio[i].gpio_name);
if (rc < 0) {
- pr_err("%s: %s enable failed\n",
- __func__, in_gpio[i].gpio_name);
+ DEV_ERR("%pS->%s: %s enable failed\n",
+ __builtin_return_address(0), __func__,
+ in_gpio[i].gpio_name);
goto disable_gpio;
}
}
@@ -192,3 +268,117 @@
gpio_free(in_gpio[i].gpio);
return rc;
} /* msm_dss_enable_gpio */
+
+void msm_dss_put_clk(struct dss_clk *clk_arry, int num_clk)
+{
+ int i;
+
+ for (i = num_clk - 1; i >= 0; i--) {
+ if (clk_arry[i].clk)
+ clk_put(clk_arry[i].clk);
+ clk_arry[i].clk = NULL;
+ }
+} /* msm_dss_put_clk */
+
+int msm_dss_get_clk(struct device *dev, struct dss_clk *clk_arry, int num_clk)
+{
+ int i, rc = 0;
+
+ for (i = 0; i < num_clk; i++) {
+ clk_arry[i].clk = clk_get(dev, clk_arry[i].clk_name);
+ rc = IS_ERR(clk_arry[i].clk);
+ if (rc) {
+ DEV_ERR("%pS->%s: '%s' get failed. rc=%d\n",
+ __builtin_return_address(0), __func__,
+ clk_arry[i].clk_name, rc);
+ goto error;
+ }
+ }
+
+ return rc;
+
+error:
+ msm_dss_put_clk(clk_arry, num_clk);
+
+ return rc;
+} /* msm_dss_get_clk */
+
+int msm_dss_clk_set_rate(struct dss_clk *clk_arry, int num_clk)
+{
+ int i, rc = 0;
+
+ for (i = 0; i < num_clk; i++) {
+ if (clk_arry[i].clk) {
+ if (DSS_CLK_AHB != clk_arry[i].type) {
+ DEV_DBG("%pS->%s: '%s' rate %ld\n",
+ __builtin_return_address(0), __func__,
+ clk_arry[i].clk_name,
+ clk_arry[i].rate);
+ rc = clk_set_rate(clk_arry[i].clk,
+ clk_arry[i].rate);
+ if (rc) {
+ DEV_ERR("%pS->%s: %s failed. rc=%d\n",
+ __builtin_return_address(0),
+ __func__,
+ clk_arry[i].clk_name, rc);
+ break;
+ }
+ }
+ } else {
+ DEV_ERR("%pS->%s: '%s' is not available\n",
+ __builtin_return_address(0), __func__,
+ clk_arry[i].clk_name);
+ rc = -EPERM;
+ break;
+ }
+ }
+
+ return rc;
+} /* msm_dss_clk_set_rate */
+
+int msm_dss_enable_clk(struct dss_clk *clk_arry, int num_clk, int enable)
+{
+ int i, rc = 0;
+
+ if (enable) {
+ for (i = 0; i < num_clk; i++) {
+ DEV_DBG("%pS->%s: enable '%s'\n",
+ __builtin_return_address(0), __func__,
+ clk_arry[i].clk_name);
+ if (clk_arry[i].clk) {
+ rc = clk_prepare_enable(clk_arry[i].clk);
+ if (rc)
+ DEV_ERR("%pS->%s: %s en fail. rc=%d\n",
+ __builtin_return_address(0),
+ __func__,
+ clk_arry[i].clk_name, rc);
+ } else {
+ DEV_ERR("%pS->%s: '%s' is not available\n",
+ __builtin_return_address(0), __func__,
+ clk_arry[i].clk_name);
+ rc = -EPERM;
+ }
+
+ if (rc) {
+ msm_dss_enable_clk(&clk_arry[i],
+ i, false);
+ break;
+ }
+ }
+ } else {
+ for (i = num_clk - 1; i >= 0; i--) {
+ DEV_DBG("%pS->%s: disable '%s'\n",
+ __builtin_return_address(0), __func__,
+ clk_arry[i].clk_name);
+
+ if (clk_arry[i].clk)
+ clk_disable_unprepare(clk_arry[i].clk);
+ else
+ DEV_ERR("%pS->%s: '%s' is not available\n",
+ __builtin_return_address(0), __func__,
+ clk_arry[i].clk_name);
+ }
+ }
+
+ return rc;
+} /* msm_dss_enable_clk */
diff --git a/drivers/video/msm/mdss/mdss_io_util.h b/drivers/video/msm/mdss/mdss_io_util.h
index 9671414..51e9e54 100644
--- a/drivers/video/msm/mdss/mdss_io_util.h
+++ b/drivers/video/msm/mdss/mdss_io_util.h
@@ -17,11 +17,29 @@
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
+#ifdef DEBUG
+#define DEV_DBG(fmt, args...) pr_err(fmt, ##args)
+#else
+#define DEV_DBG(fmt, args...) pr_debug(fmt, ##args)
+#endif
+#define DEV_INFO(fmt, args...) pr_info(fmt, ##args)
+#define DEV_WARN(fmt, args...) pr_warn(fmt, ##args)
+#define DEV_ERR(fmt, args...) pr_err(fmt, ##args)
+
struct dss_io_data {
u32 len;
void __iomem *base;
};
+void dss_reg_w(struct dss_io_data *io, u32 offset, u32 value, u32 debug);
+u32 dss_reg_r(struct dss_io_data *io, u32 offset, u32 debug);
+void dss_reg_dump(void __iomem *base, u32 len, const char *prefix, u32 debug);
+
+#define DSS_REG_W_ND(io, offset, val) dss_reg_w(io, offset, val, false)
+#define DSS_REG_W(io, offset, val) dss_reg_w(io, offset, val, true)
+#define DSS_REG_R_ND(io, offset) dss_reg_r(io, offset, false)
+#define DSS_REG_R(io, offset) dss_reg_r(io, offset, true)
+
enum dss_vreg_type {
DSS_REG_LDO,
DSS_REG_VS,
@@ -41,19 +59,42 @@
char gpio_name[32];
};
+enum dss_clk_type {
+ DSS_CLK_AHB, /* no set rate. rate controlled through rpm */
+ DSS_CLK_PCLK,
+ DSS_CLK_OTHER,
+};
+
+struct dss_clk {
+ struct clk *clk; /* clk handle */
+ char clk_name[32];
+ enum dss_clk_type type;
+ unsigned long rate;
+};
+
struct dss_module_power {
unsigned num_vreg;
struct dss_vreg *vreg_config;
unsigned num_gpio;
struct dss_gpio *gpio_config;
+ unsigned num_clk;
+ struct dss_clk *clk_config;
};
int msm_dss_ioremap_byname(struct platform_device *pdev,
struct dss_io_data *io_data, const char *name);
+void msm_dss_iounmap(struct dss_io_data *io_data);
+
int msm_dss_enable_gpio(struct dss_gpio *in_gpio, int num_gpio, int enable);
int msm_dss_gpio_enable(struct dss_gpio *in_gpio, int num_gpio, int enable);
+
int msm_dss_config_vreg(struct device *dev, struct dss_vreg *in_vreg,
int num_vreg, int config);
int msm_dss_enable_vreg(struct dss_vreg *in_vreg, int num_vreg, int enable);
+int msm_dss_get_clk(struct device *dev, struct dss_clk *clk_arry, int num_clk);
+void msm_dss_put_clk(struct dss_clk *clk_arry, int num_clk);
+int msm_dss_clk_set_rate(struct dss_clk *clk_arry, int num_clk);
+int msm_dss_enable_clk(struct dss_clk *clk_arry, int num_clk, int enable);
+
#endif /* __MDSS_IO_UTIL_H__ */
diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c
index 20fce7c..4f641cc 100644
--- a/drivers/video/msm/mdss/mdss_mdp.c
+++ b/drivers/video/msm/mdss/mdss_mdp.c
@@ -218,8 +218,9 @@
spin_lock_irqsave(&mdss_lock, irq_flags);
if (!(mdss_res->irq_mask & ndx_bit)) {
- pr_warn("MDSS HW ndx=%d is NOT set, mask=%x\n",
- hw->hw_ndx, mdss_res->mdp_irq_mask);
+ pr_warn("MDSS HW ndx=%d is NOT set, mask=%x, hist mask=%x\n",
+ hw->hw_ndx, mdss_res->mdp_irq_mask,
+ mdss_res->mdp_hist_irq_mask);
} else {
mdss_irq_handlers[hw->hw_ndx] = NULL;
mdss_res->irq_mask &= ~ndx_bit;
@@ -246,8 +247,9 @@
spin_lock(&mdss_lock);
if (!(mdss_res->irq_mask & ndx_bit)) {
- pr_warn("MDSS HW ndx=%d is NOT set, mask=%x\n",
- hw->hw_ndx, mdss_res->mdp_irq_mask);
+ pr_warn("MDSS HW ndx=%d is NOT set, mask=%x, hist mask=%x\n",
+ hw->hw_ndx, mdss_res->mdp_irq_mask,
+ mdss_res->mdp_hist_irq_mask);
} else {
mdss_irq_handlers[hw->hw_ndx] = NULL;
mdss_res->irq_mask &= ~ndx_bit;
@@ -359,6 +361,29 @@
return ret;
}
+int mdss_mdp_hist_irq_enable(u32 irq)
+{
+ unsigned long irq_flags;
+ int ret = 0;
+
+ spin_lock_irqsave(&mdp_lock, irq_flags);
+ if (mdss_res->mdp_hist_irq_mask & irq) {
+ pr_warn("MDSS MDP Hist IRQ-0x%x is already set, mask=%x\n",
+ irq, mdss_res->mdp_hist_irq_mask);
+ ret = -EBUSY;
+ } else {
+ pr_debug("MDP IRQ mask old=%x new=%x\n",
+ mdss_res->mdp_hist_irq_mask, irq);
+ mdss_res->mdp_hist_irq_mask |= irq;
+ MDSS_MDP_REG_WRITE(MDSS_MDP_REG_HIST_INTR_CLEAR, irq);
+ MDSS_MDP_REG_WRITE(MDSS_MDP_REG_HIST_INTR_EN,
+ mdss_res->mdp_hist_irq_mask);
+ mdss_enable_irq(&mdss_mdp_hw);
+ }
+ spin_unlock_irqrestore(&mdp_lock, irq_flags);
+
+ return ret;
+}
void mdss_mdp_irq_disable(u32 intr_type, u32 intf_num)
{
@@ -376,7 +401,27 @@
MDSS_MDP_REG_WRITE(MDSS_MDP_REG_INTR_EN,
mdss_res->mdp_irq_mask);
- if (mdss_res->mdp_irq_mask == 0)
+ if ((mdss_res->mdp_irq_mask == 0) &&
+ (mdss_res->mdp_hist_irq_mask == 0))
+ mdss_disable_irq(&mdss_mdp_hw);
+ }
+ spin_unlock_irqrestore(&mdp_lock, irq_flags);
+}
+
+void mdss_mdp_hist_irq_disable(u32 irq)
+{
+ unsigned long irq_flags;
+
+ spin_lock_irqsave(&mdp_lock, irq_flags);
+ if (!(mdss_res->mdp_hist_irq_mask & irq)) {
+ pr_warn("MDSS MDP IRQ-%x is NOT set, mask=%x\n",
+ irq, mdss_res->mdp_hist_irq_mask);
+ } else {
+ mdss_res->mdp_hist_irq_mask &= ~irq;
+ MDSS_MDP_REG_WRITE(MDSS_MDP_REG_HIST_INTR_EN,
+ mdss_res->mdp_hist_irq_mask);
+ if ((mdss_res->mdp_irq_mask == 0) &&
+ (mdss_res->mdp_hist_irq_mask == 0))
mdss_disable_irq(&mdss_mdp_hw);
}
spin_unlock_irqrestore(&mdp_lock, irq_flags);
@@ -396,7 +441,8 @@
mdss_res->mdp_irq_mask &= ~irq;
MDSS_MDP_REG_WRITE(MDSS_MDP_REG_INTR_EN,
mdss_res->mdp_irq_mask);
- if (mdss_res->mdp_irq_mask == 0)
+ if ((mdss_res->mdp_irq_mask == 0) &&
+ (mdss_res->mdp_hist_irq_mask == 0))
mdss_disable_irq_nosync(&mdss_mdp_hw);
}
spin_unlock(&mdp_lock);
diff --git a/drivers/video/msm/mdss/mdss_mdp.h b/drivers/video/msm/mdss/mdss_mdp.h
index 8a9f9c9..6fd642f 100644
--- a/drivers/video/msm/mdss/mdss_mdp.h
+++ b/drivers/video/msm/mdss/mdss_mdp.h
@@ -29,7 +29,7 @@
#define MDP_CLK_DEFAULT_RATE 37500000
#define PHASE_STEP_SHIFT 21
#define MAX_MIXER_WIDTH 2048
-#define MAX_MIXER_HEIGHT 2048
+#define MAX_MIXER_HEIGHT 2400
#define MAX_IMG_WIDTH 0x3FFF
#define MAX_IMG_HEIGHT 0x3FFF
#define MIN_DST_W 10
@@ -242,6 +242,7 @@
struct mdss_mdp_data buffers[2];
struct list_head list;
+ struct mdp_overlay_pp_params pp_cfg;
};
struct mdss_mdp_writeback_arg {
@@ -250,6 +251,7 @@
void *priv_data;
};
+#define is_vig_pipe(_pipe_id_) ((_pipe_id_) <= MDSS_MDP_SSPP_VIG2)
static inline void mdss_mdp_ctl_write(struct mdss_mdp_ctl *ctl,
u32 reg, u32 val)
{
@@ -266,6 +268,8 @@
irqreturn_t mdss_mdp_isr(int irq, void *ptr);
int mdss_mdp_irq_enable(u32 intr_type, u32 intf_num);
void mdss_mdp_irq_disable(u32 intr_type, u32 intf_num);
+int mdss_mdp_hist_irq_enable(u32 irq);
+void mdss_mdp_hist_irq_disable(u32 irq);
void mdss_mdp_irq_disable_nosync(u32 intr_type, u32 intf_num);
int mdss_mdp_set_intr_callback(u32 intr_type, u32 intf_num,
void (*fnc_ptr)(void *), void *arg);
@@ -295,7 +299,24 @@
int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg);
int mdss_mdp_csc_setup(u32 block, u32 blk_idx, u32 tbl_idx, u32 csc_type);
+int mdss_mdp_csc_setup_data(u32 block, u32 blk_idx, u32 tbl_idx,
+ struct mdp_csc_cfg *data);
+
int mdss_mdp_pp_setup(struct mdss_mdp_ctl *ctl);
+int mdss_mdp_pcc_config(struct mdp_pcc_cfg_data *cfg_ptr, u32 *copyback);
+
+int mdss_mdp_igc_lut_config(struct mdp_igc_lut_data *config, u32 *copyback);
+int mdss_mdp_argc_config(struct mdp_pgc_lut_data *config, u32 *copyback);
+int mdss_mdp_hist_lut_config(struct mdp_hist_lut_data *config, u32 *copyback);
+int mdss_mdp_dither_config(struct mdp_dither_cfg_data *config, u32 *copyback);
+int mdss_mdp_gamut_config(struct mdp_gamut_cfg_data *config, u32 *copyback);
+
+int mdss_mdp_histogram_start(struct mdp_histogram_start_req *req);
+int mdss_mdp_histogram_stop(u32 block);
+int mdss_mdp_hist_collect(struct fb_info *info,
+ struct mdp_histogram_data *hist, u32 *hist_data_addr);
+void mdss_mdp_hist_intr_done(u32 isr);
+
struct mdss_mdp_pipe *mdss_mdp_pipe_alloc_pnum(u32 pnum);
struct mdss_mdp_pipe *mdss_mdp_pipe_alloc_locked(u32 type);
diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c
index f72ff8d..161f54a 100644
--- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
+++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c
@@ -382,17 +382,18 @@
return -ENOMEM;
}
- ctl->mixer_left->width = MIN(width, MAX_MIXER_WIDTH);
+ if (width > MAX_MIXER_WIDTH)
+ width /= 2;
+
+ ctl->mixer_left->width = width;
ctl->mixer_left->height = height;
ctl->mixer_left->ctl = ctl;
- width -= ctl->mixer_left->width;
-
- if (width) {
+ if (width < ctl->width) {
ctl->mixer_right =
- mdss_mdp_mixer_alloc(MDSS_MDP_MIXER_TYPE_INTF);
+ mdss_mdp_mixer_alloc(MDSS_MDP_MIXER_TYPE_INTF);
if (!ctl->mixer_right) {
- pr_err("unable to allocate layer mixer\n");
+ pr_err("unable to allocate right layer mixer\n");
mdss_mdp_mixer_free(ctl->mixer_left);
mdss_mdp_ctl_free(ctl);
return -ENOMEM;
diff --git a/drivers/video/msm/mdss/mdss_mdp_hwio.h b/drivers/video/msm/mdss/mdss_mdp_hwio.h
index 0139afd..651d595 100644
--- a/drivers/video/msm/mdss/mdss_mdp_hwio.h
+++ b/drivers/video/msm/mdss/mdss_mdp_hwio.h
@@ -74,6 +74,11 @@
MDSS_MDP_IRQ_INTF_VSYNC = 25,
};
+#define MDSS_MDP_REG_IGC_VIG_BASE 0x300
+#define MDSS_MDP_REG_IGC_RGB_BASE 0x310
+#define MDSS_MDP_REG_IGC_DMA_BASE 0x320
+#define MDSS_MDP_REG_IGC_DSPP_BASE 0x400
+
enum mdss_mdp_ctl_index {
MDSS_MDP_CTL0,
MDSS_MDP_CTL1,
@@ -189,6 +194,9 @@
#define MDSS_MDP_REG_VIG_CSC_0_BASE 0x280
#define MDSS_MDP_REG_VIG_CSC_1_BASE 0x320
+#define MDSS_MDP_REG_VIG_HIST_CTL_BASE 0x2C4
+#define MDSS_MDP_REG_VIG_HIST_LUT_BASE 0x2F0
+
#define MDSS_MDP_SCALE_FILTER_NEAREST 0x0
#define MDSS_MDP_SCALE_FILTER_BIL 0x1
#define MDSS_MDP_SCALE_FILTER_PCMN 0x2
@@ -260,6 +268,8 @@
#define MDSS_MDP_REG_LM_CURSOR_BLEND_TRANSP_HIGH0 0x108
#define MDSS_MDP_REG_LM_CURSOR_BLEND_TRANSP_HIGH1 0x10C
+#define MDSS_MDP_REG_LM_GC_LUT_BASE 0x110
+
#define MDSS_MDP_LM_BORDER_COLOR (1 << 24)
#define MDSS_MDP_LM_CURSOR_OUT (1 << 25)
#define MDSS_MDP_BLEND_FG_ALPHA_FG_CONST (0 << 0)
@@ -323,7 +333,12 @@
#define MDSS_MDP_REG_DSPP_OFFSET(pipe) (0x4600 + ((pipe) * 0x400))
#define MDSS_MDP_REG_DSPP_OP_MODE 0x000
+#define MDSS_MDP_REG_DSPP_PCC_BASE 0x030
+#define MDSS_MDP_REG_DSPP_DITHER_DEPTH 0x150
+#define MDSS_MDP_REG_DSPP_HIST_CTL_BASE 0x210
+#define MDSS_MDP_REG_DSPP_HIST_LUT_BASE 0x230
#define MDSS_MDP_REG_DSPP_PA_BASE 0x238
+#define MDSS_MDP_REG_DSPP_GAMUT_BASE 0x2DC
enum mdss_mpd_intf_index {
MDSS_MDP_NO_INTF,
diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
index bb400bc..f70ef91 100644
--- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
+++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c
@@ -316,7 +316,17 @@
pipe->req_data = *req;
+ if (pipe->flags & MDP_OVERLAY_PP_CFG_EN) {
+ if (pipe->num <= MDSS_MDP_SSPP_VIG2)
+ memcpy(&pipe->pp_cfg, &req->overlay_pp_cfg,
+ sizeof(struct mdp_overlay_pp_params));
+ else
+ pr_debug("%s: RGB Pipes don't support CSC/QSEED\n",
+ __func__);
+ }
+
pipe->params_changed++;
+ pipe->play_cnt = 0;
req->id = pipe->ndx;
@@ -626,8 +636,15 @@
if (pipe == NULL) {
struct mdp_overlay req;
struct fb_info *fbi = mfd->fbi;
+ struct mdss_mdp_mixer *mixer;
int ret, bpp;
+ mixer = mdss_mdp_mixer_get(mfd->ctl, MDSS_MDP_MIXER_MUX_LEFT);
+ if (!mixer) {
+ pr_err("unable to retrieve mixer\n");
+ return -ENODEV;
+ }
+
memset(&req, 0, sizeof(req));
bpp = fbi->var.bits_per_pixel / 8;
@@ -636,20 +653,22 @@
req.src.height = fbi->var.yres;
req.src.width = fbi->fix.line_length / bpp;
if (mixer_mux == MDSS_MDP_MIXER_MUX_RIGHT) {
- if (req.src.width <= MAX_MIXER_WIDTH)
- return -ENODEV;
+ if (req.src.width <= mixer->width) {
+ pr_warn("right fb pipe not needed\n");
+ return -EINVAL;
+ }
req.flags |= MDSS_MDP_RIGHT_MIXER;
- req.src_rect.x = MAX_MIXER_WIDTH;
- req.src_rect.w = fbi->var.xres - MAX_MIXER_WIDTH;
+ req.src_rect.x = mixer->width;
+ req.src_rect.w = fbi->var.xres - mixer->width;
} else {
req.src_rect.x = 0;
- req.src_rect.w = MIN(fbi->var.xres, MAX_MIXER_WIDTH);
+ req.src_rect.w = MIN(fbi->var.xres, mixer->width);
}
req.src_rect.y = 0;
req.src_rect.h = req.src.height;
- req.dst_rect.x = req.src_rect.x;
+ req.dst_rect.x = 0;
req.dst_rect.y = 0;
req.dst_rect.w = req.src_rect.w;
req.dst_rect.h = req.src_rect.h;
@@ -686,6 +705,7 @@
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/mdss/mdss_mdp_pipe.c b/drivers/video/msm/mdss/mdss_mdp_pipe.c
index c936b7d..c90ce8c 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pipe.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pipe.c
@@ -560,16 +560,32 @@
pr_debug("pnum=%x\n", pipe->num);
- if (pipe->src_fmt->is_yuv)
- opmode |= (0 << 19) | /* DST_DATA=RGB */
- (1 << 18) | /* SRC_DATA=YCBCR */
- (1 << 17); /* CSC_1_EN */
-
- /* only need to program once */
- if (pipe->play_cnt == 0) {
- mdss_mdp_csc_setup(MDSS_MDP_BLOCK_SSPP, pipe->num, 1,
- MDSS_MDP_CSC_YUV2RGB);
+ /* CSC Post Processing enabled? */
+ if (pipe->flags & MDP_OVERLAY_PP_CFG_EN) {
+ if (pipe->pp_cfg.config_ops & MDP_OVERLAY_PP_CSC_CFG) {
+ if (pipe->pp_cfg.csc_cfg.flags & MDP_CSC_FLAG_ENABLE)
+ opmode |= 1 << 17; /* CSC_1_EN */
+ if (pipe->pp_cfg.csc_cfg.flags & MDP_CSC_FLAG_YUV_IN)
+ opmode |= 1 << 18; /* SRC_DATA=YCBCR */
+ if (pipe->pp_cfg.csc_cfg.flags & MDP_CSC_FLAG_YUV_OUT)
+ opmode |= 1 << 19; /* DST_DATA=YCBCR */
+ /* only need to program once */
+ if (pipe->play_cnt == 0)
+ mdss_mdp_csc_setup_data(MDSS_MDP_BLOCK_SSPP,
+ pipe->num, 1, &pipe->pp_cfg.csc_cfg);
+ }
+ } else {
+ if (pipe->src_fmt->is_yuv)
+ opmode |= (0 << 19) | /* DST_DATA=RGB */
+ (1 << 18) | /* SRC_DATA=YCBCR */
+ (1 << 17); /* CSC_1_EN */
+ /* only need to program once */
+ if (pipe->play_cnt == 0) {
+ mdss_mdp_csc_setup(MDSS_MDP_BLOCK_SSPP, pipe->num, 1,
+ MDSS_MDP_CSC_YUV2RGB);
+ }
}
+
mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_VIG_OP_MODE, opmode);
return 0;
diff --git a/drivers/video/msm/mdss/mdss_mdp_pp.c b/drivers/video/msm/mdss/mdss_mdp_pp.c
index 7ab3b01..6e04124 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pp.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pp.c
@@ -15,6 +15,9 @@
#include "mdss_fb.h"
#include "mdss_mdp.h"
+#include <linux/uaccess.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
struct mdp_csc_cfg mdp_csc_convert[MDSS_MDP_MAX_CSC] = {
[MDSS_MDP_CSC_RGB2RGB] = {
@@ -74,26 +77,118 @@
#define MDSS_BLOCK_DISP_NUM (MDP_BLOCK_MAX - MDP_LOGICAL_BLOCK_DISP_0)
+#define IGC_LUT_ENTRIES 256
+#define GC_LUT_SEGMENTS 16
+#define ENHIST_LUT_ENTRIES 256
+#define HIST_V_SIZE 256
+
+#define HIST_WAIT_TIMEOUT 1000
+/* hist collect state */
+enum {
+ HIST_UNKNOWN,
+ HIST_IDLE,
+ HIST_RESET,
+ HIST_START,
+ HIST_READY,
+};
+
+struct pp_hist_col_info {
+ u32 col_state;
+ u32 col_en;
+ u32 read_request;
+ u32 hist_cnt_read;
+ u32 hist_cnt_sent;
+ u32 frame_cnt;
+ struct completion comp;
+ u32 data[HIST_V_SIZE];
+};
+
+static u32 dither_matrix[16] = {
+ 15, 7, 13, 5, 3, 11, 1, 9, 12, 4, 14, 6, 0, 8, 2, 10};
+static u32 dither_depth_map[9] = {
+ 0, 0, 0, 0, 0, 1, 2, 3, 3};
+
+#define GAMUT_T0_SIZE 125
+#define GAMUT_T1_SIZE 100
+#define GAMUT_T2_SIZE 80
+#define GAMUT_T3_SIZE 100
+#define GAMUT_T4_SIZE 100
+#define GAMUT_T5_SIZE 80
+#define GAMUT_T6_SIZE 64
+#define GAMUT_T7_SIZE 80
+#define GAMUT_TOTAL_TABLE_SIZE (GAMUT_T0_SIZE + GAMUT_T1_SIZE + \
+ GAMUT_T2_SIZE + GAMUT_T3_SIZE + GAMUT_T4_SIZE + \
+ GAMUT_T5_SIZE + GAMUT_T6_SIZE + GAMUT_T7_SIZE)
+
struct pp_sts_type {
u32 pa_sts;
+ u32 pcc_sts;
+ u32 igc_sts;
+ u32 igc_tbl_idx;
+ u32 argc_sts;
+ u32 enhist_sts;
+ u32 dither_sts;
+ u32 gamut_sts;
};
#define PP_FLAGS_DIRTY_PA 0x1
+#define PP_FLAGS_DIRTY_PCC 0x2
+#define PP_FLAGS_DIRTY_IGC 0x4
+#define PP_FLAGS_DIRTY_ARGC 0x8
+#define PP_FLAGS_DIRTY_ENHIST 0x10
+#define PP_FLAGS_DIRTY_DITHER 0x20
+#define PP_FLAGS_DIRTY_GAMUT 0x40
+#define PP_FLAGS_DIRTY_HIST_COL 0x80
#define PP_STS_ENABLE 0x1
+#define PP_STS_GAMUT_FIRST 0x2
struct mdss_pp_res_type {
/* logical info */
u32 pp_disp_flags[MDSS_BLOCK_DISP_NUM];
+ u32 igc_lut_c0c1[MDSS_BLOCK_DISP_NUM][IGC_LUT_ENTRIES];
+ u32 igc_lut_c2[MDSS_BLOCK_DISP_NUM][IGC_LUT_ENTRIES];
+ struct mdp_ar_gc_lut_data
+ gc_lut_r[MDSS_BLOCK_DISP_NUM][GC_LUT_SEGMENTS];
+ struct mdp_ar_gc_lut_data
+ gc_lut_g[MDSS_BLOCK_DISP_NUM][GC_LUT_SEGMENTS];
+ struct mdp_ar_gc_lut_data
+ gc_lut_b[MDSS_BLOCK_DISP_NUM][GC_LUT_SEGMENTS];
+ u32 enhist_lut[MDSS_BLOCK_DISP_NUM][ENHIST_LUT_ENTRIES];
struct mdp_pa_cfg_data pa_disp_cfg[MDSS_BLOCK_DISP_NUM];
+ struct mdp_pcc_cfg_data pcc_disp_cfg[MDSS_BLOCK_DISP_NUM];
+ struct mdp_igc_lut_data igc_disp_cfg[MDSS_BLOCK_DISP_NUM];
+ struct mdp_pgc_lut_data pgc_disp_cfg[MDSS_BLOCK_DISP_NUM];
+ struct mdp_hist_lut_data enhist_disp_cfg[MDSS_BLOCK_DISP_NUM];
+ struct mdp_dither_cfg_data dither_disp_cfg[MDSS_BLOCK_DISP_NUM];
+ struct mdp_gamut_cfg_data gamut_disp_cfg[MDSS_BLOCK_DISP_NUM];
+ uint16_t gamut_tbl[MDSS_BLOCK_DISP_NUM][GAMUT_TOTAL_TABLE_SIZE];
+ struct pp_hist_col_info
+ *hist_col[MDSS_BLOCK_DISP_NUM][MDSS_MDP_MAX_DSPP];
+ u32 hist_data[MDSS_BLOCK_DISP_NUM][HIST_V_SIZE];
/* physical info */
struct pp_sts_type pp_dspp_sts[MDSS_MDP_MAX_DSPP];
+ struct pp_hist_col_info dspp_hist[MDSS_MDP_MAX_DSPP];
};
static DEFINE_MUTEX(mdss_pp_mutex);
+static DEFINE_SPINLOCK(mdss_hist_lock);
+static DEFINE_MUTEX(mdss_mdp_hist_mutex);
static struct mdss_pp_res_type *mdss_pp_res;
-static int mdss_mdp_csc_setup_data(u32 block, u32 blk_idx, u32 tbl_idx,
+
+static void pp_hist_read(u32 v_base, struct pp_hist_col_info *hist_info);
+
+static void pp_update_pcc_regs(u32 offset,
+ struct mdp_pcc_cfg_data *cfg_ptr);
+static void pp_update_igc_lut(struct mdp_igc_lut_data *cfg,
+ u32 offset, u32 blk_idx);
+static void pp_update_gc_one_lut(u32 offset,
+ struct mdp_ar_gc_lut_data *lut_data);
+static void pp_update_argc_lut(u32 offset,
+ struct mdp_pgc_lut_data *config);
+
+int mdss_mdp_csc_setup_data(u32 block, u32 blk_idx, u32 tbl_idx,
struct mdp_csc_cfg *data)
{
int i, ret = 0;
@@ -181,19 +276,123 @@
data = &mdp_csc_convert[csc_type];
return mdss_mdp_csc_setup_data(block, blk_idx, tbl_idx, data);
}
-
-static int pp_dspp_setup(u32 disp_num, struct mdss_mdp_ctl *ctl,
+static int pp_mixer_setup(u32 disp_num, struct mdss_mdp_ctl *ctl,
struct mdss_mdp_mixer *mixer)
{
- u32 flags, base, offset, dspp_num, opmode = 0;
- struct mdp_pa_cfg_data *pa_config;
+ u32 flags, offset, dspp_num, opmode = 0;
+ struct mdp_pgc_lut_data *pgc_config;
struct pp_sts_type *pp_sts;
-
dspp_num = mixer->num;
/* no corresponding dspp */
if ((mixer->type != MDSS_MDP_MIXER_TYPE_INTF) ||
(dspp_num >= MDSS_MDP_MAX_DSPP))
return 0;
+ if (disp_num < MDSS_BLOCK_DISP_NUM)
+ flags = mdss_pp_res->pp_disp_flags[disp_num];
+ else
+ flags = 0;
+
+ pp_sts = &mdss_pp_res->pp_dspp_sts[dspp_num];
+ /* GC_LUT is in layer mixer */
+ if (flags & PP_FLAGS_DIRTY_ARGC) {
+ pgc_config = &mdss_pp_res->pgc_disp_cfg[disp_num];
+ if (pgc_config->flags & MDP_PP_OPS_WRITE) {
+ offset = MDSS_MDP_REG_LM_OFFSET(disp_num) +
+ MDSS_MDP_REG_LM_GC_LUT_BASE;
+ pp_update_argc_lut(offset, pgc_config);
+ }
+ if (pgc_config->flags & MDP_PP_OPS_DISABLE)
+ pp_sts->argc_sts &= ~PP_STS_ENABLE;
+ else if (pgc_config->flags & MDP_PP_OPS_ENABLE)
+ pp_sts->argc_sts |= PP_STS_ENABLE;
+ ctl->flush_bits |= BIT(6) << dspp_num; /* LAYER_MIXER */
+ }
+ /* update LM opmode if LM needs flush */
+ if ((pp_sts->argc_sts & PP_STS_ENABLE) &&
+ (ctl->flush_bits & (BIT(6) << dspp_num))) {
+ offset = MDSS_MDP_REG_LM_OFFSET(dspp_num) +
+ MDSS_MDP_REG_LM_OP_MODE;
+ opmode = MDSS_MDP_REG_READ(offset);
+ opmode |= (1 << 0); /* GC_LUT_EN */
+ MDSS_MDP_REG_WRITE(offset, opmode);
+ }
+ return 0;
+}
+static void pp_gamut_config(struct mdp_gamut_cfg_data *gamut_cfg,
+ u32 base,
+ u32 *gamut_sts)
+{
+ u32 offset;
+ int i, j;
+ if (gamut_cfg->flags & MDP_PP_OPS_WRITE) {
+ offset = base + MDSS_MDP_REG_DSPP_GAMUT_BASE;
+ for (i = 0; i < MDP_GAMUT_TABLE_NUM; i++) {
+ for (j = 0; j < gamut_cfg->tbl_size[i]; j++)
+ MDSS_MDP_REG_WRITE(offset,
+ (u32)gamut_cfg->r_tbl[i][j]);
+ offset += 4;
+ }
+ for (i = 0; i < MDP_GAMUT_TABLE_NUM; i++) {
+ for (j = 0; j < gamut_cfg->tbl_size[i]; j++)
+ MDSS_MDP_REG_WRITE(offset,
+ (u32)gamut_cfg->g_tbl[i][j]);
+ offset += 4;
+ }
+ for (i = 0; i < MDP_GAMUT_TABLE_NUM; i++) {
+ for (j = 0; j < gamut_cfg->tbl_size[i]; j++)
+ MDSS_MDP_REG_WRITE(offset,
+ (u32)gamut_cfg->b_tbl[i][j]);
+ offset += 4;
+ }
+ if (gamut_cfg->gamut_first)
+ *gamut_sts |= PP_STS_GAMUT_FIRST;
+ }
+
+ if (gamut_cfg->flags & MDP_PP_OPS_DISABLE)
+ *gamut_sts &= ~PP_STS_ENABLE;
+ else if (gamut_cfg->flags & MDP_PP_OPS_ENABLE)
+ *gamut_sts |= PP_STS_ENABLE;
+}
+static int pp_dspp_setup(u32 disp_num, struct mdss_mdp_ctl *ctl,
+ struct mdss_mdp_mixer *mixer)
+{
+ u32 flags, base, offset, dspp_num, opmode = 0;
+ struct mdp_pa_cfg_data *pa_config;
+ struct mdp_pcc_cfg_data *pcc_config;
+ struct mdp_igc_lut_data *igc_config;
+ struct mdp_hist_lut_data *enhist_cfg;
+ struct mdp_dither_cfg_data *dither_cfg;
+ struct pp_hist_col_info *hist_info;
+ struct pp_sts_type *pp_sts;
+ u32 data, tbl_idx, col_state;
+ int i;
+ dspp_num = mixer->num;
+ /* no corresponding dspp */
+ if ((mixer->type != MDSS_MDP_MIXER_TYPE_INTF) ||
+ (dspp_num >= MDSS_MDP_MAX_DSPP))
+ return 0;
+ base = MDSS_MDP_REG_DSPP_OFFSET(dspp_num);
+ hist_info = &mdss_pp_res->dspp_hist[dspp_num];
+ if (hist_info->col_en) {
+ /* HIST_EN & AUTO_CLEAR */
+ opmode |= (1 << 16) | (1 << 17);
+ mutex_lock(&mdss_mdp_hist_mutex);
+ if (hist_info->col_state == HIST_READY)
+ pp_hist_read(base + MDSS_MDP_REG_DSPP_HIST_CTL_BASE +
+ 0x1C, hist_info);
+ spin_lock(&mdss_hist_lock);
+ col_state = hist_info->col_state;
+ if ((col_state == HIST_IDLE) ||
+ (col_state == HIST_READY) ||
+ (col_state == HIST_START)) {
+ /* Kick off collection */
+ MDSS_MDP_REG_WRITE(base +
+ MDSS_MDP_REG_DSPP_HIST_CTL_BASE, 1);
+ hist_info->col_state = HIST_START;
+ }
+ spin_unlock(&mdss_hist_lock);
+ mutex_unlock(&mdss_mdp_hist_mutex);
+ }
if (disp_num < MDSS_BLOCK_DISP_NUM)
flags = mdss_pp_res->pp_disp_flags[disp_num];
@@ -201,10 +400,9 @@
flags = 0;
/* nothing to update */
- if (!flags)
+ if ((!flags) && (!(hist_info->col_en)))
return 0;
pp_sts = &mdss_pp_res->pp_dspp_sts[dspp_num];
- base = MDSS_MDP_REG_DSPP_OFFSET(dspp_num);
if (flags & PP_FLAGS_DIRTY_PA) {
pa_config = &mdss_pp_res->pa_disp_cfg[disp_num];
if (pa_config->flags & MDP_PP_OPS_WRITE) {
@@ -224,10 +422,108 @@
}
if (pp_sts->pa_sts & PP_STS_ENABLE)
opmode |= (1 << 20); /* PA_EN */
+ if (flags & PP_FLAGS_DIRTY_PCC) {
+ pcc_config = &mdss_pp_res->pcc_disp_cfg[disp_num];
+ if (pcc_config->ops & MDP_PP_OPS_WRITE) {
+ offset = base + MDSS_MDP_REG_DSPP_PCC_BASE;
+ pp_update_pcc_regs(offset, pcc_config);
+ }
+ if (pcc_config->ops & MDP_PP_OPS_DISABLE)
+ pp_sts->pcc_sts &= ~PP_STS_ENABLE;
+ else if (pcc_config->ops & MDP_PP_OPS_ENABLE)
+ pp_sts->pcc_sts |= PP_STS_ENABLE;
+ }
+ if (pp_sts->pcc_sts & PP_STS_ENABLE)
+ opmode |= (1 << 4); /* PCC_EN */
+
+ if (flags & PP_FLAGS_DIRTY_IGC) {
+ igc_config = &mdss_pp_res->igc_disp_cfg[disp_num];
+ if (igc_config->ops & MDP_PP_OPS_WRITE) {
+ offset = MDSS_MDP_REG_IGC_DSPP_BASE;
+ pp_update_igc_lut(igc_config, offset, dspp_num);
+ }
+ if (igc_config->ops & MDP_PP_IGC_FLAG_ROM0) {
+ pp_sts->pcc_sts |= PP_STS_ENABLE;
+ tbl_idx = 1;
+ } else if (igc_config->ops & MDP_PP_IGC_FLAG_ROM1) {
+ pp_sts->pcc_sts |= PP_STS_ENABLE;
+ tbl_idx = 2;
+ } else {
+ tbl_idx = 0;
+ }
+ pp_sts->igc_tbl_idx = tbl_idx;
+ if (igc_config->ops & MDP_PP_OPS_DISABLE)
+ pp_sts->igc_sts &= ~PP_STS_ENABLE;
+ else if (igc_config->ops & MDP_PP_OPS_ENABLE)
+ pp_sts->igc_sts |= PP_STS_ENABLE;
+ }
+ if (pp_sts->igc_sts & PP_STS_ENABLE) {
+ opmode |= (1 << 0) | /* IGC_LUT_EN */
+ (pp_sts->igc_tbl_idx << 1);
+ }
+ if (flags & PP_FLAGS_DIRTY_ENHIST) {
+ enhist_cfg = &mdss_pp_res->enhist_disp_cfg[disp_num];
+ if (enhist_cfg->ops & MDP_PP_OPS_WRITE) {
+ offset = base + MDSS_MDP_REG_DSPP_HIST_LUT_BASE;
+ for (i = 0; i < ENHIST_LUT_ENTRIES; i++)
+ MDSS_MDP_REG_WRITE(offset, enhist_cfg->data[i]);
+ /* swap */
+ MDSS_MDP_REG_WRITE(offset + 4, 1);
+ }
+ if (enhist_cfg->ops & MDP_PP_OPS_DISABLE)
+ pp_sts->enhist_sts &= ~PP_STS_ENABLE;
+ else if (enhist_cfg->ops & MDP_PP_OPS_ENABLE)
+ pp_sts->enhist_sts |= PP_STS_ENABLE;
+ }
+ if (pp_sts->enhist_sts & PP_STS_ENABLE) {
+ opmode |= (1 << 19) | /* HIST_LUT_EN */
+ (1 << 20); /* PA_EN */
+ if (!(pp_sts->pa_sts & PP_STS_ENABLE)) {
+ /* Program default value */
+ offset = base + MDSS_MDP_REG_DSPP_PA_BASE;
+ MDSS_MDP_REG_WRITE(offset, 0);
+ MDSS_MDP_REG_WRITE(offset + 4, 0);
+ MDSS_MDP_REG_WRITE(offset + 8, 0);
+ MDSS_MDP_REG_WRITE(offset + 12, 0);
+ }
+ }
+ if (flags & PP_FLAGS_DIRTY_DITHER) {
+ dither_cfg = &mdss_pp_res->dither_disp_cfg[disp_num];
+ if (dither_cfg->flags & MDP_PP_OPS_WRITE) {
+ offset = base + MDSS_MDP_REG_DSPP_DITHER_DEPTH;
+ MDSS_MDP_REG_WRITE(offset,
+ dither_depth_map[dither_cfg->g_y_depth] |
+ (dither_depth_map[dither_cfg->b_cb_depth] << 2) |
+ (dither_depth_map[dither_cfg->r_cr_depth] << 4));
+ offset += 0x14;
+ for (i = 0; i << 16; i += 4) {
+ data = dither_matrix[i] |
+ (dither_matrix[i + 1] << 4) |
+ (dither_matrix[i + 2] << 8) |
+ (dither_matrix[i + 3] << 12);
+ MDSS_MDP_REG_WRITE(offset, data);
+ offset += 4;
+ }
+ }
+ if (dither_cfg->flags & MDP_PP_OPS_DISABLE)
+ pp_sts->dither_sts &= ~PP_STS_ENABLE;
+ else if (dither_cfg->flags & MDP_PP_OPS_ENABLE)
+ pp_sts->dither_sts |= PP_STS_ENABLE;
+ }
+ if (pp_sts->dither_sts & PP_STS_ENABLE)
+ opmode |= (1 << 8); /* DITHER_EN */
+ if (flags & PP_FLAGS_DIRTY_GAMUT)
+ pp_gamut_config(&mdss_pp_res->gamut_disp_cfg[disp_num],
+ base, &pp_sts->gamut_sts);
+ if (pp_sts->gamut_sts & PP_STS_ENABLE) {
+ opmode |= (1 << 23); /* GAMUT_EN */
+ if (pp_sts->gamut_sts & PP_STS_GAMUT_FIRST)
+ opmode |= (1 << 24); /* GAMUT_ORDER */
+ }
+
MDSS_MDP_REG_WRITE(base + MDSS_MDP_REG_DSPP_OP_MODE, opmode);
ctl->flush_bits |= BIT(13 + dspp_num); /* DSPP */
return 0;
-
}
int mdss_mdp_pp_setup(struct mdss_mdp_ctl *ctl)
{
@@ -239,10 +535,14 @@
disp_num = ctl->mfd->index;
mutex_lock(&mdss_pp_mutex);
- if (ctl->mixer_left)
+ if (ctl->mixer_left) {
+ pp_mixer_setup(disp_num, ctl, ctl->mixer_left);
pp_dspp_setup(disp_num, ctl, ctl->mixer_left);
- if (ctl->mixer_right)
+ }
+ if (ctl->mixer_right) {
+ pp_mixer_setup(disp_num, ctl, ctl->mixer_right);
pp_dspp_setup(disp_num, ctl, ctl->mixer_right);
+ }
/* clear dirty flag */
if (disp_num < MDSS_BLOCK_DISP_NUM)
mdss_pp_res->pp_disp_flags[disp_num] = 0;
@@ -275,12 +575,31 @@
mutex_unlock(&mdss_pp_mutex);
}
}
+static int pp_get_dspp_num(u32 disp_num, u32 *dspp_num)
+{
+ int i;
+ u32 mixer_cnt;
+ u32 mixer_id[MDSS_MDP_MAX_LAYERMIXER];
+ mixer_cnt = mdss_mdp_get_ctl_mixers(disp_num, mixer_id);
+
+ if (!mixer_cnt)
+ return -EPERM;
+
+ /* only read the first mixer */
+ for (i = 0; i < mixer_cnt; i++) {
+ if (mixer_id[i] < MDSS_MDP_MAX_DSPP)
+ break;
+ }
+ if (i >= mixer_cnt)
+ return -EPERM;
+ *dspp_num = mixer_id[i];
+ return 0;
+}
int mdss_mdp_pa_config(struct mdp_pa_cfg_data *config, u32 *copyback)
{
- int i, ret = 0;
- u32 pa_offset, disp_num, mixer_cnt;
- u32 mixer_id[MDSS_MDP_MAX_LAYERMIXER];
+ int ret = 0;
+ u32 pa_offset, disp_num, dspp_num = 0;
if ((config->block < MDP_LOGICAL_BLOCK_DISP_0) ||
(config->block >= MDP_BLOCK_MAX))
@@ -290,24 +609,15 @@
disp_num = config->block - MDP_LOGICAL_BLOCK_DISP_0;
if (config->flags & MDP_PP_OPS_READ) {
- mixer_cnt = mdss_mdp_get_ctl_mixers(disp_num, mixer_id);
- if (!mixer_cnt) {
- ret = -EPERM;
- goto pa_config_exit;
- }
- /* only read the first mixer */
- for (i = 0; i < mixer_cnt; i++) {
- if (mixer_id[i] < MDSS_MDP_MAX_DSPP)
- break;
- }
- if (i >= mixer_cnt) {
- ret = -EPERM;
+ ret = pp_get_dspp_num(disp_num, &dspp_num);
+ if (ret) {
+ pr_err("%s, no dspp connects to disp %d",
+ __func__, disp_num);
goto pa_config_exit;
}
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
- pa_offset = MDSS_MDP_REG_DSPP_OFFSET(mixer_id[i]) +
+ pa_offset = MDSS_MDP_REG_DSPP_OFFSET(dspp_num) +
MDSS_MDP_REG_DSPP_PA_BASE;
-
config->hue_adj = MDSS_MDP_REG_READ(pa_offset);
pa_offset += 4;
config->sat_adj = MDSS_MDP_REG_READ(pa_offset);
@@ -326,3 +636,910 @@
mutex_unlock(&mdss_pp_mutex);
return ret;
}
+
+static void pp_read_pcc_regs(u32 offset,
+ struct mdp_pcc_cfg_data *cfg_ptr)
+{
+ cfg_ptr->r.c = MDSS_MDP_REG_READ(offset);
+ cfg_ptr->g.c = MDSS_MDP_REG_READ(offset + 4);
+ cfg_ptr->b.c = MDSS_MDP_REG_READ(offset + 8);
+ offset += 0x10;
+
+ cfg_ptr->r.r = MDSS_MDP_REG_READ(offset);
+ cfg_ptr->g.r = MDSS_MDP_REG_READ(offset + 4);
+ cfg_ptr->b.r = MDSS_MDP_REG_READ(offset + 8);
+ offset += 0x10;
+
+ cfg_ptr->r.g = MDSS_MDP_REG_READ(offset);
+ cfg_ptr->g.g = MDSS_MDP_REG_READ(offset + 4);
+ cfg_ptr->b.g = MDSS_MDP_REG_READ(offset + 8);
+ offset += 0x10;
+
+ cfg_ptr->r.b = MDSS_MDP_REG_READ(offset);
+ cfg_ptr->g.b = MDSS_MDP_REG_READ(offset + 4);
+ cfg_ptr->b.b = MDSS_MDP_REG_READ(offset + 8);
+ offset += 0x10;
+
+ cfg_ptr->r.rr = MDSS_MDP_REG_READ(offset);
+ cfg_ptr->g.rr = MDSS_MDP_REG_READ(offset + 4);
+ cfg_ptr->b.rr = MDSS_MDP_REG_READ(offset + 8);
+ offset += 0x10;
+
+ cfg_ptr->r.rg = MDSS_MDP_REG_READ(offset);
+ cfg_ptr->g.rg = MDSS_MDP_REG_READ(offset + 4);
+ cfg_ptr->b.rg = MDSS_MDP_REG_READ(offset + 8);
+ offset += 0x10;
+
+ cfg_ptr->r.rb = MDSS_MDP_REG_READ(offset);
+ cfg_ptr->g.rb = MDSS_MDP_REG_READ(offset + 4);
+ cfg_ptr->b.rb = MDSS_MDP_REG_READ(offset + 8);
+ offset += 0x10;
+
+ cfg_ptr->r.gg = MDSS_MDP_REG_READ(offset);
+ cfg_ptr->g.gg = MDSS_MDP_REG_READ(offset + 4);
+ cfg_ptr->b.gg = MDSS_MDP_REG_READ(offset + 8);
+ offset += 0x10;
+
+ cfg_ptr->r.gb = MDSS_MDP_REG_READ(offset);
+ cfg_ptr->g.gb = MDSS_MDP_REG_READ(offset + 4);
+ cfg_ptr->b.gb = MDSS_MDP_REG_READ(offset + 8);
+ offset += 0x10;
+
+ cfg_ptr->r.bb = MDSS_MDP_REG_READ(offset);
+ cfg_ptr->g.bb = MDSS_MDP_REG_READ(offset + 4);
+ cfg_ptr->b.bb = MDSS_MDP_REG_READ(offset + 8);
+ offset += 0x10;
+
+ cfg_ptr->r.rgb_0 = MDSS_MDP_REG_READ(offset);
+ cfg_ptr->g.rgb_0 = MDSS_MDP_REG_READ(offset + 4);
+ cfg_ptr->b.rgb_0 = MDSS_MDP_REG_READ(offset + 8);
+ offset += 0x10;
+
+ cfg_ptr->r.rgb_1 = MDSS_MDP_REG_READ(offset);
+ cfg_ptr->g.rgb_1 = MDSS_MDP_REG_READ(offset + 4);
+ cfg_ptr->b.rgb_1 = MDSS_MDP_REG_READ(offset + 8);
+}
+
+static void pp_update_pcc_regs(u32 offset,
+ struct mdp_pcc_cfg_data *cfg_ptr)
+{
+ MDSS_MDP_REG_WRITE(offset, cfg_ptr->r.c);
+ MDSS_MDP_REG_WRITE(offset + 4, cfg_ptr->g.c);
+ MDSS_MDP_REG_WRITE(offset + 8, cfg_ptr->b.c);
+ offset += 0x10;
+
+ MDSS_MDP_REG_WRITE(offset, cfg_ptr->r.r);
+ MDSS_MDP_REG_WRITE(offset + 4, cfg_ptr->g.r);
+ MDSS_MDP_REG_WRITE(offset + 8, cfg_ptr->b.r);
+ offset += 0x10;
+
+ MDSS_MDP_REG_WRITE(offset, cfg_ptr->r.g);
+ MDSS_MDP_REG_WRITE(offset + 4, cfg_ptr->g.g);
+ MDSS_MDP_REG_WRITE(offset + 8, cfg_ptr->b.g);
+ offset += 0x10;
+
+ MDSS_MDP_REG_WRITE(offset, cfg_ptr->r.b);
+ MDSS_MDP_REG_WRITE(offset + 4, cfg_ptr->g.b);
+ MDSS_MDP_REG_WRITE(offset + 8, cfg_ptr->b.b);
+ offset += 0x10;
+
+ MDSS_MDP_REG_WRITE(offset, cfg_ptr->r.rr);
+ MDSS_MDP_REG_WRITE(offset + 4, cfg_ptr->g.rr);
+ MDSS_MDP_REG_WRITE(offset + 8, cfg_ptr->b.rr);
+ offset += 0x10;
+
+ MDSS_MDP_REG_WRITE(offset, cfg_ptr->r.rg);
+ MDSS_MDP_REG_WRITE(offset + 4, cfg_ptr->g.rg);
+ MDSS_MDP_REG_WRITE(offset + 8, cfg_ptr->b.rg);
+ offset += 0x10;
+
+ MDSS_MDP_REG_WRITE(offset, cfg_ptr->r.rb);
+ MDSS_MDP_REG_WRITE(offset + 4, cfg_ptr->g.rb);
+ MDSS_MDP_REG_WRITE(offset + 8, cfg_ptr->b.rb);
+ offset += 0x10;
+
+ MDSS_MDP_REG_WRITE(offset, cfg_ptr->r.gg);
+ MDSS_MDP_REG_WRITE(offset + 4, cfg_ptr->g.gg);
+ MDSS_MDP_REG_WRITE(offset + 8, cfg_ptr->b.gg);
+ offset += 0x10;
+
+ MDSS_MDP_REG_WRITE(offset, cfg_ptr->r.gb);
+ MDSS_MDP_REG_WRITE(offset + 4, cfg_ptr->g.gb);
+ MDSS_MDP_REG_WRITE(offset + 8, cfg_ptr->b.gb);
+ offset += 0x10;
+
+ MDSS_MDP_REG_WRITE(offset, cfg_ptr->r.bb);
+ MDSS_MDP_REG_WRITE(offset + 4, cfg_ptr->g.bb);
+ MDSS_MDP_REG_WRITE(offset + 8, cfg_ptr->b.bb);
+ offset += 0x10;
+
+ MDSS_MDP_REG_WRITE(offset, cfg_ptr->r.rgb_0);
+ MDSS_MDP_REG_WRITE(offset + 4, cfg_ptr->g.rgb_0);
+ MDSS_MDP_REG_WRITE(offset + 8, cfg_ptr->b.rgb_0);
+ offset += 0x10;
+
+ MDSS_MDP_REG_WRITE(offset, cfg_ptr->r.rgb_1);
+ MDSS_MDP_REG_WRITE(offset + 4, cfg_ptr->g.rgb_1);
+ MDSS_MDP_REG_WRITE(offset + 8, cfg_ptr->b.rgb_1);
+}
+
+int mdss_mdp_pcc_config(struct mdp_pcc_cfg_data *config, u32 *copyback)
+{
+ int ret = 0;
+ u32 base, disp_num, dspp_num = 0;
+
+ if ((config->block < MDP_LOGICAL_BLOCK_DISP_0) ||
+ (config->block >= MDP_BLOCK_MAX))
+ return -EINVAL;
+
+ mutex_lock(&mdss_pp_mutex);
+ disp_num = config->block - MDP_LOGICAL_BLOCK_DISP_0;
+
+ if (config->ops & MDP_PP_OPS_READ) {
+ ret = pp_get_dspp_num(disp_num, &dspp_num);
+ if (ret) {
+ pr_err("%s, no dspp connects to disp %d",
+ __func__, disp_num);
+ goto pcc_config_exit;
+ }
+
+ mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
+
+ base = MDSS_MDP_REG_DSPP_OFFSET(dspp_num) +
+ MDSS_MDP_REG_DSPP_PCC_BASE;
+ pp_read_pcc_regs(base, config);
+ *copyback = 1;
+ mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
+ } else {
+ mdss_pp_res->pcc_disp_cfg[disp_num] = *config;
+ mdss_pp_res->pp_disp_flags[disp_num] |= PP_FLAGS_DIRTY_PCC;
+ }
+
+pcc_config_exit:
+ mutex_unlock(&mdss_pp_mutex);
+ return ret;
+
+}
+
+static void pp_read_igc_lut(struct mdp_igc_lut_data *cfg,
+ u32 offset, u32 blk_idx)
+{
+ int i;
+ u32 data;
+
+ /* INDEX_UPDATE & VALUE_UPDATEN */
+ data = (3 << 24) | (((~(1 << blk_idx)) & 0x7) << 28);
+ MDSS_MDP_REG_WRITE(offset, data);
+
+ for (i = 0; i < cfg->len; i++)
+ cfg->c0_c1_data[i] = MDSS_MDP_REG_READ(offset) & 0xFFF;
+
+ offset += 0x4;
+ MDSS_MDP_REG_WRITE(offset, data);
+ for (i = 0; i < cfg->len; i++)
+ cfg->c0_c1_data[i] |= (MDSS_MDP_REG_READ(offset) & 0xFFF) << 16;
+
+ offset += 0x4;
+ MDSS_MDP_REG_WRITE(offset, data);
+ for (i = 0; i < cfg->len; i++)
+ cfg->c2_data[i] = MDSS_MDP_REG_READ(offset) & 0xFFF;
+}
+
+static void pp_update_igc_lut(struct mdp_igc_lut_data *cfg,
+ u32 offset, u32 blk_idx)
+{
+ int i;
+ u32 data;
+ /* INDEX_UPDATE */
+ data = (1 << 25) | (((~(1 << blk_idx)) & 0x7) << 28);
+ MDSS_MDP_REG_WRITE(offset, (cfg->c0_c1_data[0] & 0xFFF) | data);
+
+ /* disable index update */
+ data &= ~(1 << 25);
+ for (i = 1; i < cfg->len; i++)
+ MDSS_MDP_REG_WRITE(offset, (cfg->c0_c1_data[i] & 0xFFF) | data);
+
+ offset += 0x4;
+ data |= (1 << 25);
+ MDSS_MDP_REG_WRITE(offset, ((cfg->c0_c1_data[0] >> 16) & 0xFFF) | data);
+ data &= ~(1 << 25);
+ for (i = 1; i < cfg->len; i++)
+ MDSS_MDP_REG_WRITE(offset,
+ ((cfg->c0_c1_data[i] >> 16) & 0xFFF) | data);
+
+ offset += 0x4;
+ data |= (1 << 25);
+ MDSS_MDP_REG_WRITE(offset, (cfg->c2_data[0] & 0xFFF) | data);
+ data &= ~(1 << 25);
+ for (i = 1; i < cfg->len; i++)
+ MDSS_MDP_REG_WRITE(offset, (cfg->c2_data[i] & 0xFFF) | data);
+}
+
+int mdss_mdp_igc_lut_config(struct mdp_igc_lut_data *config, u32 *copyback)
+{
+ int ret = 0;
+ u32 tbl_idx, igc_offset, disp_num, dspp_num = 0;
+ struct mdp_igc_lut_data local_cfg;
+
+ if ((config->block < MDP_LOGICAL_BLOCK_DISP_0) ||
+ (config->block >= MDP_BLOCK_MAX))
+ return -EINVAL;
+
+ mutex_lock(&mdss_pp_mutex);
+ disp_num = config->block - MDP_LOGICAL_BLOCK_DISP_0;
+
+ if (config->ops & MDP_PP_OPS_READ) {
+ ret = pp_get_dspp_num(disp_num, &dspp_num);
+ if (ret) {
+ pr_err("%s, no dspp connects to disp %d",
+ __func__, disp_num);
+ goto igc_config_exit;
+ }
+ mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
+ if (config->ops & MDP_PP_IGC_FLAG_ROM0)
+ tbl_idx = 1;
+ else if (config->ops & MDP_PP_IGC_FLAG_ROM1)
+ tbl_idx = 2;
+ else
+ tbl_idx = 0;
+ igc_offset = MDSS_MDP_REG_IGC_DSPP_BASE + (0x10 * tbl_idx);
+ local_cfg = *config;
+ local_cfg.c0_c1_data =
+ &mdss_pp_res->igc_lut_c0c1[disp_num][0];
+ local_cfg.c2_data =
+ &mdss_pp_res->igc_lut_c2[disp_num][0];
+ pp_read_igc_lut(&local_cfg, igc_offset, dspp_num);
+ if (copy_to_user(config->c0_c1_data, local_cfg.c2_data,
+ config->len * sizeof(u32))) {
+ ret = -EFAULT;
+ goto igc_config_exit;
+ }
+ if (copy_to_user(config->c2_data, local_cfg.c0_c1_data,
+ config->len * sizeof(u32))) {
+ ret = -EFAULT;
+ goto igc_config_exit;
+ }
+ *copyback = 1;
+ mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
+ } else {
+ if (copy_from_user(&mdss_pp_res->igc_lut_c0c1[disp_num][0],
+ config->c0_c1_data, config->len * sizeof(u32))) {
+ ret = -EFAULT;
+ goto igc_config_exit;
+ }
+ if (copy_from_user(&mdss_pp_res->igc_lut_c2[disp_num][0],
+ config->c2_data, config->len * sizeof(u32))) {
+ ret = -EFAULT;
+ goto igc_config_exit;
+ }
+ mdss_pp_res->igc_disp_cfg[disp_num] = *config;
+ mdss_pp_res->igc_disp_cfg[disp_num].c0_c1_data =
+ &mdss_pp_res->igc_lut_c0c1[disp_num][0];
+ mdss_pp_res->igc_disp_cfg[disp_num].c2_data =
+ &mdss_pp_res->igc_lut_c2[disp_num][0];
+ mdss_pp_res->pp_disp_flags[disp_num] |= PP_FLAGS_DIRTY_IGC;
+ }
+
+igc_config_exit:
+ mutex_unlock(&mdss_pp_mutex);
+ return ret;
+}
+static void pp_update_gc_one_lut(u32 offset,
+ struct mdp_ar_gc_lut_data *lut_data)
+{
+ int i, start_idx;
+
+ start_idx = (MDSS_MDP_REG_READ(offset) >> 16) & 0xF;
+ for (i = start_idx; i < GC_LUT_SEGMENTS; i++)
+ MDSS_MDP_REG_WRITE(offset, lut_data[i].x_start);
+ for (i = 0; i < start_idx; i++)
+ MDSS_MDP_REG_WRITE(offset, lut_data[i].x_start);
+ offset += 4;
+ start_idx = (MDSS_MDP_REG_READ(offset) >> 16) & 0xF;
+ for (i = start_idx; i < GC_LUT_SEGMENTS; i++)
+ MDSS_MDP_REG_WRITE(offset, lut_data[i].slope);
+ for (i = 0; i < start_idx; i++)
+ MDSS_MDP_REG_WRITE(offset, lut_data[i].slope);
+ offset += 4;
+ start_idx = (MDSS_MDP_REG_READ(offset) >> 16) & 0xF;
+ for (i = start_idx; i < GC_LUT_SEGMENTS; i++)
+ MDSS_MDP_REG_WRITE(offset, lut_data[i].offset);
+ for (i = 0; i < start_idx; i++)
+ MDSS_MDP_REG_WRITE(offset, lut_data[i].offset);
+}
+static void pp_update_argc_lut(u32 offset, struct mdp_pgc_lut_data *config)
+{
+ pp_update_gc_one_lut(offset, config->r_data);
+ offset += 0x10;
+ pp_update_gc_one_lut(offset, config->g_data);
+ offset += 0x10;
+ pp_update_gc_one_lut(offset, config->b_data);
+}
+static void pp_read_gc_one_lut(u32 offset,
+ struct mdp_ar_gc_lut_data *gc_data)
+{
+ int i, start_idx, data;
+ data = MDSS_MDP_REG_READ(offset);
+ start_idx = (data >> 16) & 0xF;
+ gc_data[start_idx].x_start = data & 0xFFF;
+
+ for (i = start_idx + 1; i < GC_LUT_SEGMENTS; i++) {
+ data = MDSS_MDP_REG_READ(offset);
+ gc_data[i].x_start = data & 0xFFF;
+ }
+ for (i = 0; i < start_idx; i++) {
+ data = MDSS_MDP_REG_READ(offset);
+ gc_data[i].x_start = data & 0xFFF;
+ }
+
+ offset += 4;
+ data = MDSS_MDP_REG_READ(offset);
+ start_idx = (data >> 16) & 0xF;
+ gc_data[start_idx].slope = data & 0x7FFF;
+ for (i = start_idx + 1; i < GC_LUT_SEGMENTS; i++) {
+ data = MDSS_MDP_REG_READ(offset);
+ gc_data[i].slope = data & 0x7FFF;
+ }
+ for (i = 0; i < start_idx; i++) {
+ data = MDSS_MDP_REG_READ(offset);
+ gc_data[i].slope = data & 0x7FFF;
+ }
+ offset += 4;
+ data = MDSS_MDP_REG_READ(offset);
+ start_idx = (data >> 16) & 0xF;
+ gc_data[start_idx].offset = data & 0x7FFF;
+ for (i = start_idx + 1; i < GC_LUT_SEGMENTS; i++) {
+ data = MDSS_MDP_REG_READ(offset);
+ gc_data[i].offset = data & 0x7FFF;
+ }
+ for (i = 0; i < start_idx; i++) {
+ data = MDSS_MDP_REG_READ(offset);
+ gc_data[i].offset = data & 0x7FFF;
+ }
+}
+
+static int pp_read_argc_lut(struct mdp_pgc_lut_data *config, u32 offset)
+{
+ int ret = 0;
+ pp_read_gc_one_lut(offset, config->r_data);
+ offset += 0x10;
+ pp_read_gc_one_lut(offset, config->g_data);
+ offset += 0x10;
+ pp_read_gc_one_lut(offset, config->b_data);
+ return ret;
+}
+int mdss_mdp_argc_config(struct mdp_pgc_lut_data *config, u32 *copyback)
+{
+ int ret = 0;
+ u32 argc_offset, disp_num, dspp_num = 0;
+ struct mdp_pgc_lut_data local_cfg;
+ u32 tbl_size;
+
+ if ((config->block < MDP_LOGICAL_BLOCK_DISP_0) ||
+ (config->block >= MDP_BLOCK_MAX))
+ return -EINVAL;
+
+ mutex_lock(&mdss_pp_mutex);
+ disp_num = config->block - MDP_LOGICAL_BLOCK_DISP_0;
+
+ tbl_size = GC_LUT_SEGMENTS * sizeof(struct mdp_ar_gc_lut_data);
+ if (config->flags & MDP_PP_OPS_READ) {
+ ret = pp_get_dspp_num(disp_num, &dspp_num);
+ if (ret) {
+ pr_err("%s, no dspp connects to disp %d",
+ __func__, disp_num);
+ goto argc_config_exit;
+ }
+ mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
+
+ argc_offset = MDSS_MDP_REG_LM_OFFSET(dspp_num) +
+ MDSS_MDP_REG_LM_GC_LUT_BASE;
+ mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
+ local_cfg = *config;
+ local_cfg.r_data =
+ &mdss_pp_res->gc_lut_r[disp_num][0];
+ local_cfg.g_data =
+ &mdss_pp_res->gc_lut_g[disp_num][0];
+ local_cfg.b_data =
+ &mdss_pp_res->gc_lut_b[disp_num][0];
+ pp_read_argc_lut(&local_cfg, argc_offset);
+ if (copy_to_user(config->r_data,
+ &mdss_pp_res->gc_lut_r[disp_num][0], tbl_size)) {
+ ret = -EFAULT;
+ goto argc_config_exit;
+ }
+ if (copy_to_user(config->g_data,
+ &mdss_pp_res->gc_lut_g[disp_num][0], tbl_size)) {
+ ret = -EFAULT;
+ goto argc_config_exit;
+ }
+ if (copy_to_user(config->b_data,
+ &mdss_pp_res->gc_lut_b[disp_num][0], tbl_size)) {
+ ret = -EFAULT;
+ goto argc_config_exit;
+ }
+ *copyback = 1;
+ mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
+ } else {
+ if (copy_from_user(&mdss_pp_res->gc_lut_r[disp_num][0],
+ config->r_data, tbl_size)) {
+ ret = -EFAULT;
+ goto argc_config_exit;
+ }
+ if (copy_from_user(&mdss_pp_res->gc_lut_g[disp_num][0],
+ config->g_data, tbl_size)) {
+ ret = -EFAULT;
+ goto argc_config_exit;
+ }
+ if (copy_from_user(&mdss_pp_res->gc_lut_b[disp_num][0],
+ config->b_data, tbl_size)) {
+ ret = -EFAULT;
+ goto argc_config_exit;
+ }
+ mdss_pp_res->pgc_disp_cfg[disp_num] = *config;
+ mdss_pp_res->pgc_disp_cfg[disp_num].r_data =
+ &mdss_pp_res->gc_lut_r[disp_num][0];
+ mdss_pp_res->pgc_disp_cfg[disp_num].g_data =
+ &mdss_pp_res->gc_lut_g[disp_num][0];
+ mdss_pp_res->pgc_disp_cfg[disp_num].b_data =
+ &mdss_pp_res->gc_lut_b[disp_num][0];
+ mdss_pp_res->pp_disp_flags[disp_num] |= PP_FLAGS_DIRTY_ARGC;
+ }
+argc_config_exit:
+ mutex_unlock(&mdss_pp_mutex);
+ return ret;
+}
+int mdss_mdp_hist_lut_config(struct mdp_hist_lut_data *config, u32 *copyback)
+{
+ int i, ret = 0;
+ u32 hist_offset, disp_num, dspp_num = 0;
+
+ if ((config->block < MDP_LOGICAL_BLOCK_DISP_0) ||
+ (config->block >= MDP_BLOCK_MAX))
+ return -EINVAL;
+
+ mutex_lock(&mdss_pp_mutex);
+ disp_num = config->block - MDP_LOGICAL_BLOCK_DISP_0;
+
+ if (config->ops & MDP_PP_OPS_READ) {
+ ret = pp_get_dspp_num(disp_num, &dspp_num);
+ if (ret) {
+ pr_err("%s, no dspp connects to disp %d",
+ __func__, disp_num);
+ goto enhist_config_exit;
+ }
+ mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
+
+ hist_offset = MDSS_MDP_REG_DSPP_OFFSET(dspp_num) +
+ MDSS_MDP_REG_DSPP_HIST_LUT_BASE;
+ for (i = 0; i < ENHIST_LUT_ENTRIES; i++)
+ mdss_pp_res->enhist_lut[disp_num][i] =
+ MDSS_MDP_REG_READ(hist_offset);
+ if (copy_to_user(config->data,
+ &mdss_pp_res->enhist_lut[disp_num][0],
+ ENHIST_LUT_ENTRIES * sizeof(u32))) {
+ ret = -EFAULT;
+ goto enhist_config_exit;
+ }
+ *copyback = 1;
+ mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
+ } else {
+ if (copy_from_user(&mdss_pp_res->enhist_lut[disp_num][0],
+ config->data, ENHIST_LUT_ENTRIES * sizeof(u32))) {
+ ret = -EFAULT;
+ goto enhist_config_exit;
+ }
+ mdss_pp_res->enhist_disp_cfg[disp_num] = *config;
+ mdss_pp_res->enhist_disp_cfg[disp_num].data =
+ &mdss_pp_res->enhist_lut[disp_num][0];
+ mdss_pp_res->pp_disp_flags[disp_num] |= PP_FLAGS_DIRTY_ENHIST;
+ }
+enhist_config_exit:
+ mutex_unlock(&mdss_pp_mutex);
+ return ret;
+}
+
+int mdss_mdp_dither_config(struct mdp_dither_cfg_data *config, u32 *copyback)
+{
+ u32 disp_num;
+ if ((config->block < MDP_LOGICAL_BLOCK_DISP_0) ||
+ (config->block >= MDP_BLOCK_MAX))
+ return -EINVAL;
+ if (config->flags & MDP_PP_OPS_READ)
+ return -ENOTSUPP;
+
+ mutex_lock(&mdss_pp_mutex);
+ disp_num = config->block - MDP_LOGICAL_BLOCK_DISP_0;
+ mdss_pp_res->dither_disp_cfg[disp_num] = *config;
+ mdss_pp_res->pp_disp_flags[disp_num] |= PP_FLAGS_DIRTY_DITHER;
+ mutex_unlock(&mdss_pp_mutex);
+ return 0;
+}
+
+int mdss_mdp_gamut_config(struct mdp_gamut_cfg_data *config, u32 *copyback)
+{
+ int i, j, size_total = 0, ret = 0;
+ u32 offset, disp_num, dspp_num = 0;
+ uint16_t *tbl_off;
+ struct mdp_gamut_cfg_data local_cfg;
+
+ if ((config->block < MDP_LOGICAL_BLOCK_DISP_0) ||
+ (config->block >= MDP_BLOCK_MAX))
+ return -EINVAL;
+ for (i = 0; i < MDP_GAMUT_TABLE_NUM; i++)
+ size_total += config->tbl_size[i];
+ if (size_total != GAMUT_TOTAL_TABLE_SIZE)
+ return -EINVAL;
+
+ mutex_lock(&mdss_pp_mutex);
+ disp_num = config->block - MDP_LOGICAL_BLOCK_DISP_0;
+
+ if (config->flags & MDP_PP_OPS_READ) {
+ ret = pp_get_dspp_num(disp_num, &dspp_num);
+ if (ret) {
+ pr_err("%s, no dspp connects to disp %d",
+ __func__, disp_num);
+ goto gamut_config_exit;
+ }
+ mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
+
+ offset = MDSS_MDP_REG_DSPP_OFFSET(dspp_num) +
+ MDSS_MDP_REG_DSPP_GAMUT_BASE;
+ for (i = 0; i < MDP_GAMUT_TABLE_NUM; i++) {
+ for (j = 0; j < config->tbl_size[i]; j++)
+ config->r_tbl[i][j] =
+ (u16)MDSS_MDP_REG_READ(offset);
+ offset += 4;
+ }
+ for (i = 0; i < MDP_GAMUT_TABLE_NUM; i++) {
+ for (j = 0; j < config->tbl_size[i]; j++)
+ config->g_tbl[i][j] =
+ (u16)MDSS_MDP_REG_READ(offset);
+ offset += 4;
+ }
+ for (i = 0; i < MDP_GAMUT_TABLE_NUM; i++) {
+ for (j = 0; j < config->tbl_size[i]; j++)
+ config->b_tbl[i][j] =
+ (u16)MDSS_MDP_REG_READ(offset);
+ offset += 4;
+ }
+ *copyback = 1;
+ mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
+ } else {
+ local_cfg = *config;
+ tbl_off = mdss_pp_res->gamut_tbl[disp_num];
+ for (i = 0; i < MDP_GAMUT_TABLE_NUM; i++) {
+ local_cfg.r_tbl[i] = tbl_off;
+ if (copy_from_user(tbl_off, config->r_tbl[i],
+ config->tbl_size[i] * sizeof(uint16_t))) {
+ ret = -EFAULT;
+ goto gamut_config_exit;
+ }
+ tbl_off += local_cfg.tbl_size[i];
+ }
+ for (i = 0; i < MDP_GAMUT_TABLE_NUM; i++) {
+ local_cfg.g_tbl[i] = tbl_off;
+ if (copy_from_user(tbl_off, config->g_tbl[i],
+ config->tbl_size[i] * sizeof(uint16_t))) {
+ ret = -EFAULT;
+ goto gamut_config_exit;
+ }
+ tbl_off += local_cfg.tbl_size[i];
+ }
+ for (i = 0; i < MDP_GAMUT_TABLE_NUM; i++) {
+ local_cfg.b_tbl[i] = tbl_off;
+ if (copy_from_user(tbl_off, config->b_tbl[i],
+ config->tbl_size[i] * sizeof(uint16_t))) {
+ ret = -EFAULT;
+ goto gamut_config_exit;
+ }
+ tbl_off += local_cfg.tbl_size[i];
+ }
+ mdss_pp_res->gamut_disp_cfg[disp_num] = local_cfg;
+ mdss_pp_res->pp_disp_flags[disp_num] |= PP_FLAGS_DIRTY_GAMUT;
+ }
+gamut_config_exit:
+ mutex_unlock(&mdss_pp_mutex);
+ return ret;
+}
+static void pp_hist_read(u32 v_base, struct pp_hist_col_info *hist_info)
+{
+ int i, i_start;
+ u32 data;
+ data = MDSS_MDP_REG_READ(v_base);
+ i_start = data >> 24;
+ hist_info->data[i_start] = data & 0xFFFFFF;
+ for (i = i_start + 1; i < HIST_V_SIZE; i++)
+ hist_info->data[i] = MDSS_MDP_REG_READ(v_base) & 0xFFFFFF;
+ for (i = 0; i < i_start - 1; i++)
+ hist_info->data[i] = MDSS_MDP_REG_READ(v_base) & 0xFFFFFF;
+ hist_info->hist_cnt_read++;
+}
+
+int mdss_mdp_histogram_start(struct mdp_histogram_start_req *req)
+{
+ u32 ctl_base, done_shift_bit;
+ struct pp_hist_col_info *hist_info;
+ int i, ret = 0;
+ u32 disp_num, dspp_num = 0;
+ u32 mixer_cnt, mixer_id[MDSS_MDP_MAX_LAYERMIXER];
+
+ if ((req->block < MDP_LOGICAL_BLOCK_DISP_0) ||
+ (req->block >= MDP_BLOCK_MAX))
+ return -EINVAL;
+
+ mutex_lock(&mdss_mdp_hist_mutex);
+ disp_num = req->block - MDP_LOGICAL_BLOCK_DISP_0;
+ mixer_cnt = mdss_mdp_get_ctl_mixers(disp_num, mixer_id);
+
+ if (!mixer_cnt) {
+ pr_err("%s, no dspp connects to disp %d",
+ __func__, disp_num);
+ ret = -EPERM;
+ goto hist_start_exit;
+ }
+ if (mixer_cnt >= MDSS_MDP_MAX_DSPP) {
+ pr_err("%s, Too many dspp connects to disp %d",
+ __func__, mixer_cnt);
+ ret = -EPERM;
+ goto hist_start_exit;
+ }
+ mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
+ for (i = 0; i < mixer_cnt; i++) {
+ dspp_num = mixer_id[i];
+ hist_info = &mdss_pp_res->dspp_hist[dspp_num];
+ done_shift_bit = (dspp_num * 4) + 12;
+ /* check if it is idle */
+ if (hist_info->col_en) {
+ mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
+ pr_info("%s Hist collection has already been enabled %d",
+ __func__, dspp_num);
+ goto hist_start_exit;
+ }
+ spin_lock(&mdss_hist_lock);
+ hist_info->frame_cnt = req->frame_cnt;
+ init_completion(&hist_info->comp);
+ hist_info->hist_cnt_read = 0;
+ hist_info->hist_cnt_sent = 0;
+ hist_info->read_request = false;
+ hist_info->col_state = HIST_RESET;
+ hist_info->col_en = true;
+ spin_unlock(&mdss_hist_lock);
+ mdss_pp_res->hist_col[disp_num][i] =
+ &mdss_pp_res->dspp_hist[dspp_num];
+ mdss_mdp_hist_irq_enable(3 << done_shift_bit);
+ ctl_base = MDSS_MDP_REG_DSPP_OFFSET(dspp_num) +
+ MDSS_MDP_REG_DSPP_HIST_CTL_BASE;
+ MDSS_MDP_REG_WRITE(ctl_base + 8, req->frame_cnt);
+ /* Kick out reset start */
+ MDSS_MDP_REG_WRITE(ctl_base + 4, 1);
+ }
+ for (i = mixer_cnt; i < MDSS_MDP_MAX_DSPP; i++)
+ mdss_pp_res->hist_col[disp_num][i] = 0;
+ mdss_pp_res->pp_disp_flags[disp_num] |= PP_FLAGS_DIRTY_HIST_COL;
+ mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
+hist_start_exit:
+ mutex_unlock(&mdss_mdp_hist_mutex);
+ return ret;
+}
+
+int mdss_mdp_histogram_stop(u32 block)
+{
+ int i, ret = 0;
+ u32 dspp_num, disp_num, ctl_base, done_bit;
+ struct pp_hist_col_info *hist_info;
+ u32 mixer_cnt, mixer_id[MDSS_MDP_MAX_LAYERMIXER];
+
+ if ((block < MDP_LOGICAL_BLOCK_DISP_0) ||
+ (block >= MDP_BLOCK_MAX))
+ return -EINVAL;
+
+ mutex_lock(&mdss_mdp_hist_mutex);
+ disp_num = block - MDP_LOGICAL_BLOCK_DISP_0;
+ mixer_cnt = mdss_mdp_get_ctl_mixers(disp_num, mixer_id);
+
+ if (!mixer_cnt) {
+ pr_err("%s, no dspp connects to disp %d",
+ __func__, disp_num);
+ ret = -EPERM;
+ goto hist_stop_exit;
+ }
+ if (mixer_cnt >= MDSS_MDP_MAX_DSPP) {
+ pr_err("%s, Too many dspp connects to disp %d",
+ __func__, mixer_cnt);
+ ret = -EPERM;
+ goto hist_stop_exit;
+ }
+ mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
+ for (i = 0; i < mixer_cnt; i++) {
+ dspp_num = mixer_id[i];
+ hist_info = &mdss_pp_res->dspp_hist[dspp_num];
+ done_bit = 3 << ((dspp_num * 4) + 12);
+ ctl_base = MDSS_MDP_REG_DSPP_OFFSET(dspp_num) +
+ MDSS_MDP_REG_DSPP_HIST_CTL_BASE;
+ if (hist_info->col_en == false) {
+ mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
+ goto hist_stop_exit;
+ }
+ complete_all(&hist_info->comp);
+ spin_lock(&mdss_hist_lock);
+ hist_info->col_en = false;
+ hist_info->col_state = HIST_UNKNOWN;
+ spin_unlock(&mdss_hist_lock);
+ mdss_mdp_hist_irq_disable(done_bit);
+ MDSS_MDP_REG_WRITE(ctl_base, (1 << 1));/* cancel */
+ }
+ for (i = 0; i < MDSS_MDP_MAX_DSPP; i++)
+ mdss_pp_res->hist_col[disp_num][i] = 0;
+ mdss_pp_res->pp_disp_flags[disp_num] |= PP_FLAGS_DIRTY_HIST_COL;
+ mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
+hist_stop_exit:
+ mutex_unlock(&mdss_mdp_hist_mutex);
+ return ret;
+}
+
+int mdss_mdp_hist_collect(struct fb_info *info,
+ struct mdp_histogram_data *hist, u32 *hist_data_addr)
+{
+ int i, j, wait_ret, ret = 0;
+ u32 timeout, v_base;
+ struct pp_hist_col_info *hist_info;
+ u32 dspp_num, disp_num, ctl_base;
+ u32 mixer_cnt, mixer_id[MDSS_MDP_MAX_LAYERMIXER];
+
+ if ((hist->block < MDP_LOGICAL_BLOCK_DISP_0) ||
+ (hist->block >= MDP_BLOCK_MAX))
+ return -EINVAL;
+
+ mutex_lock(&mdss_mdp_hist_mutex);
+ disp_num = hist->block - MDP_LOGICAL_BLOCK_DISP_0;
+ mixer_cnt = mdss_mdp_get_ctl_mixers(disp_num, mixer_id);
+
+ if (!mixer_cnt) {
+ pr_err("%s, no dspp connects to disp %d",
+ __func__, disp_num);
+ ret = -EPERM;
+ goto hist_collect_exit;
+ }
+ if (mixer_cnt >= MDSS_MDP_MAX_DSPP) {
+ pr_err("%s, Too many dspp connects to disp %d",
+ __func__, mixer_cnt);
+ ret = -EPERM;
+ goto hist_collect_exit;
+ }
+ hist_info = &mdss_pp_res->dspp_hist[0];
+ for (i = 0; i < mixer_cnt; i++) {
+ dspp_num = mixer_id[i];
+ hist_info = &mdss_pp_res->dspp_hist[dspp_num];
+ ctl_base = MDSS_MDP_REG_DSPP_OFFSET(dspp_num) +
+ MDSS_MDP_REG_DSPP_HIST_CTL_BASE;
+ if ((hist_info->col_en == 0) ||
+ (hist_info->col_state == HIST_UNKNOWN)) {
+ ret = -EINVAL;
+ goto hist_collect_exit;
+ }
+ spin_lock(&mdss_hist_lock);
+ if ((hist_info->col_state == HIST_READY) ||
+ (hist_info->hist_cnt_read == 0)) {
+ /* wait for hist done if cache has no data */
+ if ((hist_info->col_state != HIST_READY) &&
+ (hist_info->hist_cnt_read == 0)) {
+ hist_info->read_request = true;
+ spin_unlock(&mdss_hist_lock);
+ timeout = HIST_WAIT_TIMEOUT *
+ hist_info->frame_cnt;
+ mutex_unlock(&mdss_mdp_hist_mutex);
+ wait_ret = wait_for_completion_killable_timeout(
+ &(hist_info->comp), timeout);
+
+ mutex_lock(&mdss_mdp_hist_mutex);
+ hist_info->read_request = false;
+ if (wait_ret == 0) {
+ ret = -ETIMEDOUT;
+ pr_debug("%s: bin collection timedout",
+ __func__);
+ goto hist_collect_exit;
+ } else if (wait_ret < 0) {
+ ret = -EINTR;
+ pr_debug("%s: bin collection interrupted",
+ __func__);
+ goto hist_collect_exit;
+ }
+ if (hist_info->col_state != HIST_READY) {
+ ret = -EBUSY;
+ pr_err("%s: collection state is not ready: %d",
+ __func__, hist_info->col_state);
+ goto hist_collect_exit;
+ }
+ } else {
+ spin_unlock(&mdss_hist_lock);
+ }
+ if (hist_info->col_state == HIST_READY) {
+ v_base = ctl_base + 0x1C;
+ mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
+ pp_hist_read(v_base, hist_info);
+ mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
+ spin_lock(&mdss_hist_lock);
+ hist_info->col_state = HIST_IDLE;
+ spin_unlock(&mdss_hist_lock);
+ }
+ } else {
+ spin_unlock(&mdss_hist_lock);
+ }
+ hist_info->hist_cnt_sent = hist_info->hist_cnt_read;
+ }
+ if (mixer_cnt > 1) {
+ memset(&mdss_pp_res->hist_data[disp_num][0],
+ 0, HIST_V_SIZE * sizeof(u32));
+ for (i = 0; i < mixer_cnt; i++) {
+ dspp_num = mixer_id[i];
+ hist_info = &mdss_pp_res->dspp_hist[dspp_num];
+ for (j = 0; j < HIST_V_SIZE; j++)
+ mdss_pp_res->hist_data[disp_num][i] +=
+ hist_info->data[i];
+ }
+ *hist_data_addr = (u32)&mdss_pp_res->hist_data[disp_num][0];
+ } else {
+ *hist_data_addr = (u32)hist_info->data;
+ }
+
+hist_collect_exit:
+ mutex_unlock(&mdss_mdp_hist_mutex);
+ return ret;
+}
+void mdss_mdp_hist_intr_done(u32 isr)
+{
+ u32 isr_blk, blk_idx;
+ struct pp_hist_col_info *hist_info;
+ isr &= 0x333333;
+ while (isr != 0) {
+ if (isr & 0xFFF000) {
+ if (isr & 0x3000) {
+ blk_idx = 0;
+ isr_blk = (isr >> 12) & 0x3;
+ isr &= ~0x3000;
+ } else if (isr & 0x30000) {
+ blk_idx = 1;
+ isr_blk = (isr >> 16) & 0x3;
+ isr &= ~0x30000;
+ } else {
+ blk_idx = 2;
+ isr_blk = (isr >> 20) & 0x3;
+ isr &= ~0x300000;
+ }
+ hist_info = &mdss_pp_res->dspp_hist[blk_idx];
+ } else {
+ if (isr & 0x3) {
+ blk_idx = 0;
+ isr_blk = isr & 0x3;
+ isr &= ~0x3;
+ } else if (isr & 0x30) {
+ blk_idx = 1;
+ isr_blk = (isr >> 4) & 0x3;
+ isr &= ~0x30;
+ } else {
+ blk_idx = 2;
+ isr_blk = (isr >> 8) & 0x3;
+ isr &= ~0x300;
+ }
+ /* SSPP block, not support yet*/
+ continue;
+ }
+ /* Histogram Done Interrupt */
+ if ((isr_blk & 0x1) &&
+ (hist_info->col_en)) {
+ spin_lock(&mdss_hist_lock);
+ hist_info->col_state = HIST_READY;
+ spin_unlock(&mdss_hist_lock);
+ if (hist_info->read_request)
+ complete(&hist_info->comp);
+ }
+ /* Histogram Reset Done Interrupt */
+ if ((isr_blk & 0x2) &&
+ (hist_info->col_en)) {
+ spin_lock(&mdss_hist_lock);
+ hist_info->col_state = HIST_IDLE;
+ spin_unlock(&mdss_hist_lock);
+ }
+ };
+}
diff --git a/drivers/video/msm/mdss/mdss_mdp_util.c b/drivers/video/msm/mdss/mdss_mdp_util.c
index 57e8441..95c92fc 100644
--- a/drivers/video/msm/mdss/mdss_mdp_util.c
+++ b/drivers/video/msm/mdss/mdss_mdp_util.c
@@ -112,22 +112,22 @@
irqreturn_t mdss_mdp_isr(int irq, void *ptr)
{
- u32 isr, mask;
+ u32 isr, mask, hist_isr, hist_mask;
isr = MDSS_MDP_REG_READ(MDSS_MDP_REG_INTR_STATUS);
- pr_debug("isr=%x\n", isr);
-
if (isr == 0)
- goto done;
+ goto mdp_isr_done;
+
+ pr_debug("isr=%x\n", isr);
mask = MDSS_MDP_REG_READ(MDSS_MDP_REG_INTR_EN);
MDSS_MDP_REG_WRITE(MDSS_MDP_REG_INTR_CLEAR, isr);
isr &= mask;
if (isr == 0)
- goto done;
+ goto mdp_isr_done;
if (isr & MDSS_MDP_INTR_PING_PONG_0_DONE)
mdss_mdp_intr_done(MDP_INTR_PING_PONG_0);
@@ -159,7 +159,17 @@
if (isr & MDSS_MDP_INTR_WB_2_DONE)
mdss_mdp_intr_done(MDP_INTR_WB_2);
-done:
+mdp_isr_done:
+ hist_isr = MDSS_MDP_REG_READ(MDSS_MDP_REG_HIST_INTR_STATUS);
+ if (hist_isr == 0)
+ goto hist_isr_done;
+ hist_mask = MDSS_MDP_REG_READ(MDSS_MDP_REG_HIST_INTR_EN);
+ MDSS_MDP_REG_WRITE(MDSS_MDP_REG_HIST_INTR_CLEAR, hist_isr);
+ hist_isr &= hist_mask;
+ if (hist_isr == 0)
+ goto hist_isr_done;
+ mdss_mdp_hist_intr_done(hist_isr);
+hist_isr_done:
return IRQ_HANDLED;
}
@@ -203,7 +213,7 @@
} else {
u8 hmap[] = { 1, 2, 1, 2 };
u8 vmap[] = { 1, 1, 2, 2 };
- u8 horiz, vert, stride_align;
+ u8 horiz, vert, stride_align, height_align;
horiz = hmap[fmt->chroma_sample];
vert = vmap[fmt->chroma_sample];
@@ -211,18 +221,21 @@
switch (format) {
case MDP_Y_CR_CB_GH2V2:
stride_align = 16;
+ height_align = 1;
break;
case MDP_Y_CBCR_H2V2_VENUS:
stride_align = 32;
+ height_align = 32;
break;
default:
stride_align = 1;
+ height_align = 1;
break;
}
ps->ystride[0] = ALIGN(w, stride_align);
ps->ystride[1] = ALIGN(w / horiz, stride_align);
- ps->plane_size[0] = ps->ystride[0] * h;
+ ps->plane_size[0] = ps->ystride[0] * ALIGN(h, height_align);
ps->plane_size[1] = ps->ystride[1] * (h / vert);
if (fmt->fetch_planes == MDSS_MDP_PLANE_PSEUDO_PLANAR) {
diff --git a/drivers/video/msm/mdss/mdss_mdp_wb.c b/drivers/video/msm/mdss/mdss_mdp_wb.c
index b0a67938..b18efbe 100644
--- a/drivers/video/msm/mdss/mdss_mdp_wb.c
+++ b/drivers/video/msm/mdss/mdss_mdp_wb.c
@@ -86,13 +86,13 @@
ihdl = ion_alloc(iclient, img_size, SZ_4K,
- ION_HEAP(ION_SF_HEAP_ID));
+ ION_HEAP(ION_SF_HEAP_ID), 0);
if (IS_ERR_OR_NULL(ihdl)) {
pr_err("unable to alloc fbmem from ion (%p)\n", ihdl);
return NULL;
}
- videomemory = ion_map_kernel(iclient, ihdl, 0);
+ videomemory = ion_map_kernel(iclient, ihdl);
ion_phys(iclient, ihdl, &mdss_wb_mem, &img_size);
if (is_mdss_iommu_attached()) {
diff --git a/drivers/video/msm/mipi_dsi_host.c b/drivers/video/msm/mipi_dsi_host.c
index 2b75193..60311dc 100644
--- a/drivers/video/msm/mipi_dsi_host.c
+++ b/drivers/video/msm/mipi_dsi_host.c
@@ -25,6 +25,7 @@
#include <linux/uaccess.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
+#include <linux/iopoll.h>
#include <asm/system.h>
#include <asm/mach-types.h>
@@ -964,31 +965,30 @@
uint32 dsi_ctrl;
uint32 status;
- int cnt;
+ u32 sleep_us = 1000;
+ u32 timeout_us = 16000;
- cnt = 16;
- while (cnt--) {
- status = MIPI_INP(MIPI_DSI_BASE + 0x0004);
- status &= 0x02; /* CMD_MODE_DMA_BUSY */
- if (status == 0)
- break;
- usleep(1000);
- }
- if (cnt == 0)
+ /* Check for CMD_MODE_DMA_BUSY */
+ if (readl_poll_timeout((MIPI_DSI_BASE + 0x0004),
+ status,
+ ((status & 0x02) == 0),
+ sleep_us, timeout_us))
pr_info("%s: DSI status=%x failed\n", __func__, status);
- cnt = 16;
- while (cnt--) {
- status = MIPI_INP(MIPI_DSI_BASE + 0x0008);
- status &= 0x11111000; /* x_HS_FIFO_EMPTY */
- if (status == 0x11111000) /* all empty */
- break;
- usleep(1000);
- }
-
- if (cnt == 0)
+ /* Check for x_HS_FIFO_EMPTY */
+ if (readl_poll_timeout((MIPI_DSI_BASE + 0x0008),
+ status,
+ ((status & 0x11111000) == 0x11111000),
+ sleep_us, timeout_us))
pr_info("%s: FIFO status=%x failed\n", __func__, status);
+ /* Check for VIDEO_MODE_ENGINE_BUSY */
+ if (readl_poll_timeout((MIPI_DSI_BASE + 0x0004),
+ status,
+ ((status & 0x08) == 0),
+ sleep_us, timeout_us))
+ pr_info("%s: DSI status=%x failed\n", __func__, status);
+
dsi_ctrl = MIPI_INP(MIPI_DSI_BASE + 0x0000);
if (enable)
dsi_ctrl |= 0x01;
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c
index 9c55fe8..9f05a6a 100644
--- a/drivers/video/msm/msm_fb.c
+++ b/drivers/video/msm/msm_fb.c
@@ -185,8 +185,9 @@
if (!bl_lvl && value)
bl_lvl = 1;
-
+ down(&mfd->sem);
msm_fb_set_backlight(mfd, bl_lvl);
+ up(&mfd->sem);
}
static struct led_classdev backlight_led = {
@@ -809,7 +810,9 @@
struct mdp_bl_scale_data *data)
{
int ret = 0;
- int curr_bl = mfd->bl_level;
+ int curr_bl;
+ down(&mfd->sem);
+ curr_bl = mfd->bl_level;
bl_scale = data->scale;
bl_min_lvl = data->min_lvl;
pr_debug("%s: update scale = %d, min_lvl = %d\n", __func__, bl_scale,
@@ -817,6 +820,7 @@
/* update current backlight to use new scaling*/
msm_fb_set_backlight(mfd, curr_bl);
+ up(&mfd->sem);
return ret;
}
@@ -824,6 +828,7 @@
static void msm_fb_scale_bl(__u32 *bl_lvl)
{
__u32 temp = *bl_lvl;
+ pr_debug("%s: input = %d, scale = %d", __func__, temp, bl_scale);
if (temp >= bl_min_lvl) {
/* bl_scale is the numerator of scaling fraction (x/1024)*/
temp = ((*bl_lvl) * bl_scale) / 1024;
@@ -832,10 +837,12 @@
if (temp < bl_min_lvl)
temp = bl_min_lvl;
}
+ pr_debug("%s: output = %d", __func__, temp);
(*bl_lvl) = temp;
}
+/*must call this function from within mfd->sem*/
void msm_fb_set_backlight(struct msm_fb_data_type *mfd, __u32 bkl_lvl)
{
struct msm_fb_panel_data *pdata;
@@ -847,20 +854,17 @@
unset_bl_level = 0;
}
- msm_fb_scale_bl(&temp);
pdata = (struct msm_fb_panel_data *)mfd->pdev->dev.platform_data;
if ((pdata) && (pdata->set_backlight)) {
- down(&mfd->sem);
+ msm_fb_scale_bl(&temp);
if (bl_level_old == temp) {
- up(&mfd->sem);
return;
}
mfd->bl_level = temp;
pdata->set_backlight(mfd);
mfd->bl_level = bkl_lvl;
bl_level_old = temp;
- up(&mfd->sem);
}
}
@@ -3376,49 +3380,31 @@
switch (cmd) {
#ifdef CONFIG_FB_MSM_OVERLAY
case MSMFB_OVERLAY_GET:
- down(&msm_fb_ioctl_ppp_sem);
ret = msmfb_overlay_get(info, argp);
- up(&msm_fb_ioctl_ppp_sem);
break;
case MSMFB_OVERLAY_SET:
- down(&msm_fb_ioctl_ppp_sem);
ret = msmfb_overlay_set(info, argp);
- up(&msm_fb_ioctl_ppp_sem);
break;
case MSMFB_OVERLAY_UNSET:
- down(&msm_fb_ioctl_ppp_sem);
ret = msmfb_overlay_unset(info, argp);
- up(&msm_fb_ioctl_ppp_sem);
break;
case MSMFB_OVERLAY_PLAY:
- down(&msm_fb_ioctl_ppp_sem);
ret = msmfb_overlay_play(info, argp);
- up(&msm_fb_ioctl_ppp_sem);
break;
case MSMFB_OVERLAY_PLAY_ENABLE:
- down(&msm_fb_ioctl_ppp_sem);
ret = msmfb_overlay_play_enable(info, argp);
- up(&msm_fb_ioctl_ppp_sem);
break;
case MSMFB_OVERLAY_PLAY_WAIT:
- down(&msm_fb_ioctl_ppp_sem);
ret = msmfb_overlay_play_wait(info, argp);
- up(&msm_fb_ioctl_ppp_sem);
break;
case MSMFB_OVERLAY_BLT:
- down(&msm_fb_ioctl_ppp_sem);
ret = msmfb_overlay_blt(info, argp);
- up(&msm_fb_ioctl_ppp_sem);
break;
case MSMFB_OVERLAY_3D:
- down(&msm_fb_ioctl_ppp_sem);
ret = msmfb_overlay_3d_sbys(info, argp);
- up(&msm_fb_ioctl_ppp_sem);
break;
case MSMFB_MIXER_INFO:
- down(&msm_fb_ioctl_ppp_sem);
ret = msmfb_mixer_info(info, argp);
- up(&msm_fb_ioctl_ppp_sem);
break;
case MSMFB_WRITEBACK_INIT:
ret = msmfb_overlay_ioctl_writeback_init(info);
diff --git a/drivers/video/msm/msm_fb.h b/drivers/video/msm/msm_fb.h
index 2896349..7dc89ef 100644
--- a/drivers/video/msm/msm_fb.h
+++ b/drivers/video/msm/msm_fb.h
@@ -37,7 +37,6 @@
#include <linux/fb.h>
#include <linux/list.h>
#include <linux/types.h>
-
#include <linux/msm_mdp.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
@@ -189,6 +188,7 @@
int cont_splash_done;
void *copy_splash_buf;
unsigned char *copy_splash_phys;
+ void *cpu_pm_hdl;
};
struct dentry *msm_fb_get_debugfs_root(void);
diff --git a/drivers/video/msm/msm_fb_bl.c b/drivers/video/msm/msm_fb_bl.c
index 9afbbf1..b21adee 100644
--- a/drivers/video/msm/msm_fb_bl.c
+++ b/drivers/video/msm/msm_fb_bl.c
@@ -34,7 +34,9 @@
bl_lvl = pbd->props.brightness;
bl_lvl = mfd->fbi->bl_curve[bl_lvl];
+ down(&mfd->sem);
msm_fb_set_backlight(mfd, bl_lvl);
+ up(&mfd->sem);
return 0;
}
diff --git a/drivers/video/msm/msm_fb_panel.h b/drivers/video/msm/msm_fb_panel.h
index a2c3db1..7fc7a2f 100644
--- a/drivers/video/msm/msm_fb_panel.h
+++ b/drivers/video/msm/msm_fb_panel.h
@@ -168,7 +168,7 @@
__u32 frame_count;
__u32 is_3d_panel;
__u32 frame_rate;
-
+ __u32 frame_interval;
struct mddi_panel_info mddi;
struct lcd_panel_info lcd;
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h
index 400a3a7..2a850d8 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h
@@ -292,6 +292,7 @@
u32 num_slices_comp;
struct vcd_property_slice_delivery_info slice_delivery_info;
struct ddl_batch_frame_data batch_frame;
+ u32 avc_delimiter_enable;
};
struct ddl_decoder_data {
struct ddl_codec_data_hdr hdr;
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c
index d4601f2..1782fd2 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c
@@ -278,7 +278,8 @@
memset(frame[i].vcd_frm.virtual + luma_size,
0x80808080,
frame[i].vcd_frm.alloc_len - luma_size);
- if (frame[i].vcd_frm.ion_flag == CACHED) {
+ if (frame[i].vcd_frm.ion_flag
+ == ION_FLAG_CACHED) {
msm_ion_do_cache_op(
ddl_context->video_ion_client,
frame[i].vcd_frm.buff_ion_handle,
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
index 931c1c8..d6558c3 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
@@ -1047,6 +1047,20 @@
case VCD_REQ_PERF_LEVEL:
vcd_status = VCD_S_SUCCESS;
break;
+ case VCD_I_ENABLE_DELIMITER_FLAG:
+ {
+ struct vcd_property_avc_delimiter_enable *delimiter_enable =
+ (struct vcd_property_avc_delimiter_enable *)
+ property_value;
+ if (sizeof(struct vcd_property_avc_delimiter_enable) ==
+ property_hdr->sz &&
+ encoder->codec.codec == VCD_CODEC_H264) {
+ encoder->avc_delimiter_enable =
+ delimiter_enable->avc_delimiter_enable_flag;
+ vcd_status = VCD_S_SUCCESS;
+ }
+ break;
+ }
default:
DDL_MSG_ERROR("INVALID ID %d\n", (int)property_hdr->prop_id);
vcd_status = VCD_ERR_ILLEGAL_OP;
@@ -1530,6 +1544,15 @@
vcd_status = VCD_S_SUCCESS;
}
break;
+ case VCD_I_ENABLE_DELIMITER_FLAG:
+ if (sizeof(struct vcd_property_avc_delimiter_enable) ==
+ property_hdr->sz) {
+ ((struct vcd_property_avc_delimiter_enable *)
+ property_value)->avc_delimiter_enable_flag =
+ encoder->avc_delimiter_enable;
+ vcd_status = VCD_S_SUCCESS;
+ }
+ break;
default:
vcd_status = VCD_ERR_ILLEGAL_OP;
break;
@@ -1691,6 +1714,7 @@
encoder->slice_delivery_info.enable = 0;
encoder->slice_delivery_info.num_slices = 0;
encoder->slice_delivery_info.num_slices_enc = 0;
+ encoder->avc_delimiter_enable = 0;
}
static void ddl_set_default_enc_profile(struct ddl_encoder_data *encoder)
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c
index 8099234..40dc2aa 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c
@@ -83,6 +83,8 @@
#define VIDC_SM_ENC_EXT_CTRL_ADDR 0x0028
#define VIDC_SM_ENC_EXT_CTRL_VBV_BUFFER_SIZE_BMSK 0xffff0000
#define VIDC_SM_ENC_EXT_CTRL_VBV_BUFFER_SIZE_SHFT 16
+#define VIDC_SM_ENC_EXT_CTRL_AU_DELIMITER_EN_BMSK 0x00000800
+#define VIDC_SM_ENC_EXT_CTRL_AU_DELIMITER_EN_SHFT 11
#define VIDC_SM_ENC_EXT_CTRL_H263_CPCFC_ENABLE_BMSK 0x80
#define VIDC_SM_ENC_EXT_CTRL_H263_CPCFC_ENABLE_SHFT 7
#define VIDC_SM_ENC_EXT_CTRL_SPS_PPS_CONTROL_BMSK 0X100
@@ -446,10 +448,10 @@
*shared_mem, u32 hec_enable,
enum VIDC_SM_frame_skip frame_skip_mode,
u32 seq_hdr_in_band, u32 vbv_buffer_size, u32 cpcfc_enable,
- u32 sps_pps_control, u32 closed_gop_enable)
+ u32 sps_pps_control, u32 closed_gop_enable,
+ u32 au_delim_enable)
{
u32 enc_ctrl;
-
enc_ctrl = VIDC_SETFIELD((hec_enable) ? 1 : 0,
VIDC_SM_ENC_EXT_CTRL_HEC_ENABLE_SHFT,
VIDC_SM_ENC_EXT_CTRL_HEC_ENABLE_BMSK) |
@@ -470,7 +472,11 @@
VIDC_SM_ENC_EXT_CTRL_SPS_PPS_CONTROL_BMSK) |
VIDC_SETFIELD(closed_gop_enable,
VIDC_SM_ENC_EXT_CTRL_CLOSED_GOP_ENABLE_SHFT,
- VIDC_SM_ENC_EXT_CTRL_CLOSED_GOP_ENABLE_BMSK);
+ VIDC_SM_ENC_EXT_CTRL_CLOSED_GOP_ENABLE_BMSK) |
+ VIDC_SETFIELD((au_delim_enable) ? 1 : 0,
+ VIDC_SM_ENC_EXT_CTRL_AU_DELIMITER_EN_SHFT,
+ VIDC_SM_ENC_EXT_CTRL_AU_DELIMITER_EN_BMSK);
+
DDL_MEM_WRITE_32(shared_mem, VIDC_SM_ENC_EXT_CTRL_ADDR, enc_ctrl);
}
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.h
index 9cb1933..c4d577b 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.h
@@ -106,7 +106,7 @@
struct ddl_buf_addr *shared_mem, u32 hec_enable,
enum VIDC_SM_frame_skip frame_skip_mode, u32 seq_hdr_in_band,
u32 vbv_buffer_size, u32 cpcfc_enable, u32 sps_pps_control,
- u32 closed_gop_enable);
+ u32 closed_gop_enable, u32 au_delim_enable);
void vidc_sm_set_encoder_param_change(struct ddl_buf_addr *shared_mem,
u32 bit_rate_chg, u32 frame_rate_chg, u32 i_period_chg);
void vidc_sm_set_encoder_vop_time(struct ddl_buf_addr *shared_mem,
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c
index 5897a33..31f60e5 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c
@@ -45,7 +45,6 @@
unsigned long iova = 0;
unsigned long buffer_size = 0;
unsigned long *kernel_vaddr = NULL;
- unsigned long ionflag = 0;
unsigned long flags = 0;
int ret = 0;
ion_phys_addr_t phyaddr = 0;
@@ -71,20 +70,15 @@
alloc_size = (alloc_size+4095) & ~4095;
addr->alloc_handle = ion_alloc(
ddl_context->video_ion_client, alloc_size, SZ_4K,
- res_trk_get_mem_type());
+ res_trk_get_mem_type(), 0);
if (IS_ERR_OR_NULL(addr->alloc_handle)) {
DDL_MSG_ERROR("%s() :DDL ION alloc failed\n",
__func__);
goto bail_out;
}
- if (res_trk_check_for_sec_session() ||
- addr->mem_type == DDL_FW_MEM)
- ionflag = UNCACHED;
- else
- ionflag = CACHED;
kernel_vaddr = (unsigned long *) ion_map_kernel(
ddl_context->video_ion_client,
- addr->alloc_handle, ionflag);
+ addr->alloc_handle);
if (IS_ERR_OR_NULL(kernel_vaddr)) {
DDL_MSG_ERROR("%s() :DDL ION map failed\n",
__func__);
@@ -111,7 +105,7 @@
0,
&iova,
&buffer_size,
- UNCACHED, 0);
+ 0, 0);
if (ret || !iova) {
DDL_MSG_ERROR(
"%s():DDL ION ion map iommu failed, ret = %d iova = 0x%lx\n",
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c
index 4687915..5eed305 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c
@@ -596,7 +596,7 @@
[ddl->command_channel], hdr_ext_control,
r_cframe_skip, false, 0,
h263_cpfc_enable, encoder->sps_pps.sps_pps_for_idr_enable_flag,
- encoder->closed_gop);
+ encoder->closed_gop, encoder->avc_delimiter_enable);
vidc_sm_set_encoder_init_rc_value(&ddl->shared_mem
[ddl->command_channel],
encoder->target_bit_rate.target_bitrate);
diff --git a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c
index 3ac396c..3670dc81 100644
--- a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c
+++ b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c
@@ -27,8 +27,8 @@
#define PIL_FW_SIZE 0x200000
-static unsigned int vidc_clk_table[4] = {
- 48000000, 133330000, 200000000, 228570000,
+static unsigned int vidc_clk_table[5] = {
+ 48000000, 133330000, 200000000, 228570000, 266670000,
};
static unsigned int restrk_mmu_subsystem[] = {
MSM_SUBSYSTEM_VIDEO, MSM_SUBSYSTEM_VIDEO_FWARE};
@@ -69,7 +69,7 @@
if (res_trk_get_enable_ion() && addr->alloc_handle) {
kernel_vaddr = (unsigned long *) ion_map_kernel(
ddl_context->video_ion_client,
- addr->alloc_handle, UNCACHED);
+ addr->alloc_handle);
if (IS_ERR_OR_NULL(kernel_vaddr)) {
DDL_MSG_ERROR("%s():DDL ION client map failed\n",
__func__);
@@ -84,7 +84,7 @@
0,
&iova,
&buffer_size,
- UNCACHED, 0);
+ 0, 0);
if (ret || !iova) {
DDL_MSG_ERROR(
"%s():DDL ION client iommu map failed, ret = %d iova = 0x%lx\n",
@@ -209,7 +209,7 @@
addr->alloc_handle = ion_alloc(
ddl_context->video_ion_client,
alloc_size, SZ_4K,
- res_trk_get_mem_type());
+ res_trk_get_mem_type(), 0);
if (IS_ERR_OR_NULL(addr->alloc_handle)) {
DDL_MSG_ERROR("%s() :DDL ION alloc failed\n",
__func__);
@@ -629,7 +629,7 @@
vidc_freq = vidc_clk_table[2];
*pn_set_perf_lvl = RESTRK_1080P_MAX_PERF_LEVEL;
} else {
- vidc_freq = vidc_clk_table[3];
+ vidc_freq = vidc_clk_table[4];
*pn_set_perf_lvl = RESTRK_1080P_TURBO_PERF_LEVEL;
}
@@ -650,6 +650,10 @@
VCDRES_MSG_MED("%s(): Setting vidc freq to %u\n",
__func__, vidc_freq);
if (!res_trk_sel_clk_rate(vidc_freq)) {
+ if (vidc_freq == vidc_clk_table[4]) {
+ if (res_trk_sel_clk_rate(vidc_clk_table[3]))
+ goto ret;
+ }
VCDRES_MSG_ERROR("%s(): res_trk_sel_clk_rate FAILED\n",
__func__);
*pn_set_perf_lvl = 0;
@@ -657,7 +661,7 @@
}
}
#endif
- VCDRES_MSG_MED("%s() set perl level : %d", __func__, *pn_set_perf_lvl);
+ret: VCDRES_MSG_MED("%s() set perl level : %d", __func__, *pn_set_perf_lvl);
return true;
}
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.c
index 21f01d1..3b40640 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.c
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.c
@@ -124,7 +124,7 @@
ddl_context->video_ion_client,
alloc_size,
SZ_4K,
- buff_addr->mem_type);
+ buff_addr->mem_type, 0);
if (!buff_addr->alloc_handle) {
ERR("\n%s(): DDL ION alloc failed\n",
__func__);
@@ -142,8 +142,7 @@
buff_addr->physical_base_addr = (u32 *)phyaddr;
kernel_vaddr = (unsigned long *) ion_map_kernel(
ddl_context->video_ion_client,
- buff_addr->alloc_handle,
- UNCACHED);
+ buff_addr->alloc_handle);
if (IS_ERR_OR_NULL(kernel_vaddr)) {
ERR("\n%s(): DDL ION map failed\n", __func__);
goto unmap_ion_buffer;
diff --git a/drivers/video/msm/vidc/common/dec/vdec.c b/drivers/video/msm/vidc/common/dec/vdec.c
index 68bcd5c..59e19b7 100644
--- a/drivers/video/msm/vidc/common/dec/vdec.c
+++ b/drivers/video/msm/vidc/common/dec/vdec.c
@@ -347,7 +347,7 @@
ion_flag = vidc_get_fd_info(client_ctx, BUFFER_TYPE_OUTPUT,
pmem_fd, kernel_vaddr, buffer_index,
&buff_handle);
- if (ion_flag == CACHED && buff_handle) {
+ if (ion_flag == ION_FLAG_CACHED && buff_handle) {
DBG("%s: Cache invalidate: vaddr (%p), "\
"size %u\n", __func__,
(void *)kernel_vaddr,
@@ -908,8 +908,7 @@
}
vcd_h264_mv_buffer->kernel_virtual_addr = (u8 *) ion_map_kernel(
client_ctx->user_ion_client,
- client_ctx->h264_mv_ion_handle,
- ionflag);
+ client_ctx->h264_mv_ion_handle);
if (!vcd_h264_mv_buffer->kernel_virtual_addr) {
ERR("%s(): get_ION_kernel virtual addr failed\n",
__func__);
@@ -935,7 +934,7 @@
VIDEO_DOMAIN, VIDEO_MAIN_POOL,
SZ_4K, 0, (unsigned long *)&iova,
(unsigned long *)&buffer_size,
- UNCACHED, 0);
+ 0, 0);
if (rc || !iova) {
ERR(
"%s():get_ION_kernel physical addr fail, rc = %d iova = 0x%lx\n",
@@ -1298,7 +1297,7 @@
kernel_vaddr,
buffer_index,
&buff_handle);
- if (ion_flag == CACHED && buff_handle) {
+ if (ion_flag == ION_FLAG_CACHED && buff_handle) {
msm_ion_do_cache_op(client_ctx->user_ion_client,
buff_handle,
(unsigned long *)kernel_vaddr,
@@ -1812,7 +1811,7 @@
}
ker_vaddr = (unsigned long) ion_map_kernel(
client_ctx->user_ion_client,
- client_ctx->seq_hdr_ion_handle, ionflag);
+ client_ctx->seq_hdr_ion_handle);
if (!ker_vaddr) {
ERR("%s():get_ION_kernel virtual addr fail\n",
__func__);
diff --git a/drivers/video/msm/vidc/common/enc/venc.c b/drivers/video/msm/vidc/common/enc/venc.c
index 67917b9..c7237e4 100644
--- a/drivers/video/msm/vidc/common/enc/venc.c
+++ b/drivers/video/msm/vidc/common/enc/venc.c
@@ -267,7 +267,7 @@
ion_flag = vidc_get_fd_info(client_ctx, BUFFER_TYPE_OUTPUT,
pmem_fd, kernel_vaddr, buffer_index,
&buff_handle);
- if (ion_flag == CACHED && buff_handle) {
+ if (ion_flag == ION_FLAG_CACHED && buff_handle) {
msm_ion_do_cache_op(client_ctx->user_ion_client,
buff_handle,
(unsigned long *) kernel_vaddr,
diff --git a/drivers/video/msm/vidc/common/enc/venc_internal.c b/drivers/video/msm/vidc/common/enc/venc_internal.c
index 5ee0a3d..8779432 100644
--- a/drivers/video/msm/vidc/common/enc/venc_internal.c
+++ b/drivers/video/msm/vidc/common/enc/venc_internal.c
@@ -1688,7 +1688,7 @@
&buff_handle);
if (vcd_input_buffer.data_len > 0) {
- if (ion_flag == CACHED && buff_handle) {
+ if (ion_flag == ION_FLAG_CACHED && buff_handle) {
msm_ion_do_cache_op(
client_ctx->user_ion_client,
buff_handle,
@@ -1837,8 +1837,7 @@
}
control->kernel_virtual_addr = (u8 *) ion_map_kernel(
client_ctx->user_ion_client,
- client_ctx->recon_buffer_ion_handle[i],
- ionflag);
+ client_ctx->recon_buffer_ion_handle[i]);
if (!control->kernel_virtual_addr) {
ERR("%s(): get_ION_kernel virtual addr fail\n",
__func__);
@@ -1867,7 +1866,7 @@
0,
(unsigned long *)&iova,
(unsigned long *)&buffer_size,
- UNCACHED, 0);
+ 0, 0);
if (rc || !iova) {
ERR(
"%s():ION map iommu addr fail, rc = %d, iova = 0x%lx\n",
diff --git a/drivers/video/msm/vidc/common/init/vidc_init.c b/drivers/video/msm/vidc/common/init/vidc_init.c
index 221c154..65dde68 100644
--- a/drivers/video/msm/vidc/common/init/vidc_init.c
+++ b/drivers/video/msm/vidc/common/init/vidc_init.c
@@ -647,8 +647,7 @@
*kernel_vaddr = (unsigned long)
ion_map_kernel(
client_ctx->user_ion_client,
- buff_ion_handle,
- ionflag);
+ buff_ion_handle);
if (IS_ERR_OR_NULL((void *)*kernel_vaddr)) {
ERR("%s():ION virtual addr fail\n",
__func__);
@@ -678,7 +677,7 @@
length,
(unsigned long *) &iova,
(unsigned long *) &buffer_size,
- UNCACHED,
+ 0,
ION_IOMMU_UNMAP_DELAYED);
if (ret || !iova) {
ERR(
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_sub.c b/drivers/video/msm/vidc/common/vcd/vcd_sub.c
index 71e8df8..6e332ef 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_sub.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_sub.c
@@ -92,7 +92,7 @@
} else {
map_buffer->alloc_handle = ion_alloc(
cctxt->vcd_ion_client, sz, SZ_4K,
- memtype);
+ memtype, 0);
if (!map_buffer->alloc_handle) {
pr_err("%s() ION alloc failed", __func__);
goto bailout;
@@ -105,8 +105,7 @@
}
*kernel_vaddr = (u8 *) ion_map_kernel(
cctxt->vcd_ion_client,
- map_buffer->alloc_handle,
- ionflag);
+ map_buffer->alloc_handle);
if (!(*kernel_vaddr)) {
pr_err("%s() ION map failed", __func__);
goto ion_free_bailout;
@@ -120,7 +119,7 @@
0,
(unsigned long *)&iova,
(unsigned long *)&buffer_size,
- UNCACHED, 0);
+ 0, 0);
if (ret || !iova) {
pr_err(
"%s() ION iommu map failed, ret = %d, iova = 0x%lx",
diff --git a/include/linux/epm_adc.h b/include/linux/epm_adc.h
index b7b7d90..ca1a425 100644
--- a/include/linux/epm_adc.h
+++ b/include/linux/epm_adc.h
@@ -13,6 +13,7 @@
int32_t physical;
};
+#ifdef __KERNEL__
struct epm_psoc_init_resp {
u8 cmd;
u8 version;
@@ -91,7 +92,6 @@
uint32_t vadc_voltage;
};
-#ifdef __KERNEL__
struct epm_chan_properties {
uint32_t resistorvalue;
uint32_t gain;
diff --git a/include/linux/i2c/atmel_mxt_ts.h b/include/linux/i2c/atmel_mxt_ts.h
index 5c3c728..348a231 100644
--- a/include/linux/i2c/atmel_mxt_ts.h
+++ b/include/linux/i2c/atmel_mxt_ts.h
@@ -73,6 +73,7 @@
int irq_gpio;
u32 irq_gpio_flags;
int *key_codes;
+ bool need_calibration;
u8(*read_chg) (void);
int (*init_hw) (bool);
diff --git a/include/linux/ion.h b/include/linux/ion.h
index 6ac2835..85bb182 100644
--- a/include/linux/ion.h
+++ b/include/linux/ion.h
@@ -51,6 +51,14 @@
#define ION_HEAP_CARVEOUT_MASK (1 << ION_HEAP_TYPE_CARVEOUT)
#define ION_HEAP_CP_MASK (1 << ION_HEAP_TYPE_CP)
+/**
+ * heap flags - the lower 16 bits are used by core ion, the upper 16
+ * bits are reserved for use by the heaps themselves.
+ */
+#define ION_FLAG_CACHED 1 /* mappings of this buffer should be
+ cached, ion will do cache
+ maintenance when the buffer is
+ mapped for dma */
/**
* These are the only ids that should be used for Ion heap ids.
@@ -115,14 +123,11 @@
#define ION_QSECOM_HEAP_NAME "qsecom"
#define ION_FMEM_HEAP_NAME "fmem"
-#define CACHED 1
-#define UNCACHED 0
+#define ION_SET_CACHED(__cache) (__cache | ION_FLAG_CACHED)
+#define ION_SET_UNCACHED(__cache) (__cache & ~ION_FLAG_CACHED)
-#define ION_CACHE_SHIFT 0
+#define ION_IS_CACHED(__flags) ((__flags) & ION_FLAG_CACHED)
-#define ION_SET_CACHE(__cache) ((__cache) << ION_CACHE_SHIFT)
-
-#define ION_IS_CACHED(__flags) ((__flags) & (1 << ION_CACHE_SHIFT))
/*
* This flag allows clients when mapping into the IOMMU to specify to
@@ -305,14 +310,18 @@
* @len: size of the allocation
* @align: requested allocation alignment, lots of hardware blocks have
* alignment requirements of some kind
- * @flags: mask of heaps to allocate from, if multiple bits are set
+ * @heap_mask: mask of heaps to allocate from, if multiple bits are set
* heaps will be tried in order from lowest to highest order bit
+ * @flags: heap flags, the low 16 bits are consumed by ion, the high 16
+ * bits are passed on to the respective heap and can be heap
+ * custom
*
* Allocate memory in one of the heaps provided in heap mask and return
* an opaque handle to it.
*/
struct ion_handle *ion_alloc(struct ion_client *client, size_t len,
- size_t align, unsigned int flags);
+ size_t align, unsigned int heap_mask,
+ unsigned int flags);
/**
* ion_free - free a handle
@@ -363,8 +372,7 @@
* can be used to access this address. If no flags are specified, this
* will return a non-secure uncached mapping.
*/
-void *ion_map_kernel(struct ion_client *client, struct ion_handle *handle,
- unsigned long flags);
+void *ion_map_kernel(struct ion_client *client, struct ion_handle *handle);
/**
* ion_unmap_kernel() - destroy a kernel mapping for a handle
@@ -418,7 +426,6 @@
* address space will be mapped to a dummy buffer.
* @iova - pointer to store the iova address
* @buffer_size - pointer to store the size of the buffer
- * @flags - flags for options to map
* @iommu_flags - flags specific to the iommu.
*
* Maps the handle into the iova space specified via domain number. Iova
@@ -574,7 +581,9 @@
static inline void ion_client_destroy(struct ion_client *client) { }
static inline struct ion_handle *ion_alloc(struct ion_client *client,
- size_t len, size_t align, unsigned int flags)
+ size_t len, size_t align,
+ unsigned int heap_mask,
+ unsigned int flags)
{
return ERR_PTR(-ENODEV);
}
@@ -695,6 +704,7 @@
* struct ion_allocation_data - metadata passed from userspace for allocations
* @len: size of the allocation
* @align: required alignment of the allocation
+ * @heap_mask: mask of heaps to allocate from
* @flags: flags passed to heap
* @handle: pointer that will be populated with a cookie to use to refer
* to this allocation
diff --git a/include/linux/mfd/pm8xxx/batterydata-lib.h b/include/linux/mfd/pm8xxx/batterydata-lib.h
new file mode 100644
index 0000000..c55e47e
--- /dev/null
+++ b/include/linux/mfd/pm8xxx/batterydata-lib.h
@@ -0,0 +1,155 @@
+/* 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 __PM8XXX_BMS_BATTERYDATA_H
+#define __PM8XXX_BMS_BATTERYDATA_H
+
+#include <linux/errno.h>
+
+#define FCC_CC_COLS 5
+#define FCC_TEMP_COLS 8
+
+#define PC_CC_ROWS 29
+#define PC_CC_COLS 13
+
+#define PC_TEMP_ROWS 29
+#define PC_TEMP_COLS 8
+
+#define MAX_SINGLE_LUT_COLS 20
+
+struct single_row_lut {
+ int x[MAX_SINGLE_LUT_COLS];
+ int y[MAX_SINGLE_LUT_COLS];
+ int cols;
+};
+
+/**
+ * struct sf_lut -
+ * @rows: number of percent charge entries should be <= PC_CC_ROWS
+ * @cols: number of charge cycle entries should be <= PC_CC_COLS
+ * @row_entries: the charge cycles/temperature at which sf data
+ * is available in the table.
+ * The charge cycles must be in increasing order from 0 to rows.
+ * @percent: the percent charge at which sf data is available in the table
+ * The percentcharge must be in decreasing order from 0 to cols.
+ * @sf: the scaling factor data
+ */
+struct sf_lut {
+ int rows;
+ int cols;
+ int row_entries[PC_CC_COLS];
+ int percent[PC_CC_ROWS];
+ int sf[PC_CC_ROWS][PC_CC_COLS];
+};
+
+/**
+ * struct pc_temp_ocv_lut -
+ * @rows: number of percent charge entries should be <= PC_TEMP_ROWS
+ * @cols: number of temperature entries should be <= PC_TEMP_COLS
+ * @temp: the temperatures at which ocv data is available in the table
+ * The temperatures must be in increasing order from 0 to rows.
+ * @percent: the percent charge at which ocv data is available in the table
+ * The percentcharge must be in decreasing order from 0 to cols.
+ * @ocv: the open circuit voltage
+ */
+struct pc_temp_ocv_lut {
+ int rows;
+ int cols;
+ int temp[PC_TEMP_COLS];
+ int percent[PC_TEMP_ROWS];
+ int ocv[PC_TEMP_ROWS][PC_TEMP_COLS];
+};
+
+enum battery_type {
+ BATT_UNKNOWN = 0,
+ BATT_PALLADIUM,
+ BATT_DESAY,
+};
+
+/**
+ * struct bms_battery_data -
+ * @fcc: full charge capacity (mAmpHour)
+ * @fcc_temp_lut: table to get fcc at a given temp
+ * @pc_temp_ocv_lut: table to get percent charge given batt temp and cycles
+ * @pc_sf_lut: table to get percent charge scaling factor given cycles
+ * and percent charge
+ * @rbatt_sf_lut: table to get battery resistance scaling factor given
+ * temperature and percent charge
+ * @default_rbatt_mohm: the default value of battery resistance to use when
+ * readings from bms are not available.
+ * @delta_rbatt_mohm: the resistance to be added towards lower soc to
+ * compensate for battery capacitance.
+ */
+
+struct bms_battery_data {
+ unsigned int fcc;
+ struct single_row_lut *fcc_temp_lut;
+ struct single_row_lut *fcc_sf_lut;
+ struct pc_temp_ocv_lut *pc_temp_ocv_lut;
+ struct sf_lut *pc_sf_lut;
+ struct sf_lut *rbatt_sf_lut;
+ int default_rbatt_mohm;
+ int delta_rbatt_mohm;
+};
+
+#if defined(CONFIG_PM8921_BMS) || \
+ defined(CONFIG_PM8921_BMS_MODULE)
+extern struct bms_battery_data palladium_1500_data;
+extern struct bms_battery_data desay_5200_data;
+
+int interpolate_fcc(struct single_row_lut *fcc_temp_lut, int batt_temp);
+int interpolate_scalingfactor(struct sf_lut *sf_lut, int row_entry, int pc);
+int interpolate_scalingfactor_fcc(struct single_row_lut *fcc_sf_lut,
+ int cycles);
+int interpolate_pc(struct pc_temp_ocv_lut *pc_temp_ocv,
+ int batt_temp_degc, int ocv);
+int interpolate_ocv(struct pc_temp_ocv_lut *pc_temp_ocv,
+ int batt_temp_degc, int pc);
+int linear_interpolate(int y0, int x0, int y1, int x1, int x);
+int is_between(int left, int right, int value);
+#else
+static inline int interpolate_fcc(struct single_row_lut *fcc_temp_lut,
+ int batt_temp)
+{
+ return -EINVAL;
+}
+static inline int interpolate_scalingfactor(struct sf_lut *sf_lut,
+ int row_entry, int pc)
+{
+ return -EINVAL;
+}
+static inline int interpolate_scalingfactor_fcc(
+ struct single_row_lut *fcc_sf_lut, int cycles)
+{
+ return -EINVAL;
+}
+static inline int interpolate_pc(struct pc_temp_ocv_lut *pc_temp_ocv,
+ int batt_temp_degc, int ocv)
+{
+ return -EINVAL;
+}
+static inline int interpolate_ocv(struct pc_temp_ocv_lut *pc_temp_ocv,
+ int batt_temp_degc, int pc)
+{
+ return -EINVAL;
+}
+static inline int linear_interpolate(int y0, int x0, int y1, int x1, int x)
+{
+ return -EINVAL;
+}
+static inline int is_between(int left, int right, int value)
+{
+ return -EINVAL;
+}
+#endif
+
+#endif
diff --git a/include/linux/mfd/pm8xxx/pm8921-bms.h b/include/linux/mfd/pm8xxx/pm8921-bms.h
index a73a284..5f2fe9f 100644
--- a/include/linux/mfd/pm8xxx/pm8921-bms.h
+++ b/include/linux/mfd/pm8xxx/pm8921-bms.h
@@ -14,87 +14,10 @@
#define __PM8XXX_BMS_H
#include <linux/errno.h>
+#include <linux/mfd/pm8xxx/batterydata-lib.h>
#define PM8921_BMS_DEV_NAME "pm8921-bms"
-#define FCC_CC_COLS 5
-#define FCC_TEMP_COLS 8
-
-#define PC_CC_ROWS 29
-#define PC_CC_COLS 13
-
-#define PC_TEMP_ROWS 29
-#define PC_TEMP_COLS 8
-
-#define MAX_SINGLE_LUT_COLS 20
-
-struct single_row_lut {
- int x[MAX_SINGLE_LUT_COLS];
- int y[MAX_SINGLE_LUT_COLS];
- int cols;
-};
-
-/**
- * struct sf_lut -
- * @rows: number of percent charge entries should be <= PC_CC_ROWS
- * @cols: number of charge cycle entries should be <= PC_CC_COLS
- * @row_entries: the charge cycles/temperature at which sf data
- * is available in the table.
- * The charge cycles must be in increasing order from 0 to rows.
- * @percent: the percent charge at which sf data is available in the table
- * The percentcharge must be in decreasing order from 0 to cols.
- * @sf: the scaling factor data
- */
-struct sf_lut {
- int rows;
- int cols;
- int row_entries[PC_CC_COLS];
- int percent[PC_CC_ROWS];
- int sf[PC_CC_ROWS][PC_CC_COLS];
-};
-
-/**
- * struct pc_temp_ocv_lut -
- * @rows: number of percent charge entries should be <= PC_TEMP_ROWS
- * @cols: number of temperature entries should be <= PC_TEMP_COLS
- * @temp: the temperatures at which ocv data is available in the table
- * The temperatures must be in increasing order from 0 to rows.
- * @percent: the percent charge at which ocv data is available in the table
- * The percentcharge must be in decreasing order from 0 to cols.
- * @ocv: the open circuit voltage
- */
-struct pc_temp_ocv_lut {
- int rows;
- int cols;
- int temp[PC_TEMP_COLS];
- int percent[PC_TEMP_ROWS];
- int ocv[PC_TEMP_ROWS][PC_TEMP_COLS];
-};
-
-/**
- * struct pm8921_bms_battery_data -
- * @fcc: full charge capacity (mAmpHour)
- * @fcc_temp_lut: table to get fcc at a given temp
- * @pc_temp_ocv_lut: table to get percent charge given batt temp and cycles
- * @pc_sf_lut: table to get percent charge scaling factor given cycles
- * and percent charge
- * @rbatt_sf_lut: table to get battery resistance scaling factor given
- * temperature and percent charge
- * @default_rbatt_mohm: the default value of battery resistance to use when
- * readings from bms are not available.
- * @delta_rbatt_mohm: the resistance to be added towards lower soc to
- * compensate for battery capacitance.
- */
-struct pm8921_bms_battery_data {
- unsigned int fcc;
- struct single_row_lut *fcc_temp_lut;
- struct single_row_lut *fcc_sf_lut;
- struct pc_temp_ocv_lut *pc_temp_ocv_lut;
- struct sf_lut *pc_sf_lut;
- struct sf_lut *rbatt_sf_lut;
- int default_rbatt_mohm;
- int delta_rbatt_mohm;
-};
struct pm8xxx_bms_core_data {
unsigned int batt_temp_channel;
@@ -104,12 +27,6 @@
unsigned int batt_id_channel;
};
-enum battery_type {
- BATT_UNKNOWN = 0,
- BATT_PALLADIUM,
- BATT_DESAY,
-};
-
/**
* struct pm8921_bms_platform_data -
* @batt_type: allows to force chose battery calibration data
@@ -137,8 +54,6 @@
};
#if defined(CONFIG_PM8921_BMS) || defined(CONFIG_PM8921_BMS_MODULE)
-extern struct pm8921_bms_battery_data palladium_1500_data;
-extern struct pm8921_bms_battery_data desay_5200_data;
/**
* pm8921_bms_get_vsense_avg - return the voltage across the sense
* resitor in microvolts
diff --git a/include/linux/mfd/wcd9xxx/core.h b/include/linux/mfd/wcd9xxx/core.h
index f6d164d..c306c75 100644
--- a/include/linux/mfd/wcd9xxx/core.h
+++ b/include/linux/mfd/wcd9xxx/core.h
@@ -37,6 +37,12 @@
#define SITAR_IS_1P1(ver) \
((ver == SITAR_VERSION_1P1) ? 1 : 0)
+
+#define TAIKO_VERSION_1_0 0
+#define TAIKO_IS_1_0(ver) \
+ ((ver == TAIKO_VERSION_1_0) ? 1 : 0)
+
+
enum {
TABLA_IRQ_SLIMBUS = 0,
TABLA_IRQ_MBHC_REMOVAL,
diff --git a/include/linux/mfd/wcd9xxx/wcd9320_registers.h b/include/linux/mfd/wcd9xxx/wcd9320_registers.h
index 5725e6e..4b8626a 100644
--- a/include/linux/mfd/wcd9xxx/wcd9320_registers.h
+++ b/include/linux/mfd/wcd9xxx/wcd9320_registers.h
@@ -701,45 +701,45 @@
#define TAIKO_A_CDC_TX10_VOL_CTL_CFG (0x26A)
#define TAIKO_A_CDC_TX10_VOL_CTL_CFG__POR (0x00)
#define TAIKO_A_CDC_TX1_MUX_CTL (0x223)
-#define TAIKO_A_CDC_TX1_MUX_CTL__POR (0x00)
+#define TAIKO_A_CDC_TX1_MUX_CTL__POR (0x08)
#define TAIKO_A_CDC_TX2_MUX_CTL (0x22B)
-#define TAIKO_A_CDC_TX2_MUX_CTL__POR (0x00)
+#define TAIKO_A_CDC_TX2_MUX_CTL__POR (0x08)
#define TAIKO_A_CDC_TX3_MUX_CTL (0x233)
-#define TAIKO_A_CDC_TX3_MUX_CTL__POR (0x00)
+#define TAIKO_A_CDC_TX3_MUX_CTL__POR (0x08)
#define TAIKO_A_CDC_TX4_MUX_CTL (0x23B)
-#define TAIKO_A_CDC_TX4_MUX_CTL__POR (0x00)
+#define TAIKO_A_CDC_TX4_MUX_CTL__POR (0x08)
#define TAIKO_A_CDC_TX5_MUX_CTL (0x243)
-#define TAIKO_A_CDC_TX5_MUX_CTL__POR (0x00)
+#define TAIKO_A_CDC_TX5_MUX_CTL__POR (0x08)
#define TAIKO_A_CDC_TX6_MUX_CTL (0x24B)
-#define TAIKO_A_CDC_TX6_MUX_CTL__POR (0x00)
+#define TAIKO_A_CDC_TX6_MUX_CTL__POR (0x08)
#define TAIKO_A_CDC_TX7_MUX_CTL (0x253)
-#define TAIKO_A_CDC_TX7_MUX_CTL__POR (0x00)
+#define TAIKO_A_CDC_TX7_MUX_CTL__POR (0x08)
#define TAIKO_A_CDC_TX8_MUX_CTL (0x25B)
-#define TAIKO_A_CDC_TX8_MUX_CTL__POR (0x00)
+#define TAIKO_A_CDC_TX8_MUX_CTL__POR (0x08)
#define TAIKO_A_CDC_TX9_MUX_CTL (0x263)
-#define TAIKO_A_CDC_TX9_MUX_CTL__POR (0x00)
+#define TAIKO_A_CDC_TX9_MUX_CTL__POR (0x08)
#define TAIKO_A_CDC_TX10_MUX_CTL (0x26B)
-#define TAIKO_A_CDC_TX10_MUX_CTL__POR (0x00)
+#define TAIKO_A_CDC_TX10_MUX_CTL__POR (0x08)
#define TAIKO_A_CDC_TX1_CLK_FS_CTL (0x224)
-#define TAIKO_A_CDC_TX1_CLK_FS_CTL__POR (0x00)
+#define TAIKO_A_CDC_TX1_CLK_FS_CTL__POR (0x03)
#define TAIKO_A_CDC_TX2_CLK_FS_CTL (0x22C)
-#define TAIKO_A_CDC_TX2_CLK_FS_CTL__POR (0x00)
+#define TAIKO_A_CDC_TX2_CLK_FS_CTL__POR (0x03)
#define TAIKO_A_CDC_TX3_CLK_FS_CTL (0x234)
-#define TAIKO_A_CDC_TX3_CLK_FS_CTL__POR (0x00)
+#define TAIKO_A_CDC_TX3_CLK_FS_CTL__POR (0x03)
#define TAIKO_A_CDC_TX4_CLK_FS_CTL (0x23C)
-#define TAIKO_A_CDC_TX4_CLK_FS_CTL__POR (0x00)
+#define TAIKO_A_CDC_TX4_CLK_FS_CTL__POR (0x03)
#define TAIKO_A_CDC_TX5_CLK_FS_CTL (0x244)
-#define TAIKO_A_CDC_TX5_CLK_FS_CTL__POR (0x00)
+#define TAIKO_A_CDC_TX5_CLK_FS_CTL__POR (0x03)
#define TAIKO_A_CDC_TX6_CLK_FS_CTL (0x24C)
-#define TAIKO_A_CDC_TX6_CLK_FS_CTL__POR (0x00)
+#define TAIKO_A_CDC_TX6_CLK_FS_CTL__POR (0x03)
#define TAIKO_A_CDC_TX7_CLK_FS_CTL (0x254)
-#define TAIKO_A_CDC_TX7_CLK_FS_CTL__POR (0x00)
+#define TAIKO_A_CDC_TX7_CLK_FS_CTL__POR (0x03)
#define TAIKO_A_CDC_TX8_CLK_FS_CTL (0x25C)
-#define TAIKO_A_CDC_TX8_CLK_FS_CTL__POR (0x00)
+#define TAIKO_A_CDC_TX8_CLK_FS_CTL__POR (0x03)
#define TAIKO_A_CDC_TX9_CLK_FS_CTL (0x264)
-#define TAIKO_A_CDC_TX9_CLK_FS_CTL__POR (0x00)
+#define TAIKO_A_CDC_TX9_CLK_FS_CTL__POR (0x03)
#define TAIKO_A_CDC_TX10_CLK_FS_CTL (0x26C)
-#define TAIKO_A_CDC_TX10_CLK_FS_CTL__POR (0x00)
+#define TAIKO_A_CDC_TX10_CLK_FS_CTL__POR (0x03)
#define TAIKO_A_CDC_TX1_DMIC_CTL (0x225)
#define TAIKO_A_CDC_TX1_DMIC_CTL__POR (0x00)
#define TAIKO_A_CDC_TX2_DMIC_CTL (0x22D)
@@ -779,9 +779,9 @@
#define TAIKO_A_CDC_SRC2_PDA_CFG (0x2A8)
#define TAIKO_A_CDC_SRC2_PDA_CFG__POR (0x00)
#define TAIKO_A_CDC_SRC1_FS_CTL (0x2A1)
-#define TAIKO_A_CDC_SRC1_FS_CTL__POR (0x00)
+#define TAIKO_A_CDC_SRC1_FS_CTL__POR (0x1B)
#define TAIKO_A_CDC_SRC2_FS_CTL (0x2A9)
-#define TAIKO_A_CDC_SRC2_FS_CTL__POR (0x00)
+#define TAIKO_A_CDC_SRC2_FS_CTL__POR (0x1B)
#define TAIKO_A_CDC_RX1_B1_CTL (0x2B0)
#define TAIKO_A_CDC_RX1_B1_CTL__POR (0x00)
#define TAIKO_A_CDC_RX2_B1_CTL (0x2B8)
@@ -839,33 +839,33 @@
#define TAIKO_A_CDC_RX7_B4_CTL (0x2E3)
#define TAIKO_A_CDC_RX7_B4_CTL__POR (0x00)
#define TAIKO_A_CDC_RX1_B5_CTL (0x2B4)
-#define TAIKO_A_CDC_RX1_B5_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX1_B5_CTL__POR (0x78)
#define TAIKO_A_CDC_RX2_B5_CTL (0x2BC)
-#define TAIKO_A_CDC_RX2_B5_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX2_B5_CTL__POR (0x78)
#define TAIKO_A_CDC_RX3_B5_CTL (0x2C4)
-#define TAIKO_A_CDC_RX3_B5_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX3_B5_CTL__POR (0x78)
#define TAIKO_A_CDC_RX4_B5_CTL (0x2CC)
-#define TAIKO_A_CDC_RX4_B5_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX4_B5_CTL__POR (0x78)
#define TAIKO_A_CDC_RX5_B5_CTL (0x2D4)
-#define TAIKO_A_CDC_RX5_B5_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX5_B5_CTL__POR (0x78)
#define TAIKO_A_CDC_RX6_B5_CTL (0x2DC)
-#define TAIKO_A_CDC_RX6_B5_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX6_B5_CTL__POR (0x78)
#define TAIKO_A_CDC_RX7_B5_CTL (0x2E4)
-#define TAIKO_A_CDC_RX7_B5_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX7_B5_CTL__POR (0x78)
#define TAIKO_A_CDC_RX1_B6_CTL (0x2B5)
-#define TAIKO_A_CDC_RX1_B6_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX1_B6_CTL__POR (0x80)
#define TAIKO_A_CDC_RX2_B6_CTL (0x2BD)
-#define TAIKO_A_CDC_RX2_B6_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX2_B6_CTL__POR (0x80)
#define TAIKO_A_CDC_RX3_B6_CTL (0x2C5)
-#define TAIKO_A_CDC_RX3_B6_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX3_B6_CTL__POR (0x80)
#define TAIKO_A_CDC_RX4_B6_CTL (0x2CD)
-#define TAIKO_A_CDC_RX4_B6_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX4_B6_CTL__POR (0x80)
#define TAIKO_A_CDC_RX5_B6_CTL (0x2D5)
-#define TAIKO_A_CDC_RX5_B6_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX5_B6_CTL__POR (0x80)
#define TAIKO_A_CDC_RX6_B6_CTL (0x2DD)
-#define TAIKO_A_CDC_RX6_B6_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX6_B6_CTL__POR (0x80)
#define TAIKO_A_CDC_RX7_B6_CTL (0x2E5)
-#define TAIKO_A_CDC_RX7_B6_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX7_B6_CTL__POR (0x80)
#define TAIKO_A_CDC_RX1_VOL_CTL_B1_CTL (0x2B6)
#define TAIKO_A_CDC_RX1_VOL_CTL_B1_CTL__POR (0x00)
#define TAIKO_A_CDC_RX2_VOL_CTL_B1_CTL (0x2BE)
@@ -1041,9 +1041,9 @@
#define TAIKO_A_CDC_IIR2_GAIN_B8_CTL (0x357)
#define TAIKO_A_CDC_IIR2_GAIN_B8_CTL__POR (0x00)
#define TAIKO_A_CDC_IIR1_CTL (0x348)
-#define TAIKO_A_CDC_IIR1_CTL__POR (0x00)
+#define TAIKO_A_CDC_IIR1_CTL__POR (0x40)
#define TAIKO_A_CDC_IIR2_CTL (0x358)
-#define TAIKO_A_CDC_IIR2_CTL__POR (0x00)
+#define TAIKO_A_CDC_IIR2_CTL__POR (0x40)
#define TAIKO_A_CDC_IIR1_GAIN_TIMER_CTL (0x349)
#define TAIKO_A_CDC_IIR1_GAIN_TIMER_CTL__POR (0x00)
#define TAIKO_A_CDC_IIR2_GAIN_TIMER_CTL (0x359)
@@ -1059,35 +1059,35 @@
#define TAIKO_A_CDC_TOP_GAIN_UPDATE (0x360)
#define TAIKO_A_CDC_TOP_GAIN_UPDATE__POR (0x00)
#define TAIKO_A_CDC_COMP0_B1_CTL (0x368)
-#define TAIKO_A_CDC_COMP0_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_COMP0_B1_CTL__POR (0x30)
#define TAIKO_A_CDC_COMP1_B1_CTL (0x370)
-#define TAIKO_A_CDC_COMP1_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_COMP1_B1_CTL__POR (0x30)
#define TAIKO_A_CDC_COMP2_B1_CTL (0x378)
-#define TAIKO_A_CDC_COMP2_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_COMP2_B1_CTL__POR (0x30)
#define TAIKO_A_CDC_COMP0_B2_CTL (0x369)
-#define TAIKO_A_CDC_COMP0_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_COMP0_B2_CTL__POR (0xB5)
#define TAIKO_A_CDC_COMP1_B2_CTL (0x371)
-#define TAIKO_A_CDC_COMP1_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_COMP1_B2_CTL__POR (0xB5)
#define TAIKO_A_CDC_COMP2_B2_CTL (0x379)
-#define TAIKO_A_CDC_COMP2_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_COMP2_B2_CTL__POR (0xB5)
#define TAIKO_A_CDC_COMP0_B3_CTL (0x36A)
-#define TAIKO_A_CDC_COMP0_B3_CTL__POR (0x00)
+#define TAIKO_A_CDC_COMP0_B3_CTL__POR (0x28)
#define TAIKO_A_CDC_COMP1_B3_CTL (0x372)
-#define TAIKO_A_CDC_COMP1_B3_CTL__POR (0x00)
+#define TAIKO_A_CDC_COMP1_B3_CTL__POR (0x28)
#define TAIKO_A_CDC_COMP2_B3_CTL (0x37A)
-#define TAIKO_A_CDC_COMP2_B3_CTL__POR (0x00)
+#define TAIKO_A_CDC_COMP2_B3_CTL__POR (0x28)
#define TAIKO_A_CDC_COMP0_B4_CTL (0x36B)
-#define TAIKO_A_CDC_COMP0_B4_CTL__POR (0x00)
+#define TAIKO_A_CDC_COMP0_B4_CTL__POR (0x3C)
#define TAIKO_A_CDC_COMP1_B4_CTL (0x373)
-#define TAIKO_A_CDC_COMP1_B4_CTL__POR (0x00)
+#define TAIKO_A_CDC_COMP1_B4_CTL__POR (0x3C)
#define TAIKO_A_CDC_COMP2_B4_CTL (0x37B)
-#define TAIKO_A_CDC_COMP2_B4_CTL__POR (0x00)
+#define TAIKO_A_CDC_COMP2_B4_CTL__POR (0x3C)
#define TAIKO_A_CDC_COMP0_B5_CTL (0x36C)
-#define TAIKO_A_CDC_COMP0_B5_CTL__POR (0x00)
+#define TAIKO_A_CDC_COMP0_B5_CTL__POR (0x1F)
#define TAIKO_A_CDC_COMP1_B5_CTL (0x374)
-#define TAIKO_A_CDC_COMP1_B5_CTL__POR (0x00)
+#define TAIKO_A_CDC_COMP1_B5_CTL__POR (0x1F)
#define TAIKO_A_CDC_COMP2_B5_CTL (0x37C)
-#define TAIKO_A_CDC_COMP2_B5_CTL__POR (0x00)
+#define TAIKO_A_CDC_COMP2_B5_CTL__POR (0x1F)
#define TAIKO_A_CDC_COMP0_B6_CTL (0x36D)
#define TAIKO_A_CDC_COMP0_B6_CTL__POR (0x00)
#define TAIKO_A_CDC_COMP1_B6_CTL (0x375)
@@ -1095,17 +1095,17 @@
#define TAIKO_A_CDC_COMP2_B6_CTL (0x37D)
#define TAIKO_A_CDC_COMP2_B6_CTL__POR (0x00)
#define TAIKO_A_CDC_COMP0_SHUT_DOWN_STATUS (0x36E)
-#define TAIKO_A_CDC_COMP0_SHUT_DOWN_STATUS__POR (0x00)
+#define TAIKO_A_CDC_COMP0_SHUT_DOWN_STATUS__POR (0x03)
#define TAIKO_A_CDC_COMP1_SHUT_DOWN_STATUS (0x376)
-#define TAIKO_A_CDC_COMP1_SHUT_DOWN_STATUS__POR (0x00)
+#define TAIKO_A_CDC_COMP1_SHUT_DOWN_STATUS__POR (0x03)
#define TAIKO_A_CDC_COMP2_SHUT_DOWN_STATUS (0x37E)
-#define TAIKO_A_CDC_COMP2_SHUT_DOWN_STATUS__POR (0x00)
+#define TAIKO_A_CDC_COMP2_SHUT_DOWN_STATUS__POR (0x03)
#define TAIKO_A_CDC_COMP0_FS_CFG (0x36F)
-#define TAIKO_A_CDC_COMP0_FS_CFG__POR (0x00)
+#define TAIKO_A_CDC_COMP0_FS_CFG__POR (0x03)
#define TAIKO_A_CDC_COMP1_FS_CFG (0x377)
-#define TAIKO_A_CDC_COMP1_FS_CFG__POR (0x00)
+#define TAIKO_A_CDC_COMP1_FS_CFG__POR (0x03)
#define TAIKO_A_CDC_COMP2_FS_CFG (0x37F)
-#define TAIKO_A_CDC_COMP2_FS_CFG__POR (0x00)
+#define TAIKO_A_CDC_COMP2_FS_CFG__POR (0x03)
#define TAIKO_A_CDC_CONN_RX1_B1_CTL (0x380)
#define TAIKO_A_CDC_CONN_RX1_B1_CTL__POR (0x00)
#define TAIKO_A_CDC_CONN_RX1_B2_CTL (0x381)
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index ea2575c..714cc76 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -246,6 +246,7 @@
#define MMC_CAP2_PACKED_CMD (MMC_CAP2_PACKED_RD | \
MMC_CAP2_PACKED_WR) /* Allow packed commands */
#define MMC_CAP2_SANITIZE (1 << 13) /* Support Sanitize */
+#define MMC_CAP2_INIT_BKOPS (1 << 15) /* Need to set BKOPS_EN */
#define MMC_CAP2_POWER_OFF_VCCQ_DURING_SUSPEND (1 << 16)
mmc_pm_flag_t pm_caps; /* supported pm features */
diff --git a/include/linux/msm_charm.h b/include/linux/msm_charm.h
index 44d2553..1d1f3bb 100644
--- a/include/linux/msm_charm.h
+++ b/include/linux/msm_charm.h
@@ -12,6 +12,7 @@
#define WAIT_FOR_RESTART _IOR(CHARM_CODE, 7, int)
#define GET_DLOAD_STATUS _IOR(CHARM_CODE, 8, int)
#define IMAGE_UPGRADE _IOW(CHARM_CODE, 9, int)
+#define SHUTDOWN_CHARM _IOW(CHARM_CODE, 10, int)
enum charm_boot_type {
CHARM_NORMAL_BOOT = 0,
diff --git a/include/linux/msm_ion.h b/include/linux/msm_ion.h
index 0e28e54..e7959d1 100644
--- a/include/linux/msm_ion.h
+++ b/include/linux/msm_ion.h
@@ -1,5 +1,4 @@
/*
- * include/linux/ion.h
*
* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
*
diff --git a/include/linux/msm_mdp.h b/include/linux/msm_mdp.h
index d03ecfa..861084a 100644
--- a/include/linux/msm_mdp.h
+++ b/include/linux/msm_mdp.h
@@ -276,6 +276,8 @@
#define MDP_PP_OPS_READ 0x2
#define MDP_PP_OPS_WRITE 0x4
#define MDP_PP_OPS_DISABLE 0x8
+#define MDP_PP_IGC_FLAG_ROM0 0x10
+#define MDP_PP_IGC_FLAG_ROM1 0x20
struct mdp_qseed_cfg {
uint32_t table_num;
@@ -405,7 +407,7 @@
struct mdp_histogram_data {
uint32_t block;
- uint8_t bin_cnt;
+ uint32_t bin_cnt;
uint32_t *c0;
uint32_t *c1;
uint32_t *c2;
@@ -422,6 +424,8 @@
struct mdp_pcc_coeff r, g, b;
};
+#define MDP_GAMUT_TABLE_NUM 8
+
enum {
mdp_lut_igc,
mdp_lut_pgc,
@@ -484,6 +488,24 @@
uint32_t cont_adj;
};
+struct mdp_dither_cfg_data {
+ uint32_t block;
+ uint32_t flags;
+ uint32_t g_y_depth;
+ uint32_t r_cr_depth;
+ uint32_t b_cb_depth;
+};
+
+struct mdp_gamut_cfg_data {
+ uint32_t block;
+ uint32_t flags;
+ uint32_t gamut_first;
+ uint32_t tbl_size[MDP_GAMUT_TABLE_NUM];
+ uint16_t *r_tbl[MDP_GAMUT_TABLE_NUM];
+ uint16_t *g_tbl[MDP_GAMUT_TABLE_NUM];
+ uint16_t *b_tbl[MDP_GAMUT_TABLE_NUM];
+};
+
enum {
mdp_op_pcc_cfg,
mdp_op_csc_cfg,
@@ -491,6 +513,8 @@
mdp_op_qseed_cfg,
mdp_bl_scale_cfg,
mdp_op_pa_cfg,
+ mdp_op_dither_cfg,
+ mdp_op_gamut_cfg,
mdp_op_max,
};
@@ -503,6 +527,8 @@
struct mdp_qseed_cfg_data qseed_cfg_data;
struct mdp_bl_scale_data bl_scale_data;
struct mdp_pa_cfg_data pa_cfg_data;
+ struct mdp_dither_cfg_data dither_cfg_data;
+ struct mdp_gamut_cfg_data gamut_cfg_data;
} data;
};
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
index e796bd9..03390b1 100644
--- a/include/linux/power_supply.h
+++ b/include/linux/power_supply.h
@@ -218,15 +218,19 @@
extern int power_supply_set_battery_charged(struct power_supply *psy);
extern int power_supply_set_current_limit(struct power_supply *psy, int limit);
extern int power_supply_set_online(struct power_supply *psy, bool enable);
-extern int power_supply_set_present(struct power_supply *psy, bool enable);
extern int power_supply_set_scope(struct power_supply *psy, int scope);
extern int power_supply_set_charge_type(struct power_supply *psy, int type);
extern int power_supply_set_supply_type(struct power_supply *psy,
enum power_supply_type supply_type);
extern int power_supply_is_system_supplied(void);
+extern int power_supply_register(struct device *parent,
+ struct power_supply *psy);
+extern void power_supply_unregister(struct power_supply *psy);
+extern int power_supply_powers(struct power_supply *psy, struct device *dev);
#else
static inline struct power_supply *power_supply_get_by_name(char *name)
- { return -ENOSYS; }
+ { return NULL; }
+static inline void power_supply_changed(struct power_supply *psy) { }
static inline int power_supply_am_i_supplied(struct power_supply *psy)
{ return -ENOSYS; }
static inline int power_supply_set_battery_charged(struct power_supply *psy)
@@ -237,9 +241,6 @@
static inline int power_supply_set_online(struct power_supply *psy,
bool enable)
{ return -ENOSYS; }
-static inline int power_supply_set_present(struct power_supply *psy,
- bool enable)
- { return -ENOSYS; }
static inline int power_supply_set_scope(struct power_supply *psy,
int scope)
{ return -ENOSYS; }
@@ -247,16 +248,18 @@
int type)
{ return -ENOSYS; }
static inline int power_supply_set_supply_type(struct power_supply *psy,
- enum power_supply_type supply_type);
+ enum power_supply_type supply_type)
{ return -ENOSYS; }
static inline int power_supply_is_system_supplied(void) { return -ENOSYS; }
+static inline int power_supply_register(struct device *parent,
+ struct power_supply *psy)
+ { return -ENOSYS; }
+static inline void power_supply_unregister(struct power_supply *psy) { }
+static inline int power_supply_powers(struct power_supply *psy,
+ struct device *dev)
+ { return -ENOSYS; }
#endif
-extern int power_supply_register(struct device *parent,
- struct power_supply *psy);
-extern void power_supply_unregister(struct power_supply *psy);
-extern int power_supply_powers(struct power_supply *psy, struct device *dev);
-
/* For APM emulation, think legacy userspace. */
extern struct class *power_supply_class;
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 68a87bf..44c64e8 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -368,6 +368,15 @@
struct mon_bus *mon_bus; /* non-null when associated */
int monitored; /* non-zero when monitored */
#endif
+ unsigned skip_resume:1; /* All USB devices are brought into full
+ * power state after system resume. It
+ * is desirable for some buses to keep
+ * their devices in suspend state even
+ * after system resume. The devices
+ * are resumed later when a remote
+ * wakeup is detected or an interface
+ * driver starts I/O.
+ */
};
/* ----------------------------------------------------------------------- */
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index 89b1459..920cf77 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -25,7 +25,7 @@
#include <linux/wakelock.h>
#include <linux/pm_qos.h>
#include <linux/hrtimer.h>
-#include <linux/power_supply.h>
+
/*
* The following are bit fields describing the usb_request.udc_priv word.
* These bit fields are set by function drivers that wish to queue
@@ -294,6 +294,8 @@
* @xo_handle: TCXO buffer handle
* @bus_perf_client: Bus performance client handle to request BUS bandwidth
* @mhl_enabled: MHL driver registration successful and MHL enabled.
+ * @chg_check_timer: The timer used to implement the workaround to detect
+ * very slow plug in of wall charger.
*/
struct msm_otg {
struct usb_phy phy;
@@ -323,6 +325,7 @@
#define A_CONN 15
#define B_BUS_REQ 16
#define MHL 17
+#define B_FALSE_SDP 18
unsigned long inputs;
struct work_struct sm_work;
bool sm_work_pending;
@@ -345,6 +348,7 @@
struct msm_xo_voter *xo_handle;
uint32_t bus_perf_client;
bool mhl_enabled;
+ struct timer_list chg_check_timer;
/*
* Allowing PHY power collpase turns off the HSUSB 3.3v and 1.8v
* analog regulators while going to low power mode.
@@ -380,10 +384,6 @@
u8 active_tmout;
struct hrtimer timer;
enum usb_vdd_type vdd_type;
- struct power_supply usb_psy;
- unsigned int online;
- unsigned int host_mode;
- unsigned int current_max;
};
struct msm_hsic_host_platform_data {
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index b265eb9..07beb50 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -1798,6 +1798,12 @@
V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_7_0 = 7,
};
+#define V4L2_CID_MPEG_VIDC_VIDEO_H264_AU_DELIMITER \
+ (V4L2_CID_MPEG_MSM_VIDC_BASE + 22)
+enum v4l2_mpeg_vidc_video_h264_au_delimiter {
+ V4L2_MPEG_VIDC_VIDEO_H264_AU_DELIMITER_DISABLED = 0,
+ V4L2_MPEG_VIDC_VIDEO_H264_AU_DELIMITER_ENABLED = 1
+};
/* Camera class control IDs */
#define V4L2_CID_CAMERA_CLASS_BASE (V4L2_CTRL_CLASS_CAMERA | 0x900)
#define V4L2_CID_CAMERA_CLASS (V4L2_CTRL_CLASS_CAMERA | 1)
diff --git a/include/linux/wcnss_wlan.h b/include/linux/wcnss_wlan.h
index d32bc57..7a194ca 100644
--- a/include/linux/wcnss_wlan.h
+++ b/include/linux/wcnss_wlan.h
@@ -58,6 +58,7 @@
int wcnss_hardware_type(void);
void *wcnss_prealloc_get(unsigned int size);
int wcnss_prealloc_put(void *ptr);
+void wcnss_reset_intr(void);
#define wcnss_wlan_get_drvdata(dev) dev_get_drvdata(dev)
#define wcnss_wlan_set_drvdata(dev, data) dev_set_drvdata((dev), (data))
diff --git a/include/media/msm/vcd_property.h b/include/media/msm/vcd_property.h
index 484d08f..180b38d 100644
--- a/include/media/msm/vcd_property.h
+++ b/include/media/msm/vcd_property.h
@@ -55,6 +55,7 @@
#define VCD_I_SLICE_DELIVERY_MODE (VCD_START_BASE + 0x27)
#define VCD_I_VOP_TIMING_CONSTANT_DELTA (VCD_START_BASE + 0x28)
#define VCD_I_SET_TURBO_CLK (VCD_START_BASE + 0x29)
+#define VCD_I_ENABLE_DELIMITER_FLAG (VCD_START_BASE + 0x2A)
#define VCD_START_REQ (VCD_START_BASE + 0x1000)
#define VCD_I_REQ_IFRAME (VCD_START_REQ + 0x1)
@@ -373,4 +374,8 @@
u32 sps_pps_for_idr_enable_flag;
};
+struct vcd_property_avc_delimiter_enable {
+ u32 avc_delimiter_enable_flag;
+};
+
#endif
diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h
index ed9af2c..6658b8c 100644
--- a/include/media/msm_camera.h
+++ b/include/media/msm_camera.h
@@ -34,6 +34,8 @@
#define MSM_CAM_IOCTL_MAGIC 'm'
+#define MAX_SERVER_PAYLOAD_LENGTH 8192
+
#define MSM_CAM_IOCTL_GET_SENSOR_INFO \
_IOR(MSM_CAM_IOCTL_MAGIC, 1, struct msm_camsensor_info *)
@@ -862,7 +864,10 @@
(MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+16)
#define MSM_V4L2_EXT_CAPTURE_MODE_CSTA \
(MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+17)
-#define MSM_V4L2_EXT_CAPTURE_MODE_MAX (MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+18)
+#define MSM_V4L2_EXT_CAPTURE_MODE_V2X_LIVESHOT \
+ (MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+18)
+#define MSM_V4L2_EXT_CAPTURE_MODE_MAX (MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+19)
+
#define MSM_V4L2_PID_MOTION_ISO V4L2_CID_PRIVATE_BASE
#define MSM_V4L2_PID_EFFECT (V4L2_CID_PRIVATE_BASE+1)
diff --git a/include/media/tavarua.h b/include/media/tavarua.h
index d7b1340..1cccb2b 100644
--- a/include/media/tavarua.h
+++ b/include/media/tavarua.h
@@ -104,6 +104,7 @@
#define MARIMBA_2_1 0x02010204
#define BAHAMA_1_0 0x0302010A
#define BAHAMA_2_0 0x04020205
+#define BAHAMA_2_1 0x04020309
#define WAIT_TIMEOUT 2000
#define RADIO_INIT_TIME 15
#define TAVARUA_DELAY 10
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index 2918b94..a15d1f1 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -289,7 +289,6 @@
atomic_t queued_count;
struct list_head done_list;
spinlock_t done_lock;
- struct mutex q_lock;
wait_queue_head_t done_wq;
void *alloc_ctx[VIDEO_MAX_PLANES];
diff --git a/include/sound/apr_audio-v2.h b/include/sound/apr_audio-v2.h
index 1da6aa2..d902881 100644
--- a/include/sound/apr_audio-v2.h
+++ b/include/sound/apr_audio-v2.h
@@ -1890,6 +1890,7 @@
struct afe_param_id_hdmi_multi_chan_audio_cfg hdmi_multi_ch;
struct afe_param_id_slimbus_cfg slim_sch;
struct afe_param_id_rt_proxy_port_cfg rtproxy;
+ struct afe_param_id_internal_bt_fm_cfg int_bt_fm;
} __packed;
struct afe_audioif_config_command {
diff --git a/include/sound/compress_params.h b/include/sound/compress_params.h
index 31d684b..54af7d6a 100644
--- a/include/sound/compress_params.h
+++ b/include/sound/compress_params.h
@@ -86,6 +86,7 @@
#define SND_AUDIOCODEC_DTS_PASS_THROUGH ((__u32) 0x00000012)
#define SND_AUDIOCODEC_DTS_LBR ((__u32) 0x00000013)
#define SND_AUDIOCODEC_DTS_TRANSCODE_LOOPBACK ((__u32) 0x00000014)
+#define SND_AUDIOCODEC_PASS_THROUGH ((__u32) 0x00000015)
/*
* Profile and modes are listed with bit masks. This allows for a
@@ -331,6 +332,10 @@
__u32 bw; /* encoder bandwidth */
__s32 reserved[15];
};
+struct snd_dec_dts {
+ __u32 modelIdLength;
+ __u8 *modelId;
+};
union snd_codec_options {
struct snd_enc_wma wma;
@@ -338,6 +343,7 @@
struct snd_enc_real real;
struct snd_enc_flac flac;
struct snd_enc_generic generic;
+ struct snd_dec_dts dts;
};
/** struct snd_codec_desc - description of codec capabilities
diff --git a/include/sound/q6afe-v2.h b/include/sound/q6afe-v2.h
index 8ccc9f4..e107130 100644
--- a/include/sound/q6afe-v2.h
+++ b/include/sound/q6afe-v2.h
@@ -13,6 +13,8 @@
#define __Q6AFE_V2_H__
#include <sound/apr_audio-v2.h>
+#define IN 0x000
+#define OUT 0x001
#define MSM_AFE_MONO 0
#define MSM_AFE_MONO_RIGHT 1
#define MSM_AFE_MONO_LEFT 2
@@ -71,6 +73,40 @@
AFE_MAX_PORTS
};
+struct afe_audio_buffer {
+ dma_addr_t phys;
+ void *data;
+ uint32_t used;
+ uint32_t size;/* size of buffer */
+ uint32_t actual_size; /* actual number of bytes read by DSP */
+ struct ion_handle *handle;
+ struct ion_client *client;
+};
+
+struct afe_audio_port_data {
+ struct afe_audio_buffer *buf;
+ uint32_t max_buf_cnt;
+ uint32_t dsp_buf;
+ uint32_t cpu_buf;
+ struct list_head mem_map_handle;
+ uint32_t tmp_hdl;
+ /* read or write locks */
+ struct mutex lock;
+ spinlock_t dsp_lock;
+};
+
+struct afe_audio_client {
+ atomic_t cmd_state;
+ /* Relative or absolute TS */
+ uint32_t time_flag;
+ void *priv;
+ uint64_t time_stamp;
+ struct mutex cmd_lock;
+ /* idx:1 out port, 0: in port*/
+ struct afe_audio_port_data port[2];
+ wait_queue_head_t cmd_wait;
+};
+
int afe_open(u16 port_id, union afe_port_config *afe_config, int rate);
int afe_close(int port_id);
int afe_loopback(u16 enable, u16 rx_port, u16 tx_port);
@@ -80,6 +116,7 @@
int afe_get_port_index(u16 port_id);
int afe_start_pseudo_port(u16 port_id);
int afe_stop_pseudo_port(u16 port_id);
+uint32_t afe_req_mmap_handle(void);
int afe_cmd_memory_map(u32 dma_addr_p, u32 dma_buf_sz);
int afe_cmd_memory_map_nowait(int port_id, u32 dma_addr_p, u32 dma_buf_sz);
int afe_cmd_memory_unmap(u32 dma_addr_p);
@@ -98,6 +135,14 @@
int afe_apply_gain(u16 port_id, u16 gain);
int afe_q6_interface_prepare(void);
int afe_get_port_type(u16 port_id);
+int q6afe_audio_client_buf_alloc_contiguous(unsigned int dir,
+ struct afe_audio_client *ac,
+ unsigned int bufsz,
+ unsigned int bufcnt);
+struct afe_audio_client *q6afe_audio_client_alloc(void *priv);
+int q6afe_audio_client_buf_free_contiguous(unsigned int dir,
+ struct afe_audio_client *ac);
+void q6afe_audio_client_free(struct afe_audio_client *ac);
/* if port_id is virtual, convert to physical..
* if port_id is already physical, return physical
*/
diff --git a/include/sound/q6asm.h b/include/sound/q6asm.h
index 4021d48..32d3aef 100644
--- a/include/sound/q6asm.h
+++ b/include/sound/q6asm.h
@@ -49,6 +49,7 @@
#define FORMAT_MAT 0x0017
#define FORMAT_AAC 0x0018
#define FORMAT_DTS_LBR 0x0019
+#define FORMAT_PASS_THROUGH 0x0020
#define ENCDEC_SBCBITRATE 0x0001
#define ENCDEC_IMMEDIATE_DECODE 0x0002
diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
index a1d2849..5ba1770 100644
--- a/kernel/trace/Kconfig
+++ b/kernel/trace/Kconfig
@@ -418,6 +418,19 @@
If in doubt, say N.
+config CPU_FREQ_SWITCH_PROFILER
+ bool "CPU frequency switch time profiler"
+ select GENERIC_TRACER
+ help
+ This option enables the CPU frequency switch profiler. A file is
+ created in debugfs called "cpu_freq_switch_profile_enabled", which
+ defaults to zero. When a 1 is echoed into this file, profiling begins.
+ When a zero is echoed, profiling stops. A "cpu_freq_switch" file is
+ also created in the trace_stats directory; this file shows the
+ switches that have occurred and duration statistics.
+
+ If in doubt, say N.
+
config FTRACE_MCOUNT_RECORD
def_bool y
depends on DYNAMIC_FTRACE
diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile
index 5f39a07..3c13931 100644
--- a/kernel/trace/Makefile
+++ b/kernel/trace/Makefile
@@ -36,6 +36,7 @@
obj-$(CONFIG_IRQSOFF_TRACER) += trace_irqsoff.o
obj-$(CONFIG_PREEMPT_TRACER) += trace_irqsoff.o
obj-$(CONFIG_SCHED_TRACER) += trace_sched_wakeup.o
+obj-$(CONFIG_CPU_FREQ_SWITCH_PROFILER) += trace_cpu_freq_switch.o
obj-$(CONFIG_NOP_TRACER) += trace_nop.o
obj-$(CONFIG_STACK_TRACER) += trace_stack.o
obj-$(CONFIG_MMIOTRACE) += trace_mmiotrace.o
diff --git a/kernel/trace/trace_cpu_freq_switch.c b/kernel/trace/trace_cpu_freq_switch.c
new file mode 100644
index 0000000..7e7b104
--- /dev/null
+++ b/kernel/trace/trace_cpu_freq_switch.c
@@ -0,0 +1,311 @@
+/*
+ * 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/module.h>
+#include <linux/percpu.h>
+#include <linux/slab.h>
+#include <linux/rbtree.h>
+#include <linux/hrtimer.h>
+#include <linux/debugfs.h>
+#include <linux/ktime.h>
+#include <trace/events/power.h>
+#include "trace_stat.h"
+#include "trace.h"
+
+struct trans {
+ struct rb_node node;
+ unsigned int cpu;
+ unsigned int start_freq;
+ unsigned int end_freq;
+ unsigned int min_us;
+ unsigned int max_us;
+ ktime_t total_t;
+ unsigned int count;
+};
+static struct rb_root freq_trans_tree = RB_ROOT;
+
+static struct trans *tr_search(struct rb_root *root, unsigned int cpu,
+ unsigned int start_freq, unsigned int end_freq)
+{
+ struct rb_node *node = root->rb_node;
+
+ while (node) {
+ struct trans *tr = container_of(node, struct trans, node);
+
+ if (cpu < tr->cpu)
+ node = node->rb_left;
+ else if (cpu > tr->cpu)
+ node = node->rb_right;
+ else if (start_freq < tr->start_freq)
+ node = node->rb_left;
+ else if (start_freq > tr->start_freq)
+ node = node->rb_right;
+ else if (end_freq < tr->end_freq)
+ node = node->rb_left;
+ else if (end_freq > tr->end_freq)
+ node = node->rb_right;
+ else
+ return tr;
+ }
+ return NULL;
+}
+
+static int tr_insert(struct rb_root *root, struct trans *tr)
+{
+ struct rb_node **new = &(root->rb_node), *parent = NULL;
+
+ while (*new) {
+ struct trans *this = container_of(*new, struct trans, node);
+
+ parent = *new;
+ if (tr->cpu < this->cpu)
+ new = &((*new)->rb_left);
+ else if (tr->cpu > this->cpu)
+ new = &((*new)->rb_right);
+ else if (tr->start_freq < this->start_freq)
+ new = &((*new)->rb_left);
+ else if (tr->start_freq > this->start_freq)
+ new = &((*new)->rb_right);
+ else if (tr->end_freq < this->end_freq)
+ new = &((*new)->rb_left);
+ else if (tr->end_freq > this->end_freq)
+ new = &((*new)->rb_right);
+ else
+ return -EINVAL;
+ }
+
+ rb_link_node(&tr->node, parent, new);
+ rb_insert_color(&tr->node, root);
+
+ return 0;
+}
+
+struct trans_state {
+ spinlock_t lock;
+ unsigned int start_freq;
+ unsigned int end_freq;
+ ktime_t start_t;
+ bool started;
+};
+static DEFINE_PER_CPU(struct trans_state, freq_trans_state);
+
+static DEFINE_SPINLOCK(state_lock);
+
+static void probe_start(void *ignore, unsigned int start_freq,
+ unsigned int end_freq, unsigned int cpu)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&state_lock, flags);
+ per_cpu(freq_trans_state, cpu).start_freq = start_freq;
+ per_cpu(freq_trans_state, cpu).end_freq = end_freq;
+ per_cpu(freq_trans_state, cpu).start_t = ktime_get();
+ per_cpu(freq_trans_state, cpu).started = true;
+ spin_unlock_irqrestore(&state_lock, flags);
+}
+
+static void probe_end(void *ignore, unsigned int cpu)
+{
+ unsigned long flags;
+ struct trans *tr;
+ s64 dur_us;
+ ktime_t dur_t, end_t = ktime_get();
+
+ spin_lock_irqsave(&state_lock, flags);
+
+ if (!per_cpu(freq_trans_state, cpu).started)
+ goto out;
+
+ dur_t = ktime_sub(end_t, per_cpu(freq_trans_state, cpu).start_t);
+ dur_us = ktime_to_us(dur_t);
+
+ tr = tr_search(&freq_trans_tree, cpu,
+ per_cpu(freq_trans_state, cpu).start_freq,
+ per_cpu(freq_trans_state, cpu).end_freq);
+ if (!tr) {
+ tr = kzalloc(sizeof(*tr), GFP_ATOMIC);
+ if (!tr) {
+ WARN_ONCE(1, "CPU frequency trace is now invalid!\n");
+ goto out;
+ }
+
+ tr->start_freq = per_cpu(freq_trans_state, cpu).start_freq;
+ tr->end_freq = per_cpu(freq_trans_state, cpu).end_freq;
+ tr->cpu = cpu;
+ tr->min_us = UINT_MAX;
+ tr_insert(&freq_trans_tree, tr);
+ }
+ tr->total_t = ktime_add(tr->total_t, dur_t);
+ tr->count++;
+
+ if (dur_us > tr->max_us)
+ tr->max_us = dur_us;
+ if (dur_us < tr->min_us)
+ tr->min_us = dur_us;
+
+ per_cpu(freq_trans_state, cpu).started = false;
+out:
+ spin_unlock_irqrestore(&state_lock, flags);
+}
+
+static void *freq_switch_stat_start(struct tracer_stat *trace)
+{
+ struct rb_node *n;
+ unsigned long flags;
+
+ spin_lock_irqsave(&state_lock, flags);
+ n = rb_first(&freq_trans_tree);
+ spin_unlock_irqrestore(&state_lock, flags);
+
+ return n;
+}
+
+static void *freq_switch_stat_next(void *prev, int idx)
+{
+ struct rb_node *n;
+ unsigned long flags;
+
+ spin_lock_irqsave(&state_lock, flags);
+ n = rb_next(prev);
+ spin_unlock_irqrestore(&state_lock, flags);
+
+ return n;
+}
+
+static int freq_switch_stat_show(struct seq_file *s, void *p)
+{
+ unsigned long flags;
+ struct trans *tr = p;
+
+ spin_lock_irqsave(&state_lock, flags);
+ seq_printf(s, "%3d %9d %8d %5d %6lld %6d %6d\n", tr->cpu,
+ tr->start_freq, tr->end_freq, tr->count,
+ div_s64(ktime_to_us(tr->total_t), tr->count),
+ tr->min_us, tr->max_us);
+ spin_unlock_irqrestore(&state_lock, flags);
+
+ return 0;
+}
+
+static void freq_switch_stat_release(void *stat)
+{
+ struct trans *tr = stat;
+ unsigned long flags;
+
+ spin_lock_irqsave(&state_lock, flags);
+ rb_erase(&tr->node, &freq_trans_tree);
+ spin_unlock_irqrestore(&state_lock, flags);
+ kfree(tr);
+}
+
+static int freq_switch_stat_headers(struct seq_file *s)
+{
+ seq_printf(s, "CPU START_KHZ END_KHZ COUNT AVG_US MIN_US MAX_US\n");
+ seq_printf(s, " | | | | | | |\n");
+ return 0;
+}
+
+struct tracer_stat freq_switch_stats __read_mostly = {
+ .name = "cpu_freq_switch",
+ .stat_start = freq_switch_stat_start,
+ .stat_next = freq_switch_stat_next,
+ .stat_show = freq_switch_stat_show,
+ .stat_release = freq_switch_stat_release,
+ .stat_headers = freq_switch_stat_headers
+};
+
+static void trace_freq_switch_disable(void)
+{
+ unregister_stat_tracer(&freq_switch_stats);
+ unregister_trace_cpu_frequency_switch_end(probe_end, NULL);
+ unregister_trace_cpu_frequency_switch_start(probe_start, NULL);
+ pr_info("disabled cpu frequency switch time profiling\n");
+}
+
+static int trace_freq_switch_enable(void)
+{
+ int ret;
+
+ ret = register_trace_cpu_frequency_switch_start(probe_start, NULL);
+ if (ret)
+ goto out;
+
+ ret = register_trace_cpu_frequency_switch_end(probe_end, NULL);
+ if (ret)
+ goto err_register_switch_end;
+
+ ret = register_stat_tracer(&freq_switch_stats);
+ if (ret)
+ goto err_register_stat_tracer;
+
+ pr_info("enabled cpu frequency switch time profiling\n");
+ return 0;
+
+err_register_stat_tracer:
+ unregister_trace_cpu_frequency_switch_end(probe_end, NULL);
+err_register_switch_end:
+ register_trace_cpu_frequency_switch_start(probe_start, NULL);
+out:
+ pr_err("failed to enable cpu frequency switch time profiling\n");
+
+ return ret;
+}
+
+static DEFINE_MUTEX(debugfs_lock);
+static bool trace_freq_switch_enabled;
+
+static int debug_toggle_tracing(void *data, u64 val)
+{
+ int ret = 0;
+
+ mutex_lock(&debugfs_lock);
+
+ if (val == 1 && !trace_freq_switch_enabled)
+ ret = trace_freq_switch_enable();
+ else if (val == 0 && trace_freq_switch_enabled)
+ trace_freq_switch_disable();
+ else if (val > 1)
+ ret = -EINVAL;
+
+ if (!ret)
+ trace_freq_switch_enabled = val;
+
+ mutex_unlock(&debugfs_lock);
+
+ return ret;
+}
+
+static int debug_tracing_state_get(void *data, u64 *val)
+{
+ mutex_lock(&debugfs_lock);
+ *val = trace_freq_switch_enabled;
+ mutex_unlock(&debugfs_lock);
+
+ return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(debug_tracing_state_fops, debug_tracing_state_get,
+ debug_toggle_tracing, "%llu\n");
+
+static int __init trace_freq_switch_init(void)
+{
+ struct dentry *d_tracer = tracing_init_dentry();
+ if (!d_tracer)
+ return 0;
+
+ debugfs_create_file("cpu_freq_switch_profile_enabled",
+ S_IRUGO | S_IWUSR, d_tracer, NULL, &debug_tracing_state_fops);
+
+ return 0;
+}
+late_initcall(trace_freq_switch_init);
diff --git a/sound/soc/codecs/wcd9310.c b/sound/soc/codecs/wcd9310.c
index a47e446..deddbe8 100644
--- a/sound/soc/codecs/wcd9310.c
+++ b/sound/soc/codecs/wcd9310.c
@@ -6526,7 +6526,7 @@
s16 mb_v[num_det];
s32 mic_mv[num_det];
bool inval;
- bool highdelta;
+ bool highdelta = false;
bool ahighv = false, highv;
bool gndmicswapped = false;
@@ -6587,26 +6587,29 @@
if (vddioswitch)
__tabla_codec_switch_micbias(tabla->codec, 0,
false, false);
- /* claim UNSUPPORTED plug insertion when
- * good headset is detected but HPHR GND switch makes
- * delta difference */
- if (i == (num_det - 2) && highdelta && !ahighv)
- gndmicswapped = true;
- else if (i == (num_det - 1) && inval) {
- if (gndmicswapped)
- plug_type[0] = PLUG_TYPE_GND_MIC_SWAP;
- else
- plug_type[0] = PLUG_TYPE_INVALID;
- }
}
pr_debug("%s: DCE #%d, %04x, V %d, scaled V %d, GND %d, "
"VDDIO %d, inval %d\n", __func__,
i + 1, mb_v[i] & 0xffff, mic_mv[i], scaled, gndswitch,
vddioswitch, inval);
/* don't need to run further DCEs */
- if (ahighv && inval)
+ if ((ahighv || !vddioswitch) && inval)
break;
mic_mv[i] = scaled;
+
+ /*
+ * claim UNSUPPORTED plug insertion when
+ * good headset is detected but HPHR GND switch makes
+ * delta difference
+ */
+ if (i == (num_det - 2) && highdelta && !ahighv)
+ gndmicswapped = true;
+ else if (i == (num_det - 1) && inval) {
+ if (gndmicswapped)
+ plug_type[0] = PLUG_TYPE_GND_MIC_SWAP;
+ else
+ plug_type[0] = PLUG_TYPE_INVALID;
+ }
}
for (i = 0; (plug_type[0] != PLUG_TYPE_GND_MIC_SWAP && !inval) &&
diff --git a/sound/soc/codecs/wcd9320-tables.c b/sound/soc/codecs/wcd9320-tables.c
index 68a4670..c49c276 100644
--- a/sound/soc/codecs/wcd9320-tables.c
+++ b/sound/soc/codecs/wcd9320-tables.c
@@ -673,7 +673,7 @@
[TAIKO_A_CDC_MAD_BEACON_IIR_CTL_VAL] = 1,
};
-const u8 taiko_reg_defaults[TAIKO_CACHE_SIZE] = {
+const u8 taiko_reset_reg_defaults[TAIKO_CACHE_SIZE] = {
[TAIKO_A_CHIP_CTL] = TAIKO_A_CHIP_CTL__POR,
[TAIKO_A_CHIP_STATUS] = TAIKO_A_CHIP_STATUS__POR,
[TAIKO_A_CHIP_ID_BYTE_0] = TAIKO_A_CHIP_ID_BYTE_0__POR,
diff --git a/sound/soc/codecs/wcd9320.c b/sound/soc/codecs/wcd9320.c
index 136024c..e8bb652 100644
--- a/sound/soc/codecs/wcd9320.c
+++ b/sound/soc/codecs/wcd9320.c
@@ -685,7 +685,7 @@
u32 compander, u32 enable, int event)
{
int value = 0;
- int mask = 1 << 4;
+ int mask = 1 << 5;
int gain = 0;
int gain_offset;
if (compander >= COMPANDER_MAX) {
@@ -828,19 +828,23 @@
break;
case SND_SOC_DAPM_PRE_PMD:
/* Halt the compander*/
- snd_soc_update_bits(codec, TAIKO_A_CDC_COMP1_B1_CTL +
- w->shift * 8, 1 << 2, 1 << 2);
+ if (taiko->comp_enabled[w->shift] != 0) {
+ snd_soc_update_bits(codec, TAIKO_A_CDC_COMP1_B1_CTL +
+ w->shift * 8, 1 << 2, 1 << 2);
+ }
break;
case SND_SOC_DAPM_POST_PMD:
/* Restore the gain */
- taiko_config_gain_compander(codec, w->shift,
- taiko->comp_enabled[w->shift], event);
- /* Disable the compander*/
- snd_soc_update_bits(codec, TAIKO_A_CDC_COMP1_B1_CTL +
- w->shift * 8, 0x03, 0x00);
- /* Turn off the clock for compander in pair*/
- snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RX_B2_CTL,
- 0x03 << comp_shift[w->shift], 0);
+ if (taiko->comp_enabled[w->shift] != 0) {
+ taiko_config_gain_compander(codec, w->shift,
+ taiko->comp_enabled[w->shift], event);
+ /* Disable the compander*/
+ snd_soc_update_bits(codec, TAIKO_A_CDC_COMP1_B1_CTL +
+ w->shift * 8, 0x03, 0x00);
+ /* Turn off the clock for compander in pair*/
+ snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RX_B2_CTL,
+ 0x03 << comp_shift[w->shift], 0);
+ }
break;
}
return 0;
@@ -1716,7 +1720,7 @@
usleep_range(100, 100);
taiko_codec_enable_audio_mode_bandgap(codec);
} else if (choice == TAIKO_BANDGAP_OFF) {
- snd_soc_write(codec, TAIKO_A_BIAS_CENTRAL_BG_CTL, 0x00);
+ snd_soc_write(codec, TAIKO_A_BIAS_CENTRAL_BG_CTL, 0x50);
} else {
pr_err("%s: Error, Invalid bandgap settings\n", __func__);
}
@@ -1730,7 +1734,7 @@
snd_soc_update_bits(codec, TAIKO_A_CLK_BUFF_EN2, 0x04, 0x00);
usleep_range(50, 50);
snd_soc_update_bits(codec, TAIKO_A_CLK_BUFF_EN2, 0x02, 0x02);
- snd_soc_update_bits(codec, TAIKO_A_CLK_BUFF_EN1, 0x05, 0x00);
+ snd_soc_update_bits(codec, TAIKO_A_CLK_BUFF_EN1, 0x01, 0x00);
usleep_range(50, 50);
taiko->clock_active = false;
}
@@ -1815,10 +1819,9 @@
/* switch to MCLK */
snd_soc_update_bits(codec, TAIKO_A_CLK_BUFF_EN1, 0x08, 0x00);
- if (taiko->mbhc_polling_active) {
+ if (taiko->mbhc_polling_active)
snd_soc_write(codec, TAIKO_A_CLK_BUFF_EN2, 0x02);
- taiko_codec_enable_config_mode(codec, 0);
- }
+ taiko_codec_enable_config_mode(codec, 0);
}
snd_soc_update_bits(codec, TAIKO_A_CLK_BUFF_EN1, 0x01, 0x01);
@@ -2658,7 +2661,7 @@
return ret;
}
-static int taiko_codec_reset_interpolator(struct snd_soc_dapm_widget *w,
+static int taiko_codec_enable_interpolator(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_codec *codec = w->codec;
@@ -4295,25 +4298,25 @@
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_MIXER_E("RX1 MIX2", TAIKO_A_CDC_CLK_RX_B1_CTL, 0, 0, NULL,
- 0, taiko_codec_reset_interpolator, SND_SOC_DAPM_PRE_PMU |
+ 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
SND_SOC_DAPM_POST_PMU),
SND_SOC_DAPM_MIXER_E("RX2 MIX2", TAIKO_A_CDC_CLK_RX_B1_CTL, 1, 0, NULL,
- 0, taiko_codec_reset_interpolator, SND_SOC_DAPM_PRE_PMU |
+ 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
SND_SOC_DAPM_POST_PMU),
SND_SOC_DAPM_MIXER_E("RX7 MIX2", TAIKO_A_CDC_CLK_RX_B1_CTL, 2, 0, NULL,
- 0, taiko_codec_reset_interpolator, SND_SOC_DAPM_PRE_PMU |
+ 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
SND_SOC_DAPM_POST_PMU),
SND_SOC_DAPM_MIXER_E("RX4 MIX1", TAIKO_A_CDC_CLK_RX_B1_CTL, 3, 0, NULL,
- 0, taiko_codec_reset_interpolator, SND_SOC_DAPM_PRE_PMU |
+ 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
SND_SOC_DAPM_POST_PMU),
SND_SOC_DAPM_MIXER_E("RX5 MIX1", TAIKO_A_CDC_CLK_RX_B1_CTL, 4, 0, NULL,
- 0, taiko_codec_reset_interpolator, SND_SOC_DAPM_PRE_PMU |
+ 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
SND_SOC_DAPM_POST_PMU),
SND_SOC_DAPM_MIXER_E("RX6 MIX1", TAIKO_A_CDC_CLK_RX_B1_CTL, 5, 0, NULL,
- 0, taiko_codec_reset_interpolator, SND_SOC_DAPM_PRE_PMU |
+ 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
SND_SOC_DAPM_POST_PMU),
SND_SOC_DAPM_MIXER_E("RX7 MIX1", TAIKO_A_CDC_CLK_RX_B1_CTL, 6, 0, NULL,
- 0, taiko_codec_reset_interpolator, SND_SOC_DAPM_PRE_PMU |
+ 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
SND_SOC_DAPM_POST_PMU),
SND_SOC_DAPM_MIXER("RX1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
@@ -4321,11 +4324,11 @@
SND_SOC_DAPM_MIXER("RX3 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
SND_SOC_DAPM_MUX_E("RX4 DSM MUX", TAIKO_A_CDC_CLK_RX_B1_CTL, 3, 0,
- &rx4_dsm_mux, taiko_codec_reset_interpolator,
+ &rx4_dsm_mux, taiko_codec_enable_interpolator,
SND_SOC_DAPM_PRE_PMU),
SND_SOC_DAPM_MUX_E("RX6 DSM MUX", TAIKO_A_CDC_CLK_RX_B1_CTL, 5, 0,
- &rx6_dsm_mux, taiko_codec_reset_interpolator,
+ &rx6_dsm_mux, taiko_codec_enable_interpolator,
SND_SOC_DAPM_PRE_PMU),
SND_SOC_DAPM_MIXER("RX1 CHAIN", TAIKO_A_CDC_RX1_B6_CTL, 5, 0, NULL, 0),
@@ -4381,10 +4384,10 @@
SND_SOC_DAPM_SUPPLY("CLASS_H_EAR", TAIKO_A_CDC_CLSH_B1_CTL, 4, 0,
taiko_codec_enable_class_h, SND_SOC_DAPM_POST_PMU),
- SND_SOC_DAPM_SUPPLY("CLASS_H_HPH_R", TAIKO_A_CDC_CLSH_B1_CTL, 3, 0,
+ SND_SOC_DAPM_SUPPLY("CLASS_H_HPH_L", TAIKO_A_CDC_CLSH_B1_CTL, 3, 0,
taiko_codec_enable_class_h, SND_SOC_DAPM_POST_PMU),
- SND_SOC_DAPM_SUPPLY("CLASS_H_HPH_L", TAIKO_A_CDC_CLSH_B1_CTL, 2, 0,
+ SND_SOC_DAPM_SUPPLY("CLASS_H_HPH_R", TAIKO_A_CDC_CLSH_B1_CTL, 2, 0,
taiko_codec_enable_class_h, SND_SOC_DAPM_POST_PMU),
SND_SOC_DAPM_SUPPLY("CP", TAIKO_A_NCP_EN, 0, 0,
@@ -7088,7 +7091,7 @@
return rc;
}
-static const struct taiko_reg_mask_val taiko_1_0_reg_defaults[] = {
+static const struct taiko_reg_mask_val taiko_reg_defaults[] = {
/* set MCLk to 9.6 */
TAIKO_REG_VAL(TAIKO_A_CHIP_CTL, 0x0A),
@@ -7096,14 +7099,10 @@
/* EAR PA deafults */
TAIKO_REG_VAL(TAIKO_A_RX_EAR_CMBUFF, 0x05),
- /* HPH PA */
- TAIKO_REG_VAL(TAIKO_A_RX_HPH_BIAS_PA, 0x7A),
/** BUCK and NCP defaults for EAR and HS */
TAIKO_REG_VAL(TAIKO_A_BUCK_CTRL_CCL_4, 0x50),
- TAIKO_REG_VAL(TAIKO_A_BUCK_CTRL_VCL_1, 0x08),
TAIKO_REG_VAL(TAIKO_A_BUCK_CTRL_CCL_1, 0x5B),
- TAIKO_REG_VAL(TAIKO_A_NCP_CLK, 0xFC),
/* CLASS-H defaults for EAR and HS */
TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_BUCK_NCP_VARS, 0x00),
@@ -7120,7 +7119,6 @@
*/
TAIKO_REG_VAL(TAIKO_A_CDC_CLSH_B1_CTL, 0x26),
-
/* RX deafults */
TAIKO_REG_VAL(TAIKO_A_CDC_RX1_B5_CTL, 0x78),
TAIKO_REG_VAL(TAIKO_A_CDC_RX2_B5_CTL, 0x78),
@@ -7142,20 +7140,50 @@
TAIKO_REG_VAL(TAIKO_A_CDC_RX7_B6_CTL, 0x80),
};
+static const struct taiko_reg_mask_val taiko_1_0_reg_defaults[] = {
+ /*
+ * The following only need to be written for Taiko 1.0 parts.
+ * Taiko 2.0 will have appropriate defaults for these registers.
+ */
+ /* Choose max non-overlap time for NCP */
+ TAIKO_REG_VAL(TAIKO_A_NCP_CLK, 0xFC),
+ /* Use 25mV/50mV for deltap/m to reduce ripple */
+ TAIKO_REG_VAL(TAIKO_A_BUCK_CTRL_VCL_1, 0x08),
+ /*
+ * Set DISABLE_MODE_SEL<1:0> to 0b10 (disable PWM in auto mode).
+ * Note that the other bits of this register will be changed during
+ * Rx PA bring up.
+ */
+ TAIKO_REG_VAL(TAIKO_A_BUCK_MODE_3, 0xCE),
+ /* Reduce HPH DAC bias to 70% */
+ TAIKO_REG_VAL(TAIKO_A_RX_HPH_BIAS_PA, 0x7A),
+ /*Reduce EAR DAC bias to 70% */
+ TAIKO_REG_VAL(TAIKO_A_RX_EAR_BIAS_PA, 0x76),
+ /* Reduce LINE DAC bias to 70% */
+ TAIKO_REG_VAL(TAIKO_A_RX_LINE_BIAS_PA, 0x78),
+};
+
static void taiko_update_reg_defaults(struct snd_soc_codec *codec)
{
u32 i;
+ struct wcd9xxx *taiko_core = dev_get_drvdata(codec->dev->parent);
- for (i = 0; i < ARRAY_SIZE(taiko_1_0_reg_defaults); i++)
- snd_soc_write(codec, taiko_1_0_reg_defaults[i].reg,
+ for (i = 0; i < ARRAY_SIZE(taiko_reg_defaults); i++)
+ snd_soc_write(codec, taiko_reg_defaults[i].reg,
+ taiko_reg_defaults[i].val);
+
+ if (TAIKO_IS_1_0(taiko_core->version)) {
+ for (i = 0; i < ARRAY_SIZE(taiko_1_0_reg_defaults); i++)
+ snd_soc_write(codec, taiko_1_0_reg_defaults[i].reg,
taiko_1_0_reg_defaults[i].val);
+ }
}
static const struct taiko_reg_mask_val taiko_codec_reg_init_val[] = {
/* Initialize current threshold to 350MA
* number of wait and run cycles to 4096
*/
- {TAIKO_A_RX_HPH_OCP_CTL, 0xE0, 0x60},
+ {TAIKO_A_RX_HPH_OCP_CTL, 0xE1, 0x61},
{TAIKO_A_RX_COM_OCP_COUNT, 0xFF, 0xFF},
/* Initialize gain registers to use register gain */
@@ -7185,7 +7213,7 @@
/* Use 16 bit sample size for RX */
{TAIKO_A_CDC_CONN_RX_SB_B1_CTL, 0xFF, 0xAA},
- {TAIKO_A_CDC_CONN_RX_SB_B2_CTL, 0xFF, 0xAA},
+ {TAIKO_A_CDC_CONN_RX_SB_B2_CTL, 0xFF, 0x2A},
/*enable HPF filter for TX paths */
{TAIKO_A_CDC_TX1_MUX_CTL, 0x8, 0x0},
@@ -7601,7 +7629,7 @@
.volatile_register = taiko_volatile,
.reg_cache_size = TAIKO_CACHE_SIZE,
- .reg_cache_default = taiko_reg_defaults,
+ .reg_cache_default = taiko_reset_reg_defaults,
.reg_word_size = 1,
.controls = taiko_snd_controls,
diff --git a/sound/soc/codecs/wcd9320.h b/sound/soc/codecs/wcd9320.h
index 739ab17..7ca8ff0 100644
--- a/sound/soc/codecs/wcd9320.h
+++ b/sound/soc/codecs/wcd9320.h
@@ -36,7 +36,7 @@
SND_JACK_BTN_6 | SND_JACK_BTN_7)
extern const u8 taiko_reg_readable[TAIKO_CACHE_SIZE];
-extern const u8 taiko_reg_defaults[TAIKO_CACHE_SIZE];
+extern const u8 taiko_reset_reg_defaults[TAIKO_CACHE_SIZE];
enum taiko_micbias_num {
TAIKO_MICBIAS1 = 0,
diff --git a/sound/soc/msm/apq8064-i2s.c b/sound/soc/msm/apq8064-i2s.c
index f57d686..6b5314a 100644
--- a/sound/soc/msm/apq8064-i2s.c
+++ b/sound/soc/msm/apq8064-i2s.c
@@ -63,9 +63,8 @@
#define JACK_DETECT_GPIO 38
-#define APQ_I2S_SLAVE_CONFIG 0
/* MCLK selection GPIOs from PMIC */
-#define PM_GPIO_MCLK_MDM 10
+#define PM_GPIO_MCLK_MDM 27
#define PM_GPIO_MCLK_APQ 41
/* SPKR I2S Configuration */
@@ -170,10 +169,8 @@
};
-#if APQ_I2S_SLAVE_CONFIG
static u32 mdm_mclk_gpio = PM8921_GPIO_PM_TO_SYS(PM_GPIO_MCLK_MDM);
static u32 apq_mclk_gpio = PM8921_GPIO_PM_TO_SYS(PM_GPIO_MCLK_APQ);
-#endif
static u32 top_spk_pamp_gpio = PM8921_GPIO_PM_TO_SYS(18);
static u32 bottom_spk_pamp_gpio = PM8921_GPIO_PM_TO_SYS(19);
static int msm_spk_control;
@@ -186,9 +183,6 @@
static struct clk *i2s_rx_bit_clk;
static struct clk *i2s_tx_bit_clk;
-#if (!APQ_I2S_SLAVE_CONFIG)
-static struct clk *mi2s_osr_clk;
-#endif
static struct clk *mi2s_bit_clk;
static int msm_i2s_rx_ch = 1;
@@ -953,14 +947,10 @@
static int msm_mi2s_rx_be_hw_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);
- pr_debug("%s()\n", __func__);
- rate->min = rate->max = 48000;
+ pr_debug("%s(): channels = %d\n", __func__, msm_mi2s_rx_ch);
channels->min = channels->max = msm_mi2s_rx_ch;
return 0;
@@ -969,15 +959,10 @@
static int msm_mi2s_tx_be_hw_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);
- pr_debug("%s()\n", __func__);
- rate->min = rate->max = 48000;
-
+ pr_debug("%s(): channels = %d\n", __func__, msm_mi2s_tx_ch);
channels->min = channels->max = msm_mi2s_tx_ch;
return 0;
@@ -987,14 +972,10 @@
static int msm_i2s_rx_be_hw_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);
- pr_debug("%s()\n", __func__);
- rate->min = rate->max = 48000;
+ pr_debug("%s(): channels = %d\n", __func__, msm_i2s_rx_ch);
channels->min = channels->max = msm_i2s_rx_ch;
return 0;
@@ -1003,15 +984,10 @@
static int msm_i2s_tx_be_hw_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);
- pr_debug("%s()\n", __func__);
- rate->min = rate->max = 48000;
-
+ pr_debug("%s(): channels = %d\n", __func__, msm_i2s_tx_ch);
channels->min = channels->max = msm_i2s_tx_ch;
return 0;
@@ -1038,7 +1014,6 @@
struct snd_soc_dapm_context *dapm = &codec->dapm;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
-#if APQ_I2S_SLAVE_CONFIG
struct pm_gpio param = {
.direction = PM_GPIO_DIR_OUT,
.output_buffer = PM_GPIO_OUT_BUF_CMOS,
@@ -1048,14 +1023,13 @@
.out_strength = PM_GPIO_STRENGTH_MED,
.function = PM_GPIO_FUNC_NORMAL,
};
-#endif
+
pr_debug("%s(), dev_name(%s)\n", __func__, dev_name(cpu_dai->dev));
ret = gpio_request(GPIO_MI2S_MCLK, "MI2S_MCLK");
if (ret)
pr_err("%s: Failed to request gpio %d\n", __func__,
GPIO_MI2S_MCLK);
-#if APQ_I2S_SLAVE_CONFIG
/* APQ provides the mclk to codec */
ret = gpio_request(mdm_mclk_gpio, "MDM_MCLK_SWITCH");
if (ret) {
@@ -1070,6 +1044,7 @@
else
gpio_direction_output(mdm_mclk_gpio, 0);
+ pr_debug("%s: Config mdm_mclk_gpio\n", __func__);
ret = gpio_request(apq_mclk_gpio, "APQ_MCLK_SWITCH");
if (ret) {
pr_err("%s: Failed to request gpio %d\n", __func__,
@@ -1082,12 +1057,9 @@
apq_mclk_gpio);
else
gpio_direction_output(apq_mclk_gpio, 1);
- pr_debug("%s: Config mdm_mclk_gpio and apq_mclk_gpio\n",
- __func__);
-#else
- pr_debug("%s: Not config mdm_mclk_gpio and apq_mclk_gpio\n",
- __func__);
-#endif
+
+ pr_debug("%s: Config apq_mclk_gpio\n", __func__);
+
snd_soc_dapm_new_controls(dapm, apq8064_dapm_widgets,
ARRAY_SIZE(apq8064_dapm_widgets));
@@ -1172,12 +1144,10 @@
ret = tabla_hs_detect(codec, &mbhc_cfg);
-#if APQ_I2S_SLAVE_CONFIG
/* MDM provides the mclk to codec */
gpio_direction_output(apq_mclk_gpio, 0);
gpio_direction_output(mdm_mclk_gpio, 1);
- pr_debug("%s: Should not running here if no clock switch\n", __func__);
-#endif
+ pr_debug("%s: Clock switch to MDM\n", __func__);
/* Should we add code to put back codec clock?*/
gpio_free(GPIO_MI2S_MCLK);
pr_debug("%s: Free MCLK GPIO\n", __func__);
@@ -1202,13 +1172,6 @@
clk_put(mi2s_bit_clk);
mi2s_bit_clk = NULL;
}
-#if (!APQ_I2S_SLAVE_CONFIG)
- if (mi2s_osr_clk) {
- clk_disable_unprepare(mi2s_osr_clk);
- clk_put(mi2s_osr_clk);
- mi2s_osr_clk = NULL;
- }
-#endif
msm_mi2s_free_gpios();
}
}
@@ -1250,8 +1213,6 @@
if (atomic_inc_return(&mi2s_rsc_ref) == 1) {
pr_debug("%s: acquire mi2s resources\n", __func__);
msm_configure_mi2s_gpio();
-
-#if APQ_I2S_SLAVE_CONFIG
pr_debug("%s: APQ is MI2S slave\n", __func__);
mi2s_bit_clk = clk_get(cpu_dai->dev, "bit_clk");
if (IS_ERR(mi2s_bit_clk))
@@ -1266,38 +1227,6 @@
ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBM_CFM);
if (IS_ERR_VALUE(ret))
pr_err("set format for CPU dai failed\n");
-#else
- pr_debug("%s: APQ is MI2S master\n", __func__);
- mi2s_osr_clk = clk_get(cpu_dai->dev, "osr_clk");
- if (IS_ERR(mi2s_osr_clk))
- return PTR_ERR(mi2s_osr_clk);
- clk_set_rate(mi2s_osr_clk, TABLA_EXT_CLK_RATE);
- ret = clk_prepare_enable(mi2s_osr_clk);
- if (IS_ERR_VALUE(ret)) {
- pr_err("Unable to enable mi2s_osr_clk\n");
- clk_put(mi2s_osr_clk);
- return ret;
- }
- mi2s_bit_clk = clk_get(cpu_dai->dev, "bit_clk");
- if (IS_ERR(mi2s_bit_clk)) {
- pr_err("Unable to get mi2s_bit_clk\n");
- clk_disable_unprepare(mi2s_osr_clk);
- clk_put(mi2s_osr_clk);
- return PTR_ERR(mi2s_bit_clk);
- }
- clk_set_rate(mi2s_bit_clk, 8);
- ret = clk_prepare_enable(mi2s_bit_clk);
- if (IS_ERR_VALUE(ret)) {
- pr_err("Unable to enable mi2s_bit_clk\n");
- clk_disable_unprepare(mi2s_osr_clk);
- clk_put(mi2s_osr_clk);
- clk_put(mi2s_bit_clk);
- return ret;
- }
- ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBS_CFS);
- if (IS_ERR_VALUE(ret))
- pr_err("set format for CPU dai failed\n");
-#endif
}
return ret;
@@ -2028,57 +1957,11 @@
static int msm_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 msm_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)
@@ -2446,6 +2329,14 @@
static struct snd_soc_dai_link msm_dai[] = {
/* FrontEnd DAI Links */
{
+ /*
+ * In APQ8064 I2S platform, there is no playback support
+ * only voice call is supported so there is no even system
+ * tone or dialing tone which is by design because I2S clock
+ * is provided by MDM which matches voice call sample rate
+ * 8kHz or 16kHz while system tone is 48kHz. We disable the
+ * playback by feeding the audio to AUX PCM port.
+ */
.name = "MSM8960 Media1",
.stream_name = "MultiMedia1",
.cpu_dai_name = "MultiMedia1",
diff --git a/sound/soc/msm/msm-compr-q6.c b/sound/soc/msm/msm-compr-q6.c
index 78b3abc..550a492 100644
--- a/sound/soc/msm/msm-compr-q6.c
+++ b/sound/soc/msm/msm-compr-q6.c
@@ -31,6 +31,7 @@
#include <linux/dma-mapping.h>
#include <linux/android_pmem.h>
#include <sound/timer.h>
+#include <mach/qdsp6v2/q6core.h>
#include "msm-compr-q6.h"
#include "msm-pcm-routing.h"
@@ -332,6 +333,7 @@
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct compr_audio *compr = runtime->private_data;
+ struct snd_soc_pcm_runtime *soc_prtd = substream->private_data;
struct msm_audio *prtd = &compr->prtd;
struct asm_aac_cfg aac_cfg;
struct asm_wma_cfg wma_cfg;
@@ -373,11 +375,14 @@
pr_err("%s: CMD Format block failed\n", __func__);
break;
case SND_AUDIOCODEC_AC3_PASS_THROUGH:
- pr_debug("compressd playback, no need to send"
- " the decoder params\n");
- break;
case SND_AUDIOCODEC_DTS_PASS_THROUGH:
- pr_debug("compressd DTS playback,dont send the decoder params\n");
+ pr_debug("compressd playback, no need to send decoder params");
+ pr_debug("decoder id: %d\n",
+ compr->info.codec_param.codec.id);
+ msm_pcm_routing_reg_psthr_stream(
+ soc_prtd->dai_link->be_id,
+ prtd->session_id, substream->stream,
+ 1);
break;
case SND_AUDIOCODEC_WMA:
pr_debug("SND_AUDIOCODEC_WMA\n");
@@ -470,6 +475,7 @@
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct compr_audio *compr = runtime->private_data;
+ struct snd_soc_pcm_runtime *soc_prtd = substream->private_data;
struct msm_audio *prtd = &compr->prtd;
struct audio_buffer *buf = prtd->audio_client->port[OUT].buf;
struct snd_codec *codec = &compr->info.codec_param.codec;
@@ -499,6 +505,13 @@
pr_err("%s: CMD Format block" \
"failed: %d\n", __func__, ret);
break;
+ case SND_AUDIOCODEC_PCM:
+ pr_debug("SND_AUDIOCODEC_PCM\n");
+ ret = q6asm_enc_cfg_blk_multi_ch_pcm(prtd->audio_client,
+ prtd->samp_rate, prtd->channel_mode);
+ if (ret < 0)
+ pr_info("%s: CMD Format block failed\n", __func__);
+ break;
default:
pr_debug("No config for codec %d\n", codec->id);
}
@@ -511,6 +524,7 @@
read_param.uid = i;
switch (codec->id) {
case SND_AUDIOCODEC_AMRWB:
+ case SND_AUDIOCODEC_PCM:
read_param.len = prtd->pcm_count
- COMPRE_CAPTURE_HEADER_SIZE;
read_param.paddr = (unsigned long)(buf[i].phys)
@@ -521,17 +535,30 @@
buf[i].data);
q6asm_async_read(prtd->audio_client, &read_param);
break;
- default:
+ case SND_AUDIOCODEC_PASS_THROUGH:
read_param.paddr = (unsigned long)(buf[i].phys);
q6asm_async_read_compressed(prtd->audio_client,
&read_param);
break;
+ default:
+ pr_err("Invalid format");
+ ret = -EINVAL;
+ break;
}
}
prtd->periods = runtime->periods;
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)
+ msm_pcm_routing_reg_psthr_stream(
+ soc_prtd->dai_link->be_id,
+ prtd->session_id, substream->stream,
+ 1);
+
return ret;
}
@@ -539,7 +566,6 @@
{
int ret = 0;
struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_soc_pcm_runtime *soc_prtd = substream->private_data;
struct compr_audio *compr = runtime->private_data;
struct msm_audio *prtd = &compr->prtd;
@@ -547,28 +573,7 @@
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
prtd->pcm_irq_pos = 0;
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- if (compr->info.codec_param.codec.id ==
- SND_AUDIOCODEC_AC3_PASS_THROUGH ||
- compr->info.codec_param.codec.id ==
- SND_AUDIOCODEC_DTS_PASS_THROUGH) {
- msm_pcm_routing_reg_psthr_stream(
- soc_prtd->dai_link->be_id,
- prtd->session_id, substream->stream,
- 1);
- }
- } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
- switch (compr->info.codec_param.codec.id) {
- case SND_AUDIOCODEC_AMRWB:
- break;
- default:
- msm_pcm_routing_reg_psthr_stream(
- soc_prtd->dai_link->be_id,
- prtd->session_id, substream->stream,
- 1);
- break;
- }
- }
+ /* intentional fall-through */
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
pr_debug("%s: Trigger start\n", __func__);
@@ -576,29 +581,6 @@
atomic_set(&prtd->start, 1);
break;
case SNDRV_PCM_TRIGGER_STOP:
- pr_debug("SNDRV_PCM_TRIGGER_STOP\n");
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- if (compr->info.codec_param.codec.id ==
- SND_AUDIOCODEC_AC3_PASS_THROUGH ||
- compr->info.codec_param.codec.id ==
- SND_AUDIOCODEC_DTS_PASS_THROUGH) {
- msm_pcm_routing_reg_psthr_stream(
- soc_prtd->dai_link->be_id,
- prtd->session_id, substream->stream,
- 0);
- }
- } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
- switch (compr->info.codec_param.codec.id) {
- case SND_AUDIOCODEC_AMRWB:
- break;
- default:
- msm_pcm_routing_reg_psthr_stream(
- soc_prtd->dai_link->be_id,
- prtd->session_id, substream->stream,
- 0);
- break;
- }
- }
atomic_set(&prtd->start, 0);
break;
case SNDRV_PCM_TRIGGER_SUSPEND:
@@ -620,7 +602,7 @@
{
pr_debug("%s\n", __func__);
/* MP3 Block */
- compr->info.compr_cap.num_codecs = 10;
+ compr->info.compr_cap.num_codecs = 12;
compr->info.compr_cap.min_fragment_size = runtime->hw.period_bytes_min;
compr->info.compr_cap.max_fragment_size = runtime->hw.period_bytes_max;
compr->info.compr_cap.min_fragments = runtime->hw.periods_min;
@@ -635,6 +617,8 @@
compr->info.compr_cap.codecs[7] = SND_AUDIOCODEC_DTS_PASS_THROUGH;
compr->info.compr_cap.codecs[8] = SND_AUDIOCODEC_AMRWB;
compr->info.compr_cap.codecs[9] = SND_AUDIOCODEC_AMRWBPLUS;
+ compr->info.compr_cap.codecs[10] = SND_AUDIOCODEC_PASS_THROUGH;
+ compr->info.compr_cap.codecs[11] = SND_AUDIOCODEC_PCM;
/* Add new codecs here and update num_codecs*/
}
@@ -753,11 +737,18 @@
compressed_audio.prtd = NULL;
q6asm_audio_client_buf_free_contiguous(dir,
prtd->audio_client);
- if (!(compr->info.codec_param.codec.id ==
- SND_AUDIOCODEC_AC3_PASS_THROUGH))
+ if ((compr->info.codec_param.codec.id !=
+ SND_AUDIOCODEC_AC3_PASS_THROUGH) &&
+ (compr->info.codec_param.codec.id !=
+ SND_AUDIOCODEC_DTS_PASS_THROUGH))
msm_pcm_routing_dereg_phy_stream(
soc_prtd->dai_link->be_id,
SNDRV_PCM_STREAM_PLAYBACK);
+ else
+ msm_pcm_routing_reg_psthr_stream(
+ soc_prtd->dai_link->be_id,
+ prtd->session_id, substream->stream,
+ 0);
q6asm_audio_client_free(prtd->audio_client);
kfree(prtd);
return 0;
@@ -776,8 +767,17 @@
q6asm_cmd(prtd->audio_client, CMD_CLOSE);
q6asm_audio_client_buf_free_contiguous(dir,
prtd->audio_client);
- msm_pcm_routing_dereg_phy_stream(soc_prtd->dai_link->be_id,
- SNDRV_PCM_STREAM_CAPTURE);
+ if (compr->info.codec_param.codec.id ==
+ SND_AUDIOCODEC_AC3_PASS_THROUGH ||
+ compr->info.codec_param.codec.id ==
+ SND_AUDIOCODEC_DTS_PASS_THROUGH)
+ msm_pcm_routing_reg_psthr_stream(
+ soc_prtd->dai_link->be_id,
+ prtd->session_id, substream->stream,
+ 0);
+ else
+ msm_pcm_routing_dereg_phy_stream(soc_prtd->dai_link->be_id,
+ SNDRV_PCM_STREAM_CAPTURE);
q6asm_audio_client_free(prtd->audio_client);
kfree(prtd);
@@ -909,12 +909,30 @@
prtd->audio_client->perf_mode,
prtd->session_id, substream->stream);
break;
- default:
+ case SND_AUDIOCODEC_PCM:
+ pr_debug("q6asm_open_read(FORMAT_PCM)\n");
+ ret = q6asm_open_read(prtd->audio_client,
+ FORMAT_MULTI_CHANNEL_LINEAR_PCM);
+ if (ret < 0) {
+ pr_err("%s: compressed Session open failed\n",
+ __func__);
+ return -ENOMEM;
+ }
+ pr_debug("msm_pcm_routing_reg_phy_stream\n");
+ msm_pcm_routing_reg_phy_stream(
+ soc_prtd->dai_link->be_id,
+ prtd->audio_client->perf_mode,
+ prtd->session_id, substream->stream);
+ break;
+ case SND_AUDIOCODEC_PASS_THROUGH:
pr_debug("q6asm_open_read_compressed(COMPRESSED_META_DATA_MODE)\n");
ret = q6asm_open_read_compressed(prtd->audio_client,
MAX_NUM_FRAMES_PER_BUFFER,
COMPRESSED_META_DATA_MODE);
break;
+ default:
+ pr_err("Invalid codec for compressed session open\n");
+ return -EFAULT;
}
if (ret < 0) {
@@ -1047,13 +1065,37 @@
pr_debug("SND_AUDIOCODEC_DTS_PASS_THROUGH\n");
compr->codec = FORMAT_DTS;
break;
- case SND_AUDIOCODEC_DTS:
+ case SND_AUDIOCODEC_DTS: {
+ char modelId[128];
+ struct snd_dec_dts opt_dts =
+ compr->info.codec_param.codec.options.dts;
+ int modelIdLength = opt_dts.modelIdLength;
pr_debug("SND_AUDIOCODEC_DTS\n");
+ if (copy_from_user(modelId, (void *)opt_dts.modelId,
+ modelIdLength))
+ pr_err("%s: ERROR: copy modelId\n", __func__);
+ modelId[modelIdLength] = '\0';
+ pr_debug("%s: Received modelId =%s,length=%d\n",
+ __func__, modelId, modelIdLength);
+ core_set_dts_model_id(modelIdLength, modelId);
compr->codec = FORMAT_DTS;
+ }
break;
- case SND_AUDIOCODEC_DTS_LBR:
- pr_debug("SND_AUDIOCODEC_DTS\n");
+ case SND_AUDIOCODEC_DTS_LBR:{
+ char modelId[128];
+ struct snd_dec_dts opt_dts =
+ compr->info.codec_param.codec.options.dts;
+ int modelIdLength = opt_dts.modelIdLength;
+ pr_debug("SND_AUDIOCODEC_DTS_LBR\n");
+ if (copy_from_user(modelId, (void *)opt_dts.modelId,
+ modelIdLength))
+ pr_err("%s: ERROR: copy modelId\n", __func__);
+ modelId[modelIdLength] = '\0';
+ pr_debug("%s: Received modelId =%s,length=%d\n",
+ __func__, modelId, modelIdLength);
+ core_set_dts_model_id(modelIdLength, modelId);
compr->codec = FORMAT_DTS_LBR;
+ }
break;
case SND_AUDIOCODEC_AMRWB:
pr_debug("msm_compr_ioctl SND_AUDIOCODEC_AMRWB\n");
@@ -1063,11 +1105,19 @@
pr_debug("msm_compr_ioctl SND_AUDIOCODEC_AMRWBPLUS\n");
compr->codec = FORMAT_AMR_WB_PLUS;
break;
- default:
- /*Needed for the HDMI IN compressed use case*/
- pr_debug("FORMAT_LINEAR_PCM\n");
- compr->codec = FORMAT_LINEAR_PCM;
+ case SND_AUDIOCODEC_PASS_THROUGH:
+ /* format pass through is used for HDMI IN compressed
+ where the decoder format is indicated by LPASS */
+ pr_debug("msm_compr_ioctl SND_AUDIOCODEC_PASSTHROUGH\n");
+ compr->codec = FORMAT_PASS_THROUGH;
break;
+ case SND_AUDIOCODEC_PCM:
+ pr_debug("msm_compr_ioctl SND_AUDIOCODEC_PCM\n");
+ compr->codec = FORMAT_MULTI_CHANNEL_LINEAR_PCM;
+ break;
+ default:
+ pr_err("msm_compr_ioctl failed..unknown codec\n");
+ return -EFAULT;
}
return 0;
case SNDRV_PCM_IOCTL1_RESET:
diff --git a/sound/soc/msm/msm8974.c b/sound/soc/msm/msm8974.c
index 92b7324..f462299 100644
--- a/sound/soc/msm/msm8974.c
+++ b/sound/soc/msm/msm8974.c
@@ -81,6 +81,7 @@
static int msm_slim_0_tx_ch = 1;
static int msm_btsco_rate = BTSCO_RATE_8KHZ;
+static int msm_btsco_ch = 1;
static struct snd_soc_jack hs_jack;
static struct snd_soc_jack button_jack;
@@ -480,6 +481,21 @@
msm_btsco_rate_get, msm_btsco_rate_put),
};
+static int msm_btsco_be_hw_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);
+
+ rate->min = rate->max = msm_btsco_rate;
+ channels->min = channels->max = msm_btsco_ch;
+
+ return 0;
+}
+
static int msm_auxpcm_be_params_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params)
{
@@ -495,6 +511,19 @@
return 0;
}
+
+static int msm_proxy_be_hw_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);
+
+ pr_debug("%s()\n", __func__);
+ rate->min = rate->max = 48000;
+
+ return 0;
+}
+
static int msm_aux_pcm_get_gpios(void)
{
int ret = 0;
@@ -780,19 +809,19 @@
.be_id = MSM_FRONTEND_DAI_MULTIMEDIA1
},
{
- .name = "MSM VoIP",
- .stream_name = "VoIP",
- .cpu_dai_name = "VoIP",
- .platform_name = "msm-voip-dsp",
+ .name = "MSM8974 Media2",
+ .stream_name = "MultiMedia2",
+ .cpu_dai_name = "MultiMedia2",
+ .platform_name = "msm-pcm-dsp",
.dynamic = 1,
- .trigger = {SND_SOC_DPCM_TRIGGER_POST,
- SND_SOC_DPCM_TRIGGER_POST},
.codec_dai_name = "snd-soc-dummy-dai",
.codec_name = "snd-soc-dummy",
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
.ignore_suspend = 1,
/* this dainlink has playback support */
.ignore_pmdown_time = 1,
- .be_id = MSM_FRONTEND_DAI_VOIP,
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA2,
},
{
.name = "Circuit-Switch Voice",
@@ -811,6 +840,21 @@
.be_id = MSM_FRONTEND_DAI_CS_VOICE,
},
{
+ .name = "MSM VoIP",
+ .stream_name = "VoIP",
+ .cpu_dai_name = "VoIP",
+ .platform_name = "msm-voip-dsp",
+ .dynamic = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ /* this dainlink has playback support */
+ .ignore_pmdown_time = 1,
+ .be_id = MSM_FRONTEND_DAI_VOIP,
+ },
+ {
.name = "MSM8974 LPA",
.stream_name = "LPA",
.cpu_dai_name = "MultiMedia3",
@@ -841,6 +885,41 @@
.codec_name = "snd-soc-dummy",
},
{
+ .name = "INT_FM Hostless",
+ .stream_name = "INT_FM Hostless",
+ .cpu_dai_name = "INT_FM_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,
+ /* this dainlink has playback support */
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {
+ .name = "MSM AFE-PCM RX",
+ .stream_name = "AFE-PROXY RX",
+ .cpu_dai_name = "msm-dai-q6-dev.241",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .platform_name = "msm-pcm-afe",
+ .ignore_suspend = 1,
+ /* this dainlink has playback support */
+ .ignore_pmdown_time = 1,
+ },
+ {
+ .name = "MSM AFE-PCM TX",
+ .stream_name = "AFE-PROXY TX",
+ .cpu_dai_name = "msm-dai-q6-dev.240",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .platform_name = "msm-pcm-afe",
+ .ignore_suspend = 1,
+ },
+ {
.name = "MSM8974 Compr",
.stream_name = "COMPR",
.cpu_dai_name = "MultiMedia4",
@@ -870,19 +949,55 @@
.codec_dai_name = "snd-soc-dummy-dai",
.codec_name = "snd-soc-dummy",
},
+ /* Backend BT/FM DAI Links */
{
- .name = "MSM8974 Media2",
- .stream_name = "MultiMedia2",
- .cpu_dai_name = "MultiMedia2",
- .platform_name = "msm-pcm-dsp",
- .dynamic = 1,
- .codec_dai_name = "snd-soc-dummy-dai",
- .codec_name = "snd-soc-dummy",
- .trigger = {SND_SOC_DPCM_TRIGGER_POST,
- SND_SOC_DPCM_TRIGGER_POST},
- .ignore_suspend = 1,
+ .name = LPASS_BE_INT_BT_SCO_RX,
+ .stream_name = "Internal BT-SCO Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.12288",
+ .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_INT_BT_SCO_RX,
+ .be_hw_params_fixup = msm_btsco_be_hw_params_fixup,
+ /* this dainlink has playback support */
.ignore_pmdown_time = 1,
- .be_id = MSM_FRONTEND_DAI_MULTIMEDIA2,
+ },
+ {
+ .name = LPASS_BE_INT_BT_SCO_TX,
+ .stream_name = "Internal BT-SCO Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.12289",
+ .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_INT_BT_SCO_TX,
+ .be_hw_params_fixup = msm_btsco_be_hw_params_fixup,
+ },
+ /* Backend AFE DAI Links */
+ {
+ .name = LPASS_BE_AFE_PCM_RX,
+ .stream_name = "AFE Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.224",
+ .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_AFE_PCM_RX,
+ .be_hw_params_fixup = msm_proxy_be_hw_params_fixup,
+ /* this dainlink has playback support */
+ .ignore_pmdown_time = 1,
+ },
+ {
+ .name = LPASS_BE_AFE_PCM_TX,
+ .stream_name = "AFE Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.225",
+ .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_AFE_PCM_TX,
+ .be_hw_params_fixup = msm_proxy_be_hw_params_fixup,
},
/* AUX PCM Backend DAI Links */
{
diff --git a/sound/soc/msm/qdsp6/q6asm.c b/sound/soc/msm/qdsp6/q6asm.c
index 3a226b4..b086b8e 100644
--- a/sound/soc/msm/qdsp6/q6asm.c
+++ b/sound/soc/msm/qdsp6/q6asm.c
@@ -529,7 +529,7 @@
}
buf[cnt].handle = ion_alloc
(buf[cnt].client, bufsz, SZ_4K,
- (0x1 << ION_AUDIO_HEAP_ID));
+ (0x1 << ION_AUDIO_HEAP_ID), 0);
if (IS_ERR_OR_NULL((void *)
buf[cnt].handle)) {
pr_err("%s: ION memory allocation for AUDIO failed\n",
@@ -551,8 +551,7 @@
}
buf[cnt].data = ion_map_kernel
- (buf[cnt].client, buf[cnt].handle,
- 0);
+ (buf[cnt].client, buf[cnt].handle);
if (IS_ERR_OR_NULL((void *)
buf[cnt].data)) {
pr_err("%s: ION memory mapping for AUDIO failed\n",
@@ -665,7 +664,7 @@
goto fail;
}
buf[0].handle = ion_alloc(buf[0].client, bufsz * bufcnt, SZ_4K,
- (0x1 << ION_AUDIO_HEAP_ID));
+ (0x1 << ION_AUDIO_HEAP_ID), 0);
if (IS_ERR_OR_NULL((void *) buf[0].handle)) {
pr_err("%s: ION memory allocation for AUDIO failed\n",
__func__);
@@ -682,7 +681,7 @@
goto fail;
}
- buf[0].data = ion_map_kernel(buf[0].client, buf[0].handle, 0);
+ buf[0].data = ion_map_kernel(buf[0].client, buf[0].handle);
if (IS_ERR_OR_NULL((void *) buf[0].data)) {
pr_err("%s: ION memory mapping for AUDIO failed\n", __func__);
mutex_unlock(&ac->cmd_lock);
@@ -876,8 +875,9 @@
case ASM_STREAM_CMD_OPEN_READ_COMPRESSED:
if (atomic_read(&ac->cmd_state) && wakeup_flag) {
atomic_set(&ac->cmd_state, 0);
- if (payload[1] == ADSP_EUNSUPPORTED) {
- pr_debug("paload[1]:%d unsupported",
+ if (payload[1] == ADSP_EUNSUPPORTED ||
+ payload[1] == ADSP_EFAILED) {
+ pr_debug("payload[1]:%d unsupported",
payload[1]);
atomic_set(&ac->cmd_response, 1);
}
diff --git a/sound/soc/msm/qdsp6/q6voice.c b/sound/soc/msm/qdsp6/q6voice.c
index 2a21dfa..cb2e39b 100644
--- a/sound/soc/msm/qdsp6/q6voice.c
+++ b/sound/soc/msm/qdsp6/q6voice.c
@@ -4061,7 +4061,7 @@
common.ion_handle = ion_alloc(common.ion_client,
TOTAL_VOICE_CAL_SIZE,
- SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID));
+ SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID), 0);
if (IS_ERR_OR_NULL((void *) common.ion_handle)) {
pr_err("%s: ION memory allocation failed\n",
__func__);
@@ -4076,8 +4076,7 @@
goto err_ion_handle;
}
- kvptr = ion_map_kernel(common.ion_client,
- common.ion_handle, 0);
+ kvptr = ion_map_kernel(common.ion_client, common.ion_handle);
if (IS_ERR_OR_NULL(kvptr)) {
pr_err("%s: ION memory mapping failed\n", __func__);
goto err_ion_handle;
diff --git a/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c
index 6f3249a..bbd43f7 100644
--- a/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c
@@ -25,13 +25,25 @@
#include <sound/pcm.h>
#include <sound/initval.h>
#include <sound/control.h>
+#include <sound/q6asm-v2.h>
+#include <sound/pcm_params.h>
#include <asm/dma.h>
#include <linux/dma-mapping.h>
#include <linux/android_pmem.h>
+#include <sound/timer.h>
#include "msm-compr-q6-v2.h"
#include "msm-pcm-routing-v2.h"
+#define COMPRE_CAPTURE_NUM_PERIODS 16
+/* Allocate the worst case frame size for compressed audio */
+#define COMPRE_CAPTURE_HEADER_SIZE (sizeof(struct snd_compr_audio_info))
+#define COMPRE_CAPTURE_MAX_FRAME_SIZE (6144)
+#define COMPRE_CAPTURE_PERIOD_SIZE ((COMPRE_CAPTURE_MAX_FRAME_SIZE + \
+ COMPRE_CAPTURE_HEADER_SIZE) * \
+ MAX_NUM_FRAMES_PER_BUFFER)
+#define COMPRE_OUTPUT_METADATA_SIZE (sizeof(struct output_meta_data_st))
+
struct snd_msm {
struct msm_audio *prtd;
unsigned volume;
@@ -40,7 +52,7 @@
static struct audio_locks the_locks;
-static struct snd_pcm_hardware msm_compr_hardware_playback = {
+static struct snd_pcm_hardware msm_compr_hardware_capture = {
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP_VALID |
@@ -51,12 +63,33 @@
.rate_min = 8000,
.rate_max = 48000,
.channels_min = 1,
- .channels_max = 2,
+ .channels_max = 8,
+ .buffer_bytes_max =
+ COMPRE_CAPTURE_PERIOD_SIZE * COMPRE_CAPTURE_NUM_PERIODS ,
+ .period_bytes_min = COMPRE_CAPTURE_PERIOD_SIZE,
+ .period_bytes_max = COMPRE_CAPTURE_PERIOD_SIZE,
+ .periods_min = COMPRE_CAPTURE_NUM_PERIODS,
+ .periods_max = COMPRE_CAPTURE_NUM_PERIODS,
+ .fifo_size = 0,
+};
+
+static struct snd_pcm_hardware msm_compr_hardware_playback = {
+ .info = (SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_KNOT,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ .channels_min = 1,
+ .channels_max = 8,
.buffer_bytes_max = 1200 * 1024 * 2,
- .period_bytes_min = 4800,
+ .period_bytes_min = 2400,
.period_bytes_max = 1200 * 1024,
.periods_min = 2,
- .periods_max = 512,
+ .periods_max = 1024,
.fifo_size = 0,
};
@@ -79,8 +112,13 @@
struct snd_pcm_substream *substream = prtd->substream;
struct snd_pcm_runtime *runtime = substream->runtime;
struct audio_aio_write_param param;
+ struct audio_aio_read_param read_param;
struct audio_buffer *buf = NULL;
+ struct output_meta_data_st output_meta_data;
+ uint32_t *ptrmem = (uint32_t *)payload;
int i = 0;
+ int time_stamp_flag = 0;
+ int buffer_length = 0;
pr_debug("%s opcode =%08x\n", __func__, opcode);
switch (opcode) {
@@ -91,6 +129,9 @@
prtd->pcm_irq_pos += prtd->pcm_count;
if (atomic_read(&prtd->start))
snd_pcm_period_elapsed(substream);
+ else
+ if (substream->timer_running)
+ snd_timer_interrupt(substream->timer, 1);
atomic_inc(&prtd->out_count);
wake_up(&the_locks.write_wait);
if (!atomic_read(&prtd->start)) {
@@ -98,9 +139,6 @@
break;
} else
atomic_set(&prtd->pending_buffer, 0);
-
- if (runtime->status->hw_ptr >= runtime->control->appl_ptr)
- break;
buf = prtd->audio_client->port[IN].buf;
pr_debug("%s:writing %d bytes of buffer[%d] to dsp 2\n",
__func__, prtd->pcm_count, prtd->out_head);
@@ -109,14 +147,38 @@
((unsigned int)buf[0].phys
+ (prtd->out_head * prtd->pcm_count)));
+ if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE) {
+ time_stamp_flag = SET_TIMESTAMP;
+ memcpy(&output_meta_data, (char *)(buf->data +
+ prtd->out_head * prtd->pcm_count),
+ COMPRE_OUTPUT_METADATA_SIZE);
+ } else {
+ time_stamp_flag = NO_TIMESTAMP;
+ memset(&output_meta_data, 0,
+ COMPRE_OUTPUT_METADATA_SIZE);
+ output_meta_data.frame_size = prtd->pcm_count;
+ }
+ buffer_length = output_meta_data.frame_size;
+ pr_debug("meta_data_length: %d, frame_length: %d\n",
+ output_meta_data.meta_data_length,
+ output_meta_data.frame_size);
+ pr_debug("timestamp_msw: %d, timestamp_lsw: %d\n",
+ output_meta_data.timestamp_msw,
+ output_meta_data.timestamp_lsw);
+ if (buffer_length == 0) {
+ pr_debug("Recieved a zero length buffer-break out");
+ break;
+ }
param.paddr = (unsigned long)buf[0].phys
- + (prtd->out_head * prtd->pcm_count);
- param.len = prtd->pcm_count;
- param.msw_ts = 0;
- param.lsw_ts = 0;
- param.flags = NO_TIMESTAMP;
+ + (prtd->out_head * prtd->pcm_count)
+ + output_meta_data.meta_data_length;
+ param.len = buffer_length;
+ param.msw_ts = output_meta_data.timestamp_msw;
+ param.lsw_ts = output_meta_data.timestamp_lsw;
+ param.flags = time_stamp_flag;
param.uid = (unsigned long)buf[0].phys
- + (prtd->out_head * prtd->pcm_count);
+ + (prtd->out_head * prtd->pcm_count
+ + output_meta_data.meta_data_length);
for (i = 0; i < sizeof(struct audio_aio_write_param)/4;
i++, ++ptrmem)
pr_debug("cmd[%d]=0x%08x\n", i, *ptrmem);
@@ -131,12 +193,60 @@
}
case ASM_DATA_EVENT_RENDERED_EOS:
pr_debug("ASM_DATA_CMDRSP_EOS\n");
- prtd->cmd_ack = 1;
- wake_up(&the_locks.eos_wait);
+ if (atomic_read(&prtd->eos)) {
+ pr_debug("ASM_DATA_CMDRSP_EOS wake up\n");
+ prtd->cmd_ack = 1;
+ wake_up(&the_locks.eos_wait);
+ atomic_set(&prtd->eos, 0);
+ }
break;
+ case ASM_DATA_EVENT_READ_DONE_V2: {
+ pr_debug("ASM_DATA_EVENT_READ_DONE\n");
+ pr_debug("buf = %p, data = 0x%X, *data = %p,\n"
+ "prtd->pcm_irq_pos = %d\n",
+ prtd->audio_client->port[OUT].buf,
+ *(uint32_t *)prtd->audio_client->port[OUT].buf->data,
+ prtd->audio_client->port[OUT].buf->data,
+ prtd->pcm_irq_pos);
+
+ memcpy(prtd->audio_client->port[OUT].buf->data +
+ prtd->pcm_irq_pos, (ptrmem + 2),
+ COMPRE_CAPTURE_HEADER_SIZE);
+ pr_debug("buf = %p, updated data = 0x%X, *data = %p\n",
+ prtd->audio_client->port[OUT].buf,
+ *(uint32_t *)(prtd->audio_client->port[OUT].buf->data +
+ prtd->pcm_irq_pos),
+ prtd->audio_client->port[OUT].buf->data);
+ if (!atomic_read(&prtd->start))
+ break;
+ pr_debug("frame size=%d, buffer = 0x%X\n", ptrmem[2],
+ ptrmem[1]);
+ if (ptrmem[2] > COMPRE_CAPTURE_MAX_FRAME_SIZE) {
+ pr_err("Frame length exceeded the max length");
+ break;
+ }
+ buf = prtd->audio_client->port[OUT].buf;
+ pr_debug("pcm_irq_pos=%d, buf[0].phys = 0x%X\n",
+ prtd->pcm_irq_pos, (uint32_t)buf[0].phys);
+ read_param.len = prtd->pcm_count - COMPRE_CAPTURE_HEADER_SIZE;
+ read_param.paddr = (unsigned long)(buf[0].phys) +
+ prtd->pcm_irq_pos + COMPRE_CAPTURE_HEADER_SIZE;
+ prtd->pcm_irq_pos += prtd->pcm_count;
+
+ if (atomic_read(&prtd->start))
+ snd_pcm_period_elapsed(substream);
+
+ q6asm_async_read(prtd->audio_client, &read_param);
+ break;
+ }
case APR_BASIC_RSP_RESULT: {
switch (payload[0]) {
case ASM_SESSION_CMD_RUN_V2: {
+ if (substream->stream
+ != SNDRV_PCM_STREAM_PLAYBACK) {
+ atomic_set(&prtd->start, 1);
+ break;
+ }
if (!atomic_read(&prtd->pending_buffer))
break;
pr_debug("%s:writing %d bytes of buffer[%d] to dsp\n",
@@ -146,12 +256,32 @@
__func__, prtd->out_head,
((unsigned int)buf[0].phys
+ (prtd->out_head * prtd->pcm_count)));
- param.paddr = (unsigned long)buf[prtd->out_head].phys;
- param.len = prtd->pcm_count;
- param.msw_ts = 0;
- param.lsw_ts = 0;
- param.flags = NO_TIMESTAMP;
- param.uid = (unsigned long)buf[prtd->out_head].phys;
+ if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE) {
+ time_stamp_flag = SET_TIMESTAMP;
+ memcpy(&output_meta_data, (char *)(buf->data +
+ prtd->out_head * prtd->pcm_count),
+ COMPRE_OUTPUT_METADATA_SIZE);
+ } else {
+ time_stamp_flag = NO_TIMESTAMP;
+ memset(&output_meta_data, 0,
+ COMPRE_OUTPUT_METADATA_SIZE);
+ output_meta_data.frame_size = prtd->pcm_count;
+ }
+ buffer_length = output_meta_data.frame_size;
+ pr_debug("meta_data_length: %d, frame_length: %d\n",
+ output_meta_data.meta_data_length,
+ output_meta_data.frame_size);
+ pr_debug("timestamp_msw: %d, timestamp_lsw: %d\n",
+ output_meta_data.timestamp_msw,
+ output_meta_data.timestamp_lsw);
+ param.paddr = (unsigned long)buf[prtd->out_head].phys
+ + output_meta_data.meta_data_length;
+ param.len = buffer_length;
+ param.msw_ts = output_meta_data.timestamp_msw;
+ param.lsw_ts = output_meta_data.timestamp_lsw;
+ param.flags = time_stamp_flag;
+ param.uid = (unsigned long)buf[prtd->out_head].phys
+ + output_meta_data.meta_data_length;
if (q6asm_async_write(prtd->audio_client,
¶m) < 0)
pr_err("%s:q6asm_async_write failed\n",
@@ -166,7 +296,7 @@
case ASM_STREAM_CMD_FLUSH:
pr_debug("ASM_STREAM_CMD_FLUSH\n");
prtd->cmd_ack = 1;
- wake_up(&the_locks.eos_wait);
+ wake_up(&the_locks.flush_wait);
break;
default:
break;
@@ -187,7 +317,7 @@
struct asm_aac_cfg aac_cfg;
int ret;
- pr_debug("%s\n", __func__);
+ pr_debug("compressed stream prepare\n");
prtd->pcm_size = snd_pcm_lib_buffer_bytes(substream);
prtd->pcm_count = snd_pcm_lib_period_bytes(substream);
prtd->pcm_irq_pos = 0;
@@ -205,7 +335,7 @@
/* No media format block for mp3 */
break;
case SND_AUDIOCODEC_AAC:
- pr_debug("SND_AUDIOCODEC_AAC\n");
+ pr_debug("%s: SND_AUDIOCODEC_AAC\n", __func__);
memset(&aac_cfg, 0x0, sizeof(struct asm_aac_cfg));
aac_cfg.aot = AAC_ENC_MODE_EAAC_P;
aac_cfg.format = 0x03;
@@ -226,10 +356,83 @@
return 0;
}
+static int msm_compr_capture_prepare(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct compr_audio *compr = runtime->private_data;
+ struct msm_audio *prtd = &compr->prtd;
+ struct audio_buffer *buf = prtd->audio_client->port[OUT].buf;
+ struct snd_codec *codec = &compr->info.codec_param.codec;
+ struct audio_aio_read_param read_param;
+ int ret = 0;
+ int i;
+ prtd->pcm_size = snd_pcm_lib_buffer_bytes(substream);
+ prtd->pcm_count = snd_pcm_lib_period_bytes(substream);
+ prtd->pcm_irq_pos = 0;
+
+ /* rate and channels are sent to audio driver */
+ prtd->samp_rate = runtime->rate;
+ prtd->channel_mode = runtime->channels;
+
+ if (prtd->enabled)
+ return ret;
+ read_param.len = prtd->pcm_count;
+
+ switch (codec->id) {
+ case SND_AUDIOCODEC_AMRWB:
+ pr_debug("SND_AUDIOCODEC_AMRWB\n");
+ ret = q6asm_enc_cfg_blk_amrwb(prtd->audio_client,
+ MAX_NUM_FRAMES_PER_BUFFER,
+ codec->options.generic.reserved[0] /*bitrate 0-8*/,
+ codec->options.generic.reserved[1] /*dtx mode 0/1*/);
+ if (ret < 0)
+ pr_err("%s: CMD Format block" \
+ "failed: %d\n", __func__, ret);
+ break;
+ default:
+ pr_debug("No config for codec %d\n", codec->id);
+ }
+ pr_debug("%s: Samp_rate = %d, Channel = %d, pcm_size = %d,\n"
+ "pcm_count = %d, periods = %d\n",
+ __func__, prtd->samp_rate, prtd->channel_mode,
+ prtd->pcm_size, prtd->pcm_count, runtime->periods);
+
+ for (i = 0; i < runtime->periods; i++) {
+ read_param.uid = i;
+ switch (codec->id) {
+ case SND_AUDIOCODEC_AMRWB:
+ read_param.len = prtd->pcm_count
+ - COMPRE_CAPTURE_HEADER_SIZE;
+ read_param.paddr = (unsigned long)(buf[i].phys)
+ + COMPRE_CAPTURE_HEADER_SIZE;
+ pr_debug("Push buffer [%d] to DSP, "\
+ "paddr: %p, vaddr: %p\n",
+ i, (void *) read_param.paddr,
+ buf[i].data);
+ q6asm_async_read(prtd->audio_client, &read_param);
+ break;
+ default:
+ read_param.paddr = (unsigned long)(buf[i].phys);
+ /*q6asm_async_read_compressed(prtd->audio_client,
+ &read_param);*/
+ pr_debug("%s: To add support for read compressed\n",
+ __func__);
+ ret = -EINVAL;
+ break;
+ }
+ }
+ prtd->periods = runtime->periods;
+
+ prtd->enabled = 1;
+
+ return ret;
+}
+
static int msm_compr_trigger(struct snd_pcm_substream *substream, int cmd)
{
int ret = 0;
struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_soc_pcm_runtime *soc_prtd = substream->private_data;
struct compr_audio *compr = runtime->private_data;
struct msm_audio *prtd = &compr->prtd;
@@ -237,6 +440,17 @@
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
prtd->pcm_irq_pos = 0;
+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+ switch (compr->info.codec_param.codec.id) {
+ case SND_AUDIOCODEC_AMRWB:
+ break;
+ default:
+ msm_pcm_routing_reg_psthr_stream(
+ soc_prtd->dai_link->be_id,
+ prtd->session_id, substream->stream);
+ break;
+ }
+ }
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
pr_debug("%s: Trigger start\n", __func__);
@@ -245,6 +459,17 @@
break;
case SNDRV_PCM_TRIGGER_STOP:
pr_debug("SNDRV_PCM_TRIGGER_STOP\n");
+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+ switch (compr->info.codec_param.codec.id) {
+ case SND_AUDIOCODEC_AMRWB:
+ break;
+ default:
+ msm_pcm_routing_reg_psthr_stream(
+ soc_prtd->dai_link->be_id,
+ prtd->session_id, substream->stream);
+ break;
+ }
+ }
atomic_set(&prtd->start, 0);
break;
case SNDRV_PCM_TRIGGER_SUSPEND:
@@ -266,7 +491,7 @@
{
pr_debug("%s\n", __func__);
/* MP3 Block */
- compr->info.compr_cap.num_codecs = 1;
+ compr->info.compr_cap.num_codecs = 2;
compr->info.compr_cap.min_fragment_size = runtime->hw.period_bytes_min;
compr->info.compr_cap.max_fragment_size = runtime->hw.period_bytes_max;
compr->info.compr_cap.min_fragments = runtime->hw.periods_min;
@@ -294,10 +519,6 @@
.rampingcurve = SOFT_VOLUME_CURVE_LINEAR,
};
- /* Capture path */
- if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
- return -EINVAL;
-
pr_debug("%s\n", __func__);
compr = kzalloc(sizeof(struct compr_audio), GFP_KERNEL);
if (compr == NULL) {
@@ -313,12 +534,18 @@
kfree(prtd);
return -ENOMEM;
}
- runtime->hw = msm_compr_hardware_playback;
pr_info("%s: session ID %d\n", __func__, prtd->audio_client->session);
prtd->session_id = prtd->audio_client->session;
- prtd->cmd_ack = 1;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ runtime->hw = msm_compr_hardware_playback;
+ prtd->cmd_ack = 1;
+ } else {
+ runtime->hw = msm_compr_hardware_capture;
+ }
+
ret = snd_pcm_hw_constraint_list(runtime, 0,
SNDRV_PCM_HW_PARAM_RATE,
@@ -333,9 +560,11 @@
prtd->dsp_cnt = 0;
atomic_set(&prtd->pending_buffer, 1);
- compr->codec = FORMAT_MP3;
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ compr->codec = FORMAT_MP3;
populate_codec_list(compr, runtime);
runtime->private_data = compr;
+ atomic_set(&prtd->eos, 0);
compressed_audio.prtd = &compr->prtd;
ret = compressed_set_volume(compressed_audio.volume);
if (ret < 0)
@@ -382,13 +611,34 @@
dir = IN;
atomic_set(&prtd->pending_buffer, 0);
+ prtd->pcm_irq_pos = 0;
q6asm_cmd(prtd->audio_client, CMD_CLOSE);
compressed_audio.prtd = NULL;
q6asm_audio_client_buf_free_contiguous(dir,
prtd->audio_client);
+ msm_pcm_routing_dereg_phy_stream(
+ soc_prtd->dai_link->be_id,
+ SNDRV_PCM_STREAM_PLAYBACK);
+ q6asm_audio_client_free(prtd->audio_client);
+ kfree(prtd);
+ return 0;
+}
+static int msm_compr_capture_close(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_soc_pcm_runtime *soc_prtd = substream->private_data;
+ struct compr_audio *compr = runtime->private_data;
+ struct msm_audio *prtd = &compr->prtd;
+ int dir = OUT;
+
+ pr_debug("%s\n", __func__);
+ atomic_set(&prtd->pending_buffer, 0);
+ q6asm_cmd(prtd->audio_client, CMD_CLOSE);
+ q6asm_audio_client_buf_free_contiguous(dir,
+ prtd->audio_client);
msm_pcm_routing_dereg_phy_stream(soc_prtd->dai_link->be_id,
- SNDRV_PCM_STREAM_PLAYBACK);
+ SNDRV_PCM_STREAM_CAPTURE);
q6asm_audio_client_free(prtd->audio_client);
kfree(prtd);
return 0;
@@ -401,7 +651,7 @@
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
ret = msm_compr_playback_close(substream);
else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
- ret = EINVAL;
+ ret = msm_compr_capture_close(substream);
return ret;
}
static int msm_compr_prepare(struct snd_pcm_substream *substream)
@@ -411,7 +661,7 @@
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
ret = msm_compr_playback_prepare(substream);
else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
- ret = EINVAL;
+ ret = msm_compr_capture_prepare(substream);
return ret;
}
@@ -425,7 +675,10 @@
if (prtd->pcm_irq_pos >= prtd->pcm_size)
prtd->pcm_irq_pos = 0;
- pr_debug("pcm_irq_pos = %d\n", prtd->pcm_irq_pos);
+ pr_debug("%s: pcm_irq_pos = %d, pcm_size = %d, sample_bits = %d,\n"
+ "frame_bits = %d\n", __func__, prtd->pcm_irq_pos,
+ prtd->pcm_size, runtime->sample_bits,
+ runtime->frame_bits);
return bytes_to_frames(runtime, (prtd->pcm_irq_pos));
}
@@ -467,22 +720,69 @@
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
dir = IN;
else
- return -EINVAL;
+ dir = OUT;
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ ret = q6asm_open_write(prtd->audio_client,
+ compr->codec);
+ if (ret < 0) {
+ pr_err("%s: Session out open failed\n",
+ __func__);
+ return -ENOMEM;
+ }
+ msm_pcm_routing_reg_phy_stream(
+ soc_prtd->dai_link->be_id,
+ prtd->session_id,
+ substream->stream);
+ } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+ switch (compr->info.codec_param.codec.id) {
+ case SND_AUDIOCODEC_AMRWB:
+ pr_debug("q6asm_open_read(FORMAT_AMRWB)\n");
+ ret = q6asm_open_read(prtd->audio_client,
+ FORMAT_AMRWB);
+ if (ret < 0) {
+ pr_err("%s: compressed Session out open failed\n",
+ __func__);
+ return -ENOMEM;
+ }
+ pr_debug("msm_pcm_routing_reg_phy_stream\n");
+ msm_pcm_routing_reg_phy_stream(
+ soc_prtd->dai_link->be_id,
+ prtd->session_id, substream->stream);
+ break;
+ default:
+ pr_debug("q6asm_open_read_compressed(COMPRESSED_META_DATA_MODE)\n");
+ /*
+ ret = q6asm_open_read_compressed(prtd->audio_client,
+ MAX_NUM_FRAMES_PER_BUFFER,
+ COMPRESSED_META_DATA_MODE);
+ */
+ ret = -EINVAL;
+ break;
+ }
- ret = q6asm_open_write(prtd->audio_client, compr->codec);
- if (ret < 0) {
- pr_err("%s: Session out open failed\n", __func__);
- return -ENOMEM;
+ if (ret < 0) {
+ pr_err("%s: compressed Session out open failed\n",
+ __func__);
+ return -ENOMEM;
+ }
}
- msm_pcm_routing_reg_phy_stream(soc_prtd->dai_link->be_id,
- prtd->session_id, substream->stream);
ret = q6asm_set_io_mode(prtd->audio_client, ASYNC_IO_MODE);
if (ret < 0) {
pr_err("%s: Set IO mode failed\n", __func__);
return -ENOMEM;
}
-
+ /* Modifying kernel hardware params based on userspace config */
+ if (params_periods(params) > 0 &&
+ (params_periods(params) != runtime->hw.periods_max)) {
+ runtime->hw.periods_max = params_periods(params);
+ }
+ if (params_period_bytes(params) > 0 &&
+ (params_period_bytes(params) != runtime->hw.period_bytes_min)) {
+ runtime->hw.period_bytes_min = params_period_bytes(params);
+ }
+ runtime->hw.buffer_bytes_max =
+ runtime->hw.period_bytes_min * runtime->hw.periods_max;
ret = q6asm_audio_client_buf_alloc_contiguous(dir,
prtd->audio_client,
runtime->hw.period_bytes_min,
@@ -494,13 +794,17 @@
}
buf = prtd->audio_client->port[dir].buf;
- pr_debug("%s:buf = %p\n", __func__, buf);
dma_buf->dev.type = SNDRV_DMA_TYPE_DEV;
dma_buf->dev.dev = substream->pcm->card->dev;
dma_buf->private_data = NULL;
dma_buf->area = buf[0].data;
dma_buf->addr = buf[0].phys;
dma_buf->bytes = runtime->hw.buffer_bytes_max;
+
+ pr_debug("%s: buf[%p]dma_buf->area[%p]dma_buf->addr[%p]\n"
+ "dma_buf->bytes[%d]\n", __func__,
+ (void *)buf, (void *)dma_buf->area,
+ (void *)dma_buf->addr, dma_buf->bytes);
if (!dma_buf->area)
return -ENOMEM;
@@ -577,16 +881,47 @@
}
return 0;
case SNDRV_PCM_IOCTL1_RESET:
- prtd->cmd_ack = 0;
- rc = q6asm_cmd(prtd->audio_client, CMD_FLUSH);
- if (rc < 0)
- pr_err("%s: flush cmd failed rc=%d\n", __func__, rc);
- rc = wait_event_timeout(the_locks.eos_wait,
- prtd->cmd_ack, 5 * HZ);
- if (rc < 0)
- pr_err("Flush cmd timeout\n");
- prtd->pcm_irq_pos = 0;
+ pr_debug("SNDRV_PCM_IOCTL1_RESET\n");
+ /* Flush only when session is started during CAPTURE,
+ while PLAYBACK has no such restriction. */
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
+ (substream->stream == SNDRV_PCM_STREAM_CAPTURE &&
+ atomic_read(&prtd->start))) {
+ if (atomic_read(&prtd->eos)) {
+ prtd->cmd_ack = 1;
+ wake_up(&the_locks.eos_wait);
+ atomic_set(&prtd->eos, 0);
+ }
+
+ /* A unlikely race condition possible with FLUSH
+ DRAIN if ack is set by flush and reset by drain */
+ prtd->cmd_ack = 0;
+ rc = q6asm_cmd(prtd->audio_client, CMD_FLUSH);
+ if (rc < 0) {
+ pr_err("%s: flush cmd failed rc=%d\n",
+ __func__, rc);
+ return rc;
+ }
+ rc = wait_event_timeout(the_locks.flush_wait,
+ prtd->cmd_ack, 5 * HZ);
+ if (rc < 0)
+ pr_err("Flush cmd timeout\n");
+ prtd->pcm_irq_pos = 0;
+ }
break;
+ case SNDRV_COMPRESS_DRAIN:
+ pr_debug("%s: SNDRV_COMPRESS_DRAIN\n", __func__);
+ atomic_set(&prtd->eos, 1);
+ atomic_set(&prtd->pending_buffer, 0);
+ prtd->cmd_ack = 0;
+ q6asm_cmd_nowait(prtd->audio_client, CMD_EOS);
+ /* Wait indefinitely for DRAIN. Flush can also signal this*/
+ rc = wait_event_interruptible(the_locks.eos_wait,
+ prtd->cmd_ack);
+ if (rc < 0)
+ pr_err("EOS cmd interrupted\n");
+ pr_debug("%s: SNDRV_COMPRESS_DRAIN out of wait\n", __func__);
+ return 0;
default:
break;
}
@@ -658,6 +993,7 @@
init_waitqueue_head(&the_locks.eos_wait);
init_waitqueue_head(&the_locks.write_wait);
init_waitqueue_head(&the_locks.read_wait);
+ init_waitqueue_head(&the_locks.flush_wait);
return platform_driver_register(&msm_compr_driver);
}
diff --git a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
index 3eab972..a6cdad2 100644
--- a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
@@ -540,6 +540,14 @@
memset(&dai_data->port_config, 0, sizeof(dai_data->port_config));
+ pr_debug("%s: setting bt_fm parameters\n", __func__);
+
+ dai_data->port_config.int_bt_fm.bt_fm_cfg_minor_version =
+ AFE_API_VERSION_INTERNAL_BT_FM_CONFIG;
+ dai_data->port_config.int_bt_fm.num_channels = dai_data->channels;
+ dai_data->port_config.int_bt_fm.sample_rate = dai_data->rate;
+ dai_data->port_config.int_bt_fm.bit_width = 16;
+
return 0;
}
@@ -805,6 +813,36 @@
return 0;
}
+static struct snd_soc_dai_driver msm_dai_q6_afe_rx_dai = {
+ .playback = {
+ .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
+ SNDRV_PCM_RATE_16000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .channels_min = 1,
+ .channels_max = 2,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ .ops = &msm_dai_q6_ops,
+ .probe = msm_dai_q6_dai_probe,
+ .remove = msm_dai_q6_dai_remove,
+};
+
+static struct snd_soc_dai_driver msm_dai_q6_afe_tx_dai = {
+ .capture = {
+ .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
+ SNDRV_PCM_RATE_16000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .channels_min = 1,
+ .channels_max = 4,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ .ops = &msm_dai_q6_ops,
+ .probe = msm_dai_q6_dai_probe,
+ .remove = msm_dai_q6_dai_remove,
+};
+
static struct snd_soc_dai_driver msm_dai_q6_slimbus_1_rx_dai = {
.playback = {
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
@@ -833,6 +871,34 @@
.remove = msm_dai_q6_dai_remove,
};
+static struct snd_soc_dai_driver msm_dai_q6_bt_sco_rx_dai = {
+ .playback = {
+ .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .channels_min = 1,
+ .channels_max = 1,
+ .rate_max = 16000,
+ .rate_min = 8000,
+ },
+ .ops = &msm_dai_q6_ops,
+ .probe = msm_dai_q6_dai_probe,
+ .remove = msm_dai_q6_dai_remove,
+};
+
+static struct snd_soc_dai_driver msm_dai_q6_bt_sco_tx_dai = {
+ .capture = {
+ .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .channels_min = 1,
+ .channels_max = 1,
+ .rate_max = 16000,
+ .rate_min = 8000,
+ },
+ .ops = &msm_dai_q6_ops,
+ .probe = msm_dai_q6_dai_probe,
+ .remove = msm_dai_q6_dai_remove,
+};
+
static int __devinit msm_auxpcm_dev_probe(struct platform_device *pdev)
{
int id;
@@ -1084,6 +1150,22 @@
rc = snd_soc_register_dai(&pdev->dev,
&msm_dai_q6_slimbus_1_tx_dai);
break;
+ case INT_BT_SCO_RX:
+ rc = snd_soc_register_dai(&pdev->dev,
+ &msm_dai_q6_bt_sco_rx_dai);
+ break;
+ case INT_BT_SCO_TX:
+ rc = snd_soc_register_dai(&pdev->dev,
+ &msm_dai_q6_bt_sco_tx_dai);
+ break;
+ case RT_PROXY_DAI_001_RX:
+ case RT_PROXY_DAI_002_RX:
+ rc = snd_soc_register_dai(&pdev->dev, &msm_dai_q6_afe_rx_dai);
+ break;
+ case RT_PROXY_DAI_001_TX:
+ case RT_PROXY_DAI_002_TX:
+ rc = snd_soc_register_dai(&pdev->dev, &msm_dai_q6_afe_tx_dai);
+ break;
default:
rc = -ENODEV;
break;
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c
index 4593784..73a04c2 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c
@@ -29,6 +29,8 @@
#include <sound/control.h>
#include <sound/q6adm-v2.h>
#include <asm/dma.h>
+#include <linux/memory_alloc.h>
+#include <mach/msm_subsystem_map.h>
#include "msm-pcm-afe-v2.h"
#define MIN_PERIOD_SIZE (128 * 2)
@@ -63,6 +65,11 @@
struct snd_pcm_substream *substream = prtd->substream;
struct snd_pcm_runtime *runtime = substream->runtime;
u32 mem_map_handle = 0;
+
+ mem_map_handle = afe_req_mmap_handle();
+ if (!mem_map_handle)
+ pr_err("%s: mem_map_handle is NULL\n", __func__);
+
if (prtd->start) {
pr_debug("sending frame to DSP: poll_time: %d\n",
prtd->poll_time);
@@ -89,10 +96,15 @@
struct snd_pcm_substream *substream = prtd->substream;
struct snd_pcm_runtime *runtime = substream->runtime;
u32 mem_map_handle = 0;
+
+ mem_map_handle = afe_req_mmap_handle();
+ if (!mem_map_handle)
+ pr_err("%s: mem_map_handle is NULL\n", __func__);
+
if (prtd->start) {
if (prtd->dsp_cnt == runtime->periods)
prtd->dsp_cnt = 0;
- pr_err("%s: mem_map_handle 0x%x\n", __func__, mem_map_handle);
+ pr_debug("%s: mem_map_handle 0x%x\n", __func__, mem_map_handle);
afe_rt_proxy_port_read(
(prtd->dma_addr + (prtd->dsp_cnt
* snd_pcm_lib_period_bytes(prtd->substream))), mem_map_handle,
@@ -137,9 +149,6 @@
runtime->channels * 2)));
pr_debug("prtd->poll_time: %d",
prtd->poll_time);
- hrtimer_start(&prtd->hrt,
- ns_to_ktime(0),
- HRTIMER_MODE_REL);
break;
}
case AFE_EVENT_RTPORT_STOP:
@@ -203,9 +212,6 @@
snd_pcm_lib_period_bytes(prtd->substream)
* 1000 * 1000)/(runtime->rate
* runtime->channels * 2)));
- hrtimer_start(&prtd->hrt,
- ns_to_ktime(0),
- HRTIMER_MODE_REL);
pr_debug("prtd->poll_time : %d", prtd->poll_time);
break;
}
@@ -321,13 +327,21 @@
runtime->hw = msm_afe_hardware;
prtd->substream = substream;
runtime->private_data = prtd;
- mutex_unlock(&prtd->lock);
+ prtd->audio_client = q6afe_audio_client_alloc(prtd);
+ if (!prtd->audio_client) {
+ pr_debug("%s: Could not allocate memory\n", __func__);
+ kfree(prtd);
+ mutex_unlock(&prtd->lock);
+ return -ENOMEM;
+ }
+
hrtimer_init(&prtd->hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
prtd->hrt.function = afe_hrtimer_callback;
else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
prtd->hrt.function = afe_hrtimer_rec_callback;
+ mutex_unlock(&prtd->lock);
ret = snd_pcm_hw_constraint_list(runtime, 0,
SNDRV_PCM_HW_PARAM_RATE,
&constraints_sample_rates);
@@ -350,6 +364,7 @@
struct pcm_afe_info *prtd;
struct snd_soc_pcm_runtime *rtd = NULL;
struct snd_soc_dai *dai = NULL;
+ int dir = IN;
int ret = 0;
pr_debug("%s\n", __func__);
@@ -365,17 +380,19 @@
mutex_lock(&prtd->lock);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ dir = IN;
ret = afe_unregister_get_events(dai->id);
if (ret < 0)
pr_err("AFE unregister for events failed\n");
} else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+ dir = OUT;
ret = afe_unregister_get_events(dai->id);
if (ret < 0)
pr_err("AFE unregister for events failed\n");
}
hrtimer_cancel(&prtd->hrt);
- rc = afe_cmd_memory_unmap(runtime->dma_addr);
+ rc = afe_cmd_memory_unmap(afe_req_mmap_handle());
if (rc < 0)
pr_err("AFE memory unmap failed\n");
@@ -384,15 +401,14 @@
if (dma_buf == NULL) {
pr_debug("dma_buf is NULL\n");
goto done;
- }
- if (dma_buf->area != NULL) {
- dma_free_coherent(substream->pcm->card->dev,
- runtime->hw.buffer_bytes_max, dma_buf->area,
- dma_buf->addr);
- dma_buf->area = NULL;
}
+
+ if (dma_buf->area)
+ dma_buf->area = NULL;
+ q6afe_audio_client_buf_free_contiguous(dir, prtd->audio_client);
done:
pr_debug("%s: dai->id =%x\n", __func__, dai->id);
+ q6afe_audio_client_free(prtd->audio_client);
mutex_unlock(&prtd->lock);
prtd->prepared--;
kfree(prtd);
@@ -420,14 +436,21 @@
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct pcm_afe_info *prtd = runtime->private_data;
+ int result = 0;
pr_debug("%s\n", __func__);
prtd->mmap_flag = 1;
- dma_mmap_coherent(substream->pcm->card->dev, vma,
- runtime->dma_area,
- runtime->dma_addr,
- runtime->dma_bytes);
- return 0;
+ if (runtime->dma_addr && runtime->dma_bytes) {
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ result = remap_pfn_range(vma, vma->vm_start,
+ runtime->dma_addr >> PAGE_SHIFT,
+ runtime->dma_bytes,
+ vma->vm_page_prot);
+ } else {
+ pr_err("Physical address or size of buf is NULL");
+ return -EINVAL;
+ }
+ return result;
}
static int msm_afe_trigger(struct snd_pcm_substream *substream, int cmd)
{
@@ -441,6 +464,8 @@
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
pr_debug("%s: SNDRV_PCM_TRIGGER_START\n", __func__);
prtd->start = 1;
+ hrtimer_start(&prtd->hrt, ns_to_ktime(0),
+ HRTIMER_MODE_REL);
break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
@@ -460,27 +485,45 @@
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_dma_buffer *dma_buf = &substream->dma_buffer;
struct pcm_afe_info *prtd = runtime->private_data;
- int rc;
+ struct afe_audio_buffer *buf;
+ int dir, rc;
pr_debug("%s:\n", __func__);
mutex_lock(&prtd->lock);
-
- dma_buf->dev.type = SNDRV_DMA_TYPE_DEV;
- dma_buf->dev.dev = substream->pcm->card->dev;
- dma_buf->private_data = NULL;
- dma_buf->area = dma_alloc_coherent(dma_buf->dev.dev,
- runtime->hw.buffer_bytes_max,
- &dma_buf->addr, GFP_KERNEL);
-
- pr_debug("%s: dma_buf->area: 0x%p, dma_buf->addr: 0x%x", __func__,
- (unsigned int *) dma_buf->area, dma_buf->addr);
- if (!dma_buf->area) {
- pr_err("%s:MSM AFE memory allocation failed\n", __func__);
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ dir = IN;
+ else
+ dir = OUT;
+ rc = q6afe_audio_client_buf_alloc_contiguous(dir,
+ prtd->audio_client,
+ runtime->hw.period_bytes_min,
+ runtime->hw.periods_max);
+ if (rc < 0) {
+ pr_err("Audio Start: Buffer Allocation failed rc = %d\n", rc);
mutex_unlock(&prtd->lock);
return -ENOMEM;
}
+ buf = prtd->audio_client->port[dir].buf;
+
+ if (buf == NULL || buf[0].data == NULL) {
+ mutex_unlock(&prtd->lock);
+ return -ENOMEM;
+ }
+
+ pr_debug("%s:buf = %p\n", __func__, buf);
+ dma_buf->dev.type = SNDRV_DMA_TYPE_DEV;
+ dma_buf->dev.dev = substream->pcm->card->dev;
+ dma_buf->private_data = NULL;
+ dma_buf->area = buf[0].data;
+ dma_buf->addr = buf[0].phys;
dma_buf->bytes = runtime->hw.buffer_bytes_max;
+ if (!dma_buf->area) {
+ pr_err("%s:MSM AFE physical memory allocation failed\n",
+ __func__);
+ mutex_unlock(&prtd->lock);
+ return -ENOMEM;
+ }
memset(dma_buf->area, 0, runtime->hw.buffer_bytes_max);
prtd->dma_addr = (u32) dma_buf->addr;
@@ -542,6 +585,9 @@
static __devinit int msm_afe_probe(struct platform_device *pdev)
{
+ if (pdev->dev.of_node)
+ dev_set_name(&pdev->dev, "%s", "msm-pcm-afe");
+
pr_debug("%s: dev name %s\n", __func__, dev_name(&pdev->dev));
return snd_soc_register_platform(&pdev->dev,
&msm_soc_platform);
@@ -553,11 +599,17 @@
snd_soc_unregister_platform(&pdev->dev);
return 0;
}
+static const struct of_device_id msm_pcm_afe_dt_match[] = {
+ {.compatible = "qcom,msm-pcm-afe"},
+ {}
+};
+MODULE_DEVICE_TABLE(of, msm_pcm_afe_dt_match);
static struct platform_driver msm_afe_driver = {
.driver = {
.name = "msm-pcm-afe",
.owner = THIS_MODULE,
+ .of_match_table = msm_pcm_afe_dt_match,
},
.probe = msm_afe_probe,
.remove = __devexit_p(msm_afe_remove),
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.h b/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.h
index 20d6377..446409f 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.h
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.h
@@ -30,6 +30,7 @@
int prepared;
struct hrtimer hrt;
int poll_time;
+ struct afe_audio_client *audio_client;
};
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.h b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.h
index 22bf0cc..e25d356 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.h
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.h
@@ -49,6 +49,7 @@
wait_queue_head_t write_wait;
wait_queue_head_t eos_wait;
wait_queue_head_t enable_wait;
+ wait_queue_head_t flush_wait;
};
struct msm_audio {
@@ -76,10 +77,19 @@
atomic_t out_count;
atomic_t in_count;
atomic_t out_needed;
+ atomic_t eos;
int out_head;
int periods;
int mmap_flag;
atomic_t pending_buffer;
};
+struct output_meta_data_st {
+ uint32_t meta_data_length;
+ uint32_t frame_size;
+ uint32_t timestamp_lsw;
+ uint32_t timestamp_msw;
+ uint32_t reserved[12];
+};
+
#endif /*_MSM_PCM_H*/
diff --git a/sound/soc/msm/qdsp6v2/q6afe.c b/sound/soc/msm/qdsp6v2/q6afe.c
index 0b25545..f0465a5 100644
--- a/sound/soc/msm/qdsp6v2/q6afe.c
+++ b/sound/soc/msm/qdsp6v2/q6afe.c
@@ -18,6 +18,7 @@
#include <linux/wait.h>
#include <linux/jiffies.h>
#include <linux/sched.h>
+#include <linux/msm_ion.h>
#include <mach/qdsp6v2/audio_acdb.h>
#include <sound/apr_audio-v2.h>
#include <sound/q6afe-v2.h>
@@ -37,6 +38,7 @@
uint32_t token, uint32_t *payload, void *priv);
void *tx_private_data;
void *rx_private_data;
+ uint32_t mmap_handle;
};
static struct afe_ctl this_afe;
@@ -107,6 +109,13 @@
payload[0]);
break;
}
+ } else if (data->opcode ==
+ AFE_SERVICE_CMDRSP_SHARED_MEM_MAP_REGIONS) {
+ pr_debug("%s: mmap_handle: 0x%x\n",
+ __func__, payload[0]);
+ this_afe.mmap_handle = (uint32_t)payload[0];
+ atomic_set(&this_afe.state, 0);
+ wake_up(&this_afe.wait[data->token]);
} else if (data->opcode == AFE_EVENT_RT_PROXY_PORT_STATUS) {
port_id = (uint16_t)(0x0000FFFF & payload[0]);
}
@@ -266,17 +275,21 @@
ret = -EINVAL;
return ret;
}
- index = q6audio_get_port_index(port_id);
- if (q6audio_validate_port(port_id) < 0)
- return -EINVAL;
if ((port_id == RT_PROXY_DAI_001_RX) ||
(port_id == RT_PROXY_DAI_002_TX))
- return -EINVAL;
+ return 0;
if ((port_id == RT_PROXY_DAI_002_RX) ||
(port_id == RT_PROXY_DAI_001_TX))
port_id = VIRTUAL_ID_TO_PORTID(port_id);
+ pr_debug("%s: port id: %d\n", __func__, port_id);
+ index = q6audio_get_port_index(port_id);
+ if (q6audio_validate_port(port_id) < 0) {
+ pr_err("%s: port id: %d\n", __func__, port_id);
+ return -EINVAL;
+ }
+
ret = afe_q6_interface_prepare();
if (IS_ERR_VALUE(ret))
return ret;
@@ -325,6 +338,14 @@
case SLIMBUS_4_TX:
cfg_type = AFE_PARAM_ID_SLIMBUS_CONFIG;
break;
+ case RT_PROXY_PORT_001_RX:
+ case RT_PROXY_PORT_001_TX:
+ cfg_type = AFE_PARAM_ID_RT_PROXY_CONFIG;
+ break;
+ case INT_BT_SCO_RX:
+ case INT_BT_SCO_TX:
+ cfg_type = AFE_PARAM_ID_INTERNAL_BT_FM_CONFIG;
+ break;
default:
pr_err("%s: Invalid port id 0x%x\n", __func__, port_id);
ret = -EINVAL;
@@ -904,7 +925,133 @@
return 0;
}
-/*bharath, memory map handle needs to be stored by AFE client */
+uint32_t afe_req_mmap_handle(void)
+{
+ return this_afe.mmap_handle;
+}
+
+struct afe_audio_client *q6afe_audio_client_alloc(void *priv)
+{
+ struct afe_audio_client *ac;
+ int lcnt = 0;
+
+ ac = kzalloc(sizeof(struct afe_audio_client), GFP_KERNEL);
+ if (!ac) {
+ pr_err("%s: cannot allocate audio client for afe\n", __func__);
+ return NULL;
+ }
+ ac->priv = priv;
+
+ init_waitqueue_head(&ac->cmd_wait);
+ INIT_LIST_HEAD(&ac->port[0].mem_map_handle);
+ INIT_LIST_HEAD(&ac->port[1].mem_map_handle);
+ pr_debug("%s: mem_map_handle list init'ed\n", __func__);
+ mutex_init(&ac->cmd_lock);
+ for (lcnt = 0; lcnt <= OUT; lcnt++) {
+ mutex_init(&ac->port[lcnt].lock);
+ spin_lock_init(&ac->port[lcnt].dsp_lock);
+ }
+ atomic_set(&ac->cmd_state, 0);
+
+ return ac;
+}
+
+int q6afe_audio_client_buf_alloc_contiguous(unsigned int dir,
+ struct afe_audio_client *ac,
+ unsigned int bufsz,
+ unsigned int bufcnt)
+{
+ int cnt = 0;
+ int rc = 0;
+ struct afe_audio_buffer *buf;
+ int len;
+
+ if (!(ac) || ((dir != IN) && (dir != OUT)))
+ return -EINVAL;
+
+ pr_debug("%s: bufsz[%d]bufcnt[%d]\n",
+ __func__,
+ bufsz, bufcnt);
+
+ if (ac->port[dir].buf) {
+ pr_debug("%s: buffer already allocated\n", __func__);
+ return 0;
+ }
+ mutex_lock(&ac->cmd_lock);
+ buf = kzalloc(((sizeof(struct afe_audio_buffer))*bufcnt),
+ GFP_KERNEL);
+
+ if (!buf) {
+ mutex_unlock(&ac->cmd_lock);
+ goto fail;
+ }
+
+ ac->port[dir].buf = buf;
+
+ buf[0].client = msm_ion_client_create(UINT_MAX, "audio_client");
+ if (IS_ERR_OR_NULL((void *)buf[0].client)) {
+ pr_err("%s: ION create client for AUDIO failed\n", __func__);
+ goto fail;
+ }
+ buf[0].handle = ion_alloc(buf[0].client, bufsz * bufcnt, SZ_4K,
+ (0x1 << ION_AUDIO_HEAP_ID), 0);
+ if (IS_ERR_OR_NULL((void *) buf[0].handle)) {
+ pr_err("%s: ION memory allocation for AUDIO failed\n",
+ __func__);
+ goto fail;
+ }
+
+ rc = ion_phys(buf[0].client, buf[0].handle,
+ (ion_phys_addr_t *)&buf[0].phys, (size_t *)&len);
+ if (rc) {
+ pr_err("%s: ION Get Physical for AUDIO failed, rc = %d\n",
+ __func__, rc);
+ goto fail;
+ }
+
+ buf[0].data = ion_map_kernel(buf[0].client, buf[0].handle);
+ if (IS_ERR_OR_NULL((void *) buf[0].data)) {
+ pr_err("%s: ION memory mapping for AUDIO failed\n", __func__);
+ goto fail;
+ }
+ memset((void *)buf[0].data, 0, (bufsz * bufcnt));
+ if (!buf[0].data) {
+ pr_err("%s:invalid vaddr, iomap failed\n", __func__);
+ mutex_unlock(&ac->cmd_lock);
+ goto fail;
+ }
+
+ buf[0].used = dir ^ 1;
+ buf[0].size = bufsz;
+ buf[0].actual_size = bufsz;
+ cnt = 1;
+ while (cnt < bufcnt) {
+ if (bufsz > 0) {
+ buf[cnt].data = buf[0].data + (cnt * bufsz);
+ buf[cnt].phys = buf[0].phys + (cnt * bufsz);
+ if (!buf[cnt].data) {
+ pr_err("%s Buf alloc failed\n",
+ __func__);
+ mutex_unlock(&ac->cmd_lock);
+ goto fail;
+ }
+ buf[cnt].used = dir ^ 1;
+ buf[cnt].size = bufsz;
+ buf[cnt].actual_size = bufsz;
+ pr_debug("%s data[%p]phys[%p][%p]\n", __func__,
+ (void *)buf[cnt].data,
+ (void *)buf[cnt].phys,
+ (void *)&buf[cnt].phys);
+ }
+ cnt++;
+ }
+ ac->port[dir].max_buf_cnt = cnt;
+ mutex_unlock(&ac->cmd_lock);
+ return 0;
+fail:
+ q6afe_audio_client_buf_free_contiguous(dir, ac);
+ return -EINVAL;
+}
int afe_cmd_memory_map(u32 dma_addr_p, u32 dma_buf_sz)
{
int ret = 0;
@@ -941,7 +1088,7 @@
mmap_region_cmd;
mregion->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- mregion->hdr.pkt_size = sizeof(mregion);
+ mregion->hdr.pkt_size = cmd_size;
mregion->hdr.src_port = 0;
mregion->hdr.dest_port = 0;
mregion->hdr.token = 0;
@@ -961,13 +1108,15 @@
mregion_pl->shm_addr_msw = 0x00;
mregion_pl->mem_size_bytes = dma_buf_sz;
+ pr_debug("%s: dma_addr_p 0x%x , size %d\n", __func__,
+ dma_addr_p, dma_buf_sz);
atomic_set(&this_afe.state, 1);
ret = apr_send_pkt(this_afe.apr, (uint32_t *) mmap_region_cmd);
if (ret < 0) {
pr_err("%s: AFE memory map cmd failed %d\n",
__func__, ret);
ret = -EINVAL;
- return ret;
+ goto fail_cmd;
}
ret = wait_event_timeout(this_afe.wait[index],
@@ -976,10 +1125,13 @@
if (!ret) {
pr_err("%s: wait_event timeout\n", __func__);
ret = -EINVAL;
- return ret;
+ goto fail_cmd;
}
-
+ pr_debug("%s: mmap handle 0x%x\n", __func__, this_afe.mmap_handle);
return 0;
+fail_cmd:
+ kfree(mmap_region_cmd);
+ return ret;
}
int afe_cmd_memory_map_nowait(int port_id, u32 dma_addr_p, u32 dma_buf_sz)
@@ -1047,6 +1199,60 @@
}
return 0;
}
+int q6afe_audio_client_buf_free_contiguous(unsigned int dir,
+ struct afe_audio_client *ac)
+{
+ struct afe_audio_port_data *port;
+ int cnt = 0;
+ mutex_lock(&ac->cmd_lock);
+ port = &ac->port[dir];
+ if (!port->buf) {
+ mutex_unlock(&ac->cmd_lock);
+ return 0;
+ }
+ cnt = port->max_buf_cnt - 1;
+
+ if (port->buf[0].data) {
+ ion_unmap_kernel(port->buf[0].client, port->buf[0].handle);
+ ion_free(port->buf[0].client, port->buf[0].handle);
+ ion_client_destroy(port->buf[0].client);
+ pr_debug("%s:data[%p]phys[%p][%p] , client[%p] handle[%p]\n",
+ __func__,
+ (void *)port->buf[0].data,
+ (void *)port->buf[0].phys,
+ (void *)&port->buf[0].phys,
+ (void *)port->buf[0].client,
+ (void *)port->buf[0].handle);
+ }
+
+ while (cnt >= 0) {
+ port->buf[cnt].data = NULL;
+ port->buf[cnt].phys = 0;
+ cnt--;
+ }
+ port->max_buf_cnt = 0;
+ kfree(port->buf);
+ port->buf = NULL;
+ mutex_unlock(&ac->cmd_lock);
+ return 0;
+}
+
+void q6afe_audio_client_free(struct afe_audio_client *ac)
+{
+ int loopcnt;
+ struct afe_audio_port_data *port;
+ if (!ac)
+ return;
+ for (loopcnt = 0; loopcnt <= OUT; loopcnt++) {
+ port = &ac->port[loopcnt];
+ if (!port->buf)
+ continue;
+ pr_debug("%s:loopcnt = %d\n", __func__, loopcnt);
+ q6afe_audio_client_buf_free_contiguous(loopcnt, ac);
+ }
+ kfree(ac);
+ return;
+}
int afe_cmd_memory_unmap(u32 mem_map_handle)
{
@@ -1143,7 +1349,7 @@
int ret = 0;
struct afe_service_cmd_register_rt_port_driver rtproxy;
- pr_debug("%s:\n", __func__);
+ pr_debug("%s: port_id: %d\n", __func__, port_id);
if (this_afe.apr == NULL) {
this_afe.apr = apr_register("ADSP", "AFE", afe_callback,
@@ -1206,9 +1412,6 @@
return ret;
}
}
- index = q6audio_get_port_index(port_id);
- if (q6audio_validate_port(port_id) < 0)
- return -EINVAL;
if ((port_id == RT_PROXY_DAI_002_RX) ||
(port_id == RT_PROXY_DAI_001_TX))
@@ -1216,6 +1419,10 @@
else
return -EINVAL;
+ index = q6audio_get_port_index(port_id);
+ if (q6audio_validate_port(port_id) < 0)
+ return -EINVAL;
+
rtproxy.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
rtproxy.hdr.pkt_size = sizeof(rtproxy);
@@ -1318,6 +1525,7 @@
afecmd_rd.buffer_address_lsw = (uint32_t)buf_addr_p;
afecmd_rd.buffer_address_msw = 0x00;
afecmd_rd.available_bytes = bytes;
+ afecmd_rd.mem_map_handle = mem_map_handle;
ret = apr_send_pkt(this_afe.apr, (uint32_t *) &afecmd_rd);
if (ret < 0) {
@@ -1665,11 +1873,11 @@
}
pr_debug("%s: port_id=%d\n", __func__, port_id);
+ port_id = q6audio_convert_virtual_to_portid(port_id);
index = q6audio_get_port_index(port_id);
if (q6audio_validate_port(port_id) < 0)
return -EINVAL;
- port_id = q6audio_convert_virtual_to_portid(port_id);
stop.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
@@ -1708,6 +1916,7 @@
atomic_set(&this_afe.state, 0);
atomic_set(&this_afe.status, 0);
this_afe.apr = NULL;
+ this_afe.mmap_handle = 0;
for (i = 0; i < AFE_MAX_PORTS; i++)
init_waitqueue_head(&this_afe.wait[i]);
diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c
index 714b2ce..9f98c1b 100644
--- a/sound/soc/msm/qdsp6v2/q6asm.c
+++ b/sound/soc/msm/qdsp6v2/q6asm.c
@@ -632,7 +632,7 @@
}
buf[cnt].handle = ion_alloc
(buf[cnt].client, bufsz, SZ_4K,
- (0x1 << ION_AUDIO_HEAP_ID));
+ (0x1 << ION_AUDIO_HEAP_ID), 0);
if (IS_ERR_OR_NULL((void *)
buf[cnt].handle)) {
pr_err("%s: ION memory allocation for AUDIO failed\n",
@@ -652,8 +652,7 @@
}
buf[cnt].data = ion_map_kernel
- (buf[cnt].client, buf[cnt].handle,
- 0);
+ (buf[cnt].client, buf[cnt].handle);
if (IS_ERR_OR_NULL((void *)
buf[cnt].data)) {
pr_err("%s: ION memory mapping for AUDIO failed\n",
@@ -729,7 +728,7 @@
goto fail;
}
buf[0].handle = ion_alloc(buf[0].client, bufsz * bufcnt, SZ_4K,
- (0x1 << ION_AUDIO_HEAP_ID));
+ (0x1 << ION_AUDIO_HEAP_ID), 0);
if (IS_ERR_OR_NULL((void *) buf[0].handle)) {
pr_err("%s: ION memory allocation for AUDIO failed\n",
__func__);
@@ -744,7 +743,7 @@
goto fail;
}
- buf[0].data = ion_map_kernel(buf[0].client, buf[0].handle, 0);
+ buf[0].data = ion_map_kernel(buf[0].client, buf[0].handle);
if (IS_ERR_OR_NULL((void *) buf[0].data)) {
pr_err("%s: ION memory mapping for AUDIO failed\n", __func__);
goto fail;
diff --git a/sound/soc/msm/qdsp6v2/q6voice.c b/sound/soc/msm/qdsp6v2/q6voice.c
index 0a057fa..1f6dbf1 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.c
+++ b/sound/soc/msm/qdsp6v2/q6voice.c
@@ -3453,7 +3453,7 @@
v->shmem_info.sh_buf.handle = ion_alloc(v->shmem_info.sh_buf.client,
bufsz * bufcnt, SZ_4K,
- (0x1 << ION_AUDIO_HEAP_ID));
+ (0x1 << ION_AUDIO_HEAP_ID), 0);
if (IS_ERR_OR_NULL((void *)v->shmem_info.sh_buf.handle)) {
pr_err("%s: ION memory allocation failed\n",
__func__);
@@ -3469,7 +3469,7 @@
}
mem_addr = ion_map_kernel(v->shmem_info.sh_buf.client,
- v->shmem_info.sh_buf.handle, 0);
+ v->shmem_info.sh_buf.handle);
if (IS_ERR_OR_NULL(mem_addr)) {
pr_err("%s: ION memory mapping failed\n", __func__);
goto err_ion_handle;
@@ -3521,7 +3521,7 @@
v->shmem_info.memtbl.handle = ion_alloc(v->shmem_info.memtbl.client,
sizeof(struct vss_imemory_table_t), SZ_4K,
- (0x1 << ION_AUDIO_HEAP_ID));
+ (0x1 << ION_AUDIO_HEAP_ID), 0);
if (IS_ERR_OR_NULL((void *) v->shmem_info.memtbl.handle)) {
pr_err("%s: ION memory allocation for memtbl failed\n",
__func__);
@@ -3537,8 +3537,7 @@
}
v->shmem_info.memtbl.data = ion_map_kernel(v->shmem_info.memtbl.client,
- v->shmem_info.memtbl.handle,
- 0);
+ v->shmem_info.memtbl.handle);
if (IS_ERR_OR_NULL((void *)v->shmem_info.memtbl.data)) {
pr_err("%s: ION memory mapping for memtbl failed\n",
__func__);
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 2d2b333..4c6a5a4 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -308,7 +308,7 @@
{
static char buf[32];
- if (type == PERF_TYPE_RAW) {
+ if (!pmu_name && type == PERF_TYPE_RAW) {
sprintf(buf, "raw 0x%" PRIx64, config);
return buf;
}
@@ -684,6 +684,7 @@
{
struct perf_event_attr attr;
struct perf_pmu *pmu;
+ char *ev_name;
pmu = perf_pmu__find(name);
if (!pmu)
@@ -700,7 +701,9 @@
if (perf_pmu__config(pmu, &attr, head_config))
return -EINVAL;
- return add_event(list, idx, &attr, pmu->name);
+ ev_name = (char *) __event_name(attr.type, attr.config, pmu->name);
+
+ return add_event(list, idx, &attr, ev_name);
}
void parse_events_update_lists(struct list_head *list_event,