Merge "mfd: wcd9xxx: Continue to probe codec without interrupt" into msm-3.4
diff --git a/Documentation/devicetree/bindings/arm/msm/bam_dmux.txt b/Documentation/devicetree/bindings/arm/msm/bam_dmux.txt
new file mode 100644
index 0000000..d82284d
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/msm/bam_dmux.txt
@@ -0,0 +1,14 @@
+Qualcomm BAM Data Multiplexer Driver
+
+Required properties:
+- compatible : should be "qcom,bam_dmux"
+- reg : the location and size of the BAM hardware
+- interrupts : the BAM hardware to apps processor interrupt line
+
+Example:
+
+ qcom,bam_dmux@fc834000 {
+ compatible = "qcom,bam_dmux";
+ reg = <0xfc834000 0x7000>;
+ interrupts = <0 29 1>;
+ };
diff --git a/Documentation/devicetree/bindings/usb/msm-hsusb.txt b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
index 62258ca..43e87a8 100644
--- a/Documentation/devicetree/bindings/usb/msm-hsusb.txt
+++ b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
@@ -95,6 +95,10 @@
- qcom,descriptor-fifo-offset: descriptor fifo offset address
- qcom,descriptor-fifo-size: descriptor fifo size
+Optional properties :
+- qcom,ignore-core-reset-ack: If present then BAM ignores ACK from USB core
+ while performing PIPE RESET
+
Example USB BAM controller device node:
qcom,usbbam@f9304000 {
@@ -109,6 +113,7 @@
qcom,usb-total-bam-num = <2>;
qcom,usb-bam-num-pipes = <16>;
qcom,usb-base-address = <0xf9200000>;
+ qcom,ignore-core-reset-ack;
qcom,pipe1 {
label = "usb-to-peri-qdss-dwc3";
diff --git a/Documentation/devicetree/bindings/usb/msm-ssusb.txt b/Documentation/devicetree/bindings/usb/msm-ssusb.txt
index a2b7dfc..bff3732 100644
--- a/Documentation/devicetree/bindings/usb/msm-ssusb.txt
+++ b/Documentation/devicetree/bindings/usb/msm-ssusb.txt
@@ -3,6 +3,8 @@
Required properties :
- compatible : should be "qcom,dwc-usb3-msm"
- reg : offset and length of the register set in the memory map
+ offset and length of the TCSR register for routing USB
+ signals to either picoPHY0 or picoPHY1.
- interrupts: IRQ lines used by this controller
- interrupt-names : Required interrupt resource entries are:
"irq" : Interrupt for DWC3 core
@@ -18,7 +20,8 @@
Example MSM USB3.0 controller device node :
usb@f9200000 {
compatible = "qcom,dwc-usb3-msm";
- reg = <0xF9200000 0xFA000>;
+ reg = <0xF9200000 0xFA000>,
+ <0xFD4AB000 0x4>;
interrupts = <0 131 0 0 179 0>;
interrupt-names = "irq", "otg_irq";
SSUSB_VDDCX-supply = <&pm8841_s2>;
diff --git a/arch/arm/boot/dts/dsi-panel-toshiba-720p-video.dtsi b/arch/arm/boot/dts/dsi-panel-toshiba-720p-video.dtsi
new file mode 100644
index 0000000..1f7e488
--- /dev/null
+++ b/arch/arm/boot/dts/dsi-panel-toshiba-720p-video.dtsi
@@ -0,0 +1,119 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+&mdss_dsi {
+
+ qcom,mdss_dsi_toshiba_720p_video {
+ compatible = "qcom,mdss-dsi-panel";
+ label = "toshiba 720p video mode dsi panel";
+ status = "disable";
+ qcom,enable-gpio = <&msmgpio 58 0>;
+ qcom,rst-gpio = <&pm8941_gpios 19 0>;
+ qcom,mdss-pan-res = <720 1280>;
+ qcom,mdss-pan-bpp = <24>;
+ qcom,mdss-pan-porch-values = <32 12 144 3 4 9>;
+ qcom,mdss-pan-underflow-clr = <0xff>;
+ qcom,mdss-pan-bl-ctrl = "bl_ctrl_wled";
+ qcom,mdss-pan-bl-levels = <1 255>;
+ qcom,mdss-pan-dsi-mode = <0>;
+ qcom,mdss-pan-dsi-h-pulse-mode = <0>;
+ qcom,mdss-pan-dsi-h-power-stop = <0 0 0>;
+ qcom,mdss-pan-dsi-bllp-power-stop = <1 1>;
+ qcom,mdss-pan-dsi-traffic-mode = <1>;
+ qcom,mdss-pan-dsi-dst-format = <3>;
+ qcom,mdss-pan-dsi-vc = <0>;
+ qcom,mdss-pan-dsi-rgb-swap = <0>;
+ qcom,mdss-pan-dsi-data-lanes = <1 1 1 1>;
+ qcom,mdss-pan-dsi-t-clk = <0x1b 0x04>;
+ qcom,mdss-pan-dsi-stream = <0>;
+ qcom,mdss-pan-dsi-mdp-tr = <0x0>;
+ qcom,mdss-pan-dsi-dma-tr = <0x04>;
+ qcom,mdss-pan-frame-rate = <60>;
+ qcom,panel-phy-regulatorSettings = [03 01 01 00 /* Regualotor settings */
+ 20 00 01 00];
+ qcom,panel-phy-timingSettings = [69 29 1f 00 55 55
+ 19 2a 2a 03 04 00];
+ qcom,panel-phy-strengthCtrl = [77 06];
+ qcom,panel-phy-bistCtrl = [00 00 01 ff /* BIST Ctrl settings */
+ 00 00];
+ qcom,panel-phy-laneConfig = [05 c2 00 00 00 00 00 01 75 /* lane0 config */
+ 05 c2 00 00 00 00 00 01 75 /* lane1 config */
+ 05 c2 00 00 00 00 00 01 75 /* lane2 config */
+ 05 c2 00 00 00 00 00 01 75 /* lane3 config */
+ 00 c2 00 00 00 00 00 01 97]; /* Clk ln config */
+
+ qcom,panel-on-cmds = [23 01 00 00 0a 02 b0 00
+ 23 01 00 00 0a 02 b2 00
+ 23 01 00 00 0a 02 b3 0c
+ 23 01 00 00 0a 02 b4 02
+ 29 01 00 00 00 06
+ c0 40 02 7f c8 08
+ 29 01 00 00 00 10
+ c1 00 a8 00 00 00
+ 00 00 9d 08 27 00
+ 00 00 00 00
+ 29 01 00 00 00 06
+ c2 00 00 09 00 00
+ 23 01 00 00 0a 02 c3 04
+ 29 01 00 00 00 04
+ c4 4d 83 00
+ 29 01 00 00 00 0b
+ c6 12 00 08 71 00
+ 00 00 80 00 04
+ 23 01 00 00 0a 02 c7 22
+ 29 01 00 00 00 05
+ c8 4c 0c 0c 0c
+ 29 01 00 00 00 0e
+ c9 00 40 00 16 32
+ 2e 3a 43 3e 3c 45
+ 79 3f
+ 29 01 00 00 00 0e
+ ca 00 46 1a 23 21
+ 1c 25 31 2d 49 5f
+ 7f 3f
+ 29 01 00 00 00 0e
+ cb 00 4c 20 3a 42
+ 40 47 4b 42 3e 46
+ 7e 3f
+ 29 01 00 00 00 0e
+ cc 00 41 19 21 1d
+ 14 18 1f 1d 25 3f
+ 73 3f
+ 29 01 00 00 00 0e
+ cd 23 79 5a 5f 57
+ 4c 51 51 45 3f 4b
+ 7f 3f
+ 29 01 00 00 00 0e
+ ce 00 40 14 20 1a
+ 0e 0e 13 08 00 05
+ 46 1c
+ 29 01 00 00 00 04
+ d0 6a 64 01
+ 29 01 00 00 00 03 d1 77 d4
+ 23 01 00 00 0a 02 d3 33
+ 29 01 00 00 00 03 d5 0f 0f
+ 29 01 00 00 00 07
+ d8 34 64 23 25 62
+ 32
+ 29 01 00 00 00 0c
+ de 10 7b 11 0a 00
+ 00 00 00 00 00 00
+ 29 01 00 00 00 09
+ fd 04 55 53 00 70
+ ff 10 73
+ 23 01 00 00 0a 02 e2 00
+ 05 01 00 00 78 02 11 00
+ 05 01 00 00 32 02 29 00];
+ qcom,panel-off-cmds = [05 01 00 00 32 02 28 00
+ 05 01 00 00 78 02 10 00];
+ };
+};
diff --git a/arch/arm/boot/dts/msm8974-camera.dtsi b/arch/arm/boot/dts/msm8974-camera.dtsi
index 0375e93..cf4f098 100644
--- a/arch/arm/boot/dts/msm8974-camera.dtsi
+++ b/arch/arm/boot/dts/msm8974-camera.dtsi
@@ -19,6 +19,7 @@
reg = <0xfd8C0000 0x10000>;
reg-names = "server";
};
+
qcom,csiphy@fda0ac00 {
cell-index = <0>;
compatible = "qcom,csiphy";
@@ -27,6 +28,7 @@
interrupts = <0 78 0>;
interrupt-names = "csiphy";
};
+
qcom,csiphy@fda0b000 {
cell-index = <1>;
compatible = "qcom,csiphy";
@@ -35,6 +37,7 @@
interrupts = <0 79 0>;
interrupt-names = "csiphy";
};
+
qcom,csiphy@fda0b400 {
cell-index = <2>;
compatible = "qcom,csiphy";
@@ -43,6 +46,7 @@
interrupts = <0 80 0>;
interrupt-names = "csiphy";
};
+
qcom,csid@fda08000 {
cell-index = <0>;
compatible = "qcom,csid";
@@ -50,7 +54,9 @@
reg-names = "csid";
interrupts = <0 51 0>;
interrupt-names = "csid";
+ mipi_csi_vdd-supply = <&pm8941_l12>;
};
+
qcom,csid@fda08400 {
cell-index = <1>;
compatible = "qcom,csid";
@@ -58,7 +64,9 @@
reg-names = "csid";
interrupts = <0 52 0>;
interrupt-names = "csid";
+ mipi_csi_vdd-supply = <&pm8941_l12>;
};
+
qcom,csid@fda08800 {
cell-index = <2>;
compatible = "qcom,csid";
@@ -66,7 +74,9 @@
reg-names = "csid";
interrupts = <0 53 0>;
interrupt-names = "csid";
+ mipi_csi_vdd-supply = <&pm8941_l12>;
};
+
qcom,csid@fda08C00 {
cell-index = <3>;
compatible = "qcom,csid";
@@ -74,7 +84,9 @@
reg-names = "csid";
interrupts = <0 54 0>;
interrupt-names = "csid";
+ mipi_csi_vdd-supply = <&pm8941_l12>;
};
+
qcom,ispif@fda0A000 {
cell-index = <0>;
compatible = "qcom,ispif";
@@ -83,32 +95,29 @@
interrupts = <0 55 0>;
interrupt-names = "ispif";
};
- qcom,cci@fda0C000 {
- cell-index = <0>;
- compatible = "qcom,cci";
- reg = <0xfda0C000 0x1000>;
- reg-names = "cci";
- interrupts = <0 50 0>;
- interrupt-names = "cci";
- };
+
qcom,vfe@fda10000 {
cell-index = <0>;
compatible = "qcom,vfe40";
- reg = <0xfda10000 0x1000>;
- reg-names = "vfe";
+ reg = <0xfda10000 0x1000>,
+ <0xfda40000 0x200>;
+ reg-names = "vfe", "vfe_vbif";
interrupts = <0 57 0>;
interrupt-names = "vfe";
vdd-supply = <&gdsc_vfe>;
};
+
qcom,vfe@fda14000 {
cell-index = <1>;
compatible = "qcom,vfe40";
- reg = <0xfda14000 0x1000>;
- reg-names = "vfe";
+ reg = <0xfda14000 0x1000>,
+ <0xfda40000 0x200>;
+ reg-names = "vfe", "vfe_vbif";
interrupts = <0 58 0>;
interrupt-names = "vfe";
vdd-supply = <&gdsc_vfe>;
};
+
qcom,jpeg@fda1c000 {
cell-index = <0>;
compatible = "qcom,jpeg";
@@ -117,6 +126,7 @@
interrupts = <0 59 0>;
interrupt-names = "jpeg";
};
+
qcom,jpeg@fda20000 {
cell-index = <1>;
compatible = "qcom,jpeg";
@@ -125,6 +135,7 @@
interrupts = <0 60 0>;
interrupt-names = "jpeg";
};
+
qcom,jpeg@fda24000 {
cell-index = <2>;
compatible = "qcom,jpeg";
@@ -133,12 +144,14 @@
interrupts = <0 61 0>;
interrupt-names = "jpeg";
};
+
qcom,irqrouter@fda00000 {
cell-index = <0>;
compatible = "qcom,irqrouter";
reg = <0xfda00000 0x100>;
reg-names = "irqrouter";
};
+
qcom,cpp@fda04000 {
cell-index = <0>;
compatible = "qcom,cpp";
@@ -148,4 +161,98 @@
interrupt-names = "cpp";
vdd-supply = <&gdsc_vfe>;
};
+
+ qcom,cci@fda0C000 {
+ cell-index = <0>;
+ compatible = "qcom,cci";
+ reg = <0xfda0C000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ reg-names = "cci";
+ interrupts = <0 50 0>;
+ interrupt-names = "cci";
+
+ qcom,camera@6e {
+ compatible = "qcom,s5k3l1yx";
+ 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";
+ cam_vdig-supply = <&pm8941_l3>;
+ cam_vana-supply = <&pm8941_l17>;
+ cam_vio-supply = <&pm8941_lvs3>;
+ cam_vaf-supply = <&pm8941_l23>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vana", "cam_vio",
+ "cam_vaf";
+ qcom,cam-vreg-type = <0 0 1 0>;
+ qcom,cam-vreg-min-voltage = <1225000 2850000 0 3000000>;
+ qcom,cam-vreg-max-voltage = <1225000 2850000 0 3000000>;
+ qcom,cam-vreg-op-mode = <105000 80000 0 100000>;
+ qcom,gpio-no-mux = <0>;
+ gpios = <&msmgpio 15 0>,
+ <&msmgpio 19 0>,
+ <&msmgpio 20 0>,
+ <&msmgpio 90 0>;
+ qcom,gpio-common-tbl-num = <0 1 2>;
+ qcom,gpio-common-tbl-flags = <1 1 1>;
+ qcom,gpio-common-tbl-label = "CAMIF_MCLK",
+ "CAMIF_I2C_DATA",
+ "CAMIF_I2C_CLK";
+ qcom,gpio-req-tbl-num = <3>;
+ qcom,gpio-req-tbl-flags = <0>;
+ qcom,gpio-req-tbl-label = "CAM_RESET1";
+ qcom,gpio-set-tbl-num = <3 3>;
+ qcom,gpio-set-tbl-flags = <0 2>;
+ qcom,gpio-set-tbl-delay = <1000 30000>;
+ qcom,csi-lane-assign = <0x4320>;
+ qcom,csi-lane-mask = <0x1F>;
+ qcom,csi-phy-sel = <0>;
+ qcom,camera-type = <0>;
+ qcom,sensor-type = <0>;
+ };
+
+ qcom,camera@6c {
+ compatible = "qcom,ov2720";
+ reg = <0x6c 0x0>;
+ qcom,csi-if = <1>;
+ qcom,csid-core = <1>;
+ qcom,is-vpe = <1>;
+ qcom,flash-type = <0>;
+ qcom,mount-angle = <0>;
+ qcom,sensor-name = "ov2720";
+ 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 19 0>,
+ <&msmgpio 20 0>,
+ <&msmgpio 92 0>;
+ qcom,gpio-common-tbl-num = <0 1 2>;
+ qcom,gpio-common-tbl-flags = <1 1 1>;
+ qcom,gpio-common-tbl-label = "CAMIF_MCLK",
+ "CAMIF_I2C_DATA",
+ "CAMIF_I2C_CLK";
+ qcom,gpio-req-tbl-num = <3>;
+ qcom,gpio-req-tbl-flags = <0>;
+ qcom,gpio-req-tbl-label = "CAM_RESET1";
+ qcom,gpio-set-tbl-num = <3 3>;
+ qcom,gpio-set-tbl-flags = <0 2>;
+ qcom,gpio-set-tbl-delay = <1000 4000>;
+ qcom,csi-lane-assign = <0x4320>;
+ qcom,csi-lane-mask = <0x7>;
+ qcom,csi-phy-sel = <1>;
+ qcom,camera-type = <0>;
+ qcom,sensor-type = <0>;
+ };
+ };
};
diff --git a/arch/arm/boot/dts/msm8974-cdp.dts b/arch/arm/boot/dts/msm8974-cdp.dts
index 8ae9583..779b4f2 100644
--- a/arch/arm/boot/dts/msm8974-cdp.dts
+++ b/arch/arm/boot/dts/msm8974-cdp.dts
@@ -13,6 +13,7 @@
/dts-v1/;
/include/ "msm8974.dtsi"
+/include/ "dsi-panel-toshiba-720p-video.dtsi"
/ {
model = "Qualcomm MSM 8974 CDP";
@@ -22,6 +23,12 @@
serial@f991e000 {
status = "ok";
};
+
+ qcom,mdss_dsi@fd922800 {
+ qcom,mdss_dsi_toshiba_720p_video {
+ status = "ok";
+ };
+ };
};
&sdcc2 {
diff --git a/arch/arm/boot/dts/msm8974-mdss.dtsi b/arch/arm/boot/dts/msm8974-mdss.dtsi
index de9173c7..dbaa492 100644
--- a/arch/arm/boot/dts/msm8974-mdss.dtsi
+++ b/arch/arm/boot/dts/msm8974-mdss.dtsi
@@ -22,8 +22,11 @@
mdss_dsi: qcom,mdss_dsi@fd922800 {
compatible = "qcom,msm-mdss-dsi";
- reg = <0xfd922800 0x5ac>,
+ reg = <0xfd922800 0x600>,
<0xfd8c2000 0x01000>;
+ vdd-supply = <&pm8941_l22>;
+ vdd_io-supply = <&pm8941_l12>;
+ vreg-supply = <&pm8941_l2>;
};
qcom,mdss_wb_panel {
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index 1be0af9..8c08715 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -421,12 +421,12 @@
<0x1e70008c>; /* LPG_CHAN12 */
};
- i2c@f9966000 {
+ i2c@f9967000 {
cell-index = <0>;
compatible = "qcom,i2c-qup";
- reg = <0Xf9966000 0x1000>;
+ reg = <0Xf9967000 0x1000>;
reg-names = "qup_phys_addr";
- interrupts = <0 104 0>;
+ interrupts = <0 105 0>;
interrupt-names = "qup_err_intr";
qcom,i2c-bus-freq = <100000>;
qcom,i2c-src-freq = <24000000>;
@@ -551,7 +551,8 @@
qcom,ssusb@f9200000 {
compatible = "qcom,dwc-usb3-msm";
- reg = <0xf9200000 0xfc000>;
+ reg = <0xf9200000 0xfc000>,
+ <0xfd4ab000 0x4>;
interrupts = <0 131 0 0 179 0>;
interrupt-names = "irq", "otg_irq";
SSUSB_VDDCX-supply = <&pm8841_s2>;
diff --git a/arch/arm/configs/msm8974_defconfig b/arch/arm/configs/msm8974_defconfig
index 719933f..2d0a428 100644
--- a/arch/arm/configs/msm8974_defconfig
+++ b/arch/arm/configs/msm8974_defconfig
@@ -168,12 +168,22 @@
CONFIG_REGULATOR_STUB=y
CONFIG_REGULATOR_QPNP=y
CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CONTROLLER=y
CONFIG_VIDEO_DEV=y
-# CONFIG_RC_CORE is not set
-# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
+CONFIG_VIDEO_V4L2_SUBDEV_API=y
CONFIG_VIDEOBUF2_MSM_MEM=y
-# CONFIG_VIDEO_CAPTURE_DRIVERS is not set
-# CONFIG_RADIO_ADAPTERS is not set
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_MSM_CAMERA_V4L2=y
+CONFIG_MSM_CAMERA_SENSOR=y
+CONFIG_MSM_ACTUATOR=y
+CONFIG_MSM_CAM_IRQ_ROUTER=n
+CONFIG_MSM_CCI=y
+CONFIG_MSM_CSI30_HEADER=y
+CONFIG_MSM_CSIPHY=y
+CONFIG_MSM_CSID=y
+CONFIG_MSM_CSI2_REGISTER=y
+CONFIG_MSM_ISPIF=y
+CONFIG_S5K3L1YX=y
CONFIG_ION=y
CONFIG_ION_MSM=y
CONFIG_MSM_KGSL=y
@@ -231,6 +241,7 @@
CONFIG_ANDROID_LOW_MEMORY_KILLER=y
CONFIG_MSM_SSBI=y
CONFIG_SPS=y
+CONFIG_USB_BAM=y
CONFIG_SPS_SUPPORT_BAMDMA=y
CONFIG_SPS_SUPPORT_NDP_BAM=y
CONFIG_QPNP_POWER_ON=y
diff --git a/arch/arm/configs/msm9615_defconfig b/arch/arm/configs/msm9615_defconfig
index db94f13..b8417fe 100644
--- a/arch/arm/configs/msm9615_defconfig
+++ b/arch/arm/configs/msm9615_defconfig
@@ -147,6 +147,10 @@
CONFIG_IP6_NF_TARGET_REJECT_SKERR=y
CONFIG_IP6_NF_MANGLE=y
CONFIG_IP6_NF_RAW=y
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_HTB=y
+CONFIG_NET_SCH_PRIO=y
+CONFIG_NET_CLS_FW=y
CONFIG_MTD=y
CONFIG_MTD_TESTS=m
CONFIG_MTD_CMDLINE_PARTS=y
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index f27889b..da3d3c4 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -276,9 +276,9 @@
obj-$(CONFIG_MACH_MSM8960_CDP) += board-8960-all.o board-8960-regulator.o
obj-$(CONFIG_MACH_MSM8960_MTP) += board-8960-all.o board-8960-regulator.o
obj-$(CONFIG_MACH_MSM8960_FLUID) += board-8960-all.o board-8960-regulator.o
-obj-$(CONFIG_MACH_MSM8930_CDP) += board-8930-all.o board-8930-regulator.o
-obj-$(CONFIG_MACH_MSM8930_MTP) += board-8930-all.o board-8930-regulator.o
-obj-$(CONFIG_MACH_MSM8930_FLUID) += board-8930-all.o board-8930-regulator.o
+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_MACH_APQ8064_CDP) += board-8064-all.o board-8064-regulator.o
obj-$(CONFIG_MACH_APQ8064_MTP) += board-8064-all.o board-8064-regulator.o
diff --git a/arch/arm/mach-msm/acpuclock-8930.c b/arch/arm/mach-msm/acpuclock-8930.c
index 5647d14..782ee60 100644
--- a/arch/arm/mach-msm/acpuclock-8930.c
+++ b/arch/arm/mach-msm/acpuclock-8930.c
@@ -45,6 +45,39 @@
.vdd[HFPLL_VDD_HIGH] = LVL_HIGH,
};
+static struct scalable scalable_pm8917[] __initdata = {
+ [CPU0] = {
+ .hfpll_phys_base = 0x00903200,
+ .aux_clk_sel_phys = 0x02088014,
+ .aux_clk_sel = 3,
+ .l2cpmr_iaddr = 0x4501,
+ .vreg[VREG_CORE] = { "krait0", 1300000 },
+ .vreg[VREG_MEM] = { "krait0_mem", 1150000 },
+ .vreg[VREG_DIG] = { "krait0_dig", 1150000 },
+ .vreg[VREG_HFPLL_A] = { "krait0_s8", 2050000 },
+ .vreg[VREG_HFPLL_B] = { "krait0_l23", 1800000 },
+ },
+ [CPU1] = {
+ .hfpll_phys_base = 0x00903300,
+ .aux_clk_sel_phys = 0x02098014,
+ .aux_clk_sel = 3,
+ .l2cpmr_iaddr = 0x5501,
+ .vreg[VREG_CORE] = { "krait1", 1300000 },
+ .vreg[VREG_MEM] = { "krait1_mem", 1150000 },
+ .vreg[VREG_DIG] = { "krait1_dig", 1150000 },
+ .vreg[VREG_HFPLL_A] = { "krait1_s8", 2050000 },
+ .vreg[VREG_HFPLL_B] = { "krait1_l23", 1800000 },
+ },
+ [L2] = {
+ .hfpll_phys_base = 0x00903400,
+ .aux_clk_sel_phys = 0x02011028,
+ .aux_clk_sel = 3,
+ .l2cpmr_iaddr = 0x0500,
+ .vreg[VREG_HFPLL_A] = { "l2_s8", 2050000 },
+ .vreg[VREG_HFPLL_B] = { "l2_l23", 1800000 },
+ },
+};
+
static struct scalable scalable[] __initdata = {
[CPU0] = {
.hfpll_phys_base = 0x00903200,
@@ -193,6 +226,10 @@
static int __init acpuclk_8930_probe(struct platform_device *pdev)
{
+ struct acpuclk_platform_data *pdata = pdev->dev.platform_data;
+ if (pdata && pdata->uses_pm8917)
+ acpuclk_8930_params.scalable = scalable_pm8917;
+
return acpuclk_krait_init(&pdev->dev, &acpuclk_8930_params);
}
diff --git a/arch/arm/mach-msm/acpuclock-8960ab.c b/arch/arm/mach-msm/acpuclock-8960ab.c
index 1097907..3c42090 100644
--- a/arch/arm/mach-msm/acpuclock-8960ab.c
+++ b/arch/arm/mach-msm/acpuclock-8960ab.c
@@ -124,6 +124,10 @@
{ 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 },
{ 0, { 0 } }
};
diff --git a/arch/arm/mach-msm/acpuclock-krait.h b/arch/arm/mach-msm/acpuclock-krait.h
index 5a95e76..1b891b1 100644
--- a/arch/arm/mach-msm/acpuclock-krait.h
+++ b/arch/arm/mach-msm/acpuclock-krait.h
@@ -253,9 +253,16 @@
};
/**
+ * struct acpuclk_platform_data - PMIC configuration data.
+ * @uses_pm8917: Boolean indicates presence of pm8917.
+ */
+struct acpuclk_platform_data {
+ bool uses_pm8917;
+};
+
+/**
* acpuclk_krait_init - Initialize the Krait CPU clock driver give SoC params.
*/
extern int acpuclk_krait_init(struct device *dev,
const struct acpuclk_krait_params *params);
-
#endif
diff --git a/arch/arm/mach-msm/bam_dmux.c b/arch/arm/mach-msm/bam_dmux.c
index 125094d..fbc3e25 100644
--- a/arch/arm/mach-msm/bam_dmux.c
+++ b/arch/arm/mach-msm/bam_dmux.c
@@ -27,6 +27,7 @@
#include <linux/clk.h>
#include <linux/wakelock.h>
#include <linux/kfifo.h>
+#include <linux/of.h>
#include <mach/sps.h>
#include <mach/bam_dmux.h>
@@ -175,6 +176,14 @@
#define A2_PHYS_SIZE 0x2000
#define BUFFER_SIZE 2048
#define NUM_BUFFERS 32
+
+#ifndef A2_BAM_IRQ
+#define A2_BAM_IRQ -1
+#endif
+
+static void *a2_phys_base;
+static uint32_t a2_phys_size;
+static int a2_bam_irq;
static struct sps_bam_props a2_props;
static u32 a2_device_handle;
static struct sps_pipe *bam_tx_pipe;
@@ -2028,16 +2037,17 @@
vote_dfab();
/* init BAM */
- a2_virt_addr = ioremap_nocache(A2_PHYS_BASE, A2_PHYS_SIZE);
+ a2_virt_addr = ioremap_nocache((unsigned long)(a2_phys_base),
+ a2_phys_size);
if (!a2_virt_addr) {
pr_err("%s: ioremap failed\n", __func__);
ret = -ENOMEM;
goto ioremap_failed;
}
- a2_props.phys_addr = A2_PHYS_BASE;
+ a2_props.phys_addr = (u32)(a2_phys_base);
a2_props.virt_addr = a2_virt_addr;
- a2_props.virt_size = A2_PHYS_SIZE;
- a2_props.irq = A2_BAM_IRQ;
+ a2_props.virt_size = a2_phys_size;
+ a2_props.irq = a2_bam_irq;
a2_props.options = SPS_BAM_OPT_IRQ_WAKEUP;
a2_props.num_pipes = A2_NUM_PIPES;
a2_props.summing_threshold = A2_SUMMING_THRESHOLD;
@@ -2199,16 +2209,17 @@
void *a2_virt_addr;
/* init BAM */
- a2_virt_addr = ioremap_nocache(A2_PHYS_BASE, A2_PHYS_SIZE);
+ a2_virt_addr = ioremap_nocache((unsigned long)(a2_phys_base),
+ a2_phys_size);
if (!a2_virt_addr) {
pr_err("%s: ioremap failed\n", __func__);
ret = -ENOMEM;
goto ioremap_failed;
}
- a2_props.phys_addr = A2_PHYS_BASE;
+ a2_props.phys_addr = (u32)(a2_phys_base);
a2_props.virt_addr = a2_virt_addr;
- a2_props.virt_size = A2_PHYS_SIZE;
- a2_props.irq = A2_BAM_IRQ;
+ a2_props.virt_size = a2_phys_size;
+ a2_props.irq = a2_bam_irq;
a2_props.options = SPS_BAM_OPT_IRQ_WAKEUP;
a2_props.num_pipes = A2_NUM_PIPES;
a2_props.summing_threshold = A2_SUMMING_THRESHOLD;
@@ -2321,11 +2332,35 @@
static int bam_dmux_probe(struct platform_device *pdev)
{
int rc;
+ struct resource *r;
DBG("%s probe called\n", __func__);
if (bam_mux_initialized)
return 0;
+ if (pdev->dev.of_node) {
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!r) {
+ pr_err("%s: reg field missing\n", __func__);
+ return -ENODEV;
+ }
+ a2_phys_base = (void *)(r->start);
+ a2_phys_size = (uint32_t)(resource_size(r));
+ a2_bam_irq = platform_get_irq(pdev, 0);
+ if (a2_bam_irq == -ENXIO) {
+ pr_err("%s: irq field missing\n", __func__);
+ return -ENODEV;
+ }
+ DBG("%s: base:%p size:%x irq:%d\n", __func__,
+ a2_phys_base,
+ a2_phys_size,
+ a2_bam_irq);
+ } else { /* fallback to default init data */
+ a2_phys_base = (void *)(A2_PHYS_BASE);
+ a2_phys_size = A2_PHYS_SIZE;
+ a2_bam_irq = A2_BAM_IRQ;
+ }
+
xo_clk = clk_get(&pdev->dev, "xo");
if (IS_ERR(xo_clk)) {
bam_dmux_log("%s: did not get xo clock\n", __func__);
@@ -2409,11 +2444,17 @@
return 0;
}
+static struct of_device_id msm_match_table[] = {
+ {.compatible = "qcom,bam_dmux"},
+ {},
+};
+
static struct platform_driver bam_dmux_driver = {
.probe = bam_dmux_probe,
.driver = {
.name = "BAM_RMNT",
.owner = THIS_MODULE,
+ .of_match_table = msm_match_table,
},
};
diff --git a/arch/arm/mach-msm/board-8064-pmic.c b/arch/arm/mach-msm/board-8064-pmic.c
index 86bc6ba..04326aa 100644
--- a/arch/arm/mach-msm/board-8064-pmic.c
+++ b/arch/arm/mach-msm/board-8064-pmic.c
@@ -126,7 +126,7 @@
PM8921_GPIO_INPUT(35, PM_GPIO_PULL_UP_30),
PM8921_GPIO_INPUT(38, PM_GPIO_PULL_UP_30),
/* TABLA CODEC RESET */
- PM8921_GPIO_OUTPUT(34, 1, MED),
+ PM8921_GPIO_OUTPUT(34, 0, MED),
PM8921_GPIO_OUTPUT(13, 0, HIGH), /* PCIE_CLK_PWR_EN */
PM8921_GPIO_INPUT(12, PM_GPIO_PULL_UP_30), /* PCIE_WAKE_N */
};
@@ -494,5 +494,7 @@
apq8064_pm8921_bms_pdata.battery_type = BATT_PALLADIUM;
} else if (machine_is_apq8064_liquid()) {
apq8064_pm8921_bms_pdata.battery_type = BATT_DESAY;
+ } else if (machine_is_apq8064_cdp()) {
+ apq8064_pm8921_chg_pdata.has_dc_supply = true;
}
}
diff --git a/arch/arm/mach-msm/board-8930-display.c b/arch/arm/mach-msm/board-8930-display.c
index 2a8e918..4b4a51a 100644
--- a/arch/arm/mach-msm/board-8930-display.c
+++ b/arch/arm/mach-msm/board-8930-display.c
@@ -135,6 +135,8 @@
static int mipi_dsi_cdp_panel_power(int on)
{
static struct regulator *reg_l8, *reg_l23, *reg_l2;
+ /* Control backlight GPIO (24) directly when using PM8917 */
+ int gpio24 = PM8917_GPIO_PM_TO_SYS(24);
int rc;
pr_debug("%s: state : %d\n", __func__, on);
@@ -190,13 +192,21 @@
rc);
gpio_free(DISP_3D_2D_MODE);
return -ENODEV;
- }
+ }
rc = gpio_direction_output(DISP_3D_2D_MODE, 0);
if (rc) {
pr_err("gpio_direction_output failed for %d gpio rc=%d\n",
DISP_3D_2D_MODE, rc);
return -ENODEV;
+ }
+ if (socinfo_get_pmic_model() == PMIC_MODEL_PM8917) {
+ rc = gpio_request(gpio24, "disp_bl");
+ if (rc) {
+ pr_err("request for gpio 24 failed, rc=%d\n",
+ rc);
+ return -ENODEV;
}
+ }
dsi_power_on = true;
}
if (on) {
@@ -238,6 +248,8 @@
gpio_set_value(DISP_RST_GPIO, 1);
gpio_set_value(DISP_3D_2D_MODE, 1);
usleep(20);
+ if (socinfo_get_pmic_model() == PMIC_MODEL_PM8917)
+ gpio_set_value_cansleep(gpio24, 1);
} else {
gpio_set_value(DISP_RST_GPIO, 0);
@@ -274,6 +286,8 @@
}
gpio_set_value(DISP_3D_2D_MODE, 0);
usleep(20);
+ if (socinfo_get_pmic_model() == PMIC_MODEL_PM8917)
+ gpio_set_value_cansleep(gpio24, 0);
}
return 0;
}
diff --git a/arch/arm/mach-msm/board-8930-gpiomux.c b/arch/arm/mach-msm/board-8930-gpiomux.c
index 74dfca1..2331b0b 100644
--- a/arch/arm/mach-msm/board-8930-gpiomux.c
+++ b/arch/arm/mach-msm/board-8930-gpiomux.c
@@ -280,6 +280,13 @@
#endif
+static struct gpiomux_setting sitar_reset = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_6MA,
+ .pull = GPIOMUX_PULL_NONE,
+ .dir = GPIOMUX_OUT_LOW,
+};
+
#if defined(CONFIG_KS8851) || defined(CONFIG_KS8851_MODULE)
static struct msm_gpiomux_config msm8960_ethernet_configs[] = {
{
@@ -710,6 +717,15 @@
},
};
+static struct msm_gpiomux_config msm_sitar_config[] __initdata = {
+ {
+ .gpio = 42, /* SYS_RST_N */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &sitar_reset,
+ },
+ }
+};
+
int __init msm8930_init_gpiomux(void)
{
int rc = msm_gpiomux_init(NR_GPIO_IRQS);
@@ -784,5 +800,7 @@
msm_gpiomux_install(msm8930_gyro_int_config,
ARRAY_SIZE(msm8930_gyro_int_config));
+ msm_gpiomux_install(msm_sitar_config, ARRAY_SIZE(msm_sitar_config));
+
return 0;
}
diff --git a/arch/arm/mach-msm/board-8930-pmic.c b/arch/arm/mach-msm/board-8930-pmic.c
index e3479eb..b6e20fd 100644
--- a/arch/arm/mach-msm/board-8930-pmic.c
+++ b/arch/arm/mach-msm/board-8930-pmic.c
@@ -18,6 +18,7 @@
#include <asm/mach-types.h>
#include <mach/msm_bus_board.h>
#include <mach/restart.h>
+#include <mach/socinfo.h>
#include "devices.h"
#include "board-8930.h"
@@ -31,7 +32,7 @@
struct pm8xxx_mpp_config_data config;
};
-#define PM8XXX_GPIO_INIT(_gpio, _dir, _buf, _val, _pull, _vin, _out_strength, \
+#define PM8038_GPIO_INIT(_gpio, _dir, _buf, _val, _pull, _vin, _out_strength, \
_func, _inv, _disable) \
{ \
.gpio = PM8038_GPIO_PM_TO_SYS(_gpio), \
@@ -48,7 +49,7 @@
} \
}
-#define PM8XXX_MPP_INIT(_mpp, _type, _level, _control) \
+#define PM8038_MPP_INIT(_mpp, _type, _level, _control) \
{ \
.mpp = PM8038_MPP_PM_TO_SYS(_mpp), \
.config = { \
@@ -58,49 +59,128 @@
} \
}
-#define PM8XXX_GPIO_DISABLE(_gpio) \
- PM8XXX_GPIO_INIT(_gpio, PM_GPIO_DIR_IN, 0, 0, 0, PM8038_GPIO_VIN_L11, \
+#define PM8038_GPIO_DISABLE(_gpio) \
+ PM8038_GPIO_INIT(_gpio, PM_GPIO_DIR_IN, 0, 0, 0, PM8038_GPIO_VIN_L11, \
0, 0, 0, 1)
-#define PM8XXX_GPIO_OUTPUT(_gpio, _val) \
- PM8XXX_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
+#define PM8038_GPIO_OUTPUT(_gpio, _val) \
+ PM8038_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
PM_GPIO_PULL_NO, PM8038_GPIO_VIN_L11, \
PM_GPIO_STRENGTH_HIGH, \
PM_GPIO_FUNC_NORMAL, 0, 0)
-#define PM8XXX_GPIO_INPUT(_gpio, _pull) \
- PM8XXX_GPIO_INIT(_gpio, PM_GPIO_DIR_IN, PM_GPIO_OUT_BUF_CMOS, 0, \
+#define PM8038_GPIO_INPUT(_gpio, _pull) \
+ PM8038_GPIO_INIT(_gpio, PM_GPIO_DIR_IN, PM_GPIO_OUT_BUF_CMOS, 0, \
_pull, PM8038_GPIO_VIN_L11, \
PM_GPIO_STRENGTH_NO, \
PM_GPIO_FUNC_NORMAL, 0, 0)
-#define PM8XXX_GPIO_OUTPUT_FUNC(_gpio, _val, _func) \
- PM8XXX_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
+#define PM8038_GPIO_OUTPUT_FUNC(_gpio, _val, _func) \
+ PM8038_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
PM_GPIO_PULL_NO, PM8038_GPIO_VIN_L11, \
PM_GPIO_STRENGTH_HIGH, \
_func, 0, 0)
-#define PM8XXX_GPIO_OUTPUT_VIN(_gpio, _val, _vin) \
- PM8XXX_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
+#define PM8038_GPIO_OUTPUT_VIN(_gpio, _val, _vin) \
+ PM8038_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
PM_GPIO_PULL_NO, _vin, \
PM_GPIO_STRENGTH_HIGH, \
PM_GPIO_FUNC_NORMAL, 0, 0)
-/* Initial pm8038 GPIO configurations */
+#define PM8917_GPIO_INIT(_gpio, _dir, _buf, _val, _pull, _vin, _out_strength, \
+ _func, _inv, _disable) \
+{ \
+ .gpio = PM8917_GPIO_PM_TO_SYS(_gpio), \
+ .config = { \
+ .direction = _dir, \
+ .output_buffer = _buf, \
+ .output_value = _val, \
+ .pull = _pull, \
+ .vin_sel = _vin, \
+ .out_strength = _out_strength, \
+ .function = _func, \
+ .inv_int_pol = _inv, \
+ .disable_pin = _disable, \
+ } \
+}
+
+#define PM8917_MPP_INIT(_mpp, _type, _level, _control) \
+{ \
+ .mpp = PM8917_MPP_PM_TO_SYS(_mpp), \
+ .config = { \
+ .type = PM8XXX_MPP_TYPE_##_type, \
+ .level = _level, \
+ .control = PM8XXX_MPP_##_control, \
+ } \
+}
+
+#define PM8917_GPIO_DISABLE(_gpio) \
+ PM8917_GPIO_INIT(_gpio, PM_GPIO_DIR_IN, 0, 0, 0, PM_GPIO_VIN_S4, \
+ 0, 0, 0, 1)
+
+#define PM8917_GPIO_OUTPUT(_gpio, _val) \
+ PM8917_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
+ PM_GPIO_PULL_NO, PM_GPIO_VIN_S4, \
+ PM_GPIO_STRENGTH_HIGH, \
+ PM_GPIO_FUNC_NORMAL, 0, 0)
+
+#define PM8917_GPIO_INPUT(_gpio, _pull) \
+ PM8917_GPIO_INIT(_gpio, PM_GPIO_DIR_IN, PM_GPIO_OUT_BUF_CMOS, 0, \
+ _pull, PM_GPIO_VIN_S4, \
+ PM_GPIO_STRENGTH_NO, \
+ PM_GPIO_FUNC_NORMAL, 0, 0)
+
+#define PM8917_GPIO_OUTPUT_FUNC(_gpio, _val, _func) \
+ PM8917_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
+ PM_GPIO_PULL_NO, PM_GPIO_VIN_S4, \
+ PM_GPIO_STRENGTH_HIGH, \
+ _func, 0, 0)
+
+#define PM8917_GPIO_OUTPUT_VIN(_gpio, _val, _vin) \
+ PM8917_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
+ PM_GPIO_PULL_NO, _vin, \
+ PM_GPIO_STRENGTH_HIGH, \
+ PM_GPIO_FUNC_NORMAL, 0, 0)
+
+/* GPIO and MPP configurations for MSM8930 + PM8038 targets */
+
+/* Initial PM8038 GPIO configurations */
static struct pm8xxx_gpio_init pm8038_gpios[] __initdata = {
/* keys GPIOs */
- PM8XXX_GPIO_INPUT(3, PM_GPIO_PULL_UP_30),
- PM8XXX_GPIO_INPUT(8, PM_GPIO_PULL_UP_30),
- PM8XXX_GPIO_INPUT(10, PM_GPIO_PULL_UP_30),
- PM8XXX_GPIO_INPUT(11, PM_GPIO_PULL_UP_30),
+ PM8038_GPIO_INPUT(3, PM_GPIO_PULL_UP_30),
+ PM8038_GPIO_INPUT(8, PM_GPIO_PULL_UP_30),
+ PM8038_GPIO_INPUT(10, PM_GPIO_PULL_UP_30),
+ PM8038_GPIO_INPUT(11, PM_GPIO_PULL_UP_30),
/* haptics gpio */
- PM8XXX_GPIO_OUTPUT_FUNC(7, 0, PM_GPIO_FUNC_1),
+ PM8038_GPIO_OUTPUT_FUNC(7, 0, PM_GPIO_FUNC_1),
/* MHL PWR EN */
- PM8XXX_GPIO_OUTPUT_VIN(5, 1, PM_GPIO_VIN_VPH),
+ PM8038_GPIO_OUTPUT_VIN(5, 1, PM8038_GPIO_VIN_VPH),
};
-/* Initial pm8038 MPP configurations */
-static struct pm8xxx_mpp_init pm8038_mpps[] __initdata = {};
+/* Initial PM8038 MPP configurations */
+static struct pm8xxx_mpp_init pm8038_mpps[] __initdata = {
+};
+
+/* GPIO and MPP configurations for MSM8930 + PM8917 targets */
+
+/* Initial PM8917 GPIO configurations */
+static struct pm8xxx_gpio_init pm8917_gpios[] __initdata = {
+ /* Backlight enable control */
+ PM8917_GPIO_OUTPUT(24, 1),
+ /* keys GPIOs */
+ PM8917_GPIO_INPUT(27, PM_GPIO_PULL_UP_30),
+ PM8917_GPIO_INPUT(28, PM_GPIO_PULL_UP_30),
+ PM8917_GPIO_INPUT(36, PM_GPIO_PULL_UP_30),
+ PM8917_GPIO_INPUT(37, PM_GPIO_PULL_UP_30),
+ /* haptics gpio */
+ PM8917_GPIO_OUTPUT_FUNC(38, 0, PM_GPIO_FUNC_2),
+ /* MHL PWR EN */
+ PM8917_GPIO_OUTPUT_VIN(25, 1, PM_GPIO_VIN_VPH),
+};
+
+/* Initial PM8917 MPP configurations */
+static struct pm8xxx_mpp_init pm8917_mpps[] __initdata = {
+};
void __init msm8930_pm8038_gpio_mpp_init(void)
{
@@ -126,7 +206,31 @@
}
}
-static struct pm8xxx_adc_amux pm8xxx_adc_channels_data[] = {
+void __init msm8930_pm8917_gpio_mpp_init(void)
+{
+ int i, rc;
+
+ for (i = 0; i < ARRAY_SIZE(pm8917_gpios); i++) {
+ rc = pm8xxx_gpio_config(pm8917_gpios[i].gpio,
+ &pm8917_gpios[i].config);
+ if (rc) {
+ pr_err("%s: pm8xxx_gpio_config: rc=%d\n", __func__, rc);
+ break;
+ }
+ }
+
+ /* Initial MPP configuration. */
+ for (i = 0; i < ARRAY_SIZE(pm8917_mpps); i++) {
+ rc = pm8xxx_mpp_config(pm8917_mpps[i].mpp,
+ &pm8917_mpps[i].config);
+ if (rc) {
+ pr_err("%s: pm8xxx_mpp_config: rc=%d\n", __func__, rc);
+ break;
+ }
+ }
+}
+
+static struct pm8xxx_adc_amux pm8038_adc_channels_data[] = {
{"vcoin", CHANNEL_VCOIN, CHAN_PATH_SCALING2, AMUX_RSV1,
ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
{"vbat", CHANNEL_VBAT, CHAN_PATH_SCALING2, AMUX_RSV1,
@@ -161,16 +265,16 @@
ADC_DECIMATION_TYPE2, ADC_SCALE_PA_THERM},
};
-static struct pm8xxx_adc_properties pm8xxx_adc_data = {
+static struct pm8xxx_adc_properties pm8038_adc_data = {
.adc_vdd_reference = 1800, /* milli-voltage for this adc */
.bitresolution = 15,
.bipolar = 0,
};
-static struct pm8xxx_adc_platform_data pm8xxx_adc_pdata = {
- .adc_channel = pm8xxx_adc_channels_data,
- .adc_num_board_channel = ARRAY_SIZE(pm8xxx_adc_channels_data),
- .adc_prop = &pm8xxx_adc_data,
+static struct pm8xxx_adc_platform_data pm8038_adc_pdata = {
+ .adc_channel = pm8038_adc_channels_data,
+ .adc_num_board_channel = ARRAY_SIZE(pm8038_adc_channels_data),
+ .adc_prop = &pm8038_adc_data,
.adc_mpp_base = PM8038_MPP_PM_TO_SYS(1),
};
@@ -227,6 +331,7 @@
.thermal_mitigation = pm8921_therm_mitigation,
.thermal_levels = ARRAY_SIZE(pm8921_therm_mitigation),
.led_src_config = LED_SRC_VPH_PWR,
+ .rconn_mohm = 18,
};
#define PM8038_WLED_MAX_CURRENT 25
@@ -348,6 +453,7 @@
.shutdown_soc_valid_limit = 20,
.adjust_soc_low_threshold = 25,
.chg_term_ua = CHG_TERM_MA * 1000,
+ .rconn_mohm = 18,
};
static struct pm8038_platform_data pm8038_platform_data __devinitdata = {
@@ -360,7 +466,7 @@
.regulator_pdatas = msm8930_pm8038_regulator_pdata,
.charger_pdata = &pm8921_chg_pdata,
.bms_pdata = &pm8921_bms_pdata,
- .adc_pdata = &pm8xxx_adc_pdata,
+ .adc_pdata = &pm8038_adc_pdata,
.leds_pdata = &pm8xxx_leds_pdata,
.ccadc_pdata = &pm8xxx_ccadc_pdata,
.spk_pdata = &pm8xxx_spk_pdata,
@@ -374,15 +480,99 @@
},
};
+/* PM8917 platform data */
+
+static struct pm8xxx_adc_amux pm8917_adc_channels_data[] = {
+ {"vcoin", CHANNEL_VCOIN, CHAN_PATH_SCALING2, AMUX_RSV1,
+ ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+ {"vbat", CHANNEL_VBAT, CHAN_PATH_SCALING2, AMUX_RSV1,
+ ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+ {"dcin", CHANNEL_DCIN, CHAN_PATH_SCALING4, AMUX_RSV1,
+ ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+ {"ichg", CHANNEL_ICHG, CHAN_PATH_SCALING1, AMUX_RSV1,
+ ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+ {"vph_pwr", CHANNEL_VPH_PWR, CHAN_PATH_SCALING2, AMUX_RSV1,
+ ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+ {"ibat", CHANNEL_IBAT, CHAN_PATH_SCALING1, AMUX_RSV1,
+ ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+ {"batt_therm", CHANNEL_BATT_THERM, CHAN_PATH_SCALING1, AMUX_RSV2,
+ ADC_DECIMATION_TYPE2, ADC_SCALE_BATT_THERM},
+ {"batt_id", CHANNEL_BATT_ID, CHAN_PATH_SCALING1, AMUX_RSV2,
+ ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+ {"usbin", CHANNEL_USBIN, CHAN_PATH_SCALING3, AMUX_RSV1,
+ ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+ {"pmic_therm", CHANNEL_DIE_TEMP, CHAN_PATH_SCALING1, AMUX_RSV1,
+ ADC_DECIMATION_TYPE2, ADC_SCALE_PMIC_THERM},
+ {"625mv", CHANNEL_625MV, CHAN_PATH_SCALING1, AMUX_RSV1,
+ ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+ {"125v", CHANNEL_125V, CHAN_PATH_SCALING1, AMUX_RSV1,
+ ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+ {"chg_temp", CHANNEL_CHG_TEMP, CHAN_PATH_SCALING1, AMUX_RSV1,
+ ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+ {"xo_therm", CHANNEL_MUXOFF, CHAN_PATH_SCALING1, AMUX_RSV0,
+ ADC_DECIMATION_TYPE2, ADC_SCALE_XOTHERM},
+ {"pa_therm0", ADC_MPP_1_AMUX3, CHAN_PATH_SCALING1, AMUX_RSV1,
+ ADC_DECIMATION_TYPE2, ADC_SCALE_PA_THERM},
+};
+
+static struct pm8xxx_adc_properties pm8917_adc_data = {
+ .adc_vdd_reference = 1800, /* milli-voltage for this adc */
+ .bitresolution = 15,
+ .bipolar = 0,
+};
+
+static struct pm8xxx_adc_platform_data pm8917_adc_pdata = {
+ .adc_channel = pm8917_adc_channels_data,
+ .adc_num_board_channel = ARRAY_SIZE(pm8917_adc_channels_data),
+ .adc_prop = &pm8917_adc_data,
+ .adc_mpp_base = PM8917_MPP_PM_TO_SYS(1),
+};
+
+static struct pm8921_platform_data pm8917_platform_data __devinitdata = {
+ .irq_pdata = &pm8xxx_irq_pdata,
+ .gpio_pdata = &pm8xxx_gpio_pdata,
+ .mpp_pdata = &pm8xxx_mpp_pdata,
+ .rtc_pdata = &pm8xxx_rtc_pdata,
+ .pwrkey_pdata = &pm8xxx_pwrkey_pdata,
+ .misc_pdata = &pm8xxx_misc_pdata,
+ .regulator_pdatas = msm8930_pm8917_regulator_pdata,
+ .charger_pdata = &pm8921_chg_pdata,
+ .bms_pdata = &pm8921_bms_pdata,
+ .adc_pdata = &pm8917_adc_pdata,
+ .ccadc_pdata = &pm8xxx_ccadc_pdata,
+};
+
+static struct msm_ssbi_platform_data msm8930_ssbi_pm8917_pdata __devinitdata = {
+ .controller_type = MSM_SBI_CTRL_PMIC_ARBITER,
+ .slave = {
+ .name = "pm8921-core",
+ .platform_data = &pm8917_platform_data,
+ },
+};
+
void __init msm8930_init_pmic(void)
{
- pmic_reset_irq = PM8038_IRQ_BASE + PM8038_RESOUT_IRQ;
- msm8960_device_ssbi_pmic.dev.platform_data =
- &msm8930_ssbi_pm8038_pdata;
- pm8038_platform_data.num_regulators
- = msm8930_pm8038_regulator_pdata_len;
- if (machine_is_apq8064_mtp())
- pm8921_bms_pdata.battery_type = BATT_PALLADIUM;
- else if (machine_is_apq8064_liquid())
- pm8921_bms_pdata.battery_type = BATT_DESAY;
+ if (socinfo_get_pmic_model() != PMIC_MODEL_PM8917) {
+ /* PM8038 configuration */
+ pmic_reset_irq = PM8038_IRQ_BASE + PM8038_RESOUT_IRQ;
+ msm8960_device_ssbi_pmic.dev.platform_data =
+ &msm8930_ssbi_pm8038_pdata;
+ pm8038_platform_data.num_regulators
+ = msm8930_pm8038_regulator_pdata_len;
+ if (machine_is_msm8930_mtp())
+ pm8921_bms_pdata.battery_type = BATT_PALLADIUM;
+ else if (machine_is_msm8930_cdp())
+ pm8921_chg_pdata.has_dc_supply = true;
+ } else {
+ /* PM8917 configuration */
+ pmic_reset_irq = PM8917_IRQ_BASE + PM8921_RESOUT_IRQ;
+ msm8960_device_ssbi_pmic.dev.platform_data =
+ &msm8930_ssbi_pm8917_pdata;
+ pm8917_platform_data.num_regulators
+ = msm8930_pm8917_regulator_pdata_len;
+ if (machine_is_msm8930_mtp())
+ pm8921_bms_pdata.battery_type = BATT_PALLADIUM;
+ else if (machine_is_msm8930_cdp())
+ pm8921_chg_pdata.has_dc_supply = true;
+ }
}
diff --git a/arch/arm/mach-msm/board-8930-regulator.c b/arch/arm/mach-msm/board-8930-regulator-pm8038.c
similarity index 97%
rename from arch/arm/mach-msm/board-8930-regulator.c
rename to arch/arm/mach-msm/board-8930-regulator-pm8038.c
index d4bd18f..ed9d802 100644
--- a/arch/arm/mach-msm/board-8930-regulator.c
+++ b/arch/arm/mach-msm/board-8930-regulator-pm8038.c
@@ -11,6 +11,11 @@
* GNU General Public License for more details.
*/
+/*
+ * This file contains regulator configuration and mappings for targets
+ * consisting of MSM8930 and PM8038.
+ */
+
#include <linux/regulator/pm8xxx-regulator.h>
#include "board-8930.h"
@@ -449,17 +454,17 @@
/* GPIO regulator constraints */
struct gpio_regulator_platform_data
-msm8930_gpio_regulator_pdata[] __devinitdata = {
+msm8930_pm8038_gpio_regulator_pdata[] __devinitdata = {
/* ID vreg_name gpio_label gpio supply */
GPIO_VREG(EXT_5V, "ext_5v", "ext_5v_en", 63, NULL),
GPIO_VREG(EXT_OTG_SW, "ext_otg_sw", "ext_otg_sw_en", 97, "ext_5v"),
};
/* SAW regulator constraints */
-struct regulator_init_data msm8930_saw_regulator_core0_pdata =
+struct regulator_init_data msm8930_pm8038_saw_regulator_core0_pdata =
/* ID vreg_name min_uV max_uV */
SAW_VREG_INIT(S5, "8038_s5", 850000, 1300000);
-struct regulator_init_data msm8930_saw_regulator_core1_pdata =
+struct regulator_init_data msm8930_pm8038_saw_regulator_core1_pdata =
SAW_VREG_INIT(S6, "8038_s6", 850000, 1300000);
/* PM8038 regulator constraints */
@@ -558,7 +563,8 @@
RPM_REG_MAP(VDD_DIG_CORNER, 0, 2, "krait1_dig", "acpuclk-8930aa"),
};
-struct rpm_regulator_platform_data msm8930_rpm_regulator_pdata __devinitdata = {
+struct rpm_regulator_platform_data
+msm8930_pm8038_rpm_regulator_pdata __devinitdata = {
.init_data = msm8930_rpm_regulator_init_data,
.num_regulators = ARRAY_SIZE(msm8930_rpm_regulator_init_data),
.version = RPM_VREG_VERSION_8930,
diff --git a/arch/arm/mach-msm/board-8930-regulator.c b/arch/arm/mach-msm/board-8930-regulator-pm8917.c
similarity index 72%
copy from arch/arm/mach-msm/board-8930-regulator.c
copy to arch/arm/mach-msm/board-8930-regulator-pm8917.c
index d4bd18f..db40e5d 100644
--- a/arch/arm/mach-msm/board-8930-regulator.c
+++ b/arch/arm/mach-msm/board-8930-regulator-pm8917.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -11,6 +11,11 @@
* GNU General Public License for more details.
*/
+/*
+ * This file contains regulator configuration and mappings for targets
+ * consisting of MSM8930 and PM8917.
+ */
+
#include <linux/regulator/pm8xxx-regulator.h>
#include "board-8930.h"
@@ -23,11 +28,10 @@
* regulator name consumer dev_name
*/
VREG_CONSUMERS(L1) = {
- REGULATOR_SUPPLY("8038_l1", NULL),
- REGULATOR_SUPPLY("iris_vddrfa", "wcnss_wlan.0"),
+ REGULATOR_SUPPLY("8917_l1", NULL),
};
VREG_CONSUMERS(L2) = {
- REGULATOR_SUPPLY("8038_l2", NULL),
+ REGULATOR_SUPPLY("8917_l2", NULL),
REGULATOR_SUPPLY("iris_vdddig", "wcnss_wlan.0"),
REGULATOR_SUPPLY("dsi_vdda", "mipi_dsi.1"),
REGULATOR_SUPPLY("mipi_csi_vdd", "msm_csid.0"),
@@ -35,53 +39,152 @@
REGULATOR_SUPPLY("mipi_csi_vdd", "msm_csid.2"),
};
VREG_CONSUMERS(L3) = {
- REGULATOR_SUPPLY("8038_l3", NULL),
+ REGULATOR_SUPPLY("8917_l3", NULL),
REGULATOR_SUPPLY("HSUSB_3p3", "msm_otg"),
};
VREG_CONSUMERS(L4) = {
- REGULATOR_SUPPLY("8038_l4", NULL),
+ REGULATOR_SUPPLY("8917_l4", NULL),
REGULATOR_SUPPLY("HSUSB_1p8", "msm_otg"),
REGULATOR_SUPPLY("iris_vddxo", "wcnss_wlan.0"),
};
VREG_CONSUMERS(L5) = {
- REGULATOR_SUPPLY("8038_l5", NULL),
+ REGULATOR_SUPPLY("8917_l5", NULL),
REGULATOR_SUPPLY("sdc_vdd", "msm_sdcc.1"),
};
VREG_CONSUMERS(L6) = {
- REGULATOR_SUPPLY("8038_l6", NULL),
+ REGULATOR_SUPPLY("8917_l6", NULL),
REGULATOR_SUPPLY("sdc_vdd", "msm_sdcc.3"),
};
VREG_CONSUMERS(L7) = {
- REGULATOR_SUPPLY("8038_l7", NULL),
+ REGULATOR_SUPPLY("8917_l7", NULL),
+ REGULATOR_SUPPLY("sdc_vdd_io", "msm_sdcc.3"),
};
VREG_CONSUMERS(L8) = {
- REGULATOR_SUPPLY("8038_l8", NULL),
+ REGULATOR_SUPPLY("8917_l8", NULL),
REGULATOR_SUPPLY("dsi_vdc", "mipi_dsi.1"),
};
VREG_CONSUMERS(L9) = {
- REGULATOR_SUPPLY("8038_l9", NULL),
+ REGULATOR_SUPPLY("8917_l9", NULL),
REGULATOR_SUPPLY("vdd_ana", "3-004a"),
REGULATOR_SUPPLY("vdd", "3-0024"),
- REGULATOR_SUPPLY("cam_vana", "4-001a"),
- REGULATOR_SUPPLY("cam_vana", "4-006c"),
- REGULATOR_SUPPLY("cam_vana", "4-0048"),
- REGULATOR_SUPPLY("cam_vaf", "4-001a"),
- REGULATOR_SUPPLY("cam_vaf", "4-006c"),
- REGULATOR_SUPPLY("cam_vaf", "4-0048"),
- REGULATOR_SUPPLY("cam_vana", "4-0020"),
- REGULATOR_SUPPLY("cam_vaf", "4-0020"),
REGULATOR_SUPPLY("vdd", "12-0018"),
REGULATOR_SUPPLY("vdd", "12-0068"),
};
VREG_CONSUMERS(L10) = {
- REGULATOR_SUPPLY("8038_l10", NULL),
+ REGULATOR_SUPPLY("8917_l10", NULL),
REGULATOR_SUPPLY("iris_vddpa", "wcnss_wlan.0"),
};
VREG_CONSUMERS(L11) = {
- REGULATOR_SUPPLY("8038_l11", NULL),
+ REGULATOR_SUPPLY("8917_l11", NULL),
+ REGULATOR_SUPPLY("cam_vana", "4-001a"),
+ REGULATOR_SUPPLY("cam_vana", "4-006c"),
+ REGULATOR_SUPPLY("cam_vana", "4-0048"),
+ REGULATOR_SUPPLY("cam_vana", "4-0020"),
+};
+VREG_CONSUMERS(L12) = {
+ REGULATOR_SUPPLY("8917_l12", NULL),
+ REGULATOR_SUPPLY("cam_vdig", "4-001a"),
+ REGULATOR_SUPPLY("cam_vdig", "4-006c"),
+ REGULATOR_SUPPLY("cam_vdig", "4-0048"),
+ REGULATOR_SUPPLY("cam_vdig", "4-0020"),
+};
+VREG_CONSUMERS(L14) = {
+ REGULATOR_SUPPLY("8917_l14", NULL),
+ REGULATOR_SUPPLY("pa_therm", "pm8xxx-adc"),
+};
+VREG_CONSUMERS(L15) = {
+ REGULATOR_SUPPLY("8917_l15", NULL),
+};
+VREG_CONSUMERS(L16) = {
+ REGULATOR_SUPPLY("8917_l16", NULL),
+ REGULATOR_SUPPLY("cam_vaf", "4-001a"),
+ REGULATOR_SUPPLY("cam_vaf", "4-006c"),
+ REGULATOR_SUPPLY("cam_vaf", "4-0048"),
+ REGULATOR_SUPPLY("cam_vaf", "4-0020"),
+};
+VREG_CONSUMERS(L17) = {
+ REGULATOR_SUPPLY("8917_l17", NULL),
+};
+VREG_CONSUMERS(L18) = {
+ REGULATOR_SUPPLY("8917_l18", NULL),
+};
+VREG_CONSUMERS(L21) = {
+ REGULATOR_SUPPLY("8917_l21", NULL),
+};
+VREG_CONSUMERS(L22) = {
+ REGULATOR_SUPPLY("8917_l22", NULL),
+};
+VREG_CONSUMERS(L23) = {
+ REGULATOR_SUPPLY("8917_l23", NULL),
+ REGULATOR_SUPPLY("dsi_vddio", "mipi_dsi.1"),
+ REGULATOR_SUPPLY("hdmi_avdd", "hdmi_msm.0"),
+ REGULATOR_SUPPLY("hdmi_vcc", "hdmi_msm.0"),
+ REGULATOR_SUPPLY("pll_vdd", "pil_riva"),
+ REGULATOR_SUPPLY("pll_vdd", "pil_qdsp6v4.1"),
+ REGULATOR_SUPPLY("pll_vdd", "pil_qdsp6v4.2"),
+};
+VREG_CONSUMERS(L24) = {
+ REGULATOR_SUPPLY("8917_l24", NULL),
+ REGULATOR_SUPPLY("riva_vddmx", "wcnss_wlan.0"),
+};
+VREG_CONSUMERS(L25) = {
+ REGULATOR_SUPPLY("8917_l25", NULL),
+ REGULATOR_SUPPLY("VDDD_CDC_D", "sitar-slim"),
+ REGULATOR_SUPPLY("CDC_VDDA_A_1P2V", "sitar-slim"),
+ REGULATOR_SUPPLY("VDDD_CDC_D", "sitar1p1-slim"),
+ REGULATOR_SUPPLY("CDC_VDDA_A_1P2V", "sitar1p1-slim"),
+ REGULATOR_SUPPLY("mhl_avcc12", "0-0039"),
+};
+VREG_CONSUMERS(L26) = {
+ REGULATOR_SUPPLY("8921_l26", NULL),
+ REGULATOR_SUPPLY("core_vdd", "pil_qdsp6v4.0"),
+};
+VREG_CONSUMERS(L27) = {
+ REGULATOR_SUPPLY("8921_l27", NULL),
+ REGULATOR_SUPPLY("core_vdd", "pil_qdsp6v4.2"),
+};
+VREG_CONSUMERS(L28) = {
+ REGULATOR_SUPPLY("8921_l28", NULL),
+ REGULATOR_SUPPLY("core_vdd", "pil_qdsp6v4.1"),
+};
+VREG_CONSUMERS(L29) = {
+ REGULATOR_SUPPLY("8921_l29", NULL),
+};
+VREG_CONSUMERS(L30) = {
+ REGULATOR_SUPPLY("8917_l30", NULL),
+};
+VREG_CONSUMERS(L31) = {
+ REGULATOR_SUPPLY("8917_l31", NULL),
+};
+VREG_CONSUMERS(L32) = {
+ REGULATOR_SUPPLY("8917_l32", NULL),
+};
+VREG_CONSUMERS(L33) = {
+ REGULATOR_SUPPLY("8917_l33", NULL),
+};
+VREG_CONSUMERS(L34) = {
+ REGULATOR_SUPPLY("8917_l34", NULL),
+};
+VREG_CONSUMERS(L35) = {
+ REGULATOR_SUPPLY("8917_l35", NULL),
+};
+VREG_CONSUMERS(L36) = {
+ REGULATOR_SUPPLY("8917_l36", NULL),
+};
+VREG_CONSUMERS(S1) = {
+ REGULATOR_SUPPLY("8917_s1", NULL),
+};
+VREG_CONSUMERS(S2) = {
+ REGULATOR_SUPPLY("8917_s2", NULL),
+ REGULATOR_SUPPLY("iris_vddrfa", "wcnss_wlan.0"),
+};
+VREG_CONSUMERS(S3) = {
+ REGULATOR_SUPPLY("8917_s3", NULL),
+ REGULATOR_SUPPLY("riva_vddcx", "wcnss_wlan.0"),
+};
+VREG_CONSUMERS(S4) = {
+ REGULATOR_SUPPLY("8917_s4", NULL),
REGULATOR_SUPPLY("vdd_dig", "3-004a"),
- REGULATOR_SUPPLY("iris_vddio", "wcnss_wlan.0"),
- REGULATOR_SUPPLY("riva_vddpx", "wcnss_wlan.0"),
REGULATOR_SUPPLY("sdc_vdd_io", "msm_sdcc.1"),
REGULATOR_SUPPLY("VDDIO_CDC", "sitar-slim"),
REGULATOR_SUPPLY("CDC_VDDA_TX", "sitar-slim"),
@@ -91,132 +194,71 @@
REGULATOR_SUPPLY("CDC_VDDA_RX", "sitar1p1-slim"),
REGULATOR_SUPPLY("vddp", "0-0048"),
REGULATOR_SUPPLY("mhl_iovcc18", "0-0039"),
-};
-VREG_CONSUMERS(L12) = {
- REGULATOR_SUPPLY("8038_l12", NULL),
- REGULATOR_SUPPLY("cam_vdig", "4-001a"),
- REGULATOR_SUPPLY("cam_vdig", "4-006c"),
- REGULATOR_SUPPLY("cam_vdig", "4-0048"),
- REGULATOR_SUPPLY("cam_vdig", "4-0020"),
-};
-VREG_CONSUMERS(L13) = {
- REGULATOR_SUPPLY("8038_l13", NULL),
-};
-VREG_CONSUMERS(L14) = {
- REGULATOR_SUPPLY("8038_l14", NULL),
- REGULATOR_SUPPLY("pa_therm", "pm8xxx-adc"),
-};
-VREG_CONSUMERS(L15) = {
- REGULATOR_SUPPLY("8038_l15", NULL),
-};
-VREG_CONSUMERS(L16) = {
- REGULATOR_SUPPLY("8038_l16", NULL),
- REGULATOR_SUPPLY("core_vdd", "pil_qdsp6v4.2"),
-};
-VREG_CONSUMERS(L17) = {
- REGULATOR_SUPPLY("8038_l17", NULL),
-};
-VREG_CONSUMERS(L18) = {
- REGULATOR_SUPPLY("8038_l18", NULL),
-};
-VREG_CONSUMERS(L19) = {
- REGULATOR_SUPPLY("8038_l19", NULL),
- REGULATOR_SUPPLY("core_vdd", "pil_qdsp6v4.1"),
-};
-VREG_CONSUMERS(L20) = {
- REGULATOR_SUPPLY("8038_l20", NULL),
- REGULATOR_SUPPLY("VDDD_CDC_D", "sitar-slim"),
- REGULATOR_SUPPLY("CDC_VDDA_A_1P2V", "sitar-slim"),
- REGULATOR_SUPPLY("VDDD_CDC_D", "sitar1p1-slim"),
- REGULATOR_SUPPLY("CDC_VDDA_A_1P2V", "sitar1p1-slim"),
- REGULATOR_SUPPLY("mhl_avcc12", "0-0039"),
-};
-VREG_CONSUMERS(L21) = {
- REGULATOR_SUPPLY("8038_l21", NULL),
-};
-VREG_CONSUMERS(L22) = {
- REGULATOR_SUPPLY("8038_l22", NULL),
- REGULATOR_SUPPLY("sdc_vdd_io", "msm_sdcc.3"),
-};
-VREG_CONSUMERS(L23) = {
- REGULATOR_SUPPLY("8038_l23", NULL),
- REGULATOR_SUPPLY("dsi_vddio", "mipi_dsi.1"),
- REGULATOR_SUPPLY("hdmi_avdd", "hdmi_msm.0"),
- REGULATOR_SUPPLY("hdmi_vcc", "hdmi_msm.0"),
- REGULATOR_SUPPLY("pll_vdd", "pil_riva"),
- REGULATOR_SUPPLY("pll_vdd", "pil_qdsp6v4.1"),
- REGULATOR_SUPPLY("pll_vdd", "pil_qdsp6v4.2"),
-};
-VREG_CONSUMERS(L24) = {
- REGULATOR_SUPPLY("8038_l24", NULL),
- REGULATOR_SUPPLY("riva_vddmx", "wcnss_wlan.0"),
-};
-VREG_CONSUMERS(L25) = {
- REGULATOR_SUPPLY("8038_l25", NULL),
-};
-VREG_CONSUMERS(L26) = {
- REGULATOR_SUPPLY("8038_l26", NULL),
-};
-VREG_CONSUMERS(L27) = {
- REGULATOR_SUPPLY("8038_l27", NULL),
- REGULATOR_SUPPLY("core_vdd", "pil_qdsp6v4.0"),
-};
-VREG_CONSUMERS(S1) = {
- REGULATOR_SUPPLY("8038_s1", NULL),
- REGULATOR_SUPPLY("riva_vddcx", "wcnss_wlan.0"),
-};
-VREG_CONSUMERS(S2) = {
- REGULATOR_SUPPLY("8038_s2", NULL),
-};
-VREG_CONSUMERS(S3) = {
- REGULATOR_SUPPLY("8038_s3", NULL),
-};
-VREG_CONSUMERS(S4) = {
- REGULATOR_SUPPLY("8038_s4", NULL),
REGULATOR_SUPPLY("CDC_VDD_CP", "sitar-slim"),
REGULATOR_SUPPLY("CDC_VDD_CP", "sitar1p1-slim"),
};
VREG_CONSUMERS(S5) = {
- REGULATOR_SUPPLY("8038_s5", NULL),
+ REGULATOR_SUPPLY("8917_s5", NULL),
REGULATOR_SUPPLY("krait0", "acpuclk-8627"),
REGULATOR_SUPPLY("krait0", "acpuclk-8930"),
REGULATOR_SUPPLY("krait0", "acpuclk-8930aa"),
};
VREG_CONSUMERS(S6) = {
- REGULATOR_SUPPLY("8038_s6", NULL),
+ REGULATOR_SUPPLY("8917_s6", NULL),
REGULATOR_SUPPLY("krait1", "acpuclk-8627"),
REGULATOR_SUPPLY("krait1", "acpuclk-8930"),
REGULATOR_SUPPLY("krait1", "acpuclk-8930aa"),
};
-VREG_CONSUMERS(LVS1) = {
- REGULATOR_SUPPLY("8038_lvs1", NULL),
- REGULATOR_SUPPLY("cam_vio", "4-001a"),
- REGULATOR_SUPPLY("cam_vio", "4-006c"),
- REGULATOR_SUPPLY("cam_vio", "4-0048"),
- REGULATOR_SUPPLY("cam_vio", "4-0020"),
+VREG_CONSUMERS(S7) = {
+ REGULATOR_SUPPLY("8917_s7", NULL),
};
-VREG_CONSUMERS(LVS2) = {
- REGULATOR_SUPPLY("8038_lvs2", NULL),
+VREG_CONSUMERS(S8) = {
+ REGULATOR_SUPPLY("8917_s8", NULL),
+};
+VREG_CONSUMERS(LVS1) = {
+ REGULATOR_SUPPLY("8917_lvs1", NULL),
+ REGULATOR_SUPPLY("iris_vddio", "wcnss_wlan.0"),
+ REGULATOR_SUPPLY("riva_vddpx", "wcnss_wlan.0"),
+};
+VREG_CONSUMERS(LVS3) = {
+ REGULATOR_SUPPLY("8917_lvs3", NULL),
+};
+VREG_CONSUMERS(LVS4) = {
+ REGULATOR_SUPPLY("8917_lvs4", NULL),
REGULATOR_SUPPLY("vcc_i2c", "3-004a"),
REGULATOR_SUPPLY("vcc_i2c", "3-0024"),
REGULATOR_SUPPLY("vcc_i2c", "0-0048"),
REGULATOR_SUPPLY("vddio", "12-0018"),
REGULATOR_SUPPLY("vlogic", "12-0068"),
};
-VREG_CONSUMERS(EXT_5V) = {
- REGULATOR_SUPPLY("ext_5v", NULL),
+VREG_CONSUMERS(LVS5) = {
+ REGULATOR_SUPPLY("8917_lvs5", NULL),
+ REGULATOR_SUPPLY("cam_vio", "4-001a"),
+ REGULATOR_SUPPLY("cam_vio", "4-006c"),
+ REGULATOR_SUPPLY("cam_vio", "4-0048"),
+ REGULATOR_SUPPLY("cam_vio", "4-0020"),
+};
+VREG_CONSUMERS(LVS6) = {
+ REGULATOR_SUPPLY("8917_lvs6", NULL),
+};
+VREG_CONSUMERS(LVS7) = {
+ REGULATOR_SUPPLY("8917_lvs7", NULL),
+};
+VREG_CONSUMERS(USB_OTG) = {
+ REGULATOR_SUPPLY("8921_usb_otg", NULL),
+ REGULATOR_SUPPLY("vbus_otg", "msm_otg"),
+};
+VREG_CONSUMERS(BOOST) = {
+ REGULATOR_SUPPLY("8917_boost", NULL),
REGULATOR_SUPPLY("hdmi_mvs", "hdmi_msm.0"),
REGULATOR_SUPPLY("mhl_usb_hs_switch", "msm_otg"),
};
-VREG_CONSUMERS(EXT_OTG_SW) = {
- REGULATOR_SUPPLY("ext_otg_sw", NULL),
- REGULATOR_SUPPLY("vbus_otg", "msm_otg"),
-};
VREG_CONSUMERS(VDD_DIG_CORNER) = {
REGULATOR_SUPPLY("vdd_dig_corner", NULL),
REGULATOR_SUPPLY("hsusb_vdd_dig", "msm_otg"),
};
+
#define PM8XXX_VREG_INIT(_id, _name, _min_uV, _max_uV, _modes, _ops, \
_apply_uV, _pull_down, _always_on, _supply_regulator, \
_system_uA, _enable_time, _reg_id) \
@@ -286,7 +328,7 @@
_pull_down, _always_on, _supply_regulator, 0, _enable_time, \
_reg_id)
-#define PM8XXX_NCP(_id, _name, _always_on, _min_uV, _max_uV, _enable_time, \
+#define PM8XXX_BOOST(_id, _name, _always_on, _min_uV, _max_uV, _enable_time, \
_supply_regulator, _reg_id) \
PM8XXX_VREG_INIT(_id, _name, _min_uV, _max_uV, 0, \
REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_STATUS, 0, 0, \
@@ -332,7 +374,7 @@
.consumer_supplies = vreg_consumers_##_id, \
.supply_regulator = _supply_regulator, \
}, \
- .id = RPM_VREG_ID_PM8038_##_id, \
+ .id = RPM_VREG_ID_PM8917_##_id, \
.default_uV = _default_uV, \
.peak_uA = _peak_uA, \
.avg_uA = _avg_uA, \
@@ -414,7 +456,7 @@
.consumer_supplies = vreg_consumers_##_id##_PC, \
.supply_regulator = _supply_regulator, \
}, \
- .id = RPM_VREG_ID_PM8038_##_id##_PC, \
+ .id = RPM_VREG_ID_PM8917_##_id##_PC, \
.pin_fn = RPM_VREG_PIN_FN_8930_##_pin_fn, \
.pin_ctrl = _pin_ctrl, \
}
@@ -449,93 +491,122 @@
/* GPIO regulator constraints */
struct gpio_regulator_platform_data
-msm8930_gpio_regulator_pdata[] __devinitdata = {
+msm8930_pm8917_gpio_regulator_pdata[] __devinitdata = {
/* ID vreg_name gpio_label gpio supply */
- GPIO_VREG(EXT_5V, "ext_5v", "ext_5v_en", 63, NULL),
- GPIO_VREG(EXT_OTG_SW, "ext_otg_sw", "ext_otg_sw_en", 97, "ext_5v"),
};
/* SAW regulator constraints */
-struct regulator_init_data msm8930_saw_regulator_core0_pdata =
+struct regulator_init_data msm8930_pm8917_saw_regulator_core0_pdata =
/* ID vreg_name min_uV max_uV */
- SAW_VREG_INIT(S5, "8038_s5", 850000, 1300000);
-struct regulator_init_data msm8930_saw_regulator_core1_pdata =
- SAW_VREG_INIT(S6, "8038_s6", 850000, 1300000);
+ SAW_VREG_INIT(S5, "8917_s5", 850000, 1300000);
+struct regulator_init_data msm8930_pm8917_saw_regulator_core1_pdata =
+ SAW_VREG_INIT(S6, "8917_s6", 850000, 1300000);
-/* PM8038 regulator constraints */
+/* PM8917 regulator constraints */
struct pm8xxx_regulator_platform_data
-msm8930_pm8038_regulator_pdata[] __devinitdata = {
+msm8930_pm8917_regulator_pdata[] __devinitdata = {
/*
- * ID name always_on pd min_uV max_uV en_t supply
+ * ID name always_on pd min_uV max_uV en_t supply
* system_uA reg_ID
*/
- PM8XXX_NLDO1200(L16, "8038_l16", 0, 1, 375000, 1050000, 200, "8038_s3",
+ PM8XXX_NLDO1200(L26, "8921_l26", 0, 1, 375000, 1050000, 200, "8917_s7",
0, 0),
- PM8XXX_NLDO1200(L19, "8038_l19", 0, 1, 375000, 1050000, 200, "8038_s3",
+ PM8XXX_NLDO1200(L27, "8921_l27", 0, 1, 375000, 1050000, 200, "8917_s7",
0, 1),
- PM8XXX_NLDO1200(L27, "8038_l27", 0, 1, 375000, 1050000, 200, "8038_s3",
+ PM8XXX_NLDO1200(L28, "8921_l28", 0, 1, 375000, 1050000, 200, "8917_s7",
0, 2),
+ PM8XXX_LDO(L29, "8921_l29", 0, 1, 1800000, 1800000, 200, "8917_s8",
+ 0, 3),
+ PM8XXX_LDO(L30, "8917_l30", 0, 1, 1800000, 1800000, 200, NULL,
+ 0, 4),
+ PM8XXX_LDO(L31, "8917_l31", 0, 1, 1800000, 1800000, 200, NULL,
+ 0, 5),
+ PM8XXX_LDO(L32, "8917_l32", 0, 1, 2800000, 2800000, 200, NULL,
+ 0, 6),
+ PM8XXX_LDO(L33, "8917_l33", 0, 1, 2800000, 2800000, 200, NULL,
+ 0, 7),
+ PM8XXX_LDO(L34, "8917_l34", 0, 1, 1800000, 1800000, 200, NULL,
+ 0, 8),
+ PM8XXX_LDO(L35, "8917_l35", 0, 1, 3000000, 3000000, 200, NULL,
+ 0, 9),
+ PM8XXX_LDO(L36, "8917_l36", 0, 1, 1800000, 1800000, 200, NULL,
+ 0, 10),
+ /*
+ * ID name always_on min_uV max_uV en_t supply reg_ID
+ */
+ PM8XXX_BOOST(BOOST, "8917_boost", 0, 5000000, 5000000, 500, NULL, 11),
+
+ /* ID name always_on pd en_t supply reg_ID */
+ PM8XXX_VS300(USB_OTG, "8921_usb_otg", 0, 1, 0, "8917_boost", 12),
};
static struct rpm_regulator_init_data
msm8930_rpm_regulator_init_data[] __devinitdata = {
/* ID a_on pd ss min_uV max_uV supply sys_uA freq fm ss_fm */
- RPM_SMPS(S1, 0, 1, 1, 500000, 1150000, NULL, 100000, 4p80, AUTO, LPM),
- RPM_SMPS(S2, 1, 1, 1, 1400000, 1400000, NULL, 100000, 1p60, AUTO, LPM),
- RPM_SMPS(S3, 0, 1, 1, 1150000, 1150000, NULL, 100000, 3p20, AUTO, LPM),
- RPM_SMPS(S4, 1, 1, 1, 1950000, 2200000, NULL, 100000, 1p60, AUTO, LPM),
+ RPM_SMPS(S1, 1, 1, 0, 1300000, 1300000, NULL, 100000, 3p20, NONE, NONE),
+ RPM_SMPS(S2, 0, 1, 0, 1300000, 1300000, NULL, 0, 1p60, NONE, NONE),
+ RPM_SMPS(S3, 0, 1, 1, 500000, 1150000, NULL, 100000, 4p80, AUTO, LPM),
+ RPM_SMPS(S4, 1, 1, 0, 1800000, 1800000, NULL, 100000, 1p60, AUTO, LPM),
+ RPM_SMPS(S7, 0, 1, 0, 1150000, 1150000, NULL, 100000, 3p20, NONE, NONE),
+ RPM_SMPS(S8, 1, 1, 1, 2050000, 2050000, NULL, 100000, 1p60, NONE, NONE),
/* ID a_on pd ss min_uV max_uV supply sys_uA init_ip */
- RPM_LDO(L1, 0, 1, 0, 1300000, 1300000, "8038_s2", 0, 0),
- RPM_LDO(L2, 0, 1, 0, 1200000, 1200000, "8038_s2", 0, 0),
+ RPM_LDO(L1, 1, 1, 0, 1050000, 1050000, "8917_s4", 0, 10000),
+ RPM_LDO(L2, 0, 1, 0, 1200000, 1200000, "8917_s4", 0, 0),
RPM_LDO(L3, 0, 1, 0, 3075000, 3075000, NULL, 0, 0),
RPM_LDO(L4, 1, 1, 0, 1800000, 1800000, NULL, 10000, 10000),
RPM_LDO(L5, 0, 1, 0, 2950000, 2950000, NULL, 0, 0),
RPM_LDO(L6, 0, 1, 0, 2950000, 2950000, NULL, 0, 0),
- RPM_LDO(L7, 0, 1, 0, 2050000, 2050000, "8038_s4", 0, 0),
+ RPM_LDO(L7, 1, 1, 0, 1850000, 2950000, NULL, 10000, 10000),
RPM_LDO(L8, 0, 1, 0, 2800000, 2800000, NULL, 0, 0),
RPM_LDO(L9, 0, 1, 0, 2850000, 2850000, NULL, 0, 0),
RPM_LDO(L10, 0, 1, 0, 2900000, 2900000, NULL, 0, 0),
- RPM_LDO(L11, 1, 1, 0, 1800000, 1800000, "8038_s4", 10000, 10000),
- RPM_LDO(L12, 0, 1, 0, 1200000, 1200000, "8038_s2", 0, 0),
- RPM_LDO(L13, 0, 0, 0, 2220000, 2220000, NULL, 0, 0),
+ RPM_LDO(L11, 0, 1, 0, 2850000, 2850000, NULL, 0, 0),
+ RPM_LDO(L12, 0, 1, 0, 1200000, 1200000, "8917_s4", 0, 0),
RPM_LDO(L14, 0, 1, 0, 1800000, 1800000, NULL, 0, 0),
RPM_LDO(L15, 0, 1, 0, 1800000, 2950000, NULL, 0, 0),
+ RPM_LDO(L16, 0, 1, 0, 2850000, 2850000, NULL, 0, 0),
RPM_LDO(L17, 0, 1, 0, 1800000, 2950000, NULL, 0, 0),
- RPM_LDO(L18, 0, 1, 0, 1800000, 1800000, NULL, 0, 0),
- RPM_LDO(L20, 1, 1, 0, 1250000, 1250000, "8038_s2", 10000, 10000),
- RPM_LDO(L21, 0, 1, 0, 1900000, 1900000, "8038_s4", 0, 0),
- RPM_LDO(L22, 1, 1, 0, 1850000, 2950000, NULL, 10000, 10000),
- RPM_LDO(L23, 1, 1, 1, 1800000, 1800000, "8038_s4", 0, 0),
- RPM_LDO(L24, 0, 1, 1, 500000, 1150000, "8038_s2", 10000, 10000),
- RPM_LDO(L25, 0, 0, 0, 1740000, 1740000, "8038_l13", 0, 0),
- RPM_LDO(L26, 1, 1, 0, 1050000, 1050000, "8038_s2", 10000, 10000),
+ RPM_LDO(L18, 0, 1, 0, 1200000, 1200000, "8917_s4", 0, 0),
+ RPM_LDO(L21, 0, 1, 0, 1900000, 1900000, "8917_s8", 0, 0),
+ RPM_LDO(L22, 0, 1, 0, 2750000, 2750000, NULL, 0, 0),
+ RPM_LDO(L23, 1, 1, 1, 1800000, 1800000, "8917_s8", 10000, 10000),
+ RPM_LDO(L24, 0, 1, 1, 500000, 1150000, "8917_s1", 10000, 10000),
+ RPM_LDO(L25, 1, 1, 0, 1250000, 1250000, "8917_s1", 10000, 10000),
/* ID a_on pd ss supply */
- RPM_VS(LVS1, 0, 1, 0, "8038_l11"),
- RPM_VS(LVS2, 0, 1, 0, "8038_l11"),
+ RPM_VS(LVS1, 0, 1, 0, "8917_s4"),
+ RPM_VS(LVS3, 0, 1, 0, "8917_s4"),
+ RPM_VS(LVS4, 0, 1, 0, "8917_s4"),
+ RPM_VS(LVS5, 0, 1, 0, "8917_s4"),
+ RPM_VS(LVS6, 0, 1, 0, "8917_s4"),
+ RPM_VS(LVS7, 0, 1, 0, "8917_s4"),
/* ID a_on ss min_corner max_corner supply */
RPM_CORNER(VDD_DIG_CORNER, 0, 1, RPM_VREG_CORNER_NONE,
RPM_VREG_CORNER_HIGH, NULL),
};
-int msm8930_pm8038_regulator_pdata_len __devinitdata =
- ARRAY_SIZE(msm8930_pm8038_regulator_pdata);
+int msm8930_pm8917_regulator_pdata_len __devinitdata =
+ ARRAY_SIZE(msm8930_pm8917_regulator_pdata);
#define RPM_REG_MAP(_id, _sleep_also, _voter, _supply, _dev_name) \
{ \
- .vreg_id = RPM_VREG_ID_PM8038_##_id, \
+ .vreg_id = RPM_VREG_ID_PM8917_##_id, \
.sleep_also = _sleep_also, \
.voter = _voter, \
.supply = _supply, \
.dev_name = _dev_name, \
}
+
static struct rpm_regulator_consumer_mapping
msm_rpm_regulator_consumer_mapping[] __devinitdata = {
- RPM_REG_MAP(L23, 0, 1, "krait0_hfpll", "acpuclk-8930"),
- RPM_REG_MAP(L23, 0, 2, "krait1_hfpll", "acpuclk-8930"),
- RPM_REG_MAP(L23, 0, 6, "l2_hfpll", "acpuclk-8930"),
+ RPM_REG_MAP(L23, 0, 1, "krait0_l23", "acpuclk-8930"),
+ RPM_REG_MAP(S8, 0, 1, "krait0_s8", "acpuclk-8930"),
+ RPM_REG_MAP(L23, 0, 2, "krait1_l23", "acpuclk-8930"),
+ RPM_REG_MAP(S8, 0, 2, "krait1_s8", "acpuclk-8930"),
+ RPM_REG_MAP(L23, 0, 6, "l2_l23", "acpuclk-8930"),
+ RPM_REG_MAP(S8, 0, 6, "l2_s8", "acpuclk-8930"),
RPM_REG_MAP(L24, 0, 1, "krait0_mem", "acpuclk-8930"),
RPM_REG_MAP(L24, 0, 2, "krait1_mem", "acpuclk-8930"),
RPM_REG_MAP(VDD_DIG_CORNER, 0, 1, "krait0_dig", "acpuclk-8930"),
@@ -558,12 +629,13 @@
RPM_REG_MAP(VDD_DIG_CORNER, 0, 2, "krait1_dig", "acpuclk-8930aa"),
};
-struct rpm_regulator_platform_data msm8930_rpm_regulator_pdata __devinitdata = {
+struct rpm_regulator_platform_data
+msm8930_pm8917_rpm_regulator_pdata __devinitdata = {
.init_data = msm8930_rpm_regulator_init_data,
.num_regulators = ARRAY_SIZE(msm8930_rpm_regulator_init_data),
- .version = RPM_VREG_VERSION_8930,
- .vreg_id_vdd_mem = RPM_VREG_ID_PM8038_L24,
- .vreg_id_vdd_dig = RPM_VREG_ID_PM8038_VDD_DIG_CORNER,
+ .version = RPM_VREG_VERSION_8930_PM8917,
+ .vreg_id_vdd_mem = RPM_VREG_ID_PM8917_L24,
+ .vreg_id_vdd_dig = RPM_VREG_ID_PM8917_VDD_DIG_CORNER,
.consumer_map = msm_rpm_regulator_consumer_mapping,
.consumer_map_len = ARRAY_SIZE(msm_rpm_regulator_consumer_mapping),
};
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index a7147b5..2b1c665 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -100,6 +100,7 @@
#include "pm-boot.h"
#include "msm_watchdog.h"
#include "board-8930.h"
+#include "acpuclock-krait.h"
static struct platform_device msm_fm_platform_init = {
.name = "iris_fm",
@@ -791,7 +792,7 @@
.regulator = {
{
.name = "CDC_VDD_CP",
- .min_uV = 1950000,
+ .min_uV = 1800000,
.max_uV = 2200000,
.optimum_uA = WCD9XXX_CDC_VDDA_CP_CUR_MAX,
},
@@ -857,7 +858,7 @@
.regulator = {
{
.name = "CDC_VDD_CP",
- .min_uV = 1950000,
+ .min_uV = 1800000,
.max_uV = 2200000,
.optimum_uA = WCD9XXX_CDC_VDDA_CP_CUR_MAX,
},
@@ -1656,18 +1657,26 @@
#define ISA1200_HAP_EN_GPIO 77
#define ISA1200_HAP_LEN_GPIO 78
-#define ISA1200_HAP_CLK PM8038_GPIO_PM_TO_SYS(7)
+#define ISA1200_HAP_CLK_PM8038 PM8038_GPIO_PM_TO_SYS(7)
+#define ISA1200_HAP_CLK_PM8917 PM8917_GPIO_PM_TO_SYS(38)
static int isa1200_power(int on)
{
+ unsigned int gpio = ISA1200_HAP_CLK_PM8038;
+ enum pm8xxx_aux_clk_id clk_id = CLK_MP3_1;
int rc = 0;
- gpio_set_value_cansleep(ISA1200_HAP_CLK, !!on);
+ if (socinfo_get_pmic_model() == PMIC_MODEL_PM8917) {
+ gpio = ISA1200_HAP_CLK_PM8917;
+ clk_id = CLK_MP3_2;
+ }
+
+ gpio_set_value_cansleep(gpio, !!on);
if (on)
- rc = pm8xxx_aux_clk_control(CLK_MP3_1, XO_DIV_1, true);
+ rc = pm8xxx_aux_clk_control(clk_id, XO_DIV_1, true);
else
- rc = pm8xxx_aux_clk_control(CLK_MP3_1, XO_DIV_NONE, true);
+ rc = pm8xxx_aux_clk_control(clk_id, XO_DIV_NONE, true);
if (rc) {
pr_err("%s: unable to write aux clock register(%d)\n",
@@ -1679,29 +1688,33 @@
static int isa1200_dev_setup(bool enable)
{
+ unsigned int gpio = ISA1200_HAP_CLK_PM8038;
int rc = 0;
+ if (socinfo_get_pmic_model() == PMIC_MODEL_PM8917)
+ gpio = ISA1200_HAP_CLK_PM8917;
+
if (!enable)
goto fail_gpio_dir;
- rc = gpio_request(ISA1200_HAP_CLK, "haptics_clk");
+ rc = gpio_request(gpio, "haptics_clk");
if (rc) {
pr_err("%s: gpio_request for %d gpio failed rc(%d)\n",
- __func__, ISA1200_HAP_CLK, rc);
+ __func__, gpio, rc);
goto fail_gpio_req;
}
- rc = gpio_direction_output(ISA1200_HAP_CLK, 0);
+ rc = gpio_direction_output(gpio, 0);
if (rc) {
pr_err("%s: gpio_direction_output failed for %d gpio rc(%d)\n",
- __func__, ISA1200_HAP_CLK, rc);
+ __func__, gpio, rc);
goto fail_gpio_dir;
}
return 0;
fail_gpio_dir:
- gpio_free(ISA1200_HAP_CLK);
+ gpio_free(gpio);
fail_gpio_req:
return rc;
@@ -1938,12 +1951,13 @@
},
};
-#define MHL_POWER_GPIO PM8038_GPIO_PM_TO_SYS(MHL_GPIO_PWR_EN)
+#define MHL_POWER_GPIO_PM8038 PM8038_GPIO_PM_TO_SYS(MHL_GPIO_PWR_EN)
+#define MHL_POWER_GPIO_PM8917 PM8917_GPIO_PM_TO_SYS(25)
static struct msm_mhl_platform_data mhl_platform_data = {
.irq = MSM_GPIO_TO_INT(MHL_GPIO_INT),
.gpio_mhl_int = MHL_GPIO_INT,
.gpio_mhl_reset = MHL_GPIO_RESET,
- .gpio_mhl_power = MHL_POWER_GPIO,
+ .gpio_mhl_power = MHL_POWER_GPIO_PM8038,
.gpio_hdmi_mhl_mux = HDMI_MHL_MUX_GPIO,
};
@@ -1962,17 +1976,22 @@
#ifdef MSM8930_PHASE_2
-#define GPIO_VOLUME_UP PM8038_GPIO_PM_TO_SYS(3)
-#define GPIO_VOLUME_DOWN PM8038_GPIO_PM_TO_SYS(8)
-#define GPIO_CAMERA_SNAPSHOT PM8038_GPIO_PM_TO_SYS(10)
-#define GPIO_CAMERA_FOCUS PM8038_GPIO_PM_TO_SYS(11)
+#define GPIO_VOLUME_UP_PM8038 PM8038_GPIO_PM_TO_SYS(3)
+#define GPIO_VOLUME_DOWN_PM8038 PM8038_GPIO_PM_TO_SYS(8)
+#define GPIO_CAMERA_SNAPSHOT_PM8038 PM8038_GPIO_PM_TO_SYS(10)
+#define GPIO_CAMERA_FOCUS_PM8038 PM8038_GPIO_PM_TO_SYS(11)
-static struct gpio_keys_button keys_8930[] = {
+#define GPIO_VOLUME_UP_PM8917 PM8917_GPIO_PM_TO_SYS(27)
+#define GPIO_VOLUME_DOWN_PM8917 PM8917_GPIO_PM_TO_SYS(28)
+#define GPIO_CAMERA_SNAPSHOT_PM8917 PM8917_GPIO_PM_TO_SYS(36)
+#define GPIO_CAMERA_FOCUS_PM8917 PM8917_GPIO_PM_TO_SYS(37)
+
+static struct gpio_keys_button keys_8930_pm8038[] = {
{
.code = KEY_VOLUMEUP,
.type = EV_KEY,
.desc = "volume_up",
- .gpio = GPIO_VOLUME_UP,
+ .gpio = GPIO_VOLUME_UP_PM8038,
.wakeup = 1,
.active_low = 1,
.debounce_interval = 15,
@@ -1981,7 +2000,7 @@
.code = KEY_VOLUMEDOWN,
.type = EV_KEY,
.desc = "volume_down",
- .gpio = GPIO_VOLUME_DOWN,
+ .gpio = GPIO_VOLUME_DOWN_PM8038,
.wakeup = 1,
.active_low = 1,
.debounce_interval = 15,
@@ -1990,7 +2009,7 @@
.code = KEY_CAMERA_FOCUS,
.type = EV_KEY,
.desc = "camera_focus",
- .gpio = GPIO_CAMERA_FOCUS,
+ .gpio = GPIO_CAMERA_FOCUS_PM8038,
.wakeup = 1,
.active_low = 1,
.debounce_interval = 15,
@@ -1999,7 +2018,46 @@
.code = KEY_CAMERA_SNAPSHOT,
.type = EV_KEY,
.desc = "camera_snapshot",
- .gpio = GPIO_CAMERA_SNAPSHOT,
+ .gpio = GPIO_CAMERA_SNAPSHOT_PM8038,
+ .wakeup = 1,
+ .active_low = 1,
+ .debounce_interval = 15,
+ },
+};
+
+static struct gpio_keys_button keys_8930_pm8917[] = {
+ {
+ .code = KEY_VOLUMEUP,
+ .type = EV_KEY,
+ .desc = "volume_up",
+ .gpio = GPIO_VOLUME_UP_PM8917,
+ .wakeup = 1,
+ .active_low = 1,
+ .debounce_interval = 15,
+ },
+ {
+ .code = KEY_VOLUMEDOWN,
+ .type = EV_KEY,
+ .desc = "volume_down",
+ .gpio = GPIO_VOLUME_DOWN_PM8917,
+ .wakeup = 1,
+ .active_low = 1,
+ .debounce_interval = 15,
+ },
+ {
+ .code = KEY_CAMERA_FOCUS,
+ .type = EV_KEY,
+ .desc = "camera_focus",
+ .gpio = GPIO_CAMERA_FOCUS_PM8917,
+ .wakeup = 1,
+ .active_low = 1,
+ .debounce_interval = 15,
+ },
+ {
+ .code = KEY_CAMERA_SNAPSHOT,
+ .type = EV_KEY,
+ .desc = "camera_snapshot",
+ .gpio = GPIO_CAMERA_SNAPSHOT_PM8917,
.wakeup = 1,
.active_low = 1,
.debounce_interval = 15,
@@ -2008,8 +2066,8 @@
/* Add GPIO keys for 8930 */
static struct gpio_keys_platform_data gpio_keys_8930_pdata = {
- .buttons = keys_8930,
- .nbuttons = 4,
+ .buttons = keys_8930_pm8038,
+ .nbuttons = ARRAY_SIZE(keys_8930_pm8038),
};
static struct platform_device gpio_keys_8930 = {
@@ -2075,7 +2133,7 @@
.name = "saw-regulator",
.id = 0,
.dev = {
- .platform_data = &msm8930_saw_regulator_core0_pdata,
+ .platform_data = &msm8930_pm8038_saw_regulator_core0_pdata,
},
};
@@ -2083,7 +2141,7 @@
.name = "saw-regulator",
.id = 1,
.dev = {
- .platform_data = &msm8930_saw_regulator_core1_pdata,
+ .platform_data = &msm8930_pm8038_saw_regulator_core1_pdata,
},
};
@@ -2140,8 +2198,8 @@
.name = GPIO_REGULATOR_DEV_NAME,
.id = 63,
.dev = {
- .platform_data =
- &msm8930_gpio_regulator_pdata[MSM8930_GPIO_VREG_ID_EXT_5V],
+ .platform_data = &msm8930_pm8038_gpio_regulator_pdata[
+ MSM8930_GPIO_VREG_ID_EXT_5V],
},
};
@@ -2149,8 +2207,8 @@
.name = GPIO_REGULATOR_DEV_NAME,
.id = 97,
.dev = {
- .platform_data =
- &msm8930_gpio_regulator_pdata[MSM8930_GPIO_VREG_ID_EXT_OTG_SW],
+ .platform_data = &msm8930_pm8038_gpio_regulator_pdata[
+ MSM8930_GPIO_VREG_ID_EXT_OTG_SW],
},
};
@@ -2163,18 +2221,22 @@
#ifndef MSM8930_PHASE_2
.platform_data = &msm_rpm_regulator_pdata,
#else
- .platform_data = &msm8930_rpm_regulator_pdata,
+ .platform_data = &msm8930_pm8038_rpm_regulator_pdata,
#endif
},
};
-static struct platform_device *common_devices[] __initdata = {
+static struct platform_device *early_common_devices[] __initdata = {
&msm8960_device_dmov,
&msm_device_smd,
&msm8960_device_uart_gsbi5,
&msm_device_uart_dm6,
&msm_device_saw_core0,
&msm_device_saw_core1,
+};
+
+/* ext_5v and ext_otg_sw are present when using PM8038 */
+static struct platform_device *pmic_pm8038_devices[] __initdata = {
&msm8930_device_ext_5v_vreg,
#ifndef MSM8930_PHASE_2
&msm8930_device_ext_l2_vreg,
@@ -2183,6 +2245,14 @@
#ifdef MSM8930_PHASE_2
&msm8930_device_ext_otg_sw_vreg,
#endif
+};
+
+/* ext_5v and ext_otg_sw are not present when using PM8917 */
+static struct platform_device *pmic_pm8917_devices[] __initdata = {
+ &msm8960_device_ssbi_pmic,
+};
+
+static struct platform_device *common_devices[] __initdata = {
&msm_8960_q6_lpass,
&msm_8960_q6_mss_fw,
&msm_8960_q6_mss_sw,
@@ -2404,6 +2474,33 @@
},
};
+static struct msm_rpmrs_platform_data msm_rpmrs_data_pm8917 __initdata = {
+ .levels = &msm_rpmrs_levels[0],
+ .num_levels = ARRAY_SIZE(msm_rpmrs_levels),
+ .vdd_mem_levels = {
+ [MSM_RPMRS_VDD_MEM_RET_LOW] = 750000,
+ [MSM_RPMRS_VDD_MEM_RET_HIGH] = 750000,
+ [MSM_RPMRS_VDD_MEM_ACTIVE] = 1050000,
+ [MSM_RPMRS_VDD_MEM_MAX] = 1150000,
+ },
+ .vdd_dig_levels = {
+ [MSM_RPMRS_VDD_DIG_RET_LOW] = 0,
+ [MSM_RPMRS_VDD_DIG_RET_HIGH] = 0,
+ [MSM_RPMRS_VDD_DIG_ACTIVE] = 1,
+ [MSM_RPMRS_VDD_DIG_MAX] = 3,
+ },
+ .vdd_mask = 0x7FFFFF,
+ .rpmrs_target_id = {
+ [MSM_RPMRS_ID_PXO_CLK] = MSM_RPM_ID_PXO_CLK,
+ [MSM_RPMRS_ID_L2_CACHE_CTL] = MSM_RPM_ID_LAST,
+ [MSM_RPMRS_ID_VDD_DIG_0] = MSM_RPM_ID_VOLTAGE_CORNER,
+ [MSM_RPMRS_ID_VDD_DIG_1] = MSM_RPM_ID_LAST,
+ [MSM_RPMRS_ID_VDD_MEM_0] = MSM_RPM_ID_PM8917_L24_0,
+ [MSM_RPMRS_ID_VDD_MEM_1] = MSM_RPM_ID_PM8917_L24_1,
+ [MSM_RPMRS_ID_RPM_CTL] = MSM_RPM_ID_RPM_CTL,
+ },
+};
+
static struct msm_pm_boot_platform_data msm_pm_boot_pdata __initdata = {
.mode = MSM_PM_BOOT_CONFIG_TZ,
};
@@ -2570,22 +2667,54 @@
#endif
}
+/* Modify platform data values to match requirements for PM8917. */
+static void __init msm8930_pm8917_pdata_fixup(void)
+{
+ struct acpuclk_platform_data *pdata;
+
+ mhl_platform_data.gpio_mhl_power = MHL_POWER_GPIO_PM8917;
+
+ gpio_keys_8930_pdata.buttons = keys_8930_pm8917;
+ gpio_keys_8930_pdata.nbuttons = ARRAY_SIZE(keys_8930_pm8917);
+
+ msm_device_saw_core0.dev.platform_data
+ = &msm8930_pm8038_saw_regulator_core0_pdata;
+ msm_device_saw_core1.dev.platform_data
+ = &msm8930_pm8038_saw_regulator_core1_pdata;
+
+ msm8930_device_rpm_regulator.dev.platform_data
+ = &msm8930_pm8917_rpm_regulator_pdata;
+
+ pdata = msm8930_device_acpuclk.dev.platform_data;
+ pdata->uses_pm8917 = true;
+}
+
static void __init msm8930_cdp_init(void)
{
+ if (socinfo_get_pmic_model() == PMIC_MODEL_PM8917)
+ msm8930_pm8917_pdata_fixup();
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);
msm_thermal_init(&msm_thermal_pdata);
- BUG_ON(msm_rpm_init(&msm8930_rpm_data));
- BUG_ON(msm_rpmrs_levels_init(&msm_rpmrs_data));
+ if (socinfo_get_pmic_model() != PMIC_MODEL_PM8917) {
+ BUG_ON(msm_rpm_init(&msm8930_rpm_data));
+ BUG_ON(msm_rpmrs_levels_init(&msm_rpmrs_data));
+ } else {
+ BUG_ON(msm_rpm_init(&msm8930_rpm_data_pm8917));
+ BUG_ON(msm_rpmrs_levels_init(&msm_rpmrs_data_pm8917));
+ }
regulator_suppress_info_printing();
if (msm_xo_init())
pr_err("Failed to initialize XO votes\n");
platform_device_register(&msm8930_device_rpm_regulator);
- msm_clock_init(&msm8930_clock_init_data);
+ if (socinfo_get_pmic_model() == PMIC_MODEL_PM8917)
+ msm_clock_init(&msm8930_pm8917_clock_init_data);
+ else
+ msm_clock_init(&msm8930_clock_init_data);
msm_otg_pdata.phy_init_seq = hsusb_phy_init_seq;
msm8960_device_otg.dev.platform_data = &msm_otg_pdata;
android_usb_pdata.swfi_latency =
@@ -2622,6 +2751,14 @@
platform_device_register(&msm8930_device_acpuclk);
else if (cpu_is_msm8930aa())
platform_device_register(&msm8930aa_device_acpuclk);
+ platform_add_devices(early_common_devices,
+ ARRAY_SIZE(early_common_devices));
+ if (socinfo_get_pmic_model() != PMIC_MODEL_PM8917)
+ platform_add_devices(pmic_pm8038_devices,
+ ARRAY_SIZE(pmic_pm8038_devices));
+ else
+ platform_add_devices(pmic_pm8917_devices,
+ ARRAY_SIZE(pmic_pm8917_devices));
platform_add_devices(common_devices, ARRAY_SIZE(common_devices));
msm8930_add_vidc_device();
/*
@@ -2632,7 +2769,10 @@
#ifndef MSM8930_PHASE_2
msm8960_pm8921_gpio_mpp_init();
#else
- msm8930_pm8038_gpio_mpp_init();
+ if (socinfo_get_pmic_model() != PMIC_MODEL_PM8917)
+ msm8930_pm8038_gpio_mpp_init();
+ else
+ msm8930_pm8917_gpio_mpp_init();
#endif
platform_add_devices(cdp_devices, ARRAY_SIZE(cdp_devices));
#ifdef CONFIG_MSM_CAMERA
diff --git a/arch/arm/mach-msm/board-8930.h b/arch/arm/mach-msm/board-8930.h
index 9f6276c..7c1ad5b 100644
--- a/arch/arm/mach-msm/board-8930.h
+++ b/arch/arm/mach-msm/board-8930.h
@@ -17,6 +17,7 @@
#include <linux/regulator/msm-gpio-regulator.h>
#include <linux/mfd/pm8xxx/pm8038.h>
+#include <linux/mfd/pm8xxx/pm8921.h>
#include <linux/i2c.h>
#include <linux/i2c/sx150x.h>
#include <mach/irqs.h>
@@ -37,12 +38,23 @@
#endif
/* Macros assume PMIC GPIOs and MPPs start at 1 */
+/*
+ * PM8917 has more GPIOs and MPPs than PM8038; therefore, use PM8038 sizes at
+ * all times so that PM8038 vs PM8917 can be chosen at runtime. This results in
+ * the Linux GPIO address space being contiguous for PM8917 and discontiguous
+ * for PM8038.
+ */
#define PM8038_GPIO_BASE NR_GPIO_IRQS
#define PM8038_GPIO_PM_TO_SYS(pm_gpio) (pm_gpio - 1 + PM8038_GPIO_BASE)
-#define PM8038_MPP_BASE (PM8038_GPIO_BASE + PM8038_NR_GPIOS)
+#define PM8038_MPP_BASE (PM8038_GPIO_BASE + PM8917_NR_GPIOS)
#define PM8038_MPP_PM_TO_SYS(pm_gpio) (pm_gpio - 1 + PM8038_MPP_BASE)
#define PM8038_IRQ_BASE (NR_MSM_IRQS + NR_GPIO_IRQS)
+/* These PM8917 alias macros are used to provide context in board files. */
+#define PM8917_GPIO_PM_TO_SYS(pm_gpio) PM8038_GPIO_PM_TO_SYS(pm_gpio)
+#define PM8917_MPP_PM_TO_SYS(pm_gpio) PM8038_MPP_PM_TO_SYS(pm_gpio)
+#define PM8917_IRQ_BASE PM8038_IRQ_BASE
+
/*
* TODO: When physical 8930/PM8038 hardware becomes
* available, replace this block with 8930/pm8038 regulator
@@ -64,27 +76,36 @@
#define GPIO_VREG_ID_EXT_3P3V 2
#endif
-extern struct regulator_init_data msm8930_saw_regulator_core0_pdata;
-extern struct regulator_init_data msm8930_saw_regulator_core1_pdata;
+extern struct regulator_init_data msm8930_pm8038_saw_regulator_core0_pdata;
+extern struct regulator_init_data msm8930_pm8038_saw_regulator_core1_pdata;
+extern struct regulator_init_data msm8930_pm8917_saw_regulator_core0_pdata;
+extern struct regulator_init_data msm8930_pm8917_saw_regulator_core1_pdata;
extern struct pm8xxx_regulator_platform_data
msm8930_pm8038_regulator_pdata[] __devinitdata;
-
extern int msm8930_pm8038_regulator_pdata_len __devinitdata;
+extern struct pm8xxx_regulator_platform_data
+ msm8930_pm8917_regulator_pdata[] __devinitdata;
+extern int msm8930_pm8917_regulator_pdata_len __devinitdata;
+
#define MSM8930_GPIO_VREG_ID_EXT_5V 0
#define MSM8930_GPIO_VREG_ID_EXT_OTG_SW 1
extern struct gpio_regulator_platform_data
- msm8930_gpio_regulator_pdata[] __devinitdata;
+ msm8930_pm8038_gpio_regulator_pdata[] __devinitdata;
+extern struct gpio_regulator_platform_data
+ msm8930_pm8917_gpio_regulator_pdata[] __devinitdata;
extern struct rpm_regulator_platform_data
- msm8930_rpm_regulator_pdata __devinitdata;
+ msm8930_pm8038_rpm_regulator_pdata __devinitdata;
+extern struct rpm_regulator_platform_data
+ msm8930_pm8917_rpm_regulator_pdata __devinitdata;
#if defined(CONFIG_GPIO_SX150X) || defined(CONFIG_GPIO_SX150X_MODULE)
enum {
GPIO_EXPANDER_IRQ_BASE = (PM8038_IRQ_BASE + PM8038_NR_IRQS),
- GPIO_EXPANDER_GPIO_BASE = (PM8038_MPP_BASE + PM8038_NR_MPPS),
+ GPIO_EXPANDER_GPIO_BASE = (PM8038_MPP_BASE + PM8917_NR_MPPS),
/* CAM Expander */
GPIO_CAM_EXPANDER_BASE = GPIO_EXPANDER_GPIO_BASE,
GPIO_CAM_GP_STROBE_READY = GPIO_CAM_EXPANDER_BASE,
@@ -126,6 +147,7 @@
int msm8930_init_gpiomux(void);
void msm8930_allocate_fb_region(void);
void msm8930_pm8038_gpio_mpp_init(void);
+void msm8930_pm8917_gpio_mpp_init(void);
void msm8930_mdp_writeback(struct memtype_reserve *reserve_table);
void __init msm8930_init_gpu(void);
diff --git a/arch/arm/mach-msm/board-8960-pmic.c b/arch/arm/mach-msm/board-8960-pmic.c
index 8d75ee9..244125c 100644
--- a/arch/arm/mach-msm/board-8960-pmic.c
+++ b/arch/arm/mach-msm/board-8960-pmic.c
@@ -109,7 +109,7 @@
PM8XXX_GPIO_OUTPUT(43, 1), /* DISP_RESET_N */
PM8XXX_GPIO_OUTPUT(42, 0), /* USB 5V reg enable */
/* TABLA CODEC RESET */
- PM8XXX_GPIO_OUTPUT_STRENGTH(34, 1, PM_GPIO_STRENGTH_MED)
+ PM8XXX_GPIO_OUTPUT_STRENGTH(34, 0, PM_GPIO_STRENGTH_MED)
};
/* Initial PM8921 MPP configurations */
@@ -603,6 +603,8 @@
pm8921_platform_data.bms_pdata->battery_type = BATT_DESAY;
} else if (machine_is_msm8960_mtp()) {
pm8921_platform_data.bms_pdata->battery_type = BATT_PALLADIUM;
+ } else if (machine_is_msm8960_cdp()) {
+ pm8921_chg_pdata.has_dc_supply = true;
}
if (machine_is_msm8960_fluid())
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index 4263cd6..77f94f4 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -2324,6 +2324,7 @@
static struct msm_i2c_platform_data msm8960_i2c_qup_gsbi4_pdata = {
.clk_freq = 100000,
.src_clk_rate = 24000000,
+ .keep_ahb_clk_on = 1,
};
static struct msm_i2c_platform_data msm8960_i2c_qup_gsbi3_pdata = {
@@ -2550,43 +2551,42 @@
{
int rc;
+ pr_debug("%s on= %d\n", __func__, on);
+
if (on) {
- rc = gpio_direction_output(gpio_bt_sys_rest_en, 1);
+ rc = gpio_request(gpio_bt_sys_rest_en, "bt sys_rst_n");
+ if (rc) {
+ pr_err("%s: unable to request gpio %d (%d)\n",
+ __func__, gpio_bt_sys_rest_en, rc);
+ goto out;
+ }
+ rc = gpio_direction_output(gpio_bt_sys_rest_en, 0);
+ if (rc) {
+ pr_err("%s: Unable to set gpio %d direction\n",
+ __func__, gpio_bt_sys_rest_en);
+ goto free_gpio;
+ }
msleep(100);
+ gpio_set_value(gpio_bt_sys_rest_en, 1);
+ msleep(100);
+ goto out;
} else {
gpio_set_value(gpio_bt_sys_rest_en, 0);
rc = gpio_direction_input(gpio_bt_sys_rest_en);
msleep(100);
}
- pr_err("%s on= %d rc = %d\n", __func__, on, rc);
- return 0;
+
+free_gpio:
+ gpio_free(gpio_bt_sys_rest_en);
+out:
+ return rc;
}
static void __init bt_power_init(void)
{
- int rc;
-
+ pr_debug("%s enter\n", __func__);
msm_bt_power_device.dev.platform_data = &bluetooth_power;
- pr_err("%s enter\n", __func__);
- rc = gpio_request(gpio_bt_sys_rest_en, "bt sys_rst_n");
- if (rc) {
- pr_err("%s: unable to request gpio %d (%d)\n",
- __func__, gpio_bt_sys_rest_en, rc);
- return;
- }
-
- /* When booting up, de-assert BT reset pin */
- rc = gpio_direction_output(gpio_bt_sys_rest_en, 0);
- if (rc) {
- pr_err("%s: Unable to set direction\n", __func__);
- goto free_gpio;
- }
- pr_err("%s done\n", __func__);
- return;
-
-free_gpio:
- gpio_free(gpio_bt_sys_rest_en);
return;
}
#else
diff --git a/arch/arm/mach-msm/board-8974-gpiomux.c b/arch/arm/mach-msm/board-8974-gpiomux.c
index a2087e4..74c503d 100644
--- a/arch/arm/mach-msm/board-8974-gpiomux.c
+++ b/arch/arm/mach-msm/board-8974-gpiomux.c
@@ -102,6 +102,13 @@
.pull = GPIOMUX_PULL_DOWN,
};
+static struct gpiomux_setting taiko_reset = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_6MA,
+ .pull = GPIOMUX_PULL_NONE,
+ .dir = GPIOMUX_OUT_LOW,
+};
+
static struct msm_gpiomux_config msm_touch_configs[] __initdata = {
{
.gpio = 60, /* TOUCH RESET */
@@ -355,6 +362,15 @@
},
};
+static struct msm_gpiomux_config msm_taiko_config[] __initdata = {
+ {
+ .gpio = 63, /* SYS_RST_N */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &taiko_reset,
+ },
+ }
+};
+
void __init msm_8974_init_gpiomux(void)
{
int rc;
@@ -376,4 +392,6 @@
msm_gpiomux_install(msm_touch_configs, ARRAY_SIZE(msm_touch_configs));
msm_gpiomux_install(msm_sensor_configs, ARRAY_SIZE(msm_sensor_configs));
+
+ msm_gpiomux_install(msm_taiko_config, ARRAY_SIZE(msm_taiko_config));
}
diff --git a/arch/arm/mach-msm/board-9615-gpiomux.c b/arch/arm/mach-msm/board-9615-gpiomux.c
index 47a9835..9339638 100644
--- a/arch/arm/mach-msm/board-9615-gpiomux.c
+++ b/arch/arm/mach-msm/board-9615-gpiomux.c
@@ -119,6 +119,13 @@
.dir = GPIOMUX_IN,
};
+static struct gpiomux_setting tabla_reset = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_6MA,
+ .pull = GPIOMUX_PULL_NONE,
+ .dir = GPIOMUX_OUT_LOW,
+};
+
static struct msm_gpiomux_config msm9615_audio_codec_configs[] __initdata = {
{
.gpio = 24,
@@ -126,6 +133,12 @@
[GPIOMUX_SUSPENDED] = &cdc_mclk,
},
},
+ {
+ .gpio = 84, /* SYS_RST_N */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &tabla_reset,
+ },
+ }
};
static struct msm_gpiomux_config msm9615_sdcc2_configs[] __initdata = {
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index cde6437..e6229d5 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -393,6 +393,7 @@
static DEFINE_VDD_CLASS(vdd_dig, set_vdd_dig_8960);
+static int rpm_vreg_dig_8930 = RPM_VREG_ID_PM8038_VDD_DIG_CORNER;
static int set_vdd_dig_8930(struct clk_vdd_class *vdd_class, int level)
{
static const int vdd_corner[] = {
@@ -401,7 +402,7 @@
[VDD_DIG_NOMINAL] = RPM_VREG_CORNER_NOMINAL,
[VDD_DIG_HIGH] = RPM_VREG_CORNER_HIGH,
};
- return rpm_vreg_set_voltage(RPM_VREG_ID_PM8038_VDD_DIG_CORNER,
+ return rpm_vreg_set_voltage(rpm_vreg_dig_8930,
RPM_VREG_VOTER3,
vdd_corner[level],
RPM_VREG_CORNER_HIGH, 1);
@@ -467,6 +468,36 @@
sr2_lreg_uv[level], sr2_lreg_uv[level], 1);
}
+static int set_vdd_sr2_hdmi_pll_8930_pm8917(struct clk_vdd_class *vdd_class,
+ int level)
+{
+ int rc = 0;
+
+ if (level == VDD_SR2_HDMI_PLL_OFF) {
+ rc = rpm_vreg_set_voltage(RPM_VREG_ID_PM8917_L23,
+ RPM_VREG_VOTER3, 0, 0, 1);
+ if (rc)
+ return rc;
+ rc = rpm_vreg_set_voltage(RPM_VREG_ID_PM8917_S8,
+ RPM_VREG_VOTER3, 0, 0, 1);
+ if (rc)
+ rpm_vreg_set_voltage(RPM_VREG_ID_PM8917_L23,
+ RPM_VREG_VOTER3, 1800000, 1800000, 1);
+ } else {
+ rc = rpm_vreg_set_voltage(RPM_VREG_ID_PM8917_S8,
+ RPM_VREG_VOTER3, 2050000, 2100000, 1);
+ if (rc)
+ return rc;
+ rc = rpm_vreg_set_voltage(RPM_VREG_ID_PM8917_L23,
+ RPM_VREG_VOTER3, 1800000, 1800000, 1);
+ if (rc)
+ rpm_vreg_set_voltage(RPM_VREG_ID_PM8917_S8,
+ RPM_VREG_VOTER3, 0, 0, 1);
+ }
+
+ return rc;
+}
+
static int set_vdd_sr2_hdmi_pll_8930(struct clk_vdd_class *vdd_class, int level)
{
return rpm_vreg_set_voltage(RPM_VREG_ID_PM8038_L23, RPM_VREG_VOTER3,
@@ -6237,7 +6268,7 @@
rmwreg(0x00000003, AHB_EN_REG, 0x6C000103);
writel_relaxed(0x000007F9, AHB_EN2_REG);
} else {
- rmwreg(0x44000000, AHB_EN_REG, 0x6C000103);
+ rmwreg(0x40000000, AHB_EN_REG, 0x6C000103);
writel_relaxed(0x3C7097F9, AHB_EN2_REG);
}
@@ -6421,12 +6452,8 @@
/* Initialize clock registers. */
reg_init();
- if (cpu_is_apq8064()) {
+ if (cpu_is_apq8064())
vdd_sr2_hdmi_pll.set_vdd = set_vdd_sr2_hdmi_pll_8064;
- } else if (cpu_is_msm8930() || cpu_is_msm8930aa() || cpu_is_msm8627()) {
- vdd_dig.set_vdd = set_vdd_dig_8930;
- vdd_sr2_hdmi_pll.set_vdd = set_vdd_sr2_hdmi_pll_8930;
- }
/* Detect PLL4 programmed for alternate 491.52MHz clock plan. */
if (readl_relaxed(LCC_PLL0_L_VAL_REG) == 0x12) {
@@ -6510,6 +6537,25 @@
clk_ops_local_pll.enable = sr_pll_clk_enable;
}
+static void __init msm8930_pm8917_clock_pre_init(void)
+{
+ /* detect pmic8917 from board file, and call this init function */
+
+ vdd_dig.set_vdd = set_vdd_dig_8930;
+ rpm_vreg_dig_8930 = RPM_VREG_ID_PM8917_VDD_DIG_CORNER;
+ vdd_sr2_hdmi_pll.set_vdd = set_vdd_sr2_hdmi_pll_8930_pm8917;
+
+ msm8960_clock_pre_init();
+}
+
+static void __init msm8930_clock_pre_init(void)
+{
+ vdd_dig.set_vdd = set_vdd_dig_8930;
+ vdd_sr2_hdmi_pll.set_vdd = set_vdd_sr2_hdmi_pll_8930;
+
+ msm8960_clock_pre_init();
+}
+
static void __init msm8960_clock_post_init(void)
{
/* Keep PXO on whenever APPS cpu is active */
@@ -6620,7 +6666,15 @@
struct clock_init_data msm8930_clock_init_data __initdata = {
.table = msm_clocks_8930,
.size = ARRAY_SIZE(msm_clocks_8930),
- .pre_init = msm8960_clock_pre_init,
+ .pre_init = msm8930_clock_pre_init,
+ .post_init = msm8960_clock_post_init,
+ .late_init = msm8960_clock_late_init,
+};
+
+struct clock_init_data msm8930_pm8917_clock_init_data __initdata = {
+ .table = msm_clocks_8930,
+ .size = ARRAY_SIZE(msm_clocks_8930),
+ .pre_init = msm8930_pm8917_clock_pre_init,
.post_init = msm8960_clock_post_init,
.late_init = msm8960_clock_late_init,
};
diff --git a/arch/arm/mach-msm/clock-8974.c b/arch/arm/mach-msm/clock-8974.c
index e21a645..9eb3e8b 100644
--- a/arch/arm/mach-msm/clock-8974.c
+++ b/arch/arm/mach-msm/clock-8974.c
@@ -497,6 +497,7 @@
#define LPASS_Q6SS_XO_CBCR 0x26000
#define LPASS_Q6_AXI_CBCR 0x11C0
#define Q6SS_AHBM_CBCR 0x22004
+#define AUDIO_WRAPPER_BR_CBCR 0x24000
#define MSS_XO_Q6_CBCR 0x108C
#define MSS_BUS_Q6_CBCR 0x10A4
#define MSS_CFG_AHB_CBCR 0x0280
@@ -634,7 +635,8 @@
#define MMSSNOC_AHB_ID 0x3
#define BIMC_ID 0x0
-#define OCMEM_ID 0x1
+#define OXILI_ID 0x1
+#define OCMEM_ID 0x2
enum {
D0_ID = 1,
@@ -653,6 +655,8 @@
DEFINE_CLK_RPM_SMD(bimc_clk, bimc_a_clk, RPM_MEM_CLK_TYPE, BIMC_ID, NULL);
DEFINE_CLK_RPM_SMD(ocmemgx_clk, ocmemgx_a_clk, RPM_MEM_CLK_TYPE, OCMEM_ID,
NULL);
+DEFINE_CLK_RPM_SMD(gfx3d_clk_src, gfx3d_a_clk_src, RPM_MEM_CLK_TYPE, OXILI_ID,
+ NULL);
DEFINE_CLK_RPM_SMD_BRANCH(cxo_clk_src, cxo_a_clk_src,
RPM_MISC_CLK_TYPE, CXO_ID, 19200000);
@@ -773,7 +777,7 @@
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(bimc_acpu_a_clk, &bimc_a_clk.c, LONG_MAX);
-static DEFINE_CLK_VOTER(ocmemgx_gfx3d_clk, &ocmemgx_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(oxili_gfx3d_clk_src, &gfx3d_clk_src.c, LONG_MAX);
static DEFINE_CLK_VOTER(ocmemgx_msmbus_clk, &ocmemgx_clk.c, LONG_MAX);
static DEFINE_CLK_VOTER(ocmemgx_msmbus_a_clk, &ocmemgx_a_clk.c, LONG_MAX);
static DEFINE_CLK_VOTER(ocmemgx_core_clk, &ocmemgx_clk.c, LONG_MAX);
@@ -4012,7 +4016,7 @@
static struct branch_clk oxili_gfx3d_clk = {
.cbcr_reg = OXILI_GFX3D_CBCR,
- .parent = &ocmemgx_gfx3d_clk.c,
+ .parent = &oxili_gfx3d_clk_src.c,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "oxili_gfx3d_clk",
@@ -4494,6 +4498,17 @@
},
};
+static struct branch_clk audio_wrapper_br_clk = {
+ .cbcr_reg = AUDIO_WRAPPER_BR_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[LPASS_BASE],
+ .c = {
+ .dbg_name = "audio_wrapper_br_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(audio_wrapper_br_clk.c),
+ },
+};
+
static struct branch_clk mss_xo_q6_clk = {
.cbcr_reg = MSS_XO_Q6_CBCR,
.bcr_reg = MSS_Q6SS_BCR,
@@ -4702,6 +4717,7 @@
{&q6ss_ahb_lfabif_clk.c, LPASS_BASE, 0x001e},
{&q6ss_ahbm_clk.c, LPASS_BASE, 0x001d},
{&audio_core_ixfabric_clk.c, LPASS_BASE, 0x0059},
+ {&audio_wrapper_br_clk.c, LPASS_BASE, 0x0022},
{&mss_bus_q6_clk.c, MSS_BASE, 0x003b},
{&mss_xo_q6_clk.c, MSS_BASE, 0x0007},
@@ -4976,7 +4992,7 @@
CLK_LOOKUP("core_clk", gcc_blsp1_uart5_apps_clk.c, ""),
CLK_LOOKUP("core_clk", gcc_blsp1_uart6_apps_clk.c, ""),
- CLK_LOOKUP("iface_clk", gcc_blsp2_ahb_clk.c, "f9966000.i2c"),
+ CLK_LOOKUP("iface_clk", gcc_blsp2_ahb_clk.c, "f9967000.i2c"),
CLK_LOOKUP("iface_clk", gcc_blsp2_ahb_clk.c, "f995e000.serial"),
CLK_LOOKUP("core_clk", gcc_blsp2_qup1_i2c_apps_clk.c, ""),
CLK_LOOKUP("core_clk", gcc_blsp2_qup1_spi_apps_clk.c, ""),
@@ -4984,9 +5000,9 @@
CLK_LOOKUP("core_clk", gcc_blsp2_qup2_spi_apps_clk.c, ""),
CLK_LOOKUP("core_clk", gcc_blsp2_qup3_i2c_apps_clk.c, ""),
CLK_LOOKUP("core_clk", gcc_blsp2_qup3_spi_apps_clk.c, ""),
- CLK_LOOKUP("core_clk", gcc_blsp2_qup4_i2c_apps_clk.c, "f9966000.i2c"),
+ CLK_LOOKUP("core_clk", gcc_blsp2_qup4_i2c_apps_clk.c, ""),
CLK_LOOKUP("core_clk", gcc_blsp2_qup4_spi_apps_clk.c, ""),
- CLK_LOOKUP("core_clk", gcc_blsp2_qup5_i2c_apps_clk.c, ""),
+ CLK_LOOKUP("core_clk", gcc_blsp2_qup5_i2c_apps_clk.c, "f9967000.i2c"),
CLK_LOOKUP("core_clk", gcc_blsp2_qup5_spi_apps_clk.c, ""),
CLK_LOOKUP("core_clk", gcc_blsp2_qup6_i2c_apps_clk.c, ""),
CLK_LOOKUP("core_clk", gcc_blsp2_qup6_spi_apps_clk.c, ""),
@@ -5236,7 +5252,7 @@
"msm-dai-q6.4106"),
CLK_LOOKUP("core_oe_clk", audio_core_lpaif_pcmoe_clk.c,
"msm-dai-q6.4106"),
-
+ CLK_LOOKUP("br_clk", audio_wrapper_br_clk.c, "fdd00000.qcom,ocmem"),
CLK_LOOKUP("core_clk", mss_xo_q6_clk.c, "pil-q6v5-mss"),
CLK_LOOKUP("bus_clk", gcc_mss_q6_bimc_axi_clk.c, "pil-q6v5-mss"),
CLK_LOOKUP("iface_clk", gcc_mss_cfg_ahb_clk.c, "pil-q6v5-mss"),
diff --git a/arch/arm/mach-msm/clock.h b/arch/arm/mach-msm/clock.h
index d88466d..4e3d83b 100644
--- a/arch/arm/mach-msm/clock.h
+++ b/arch/arm/mach-msm/clock.h
@@ -169,6 +169,7 @@
extern struct clock_init_data qds8x50_clock_init_data;
extern struct clock_init_data msm8625_dummy_clock_init_data;
extern struct clock_init_data msm8930_clock_init_data;
+extern struct clock_init_data msm8930_pm8917_clock_init_data;
extern struct clock_init_data msm8974_clock_init_data;
extern struct clock_init_data msm8974_rumi_clock_init_data;
diff --git a/arch/arm/mach-msm/devices-8930.c b/arch/arm/mach-msm/devices-8930.c
index a257a9c..867e8fc 100644
--- a/arch/arm/mach-msm/devices-8930.c
+++ b/arch/arm/mach-msm/devices-8930.c
@@ -32,6 +32,7 @@
#include "rpm_stats.h"
#include "rpm_rbcpr_stats.h"
#include "footswitch.h"
+#include "acpuclock-krait.h"
#ifdef CONFIG_MSM_MPM
#include <mach/mpm.h>
@@ -228,13 +229,13 @@
MSM_RPM_STATUS_ID_MAP(8930, PM8038_CLK2_1),
MSM_RPM_STATUS_ID_MAP(8930, PM8038_LVS1),
MSM_RPM_STATUS_ID_MAP(8930, PM8038_LVS2),
- MSM_RPM_STATUS_ID_MAP(8930, NCP_0),
- MSM_RPM_STATUS_ID_MAP(8930, NCP_1),
- MSM_RPM_STATUS_ID_MAP(8930, CXO_BUFFERS),
- MSM_RPM_STATUS_ID_MAP(8930, USB_OTG_SWITCH),
- MSM_RPM_STATUS_ID_MAP(8930, HDMI_SWITCH),
- MSM_RPM_STATUS_ID_MAP(8930, QDSS_CLK),
- MSM_RPM_STATUS_ID_MAP(8930, VOLTAGE_CORNER),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8038_NCP_0),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8038_NCP_1),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8038_CXO_BUFFERS),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8038_USB_OTG_SWITCH),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8038_HDMI_SWITCH),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8038_QDSS_CLK),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8038_VOLTAGE_CORNER),
},
.target_ctrl_id = {
MSM_RPM_CTRL_MAP(8930, VERSION_MAJOR),
@@ -251,6 +252,259 @@
.ver = {3, 0, 0},
};
+struct msm_rpm_platform_data msm8930_rpm_data_pm8917 __initdata = {
+ .reg_base_addrs = {
+ [MSM_RPM_PAGE_STATUS] = MSM_RPM_BASE,
+ [MSM_RPM_PAGE_CTRL] = MSM_RPM_BASE + 0x400,
+ [MSM_RPM_PAGE_REQ] = MSM_RPM_BASE + 0x600,
+ [MSM_RPM_PAGE_ACK] = MSM_RPM_BASE + 0xa00,
+ },
+ .irq_ack = RPM_APCC_CPU0_GP_HIGH_IRQ,
+ .irq_err = RPM_APCC_CPU0_GP_LOW_IRQ,
+ .irq_wakeup = RPM_APCC_CPU0_WAKE_UP_IRQ,
+ .ipc_rpm_reg = MSM_APCS_GCC_BASE + 0x008,
+ .ipc_rpm_val = 4,
+ .target_id = {
+ MSM_RPM_MAP(8930, NOTIFICATION_CONFIGURED_0, NOTIFICATION, 4),
+ MSM_RPM_MAP(8930, NOTIFICATION_REGISTERED_0, NOTIFICATION, 4),
+ MSM_RPM_MAP(8930, INVALIDATE_0, INVALIDATE, 8),
+ MSM_RPM_MAP(8960, TRIGGER_TIMED_TO, TRIGGER_TIMED, 1),
+ MSM_RPM_MAP(8960, TRIGGER_TIMED_SCLK_COUNT, TRIGGER_TIMED, 1),
+ MSM_RPM_MAP(8930, RPM_CTL, RPM_CTL, 1),
+ MSM_RPM_MAP(8930, CXO_CLK, CXO_CLK, 1),
+ MSM_RPM_MAP(8930, PXO_CLK, PXO_CLK, 1),
+ MSM_RPM_MAP(8930, APPS_FABRIC_CLK, APPS_FABRIC_CLK, 1),
+ MSM_RPM_MAP(8930, SYSTEM_FABRIC_CLK, SYSTEM_FABRIC_CLK, 1),
+ MSM_RPM_MAP(8930, MM_FABRIC_CLK, MM_FABRIC_CLK, 1),
+ MSM_RPM_MAP(8930, DAYTONA_FABRIC_CLK, DAYTONA_FABRIC_CLK, 1),
+ MSM_RPM_MAP(8930, SFPB_CLK, SFPB_CLK, 1),
+ MSM_RPM_MAP(8930, CFPB_CLK, CFPB_CLK, 1),
+ MSM_RPM_MAP(8930, MMFPB_CLK, MMFPB_CLK, 1),
+ MSM_RPM_MAP(8930, EBI1_CLK, EBI1_CLK, 1),
+ MSM_RPM_MAP(8930, APPS_FABRIC_CFG_HALT_0,
+ APPS_FABRIC_CFG_HALT, 2),
+ MSM_RPM_MAP(8930, APPS_FABRIC_CFG_CLKMOD_0,
+ APPS_FABRIC_CFG_CLKMOD, 3),
+ MSM_RPM_MAP(8930, APPS_FABRIC_CFG_IOCTL,
+ APPS_FABRIC_CFG_IOCTL, 1),
+ MSM_RPM_MAP(8930, APPS_FABRIC_ARB_0, APPS_FABRIC_ARB, 6),
+ MSM_RPM_MAP(8930, SYS_FABRIC_CFG_HALT_0,
+ SYS_FABRIC_CFG_HALT, 2),
+ MSM_RPM_MAP(8930, SYS_FABRIC_CFG_CLKMOD_0,
+ SYS_FABRIC_CFG_CLKMOD, 3),
+ MSM_RPM_MAP(8930, SYS_FABRIC_CFG_IOCTL,
+ SYS_FABRIC_CFG_IOCTL, 1),
+ MSM_RPM_MAP(8930, SYSTEM_FABRIC_ARB_0,
+ SYSTEM_FABRIC_ARB, 20),
+ MSM_RPM_MAP(8930, MMSS_FABRIC_CFG_HALT_0,
+ MMSS_FABRIC_CFG_HALT, 2),
+ MSM_RPM_MAP(8930, MMSS_FABRIC_CFG_CLKMOD_0,
+ MMSS_FABRIC_CFG_CLKMOD, 3),
+ MSM_RPM_MAP(8930, MMSS_FABRIC_CFG_IOCTL,
+ MMSS_FABRIC_CFG_IOCTL, 1),
+ MSM_RPM_MAP(8930, MM_FABRIC_ARB_0, MM_FABRIC_ARB, 11),
+ MSM_RPM_MAP(8930, PM8917_S1_0, PM8917_S1, 2),
+ MSM_RPM_MAP(8930, PM8917_S2_0, PM8917_S2, 2),
+ MSM_RPM_MAP(8930, PM8917_S3_0, PM8917_S3, 2),
+ MSM_RPM_MAP(8930, PM8917_S4_0, PM8917_S4, 2),
+ MSM_RPM_MAP(8930, PM8917_S5_0, PM8917_S5, 2),
+ MSM_RPM_MAP(8930, PM8917_S6_0, PM8917_S6, 2),
+ MSM_RPM_MAP(8930, PM8917_S7_0, PM8917_S7, 2),
+ MSM_RPM_MAP(8930, PM8917_S8_0, PM8917_S8, 2),
+ MSM_RPM_MAP(8930, PM8917_L1_0, PM8917_L1, 2),
+ MSM_RPM_MAP(8930, PM8917_L2_0, PM8917_L2, 2),
+ MSM_RPM_MAP(8930, PM8917_L3_0, PM8917_L3, 2),
+ MSM_RPM_MAP(8930, PM8917_L4_0, PM8917_L4, 2),
+ MSM_RPM_MAP(8930, PM8917_L5_0, PM8917_L5, 2),
+ MSM_RPM_MAP(8930, PM8917_L6_0, PM8917_L6, 2),
+ MSM_RPM_MAP(8930, PM8917_L7_0, PM8917_L7, 2),
+ MSM_RPM_MAP(8930, PM8917_L8_0, PM8917_L8, 2),
+ MSM_RPM_MAP(8930, PM8917_L9_0, PM8917_L9, 2),
+ MSM_RPM_MAP(8930, PM8917_L10_0, PM8917_L10, 2),
+ MSM_RPM_MAP(8930, PM8917_L11_0, PM8917_L11, 2),
+ MSM_RPM_MAP(8930, PM8917_L12_0, PM8917_L12, 2),
+ MSM_RPM_MAP(8930, PM8917_L14_0, PM8917_L14, 2),
+ MSM_RPM_MAP(8930, PM8917_L15_0, PM8917_L15, 2),
+ MSM_RPM_MAP(8930, PM8917_L16_0, PM8917_L16, 2),
+ MSM_RPM_MAP(8930, PM8917_L17_0, PM8917_L17, 2),
+ MSM_RPM_MAP(8930, PM8917_L18_0, PM8917_L18, 2),
+ MSM_RPM_MAP(8930, PM8917_L21_0, PM8917_L21, 2),
+ MSM_RPM_MAP(8930, PM8917_L22_0, PM8917_L22, 2),
+ MSM_RPM_MAP(8930, PM8917_L23_0, PM8917_L23, 2),
+ MSM_RPM_MAP(8930, PM8917_L24_0, PM8917_L24, 2),
+ MSM_RPM_MAP(8930, PM8917_L25_0, PM8917_L25, 2),
+ MSM_RPM_MAP(8930, PM8917_L26_0, PM8917_L26, 2),
+ MSM_RPM_MAP(8930, PM8917_L27_0, PM8917_L27, 2),
+ MSM_RPM_MAP(8930, PM8917_L28_0, PM8917_L28, 2),
+ MSM_RPM_MAP(8930, PM8917_L29_0, PM8917_L29, 2),
+ MSM_RPM_MAP(8930, PM8917_L30_0, PM8917_L30, 2),
+ MSM_RPM_MAP(8930, PM8917_L31_0, PM8917_L31, 2),
+ MSM_RPM_MAP(8930, PM8917_L32_0, PM8917_L32, 2),
+ MSM_RPM_MAP(8930, PM8917_L33_0, PM8917_L33, 2),
+ MSM_RPM_MAP(8930, PM8917_L34_0, PM8917_L34, 2),
+ MSM_RPM_MAP(8930, PM8917_L35_0, PM8917_L35, 2),
+ MSM_RPM_MAP(8930, PM8917_L36_0, PM8917_L36, 2),
+ MSM_RPM_MAP(8930, PM8917_CLK1_0, PM8917_CLK1, 2),
+ MSM_RPM_MAP(8930, PM8917_CLK2_0, PM8917_CLK2, 2),
+ MSM_RPM_MAP(8930, PM8917_LVS1, PM8917_LVS1, 1),
+ MSM_RPM_MAP(8930, PM8917_LVS3, PM8917_LVS3, 1),
+ MSM_RPM_MAP(8930, PM8917_LVS4, PM8917_LVS4, 1),
+ MSM_RPM_MAP(8930, PM8917_LVS5, PM8917_LVS5, 1),
+ MSM_RPM_MAP(8930, PM8917_LVS6, PM8917_LVS6, 1),
+ MSM_RPM_MAP(8930, PM8917_LVS7, PM8917_LVS7, 1),
+ MSM_RPM_MAP(8930, NCP_0, NCP, 2),
+ MSM_RPM_MAP(8930, CXO_BUFFERS, CXO_BUFFERS, 1),
+ MSM_RPM_MAP(8930, USB_OTG_SWITCH, USB_OTG_SWITCH, 1),
+ MSM_RPM_MAP(8930, HDMI_SWITCH, HDMI_SWITCH, 1),
+ MSM_RPM_MAP(8930, QDSS_CLK, QDSS_CLK, 1),
+ MSM_RPM_MAP(8930, VOLTAGE_CORNER, VOLTAGE_CORNER, 1),
+ },
+ .target_status = {
+ MSM_RPM_STATUS_ID_MAP(8930, VERSION_MAJOR),
+ MSM_RPM_STATUS_ID_MAP(8930, VERSION_MINOR),
+ MSM_RPM_STATUS_ID_MAP(8930, VERSION_BUILD),
+ MSM_RPM_STATUS_ID_MAP(8930, SUPPORTED_RESOURCES_0),
+ MSM_RPM_STATUS_ID_MAP(8930, SUPPORTED_RESOURCES_1),
+ MSM_RPM_STATUS_ID_MAP(8930, SUPPORTED_RESOURCES_2),
+ MSM_RPM_STATUS_ID_MAP(8930, RESERVED_SUPPORTED_RESOURCES_0),
+ MSM_RPM_STATUS_ID_MAP(8930, SEQUENCE),
+ MSM_RPM_STATUS_ID_MAP(8930, RPM_CTL),
+ MSM_RPM_STATUS_ID_MAP(8930, CXO_CLK),
+ MSM_RPM_STATUS_ID_MAP(8930, PXO_CLK),
+ MSM_RPM_STATUS_ID_MAP(8930, APPS_FABRIC_CLK),
+ MSM_RPM_STATUS_ID_MAP(8930, SYSTEM_FABRIC_CLK),
+ MSM_RPM_STATUS_ID_MAP(8930, MM_FABRIC_CLK),
+ MSM_RPM_STATUS_ID_MAP(8930, DAYTONA_FABRIC_CLK),
+ MSM_RPM_STATUS_ID_MAP(8930, SFPB_CLK),
+ MSM_RPM_STATUS_ID_MAP(8930, CFPB_CLK),
+ MSM_RPM_STATUS_ID_MAP(8930, MMFPB_CLK),
+ MSM_RPM_STATUS_ID_MAP(8930, EBI1_CLK),
+ MSM_RPM_STATUS_ID_MAP(8930, APPS_FABRIC_CFG_HALT),
+ MSM_RPM_STATUS_ID_MAP(8930, APPS_FABRIC_CFG_CLKMOD),
+ MSM_RPM_STATUS_ID_MAP(8930, APPS_FABRIC_CFG_IOCTL),
+ MSM_RPM_STATUS_ID_MAP(8930, APPS_FABRIC_ARB),
+ MSM_RPM_STATUS_ID_MAP(8930, SYS_FABRIC_CFG_HALT),
+ MSM_RPM_STATUS_ID_MAP(8930, SYS_FABRIC_CFG_CLKMOD),
+ MSM_RPM_STATUS_ID_MAP(8930, SYS_FABRIC_CFG_IOCTL),
+ MSM_RPM_STATUS_ID_MAP(8930, SYSTEM_FABRIC_ARB),
+ MSM_RPM_STATUS_ID_MAP(8930, MMSS_FABRIC_CFG_HALT),
+ MSM_RPM_STATUS_ID_MAP(8930, MMSS_FABRIC_CFG_CLKMOD),
+ MSM_RPM_STATUS_ID_MAP(8930, MMSS_FABRIC_CFG_IOCTL),
+ MSM_RPM_STATUS_ID_MAP(8930, MM_FABRIC_ARB),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_S1_0),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_S1_1),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_S2_0),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_S2_1),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_S3_0),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_S3_1),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_S4_0),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_S4_1),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_S5_0),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_S5_1),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_S6_0),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_S6_1),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_S7_0),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_S7_1),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_S8_0),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_S8_1),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L1_0),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L1_1),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L2_0),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L2_1),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L3_0),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L3_1),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L4_0),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L4_1),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L5_0),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L5_1),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L6_0),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L6_1),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L7_0),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L7_1),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L8_0),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L8_1),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L9_0),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L9_1),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L10_0),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L10_1),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L11_0),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L11_1),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L12_0),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L12_1),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L14_0),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L14_1),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L15_0),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L15_1),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L16_0),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L16_1),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L17_0),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L17_1),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L18_0),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L18_1),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L21_0),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L21_1),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L22_0),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L22_1),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L23_0),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L23_1),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L24_0),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L24_1),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L25_0),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L25_1),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L26_0),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L26_1),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L27_0),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L27_1),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L28_0),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L28_1),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L29_0),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L29_1),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L30_0),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L30_1),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L31_0),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L31_1),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L32_0),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L32_1),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L33_0),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L33_1),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L34_0),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L34_1),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L35_0),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L35_1),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L36_0),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_L36_1),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_CLK1_0),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_CLK1_1),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_CLK2_0),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_CLK2_1),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_LVS1),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_LVS3),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_LVS4),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_LVS5),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_LVS6),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_LVS7),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_NCP_0),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_NCP_1),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_CXO_BUFFERS),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_USB_OTG_SWITCH),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_HDMI_SWITCH),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_QDSS_CLK),
+ MSM_RPM_STATUS_ID_MAP(8930, PM8917_VOLTAGE_CORNER),
+ },
+ .target_ctrl_id = {
+ MSM_RPM_CTRL_MAP(8930, VERSION_MAJOR),
+ MSM_RPM_CTRL_MAP(8930, VERSION_MINOR),
+ MSM_RPM_CTRL_MAP(8930, VERSION_BUILD),
+ MSM_RPM_CTRL_MAP(8930, REQ_CTX_0),
+ MSM_RPM_CTRL_MAP(8930, REQ_SEL_0),
+ MSM_RPM_CTRL_MAP(8930, ACK_CTX_0),
+ MSM_RPM_CTRL_MAP(8930, ACK_SEL_0),
+ },
+ .sel_invalidate = MSM_RPM_8930_SEL_INVALIDATE,
+ .sel_notification = MSM_RPM_8930_SEL_NOTIFICATION,
+ .sel_last = MSM_RPM_8930_SEL_LAST,
+ .ver = {3, 0, 0},
+};
struct platform_device msm8930_rpm_device = {
.name = "msm_rpm",
.id = -1,
@@ -386,9 +640,16 @@
.id = -1,
};
+static struct acpuclk_platform_data acpuclk_8930_pdata = {
+ .uses_pm8917 = false,
+};
+
struct platform_device msm8930_device_acpuclk = {
.name = "acpuclk-8930",
.id = -1,
+ .dev = {
+ .platform_data = &acpuclk_8930_pdata,
+ },
};
struct platform_device msm8930aa_device_acpuclk = {
diff --git a/arch/arm/mach-msm/devices-msm7x27a.c b/arch/arm/mach-msm/devices-msm7x27a.c
index 0331919..27de697 100644
--- a/arch/arm/mach-msm/devices-msm7x27a.c
+++ b/arch/arm/mach-msm/devices-msm7x27a.c
@@ -1592,6 +1592,47 @@
},
};
+enum {
+ MSM8625,
+ MSM8625A,
+ MSM8625AB,
+};
+
+static int __init msm8625_cpu_id(void)
+{
+ int raw_id, cpu;
+
+ raw_id = socinfo_get_raw_id();
+ switch (raw_id) {
+ /* Part number for 1GHz part */
+ case 0x770:
+ case 0x771:
+ case 0x77C:
+ case 0x780:
+ case 0x8D0:
+ cpu = MSM8625;
+ break;
+ /* Part number for 1.2GHz part */
+ case 0x773:
+ case 0x774:
+ case 0x781:
+ case 0x8D1:
+ cpu = MSM8625A;
+ break;
+ case 0x775:
+ case 0x776:
+ case 0x77D:
+ case 0x782:
+ case 0x8D2:
+ cpu = MSM8625AB;
+ break;
+ default:
+ pr_err("Invalid Raw ID\n");
+ return -ENODEV;
+ }
+ return cpu;
+}
+
static struct resource cpr_resources[] = {
{
.start = MSM8625_INT_CPR_IRQ0,
@@ -1608,12 +1649,12 @@
* These are various Vdd levels supported by PMIC
*/
static uint32_t msm_c2_pmic_mv[] __initdata = {
- 1300, 12875 / 10, 1275, 12625 / 10, 1250,
- 12375 / 10, 1225, 12125 / 10, 1200, 11875 / 10,
- 1175, 11625 / 10, 1150, 11375 / 10, 1125,
- 11125 / 10, 1100, 10875 / 10, 1075, 10625 / 10,
- 1050, 10375 / 10, 1025, 10125 / 10, 0, 0, 0, 0,
- 0, 0, 0, 1000,
+ 1300000, 1287500, 1275000, 1262500, 1250000,
+ 1237500, 1225000, 1212500, 1200000, 1187500,
+ 1175000, 1162500, 1150000, 1137500, 1125000,
+ 1112500, 1100000, 1087500, 1075000, 1062500,
+ 1050000, 1037500, 1025000, 1012500, 0, 0, 0,
+ 0, 0, 0, 0, 1000,
};
/**
@@ -1633,10 +1674,10 @@
},
.ring_osc = 0,
.step_quot = ~0,
- .tgt_volt_offset = 1,
- .Vmax = 1200,
- .Vmin = 1000,
- .calibrated_mV = 1100,
+ .tgt_volt_offset = 0,
+ .Vmax = 1200000,
+ .Vmin = 1000000,
+ .calibrated_uV = 1100000,
},
[TURBO_MODE] = {
.ring_osc_data = {
@@ -1651,23 +1692,47 @@
},
.ring_osc = 0,
.step_quot = ~0,
- .tgt_volt_offset = 1,
- .Vmax = 1350,
- .Vmin = 1250,
- .calibrated_mV = 1300,
+ .tgt_volt_offset = 0,
+ .Vmax = 1350000,
+ .Vmin = 1150000,
+ .calibrated_uV = 1300000,
},
};
struct msm_cpr_vp_data vp_data = {
- .min_volt = 1000,
- .max_volt = 1350,
- .default_volt = 1300,
- .step_size = (12500 / 1000),
+ .min_volt = 1000000,
+ .max_volt = 1350000,
+ .default_volt = 1300000,
+ .step_size = 12500,
};
+static uint32_t
+msm_cpr_get_quot(uint32_t max_quot, uint32_t max_freq, uint32_t new_freq)
+{
+ uint32_t quot;
+
+ /* This formula is as per chip characterization data */
+ quot = max_quot - ((max_freq / 10 - new_freq / 10) * 9) + 20;
+
+ return quot;
+}
+
+static void msm_cpr_clk_enable(void)
+{
+ uint32_t reg_val;
+
+ /* Select TCXO (19.2MHz) as clock source */
+ reg_val = readl_relaxed(A11S_TEST_BUS_SEL_ADDR);
+ reg_val |= RBCPR_CLK_MUX_SEL;
+ writel_relaxed(reg_val, A11S_TEST_BUS_SEL_ADDR);
+
+ /* Get CPR out of reset */
+ writel_relaxed(0x1, RBCPR_SW_RESET_N);
+}
+
static struct msm_cpr_config msm_cpr_pdata = {
.ref_clk_khz = 19200,
- .delay_us = 10000,
+ .delay_us = 25000,
.irq_line = 0,
.cpr_mode_data = msm_cpr_mode_data,
.tgt_count_div_N = 1,
@@ -1678,8 +1743,12 @@
.dn_threshold = 2,
.up_margin = 0,
.dn_margin = 0,
- .nom_freq_limit = 1008000,
+ .max_nom_freq = 700800,
+ .max_freq = 1401600,
+ .max_quot = 0,
.vp_data = &vp_data,
+ .get_quot = msm_cpr_get_quot,
+ .clk_enable = msm_cpr_clk_enable,
};
static struct platform_device msm8625_device_cpr = {
@@ -1701,7 +1770,6 @@
{
struct cpr_info_type *cpr_info = NULL;
uint8_t ring_osc = 0;
- uint32_t reg_val;
cpr_info = kzalloc(sizeof(struct cpr_info_type), GFP_KERNEL);
if (!cpr_info) {
@@ -1728,35 +1796,32 @@
msm_cpr_mode_data[TURBO_MODE].ring_osc_data[ring_osc].gcnt = 19;
msm_cpr_mode_data[NORMAL_MODE].ring_osc_data[ring_osc].gcnt = 19;
- /* The multiplier and offset are as per PTE data */
- msm_cpr_mode_data[TURBO_MODE].ring_osc_data[ring_osc].target_count =
- cpr_info->turbo_quot * 10 + 440;
- msm_cpr_mode_data[NORMAL_MODE].ring_osc_data[ring_osc].target_count =
- cpr_info->turbo_quot / msm_cpr_pdata.tgt_count_div_N;
+ /**
+ * The scaling factor and offset are as per chip characterization data
+ * This formula is used since available fuse bits in the chip are not
+ * enough to represent the value of maximum quot
+ */
+ msm_cpr_pdata.max_quot = cpr_info->turbo_quot * 10 + 610;
/**
* Bits 4:0 of pvs_fuse provide mapping to the safe boot up voltage.
* Boot up mode is by default Turbo.
*/
- msm_cpr_mode_data[TURBO_MODE].calibrated_mV =
+ msm_cpr_mode_data[TURBO_MODE].calibrated_uV =
msm_c2_pmic_mv[cpr_info->pvs_fuse & 0x1F];
- /* TODO: Store the tgt_volt_offset values for the modes from PTE */
-
-
pr_debug("%s: cpr: ring_osc: 0x%x\n", __func__,
msm_cpr_mode_data[TURBO_MODE].ring_osc);
pr_debug("%s: cpr: turbo_quot: 0x%x\n", __func__, cpr_info->turbo_quot);
pr_debug("%s: cpr: pvs_fuse: 0x%x\n", __func__, cpr_info->pvs_fuse);
kfree(cpr_info);
- /* Select TCXO (19.2MHz) as clock source */
- reg_val = readl_relaxed(A11S_TEST_BUS_SEL_ADDR);
- reg_val |= RBCPR_CLK_MUX_SEL;
- writel_relaxed(reg_val, A11S_TEST_BUS_SEL_ADDR);
+ if (msm8625_cpu_id() == MSM8625A)
+ msm_cpr_pdata.max_freq = 1209600;
+ else if (msm8625_cpu_id() == MSM8625)
+ msm_cpr_pdata.max_freq = 1008000;
- /* Get CPR out of reset */
- writel_relaxed(0x1, RBCPR_SW_RESET_N);
+ msm_cpr_clk_enable();
platform_device_register(&msm8625_vp_device);
platform_device_register(&msm8625_device_cpr);
@@ -1828,47 +1893,6 @@
.table = msm_clock_8625_dummy,
.size = ARRAY_SIZE(msm_clock_8625_dummy),
};
-enum {
- MSM8625,
- MSM8625A,
- MSM8625AB,
-};
-
-static int __init msm8625_cpu_id(void)
-{
- int raw_id, cpu;
-
- raw_id = socinfo_get_raw_id();
- switch (raw_id) {
- /* Part number for 1GHz part */
- case 0x770:
- case 0x771:
- case 0x77C:
- case 0x780:
- case 0x8D0:
- cpu = MSM8625;
- break;
- /* Part number for 1.2GHz part */
- case 0x773:
- case 0x774:
- case 0x779:
- case 0x781:
- case 0x8D1:
- cpu = MSM8625A;
- break;
- case 0x775:
- case 0x776:
- case 0x77D:
- case 0x782:
- case 0x8D2:
- cpu = MSM8625AB;
- break;
- default:
- pr_err("Invalid Raw ID\n");
- return -ENODEV;
- }
- return cpu;
-}
int __init msm7x2x_misc_init(void)
{
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
index d8f8480..3311ea1 100644
--- a/arch/arm/mach-msm/include/mach/board.h
+++ b/arch/arm/mach-msm/include/mach/board.h
@@ -515,6 +515,7 @@
int aux_dat;
int src_clk_rate;
int use_gsbi_shared_mode;
+ int keep_ahb_clk_on;
void (*msm_i2c_config_gpio)(int iface, int config_type);
};
diff --git a/arch/arm/mach-msm/include/mach/camera.h b/arch/arm/mach-msm/include/mach/camera.h
index 0867c1d..6298d94 100644
--- a/arch/arm/mach-msm/include/mach/camera.h
+++ b/arch/arm/mach-msm/include/mach/camera.h
@@ -700,4 +700,6 @@
(struct msm_camera_sensor_info *sinfo, int gpio_en);
int msm_camera_request_gpio_table
(struct msm_camera_sensor_info *sinfo, int gpio_en);
+void msm_camera_bus_scale_cfg(uint32_t bus_perf_client,
+ enum msm_bus_perf_setting perf_setting);
#endif
diff --git a/arch/arm/mach-msm/include/mach/msm_smd.h b/arch/arm/mach-msm/include/mach/msm_smd.h
index 97c03e7..0c452f8 100644
--- a/arch/arm/mach-msm/include/mach/msm_smd.h
+++ b/arch/arm/mach-msm/include/mach/msm_smd.h
@@ -309,6 +309,24 @@
*/
int smd_is_pkt_avail(smd_channel_t *ch);
+/**
+ * smd_module_init_notifier_register() - Register a smd module
+ * init notifier block
+ * @nb: Notifier block to be registered
+ *
+ * In order to mark the dependency on SMD Driver module initialization
+ * register a notifier using this API. Once the smd module_init is
+ * done, notification will be passed to the registered module.
+ */
+int smd_module_init_notifier_register(struct notifier_block *nb);
+
+/**
+ * smd_module_init_notifier_register() - Unregister a smd module
+ * init notifier block
+ * @nb: Notifier block to be registered
+ */
+int smd_module_init_notifier_unregister(struct notifier_block *nb);
+
/*
* SMD initialization function that registers for a SMD platform driver.
*
@@ -438,6 +456,16 @@
return -ENODEV;
}
+static inline int smd_module_init_notifier_register(struct notifier_block *nb)
+{
+ return -ENODEV;
+}
+
+static inline int smd_module_init_notifier_unregister(struct notifier_block *nb)
+{
+ return -ENODEV;
+}
+
static inline int __init msm_smd_init(void)
{
return 0;
diff --git a/arch/arm/mach-msm/include/mach/msm_smsm.h b/arch/arm/mach-msm/include/mach/msm_smsm.h
index e19f39d..133a1b3 100644
--- a/arch/arm/mach-msm/include/mach/msm_smsm.h
+++ b/arch/arm/mach-msm/include/mach/msm_smsm.h
@@ -133,8 +133,6 @@
void *data);
int smsm_state_cb_deregister(uint32_t smsm_entry, uint32_t mask,
void (*notify)(void *, uint32_t, uint32_t), void *data);
-int smsm_driver_state_notifier_register(struct notifier_block *nb);
-int smsm_driver_state_notifier_unregister(struct notifier_block *nb);
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);
diff --git a/arch/arm/mach-msm/include/mach/rpm-8930.h b/arch/arm/mach-msm/include/mach/rpm-8930.h
index 6fd9cf4..4ac9192 100644
--- a/arch/arm/mach-msm/include/mach/rpm-8930.h
+++ b/arch/arm/mach-msm/include/mach/rpm-8930.h
@@ -59,6 +59,8 @@
MSM_RPM_8930_SEL_MMSS_FABRIC_CFG_CLKMOD = 27,
MSM_RPM_8930_SEL_MMSS_FABRIC_CFG_IOCTL = 28,
MSM_RPM_8930_SEL_MM_FABRIC_ARB = 29,
+
+ /* PMIC 8038 */
MSM_RPM_8930_SEL_PM8038_S1 = 30,
MSM_RPM_8930_SEL_PM8038_S2 = 31,
MSM_RPM_8930_SEL_PM8038_S3 = 32,
@@ -96,12 +98,65 @@
MSM_RPM_8930_SEL_PM8038_CLK2 = 64,
MSM_RPM_8930_SEL_PM8038_LVS1 = 65,
MSM_RPM_8930_SEL_PM8038_LVS2 = 66,
+
+ /* PMIC 8917 */
+ MSM_RPM_8930_SEL_PM8917_S1 = 30,
+ MSM_RPM_8930_SEL_PM8917_S2 = 31,
+ MSM_RPM_8930_SEL_PM8917_S3 = 32,
+ MSM_RPM_8930_SEL_PM8917_S4 = 33,
+ MSM_RPM_8930_SEL_PM8917_S5 = 34,
+ MSM_RPM_8930_SEL_PM8917_S6 = 35,
+ MSM_RPM_8930_SEL_PM8917_S7 = 36,
+ MSM_RPM_8930_SEL_PM8917_S8 = 37,
+ MSM_RPM_8930_SEL_PM8917_L1 = 38,
+ MSM_RPM_8930_SEL_PM8917_L2 = 39,
+ MSM_RPM_8930_SEL_PM8917_L3 = 40,
+ MSM_RPM_8930_SEL_PM8917_L4 = 41,
+ MSM_RPM_8930_SEL_PM8917_L5 = 42,
+ MSM_RPM_8930_SEL_PM8917_L6 = 43,
+ MSM_RPM_8930_SEL_PM8917_L7 = 44,
+ MSM_RPM_8930_SEL_PM8917_L8 = 45,
+ MSM_RPM_8930_SEL_PM8917_L9 = 46,
+ MSM_RPM_8930_SEL_PM8917_L10 = 47,
+ MSM_RPM_8930_SEL_PM8917_L11 = 48,
+ MSM_RPM_8930_SEL_PM8917_L12 = 49,
+ MSM_RPM_8930_SEL_PM8917_L14 = 50,
+ MSM_RPM_8930_SEL_PM8917_L15 = 51,
+ MSM_RPM_8930_SEL_PM8917_L16 = 52,
+ MSM_RPM_8930_SEL_PM8917_L17 = 53,
+ MSM_RPM_8930_SEL_PM8917_L18 = 54,
+ MSM_RPM_8930_SEL_PM8917_L21 = 55,
+ MSM_RPM_8930_SEL_PM8917_L22 = 56,
+ MSM_RPM_8930_SEL_PM8917_L23 = 57,
+ MSM_RPM_8930_SEL_PM8917_L24 = 58,
+ MSM_RPM_8930_SEL_PM8917_L25 = 59,
+ MSM_RPM_8930_SEL_PM8917_L26 = 60,
+ MSM_RPM_8930_SEL_PM8917_L27 = 61,
+ MSM_RPM_8930_SEL_PM8917_L28 = 62,
+ MSM_RPM_8930_SEL_PM8917_L29 = 63,
+ MSM_RPM_8930_SEL_PM8917_L30 = 64,
+ MSM_RPM_8930_SEL_PM8917_L31 = 65,
+ MSM_RPM_8930_SEL_PM8917_L32 = 66,
+ MSM_RPM_8930_SEL_PM8917_L33 = 67,
+ MSM_RPM_8930_SEL_PM8917_L34 = 68,
+ MSM_RPM_8930_SEL_PM8917_L35 = 69,
+ MSM_RPM_8930_SEL_PM8917_L36 = 70,
+ MSM_RPM_8930_SEL_PM8917_CLK1 = 71,
+ MSM_RPM_8930_SEL_PM8917_CLK2 = 72,
+ MSM_RPM_8930_SEL_PM8917_LVS1 = 73,
+ MSM_RPM_8930_SEL_PM8917_LVS3 = 74,
+ MSM_RPM_8930_SEL_PM8917_LVS4 = 75,
+ MSM_RPM_8930_SEL_PM8917_LVS5 = 76,
+ MSM_RPM_8930_SEL_PM8917_LVS6 = 77,
+ MSM_RPM_8930_SEL_PM8917_LVS7 = 78,
+
MSM_RPM_8930_SEL_NCP = 80,
MSM_RPM_8930_SEL_CXO_BUFFERS = 81,
MSM_RPM_8930_SEL_USB_OTG_SWITCH = 82,
MSM_RPM_8930_SEL_HDMI_SWITCH = 83,
MSM_RPM_8930_SEL_DDR_DMM = 84,
MSM_RPM_8930_SEL_VOLTAGE_CORNER = 87,
+
MSM_RPM_8930_SEL_LAST = MSM_RPM_8930_SEL_VOLTAGE_CORNER,
};
@@ -163,6 +218,7 @@
MSM_RPM_8930_ID_MM_FABRIC_ARB_10 =
MSM_RPM_8930_ID_MM_FABRIC_ARB_0 + 10,
+ /* PMIC 8038 */
MSM_RPM_8930_ID_PM8038_S1_0 = 90,
MSM_RPM_8930_ID_PM8038_S1_1 = 91,
MSM_RPM_8930_ID_PM8038_S2_0 = 92,
@@ -235,13 +291,109 @@
MSM_RPM_8930_ID_PM8038_CLK2_1 = 159,
MSM_RPM_8930_ID_PM8038_LVS1 = 160,
MSM_RPM_8930_ID_PM8038_LVS2 = 161,
- MSM_RPM_8930_ID_NCP_0 = 162,
- MSM_RPM_8930_ID_NCP_1 = 163,
- MSM_RPM_8930_ID_CXO_BUFFERS = 164,
- MSM_RPM_8930_ID_USB_OTG_SWITCH = 165,
- MSM_RPM_8930_ID_HDMI_SWITCH = 166,
- MSM_RPM_8930_ID_QDSS_CLK = 167,
- MSM_RPM_8930_ID_VOLTAGE_CORNER = 168,
+
+ /* PMIC 8917 */
+ MSM_RPM_8930_ID_PM8917_S1_0 = 90,
+ MSM_RPM_8930_ID_PM8917_S1_1 = 91,
+ MSM_RPM_8930_ID_PM8917_S2_0 = 92,
+ MSM_RPM_8930_ID_PM8917_S2_1 = 93,
+ MSM_RPM_8930_ID_PM8917_S3_0 = 94,
+ MSM_RPM_8930_ID_PM8917_S3_1 = 95,
+ MSM_RPM_8930_ID_PM8917_S4_0 = 96,
+ MSM_RPM_8930_ID_PM8917_S4_1 = 97,
+ MSM_RPM_8930_ID_PM8917_S5_0 = 98,
+ MSM_RPM_8930_ID_PM8917_S5_1 = 99,
+ MSM_RPM_8930_ID_PM8917_S6_0 = 100,
+ MSM_RPM_8930_ID_PM8917_S6_1 = 101,
+ MSM_RPM_8930_ID_PM8917_S7_0 = 102,
+ MSM_RPM_8930_ID_PM8917_S7_1 = 103,
+ MSM_RPM_8930_ID_PM8917_S8_0 = 104,
+ MSM_RPM_8930_ID_PM8917_S8_1 = 105,
+ MSM_RPM_8930_ID_PM8917_L1_0 = 106,
+ MSM_RPM_8930_ID_PM8917_L1_1 = 107,
+ MSM_RPM_8930_ID_PM8917_L2_0 = 108,
+ MSM_RPM_8930_ID_PM8917_L2_1 = 109,
+ MSM_RPM_8930_ID_PM8917_L3_0 = 110,
+ MSM_RPM_8930_ID_PM8917_L3_1 = 111,
+ MSM_RPM_8930_ID_PM8917_L4_0 = 112,
+ MSM_RPM_8930_ID_PM8917_L4_1 = 113,
+ MSM_RPM_8930_ID_PM8917_L5_0 = 114,
+ MSM_RPM_8930_ID_PM8917_L5_1 = 115,
+ MSM_RPM_8930_ID_PM8917_L6_0 = 116,
+ MSM_RPM_8930_ID_PM8917_L6_1 = 117,
+ MSM_RPM_8930_ID_PM8917_L7_0 = 118,
+ MSM_RPM_8930_ID_PM8917_L7_1 = 119,
+ MSM_RPM_8930_ID_PM8917_L8_0 = 120,
+ MSM_RPM_8930_ID_PM8917_L8_1 = 121,
+ MSM_RPM_8930_ID_PM8917_L9_0 = 122,
+ MSM_RPM_8930_ID_PM8917_L9_1 = 123,
+ MSM_RPM_8930_ID_PM8917_L10_0 = 124,
+ MSM_RPM_8930_ID_PM8917_L10_1 = 125,
+ MSM_RPM_8930_ID_PM8917_L11_0 = 126,
+ MSM_RPM_8930_ID_PM8917_L11_1 = 127,
+ MSM_RPM_8930_ID_PM8917_L12_0 = 128,
+ MSM_RPM_8930_ID_PM8917_L12_1 = 129,
+ MSM_RPM_8930_ID_PM8917_L14_0 = 130,
+ MSM_RPM_8930_ID_PM8917_L14_1 = 131,
+ MSM_RPM_8930_ID_PM8917_L15_0 = 132,
+ MSM_RPM_8930_ID_PM8917_L15_1 = 133,
+ MSM_RPM_8930_ID_PM8917_L16_0 = 134,
+ MSM_RPM_8930_ID_PM8917_L16_1 = 135,
+ MSM_RPM_8930_ID_PM8917_L17_0 = 136,
+ MSM_RPM_8930_ID_PM8917_L17_1 = 137,
+ MSM_RPM_8930_ID_PM8917_L18_0 = 138,
+ MSM_RPM_8930_ID_PM8917_L18_1 = 139,
+ MSM_RPM_8930_ID_PM8917_L21_0 = 140,
+ MSM_RPM_8930_ID_PM8917_L21_1 = 141,
+ MSM_RPM_8930_ID_PM8917_L22_0 = 142,
+ MSM_RPM_8930_ID_PM8917_L22_1 = 143,
+ MSM_RPM_8930_ID_PM8917_L23_0 = 144,
+ MSM_RPM_8930_ID_PM8917_L23_1 = 145,
+ MSM_RPM_8930_ID_PM8917_L24_0 = 146,
+ MSM_RPM_8930_ID_PM8917_L24_1 = 147,
+ MSM_RPM_8930_ID_PM8917_L25_0 = 148,
+ MSM_RPM_8930_ID_PM8917_L25_1 = 149,
+ MSM_RPM_8930_ID_PM8917_L26_0 = 150,
+ MSM_RPM_8930_ID_PM8917_L26_1 = 151,
+ MSM_RPM_8930_ID_PM8917_L27_0 = 152,
+ MSM_RPM_8930_ID_PM8917_L27_1 = 153,
+ MSM_RPM_8930_ID_PM8917_L28_0 = 154,
+ MSM_RPM_8930_ID_PM8917_L28_1 = 155,
+ MSM_RPM_8930_ID_PM8917_L29_0 = 156,
+ MSM_RPM_8930_ID_PM8917_L29_1 = 157,
+ MSM_RPM_8930_ID_PM8917_L30_0 = 158,
+ MSM_RPM_8930_ID_PM8917_L30_1 = 159,
+ MSM_RPM_8930_ID_PM8917_L31_0 = 160,
+ MSM_RPM_8930_ID_PM8917_L31_1 = 161,
+ MSM_RPM_8930_ID_PM8917_L32_0 = 162,
+ MSM_RPM_8930_ID_PM8917_L32_1 = 163,
+ MSM_RPM_8930_ID_PM8917_L33_0 = 164,
+ MSM_RPM_8930_ID_PM8917_L33_1 = 165,
+ MSM_RPM_8930_ID_PM8917_L34_0 = 166,
+ MSM_RPM_8930_ID_PM8917_L34_1 = 167,
+ MSM_RPM_8930_ID_PM8917_L35_0 = 168,
+ MSM_RPM_8930_ID_PM8917_L35_1 = 169,
+ MSM_RPM_8930_ID_PM8917_L36_0 = 170,
+ MSM_RPM_8930_ID_PM8917_L36_1 = 171,
+ MSM_RPM_8930_ID_PM8917_CLK1_0 = 172,
+ MSM_RPM_8930_ID_PM8917_CLK1_1 = 173,
+ MSM_RPM_8930_ID_PM8917_CLK2_0 = 174,
+ MSM_RPM_8930_ID_PM8917_CLK2_1 = 175,
+ MSM_RPM_8930_ID_PM8917_LVS1 = 176,
+ MSM_RPM_8930_ID_PM8917_LVS3 = 177,
+ MSM_RPM_8930_ID_PM8917_LVS4 = 178,
+ MSM_RPM_8930_ID_PM8917_LVS5 = 179,
+ MSM_RPM_8930_ID_PM8917_LVS6 = 180,
+ MSM_RPM_8930_ID_PM8917_LVS7 = 181,
+
+ MSM_RPM_8930_ID_NCP_0 = 182,
+ MSM_RPM_8930_ID_NCP_1 = 183,
+ MSM_RPM_8930_ID_CXO_BUFFERS = 184,
+ MSM_RPM_8930_ID_USB_OTG_SWITCH = 185,
+ MSM_RPM_8930_ID_HDMI_SWITCH = 186,
+ MSM_RPM_8930_ID_QDSS_CLK = 187,
+ MSM_RPM_8930_ID_VOLTAGE_CORNER = 188,
+
MSM_RPM_8930_ID_LAST = MSM_RPM_8930_ID_VOLTAGE_CORNER,
};
@@ -278,6 +430,8 @@
MSM_RPM_8930_STATUS_ID_MMSS_FABRIC_CFG_CLKMOD = 28,
MSM_RPM_8930_STATUS_ID_MMSS_FABRIC_CFG_IOCTL = 29,
MSM_RPM_8930_STATUS_ID_MM_FABRIC_ARB = 30,
+
+ /* PMIC 8038 */
MSM_RPM_8930_STATUS_ID_PM8038_S1_0 = 31,
MSM_RPM_8930_STATUS_ID_PM8038_S1_1 = 32,
MSM_RPM_8930_STATUS_ID_PM8038_S2_0 = 33,
@@ -346,14 +500,119 @@
MSM_RPM_8930_STATUS_ID_PM8038_CLK2_1 = 100,
MSM_RPM_8930_STATUS_ID_PM8038_LVS1 = 101,
MSM_RPM_8930_STATUS_ID_PM8038_LVS2 = 102,
- MSM_RPM_8930_STATUS_ID_NCP_0 = 103,
- MSM_RPM_8930_STATUS_ID_NCP_1 = 104,
- MSM_RPM_8930_STATUS_ID_CXO_BUFFERS = 105,
- MSM_RPM_8930_STATUS_ID_USB_OTG_SWITCH = 106,
- MSM_RPM_8930_STATUS_ID_HDMI_SWITCH = 107,
- MSM_RPM_8930_STATUS_ID_QDSS_CLK = 108,
- MSM_RPM_8930_STATUS_ID_VOLTAGE_CORNER = 109,
- MSM_RPM_8930_STATUS_ID_LAST = MSM_RPM_8930_STATUS_ID_VOLTAGE_CORNER,
+ MSM_RPM_8930_STATUS_ID_PM8038_NCP_0 = 103,
+ MSM_RPM_8930_STATUS_ID_PM8038_NCP_1 = 104,
+ MSM_RPM_8930_STATUS_ID_PM8038_CXO_BUFFERS = 105,
+ MSM_RPM_8930_STATUS_ID_PM8038_USB_OTG_SWITCH = 106,
+ MSM_RPM_8930_STATUS_ID_PM8038_HDMI_SWITCH = 107,
+ MSM_RPM_8930_STATUS_ID_PM8038_QDSS_CLK = 108,
+ MSM_RPM_8930_STATUS_ID_PM8038_VOLTAGE_CORNER = 109,
+
+ MSM_RPM_8930_STATUS_ID_PM8038_LAST
+ = MSM_RPM_8930_STATUS_ID_PM8038_VOLTAGE_CORNER,
+
+ /* PMIC 8917 */
+ MSM_RPM_8930_STATUS_ID_PM8917_S1_0 = 31,
+ MSM_RPM_8930_STATUS_ID_PM8917_S1_1 = 32,
+ MSM_RPM_8930_STATUS_ID_PM8917_S2_0 = 33,
+ MSM_RPM_8930_STATUS_ID_PM8917_S2_1 = 34,
+ MSM_RPM_8930_STATUS_ID_PM8917_S3_0 = 35,
+ MSM_RPM_8930_STATUS_ID_PM8917_S3_1 = 36,
+ MSM_RPM_8930_STATUS_ID_PM8917_S4_0 = 37,
+ MSM_RPM_8930_STATUS_ID_PM8917_S4_1 = 38,
+ MSM_RPM_8930_STATUS_ID_PM8917_S5_0 = 39,
+ MSM_RPM_8930_STATUS_ID_PM8917_S5_1 = 40,
+ MSM_RPM_8930_STATUS_ID_PM8917_S6_0 = 41,
+ MSM_RPM_8930_STATUS_ID_PM8917_S6_1 = 42,
+ MSM_RPM_8930_STATUS_ID_PM8917_S7_0 = 43,
+ MSM_RPM_8930_STATUS_ID_PM8917_S7_1 = 44,
+ MSM_RPM_8930_STATUS_ID_PM8917_S8_0 = 45,
+ MSM_RPM_8930_STATUS_ID_PM8917_S8_1 = 46,
+ MSM_RPM_8930_STATUS_ID_PM8917_L1_0 = 47,
+ MSM_RPM_8930_STATUS_ID_PM8917_L1_1 = 48,
+ MSM_RPM_8930_STATUS_ID_PM8917_L2_0 = 49,
+ MSM_RPM_8930_STATUS_ID_PM8917_L2_1 = 50,
+ MSM_RPM_8930_STATUS_ID_PM8917_L3_0 = 51,
+ MSM_RPM_8930_STATUS_ID_PM8917_L3_1 = 52,
+ MSM_RPM_8930_STATUS_ID_PM8917_L4_0 = 53,
+ MSM_RPM_8930_STATUS_ID_PM8917_L4_1 = 54,
+ MSM_RPM_8930_STATUS_ID_PM8917_L5_0 = 55,
+ MSM_RPM_8930_STATUS_ID_PM8917_L5_1 = 56,
+ MSM_RPM_8930_STATUS_ID_PM8917_L6_0 = 57,
+ MSM_RPM_8930_STATUS_ID_PM8917_L6_1 = 58,
+ MSM_RPM_8930_STATUS_ID_PM8917_L7_0 = 59,
+ MSM_RPM_8930_STATUS_ID_PM8917_L7_1 = 60,
+ MSM_RPM_8930_STATUS_ID_PM8917_L8_0 = 61,
+ MSM_RPM_8930_STATUS_ID_PM8917_L8_1 = 62,
+ MSM_RPM_8930_STATUS_ID_PM8917_L9_0 = 63,
+ MSM_RPM_8930_STATUS_ID_PM8917_L9_1 = 64,
+ MSM_RPM_8930_STATUS_ID_PM8917_L10_0 = 65,
+ MSM_RPM_8930_STATUS_ID_PM8917_L10_1 = 66,
+ MSM_RPM_8930_STATUS_ID_PM8917_L11_0 = 67,
+ MSM_RPM_8930_STATUS_ID_PM8917_L11_1 = 68,
+ MSM_RPM_8930_STATUS_ID_PM8917_L12_0 = 69,
+ MSM_RPM_8930_STATUS_ID_PM8917_L12_1 = 70,
+ MSM_RPM_8930_STATUS_ID_PM8917_L14_0 = 71,
+ MSM_RPM_8930_STATUS_ID_PM8917_L14_1 = 72,
+ MSM_RPM_8930_STATUS_ID_PM8917_L15_0 = 73,
+ MSM_RPM_8930_STATUS_ID_PM8917_L15_1 = 74,
+ MSM_RPM_8930_STATUS_ID_PM8917_L16_0 = 75,
+ MSM_RPM_8930_STATUS_ID_PM8917_L16_1 = 76,
+ MSM_RPM_8930_STATUS_ID_PM8917_L17_0 = 77,
+ MSM_RPM_8930_STATUS_ID_PM8917_L17_1 = 78,
+ MSM_RPM_8930_STATUS_ID_PM8917_L18_0 = 79,
+ MSM_RPM_8930_STATUS_ID_PM8917_L18_1 = 80,
+ MSM_RPM_8930_STATUS_ID_PM8917_L21_0 = 81,
+ MSM_RPM_8930_STATUS_ID_PM8917_L21_1 = 82,
+ MSM_RPM_8930_STATUS_ID_PM8917_L22_0 = 83,
+ MSM_RPM_8930_STATUS_ID_PM8917_L22_1 = 84,
+ MSM_RPM_8930_STATUS_ID_PM8917_L23_0 = 85,
+ MSM_RPM_8930_STATUS_ID_PM8917_L23_1 = 86,
+ MSM_RPM_8930_STATUS_ID_PM8917_L24_0 = 87,
+ MSM_RPM_8930_STATUS_ID_PM8917_L24_1 = 88,
+ MSM_RPM_8930_STATUS_ID_PM8917_L25_0 = 89,
+ MSM_RPM_8930_STATUS_ID_PM8917_L25_1 = 90,
+ MSM_RPM_8930_STATUS_ID_PM8917_L26_0 = 91,
+ MSM_RPM_8930_STATUS_ID_PM8917_L26_1 = 92,
+ MSM_RPM_8930_STATUS_ID_PM8917_L27_0 = 93,
+ MSM_RPM_8930_STATUS_ID_PM8917_L27_1 = 94,
+ MSM_RPM_8930_STATUS_ID_PM8917_L28_0 = 95,
+ MSM_RPM_8930_STATUS_ID_PM8917_L28_1 = 96,
+ MSM_RPM_8930_STATUS_ID_PM8917_L29_0 = 97,
+ MSM_RPM_8930_STATUS_ID_PM8917_L29_1 = 98,
+ MSM_RPM_8930_STATUS_ID_PM8917_L30_0 = 99,
+ MSM_RPM_8930_STATUS_ID_PM8917_L30_1 = 100,
+ MSM_RPM_8930_STATUS_ID_PM8917_L31_0 = 101,
+ MSM_RPM_8930_STATUS_ID_PM8917_L31_1 = 102,
+ MSM_RPM_8930_STATUS_ID_PM8917_L32_0 = 103,
+ MSM_RPM_8930_STATUS_ID_PM8917_L32_1 = 104,
+ MSM_RPM_8930_STATUS_ID_PM8917_L33_0 = 105,
+ MSM_RPM_8930_STATUS_ID_PM8917_L33_1 = 106,
+ MSM_RPM_8930_STATUS_ID_PM8917_L34_0 = 107,
+ MSM_RPM_8930_STATUS_ID_PM8917_L34_1 = 108,
+ MSM_RPM_8930_STATUS_ID_PM8917_L35_0 = 109,
+ MSM_RPM_8930_STATUS_ID_PM8917_L35_1 = 110,
+ MSM_RPM_8930_STATUS_ID_PM8917_L36_0 = 111,
+ MSM_RPM_8930_STATUS_ID_PM8917_L36_1 = 112,
+ MSM_RPM_8930_STATUS_ID_PM8917_CLK1_0 = 113,
+ MSM_RPM_8930_STATUS_ID_PM8917_CLK1_1 = 114,
+ MSM_RPM_8930_STATUS_ID_PM8917_CLK2_0 = 115,
+ MSM_RPM_8930_STATUS_ID_PM8917_CLK2_1 = 116,
+ MSM_RPM_8930_STATUS_ID_PM8917_LVS1 = 117,
+ MSM_RPM_8930_STATUS_ID_PM8917_LVS3 = 118,
+ MSM_RPM_8930_STATUS_ID_PM8917_LVS4 = 119,
+ MSM_RPM_8930_STATUS_ID_PM8917_LVS5 = 120,
+ MSM_RPM_8930_STATUS_ID_PM8917_LVS6 = 121,
+ MSM_RPM_8930_STATUS_ID_PM8917_LVS7 = 122,
+ MSM_RPM_8930_STATUS_ID_PM8917_NCP_0 = 123,
+ MSM_RPM_8930_STATUS_ID_PM8917_NCP_1 = 124,
+ MSM_RPM_8930_STATUS_ID_PM8917_CXO_BUFFERS = 125,
+ MSM_RPM_8930_STATUS_ID_PM8917_USB_OTG_SWITCH = 126,
+ MSM_RPM_8930_STATUS_ID_PM8917_HDMI_SWITCH = 127,
+ MSM_RPM_8930_STATUS_ID_PM8917_QDSS_CLK = 128,
+ MSM_RPM_8930_STATUS_ID_PM8917_VOLTAGE_CORNER = 129,
+ MSM_RPM_8930_STATUS_ID_PM8917_PM8917_LAST
+ = MSM_RPM_8930_STATUS_ID_PM8917_VOLTAGE_CORNER,
};
#endif /* __ARCH_ARM_MACH_MSM_RPM_8930_H */
diff --git a/arch/arm/mach-msm/include/mach/rpm-regulator-8930.h b/arch/arm/mach-msm/include/mach/rpm-regulator-8930.h
index 47056a8..f8f53f6 100644
--- a/arch/arm/mach-msm/include/mach/rpm-regulator-8930.h
+++ b/arch/arm/mach-msm/include/mach/rpm-regulator-8930.h
@@ -85,9 +85,10 @@
};
/**
- * enum rpm_vreg_id - RPM regulator ID numbers (both real and pin control)
+ * enum rpm_vreg_id_8930_pm8038 - RPM regulator ID numbers (both real and
+ * pin control) used with MSM8930 + PM8038
*/
-enum rpm_vreg_id_8930 {
+enum rpm_vreg_id_8930_pm8038 {
RPM_VREG_ID_PM8038_L1,
RPM_VREG_ID_PM8038_L2,
RPM_VREG_ID_PM8038_L3,
@@ -155,6 +156,109 @@
RPM_VREG_ID_PM8038_MAX = RPM_VREG_ID_PM8038_LVS2_PC,
};
+/**
+ * enum rpm_vreg_id_8930_pm8917 - RPM regulator ID numbers (both real and
+ * pin control) used with MSM8930 + PM8917
+ */
+enum rpm_vreg_id_8930_pm8917 {
+ RPM_VREG_ID_PM8917_L1,
+ RPM_VREG_ID_PM8917_L2,
+ RPM_VREG_ID_PM8917_L3,
+ RPM_VREG_ID_PM8917_L4,
+ RPM_VREG_ID_PM8917_L5,
+ RPM_VREG_ID_PM8917_L6,
+ RPM_VREG_ID_PM8917_L7,
+ RPM_VREG_ID_PM8917_L8,
+ RPM_VREG_ID_PM8917_L9,
+ RPM_VREG_ID_PM8917_L10,
+ RPM_VREG_ID_PM8917_L11,
+ RPM_VREG_ID_PM8917_L12,
+ RPM_VREG_ID_PM8917_L14,
+ RPM_VREG_ID_PM8917_L15,
+ RPM_VREG_ID_PM8917_L16,
+ RPM_VREG_ID_PM8917_L17,
+ RPM_VREG_ID_PM8917_L18,
+ RPM_VREG_ID_PM8917_L21,
+ RPM_VREG_ID_PM8917_L22,
+ RPM_VREG_ID_PM8917_L23,
+ RPM_VREG_ID_PM8917_L24,
+ RPM_VREG_ID_PM8917_L25,
+ RPM_VREG_ID_PM8917_L26,
+ RPM_VREG_ID_PM8917_L27,
+ RPM_VREG_ID_PM8917_L28,
+ RPM_VREG_ID_PM8917_L29,
+ RPM_VREG_ID_PM8917_L30,
+ RPM_VREG_ID_PM8917_L31,
+ RPM_VREG_ID_PM8917_L32,
+ RPM_VREG_ID_PM8917_L33,
+ RPM_VREG_ID_PM8917_L34,
+ RPM_VREG_ID_PM8917_L35,
+ RPM_VREG_ID_PM8917_L36,
+ RPM_VREG_ID_PM8917_S1,
+ RPM_VREG_ID_PM8917_S2,
+ RPM_VREG_ID_PM8917_S3,
+ RPM_VREG_ID_PM8917_S4,
+ RPM_VREG_ID_PM8917_S5,
+ RPM_VREG_ID_PM8917_S6,
+ RPM_VREG_ID_PM8917_S7,
+ RPM_VREG_ID_PM8917_S8,
+ RPM_VREG_ID_PM8917_LVS1,
+ RPM_VREG_ID_PM8917_LVS3,
+ RPM_VREG_ID_PM8917_LVS4,
+ RPM_VREG_ID_PM8917_LVS5,
+ RPM_VREG_ID_PM8917_LVS6,
+ RPM_VREG_ID_PM8917_LVS7,
+ RPM_VREG_ID_PM8917_USB_OTG,
+ RPM_VREG_ID_PM8917_VDD_DIG_CORNER,
+ RPM_VREG_ID_PM8917_MAX_REAL = RPM_VREG_ID_PM8917_VDD_DIG_CORNER,
+
+ /* The following are IDs for regulator devices to enable pin control. */
+ RPM_VREG_ID_PM8917_L1_PC,
+ RPM_VREG_ID_PM8917_L2_PC,
+ RPM_VREG_ID_PM8917_L3_PC,
+ RPM_VREG_ID_PM8917_L4_PC,
+ RPM_VREG_ID_PM8917_L5_PC,
+ RPM_VREG_ID_PM8917_L6_PC,
+ RPM_VREG_ID_PM8917_L7_PC,
+ RPM_VREG_ID_PM8917_L8_PC,
+ RPM_VREG_ID_PM8917_L9_PC,
+ RPM_VREG_ID_PM8917_L10_PC,
+ RPM_VREG_ID_PM8917_L11_PC,
+ RPM_VREG_ID_PM8917_L12_PC,
+ RPM_VREG_ID_PM8917_L14_PC,
+ RPM_VREG_ID_PM8917_L15_PC,
+ RPM_VREG_ID_PM8917_L16_PC,
+ RPM_VREG_ID_PM8917_L17_PC,
+ RPM_VREG_ID_PM8917_L18_PC,
+ RPM_VREG_ID_PM8917_L21_PC,
+ RPM_VREG_ID_PM8917_L22_PC,
+ RPM_VREG_ID_PM8917_L23_PC,
+
+ RPM_VREG_ID_PM8917_L29_PC,
+ RPM_VREG_ID_PM8917_L30_PC,
+ RPM_VREG_ID_PM8917_L31_PC,
+ RPM_VREG_ID_PM8917_L32_PC,
+ RPM_VREG_ID_PM8917_L33_PC,
+ RPM_VREG_ID_PM8917_L34_PC,
+ RPM_VREG_ID_PM8917_L35_PC,
+ RPM_VREG_ID_PM8917_L36_PC,
+ RPM_VREG_ID_PM8917_S1_PC,
+ RPM_VREG_ID_PM8917_S2_PC,
+ RPM_VREG_ID_PM8917_S3_PC,
+ RPM_VREG_ID_PM8917_S4_PC,
+
+ RPM_VREG_ID_PM8917_S7_PC,
+ RPM_VREG_ID_PM8917_S8_PC,
+ RPM_VREG_ID_PM8917_LVS1_PC,
+ RPM_VREG_ID_PM8917_LVS3_PC,
+ RPM_VREG_ID_PM8917_LVS4_PC,
+ RPM_VREG_ID_PM8917_LVS5_PC,
+ RPM_VREG_ID_PM8917_LVS6_PC,
+ RPM_VREG_ID_PM8917_LVS7_PC,
+
+ RPM_VREG_ID_PM8917_MAX = RPM_VREG_ID_PM8917_LVS7_PC,
+};
+
/* Minimum high power mode loads in uA. */
#define RPM_VREG_8930_LDO_5_HPM_MIN_LOAD 0
#define RPM_VREG_8930_LDO_50_HPM_MIN_LOAD 5000
diff --git a/arch/arm/mach-msm/include/mach/rpm-regulator.h b/arch/arm/mach-msm/include/mach/rpm-regulator.h
index d2ff2fe..f6e082d 100644
--- a/arch/arm/mach-msm/include/mach/rpm-regulator.h
+++ b/arch/arm/mach-msm/include/mach/rpm-regulator.h
@@ -31,7 +31,8 @@
RPM_VREG_VERSION_8960,
RPM_VREG_VERSION_9615,
RPM_VREG_VERSION_8930,
- RPM_VREG_VERSION_MAX = RPM_VREG_VERSION_8930,
+ RPM_VREG_VERSION_8930_PM8917,
+ RPM_VREG_VERSION_MAX = RPM_VREG_VERSION_8930_PM8917,
};
#define RPM_VREG_PIN_CTRL_NONE 0x00
diff --git a/arch/arm/mach-msm/include/mach/rpm.h b/arch/arm/mach-msm/include/mach/rpm.h
index f6b9a6e..4ee1997 100644
--- a/arch/arm/mach-msm/include/mach/rpm.h
+++ b/arch/arm/mach-msm/include/mach/rpm.h
@@ -451,6 +451,100 @@
MSM_RPM_ID_PM8038_CLK2_1,
MSM_RPM_ID_PM8038_LVS1,
MSM_RPM_ID_PM8038_LVS2,
+
+ /* PM8917 specific */
+ MSM_RPM_ID_PM8917_S1_0,
+ MSM_RPM_ID_PM8917_S1_1,
+ MSM_RPM_ID_PM8917_S2_0,
+ MSM_RPM_ID_PM8917_S2_1,
+ MSM_RPM_ID_PM8917_S3_0,
+ MSM_RPM_ID_PM8917_S3_1,
+ MSM_RPM_ID_PM8917_S4_0,
+ MSM_RPM_ID_PM8917_S4_1,
+ MSM_RPM_ID_PM8917_S5_0,
+ MSM_RPM_ID_PM8917_S5_1,
+ MSM_RPM_ID_PM8917_S6_0,
+ MSM_RPM_ID_PM8917_S6_1,
+ MSM_RPM_ID_PM8917_S7_0,
+ MSM_RPM_ID_PM8917_S7_1,
+ MSM_RPM_ID_PM8917_S8_0,
+ MSM_RPM_ID_PM8917_S8_1,
+ MSM_RPM_ID_PM8917_L1_0,
+ MSM_RPM_ID_PM8917_L1_1,
+ MSM_RPM_ID_PM8917_L2_0,
+ MSM_RPM_ID_PM8917_L2_1,
+ MSM_RPM_ID_PM8917_L3_0,
+ MSM_RPM_ID_PM8917_L3_1,
+ MSM_RPM_ID_PM8917_L4_0,
+ MSM_RPM_ID_PM8917_L4_1,
+ MSM_RPM_ID_PM8917_L5_0,
+ MSM_RPM_ID_PM8917_L5_1,
+ MSM_RPM_ID_PM8917_L6_0,
+ MSM_RPM_ID_PM8917_L6_1,
+ MSM_RPM_ID_PM8917_L7_0,
+ MSM_RPM_ID_PM8917_L7_1,
+ MSM_RPM_ID_PM8917_L8_0,
+ MSM_RPM_ID_PM8917_L8_1,
+ MSM_RPM_ID_PM8917_L9_0,
+ MSM_RPM_ID_PM8917_L9_1,
+ MSM_RPM_ID_PM8917_L10_0,
+ MSM_RPM_ID_PM8917_L10_1,
+ MSM_RPM_ID_PM8917_L11_0,
+ MSM_RPM_ID_PM8917_L11_1,
+ MSM_RPM_ID_PM8917_L12_0,
+ MSM_RPM_ID_PM8917_L12_1,
+ MSM_RPM_ID_PM8917_L14_0,
+ MSM_RPM_ID_PM8917_L14_1,
+ MSM_RPM_ID_PM8917_L15_0,
+ MSM_RPM_ID_PM8917_L15_1,
+ MSM_RPM_ID_PM8917_L16_0,
+ MSM_RPM_ID_PM8917_L16_1,
+ MSM_RPM_ID_PM8917_L17_0,
+ MSM_RPM_ID_PM8917_L17_1,
+ MSM_RPM_ID_PM8917_L18_0,
+ MSM_RPM_ID_PM8917_L18_1,
+ MSM_RPM_ID_PM8917_L21_0,
+ MSM_RPM_ID_PM8917_L21_1,
+ MSM_RPM_ID_PM8917_L22_0,
+ MSM_RPM_ID_PM8917_L22_1,
+ MSM_RPM_ID_PM8917_L23_0,
+ MSM_RPM_ID_PM8917_L23_1,
+ MSM_RPM_ID_PM8917_L24_0,
+ MSM_RPM_ID_PM8917_L24_1,
+ MSM_RPM_ID_PM8917_L25_0,
+ MSM_RPM_ID_PM8917_L25_1,
+ MSM_RPM_ID_PM8917_L26_0,
+ MSM_RPM_ID_PM8917_L26_1,
+ MSM_RPM_ID_PM8917_L27_0,
+ MSM_RPM_ID_PM8917_L27_1,
+ MSM_RPM_ID_PM8917_L28_0,
+ MSM_RPM_ID_PM8917_L28_1,
+ MSM_RPM_ID_PM8917_L29_0,
+ MSM_RPM_ID_PM8917_L29_1,
+ MSM_RPM_ID_PM8917_L30_0,
+ MSM_RPM_ID_PM8917_L30_1,
+ MSM_RPM_ID_PM8917_L31_0,
+ MSM_RPM_ID_PM8917_L31_1,
+ MSM_RPM_ID_PM8917_L32_0,
+ MSM_RPM_ID_PM8917_L32_1,
+ MSM_RPM_ID_PM8917_L33_0,
+ MSM_RPM_ID_PM8917_L33_1,
+ MSM_RPM_ID_PM8917_L34_0,
+ MSM_RPM_ID_PM8917_L34_1,
+ MSM_RPM_ID_PM8917_L35_0,
+ MSM_RPM_ID_PM8917_L35_1,
+ MSM_RPM_ID_PM8917_L36_0,
+ MSM_RPM_ID_PM8917_L36_1,
+ MSM_RPM_ID_PM8917_CLK1_0,
+ MSM_RPM_ID_PM8917_CLK1_1,
+ MSM_RPM_ID_PM8917_CLK2_0,
+ MSM_RPM_ID_PM8917_CLK2_1,
+ MSM_RPM_ID_PM8917_LVS1,
+ MSM_RPM_ID_PM8917_LVS3,
+ MSM_RPM_ID_PM8917_LVS4,
+ MSM_RPM_ID_PM8917_LVS5,
+ MSM_RPM_ID_PM8917_LVS6,
+ MSM_RPM_ID_PM8917_LVS7,
MSM_RPM_ID_VOLTAGE_CORNER,
/* 8064 specific */
@@ -605,6 +699,29 @@
MSM_RPM_STATUS_ID_EBI1_CH1_RANGE,
MSM_RPM_STATUS_ID_QDSS_CLK,
+ /* 8930 aliases to simplify device mapping */
+ MSM_RPM_STATUS_ID_PM8038_NCP_0 = MSM_RPM_STATUS_ID_NCP_0,
+ MSM_RPM_STATUS_ID_PM8038_NCP_1 = MSM_RPM_STATUS_ID_NCP_1,
+ MSM_RPM_STATUS_ID_PM8038_CXO_BUFFERS
+ = MSM_RPM_STATUS_ID_CXO_BUFFERS,
+ MSM_RPM_STATUS_ID_PM8038_USB_OTG_SWITCH
+ = MSM_RPM_STATUS_ID_USB_OTG_SWITCH,
+ MSM_RPM_STATUS_ID_PM8038_HDMI_SWITCH
+ = MSM_RPM_STATUS_ID_HDMI_SWITCH,
+ MSM_RPM_STATUS_ID_PM8038_QDSS_CLK
+ = MSM_RPM_STATUS_ID_QDSS_CLK,
+
+ MSM_RPM_STATUS_ID_PM8917_NCP_0 = MSM_RPM_STATUS_ID_NCP_0,
+ MSM_RPM_STATUS_ID_PM8917_NCP_1 = MSM_RPM_STATUS_ID_NCP_1,
+ MSM_RPM_STATUS_ID_PM8917_CXO_BUFFERS
+ = MSM_RPM_STATUS_ID_CXO_BUFFERS,
+ MSM_RPM_STATUS_ID_PM8917_USB_OTG_SWITCH
+ = MSM_RPM_STATUS_ID_USB_OTG_SWITCH,
+ MSM_RPM_STATUS_ID_PM8917_HDMI_SWITCH
+ = MSM_RPM_STATUS_ID_HDMI_SWITCH,
+ MSM_RPM_STATUS_ID_PM8917_QDSS_CLK
+ = MSM_RPM_STATUS_ID_QDSS_CLK,
+
/* 8660 Specific */
MSM_RPM_STATUS_ID_PLL_4,
MSM_RPM_STATUS_ID_SMI_CLK,
@@ -817,7 +934,105 @@
MSM_RPM_STATUS_ID_PM8038_CLK2_1,
MSM_RPM_STATUS_ID_PM8038_LVS1,
MSM_RPM_STATUS_ID_PM8038_LVS2,
+
+ /* PMIC 8917 */
+ MSM_RPM_STATUS_ID_PM8917_S1_0,
+ MSM_RPM_STATUS_ID_PM8917_S1_1,
+ MSM_RPM_STATUS_ID_PM8917_S2_0,
+ MSM_RPM_STATUS_ID_PM8917_S2_1,
+ MSM_RPM_STATUS_ID_PM8917_S3_0,
+ MSM_RPM_STATUS_ID_PM8917_S3_1,
+ MSM_RPM_STATUS_ID_PM8917_S4_0,
+ MSM_RPM_STATUS_ID_PM8917_S4_1,
+ MSM_RPM_STATUS_ID_PM8917_S5_0,
+ MSM_RPM_STATUS_ID_PM8917_S5_1,
+ MSM_RPM_STATUS_ID_PM8917_S6_0,
+ MSM_RPM_STATUS_ID_PM8917_S6_1,
+ MSM_RPM_STATUS_ID_PM8917_S7_0,
+ MSM_RPM_STATUS_ID_PM8917_S7_1,
+ MSM_RPM_STATUS_ID_PM8917_S8_0,
+ MSM_RPM_STATUS_ID_PM8917_S8_1,
+ MSM_RPM_STATUS_ID_PM8917_L1_0,
+ MSM_RPM_STATUS_ID_PM8917_L1_1,
+ MSM_RPM_STATUS_ID_PM8917_L2_0,
+ MSM_RPM_STATUS_ID_PM8917_L2_1,
+ MSM_RPM_STATUS_ID_PM8917_L3_0,
+ MSM_RPM_STATUS_ID_PM8917_L3_1,
+ MSM_RPM_STATUS_ID_PM8917_L4_0,
+ MSM_RPM_STATUS_ID_PM8917_L4_1,
+ MSM_RPM_STATUS_ID_PM8917_L5_0,
+ MSM_RPM_STATUS_ID_PM8917_L5_1,
+ MSM_RPM_STATUS_ID_PM8917_L6_0,
+ MSM_RPM_STATUS_ID_PM8917_L6_1,
+ MSM_RPM_STATUS_ID_PM8917_L7_0,
+ MSM_RPM_STATUS_ID_PM8917_L7_1,
+ MSM_RPM_STATUS_ID_PM8917_L8_0,
+ MSM_RPM_STATUS_ID_PM8917_L8_1,
+ MSM_RPM_STATUS_ID_PM8917_L9_0,
+ MSM_RPM_STATUS_ID_PM8917_L9_1,
+ MSM_RPM_STATUS_ID_PM8917_L10_0,
+ MSM_RPM_STATUS_ID_PM8917_L10_1,
+ MSM_RPM_STATUS_ID_PM8917_L11_0,
+ MSM_RPM_STATUS_ID_PM8917_L11_1,
+ MSM_RPM_STATUS_ID_PM8917_L12_0,
+ MSM_RPM_STATUS_ID_PM8917_L12_1,
+ MSM_RPM_STATUS_ID_PM8917_L14_0,
+ MSM_RPM_STATUS_ID_PM8917_L14_1,
+ MSM_RPM_STATUS_ID_PM8917_L15_0,
+ MSM_RPM_STATUS_ID_PM8917_L15_1,
+ MSM_RPM_STATUS_ID_PM8917_L16_0,
+ MSM_RPM_STATUS_ID_PM8917_L16_1,
+ MSM_RPM_STATUS_ID_PM8917_L17_0,
+ MSM_RPM_STATUS_ID_PM8917_L17_1,
+ MSM_RPM_STATUS_ID_PM8917_L18_0,
+ MSM_RPM_STATUS_ID_PM8917_L18_1,
+ MSM_RPM_STATUS_ID_PM8917_L21_0,
+ MSM_RPM_STATUS_ID_PM8917_L21_1,
+ MSM_RPM_STATUS_ID_PM8917_L22_0,
+ MSM_RPM_STATUS_ID_PM8917_L22_1,
+ MSM_RPM_STATUS_ID_PM8917_L23_0,
+ MSM_RPM_STATUS_ID_PM8917_L23_1,
+ MSM_RPM_STATUS_ID_PM8917_L24_0,
+ MSM_RPM_STATUS_ID_PM8917_L24_1,
+ MSM_RPM_STATUS_ID_PM8917_L25_0,
+ MSM_RPM_STATUS_ID_PM8917_L25_1,
+ MSM_RPM_STATUS_ID_PM8917_L26_0,
+ MSM_RPM_STATUS_ID_PM8917_L26_1,
+ MSM_RPM_STATUS_ID_PM8917_L27_0,
+ MSM_RPM_STATUS_ID_PM8917_L27_1,
+ MSM_RPM_STATUS_ID_PM8917_L28_0,
+ MSM_RPM_STATUS_ID_PM8917_L28_1,
+ MSM_RPM_STATUS_ID_PM8917_L29_0,
+ MSM_RPM_STATUS_ID_PM8917_L29_1,
+ MSM_RPM_STATUS_ID_PM8917_L30_0,
+ MSM_RPM_STATUS_ID_PM8917_L30_1,
+ MSM_RPM_STATUS_ID_PM8917_L31_0,
+ MSM_RPM_STATUS_ID_PM8917_L31_1,
+ MSM_RPM_STATUS_ID_PM8917_L32_0,
+ MSM_RPM_STATUS_ID_PM8917_L32_1,
+ MSM_RPM_STATUS_ID_PM8917_L33_0,
+ MSM_RPM_STATUS_ID_PM8917_L33_1,
+ MSM_RPM_STATUS_ID_PM8917_L34_0,
+ MSM_RPM_STATUS_ID_PM8917_L34_1,
+ MSM_RPM_STATUS_ID_PM8917_L35_0,
+ MSM_RPM_STATUS_ID_PM8917_L35_1,
+ MSM_RPM_STATUS_ID_PM8917_L36_0,
+ MSM_RPM_STATUS_ID_PM8917_L36_1,
+ MSM_RPM_STATUS_ID_PM8917_CLK1_0,
+ MSM_RPM_STATUS_ID_PM8917_CLK1_1,
+ MSM_RPM_STATUS_ID_PM8917_CLK2_0,
+ MSM_RPM_STATUS_ID_PM8917_CLK2_1,
+ MSM_RPM_STATUS_ID_PM8917_LVS1,
+ MSM_RPM_STATUS_ID_PM8917_LVS3,
+ MSM_RPM_STATUS_ID_PM8917_LVS4,
+ MSM_RPM_STATUS_ID_PM8917_LVS5,
+ MSM_RPM_STATUS_ID_PM8917_LVS6,
+ MSM_RPM_STATUS_ID_PM8917_LVS7,
MSM_RPM_STATUS_ID_VOLTAGE_CORNER,
+ MSM_RPM_STATUS_ID_PM8917_VOLTAGE_CORNER
+ = MSM_RPM_STATUS_ID_VOLTAGE_CORNER,
+ MSM_RPM_STATUS_ID_PM8038_VOLTAGE_CORNER
+ = MSM_RPM_STATUS_ID_VOLTAGE_CORNER,
/* 8064 specific */
MSM_RPM_STATUS_ID_PM8821_S1_0,
@@ -899,6 +1114,7 @@
extern struct msm_rpm_platform_data msm8960_rpm_data;
extern struct msm_rpm_platform_data msm9615_rpm_data;
extern struct msm_rpm_platform_data msm8930_rpm_data;
+extern struct msm_rpm_platform_data msm8930_rpm_data_pm8917;
extern struct msm_rpm_platform_data apq8064_rpm_data;
#if defined(CONFIG_MSM_RPM)
diff --git a/arch/arm/mach-msm/msm_cpr.c b/arch/arm/mach-msm/msm_cpr.c
index f4272f3..b6c05f4 100644
--- a/arch/arm/mach-msm/msm_cpr.c
+++ b/arch/arm/mach-msm/msm_cpr.c
@@ -36,6 +36,14 @@
#define MODULE_NAME "msm-cpr"
+/**
+ * Convert the Delay time to Timer Count Register
+ * e.g if frequency is 19200 kHz and delay required is
+ * 20000us, so timer count will be 19200 * 20000 / 1000
+ */
+#define TIMER_COUNT(freq, delay) ((freq * delay) / 1000)
+#define ALL_CPR_IRQ 0x3F
+
/* Need platform device handle for suspend and resume APIs */
static struct platform_device *cpr_pdev;
@@ -45,6 +53,7 @@
int prev_mode;
uint32_t floor;
uint32_t ceiling;
+ bool max_volt_set;
void __iomem *base;
unsigned int irq;
struct mutex cpr_mutex;
@@ -157,7 +166,7 @@
static void
cpr_2pt_kv_analysis(struct msm_cpr *cpr, struct msm_cpr_mode *chip_data)
{
- int32_t tgt_volt_mV = 0, level_uV, rc;
+ int32_t level_uV = 0, rc;
uint32_t quot1, quot2;
/**
@@ -180,15 +189,10 @@
* voltage, offset is always subtracted from it.
*
*/
- if (chip_data->tgt_volt_offset > 0) {
- tgt_volt_mV = chip_data->calibrated_mV -
- (chip_data->tgt_volt_offset * cpr->vp->step_size);
- }
- pr_debug("tgt_volt_mV = %d, calibrated_mV = %d", tgt_volt_mV,
- chip_data->calibrated_mV);
+ level_uV = chip_data->Vmax -
+ (chip_data->tgt_volt_offset * cpr->vp->step_size);
+ pr_debug("tgt_volt_uV = %d\n", level_uV);
- /* level_uV = tgt_volt_mV * 1000; */
- level_uV = 1350000;
/* Call the PMIC specific routine to set the voltage */
rc = regulator_set_voltage(cpr->vreg_cx, level_uV, level_uV);
if (rc) {
@@ -202,10 +206,7 @@
return;
}
- /* Store the adjusted value of voltage */
- chip_data->calibrated_mV = 1300;
-
- /* Take first CPR measurement at a higher voltage to get QUOT1 */
+ /* First CPR measurement at a higher voltage to get QUOT1 */
/* Enable the Software mode of operation */
cpr_modify_reg(cpr, RBCPR_CTL, HW_TO_PMIC_EN_M, SW_MODE);
@@ -231,7 +232,8 @@
quot1 = (cpr_read_reg(cpr, RBCPR_DEBUG1) & QUOT_SLOW_M) >> 12;
/* Take second CPR measurement at a lower voltage to get QUOT2 */
- level_uV = 1300000;
+ level_uV -= 4 * cpr->vp->step_size;
+ pr_debug("tgt_volt_uV = %d\n", level_uV);
cpr_modify_reg(cpr, RBCPR_CTL, LOOP_EN_M, DISABLE_CPR);
/* Call the PMIC specific routine to set the voltage */
@@ -261,7 +263,7 @@
}
quot2 = (cpr_read_reg(cpr, RBCPR_DEBUG1) & QUOT_SLOW_M) >> 12;
chip_data->step_quot = (quot1 - quot2) / 4;
- pr_debug("%s: Calculated Step Quot is %d\n",
+ pr_info("%s: Calculated Step Quot is %d\n",
__func__, chip_data->step_quot);
/* Disable the cpr */
cpr_modify_reg(cpr, RBCPR_CTL, LOOP_EN_M, DISABLE_CPR);
@@ -279,7 +281,7 @@
void cpr_irq_clr_and_ack(struct msm_cpr *cpr, uint32_t mask)
{
/* Clear the interrupt */
- cpr_write_reg(cpr, RBIF_IRQ_CLEAR, 0x3F);
+ cpr_write_reg(cpr, RBIF_IRQ_CLEAR, ALL_CPR_IRQ);
/* Acknowledge the Recommendation */
cpr_write_reg(cpr, RBIF_CONT_ACK_CMD, 0x1);
}
@@ -287,7 +289,7 @@
static inline
void cpr_irq_clr_and_nack(struct msm_cpr *cpr, uint32_t mask)
{
- cpr_write_reg(cpr, RBIF_IRQ_CLEAR, 0x3F);
+ cpr_write_reg(cpr, RBIF_IRQ_CLEAR, ALL_CPR_IRQ);
cpr_write_reg(cpr, RBIF_CONT_NACK_CMD, 0x1);
}
@@ -307,7 +309,7 @@
static void
cpr_up_event_handler(struct msm_cpr *cpr, uint32_t new_volt)
{
- int rc, set_volt_mV;
+ int rc, set_volt_uV;
struct msm_cpr_mode *chip_data;
chip_data = &cpr->config->cpr_mode_data[cpr->cpr_mode];
@@ -317,26 +319,28 @@
* freq switch handler and CPR interrupt handler here
*/
/* Set New PMIC voltage */
- set_volt_mV = (new_volt < chip_data->Vmax ? new_volt
+ set_volt_uV = (new_volt < chip_data->Vmax ? new_volt
: chip_data->Vmax);
- rc = regulator_set_voltage(cpr->vreg_cx, set_volt_mV * 1000,
- set_volt_mV * 1000);
+ rc = regulator_set_voltage(cpr->vreg_cx, set_volt_uV,
+ set_volt_uV);
if (rc) {
- pr_err("%s: Voltage set at %dmV failed. %d\n",
- __func__, set_volt_mV, rc);
+ pr_err("%s: Voltage set at %duV failed. %d\n",
+ __func__, set_volt_uV, rc);
cpr_irq_clr_and_nack(cpr, BIT(4) | BIT(0));
return;
}
- pr_debug("%s: Voltage set at %dmV\n", __func__, set_volt_mV);
+ pr_info("(railway_voltage: %d uV)\n", set_volt_uV);
+
+ cpr->max_volt_set = (set_volt_uV == chip_data->Vmax) ? 1 : 0;
/**
* Save the new calibrated voltage to be re-used
* whenever we return to same mode after a mode switch.
*/
- chip_data->calibrated_mV = set_volt_mV;
+ chip_data->calibrated_uV = set_volt_uV;
/* Clear all the interrupts */
- cpr_write_reg(cpr, RBIF_IRQ_CLEAR, 0x3F);
+ cpr_write_reg(cpr, RBIF_IRQ_CLEAR, ALL_CPR_IRQ);
/* Disable Auto ACK for Down interrupts */
cpr_modify_reg(cpr, RBCPR_CTL, SW_AUTO_CONT_NACK_DN_EN_M, 0);
@@ -353,7 +357,7 @@
static void
cpr_dn_event_handler(struct msm_cpr *cpr, uint32_t new_volt)
{
- int rc, set_volt_mV;
+ int rc, set_volt_uV;
struct msm_cpr_mode *chip_data;
chip_data = &cpr->config->cpr_mode_data[cpr->cpr_mode];
@@ -363,26 +367,28 @@
* freq switch handler and CPR interrupt handler here
*/
/* Set New PMIC volt */
- set_volt_mV = (new_volt > chip_data->Vmin ? new_volt
+ set_volt_uV = (new_volt > chip_data->Vmin ? new_volt
: chip_data->Vmin);
- rc = regulator_set_voltage(cpr->vreg_cx, set_volt_mV * 1000,
- set_volt_mV * 1000);
+ rc = regulator_set_voltage(cpr->vreg_cx, set_volt_uV,
+ set_volt_uV);
if (rc) {
- pr_err("%s: Voltage at %dmV failed %d\n",
- __func__, set_volt_mV, rc);
+ pr_err("%s: Voltage at %duV failed %d\n",
+ __func__, set_volt_uV, rc);
cpr_irq_clr_and_nack(cpr, BIT(2) | BIT(0));
return;
}
- pr_debug("%s: Voltage set at %dmV\n", __func__, set_volt_mV);
+ pr_info("(railway_voltage: %d uV)\n", set_volt_uV);
+
+ cpr->max_volt_set = 0;
/**
* Save the new calibrated voltage to be re-used
* whenever we return to same mode after a mode switch.
*/
- chip_data->calibrated_mV = set_volt_mV;
+ chip_data->calibrated_uV = set_volt_uV;
/* Clear all the interrupts */
- cpr_write_reg(cpr, RBIF_IRQ_CLEAR, 0x3F);
+ cpr_write_reg(cpr, RBIF_IRQ_CLEAR, ALL_CPR_IRQ);
if (new_volt <= chip_data->Vmin) {
/*
@@ -416,16 +422,22 @@
chip_data = &cpr->config->cpr_mode_data[cpr->cpr_mode];
error_step = cpr_read_reg(cpr, RBCPR_RESULT_0) >> 2;
error_step &= 0xF;
- curr_volt = chip_data->calibrated_mV;
+ curr_volt = chip_data->calibrated_uV;
if (action == UP) {
+ /* Clear IRQ, ACK and return if Vdd already at Vmax */
+ if (cpr->max_volt_set == 1) {
+ cpr_write_reg(cpr, RBIF_IRQ_CLEAR, ALL_CPR_IRQ);
+ cpr_write_reg(cpr, RBIF_CONT_NACK_CMD, 0x1);
+ return;
+ }
+
/**
* Using up margin in the comparison helps avoid having to
* change up threshold values in chip register.
*/
if (error_step < (cpr->config->up_threshold +
cpr->config->up_margin)) {
- /* FIXME: Avoid repeated dn interrupts if we are here */
pr_debug("UP_INT error step too small to set\n");
cpr_irq_clr_and_nack(cpr, BIT(4) | BIT(0));
return;
@@ -434,6 +446,7 @@
/* Calculte new PMIC voltage */
new_volt = curr_volt + (error_step * cpr->vp->step_size);
pr_debug("UP_INT: new_volt: %d\n", new_volt);
+ pr_info("(UP Voltage recommended by CPR: %d uV)\n", new_volt);
cpr_up_event_handler(cpr, new_volt);
} else if (action == DOWN) {
@@ -443,7 +456,6 @@
*/
if (error_step < (cpr->config->dn_threshold +
cpr->config->dn_margin)) {
- /* FIXME: Avoid repeated dn interrupts if we are here */
pr_debug("DOWN_INT error_step too small to set\n");
cpr_irq_clr_and_nack(cpr, BIT(2) | BIT(0));
return;
@@ -452,6 +464,7 @@
/* Calculte new PMIC voltage */
new_volt = curr_volt - (error_step * cpr->vp->step_size);
pr_debug("DOWN_INT: new_volt: %d\n", new_volt);
+ pr_info("(DN Voltage recommended by CPR: %d uV)\n", new_volt);
cpr_dn_event_handler(cpr, new_volt);
}
}
@@ -513,6 +526,8 @@
cpr->config->dn_threshold << 28);
cpr->curr_osc = chip_data->ring_osc;
+ chip_data->ring_osc_data[cpr->curr_osc].quot =
+ cpr->config->max_quot;
/**
* Program the gate count and target values
@@ -522,7 +537,7 @@
cpr_modify_reg(cpr, RBCPR_GCNT_TARGET(cnt),
(GCNT_M | TARGET_M),
(chip_data->ring_osc_data[cnt].gcnt << 12 |
- chip_data->ring_osc_data[cnt].target_count));
+ chip_data->ring_osc_data[cnt].quot));
pr_debug("RBCPR_GCNT_TARGET(%d): = 0x%x\n", cnt,
readl_relaxed(cpr->base + RBCPR_GCNT_TARGET(cnt)));
cnt++;
@@ -536,14 +551,19 @@
* Set with an extra step since it helps as per
* characterization data.
*/
- chip_data->calibrated_mV += cpr->vp->step_size;
- tmp_uV = chip_data->calibrated_mV * 1000;
+ chip_data->calibrated_uV += cpr->vp->step_size;
+ tmp_uV = chip_data->calibrated_uV;
rc = regulator_set_voltage(cpr->vreg_cx, tmp_uV, tmp_uV);
if (rc)
pr_err("%s: Voltage set failed %d\n", __func__, rc);
- /* Program the Timer for default delay between CPR measurements */
- delay_count = 0xFFFF;
+ /*
+ * Program the Timer Register for delay between CPR measurements
+ * This is required to allow the device sufficient time for idle
+ * power collapse.
+ */
+ delay_count = TIMER_COUNT(cpr->config->ref_clk_khz,
+ cpr->config->delay_us);
cpr_write_reg(cpr, RBCPR_TIMER_INTERVAL, delay_count);
/* Enable the Timer */
@@ -554,53 +574,69 @@
SW_AUTO_CONT_ACK_EN);
}
-static void cpr_mode_config(struct msm_cpr *cpr, enum cpr_mode mode)
-{
- if (cpr->cpr_mode == mode)
- return;
-
- cpr->cpr_mode = mode;
- pr_debug("%s: Switching to %s mode\n", __func__,
- (mode == TURBO_MODE ? "TURBO" : "NORMAL"));
-
- /* Configure the new mode */
- cpr_config(cpr);
-}
-
static int
cpr_freq_transition(struct notifier_block *nb, unsigned long val,
void *data)
{
struct msm_cpr *cpr = container_of(nb, struct msm_cpr, freq_transition);
struct cpufreq_freqs *freqs = data;
+ uint32_t quot, new_freq;
switch (val) {
case CPUFREQ_PRECHANGE:
- return 0;
pr_debug("pre freq change notification to cpr\n");
- disable_irq(cpr->irq);
+ /* Disable Measurement to stop generation of CPR IRQs */
cpr_disable(cpr);
+ /* Disable routing of IRQ to App */
+ cpr_irq_set(cpr, INT_MASK & ~MID_INT, 0);
+ disable_irq(cpr->irq);
+ cpr_write_reg(cpr, RBIF_IRQ_CLEAR, ALL_CPR_IRQ);
+ pr_debug("RBCPR_CTL: 0x%x\n",
+ readl_relaxed(cpr->base + RBCPR_CTL));
+ pr_debug("RBIF_IRQ_STATUS: 0x%x\n",
+ cpr_read_reg(cpr, RBIF_IRQ_STATUS));
+ pr_debug("RBIF_IRQ_EN(0): 0x%x\n",
+ cpr_read_reg(cpr, RBIF_IRQ_EN(cpr->config->irq_line)));
+
cpr->prev_mode = cpr->cpr_mode;
break;
- case CPUFREQ_POSTCHANGE:
- return 0;
- pr_debug("post freq change notification to cpr\n");
- if (freqs->new >= cpr->config->nom_freq_limit)
- cpr_mode_config(cpr, TURBO_MODE);
- else
- cpr_mode_config(cpr, NORMAL_MODE);
+ case CPUFREQ_POSTCHANGE:
+ pr_debug("post freq change notification to cpr\n");
+ /**
+ * As per chip characterization data, use max nominal freq
+ * to calculate quot for all lower frequencies too
+ */
+ new_freq = (freqs->new > cpr->config->max_nom_freq)
+ ? freqs->new
+ : cpr->config->max_nom_freq;
+
+ /* Configure CPR for the new frequency */
+ quot = cpr->config->get_quot(cpr->config->max_quot,
+ cpr->config->max_freq / 1000,
+ new_freq / 1000);
+ cpr_modify_reg(cpr, RBCPR_GCNT_TARGET(cpr->curr_osc), TARGET_M,
+ quot);
+ pr_debug("RBCPR_GCNT_TARGET(%d): = 0x%x\n", cpr->curr_osc,
+ readl_relaxed(cpr->base +
+ RBCPR_GCNT_TARGET(cpr->curr_osc)));
+ pr_debug("%s: new_freq: %d, set_freq: %d, quot: %d\n", __func__,
+ freqs->new, new_freq, quot);
+
+ enable_irq(cpr->irq);
/**
* Enable all interrupts. One of them could be in a disabled
* state if vdd had hit Vmax / Vmin earlier
*/
- cpr_irq_set(cpr, (UP_INT | DOWN_INT), 1);
-
- enable_irq(cpr->irq);
-
+ cpr_irq_set(cpr, INT_MASK & ~MID_INT, 1);
+ pr_debug("RBIF_IRQ_EN(0): 0x%x\n",
+ cpr_read_reg(cpr, RBIF_IRQ_EN(cpr->config->irq_line)));
+ pr_debug("RBCPR_CTL: 0x%x\n",
+ readl_relaxed(cpr->base + RBCPR_CTL));
+ pr_debug("RBIF_IRQ_STATUS: 0x%x\n",
+ cpr_read_reg(cpr, RBIF_IRQ_STATUS));
cpr_enable(cpr);
-
break;
default:
break;
@@ -614,6 +650,8 @@
struct msm_cpr *cpr = dev_get_drvdata(dev);
int osc_num = cpr->config->cpr_mode_data->ring_osc;
+ cpr->config->clk_enable();
+
cpr_write_reg(cpr, RBCPR_TIMER_INTERVAL,
cpr_save_state.rbif_timer_interval);
cpr_write_reg(cpr, RBIF_IRQ_EN(cpr->config->irq_line),
@@ -628,11 +666,11 @@
cpr_save_state.rbcpr_step_quot);
cpr_write_reg(cpr, RBIF_SW_VLEVEL,
cpr_save_state.rbif_sw_level);
-
- cpr_enable(cpr);
cpr_write_reg(cpr, RBCPR_CTL,
cpr_save_state.rbcpr_ctl);
+
enable_irq(cpr->irq);
+ cpr_enable(cpr);
return 0;
}
@@ -643,6 +681,10 @@
struct msm_cpr *cpr = dev_get_drvdata(dev);
int osc_num = cpr->config->cpr_mode_data->ring_osc;
+ /* Disable CPR measurement before IRQ to avoid pending interrupts */
+ cpr_disable(cpr);
+ disable_irq(cpr->irq);
+
cpr_save_state.rbif_timer_interval =
cpr_read_reg(cpr, RBCPR_TIMER_INTERVAL);
cpr_save_state.rbif_int_en =
@@ -660,9 +702,6 @@
cpr_save_state.rbcpr_ctl =
cpr_read_reg(cpr, RBCPR_CTL);
- disable_irq(cpr->irq);
- cpr_disable(cpr);
-
return 0;
}
@@ -700,6 +739,7 @@
const struct msm_cpr_config *pdata = pdev->dev.platform_data;
void __iomem *base;
struct resource *mem;
+ struct msm_cpr_mode *chip_data;
if (!pdata) {
pr_err("CPR: Platform data is not available\n");
@@ -766,6 +806,16 @@
platform_set_drvdata(pdev, cpr);
+ chip_data = &cpr->config->cpr_mode_data[cpr->cpr_mode];
+ pr_info("CPR Platform Data (upside_steps: %d) (downside_steps: %d) ",
+ cpr->config->up_threshold, cpr->config->dn_threshold);
+ pr_info("(nominal_voltage: %duV) (turbo_voltage: %duV)\n",
+ cpr->config->cpr_mode_data[NORMAL_MODE].calibrated_uV,
+ cpr->config->cpr_mode_data[TURBO_MODE].calibrated_uV);
+ pr_info("(Current corner: TURBO) (gcnt_target: %d) (quot: %d)\n",
+ chip_data->ring_osc_data[chip_data->ring_osc].gcnt,
+ chip_data->ring_osc_data[chip_data->ring_osc].quot);
+
/* Initialze the Debugfs Entry for cpr */
res = msm_cpr_debug_init(cpr->base);
if (res) {
@@ -793,7 +843,6 @@
/* Enable the cpr */
cpr_modify_reg(cpr, RBCPR_CTL, LOOP_EN_M, ENABLE_CPR);
-
cpr->freq_transition.notifier_call = cpr_freq_transition;
cpufreq_register_notifier(&cpr->freq_transition,
CPUFREQ_TRANSITION_NOTIFIER);
diff --git a/arch/arm/mach-msm/msm_cpr.h b/arch/arm/mach-msm/msm_cpr.h
index 2642b9c..cb665b7 100644
--- a/arch/arm/mach-msm/msm_cpr.h
+++ b/arch/arm/mach-msm/msm_cpr.h
@@ -120,10 +120,10 @@
/**
* struct msm_vp_data - structure for VP configuration
- * @min_volt_mV: minimum milivolt level for VP
- * @max_volt_mV: maximum milivolt level for VP
- * @default_volt_mV: default milivolt for VP
- * @step_size_mV: step size of voltage
+ * @min_volt: minimum microvolt level for VP
+ * @max_volt: maximum microvolt level for VP
+ * @default_volt: default microvolt for VP
+ * @step_size: step size of voltage in microvolt
*/
struct msm_cpr_vp_data {
int min_volt;
@@ -135,11 +135,11 @@
/**
* struct msm_cpr_osc - Data for CPR ring oscillator
* @gcnt: gate count value for the oscillator
- * @target_count: target value for ring oscillator
+ * @quot: target value for ring oscillator
*/
struct msm_cpr_osc {
int gcnt;
- uint32_t target_count;
+ uint32_t quot;
};
/**
@@ -156,7 +156,7 @@
uint32_t step_quot;
uint32_t Vmax;
uint32_t Vmin;
- uint32_t calibrated_mV;
+ uint32_t calibrated_uV;
};
/**
@@ -180,8 +180,13 @@
uint32_t dn_threshold;
uint32_t up_margin;
uint32_t dn_margin;
- uint32_t nom_freq_limit;
+ uint32_t max_nom_freq;
+ uint32_t max_freq;
+ uint32_t max_quot;
struct msm_cpr_vp_data *vp_data;
+ uint32_t (*get_quot)(uint32_t max_quot, uint32_t max_freq,
+ uint32_t new_freq);
+ void (*clk_enable)(void);
};
/**
diff --git a/arch/arm/mach-msm/rpm-regulator-8930.c b/arch/arm/mach-msm/rpm-regulator-8930.c
index 3878e22..9133856 100644
--- a/arch/arm/mach-msm/rpm-regulator-8930.c
+++ b/arch/arm/mach-msm/rpm-regulator-8930.c
@@ -111,51 +111,64 @@
};
#define LDO(_id, _name, _name_pc, _ranges, _hpm_min_load, _requires_cxo) \
- [RPM_VREG_ID_PM8038_##_id] = { \
+ [RPM_VREG_ID_PM##_id] = { \
.req = { \
- [0] = { .id = MSM_RPM_ID_PM8038_##_id##_0, }, \
- [1] = { .id = MSM_RPM_ID_PM8038_##_id##_1, }, \
+ [0] = { .id = MSM_RPM_ID_PM##_id##_0, }, \
+ [1] = { .id = MSM_RPM_ID_PM##_id##_1, }, \
}, \
.hpm_min_load = RPM_VREG_8930_##_hpm_min_load##_HPM_MIN_LOAD, \
.type = RPM_REGULATOR_TYPE_LDO, \
.set_points = &_ranges##_set_points, \
.part = &ldo_parts, \
- .id = RPM_VREG_ID_PM8038_##_id, \
+ .id = RPM_VREG_ID_PM##_id, \
.rdesc.name = _name, \
.rdesc_pc.name = _name_pc, \
.requires_cxo = _requires_cxo, \
}
#define SMPS(_id, _name, _name_pc, _ranges, _hpm_min_load) \
- [RPM_VREG_ID_PM8038_##_id] = { \
+ [RPM_VREG_ID_PM##_id] = { \
.req = { \
- [0] = { .id = MSM_RPM_ID_PM8038_##_id##_0, }, \
- [1] = { .id = MSM_RPM_ID_PM8038_##_id##_1, }, \
+ [0] = { .id = MSM_RPM_ID_PM##_id##_0, }, \
+ [1] = { .id = MSM_RPM_ID_PM##_id##_1, }, \
}, \
.hpm_min_load = RPM_VREG_8930_##_hpm_min_load##_HPM_MIN_LOAD, \
.type = RPM_REGULATOR_TYPE_SMPS, \
.set_points = &_ranges##_set_points, \
.part = &smps_parts, \
- .id = RPM_VREG_ID_PM8038_##_id, \
+ .id = RPM_VREG_ID_PM##_id, \
.rdesc.name = _name, \
.rdesc_pc.name = _name_pc, \
}
#define LVS(_id, _name, _name_pc) \
- [RPM_VREG_ID_PM8038_##_id] = { \
+ [RPM_VREG_ID_PM##_id] = { \
.req = { \
- [0] = { .id = MSM_RPM_ID_PM8038_##_id, }, \
+ [0] = { .id = MSM_RPM_ID_PM##_id, }, \
[1] = { .id = -1, }, \
}, \
.type = RPM_REGULATOR_TYPE_VS, \
.part = &switch_parts, \
- .id = RPM_VREG_ID_PM8038_##_id, \
+ .id = RPM_VREG_ID_PM##_id, \
+ .rdesc.name = _name, \
+ .rdesc_pc.name = _name_pc, \
+ }
+
+#define MVS(_vreg_id, _name, _name_pc, _rpm_id) \
+ [RPM_VREG_ID_PM##_vreg_id] = { \
+ .req = { \
+ [0] = { .id = MSM_RPM_ID_##_rpm_id, }, \
+ [1] = { .id = -1, }, \
+ }, \
+ .type = RPM_REGULATOR_TYPE_VS, \
+ .part = &switch_parts, \
+ .id = RPM_VREG_ID_PM##_vreg_id, \
.rdesc.name = _name, \
.rdesc_pc.name = _name_pc, \
}
#define CORNER(_id, _rpm_id, _name, _ranges) \
- [RPM_VREG_ID_PM8038_##_id] = { \
+ [RPM_VREG_ID_PM##_id] = { \
.req = { \
[0] = { .id = MSM_RPM_ID_##_rpm_id, }, \
[1] = { .id = -1, }, \
@@ -163,50 +176,105 @@
.type = RPM_REGULATOR_TYPE_CORNER, \
.set_points = &_ranges##_set_points, \
.part = &corner_parts, \
- .id = RPM_VREG_ID_PM8038_##_id, \
+ .id = RPM_VREG_ID_PM##_id, \
.rdesc.name = _name, \
}
-static struct vreg vregs[] = {
- LDO(L1, "8038_l1", NULL, nldo1200, LDO_1200, 1),
- LDO(L2, "8038_l2", "8038_l2_pc", nldo, LDO_150, 1),
- LDO(L3, "8038_l3", "8038_l3_pc", pldo, LDO_50, 0),
- LDO(L4, "8038_l4", "8038_l4_pc", pldo, LDO_50, 0),
- LDO(L5, "8038_l5", "8038_l5_pc", pldo, LDO_600, 0),
- LDO(L6, "8038_l6", "8038_l6_pc", pldo, LDO_600, 0),
- LDO(L7, "8038_l7", "8038_l7_pc", pldo, LDO_600, 0),
- LDO(L8, "8038_l8", "8038_l8_pc", pldo, LDO_300, 0),
- LDO(L9, "8038_l9", "8038_l9_pc", pldo, LDO_300, 0),
- LDO(L10, "8038_l10", "8038_l10_pc", pldo, LDO_600, 0),
- LDO(L11, "8038_l11", "8038_l11_pc", pldo, LDO_600, 0),
- LDO(L12, "8038_l12", "8038_l12_pc", nldo, LDO_300, 1),
- LDO(L13, "8038_l13", NULL, ln_ldo, LDO_5, 0),
- LDO(L14, "8038_l14", "8038_l14_pc", pldo, LDO_50, 0),
- LDO(L15, "8038_l15", "8038_l15_pc", pldo, LDO_150, 0),
- LDO(L16, "8038_l16", NULL, nldo1200, LDO_1200, 1),
- LDO(L17, "8038_l17", "8038_l17_pc", pldo, LDO_150, 0),
- LDO(L18, "8038_l18", "8038_l18_pc", pldo, LDO_50, 0),
- LDO(L19, "8038_l19", NULL, nldo1200, LDO_1200, 1),
- LDO(L20, "8038_l20", NULL, nldo1200, LDO_1200, 1),
- LDO(L21, "8038_l21", "8038_l21_pc", pldo, LDO_150, 0),
- LDO(L22, "8038_l22", "8038_l22_pc", pldo, LDO_50, 0),
- LDO(L23, "8038_l23", "8038_l23_pc", pldo, LDO_50, 0),
- LDO(L24, "8038_l24", NULL, nldo1200, LDO_1200, 1),
- LDO(L25, "8038_l25", NULL, ln_ldo, LDO_5, 0),
- LDO(L26, "8038_l26", "8038_l26_pc", nldo, LDO_150, 1),
- LDO(L27, "8038_l27", NULL, nldo1200, LDO_1200, 1),
+static struct vreg vregs_msm8930_pm8038[] = {
+ LDO(8038_L1, "8038_l1", NULL, nldo1200, LDO_1200, 1),
+ LDO(8038_L2, "8038_l2", "8038_l2_pc", nldo, LDO_150, 1),
+ LDO(8038_L3, "8038_l3", "8038_l3_pc", pldo, LDO_50, 0),
+ LDO(8038_L4, "8038_l4", "8038_l4_pc", pldo, LDO_50, 0),
+ LDO(8038_L5, "8038_l5", "8038_l5_pc", pldo, LDO_600, 0),
+ LDO(8038_L6, "8038_l6", "8038_l6_pc", pldo, LDO_600, 0),
+ LDO(8038_L7, "8038_l7", "8038_l7_pc", pldo, LDO_600, 0),
+ LDO(8038_L8, "8038_l8", "8038_l8_pc", pldo, LDO_300, 0),
+ LDO(8038_L9, "8038_l9", "8038_l9_pc", pldo, LDO_300, 0),
+ LDO(8038_L10, "8038_l10", "8038_l10_pc", pldo, LDO_600, 0),
+ LDO(8038_L11, "8038_l11", "8038_l11_pc", pldo, LDO_600, 0),
+ LDO(8038_L12, "8038_l12", "8038_l12_pc", nldo, LDO_300, 1),
+ LDO(8038_L13, "8038_l13", NULL, ln_ldo, LDO_5, 0),
+ LDO(8038_L14, "8038_l14", "8038_l14_pc", pldo, LDO_50, 0),
+ LDO(8038_L15, "8038_l15", "8038_l15_pc", pldo, LDO_150, 0),
+ LDO(8038_L16, "8038_l16", NULL, nldo1200, LDO_1200, 1),
+ LDO(8038_L17, "8038_l17", "8038_l17_pc", pldo, LDO_150, 0),
+ LDO(8038_L18, "8038_l18", "8038_l18_pc", pldo, LDO_50, 0),
+ LDO(8038_L19, "8038_l19", NULL, nldo1200, LDO_1200, 1),
+ LDO(8038_L20, "8038_l20", NULL, nldo1200, LDO_1200, 1),
+ LDO(8038_L21, "8038_l21", "8038_l21_pc", pldo, LDO_150, 0),
+ LDO(8038_L22, "8038_l22", "8038_l22_pc", pldo, LDO_50, 0),
+ LDO(8038_L23, "8038_l23", "8038_l23_pc", pldo, LDO_50, 0),
+ LDO(8038_L24, "8038_l24", NULL, nldo1200, LDO_1200, 1),
+ LDO(8038_L25, "8038_l25", NULL, ln_ldo, LDO_5, 0),
+ LDO(8038_L26, "8038_l26", "8038_l26_pc", nldo, LDO_150, 1),
+ LDO(8038_L27, "8038_l27", NULL, nldo1200, LDO_1200, 1),
- SMPS(S1, "8038_s1", "8038_s1_pc", smps, SMPS_1500),
- SMPS(S2, "8038_s2", "8038_s2_pc", smps, SMPS_1500),
- SMPS(S3, "8038_s3", "8038_s3_pc", smps, SMPS_1500),
- SMPS(S4, "8038_s4", "8038_s4_pc", smps, SMPS_1500),
- SMPS(S5, "8038_s5", NULL, ftsmps, SMPS_2000),
- SMPS(S6, "8038_s6", NULL, ftsmps, SMPS_2000),
+ SMPS(8038_S1, "8038_s1", "8038_s1_pc", smps, SMPS_1500),
+ SMPS(8038_S2, "8038_s2", "8038_s2_pc", smps, SMPS_1500),
+ SMPS(8038_S3, "8038_s3", "8038_s3_pc", smps, SMPS_1500),
+ SMPS(8038_S4, "8038_s4", "8038_s4_pc", smps, SMPS_1500),
+ SMPS(8038_S5, "8038_s5", NULL, ftsmps, SMPS_2000),
+ SMPS(8038_S6, "8038_s6", NULL, ftsmps, SMPS_2000),
- LVS(LVS1, "8038_lvs1", "8038_lvs1_pc"),
- LVS(LVS2, "8038_lvs2", "8038_lvs2_pc"),
+ LVS(8038_LVS1, "8038_lvs1", "8038_lvs1_pc"),
+ LVS(8038_LVS2, "8038_lvs2", "8038_lvs2_pc"),
- CORNER(VDD_DIG_CORNER, VOLTAGE_CORNER, "vdd_dig_corner", corner),
+ CORNER(8038_VDD_DIG_CORNER, VOLTAGE_CORNER, "vdd_dig_corner", corner),
+};
+
+static struct vreg vregs_msm8930_pm8917[] = {
+ LDO(8917_L1, "8917_l1", "8917_l1_pc", nldo, LDO_150, 1),
+ LDO(8917_L2, "8917_l2", "8917_l2_pc", nldo, LDO_150, 1),
+ LDO(8917_L3, "8917_l3", "8917_l3_pc", pldo, LDO_150, 0),
+ LDO(8917_L4, "8917_l4", "8917_l4_pc", pldo, LDO_50, 0),
+ LDO(8917_L5, "8917_l5", "8917_l5_pc", pldo, LDO_300, 0),
+ LDO(8917_L6, "8917_l6", "8917_l6_pc", pldo, LDO_600, 0),
+ LDO(8917_L7, "8917_l7", "8917_l7_pc", pldo, LDO_150, 0),
+ LDO(8917_L8, "8917_l8", "8917_l8_pc", pldo, LDO_300, 0),
+ LDO(8917_L9, "8917_l9", "8917_l9_pc", pldo, LDO_300, 0),
+ LDO(8917_L10, "8917_l10", "8917_l10_pc", pldo, LDO_600, 0),
+ LDO(8917_L11, "8917_l11", "8917_l11_pc", pldo, LDO_150, 0),
+ LDO(8917_L12, "8917_l12", "8917_l12_pc", nldo, LDO_150, 1),
+ LDO(8917_L14, "8917_l14", "8917_l14_pc", pldo, LDO_50, 0),
+ LDO(8917_L15, "8917_l15", "8917_l15_pc", pldo, LDO_150, 0),
+ LDO(8917_L16, "8917_l16", "8917_l16_pc", pldo, LDO_300, 0),
+ LDO(8917_L17, "8917_l17", "8917_l17_pc", pldo, LDO_150, 0),
+ LDO(8917_L18, "8917_l18", "8917_l18_pc", nldo, LDO_150, 1),
+ LDO(8917_L21, "8917_l21", "8917_l21_pc", pldo, LDO_150, 0),
+ LDO(8917_L22, "8917_l22", "8917_l22_pc", pldo, LDO_150, 0),
+ LDO(8917_L23, "8917_l23", "8917_l23_pc", pldo, LDO_150, 0),
+ LDO(8917_L24, "8917_l24", NULL, nldo1200, LDO_1200, 0),
+ LDO(8917_L25, "8917_l25", NULL, nldo1200, LDO_1200, 0),
+ LDO(8917_L26, "8917_l26", NULL, nldo1200, LDO_1200, 0),
+ LDO(8917_L27, "8917_l27", NULL, nldo1200, LDO_1200, 0),
+ LDO(8917_L28, "8917_l28", NULL, nldo1200, LDO_1200, 0),
+ LDO(8917_L29, "8917_l29", "8917_l29_pc", pldo, LDO_150, 0),
+ LDO(8917_L30, "8917_l30", "8917_l30_pc", pldo, LDO_150, 0),
+ LDO(8917_L31, "8917_l31", "8917_l31_pc", pldo, LDO_150, 0),
+ LDO(8917_L32, "8917_l32", "8917_l32_pc", pldo, LDO_150, 0),
+ LDO(8917_L33, "8917_l33", "8917_l33_pc", pldo, LDO_150, 0),
+ LDO(8917_L34, "8917_l34", "8917_l34_pc", pldo, LDO_150, 0),
+ LDO(8917_L35, "8917_l35", "8917_l35_pc", pldo, LDO_300, 0),
+ LDO(8917_L36, "8917_l36", "8917_l36_pc", pldo, LDO_50, 0),
+
+ SMPS(8917_S1, "8917_s1", "8917_s1_pc", smps, SMPS_1500),
+ SMPS(8917_S2, "8917_s2", "8917_s2_pc", smps, SMPS_1500),
+ SMPS(8917_S3, "8917_s3", "8917_s3_pc", smps, SMPS_1500),
+ SMPS(8917_S4, "8917_s4", "8917_s4_pc", smps, SMPS_1500),
+ SMPS(8917_S5, "8917_s5", NULL, ftsmps, SMPS_2000),
+ SMPS(8917_S6, "8917_s6", NULL, ftsmps, SMPS_2000),
+ SMPS(8917_S7, "8917_s7", "8917_s7_pc", smps, SMPS_1500),
+ SMPS(8917_S8, "8917_s8", "8917_s8_pc", smps, SMPS_1500),
+
+ LVS(8917_LVS1, "8917_lvs1", "8917_lvs1_pc"),
+ LVS(8917_LVS3, "8917_lvs3", "8917_lvs3_pc"),
+ LVS(8917_LVS4, "8917_lvs4", "8917_lvs4_pc"),
+ LVS(8917_LVS5, "8917_lvs5", "8917_lvs5_pc"),
+ LVS(8917_LVS6, "8917_lvs6", "8917_lvs6_pc"),
+ LVS(8917_LVS7, "8917_lvs7", "8917_lvs7_pc"),
+ MVS(8917_USB_OTG, "8917_usb_otg", NULL, USB_OTG_SWITCH),
+
+ CORNER(8917_VDD_DIG_CORNER, VOLTAGE_CORNER, "vdd_dig_corner", corner),
};
static const char *pin_func_label[] = {
@@ -237,17 +305,18 @@
" A2",
};
-static int is_real_id(int id)
+static int is_real_id_msm8930_pm8038(int id)
{
return (id >= 0) && (id <= RPM_VREG_ID_PM8038_MAX_REAL);
}
-static int pc_id_to_real_id(int id)
+static int pc_id_to_real_id_msm8930_pm8038(int id)
{
int real_id = 0;
if (id >= RPM_VREG_ID_PM8038_L2_PC && id <= RPM_VREG_ID_PM8038_L12_PC)
- real_id = id - RPM_VREG_ID_PM8038_L2_PC;
+ real_id = id - RPM_VREG_ID_PM8038_L2_PC
+ + RPM_VREG_ID_PM8038_L2;
else if (id >= RPM_VREG_ID_PM8038_L14_PC
&& id <= RPM_VREG_ID_PM8038_L15_PC)
real_id = id - RPM_VREG_ID_PM8038_L14_PC
@@ -274,9 +343,33 @@
return real_id;
}
-static struct vreg_config config = {
- .vregs = vregs,
- .vregs_len = ARRAY_SIZE(vregs),
+static int is_real_id_msm8930_pm8917(int id)
+{
+ return (id >= 0) && (id <= RPM_VREG_ID_PM8917_MAX_REAL);
+}
+
+static int pc_id_to_real_id_msm8930_pm8917(int id)
+{
+ int real_id = 0;
+
+ if (id >= RPM_VREG_ID_PM8917_L1_PC && id <= RPM_VREG_ID_PM8917_L23_PC)
+ real_id = id - RPM_VREG_ID_PM8917_L1_PC
+ + RPM_VREG_ID_PM8917_L1;
+ else if (id >= RPM_VREG_ID_PM8917_L29_PC
+ && id <= RPM_VREG_ID_PM8917_S4_PC)
+ real_id = id - RPM_VREG_ID_PM8917_L29_PC
+ + RPM_VREG_ID_PM8917_L29;
+ else if (id >= RPM_VREG_ID_PM8917_S7_PC
+ && id <= RPM_VREG_ID_PM8917_LVS7_PC)
+ real_id = id - RPM_VREG_ID_PM8917_S7_PC
+ + RPM_VREG_ID_PM8917_S7;
+
+ return real_id;
+}
+
+static struct vreg_config config_msm8930_pm8038 = {
+ .vregs = vregs_msm8930_pm8038,
+ .vregs_len = ARRAY_SIZE(vregs_msm8930_pm8038),
.vreg_id_min = RPM_VREG_ID_PM8038_L1,
.vreg_id_max = RPM_VREG_ID_PM8038_MAX,
@@ -299,11 +392,45 @@
.label_power_mode = power_mode_label,
.label_power_mode_len = ARRAY_SIZE(power_mode_label),
- .is_real_id = is_real_id,
- .pc_id_to_real_id = pc_id_to_real_id,
+ .is_real_id = is_real_id_msm8930_pm8038,
+ .pc_id_to_real_id = pc_id_to_real_id_msm8930_pm8038,
+};
+
+static struct vreg_config config_msm8930_pm8917 = {
+ .vregs = vregs_msm8930_pm8917,
+ .vregs_len = ARRAY_SIZE(vregs_msm8930_pm8917),
+
+ .vreg_id_min = RPM_VREG_ID_PM8917_L1,
+ .vreg_id_max = RPM_VREG_ID_PM8917_MAX,
+
+ .pin_func_none = RPM_VREG_PIN_FN_8930_NONE,
+ .pin_func_sleep_b = RPM_VREG_PIN_FN_8930_SLEEP_B,
+
+ .mode_lpm = REGULATOR_MODE_IDLE,
+ .mode_hpm = REGULATOR_MODE_NORMAL,
+
+ .set_points = all_set_points,
+ .set_points_len = ARRAY_SIZE(all_set_points),
+
+ .label_pin_ctrl = pin_control_label,
+ .label_pin_ctrl_len = ARRAY_SIZE(pin_control_label),
+ .label_pin_func = pin_func_label,
+ .label_pin_func_len = ARRAY_SIZE(pin_func_label),
+ .label_force_mode = force_mode_label,
+ .label_force_mode_len = ARRAY_SIZE(force_mode_label),
+ .label_power_mode = power_mode_label,
+ .label_power_mode_len = ARRAY_SIZE(power_mode_label),
+
+ .is_real_id = is_real_id_msm8930_pm8917,
+ .pc_id_to_real_id = pc_id_to_real_id_msm8930_pm8917,
};
struct vreg_config *get_config_8930(void)
{
- return &config;
+ return &config_msm8930_pm8038;
+}
+
+struct vreg_config *get_config_8930_pm8917(void)
+{
+ return &config_msm8930_pm8917;
}
diff --git a/arch/arm/mach-msm/rpm-regulator-private.h b/arch/arm/mach-msm/rpm-regulator-private.h
index c3ddc33..d55bd73 100644
--- a/arch/arm/mach-msm/rpm-regulator-private.h
+++ b/arch/arm/mach-msm/rpm-regulator-private.h
@@ -176,11 +176,16 @@
#if defined(CONFIG_MSM_RPM_REGULATOR) && defined(CONFIG_ARCH_MSM8930)
struct vreg_config *get_config_8930(void);
+struct vreg_config *get_config_8930_pm8917(void);
#else
static inline struct vreg_config *get_config_8930(void)
{
return NULL;
}
+static inline struct vreg_config *get_config_8930_pm8917(void)
+{
+ return NULL;
+}
#endif
#endif
diff --git a/arch/arm/mach-msm/rpm-regulator.c b/arch/arm/mach-msm/rpm-regulator.c
index 68ff55b..424a4fe 100644
--- a/arch/arm/mach-msm/rpm-regulator.c
+++ b/arch/arm/mach-msm/rpm-regulator.c
@@ -62,6 +62,7 @@
[RPM_VREG_VERSION_8960] = get_config_8960,
[RPM_VREG_VERSION_9615] = get_config_9615,
[RPM_VREG_VERSION_8930] = get_config_8930,
+ [RPM_VREG_VERSION_8930_PM8917] = get_config_8930_pm8917,
};
static struct rpm_regulator_consumer_mapping *consumer_map;
diff --git a/arch/arm/mach-msm/rpm-smd.c b/arch/arm/mach-msm/rpm-smd.c
index 5b8284d..cd5556a 100644
--- a/arch/arm/mach-msm/rpm-smd.c
+++ b/arch/arm/mach-msm/rpm-smd.c
@@ -62,7 +62,7 @@
#define DEFAULT_BUFFER_SIZE 256
#define GFP_FLAG(noirq) (noirq ? GFP_ATOMIC : GFP_KERNEL)
-#define INV_HDR "resource does not exist"
+#define INV_RSC "resource does not exist"
#define ERR "err\0"
#define MAX_ERR_BUFFER_SIZE 128
#define INIT_ERROR 1
@@ -172,8 +172,10 @@
int i;
int data_size, msg_size;
- if (!handle)
+ if (!handle) {
+ pr_err("%s(): Invalid handle\n", __func__);
return -EINVAL;
+ }
data_size = ALIGN(size, SZ_4);
msg_size = data_size + sizeof(struct rpm_request_header);
@@ -191,8 +193,11 @@
break;
}
- if (i >= handle->num_elements)
+ if (i >= handle->num_elements) {
+ pr_err("%s(): Number of resources exceeds max allocated\n",
+ __func__);
return -ENOMEM;
+ }
if (i == handle->write_idx)
handle->write_idx++;
@@ -200,8 +205,10 @@
if (!handle->kvp[i].value) {
handle->kvp[i].value = kzalloc(data_size, GFP_FLAG(noirq));
- if (!handle->kvp[i].value)
+ if (!handle->kvp[i].value) {
+ pr_err("%s(): Failed malloc\n", __func__);
return -ENOMEM;
+ }
} else {
/* We enter the else case, if a key already exists but the
* data doesn't match. In which case, we should zero the data
@@ -366,13 +373,20 @@
return elem;
}
-static int msm_rpm_get_next_msg_id(void)
+static uint32_t msm_rpm_get_next_msg_id(void)
{
- int id;
+ uint32_t id;
+
+ /*
+ * A message id of 0 is used by the driver to indicate a error
+ * condition. The RPM driver uses a id of 1 to indicate unsent data
+ * when the data sent over hasn't been modified. This isn't a error
+ * scenario and wait for ack returns a success when the message id is 1.
+ */
do {
id = atomic_inc_return(&msm_rpm_msg_id);
- } while ((id == 0) || msm_rpm_get_entry_from_msg_id(id));
+ } while ((id == 0) || (id == 1) || msm_rpm_get_entry_from_msg_id(id));
return id;
}
@@ -459,8 +473,12 @@
tmp += 2 * sizeof(uint32_t);
- if (!(memcmp(tmp, INV_HDR, min(req_len, sizeof(INV_HDR))-1)))
+ if (!(memcmp(tmp, INV_RSC, min(req_len, sizeof(INV_RSC))-1))) {
+ pr_err("%s(): RPM NACK Unsupported resource\n", __func__);
rc = -EINVAL;
+ } else {
+ pr_err("%s(): RPM NACK Invalid header\n", __func__);
+ }
return rc;
}
@@ -658,7 +676,8 @@
int req_hdr_sz, msg_hdr_sz;
if (!cdata->msg_hdr.data_len)
- return 0;
+ return 1;
+
req_hdr_sz = sizeof(cdata->req_hdr);
msg_hdr_sz = sizeof(cdata->msg_hdr);
@@ -676,8 +695,10 @@
cdata->buf = kzalloc(msg_size, GFP_FLAG(noirq));
}
- if (!cdata->buf)
+ if (!cdata->buf) {
+ pr_err("%s(): Failed malloc\n", __func__);
return 0;
+ }
tmpbuff = cdata->buf;
@@ -722,7 +743,7 @@
ret = smd_write_avail(msm_rpm_data.ch_info);
if (ret < 0) {
- pr_warn("%s(): SMD not initialized\n", __func__);
+ pr_err("%s(): SMD not initialized\n", __func__);
spin_unlock_irqrestore(&msm_rpm_data.smd_lock_write, flags);
return 0;
}
@@ -749,7 +770,7 @@
} else if (ret < msg_size) {
struct msm_rpm_wait_data *rc;
ret = 0;
- pr_info("Failed to write data msg_size:%d ret:%d\n",
+ pr_err("Failed to write data msg_size:%d ret:%d\n",
msg_size, ret);
rc = msm_rpm_get_entry_from_msg_id(cdata->msg_hdr.msg_id);
if (rc)
@@ -774,8 +795,13 @@
{
struct msm_rpm_wait_data *elem;
- if (!msg_id)
- return -EINVAL;
+ if (!msg_id) {
+ pr_err("%s(): Invalid msg id\n", __func__);
+ return -ENOMEM;
+ }
+
+ if (msg_id == 1)
+ return 0;
if (standalone)
return 0;
@@ -798,8 +824,13 @@
uint32_t id = 0;
int count = 0;
- if (!msg_id)
- return -EINVAL;
+ if (!msg_id) {
+ pr_err("%s(): Invalid msg id\n", __func__);
+ return -ENOMEM;
+ }
+
+ if (msg_id == 1)
+ return 0;
if (standalone)
return 0;
diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c
index e82e44b..eeac2b9 100644
--- a/arch/arm/mach-msm/smd.c
+++ b/arch/arm/mach-msm/smd.c
@@ -361,9 +361,15 @@
static DEFINE_MUTEX(smsm_lock);
static struct smsm_state_info *smsm_states;
static int spinlocks_initialized;
-static RAW_NOTIFIER_HEAD(smsm_driver_state_notifier_list);
-static DEFINE_MUTEX(smsm_driver_state_notifier_lock);
-static void smsm_driver_state_notify(uint32_t state, void *data);
+
+/**
+ * Variables to indicate smd module initialization.
+ * Dependents to register for smd module init notifier.
+ */
+static int smd_module_inited;
+static RAW_NOTIFIER_HEAD(smd_module_init_notifier_list);
+static DEFINE_MUTEX(smd_module_init_notifier_lock);
+static void smd_module_init_notify(uint32_t state, void *data);
static inline void smd_write_intr(unsigned int val,
const void __iomem *addr)
@@ -2465,13 +2471,6 @@
int i;
struct smsm_size_info_type *smsm_size_info;
- i = remote_spin_lock_init(&remote_spinlock, SMEM_SPINLOCK_SMEM_ALLOC);
- if (i) {
- pr_err("%s: remote spinlock init failed %d\n", __func__, i);
- return i;
- }
- spinlocks_initialized = 1;
-
smsm_size_info = smem_alloc(SMEM_SMSM_SIZE_INFO,
sizeof(struct smsm_size_info_type));
if (smsm_size_info) {
@@ -2530,7 +2529,6 @@
return i;
wmb();
- smsm_driver_state_notify(SMSM_INIT, NULL);
return 0;
}
@@ -3104,37 +3102,40 @@
}
EXPORT_SYMBOL(smsm_state_cb_deregister);
-int smsm_driver_state_notifier_register(struct notifier_block *nb)
+int smd_module_init_notifier_register(struct notifier_block *nb)
{
int ret;
if (!nb)
return -EINVAL;
- mutex_lock(&smsm_driver_state_notifier_lock);
- ret = raw_notifier_chain_register(&smsm_driver_state_notifier_list, nb);
- mutex_unlock(&smsm_driver_state_notifier_lock);
+ mutex_lock(&smd_module_init_notifier_lock);
+ ret = raw_notifier_chain_register(&smd_module_init_notifier_list, nb);
+ if (smd_module_inited)
+ nb->notifier_call(nb, 0, NULL);
+ mutex_unlock(&smd_module_init_notifier_lock);
return ret;
}
-EXPORT_SYMBOL(smsm_driver_state_notifier_register);
+EXPORT_SYMBOL(smd_module_init_notifier_register);
-int smsm_driver_state_notifier_unregister(struct notifier_block *nb)
+int smd_module_init_notifier_unregister(struct notifier_block *nb)
{
int ret;
if (!nb)
return -EINVAL;
- mutex_lock(&smsm_driver_state_notifier_lock);
- ret = raw_notifier_chain_unregister(&smsm_driver_state_notifier_list,
+ mutex_lock(&smd_module_init_notifier_lock);
+ ret = raw_notifier_chain_unregister(&smd_module_init_notifier_list,
nb);
- mutex_unlock(&smsm_driver_state_notifier_lock);
+ mutex_unlock(&smd_module_init_notifier_lock);
return ret;
}
-EXPORT_SYMBOL(smsm_driver_state_notifier_unregister);
+EXPORT_SYMBOL(smd_module_init_notifier_unregister);
-static void smsm_driver_state_notify(uint32_t state, void *data)
+static void smd_module_init_notify(uint32_t state, void *data)
{
- mutex_lock(&smsm_driver_state_notifier_lock);
- raw_notifier_call_chain(&smsm_driver_state_notifier_list,
+ mutex_lock(&smd_module_init_notifier_lock);
+ smd_module_inited = 1;
+ raw_notifier_call_chain(&smd_module_init_notifier_list,
state, data);
- mutex_unlock(&smsm_driver_state_notifier_lock);
+ mutex_unlock(&smd_module_init_notifier_lock);
}
int smd_core_init(void)
@@ -3547,12 +3548,29 @@
int __init msm_smd_init(void)
{
static bool registered;
+ int rc;
if (registered)
return 0;
registered = true;
- return platform_driver_register(&msm_smd_driver);
+ rc = remote_spin_lock_init(&remote_spinlock, SMEM_SPINLOCK_SMEM_ALLOC);
+ if (rc) {
+ pr_err("%s: remote spinlock init failed %d\n", __func__, rc);
+ return rc;
+ }
+ spinlocks_initialized = 1;
+
+ rc = platform_driver_register(&msm_smd_driver);
+ if (rc) {
+ pr_err("%s: msm_smd_driver register failed %d\n",
+ __func__, rc);
+ return rc;
+ }
+
+ smd_module_init_notify(0, NULL);
+
+ return 0;
}
module_init(msm_smd_init);
diff --git a/arch/arm/mach-msm/smem_log.c b/arch/arm/mach-msm/smem_log.c
index 2e9a97c..fd8144a 100644
--- a/arch/arm/mach-msm/smem_log.c
+++ b/arch/arm/mach-msm/smem_log.c
@@ -2008,25 +2008,23 @@
return ret;
}
-static int smsm_driver_state_notifier(struct notifier_block *this,
- unsigned long code,
- void *_cmd)
+static int smd_module_init_notifier(struct notifier_block *this,
+ unsigned long code,
+ void *_cmd)
{
int ret = 0;
- if (code & SMSM_INIT) {
- if (!smem_log_initialized)
- ret = smem_log_initialize();
- }
+ if (!smem_log_initialized)
+ ret = smem_log_initialize();
return ret;
}
static struct notifier_block nb = {
- .notifier_call = smsm_driver_state_notifier,
+ .notifier_call = smd_module_init_notifier,
};
static int __init smem_log_init(void)
{
- return smsm_driver_state_notifier_register(&nb);
+ return smd_module_init_notifier_register(&nb);
}
diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h
index 69783f4..4495eb0 100644
--- a/drivers/char/diag/diagchar.h
+++ b/drivers/char/diag/diagchar.h
@@ -35,6 +35,8 @@
#define POOL_TYPE_COPY 1
#define POOL_TYPE_HDLC 2
#define POOL_TYPE_WRITE_STRUCT 4
+#define POOL_TYPE_HSIC 8
+#define POOL_TYPE_HSIC_WRITE 16
#define POOL_TYPE_ALL 7
#define MODEM_DATA 1
#define QDSP_DATA 2
@@ -273,20 +275,19 @@
int in_busy_smux;
int diag_smux_enabled;
int smux_connected;
+ struct diag_request *write_ptr_mdm;
/* HSIC variables */
- unsigned char *buf_in_hsic;
int hsic_ch;
int hsic_device_enabled;
int hsic_device_opened;
int hsic_suspend;
int in_busy_hsic_read_on_device;
- int in_busy_hsic_write_on_device;
int in_busy_hsic_write;
- int in_busy_hsic_read;
struct work_struct diag_read_hsic_work;
/* USB MDM channel variables */
int usb_mdm_connected;
int read_len_mdm;
+ int write_len_mdm;
unsigned char *usb_buf_mdm_out;
struct usb_diag_ch *mdm_ch;
struct workqueue_struct *diag_bridge_wq;
@@ -294,7 +295,16 @@
struct work_struct diag_disconnect_work;
struct work_struct diag_usb_read_complete_work;
struct diag_request *usb_read_mdm_ptr;
- struct diag_request *write_ptr_mdm;
+ int count_hsic_pool;
+ int count_hsic_write_pool;
+ unsigned int poolsize_hsic;
+ unsigned int poolsize_hsic_write;
+ unsigned int itemsize_hsic;
+ unsigned int itemsize_hsic_write;
+ mempool_t *diag_hsic_pool;
+ mempool_t *diag_hsic_write_pool;
+ int num_hsic_buf_tbl_entries;
+ struct diag_write_device *hsic_buf_tbl;
#endif
};
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index 30504bc..2dc1929 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -243,6 +243,17 @@
driver->logging_mode = USB_MODE;
diagfwd_connect();
#ifdef CONFIG_DIAG_BRIDGE_CODE
+ driver->num_hsic_buf_tbl_entries = 0;
+ for (i = 0; i < driver->poolsize_hsic_write; i++) {
+ if (driver->hsic_buf_tbl[i].buf) {
+ /* Return the buffer to the pool */
+ diagmem_free(driver, (unsigned char *)
+ (driver->hsic_buf_tbl[i].buf),
+ POOL_TYPE_HSIC);
+ driver->hsic_buf_tbl[i].buf = 0;
+ driver->hsic_buf_tbl[i].length = 0;
+ }
+ }
diagfwd_cancel_hsic();
diagfwd_connect_bridge(0);
#endif
@@ -528,6 +539,17 @@
driver->in_busy_sdio = 1;
#endif
#ifdef CONFIG_DIAG_BRIDGE_CODE
+ driver->num_hsic_buf_tbl_entries = 0;
+ for (i = 0; i < driver->poolsize_hsic_write; i++) {
+ if (driver->hsic_buf_tbl[i].buf) {
+ /* Return the buffer to the pool */
+ diagmem_free(driver, (unsigned char *)
+ (driver->hsic_buf_tbl[i].buf),
+ POOL_TYPE_HSIC);
+ driver->hsic_buf_tbl[i].buf = 0;
+ driver->hsic_buf_tbl[i].length = 0;
+ }
+ }
diagfwd_disconnect_bridge(0);
#endif
} else if (temp == NO_LOGGING_MODE && driver->logging_mode
@@ -556,6 +578,11 @@
&(driver->diag_read_sdio_work));
#endif
#ifdef CONFIG_DIAG_BRIDGE_CODE
+ driver->num_hsic_buf_tbl_entries = 0;
+ for (i = 0; i < driver->poolsize_hsic_write; i++) {
+ driver->hsic_buf_tbl[i].buf = 0;
+ driver->hsic_buf_tbl[i].length = 0;
+ }
diagfwd_connect_bridge(0);
#endif
}
@@ -581,6 +608,7 @@
driver->in_busy_qdsp_2 = 0;
driver->in_busy_wcnss_1 = 0;
driver->in_busy_wcnss_2 = 0;
+
/* Poll SMD channels to check for data*/
if (driver->ch)
queue_work(driver->diag_wq,
@@ -599,6 +627,11 @@
&(driver->diag_read_sdio_work));
#endif
#ifdef CONFIG_DIAG_BRIDGE_CODE
+ driver->num_hsic_buf_tbl_entries = 0;
+ for (i = 0; i < driver->poolsize_hsic_write; i++) {
+ driver->hsic_buf_tbl[i].buf = 0;
+ driver->hsic_buf_tbl[i].length = 0;
+ }
diagfwd_cancel_hsic();
diagfwd_connect_bridge(0);
#endif
@@ -606,6 +639,17 @@
driver->logging_mode == USB_MODE) {
diagfwd_connect();
#ifdef CONFIG_DIAG_BRIDGE_CODE
+ driver->num_hsic_buf_tbl_entries = 0;
+ for (i = 0; i < driver->poolsize_hsic_write; i++) {
+ if (driver->hsic_buf_tbl[i].buf) {
+ /* Return the buffer to the pool */
+ diagmem_free(driver, (unsigned char *)
+ (driver->hsic_buf_tbl[i].buf),
+ POOL_TYPE_HSIC);
+ driver->hsic_buf_tbl[i].buf = 0;
+ driver->hsic_buf_tbl[i].length = 0;
+ }
+ }
diagfwd_cancel_hsic();
diagfwd_connect_bridge(0);
#endif
@@ -767,20 +811,44 @@
}
#endif
#ifdef CONFIG_DIAG_BRIDGE_CODE
- pr_debug("diag: Copy data to user space %d\n",
- driver->in_busy_hsic_write_on_device);
- if (driver->in_busy_hsic_write_on_device == 1) {
- num_data++;
- /*Copy the length of data being passed*/
- COPY_USER_SPACE_OR_EXIT(buf+ret,
- (driver->write_ptr_mdm->length), 4);
- /*Copy the actual data being passed*/
- COPY_USER_SPACE_OR_EXIT(buf+ret,
- *(driver->buf_in_hsic),
- driver->write_ptr_mdm->length);
- pr_debug("diag: data copied\n");
- /* call the write complete function */
- diagfwd_write_complete_hsic();
+
+ for (i = 0; i < driver->poolsize_hsic_write; i++) {
+ if (driver->hsic_buf_tbl[i].length > 0) {
+ pr_debug("diag: HSIC copy to user, i: %d, buf: %x, len: %d\n",
+ i, (unsigned int)
+ (driver->hsic_buf_tbl[i].buf),
+ driver->hsic_buf_tbl[i].length);
+ num_data++;
+ /* Copy the length of data being passed */
+ if (copy_to_user(buf+ret, (void *)&(driver->
+ hsic_buf_tbl[i].length), 4)) {
+ num_data--;
+ goto drop_hsic;
+ }
+ ret += 4;
+
+ /* Copy the actual data being passed */
+ if (copy_to_user(buf+ret,
+ (void *)driver->hsic_buf_tbl[i].buf,
+ driver->hsic_buf_tbl[i].length)) {
+ ret -= 4;
+ num_data--;
+ goto drop_hsic;
+ }
+ ret += driver->hsic_buf_tbl[i].length;
+drop_hsic:
+ /* Return the buffer to the pool */
+ diagmem_free(driver, (unsigned char *)
+ (driver->hsic_buf_tbl[i].buf),
+ POOL_TYPE_HSIC);
+
+ driver->hsic_buf_tbl[i].length = 0;
+ driver->hsic_buf_tbl[i].buf = 0;
+ driver->num_hsic_buf_tbl_entries--;
+
+ /* Call the write complete function */
+ diagfwd_write_complete_hsic(NULL);
+ }
}
#endif
/* copy number of data fields */
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index 5a74e8c..4419309 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -307,6 +307,26 @@
break;
}
}
+
+#ifdef CONFIG_DIAG_BRIDGE_CODE
+ else if (proc_num == HSIC_DATA) {
+ for (i = 0; i < driver->poolsize_hsic_write; i++) {
+ if (driver->hsic_buf_tbl[i].length == 0) {
+ driver->hsic_buf_tbl[i].buf = buf;
+ driver->hsic_buf_tbl[i].length =
+ driver->write_len_mdm;
+ driver->num_hsic_buf_tbl_entries++;
+#ifdef DIAG_DEBUG
+ pr_debug("diag: ENQUEUE HSIC buf ptr and length is %x , %d\n",
+ (unsigned int)
+ (driver->hsic_buf_tbl[i].buf),
+ driver->hsic_buf_tbl[i].length);
+#endif
+ break;
+ }
+ }
+ }
+#endif
for (i = 0; i < driver->num_clients; i++)
if (driver->client_map[i].pid ==
driver->logging_process_id)
@@ -343,8 +363,6 @@
#endif
#ifdef CONFIG_DIAG_BRIDGE_CODE
else if (proc_num == HSIC_DATA) {
- driver->in_busy_hsic_read = 0;
- driver->in_busy_hsic_write_on_device = 0;
if (driver->hsic_ch)
queue_work(driver->diag_bridge_wq,
&(driver->diag_read_hsic_work));
@@ -396,11 +414,33 @@
#ifdef CONFIG_DIAG_BRIDGE_CODE
else if (proc_num == HSIC_DATA) {
if (driver->hsic_device_enabled) {
- write_ptr->buf = buf;
- err = usb_diag_write(driver->mdm_ch, write_ptr);
- } else
+ struct diag_request *write_ptr_mdm;
+ write_ptr_mdm = (struct diag_request *)
+ diagmem_alloc(driver,
+ sizeof(struct diag_request),
+ POOL_TYPE_HSIC_WRITE);
+ if (write_ptr_mdm) {
+ write_ptr_mdm->buf = buf;
+ write_ptr_mdm->length =
+ driver->write_len_mdm;
+ err = usb_diag_write(driver->mdm_ch,
+ write_ptr_mdm);
+ /* Return to the pool immediately */
+ if (err) {
+ diagmem_free(driver,
+ write_ptr_mdm,
+ POOL_TYPE_HSIC_WRITE);
+ pr_err("diag: HSIC write failure\n");
+ }
+ } else {
+ pr_err("diag: allocate write fail\n");
+ err = -1;
+ }
+ } else {
pr_err("diag: Incorrect hsic data "
"while USB write\n");
+ err = -1;
+ }
} else if (proc_num == SMUX_DATA) {
write_ptr->buf = buf;
pr_debug("diag: writing SMUX data\n");
diff --git a/drivers/char/diag/diagfwd_cntl.c b/drivers/char/diag/diagfwd_cntl.c
index 95abd21..52fd673 100644
--- a/drivers/char/diag/diagfwd_cntl.c
+++ b/drivers/char/diag/diagfwd_cntl.c
@@ -401,7 +401,8 @@
"in_busy_qdsp_2: %d\n"
"in_busy_wcnss_1: %d\n"
"in_busy_wcnss_2: %d\n"
- "in_busy_dci: %d\n",
+ "in_busy_dci: %d\n"
+ "logging_mode: %d\n",
(unsigned int)driver->ch,
(unsigned int)driver->chqdsp,
(unsigned int)driver->ch_wcnss,
@@ -421,7 +422,8 @@
driver->in_busy_qdsp_2,
driver->in_busy_wcnss_1,
driver->in_busy_wcnss_2,
- driver->in_busy_dci);
+ driver->in_busy_dci,
+ driver->logging_mode);
#ifdef CONFIG_DIAG_OVER_USB
ret += scnprintf(buf+ret, DEBUG_BUF_SIZE,
@@ -541,7 +543,7 @@
return ret;
}
-#ifdef CONFIG_DIAG_HSIC_PIPE
+#ifdef CONFIG_DIAG_BRIDGE_CODE
static ssize_t diag_dbgfs_read_hsic(struct file *file, char __user *ubuf,
size_t count, loff_t *ppos)
{
@@ -555,29 +557,35 @@
}
ret = scnprintf(buf, DEBUG_BUF_SIZE,
- "hsic initialized: %d\n"
"hsic ch: %d\n"
"hsic enabled: %d\n"
"hsic_opened: %d\n"
- "hisc_suspend: %d\n"
- "in_busy_hsic_read_on_mdm: %d\n"
- "in_busy_hsic_write_on_mdm: %d\n"
+ "hsic_suspend: %d\n"
+ "in_busy_hsic_read_on_device: %d\n"
"in_busy_hsic_write: %d\n"
- "in_busy_hsic_read: %d\n"
+ "count_hsic_pool: %d\n"
+ "count_hsic_write_pool: %d\n"
+ "diag_hsic_pool: %x\n"
+ "diag_hsic_write_pool: %x\n"
+ "write_len_mdm: %d\n"
+ "num_hsic_buf_tbl_entries: %d\n"
"usb_mdm_connected: %d\n"
"diag_read_mdm_work: %d\n"
"diag_read_hsic_work: %d\n"
"diag_disconnect_work: %d\n"
"diag_usb_read_complete_work: %d\n",
- driver->hsic_initialized,
driver->hsic_ch,
driver->hsic_device_enabled,
driver->hsic_device_opened,
driver->hsic_suspend,
driver->in_busy_hsic_read_on_device,
- driver->in_busy_hsic_write_on_device,
driver->in_busy_hsic_write,
- driver->in_busy_hsic_read,
+ driver->count_hsic_pool,
+ driver->count_hsic_write_pool,
+ (unsigned int)driver->diag_hsic_pool,
+ (unsigned int)driver->diag_hsic_write_pool,
+ driver->write_len_mdm,
+ driver->num_hsic_buf_tbl_entries,
driver->usb_mdm_connected,
work_pending(&(driver->diag_read_mdm_work)),
work_pending(&(driver->diag_read_hsic_work)),
@@ -622,7 +630,7 @@
debugfs_create_file("work_pending", 0444, diag_dbgfs_dent, 0,
&diag_dbgfs_workpending_ops);
-#ifdef CONFIG_DIAG_HSIC_PIPE
+#ifdef CONFIG_DIAG_BRIDGE_CODE
debugfs_create_file("hsic", 0444, diag_dbgfs_dent, 0,
&diag_dbgfs_hsic_ops);
#endif
diff --git a/drivers/char/diag/diagfwd_hsic.c b/drivers/char/diag/diagfwd_hsic.c
index 81c6afa..54a667e 100644
--- a/drivers/char/diag/diagfwd_hsic.c
+++ b/drivers/char/diag/diagfwd_hsic.c
@@ -32,48 +32,87 @@
#include "diagfwd_hsic.h"
#include "diagfwd_smux.h"
+#define N_MDM_WRITE 8
+#define N_MDM_READ 1
+
+#define READ_HSIC_BUF_SIZE 2048
+
+#define NUM_HSIC_BUF_TBL_ENTRIES N_MDM_WRITE
+
static void diag_read_hsic_work_fn(struct work_struct *work)
{
+ unsigned char *buf_in_hsic = NULL;
+ int num_reads_submitted = 0;
+ int err = 0;
+ int write_ptrs_available;
+
if (!driver->hsic_ch) {
pr_err("DIAG in %s: driver->hsic_ch == 0\n", __func__);
return;
}
- /* If there is no hsic data being read from the hsic and there
- * is no hsic data being written to the device
+ /*
+ * Determine the current number of available buffers for writing after
+ * reading from the HSIC has completed.
*/
- if (!driver->in_busy_hsic_read &&
- !driver->in_busy_hsic_write_on_device) {
- /*
- * Initiate the read from the hsic. The hsic read is
- * asynchronous. Once the read is complete the read
- * callback function will be called.
- */
- int err;
- driver->in_busy_hsic_read = 1;
- APPEND_DEBUG('i');
- pr_debug("diag: read from HSIC\n");
- err = diag_bridge_read((char *)driver->buf_in_hsic,
- IN_BUF_SIZE);
- if (err) {
- pr_err_ratelimited("DIAG: Error initiating HSIC read, err: %d\n",
- err);
- /*
- * If the error is recoverable, then clear
- * the read flag, so we will resubmit a
- * read on the next frame. Otherwise, don't
- * resubmit a read on the next frame.
- */
- if ((-ENODEV) != err)
- driver->in_busy_hsic_read = 0;
- }
- }
+ if (driver->logging_mode == MEMORY_DEVICE_MODE)
+ write_ptrs_available = driver->poolsize_hsic_write -
+ driver->num_hsic_buf_tbl_entries;
+ else
+ write_ptrs_available = driver->poolsize_hsic_write -
+ driver->count_hsic_write_pool;
/*
- * If for some reason there was no hsic data, set up
- * the next read
+ * Queue up a read on the HSIC for all available buffers in the
+ * pool, exhausting the pool.
*/
- if (!driver->in_busy_hsic_read)
+ do {
+ /*
+ * If no more write buffers are available,
+ * stop queuing reads
+ */
+ if (write_ptrs_available <= 0)
+ break;
+
+ write_ptrs_available--;
+
+ buf_in_hsic = diagmem_alloc(driver, READ_HSIC_BUF_SIZE,
+ POOL_TYPE_HSIC);
+ if (buf_in_hsic) {
+ /*
+ * Initiate the read from the hsic. The hsic read is
+ * asynchronous. Once the read is complete the read
+ * callback function will be called.
+ */
+ int err;
+ pr_debug("diag: read from HSIC\n");
+ num_reads_submitted++;
+ err = diag_bridge_read((char *)buf_in_hsic,
+ READ_HSIC_BUF_SIZE);
+ if (err) {
+ num_reads_submitted--;
+
+ /* Return the buffer to the pool */
+ diagmem_free(driver, buf_in_hsic,
+ POOL_TYPE_HSIC);
+
+ pr_err_ratelimited("diag: Error initiating HSIC read, err: %d\n",
+ err);
+ /*
+ * An error occurred, discontinue queuing
+ * reads
+ */
+ break;
+ }
+ }
+ } while (buf_in_hsic);
+
+ /*
+ * If there are no buffers available or for some reason there
+ * was no hsic data, and if no unrecoverable error occurred
+ * (-ENODEV is an unrecoverable error), then set up the next read
+ */
+ if ((num_reads_submitted == 0) && (err != -ENODEV))
queue_work(driver->diag_bridge_wq,
&driver->diag_read_hsic_work);
}
@@ -81,45 +120,58 @@
static void diag_hsic_read_complete_callback(void *ctxt, char *buf,
int buf_size, int actual_size)
{
- /* The read of the data from the HSIC bridge is complete */
- driver->in_busy_hsic_read = 0;
+ int err = -2;
if (!driver->hsic_ch) {
- pr_err("DIAG in %s: driver->hsic_ch == 0\n", __func__);
+ /*
+ * The hsic channel is closed. Return the buffer to
+ * the pool. Do not send it on.
+ */
+ diagmem_free(driver, buf, POOL_TYPE_HSIC);
+ pr_debug("diag: In %s: driver->hsic_ch == 0, actual_size: %d\n",
+ __func__, actual_size);
return;
}
- APPEND_DEBUG('j');
- if (actual_size > 0) {
+ /* Note that zero length is valid and still needs to be sent */
+ if (actual_size >= 0) {
if (!buf) {
- pr_err("Out of diagmem for HSIC\n");
+ pr_err("diag: Out of diagmem for HSIC\n");
} else {
- driver->write_ptr_mdm->length = actual_size;
/*
- * Set flag to denote hsic data is currently
- * being written to the usb mdm channel.
- * driver->buf_in_hsic was given to
- * diag_bridge_read(), so buf here should be
- * driver->buf_in_hsic
+ * Send data in buf to be written on the
+ * appropriate device, e.g. USB MDM channel
*/
- driver->in_busy_hsic_write_on_device = 1;
- pr_debug("diag: write to device\n");
- diag_device_write((void *)buf, HSIC_DATA,
- driver->write_ptr_mdm);
+ driver->write_len_mdm = actual_size;
+ err = diag_device_write((void *)buf, HSIC_DATA, NULL);
+ /* If an error, return buffer to the pool */
+ if (err) {
+ diagmem_free(driver, buf, POOL_TYPE_HSIC);
+ pr_err("diag: In %s, error calling diag_device_write, err: %d\n",
+ __func__, err);
+ }
}
} else {
- pr_debug("%s: actual_size: %d\n", __func__, actual_size);
+ /*
+ * The buffer has an error status associated with it. Do not
+ * pass it on. Note that -ENOENT is sent when the diag bridge
+ * is closed.
+ */
+ diagmem_free(driver, buf, POOL_TYPE_HSIC);
+ pr_debug("diag: In %s: error status: %d\n", __func__,
+ actual_size);
}
/*
* If for some reason there was no hsic data to write to the
* mdm channel, set up another read
*/
- if (!driver->in_busy_hsic_write_on_device && ((driver->logging_mode
- == MEMORY_DEVICE_MODE) || (driver->usb_mdm_connected &&
- !driver->hsic_suspend)))
+ if (err &&
+ ((driver->logging_mode == MEMORY_DEVICE_MODE) ||
+ (driver->usb_mdm_connected && !driver->hsic_suspend))) {
queue_work(driver->diag_bridge_wq,
&driver->diag_read_hsic_work);
+ }
}
static void diag_hsic_write_complete_callback(void *ctxt, char *buf,
@@ -143,6 +195,8 @@
static int diag_hsic_suspend(void *ctxt)
{
pr_debug("diag: hsic_suspend\n");
+
+ /* Don't allow suspend if a write in the HSIC is in progress */
if (driver->in_busy_hsic_write)
return -EBUSY;
@@ -160,8 +214,8 @@
pr_debug("diag: hsic_resume\n");
driver->hsic_suspend = 0;
- if (!driver->in_busy_hsic_write_on_device && (driver->logging_mode
- == MEMORY_DEVICE_MODE || driver->usb_mdm_connected))
+ if ((driver->logging_mode == MEMORY_DEVICE_MODE) ||
+ (driver->usb_mdm_connected))
queue_work(driver->diag_bridge_wq,
&driver->diag_read_hsic_work);
}
@@ -202,10 +256,10 @@
diag_bridge_close();
err = diag_bridge_open(&hsic_diag_bridge_ops);
if (err) {
- pr_err("DIAG: HSIC channel open error: %d\n",
+ pr_err("diag: HSIC channel open error: %d\n",
err);
} else {
- pr_debug("DIAG: opened HSIC channel\n");
+ pr_debug("diag: opened HSIC channel\n");
driver->hsic_device_opened = 1;
driver->hsic_ch = 1;
}
@@ -234,10 +288,8 @@
}
if (driver->hsic_device_enabled) {
- driver->in_busy_hsic_write_on_device = 0;
driver->in_busy_hsic_read_on_device = 0;
driver->in_busy_hsic_write = 0;
- driver->in_busy_hsic_read = 0;
} else if (driver->diag_smux_enabled) {
driver->in_busy_smux = 0;
diagfwd_connect_smux();
@@ -288,7 +340,7 @@
*/
int diagfwd_disconnect_bridge(int process_cable)
{
- pr_debug("DIAG in %s\n", __func__);
+ pr_debug("diag: In %s, process_cable: %d\n", __func__, process_cable);
/* If the usb cable is being disconnected */
if (process_cable) {
@@ -298,10 +350,8 @@
if (driver->logging_mode == USB_MODE) {
if (driver->hsic_device_enabled) {
- driver->in_busy_hsic_write_on_device = 1;
driver->in_busy_hsic_read_on_device = 1;
driver->in_busy_hsic_write = 1;
- driver->in_busy_hsic_read = 1;
/* Turn off communication over usb mdm and hsic */
return diag_hsic_close();
} else if (driver->diag_smux_enabled) {
@@ -319,19 +369,21 @@
* diagfwd_write_complete_hsic is called after the asynchronous
* usb_diag_write() on mdm channel is complete
*/
-int diagfwd_write_complete_hsic(void)
+int diagfwd_write_complete_hsic(struct diag_request *diag_write_ptr)
{
- /*
- * Clear flag to denote that the write of the hsic data on the
- * usb mdm channel is complete
- */
- driver->in_busy_hsic_write_on_device = 0;
- if (!driver->hsic_ch) {
- pr_err("DIAG in %s: driver->hsic_ch == 0\n", __func__);
- return 0;
+ unsigned char *buf = (diag_write_ptr) ? diag_write_ptr->buf : NULL;
+
+ if (buf) {
+ /* Return buffers to their pools */
+ diagmem_free(driver, (unsigned char *)buf, POOL_TYPE_HSIC);
+ diagmem_free(driver, (unsigned char *)diag_write_ptr,
+ POOL_TYPE_HSIC_WRITE);
}
- APPEND_DEBUG('q');
+ if (!driver->hsic_ch) {
+ pr_err("diag: In %s: driver->hsic_ch == 0\n", __func__);
+ return 0;
+ }
/* Read data from the hsic */
queue_work(driver->diag_bridge_wq, &driver->diag_read_hsic_work);
@@ -375,7 +427,7 @@
err = diag_bridge_write(driver->usb_buf_mdm_out,
driver->read_len_mdm);
if (err) {
- pr_err_ratelimited("DIAG: mdm data on hsic write err: %d\n",
+ pr_err_ratelimited("diag: mdm data on hsic write err: %d\n",
err);
/*
* If the error is recoverable, then clear
@@ -415,7 +467,7 @@
break;
case USB_DIAG_WRITE_DONE:
if (driver->hsic_device_enabled)
- diagfwd_write_complete_hsic();
+ diagfwd_write_complete_hsic(d_req);
else if (driver->diag_smux_enabled)
diagfwd_write_complete_smux();
break;
@@ -492,8 +544,7 @@
int err = 0;
pr_debug("diag: in %s\n", __func__);
if (!driver->hsic_device_enabled) {
- if (driver->buf_in_hsic == NULL)
- driver->buf_in_hsic = kzalloc(IN_BUF_SIZE, GFP_KERNEL);
+ diagmem_hsic_init(driver);
INIT_WORK(&(driver->diag_read_hsic_work),
diag_read_hsic_work_fn);
driver->hsic_device_enabled = 1;
@@ -517,10 +568,9 @@
pr_info("diag: opened HSIC channel\n");
driver->hsic_device_opened = 1;
driver->hsic_ch = 1;
- driver->in_busy_hsic_write_on_device = 0;
+
driver->in_busy_hsic_read_on_device = 0;
driver->in_busy_hsic_write = 0;
- driver->in_busy_hsic_read = 0;
if (driver->usb_mdm_connected) {
/* Poll USB mdm channel to check for data */
@@ -538,7 +588,7 @@
static int diag_hsic_remove(struct platform_device *pdev)
{
- pr_debug("DIAG: %s called\n", __func__);
+ pr_debug("diag: %s called\n", __func__);
diag_hsic_close();
return 0;
}
@@ -578,11 +628,14 @@
driver->diag_bridge_wq = create_singlethread_workqueue(
"diag_bridge_wq");
driver->read_len_mdm = 0;
+ driver->write_len_mdm = 0;
+ driver->num_hsic_buf_tbl_entries = 0;
if (driver->usb_buf_mdm_out == NULL)
driver->usb_buf_mdm_out = kzalloc(USB_MAX_OUT_BUF,
GFP_KERNEL);
if (driver->usb_buf_mdm_out == NULL)
goto err;
+ /* Only used by smux move to smux probe function */
if (driver->write_ptr_mdm == NULL)
driver->write_ptr_mdm = kzalloc(
sizeof(struct diag_request), GFP_KERNEL);
@@ -594,6 +647,20 @@
if (driver->usb_read_mdm_ptr == NULL)
goto err;
+ if (driver->hsic_buf_tbl == NULL)
+ driver->hsic_buf_tbl = kzalloc(NUM_HSIC_BUF_TBL_ENTRIES *
+ sizeof(struct diag_write_device), GFP_KERNEL);
+ if (driver->hsic_buf_tbl == NULL)
+ goto err;
+
+ driver->count_hsic_pool = 0;
+ driver->count_hsic_write_pool = 0;
+
+ driver->itemsize_hsic = READ_HSIC_BUF_SIZE;
+ driver->poolsize_hsic = N_MDM_WRITE;
+ driver->itemsize_hsic_write = sizeof(struct diag_request);
+ driver->poolsize_hsic_write = N_MDM_WRITE;
+
#ifdef CONFIG_DIAG_OVER_USB
INIT_WORK(&(driver->diag_read_mdm_work), diag_read_mdm_work_fn);
#endif
@@ -608,10 +675,6 @@
goto err;
}
#endif
-#ifdef CONFIG_DIAG_BRIDGE_CODE
- INIT_WORK(&(driver->diag_disconnect_work), diag_disconnect_work_fn);
- INIT_WORK(&(driver->diag_usb_read_complete_work),
- diag_usb_read_complete_fn);
/* register HSIC device */
ret = platform_driver_register(&msm_hsic_ch_driver);
if (ret)
@@ -620,11 +683,12 @@
ret = platform_driver_register(&msm_diagfwd_smux_driver);
if (ret)
pr_err("diag: could not register SMUX device, ret: %d\n", ret);
-#endif
+
return;
err:
pr_err("diag: Could not initialize for bridge forwarding\n");
kfree(driver->usb_buf_mdm_out);
+ kfree(driver->hsic_buf_tbl);
kfree(driver->write_ptr_mdm);
kfree(driver->usb_read_mdm_ptr);
if (driver->diag_bridge_wq)
@@ -639,8 +703,8 @@
if (driver->hsic_device_enabled) {
diag_hsic_close();
- kfree(driver->buf_in_hsic);
driver->hsic_device_enabled = 0;
+ diagmem_exit(driver, POOL_TYPE_ALL);
}
if (driver->diag_smux_enabled) {
driver->lcid = LCID_INVALID;
@@ -656,6 +720,7 @@
usb_diag_close(driver->mdm_ch);
#endif
kfree(driver->usb_buf_mdm_out);
+ kfree(driver->hsic_buf_tbl);
kfree(driver->write_ptr_mdm);
kfree(driver->usb_read_mdm_ptr);
destroy_workqueue(driver->diag_bridge_wq);
diff --git a/drivers/char/diag/diagfwd_hsic.h b/drivers/char/diag/diagfwd_hsic.h
index b189c94..b2d9c9f 100644
--- a/drivers/char/diag/diagfwd_hsic.h
+++ b/drivers/char/diag/diagfwd_hsic.h
@@ -14,12 +14,10 @@
#define DIAGFWD_HSIC_H
#include <mach/diag_bridge.h>
-#define N_MDM_WRITE 1 /* Upgrade to 2 with ping pong buffer */
-#define N_MDM_READ 1
int diagfwd_connect_bridge(int);
int diagfwd_disconnect_bridge(int);
-int diagfwd_write_complete_hsic(void);
+int diagfwd_write_complete_hsic(struct diag_request *);
int diagfwd_cancel_hsic(void);
void diagfwd_bridge_init(void);
void diagfwd_bridge_exit(void);
diff --git a/drivers/char/diag/diagmem.c b/drivers/char/diag/diagmem.c
index 0b5c27a..82c47af 100644
--- a/drivers/char/diag/diagmem.c
+++ b/drivers/char/diag/diagmem.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -51,6 +51,28 @@
driver->diag_write_struct_pool, GFP_ATOMIC);
}
}
+#ifdef CONFIG_DIAG_BRIDGE_CODE
+ } else if (pool_type == POOL_TYPE_HSIC) {
+ if (driver->diag_hsic_pool) {
+ if (driver->count_hsic_pool < driver->poolsize_hsic) {
+ atomic_add(1,
+ (atomic_t *)&driver->count_hsic_pool);
+ buf = mempool_alloc(driver->diag_hsic_pool,
+ GFP_ATOMIC);
+ }
+ }
+ } else if (pool_type == POOL_TYPE_HSIC_WRITE) {
+ if (driver->diag_hsic_write_pool) {
+ if (driver->count_hsic_write_pool <
+ driver->poolsize_hsic_write) {
+ atomic_add(1, (atomic_t *)
+ &driver->count_hsic_write_pool);
+ buf = mempool_alloc(
+ driver->diag_hsic_write_pool,
+ GFP_ATOMIC);
+ }
+ }
+#endif
}
return buf;
}
@@ -63,7 +85,7 @@
driver->diagpool = NULL;
} else if (driver->ref_count == 0 && pool_type == POOL_TYPE_ALL)
printk(KERN_ALERT "Unable to destroy COPY mempool");
- }
+ }
if (driver->diag_hdlc_pool) {
if (driver->count_hdlc_pool == 0 && driver->ref_count == 0) {
@@ -71,7 +93,7 @@
driver->diag_hdlc_pool = NULL;
} else if (driver->ref_count == 0 && pool_type == POOL_TYPE_ALL)
printk(KERN_ALERT "Unable to destroy HDLC mempool");
- }
+ }
if (driver->diag_write_struct_pool) {
/* Free up struct pool ONLY if there are no outstanding
@@ -82,7 +104,30 @@
driver->diag_write_struct_pool = NULL;
} else if (driver->ref_count == 0 && pool_type == POOL_TYPE_ALL)
printk(KERN_ALERT "Unable to destroy STRUCT mempool");
- }
+ }
+#ifdef CONFIG_DIAG_BRIDGE_CODE
+ if (driver->diag_hsic_pool && (driver->hsic_device_enabled == 0)) {
+ if (driver->count_hsic_pool == 0) {
+ mempool_destroy(driver->diag_hdlc_pool);
+ driver->diag_hdlc_pool = NULL;
+ } else if (pool_type == POOL_TYPE_ALL)
+ pr_err("Unable to destroy HDLC mempool");
+ }
+
+ if (driver->diag_hsic_write_pool &&
+ (driver->hsic_device_enabled == 0)) {
+ /*
+ * Free up struct pool ONLY if there are no outstanding
+ * transactions(aggregation buffer) with USB
+ */
+ if (driver->count_hsic_write_pool == 0 &&
+ driver->count_hsic_pool == 0) {
+ mempool_destroy(driver->diag_hsic_write_pool);
+ driver->diag_hsic_write_pool = NULL;
+ } else if (pool_type == POOL_TYPE_ALL)
+ pr_err("Unable to destroy HSIC USB struct mempool");
+ }
+#endif
}
void diagmem_free(struct diagchar_dev *driver, void *buf, int pool_type)
@@ -112,6 +157,29 @@
pr_err("diag: Attempt to free up DIAG driver "
"USB structure mempool which is already free %d ",
driver->count_write_struct_pool);
+#ifdef CONFIG_DIAG_BRIDGE_CODE
+ } else if (pool_type == POOL_TYPE_HSIC) {
+ if (driver->diag_hsic_pool != NULL &&
+ driver->count_hsic_pool > 0) {
+ mempool_free(buf, driver->diag_hsic_pool);
+ atomic_add(-1, (atomic_t *)&driver->count_hsic_pool);
+ } else
+ pr_err("diag: Attempt to free up DIAG driver HSIC mempool which is already free %d ",
+ driver->count_hsic_pool);
+ } else if (pool_type == POOL_TYPE_HSIC_WRITE) {
+ if (driver->diag_hsic_write_pool != NULL &&
+ driver->count_hsic_write_pool > 0) {
+ mempool_free(buf, driver->diag_hsic_write_pool);
+ atomic_add(-1,
+ (atomic_t *)&driver->count_hsic_write_pool);
+ } else
+ pr_err("diag: Attempt to free up DIAG driver HSIC USB structure mempool which is already free %d ",
+ driver->count_write_struct_pool);
+#endif
+ } else {
+ pr_err("diag: In %s, unknown pool type: %d\n",
+ __func__, pool_type);
+
}
diagmem_exit(driver, pool_type);
@@ -143,3 +211,25 @@
printk(KERN_INFO "Cannot allocate diag USB struct mempool\n");
}
+#ifdef CONFIG_DIAG_BRIDGE_CODE
+void diagmem_hsic_init(struct diagchar_dev *driver)
+{
+ if (driver->count_hsic_pool == 0)
+ driver->diag_hsic_pool = mempool_create_kmalloc_pool(
+ driver->poolsize_hsic,
+ driver->itemsize_hsic);
+
+ if (driver->count_hsic_write_pool == 0)
+ driver->diag_hsic_write_pool = mempool_create_kmalloc_pool(
+ driver->poolsize_hsic_write,
+ driver->itemsize_hsic_write);
+
+ if (!driver->diag_hsic_pool)
+ pr_err("Cannot allocate diag HSIC mempool\n");
+
+ if (!driver->diag_hsic_write_pool)
+ pr_err("Cannot allocate diag HSIC struct mempool\n");
+
+}
+#endif
+
diff --git a/drivers/char/diag/diagmem.h b/drivers/char/diag/diagmem.h
index 43829ae..8665c75 100644
--- a/drivers/char/diag/diagmem.h
+++ b/drivers/char/diag/diagmem.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -18,5 +18,7 @@
void diagmem_free(struct diagchar_dev *driver, void *buf, int pool_type);
void diagmem_init(struct diagchar_dev *driver);
void diagmem_exit(struct diagchar_dev *driver, int pool_type);
-
+#ifdef CONFIG_DIAG_BRIDGE_CODE
+void diagmem_hsic_init(struct diagchar_dev *driver);
+#endif
#endif
diff --git a/drivers/gpu/msm/a3xx_reg.h b/drivers/gpu/msm/a3xx_reg.h
index 33fcbfd..1bb33b6 100644
--- a/drivers/gpu/msm/a3xx_reg.h
+++ b/drivers/gpu/msm/a3xx_reg.h
@@ -234,6 +234,7 @@
#define A3XX_TPL1_TP_VS_TEX_OFFSET 0x2340
#define A3XX_TPL1_TP_FS_TEX_OFFSET 0x2342
#define A3XX_TPL1_TP_FS_BORDER_COLOR_BASE_ADDR 0x2343
+#define A3XX_VBIF_CLKON 0x3001
#define A3XX_VBIF_FIXED_SORT_EN 0x300C
#define A3XX_VBIF_FIXED_SORT_SEL0 0x300D
#define A3XX_VBIF_FIXED_SORT_SEL1 0x300E
diff --git a/drivers/gpu/msm/adreno_a3xx.c b/drivers/gpu/msm/adreno_a3xx.c
index 5ce34db..548ef3c 100644
--- a/drivers/gpu/msm/adreno_a3xx.c
+++ b/drivers/gpu/msm/adreno_a3xx.c
@@ -2699,13 +2699,13 @@
/* Set up 16 deep read/write request queues */
if (adreno_dev->gpurev == ADRENO_REV_A330) {
- adreno_regwrite(device, A3XX_VBIF_IN_RD_LIM_CONF0, 0x01010101);
- adreno_regwrite(device, A3XX_VBIF_IN_RD_LIM_CONF1, 0x01010101);
- adreno_regwrite(device, A3XX_VBIF_OUT_RD_LIM_CONF0, 0x01010101);
- adreno_regwrite(device, A3XX_VBIF_OUT_WR_LIM_CONF0, 0x01010101);
+ adreno_regwrite(device, A3XX_VBIF_IN_RD_LIM_CONF0, 0x18181818);
+ adreno_regwrite(device, A3XX_VBIF_IN_RD_LIM_CONF1, 0x18181818);
+ adreno_regwrite(device, A3XX_VBIF_OUT_RD_LIM_CONF0, 0x18181818);
+ adreno_regwrite(device, A3XX_VBIF_OUT_WR_LIM_CONF0, 0x18181818);
adreno_regwrite(device, A3XX_VBIF_DDR_OUT_MAX_BURST, 0x0000303);
- adreno_regwrite(device, A3XX_VBIF_IN_WR_LIM_CONF0, 0x01010101);
- adreno_regwrite(device, A3XX_VBIF_IN_WR_LIM_CONF1, 0x01010101);
+ adreno_regwrite(device, A3XX_VBIF_IN_WR_LIM_CONF0, 0x18181818);
+ adreno_regwrite(device, A3XX_VBIF_IN_WR_LIM_CONF1, 0x18181818);
/* Enable WR-REQ */
adreno_regwrite(device, A3XX_VBIF_GATE_OFF_WRREQ_EN, 0x00003F);
@@ -2721,6 +2721,11 @@
/* Enable 1K sort */
adreno_regwrite(device, A3XX_VBIF_ABIT_SORT, 0x1FFFF);
adreno_regwrite(device, A3XX_VBIF_ABIT_SORT_CONF, 0x000000A4);
+
+ /* Diable VBIF clock gating. This is to enable AXI running
+ * higher frequency than GPU.
+ */
+ adreno_regwrite(device, A3XX_VBIF_CLKON, 1);
} else {
adreno_regwrite(device, A3XX_VBIF_IN_RD_LIM_CONF0, 0x10101010);
adreno_regwrite(device, A3XX_VBIF_IN_RD_LIM_CONF1, 0x10101010);
diff --git a/drivers/gpu/msm/adreno_drawctxt.c b/drivers/gpu/msm/adreno_drawctxt.c
index bd22233..74493f4 100644
--- a/drivers/gpu/msm/adreno_drawctxt.c
+++ b/drivers/gpu/msm/adreno_drawctxt.c
@@ -226,6 +226,10 @@
adreno_idle(device);
+ if (adreno_is_a20x(adreno_dev) && adreno_dev->drawctxt_active)
+ kgsl_setstate(&device->mmu, adreno_dev->drawctxt_active->id,
+ KGSL_MMUFLAGS_PTUPDATE);
+
kgsl_sharedmem_free(&drawctxt->gpustate);
kgsl_sharedmem_free(&drawctxt->context_gmem_shadow.gmemshadow);
diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c
index c1617bff..085b632 100644
--- a/drivers/i2c/busses/i2c-qup.c
+++ b/drivers/i2c/busses/i2c-qup.c
@@ -328,12 +328,14 @@
dev->clk_state = state;
if (state != 0) {
clk_enable(dev->clk);
- clk_enable(dev->pclk);
+ if (!dev->pdata->keep_ahb_clk_on)
+ clk_enable(dev->pclk);
} else {
qup_update_state(dev, QUP_RESET_STATE);
clk_disable(dev->clk);
qup_config_core_on_en(dev);
- clk_disable(dev->pclk);
+ if (!dev->pdata->keep_ahb_clk_on)
+ clk_disable(dev->pclk);
}
}
@@ -1325,6 +1327,12 @@
dev->clk_state = 0;
clk_prepare(dev->clk);
clk_prepare(dev->pclk);
+ /* If the same AHB clock is used on Modem side
+ * switch it on here itself and don't switch it
+ * on and off during suspend and resume.
+ */
+ if (dev->pdata->keep_ahb_clk_on)
+ clk_enable(dev->pclk);
setup_timer(&dev->pwr_timer, qup_i2c_pwr_timer, (unsigned long) dev);
pm_runtime_set_active(&pdev->dev);
@@ -1396,9 +1404,11 @@
free_irq(dev->err_irq, dev);
i2c_del_adapter(&dev->adapter);
clk_unprepare(dev->clk);
- clk_unprepare(dev->pclk);
+ if (!dev->pdata->keep_ahb_clk_on) {
+ clk_unprepare(dev->pclk);
+ clk_put(dev->pclk);
+ }
clk_put(dev->clk);
- clk_put(dev->pclk);
qup_i2c_free_gpios(dev);
if (dev->gsbi)
iounmap(dev->gsbi);
@@ -1434,7 +1444,8 @@
if (dev->clk_state != 0)
qup_i2c_pwr_mgmt(dev, 0);
clk_unprepare(dev->clk);
- clk_unprepare(dev->pclk);
+ if (!dev->pdata->keep_ahb_clk_on)
+ clk_unprepare(dev->pclk);
qup_i2c_free_gpios(dev);
return 0;
}
@@ -1445,7 +1456,8 @@
struct qup_i2c_dev *dev = platform_get_drvdata(pdev);
BUG_ON(qup_i2c_request_gpios(dev) != 0);
clk_prepare(dev->clk);
- clk_prepare(dev->pclk);
+ if (!dev->pdata->keep_ahb_clk_on)
+ clk_prepare(dev->pclk);
dev->suspended = 0;
return 0;
}
diff --git a/drivers/input/misc/mpu3050.c b/drivers/input/misc/mpu3050.c
index d3da652..04a7598 100644
--- a/drivers/input/misc/mpu3050.c
+++ b/drivers/input/misc/mpu3050.c
@@ -123,6 +123,7 @@
struct delayed_work input_work;
u32 use_poll;
u32 poll_interval;
+ u32 dlpf_index;
};
struct sensor_regulator {
@@ -137,6 +138,39 @@
{NULL, "vlogic", 1800000, 1800000},
};
+struct dlpf_cfg_tb {
+ u8 cfg; /* cfg index */
+ u32 lpf_bw; /* low pass filter bandwidth in Hz */
+ u32 sample_rate; /* analog sample rate in Khz, 1 or 8 */
+};
+
+static struct dlpf_cfg_tb dlpf_table[] = {
+ {6, 5, 1},
+ {5, 10, 1},
+ {4, 20, 1},
+ {3, 42, 1},
+ {2, 98, 1},
+ {1, 188, 1},
+ {0, 256, 8},
+};
+
+static u8 interval_to_dlpf_cfg(u32 interval)
+{
+ u32 sample_rate = 1000 / interval;
+ u32 i;
+
+ /* the filter bandwidth needs to be greater or
+ * equal to half of the sample rate
+ */
+ for (i = 0; i < sizeof(dlpf_table)/sizeof(dlpf_table[0]); i++) {
+ if (dlpf_table[i].lpf_bw * 2 >= sample_rate)
+ return i;
+ }
+
+ /* return the maximum possible */
+ return --i;
+}
+
static int mpu3050_config_regulator(struct i2c_client *client, bool on)
{
int rc = 0, i;
@@ -217,6 +251,9 @@
{
struct mpu3050_sensor *sensor = dev_get_drvdata(dev);
unsigned long interval_ms;
+ unsigned int dlpf_index;
+ u8 divider, reg;
+ int ret;
if (kstrtoul(buf, 10, &interval_ms))
return -EINVAL;
@@ -224,12 +261,27 @@
(interval_ms > MPU3050_MAX_POLL_INTERVAL))
return -EINVAL;
- if (sensor)
- sensor->poll_interval = interval_ms;
+ dlpf_index = interval_to_dlpf_cfg(interval_ms);
+ divider = interval_ms * dlpf_table[dlpf_index].sample_rate - 1;
- /* Output frequency divider. The poll interval */
- i2c_smbus_write_byte_data(sensor->client, MPU3050_SMPLRT_DIV,
- interval_ms - 1);
+ if (sensor->dlpf_index != dlpf_index) {
+ /* Set low pass filter and full scale */
+ reg = dlpf_table[dlpf_index].cfg;
+ reg |= MPU3050_DEFAULT_FS_RANGE << 3;
+ reg |= MPU3050_EXT_SYNC_NONE << 5;
+ ret = i2c_smbus_write_byte_data(sensor->client,
+ MPU3050_DLPF_FS_SYNC, reg);
+ if (ret == 0)
+ sensor->dlpf_index = dlpf_index;
+ }
+
+ if (sensor->poll_interval != interval_ms) {
+ /* Output frequency divider. The poll interval */
+ ret = i2c_smbus_write_byte_data(sensor->client,
+ MPU3050_SMPLRT_DIV, divider);
+ if (ret == 0)
+ sensor->poll_interval = interval_ms;
+ }
return size;
}
@@ -482,8 +534,8 @@
return ret;
/* Set low pass filter and full scale */
- reg = MPU3050_DEFAULT_FS_RANGE;
- reg |= MPU3050_DLPF_CFG_42HZ << 3;
+ reg = MPU3050_DLPF_CFG_42HZ;
+ reg |= MPU3050_DEFAULT_FS_RANGE << 3;
reg |= MPU3050_EXT_SYNC_NONE << 5;
ret = i2c_smbus_write_byte_data(client, MPU3050_DLPF_FS_SYNC, reg);
if (ret < 0)
diff --git a/drivers/media/video/msm/io/msm_camera_io_util.c b/drivers/media/video/msm/io/msm_camera_io_util.c
index 5dfa6a2..613850b 100644
--- a/drivers/media/video/msm/io/msm_camera_io_util.c
+++ b/drivers/media/video/msm/io/msm_camera_io_util.c
@@ -458,3 +458,39 @@
}
return rc;
}
+
+void msm_camera_bus_scale_cfg(uint32_t bus_perf_client,
+ enum msm_bus_perf_setting perf_setting)
+{
+ int rc = 0;
+ if (!bus_perf_client) {
+ pr_err("%s: Bus Client NOT Registered!!!\n", __func__);
+ return;
+ }
+
+ switch (perf_setting) {
+ case S_EXIT:
+ rc = msm_bus_scale_client_update_request(bus_perf_client, 1);
+ msm_bus_scale_unregister_client(bus_perf_client);
+ break;
+ case S_PREVIEW:
+ rc = msm_bus_scale_client_update_request(bus_perf_client, 1);
+ break;
+ case S_VIDEO:
+ rc = msm_bus_scale_client_update_request(bus_perf_client, 2);
+ break;
+ case S_CAPTURE:
+ rc = msm_bus_scale_client_update_request(bus_perf_client, 3);
+ break;
+ case S_ZSL:
+ rc = msm_bus_scale_client_update_request(bus_perf_client, 4);
+ break;
+ case S_LIVESHOT:
+ rc = msm_bus_scale_client_update_request(bus_perf_client, 5);
+ break;
+ case S_DEFAULT:
+ break;
+ default:
+ pr_warning("%s: INVALID CASE\n", __func__);
+ }
+}
diff --git a/drivers/media/video/msm/vfe/Makefile b/drivers/media/video/msm/vfe/Makefile
index 91f0e7f..250b55f 100644
--- a/drivers/media/video/msm/vfe/Makefile
+++ b/drivers/media/video/msm/vfe/Makefile
@@ -16,5 +16,5 @@
obj-$(CONFIG_ARCH_MSM_ARM11) += msm_vfe7x.o
obj-$(CONFIG_ARCH_QSD8X50) += msm_vfe8x.o msm_vfe8x_proc.o
obj-$(CONFIG_ARCH_MSM8960) += msm_vfe32.o
-obj-$(CONFIG_ARCH_MSM8974) += msm_vfe40.o msm_vfe40_axi.o
+obj-$(CONFIG_ARCH_MSM8974) += msm_vfe40.o
obj-$(CONFIG_MSM_CAMERA_V4L2) += msm_vfe_stats_buf.o
diff --git a/drivers/media/video/msm/vfe/msm_vfe40.c b/drivers/media/video/msm/vfe/msm_vfe40.c
index 875e034..1297379 100644
--- a/drivers/media/video/msm/vfe/msm_vfe40.c
+++ b/drivers/media/video/msm/vfe/msm_vfe40.c
@@ -15,226 +15,597 @@
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/io.h>
+#include <linux/of.h>
#include <linux/atomic.h>
#include <linux/regulator/consumer.h>
#include <linux/clk.h>
-#include <linux/of.h>
#include <mach/irqs.h>
#include <mach/camera.h>
#include <media/v4l2-device.h>
#include <media/v4l2-subdev.h>
#include <media/msm_isp.h>
+#include <mach/msm_bus.h>
+#include <mach/msm_bus_board.h>
#include "msm.h"
+#include "msm_cam_server.h"
#include "msm_vfe40.h"
+atomic_t irq_cnt;
+
+#define VFE_WM_CFG_BASE 0x0070
+#define VFE_WM_CFG_LEN 0x0024
+
+#define vfe40_get_ch_ping_addr(base, chn) \
+ (msm_camera_io_r((base) + VFE_WM_CFG_BASE + VFE_WM_CFG_LEN * (chn)))
+#define vfe40_get_ch_pong_addr(base, chn) \
+ (msm_camera_io_r((base) + VFE_WM_CFG_BASE + VFE_WM_CFG_LEN * (chn) + 4))
+#define vfe40_get_ch_addr(ping_pong, base, chn) \
+ ((((ping_pong) & (1 << (chn))) == 0) ? \
+ (vfe40_get_ch_pong_addr((base), chn)) : \
+ (vfe40_get_ch_ping_addr((base), chn)))
+
+#define vfe40_put_ch_ping_addr(base, chn, addr) \
+ (msm_camera_io_w((addr), \
+ (base) + VFE_WM_CFG_BASE + VFE_WM_CFG_LEN * (chn)))
+#define vfe40_put_ch_pong_addr(base, chn, addr) \
+ (msm_camera_io_w((addr), \
+ (base) + VFE_WM_CFG_BASE + VFE_WM_CFG_LEN * (chn) + 4))
+#define vfe40_put_ch_addr(ping_pong, base, chn, addr) \
+ (((ping_pong) & (1 << (chn))) == 0 ? \
+ vfe40_put_ch_pong_addr((base), (chn), (addr)) : \
+ vfe40_put_ch_ping_addr((base), (chn), (addr)))
+
+static uint32_t vfe_clk_rate;
+static void vfe40_send_isp_msg(struct v4l2_subdev *sd,
+ uint32_t vfeFrameId, uint32_t isp_msg_id);
+
+
struct vfe40_isr_queue_cmd {
struct list_head list;
uint32_t vfeInterruptStatus0;
uint32_t vfeInterruptStatus1;
};
-static const char * const vfe40_general_cmd[] = {
- "DUMMY_0", /* 0 */
- "SET_CLK",
- "RESET",
- "START",
- "TEST_GEN_START",
- "OPERATION_CFG", /* 5 */
- "AXI_OUT_CFG",
- "CAMIF_CFG",
- "AXI_INPUT_CFG",
- "BLACK_LEVEL_CFG",
- "ROLL_OFF_CFG", /* 10 */
- "DEMUX_CFG",
- "FOV_CFG",
- "MAIN_SCALER_CFG",
- "WB_CFG",
- "COLOR_COR_CFG", /* 15 */
- "RGB_G_CFG",
- "LA_CFG",
- "CHROMA_EN_CFG",
- "CHROMA_SUP_CFG",
- "MCE_CFG", /* 20 */
- "SK_ENHAN_CFG",
- "ASF_CFG",
- "S2Y_CFG",
- "S2CbCr_CFG",
- "CHROMA_SUBS_CFG", /* 25 */
- "OUT_CLAMP_CFG",
- "FRAME_SKIP_CFG",
- "DUMMY_1",
- "DUMMY_2",
- "DUMMY_3", /* 30 */
- "UPDATE",
- "BL_LVL_UPDATE",
- "DEMUX_UPDATE",
- "FOV_UPDATE",
- "MAIN_SCALER_UPDATE", /* 35 */
- "WB_UPDATE",
- "COLOR_COR_UPDATE",
- "RGB_G_UPDATE",
- "LA_UPDATE",
- "CHROMA_EN_UPDATE", /* 40 */
- "CHROMA_SUP_UPDATE",
- "MCE_UPDATE",
- "SK_ENHAN_UPDATE",
- "S2CbCr_UPDATE",
- "S2Y_UPDATE", /* 45 */
- "ASF_UPDATE",
- "FRAME_SKIP_UPDATE",
- "CAMIF_FRAME_UPDATE",
- "STATS_AF_UPDATE",
- "STATS_AE_UPDATE", /* 50 */
- "STATS_AWB_UPDATE",
- "STATS_RS_UPDATE",
- "STATS_CS_UPDATE",
- "STATS_SKIN_UPDATE",
- "STATS_IHIST_UPDATE", /* 55 */
- "DUMMY_4",
- "EPOCH1_ACK",
- "EPOCH2_ACK",
- "START_RECORDING",
- "STOP_RECORDING", /* 60 */
- "DUMMY_5",
- "DUMMY_6",
- "CAPTURE",
- "DUMMY_7",
- "STOP", /* 65 */
- "GET_HW_VERSION",
- "GET_FRAME_SKIP_COUNTS",
- "OUTPUT1_BUFFER_ENQ",
- "OUTPUT2_BUFFER_ENQ",
- "OUTPUT3_BUFFER_ENQ", /* 70 */
- "JPEG_OUT_BUF_ENQ",
- "RAW_OUT_BUF_ENQ",
- "RAW_IN_BUF_ENQ",
- "STATS_AF_ENQ",
- "STATS_AE_ENQ", /* 75 */
- "STATS_AWB_ENQ",
- "STATS_RS_ENQ",
- "STATS_CS_ENQ",
- "STATS_SKIN_ENQ",
- "STATS_IHIST_ENQ", /* 80 */
- "DUMMY_8",
- "JPEG_ENC_CFG",
- "DUMMY_9",
- "STATS_AF_START",
- "STATS_AF_STOP", /* 85 */
- "STATS_AE_START",
- "STATS_AE_STOP",
- "STATS_AWB_START",
- "STATS_AWB_STOP",
- "STATS_RS_START", /* 90 */
- "STATS_RS_STOP",
- "STATS_CS_START",
- "STATS_CS_STOP",
- "STATS_SKIN_START",
- "STATS_SKIN_STOP", /* 95 */
- "STATS_IHIST_START",
- "STATS_IHIST_STOP",
- "DUMMY_10",
- "SYNC_TIMER_SETTING",
- "ASYNC_TIMER_SETTING", /* 100 */
- "LIVESHOT",
- "LA_SETUP",
- "LINEARIZATION_CFG",
- "DEMOSAICV3",
- "DEMOSAICV3_ABCC_CFG", /* 105 */
- "DEMOSAICV3_DBCC_CFG",
- "DEMOSAICV3_DBPC_CFG",
- "DEMOSAICV3_ABF_CFG",
- "DEMOSAICV3_ABCC_UPDATE",
- "DEMOSAICV3_DBCC_UPDATE", /* 110 */
- "DEMOSAICV3_DBPC_UPDATE",
- "XBAR_CFG",
- "EZTUNE_CFG",
- "V40_ZSL",
- "LINEARIZATION_UPDATE", /*115*/
- "DEMOSAICV3_ABF_UPDATE",
- "CLF_CFG",
- "CLF_LUMA_UPDATE",
- "CLF_CHROMA_UPDATE",
- "PCA_ROLL_OFF_CFG", /*120*/
- "PCA_ROLL_OFF_UPDATE",
- "GET_REG_DUMP",
- "GET_LINEARIZATON_TABLE",
- "GET_MESH_ROLLOFF_TABLE",
- "GET_PCA_ROLLOFF_TABLE", /*125*/
- "GET_RGB_G_TABLE",
- "GET_LA_TABLE",
- "DEMOSAICV3_UPDATE",
- "ACTIVE_REGION_CONFIG",
- "COLOR_PROCESSING_CONFIG", /*130*/
- "STATS_WB_AEC_CONFIG",
- "STATS_WB_AEC_UPDATE",
- "Y_GAMMA_CONFIG",
- "SCALE_OUTPUT1_CONFIG",
- "SCALE_OUTPUT2_CONFIG", /*135*/
- "CAPTURE_RAW",
- "STOP_LIVESHOT",
- "RECONFIG_VFE",
- "STATS_REQBUF_CFG",
- "STATS_ENQUEUEBUF_CFG",/*140*/
- "STATS_FLUSH_BUFQ_CFG",
- "FOV_ENC_CFG",
- "FOV_VIEW_CFG",
- "FOV_ENC_UPDATE",
- "FOV_VIEW_UPDATE",/*145*/
- "SCALER_ENC_CFG",
- "SCALER_VIEW_CFG",
- "SCALER_ENC_UPDATE",
- "SCALER_VIEW_UPDATE",
- "COLORXFORM_ENC_CFG",/*150*/
- "COLORXFORM_VIEW_CFG",
- "COLORXFORM_ENC_UPDATE",
- "COLORXFORM_VIEW_UPDATE",
+static struct vfe40_cmd_type vfe40_cmd[] = {
+ [1] = {VFE_CMD_SET_CLK},
+ [2] = {VFE_CMD_RESET},
+ [3] = {VFE_CMD_START},
+ [4] = {VFE_CMD_TEST_GEN_START},
+ [5] = {VFE_CMD_OPERATION_CFG, V40_OPERATION_CFG_LEN},
+ [6] = {VFE_CMD_AXI_OUT_CFG, V40_AXI_OUT_LEN, V40_AXI_BUS_CMD_OFF, 0xFF},
+ [7] = {VFE_CMD_CAMIF_CFG, V40_CAMIF_LEN, V40_CAMIF_OFF, 0xFF},
+ [8] = {VFE_CMD_AXI_INPUT_CFG},
+ [9] = {VFE_CMD_BLACK_LEVEL_CFG},
+ [10] = {VFE_CMD_MESH_ROLL_OFF_CFG, V40_MESH_ROLL_OFF_CFG_LEN,
+ V40_MESH_ROLL_OFF_CFG_OFF, 0xFF},
+ [11] = {VFE_CMD_DEMUX_CFG, V40_DEMUX_LEN, V40_DEMUX_OFF, 0xFF},
+ [12] = {VFE_CMD_FOV_CFG},
+ [13] = {VFE_CMD_MAIN_SCALER_CFG},
+ [14] = {VFE_CMD_WB_CFG, V40_WB_LEN, V40_WB_OFF, 0xFF},
+ [15] = {VFE_CMD_COLOR_COR_CFG, V40_COLOR_COR_LEN,
+ V40_COLOR_COR_OFF, 0xFF},
+ [16] = {VFE_CMD_RGB_G_CFG, V40_RGB_G_LEN, V40_RGB_G_OFF, 0xFF},
+ [17] = {VFE_CMD_LA_CFG, V40_LA_LEN, V40_LA_OFF, 0xFF },
+ [18] = {VFE_CMD_CHROMA_EN_CFG, V40_CHROMA_EN_LEN, V40_CHROMA_EN_OFF,
+ 0xFF},
+ [19] = {VFE_CMD_CHROMA_SUP_CFG, V40_CHROMA_SUP_LEN,
+ V40_CHROMA_SUP_OFF, 0xFF},
+ [20] = {VFE_CMD_MCE_CFG, V40_MCE_LEN, V40_MCE_OFF, 0xFF},
+ [21] = {VFE_CMD_SK_ENHAN_CFG, V40_SCE_LEN, V40_SCE_OFF, 0xFF},
+ [22] = {VFE_CMD_ASF_CFG, V40_ASF_LEN, V40_ASF_OFF, 0xFF},
+ [23] = {VFE_CMD_S2Y_CFG},
+ [24] = {VFE_CMD_S2CbCr_CFG},
+ [25] = {VFE_CMD_CHROMA_SUBS_CFG},
+ [26] = {VFE_CMD_OUT_CLAMP_CFG, V40_OUT_CLAMP_LEN, V40_OUT_CLAMP_OFF,
+ 0xFF},
+ [27] = {VFE_CMD_FRAME_SKIP_CFG},
+ [31] = {VFE_CMD_UPDATE},
+ [32] = {VFE_CMD_BL_LVL_UPDATE},
+ [33] = {VFE_CMD_DEMUX_UPDATE, V40_DEMUX_LEN, V40_DEMUX_OFF, 0xFF},
+ [34] = {VFE_CMD_FOV_UPDATE},
+ [35] = {VFE_CMD_MAIN_SCALER_UPDATE},
+ [36] = {VFE_CMD_WB_UPDATE, V40_WB_LEN, V40_WB_OFF, 0xFF},
+ [37] = {VFE_CMD_COLOR_COR_UPDATE, V40_COLOR_COR_LEN,
+ V40_COLOR_COR_OFF, 0xFF},
+ [38] = {VFE_CMD_RGB_G_UPDATE, V40_RGB_G_LEN, V40_CHROMA_EN_OFF, 0xFF},
+ [39] = {VFE_CMD_LA_UPDATE, V40_LA_LEN, V40_LA_OFF, 0xFF },
+ [40] = {VFE_CMD_CHROMA_EN_UPDATE, V40_CHROMA_EN_LEN,
+ V40_CHROMA_EN_OFF, 0xFF},
+ [41] = {VFE_CMD_CHROMA_SUP_UPDATE, V40_CHROMA_SUP_LEN,
+ V40_CHROMA_SUP_OFF, 0xFF},
+ [42] = {VFE_CMD_MCE_UPDATE, V40_MCE_LEN, V40_MCE_OFF, 0xFF},
+ [43] = {VFE_CMD_SK_ENHAN_UPDATE, V40_SCE_LEN, V40_SCE_OFF, 0xFF},
+ [44] = {VFE_CMD_S2CbCr_UPDATE},
+ [45] = {VFE_CMD_S2Y_UPDATE},
+ [46] = {VFE_CMD_ASF_UPDATE, V40_ASF_UPDATE_LEN, V40_ASF_OFF, 0xFF},
+ [47] = {VFE_CMD_FRAME_SKIP_UPDATE},
+ [48] = {VFE_CMD_CAMIF_FRAME_UPDATE},
+ [49] = {VFE_CMD_STATS_AF_UPDATE},
+ [50] = {VFE_CMD_STATS_AE_UPDATE},
+ [51] = {VFE_CMD_STATS_AWB_UPDATE, V40_STATS_AWB_LEN,
+ V40_STATS_AWB_OFF},
+ [52] = {VFE_CMD_STATS_RS_UPDATE, V40_STATS_RS_LEN, V40_STATS_RS_OFF},
+ [53] = {VFE_CMD_STATS_CS_UPDATE, V40_STATS_CS_LEN, V40_STATS_CS_OFF},
+ [54] = {VFE_CMD_STATS_SKIN_UPDATE},
+ [55] = {VFE_CMD_STATS_IHIST_UPDATE, V40_STATS_IHIST_LEN,
+ V40_STATS_IHIST_OFF},
+ [57] = {VFE_CMD_EPOCH1_ACK},
+ [58] = {VFE_CMD_EPOCH2_ACK},
+ [59] = {VFE_CMD_START_RECORDING},
+ [60] = {VFE_CMD_STOP_RECORDING},
+ [63] = {VFE_CMD_CAPTURE, V40_CAPTURE_LEN, 0xFF},
+ [65] = {VFE_CMD_STOP},
+ [66] = {VFE_CMD_GET_HW_VERSION, V40_GET_HW_VERSION_LEN,
+ V40_GET_HW_VERSION_OFF},
+ [67] = {VFE_CMD_GET_FRAME_SKIP_COUNTS},
+ [68] = {VFE_CMD_OUTPUT1_BUFFER_ENQ},
+ [69] = {VFE_CMD_OUTPUT2_BUFFER_ENQ},
+ [70] = {VFE_CMD_OUTPUT3_BUFFER_ENQ},
+ [71] = {VFE_CMD_JPEG_OUT_BUF_ENQ},
+ [72] = {VFE_CMD_RAW_OUT_BUF_ENQ},
+ [73] = {VFE_CMD_RAW_IN_BUF_ENQ},
+ [74] = {VFE_CMD_STATS_AF_ENQ},
+ [75] = {VFE_CMD_STATS_AE_ENQ},
+ [76] = {VFE_CMD_STATS_AWB_ENQ},
+ [77] = {VFE_CMD_STATS_RS_ENQ},
+ [78] = {VFE_CMD_STATS_CS_ENQ},
+ [79] = {VFE_CMD_STATS_SKIN_ENQ},
+ [80] = {VFE_CMD_STATS_IHIST_ENQ},
+ [82] = {VFE_CMD_JPEG_ENC_CFG},
+ [84] = {VFE_CMD_STATS_AF_START},
+ [85] = {VFE_CMD_STATS_AF_STOP},
+ [86] = {VFE_CMD_STATS_AE_START},
+ [87] = {VFE_CMD_STATS_AE_STOP},
+ [88] = {VFE_CMD_STATS_AWB_START, V40_STATS_AWB_LEN, V40_STATS_AWB_OFF},
+ [89] = {VFE_CMD_STATS_AWB_STOP},
+ [90] = {VFE_CMD_STATS_RS_START, V40_STATS_RS_LEN, V40_STATS_RS_OFF},
+ [91] = {VFE_CMD_STATS_RS_STOP},
+ [92] = {VFE_CMD_STATS_CS_START, V40_STATS_CS_LEN, V40_STATS_CS_OFF},
+ [93] = {VFE_CMD_STATS_CS_STOP},
+ [94] = {VFE_CMD_STATS_SKIN_START},
+ [95] = {VFE_CMD_STATS_SKIN_STOP},
+ [96] = {VFE_CMD_STATS_IHIST_START,
+ V40_STATS_IHIST_LEN, V40_STATS_IHIST_OFF},
+ [97] = {VFE_CMD_STATS_IHIST_STOP},
+ [99] = {VFE_CMD_SYNC_TIMER_SETTING, V40_SYNC_TIMER_LEN,
+ V40_SYNC_TIMER_OFF},
+ [100] = {VFE_CMD_ASYNC_TIMER_SETTING, V40_ASYNC_TIMER_LEN,
+ V40_ASYNC_TIMER_OFF},
+ [101] = {VFE_CMD_LIVESHOT},
+ [102] = {VFE_CMD_LA_SETUP},
+ [103] = {VFE_CMD_LINEARIZATION_CFG, V40_LINEARIZATION_LEN1,
+ V40_LINEARIZATION_OFF1},
+ [104] = {VFE_CMD_DEMOSAICV3},
+ [105] = {VFE_CMD_DEMOSAICV3_ABCC_CFG},
+ [106] = {VFE_CMD_DEMOSAICV3_DBCC_CFG, V40_DEMOSAICV3_DBCC_LEN,
+ V40_DEMOSAICV3_DBCC_OFF},
+ [107] = {VFE_CMD_DEMOSAICV3_DBPC_CFG},
+ [108] = {VFE_CMD_DEMOSAICV3_ABF_CFG, V40_DEMOSAICV3_ABF_LEN,
+ V40_DEMOSAICV3_ABF_OFF},
+ [109] = {VFE_CMD_DEMOSAICV3_ABCC_UPDATE},
+ [110] = {VFE_CMD_DEMOSAICV3_DBCC_UPDATE, V40_DEMOSAICV3_DBCC_LEN,
+ V40_DEMOSAICV3_DBCC_OFF},
+ [111] = {VFE_CMD_DEMOSAICV3_DBPC_UPDATE},
+ [112] = {VFE_CMD_XBAR_CFG},
+ [113] = {VFE_CMD_MODULE_CFG, V40_MODULE_CFG_LEN, V40_MODULE_CFG_OFF},
+ [114] = {VFE_CMD_ZSL},
+ [115] = {VFE_CMD_LINEARIZATION_UPDATE, V40_LINEARIZATION_LEN1,
+ V40_LINEARIZATION_OFF1},
+ [116] = {VFE_CMD_DEMOSAICV3_ABF_UPDATE, V40_DEMOSAICV3_ABF_LEN,
+ V40_DEMOSAICV3_ABF_OFF},
+ [117] = {VFE_CMD_CLF_CFG, V40_CLF_CFG_LEN, V40_CLF_CFG_OFF},
+ [118] = {VFE_CMD_CLF_LUMA_UPDATE, V40_CLF_LUMA_UPDATE_LEN,
+ V40_CLF_LUMA_UPDATE_OFF},
+ [119] = {VFE_CMD_CLF_CHROMA_UPDATE, V40_CLF_CHROMA_UPDATE_LEN,
+ V40_CLF_CHROMA_UPDATE_OFF},
+ [120] = {VFE_CMD_PCA_ROLL_OFF_CFG},
+ [121] = {VFE_CMD_PCA_ROLL_OFF_UPDATE},
+ [122] = {VFE_CMD_GET_REG_DUMP},
+ [123] = {VFE_CMD_GET_LINEARIZATON_TABLE},
+ [124] = {VFE_CMD_GET_MESH_ROLLOFF_TABLE},
+ [125] = {VFE_CMD_GET_PCA_ROLLOFF_TABLE},
+ [126] = {VFE_CMD_GET_RGB_G_TABLE},
+ [127] = {VFE_CMD_GET_LA_TABLE},
+ [128] = {VFE_CMD_DEMOSAICV3_UPDATE},
+ [129] = {VFE_CMD_ACTIVE_REGION_CFG},
+ [130] = {VFE_CMD_COLOR_PROCESSING_CONFIG},
+ [131] = {VFE_CMD_STATS_WB_AEC_CONFIG},
+ [132] = {VFE_CMD_STATS_WB_AEC_UPDATE},
+ [133] = {VFE_CMD_Y_GAMMA_CONFIG},
+ [134] = {VFE_CMD_SCALE_OUTPUT1_CONFIG},
+ [135] = {VFE_CMD_SCALE_OUTPUT2_CONFIG},
+ [136] = {VFE_CMD_CAPTURE_RAW},
+ [137] = {VFE_CMD_STOP_LIVESHOT},
+ [138] = {VFE_CMD_RECONFIG_VFE},
+ [139] = {VFE_CMD_STATS_REQBUF},
+ [140] = {VFE_CMD_STATS_ENQUEUEBUF},
+ [141] = {VFE_CMD_STATS_FLUSH_BUFQ},
+ [142] = {VFE_CMD_STATS_UNREGBUF},
+ [143] = {VFE_CMD_STATS_BG_START, V40_STATS_BG_LEN, V40_STATS_BG_OFF},
+ [144] = {VFE_CMD_STATS_BG_STOP},
+ [145] = {VFE_CMD_STATS_BF_START, V40_STATS_BF_LEN, V40_STATS_BF_OFF},
+ [146] = {VFE_CMD_STATS_BF_STOP},
+ [147] = {VFE_CMD_STATS_BHIST_START, V40_STATS_BHIST_LEN,
+ V40_STATS_BHIST_OFF},
+ [148] = {VFE_CMD_STATS_BHIST_STOP},
+ [149] = {VFE_CMD_RESET_2},
+ [150] = {VFE_CMD_FOV_ENC_CFG, V40_FOV_ENC_LEN,
+ V40_FOV_ENC_OFF, 0xFF},
+ [151] = {VFE_CMD_FOV_VIEW_CFG, V40_FOV_VIEW_LEN,
+ V40_FOV_VIEW_OFF, 0xFF},
+ [152] = {VFE_CMD_FOV_ENC_UPDATE, V40_FOV_ENC_LEN,
+ V40_FOV_ENC_OFF, 0xFF},
+ [153] = {VFE_CMD_FOV_VIEW_UPDATE, V40_FOV_VIEW_LEN,
+ V40_FOV_VIEW_OFF, 0xFF},
+ [154] = {VFE_CMD_SCALER_ENC_CFG, V40_SCALER_ENC_LEN,
+ V40_SCALER_ENC_OFF, 0xFF},
+ [155] = {VFE_CMD_SCALER_VIEW_CFG, V40_SCALER_VIEW_LEN,
+ V40_SCALER_VIEW_OFF, 0xFF},
+ [156] = {VFE_CMD_SCALER_ENC_UPDATE, V40_SCALER_ENC_LEN,
+ V40_SCALER_ENC_OFF, 0xFF},
+ [157] = {VFE_CMD_SCALER_VIEW_UPDATE, V40_SCALER_VIEW_LEN,
+ V40_SCALER_VIEW_OFF, 0xFF},
+ [158] = {VFE_CMD_COLORXFORM_ENC_CFG, V40_COLORXFORM_ENC_CFG_LEN,
+ V40_COLORXFORM_ENC_CFG_OFF, 0xFF},
+ [159] = {VFE_CMD_COLORXFORM_VIEW_CFG, V40_COLORXFORM_VIEW_CFG_LEN,
+ V40_COLORXFORM_VIEW_CFG_OFF},
+ [160] = {VFE_CMD_COLORXFORM_ENC_UPDATE, V40_COLORXFORM_ENC_CFG_LEN,
+ V40_COLORXFORM_ENC_CFG_OFF, 0xFF},
+ [161] = {VFE_CMD_COLORXFORM_VIEW_UPDATE, V40_COLORXFORM_VIEW_CFG_LEN,
+ V40_COLORXFORM_VIEW_CFG_OFF, 0xFF},
};
-static void vfe40_stop(struct vfe40_ctrl_type *vfe40_ctrl)
+static const uint32_t vfe40_AXI_WM_CFG[] = {
+ 0x0000006C,
+ 0x00000090,
+ 0x000000B4,
+ 0x000000D8,
+ 0x000000FC,
+ 0x00000120,
+ 0x00000144,
+};
+
+static const char * const vfe40_general_cmd[] = {
+ [1] = "SET_CLK",
+ [2] = "RESET",
+ [3] = "START",
+ [4] = "TEST_GEN_START",
+ [5] = "OPERATION_CFG", /* 5 */
+ [6] = "AXI_OUT_CFG",
+ [7] = "CAMIF_CFG",
+ [8] = "AXI_INPUT_CFG",
+ [9] = "BLACK_LEVEL_CFG",
+ [10] = "ROLL_OFF_CFG", /* 10 */
+ [11] = "DEMUX_CFG",
+ [12] = "FOV_CFG",
+ [13] = "MAIN_SCALER_CFG",
+ [14] = "WB_CFG",
+ [15] = "COLOR_COR_CFG", /* 15 */
+ [16] = "RGB_G_CFG",
+ [17] = "LA_CFG",
+ [18] = "CHROMA_EN_CFG",
+ [19] = "CHROMA_SUP_CFG",
+ [20] = "MCE_CFG", /* 20 */
+ [21] = "SK_ENHAN_CFG",
+ [22] = "ASF_CFG",
+ [23] = "S2Y_CFG",
+ [24] = "S2CbCr_CFG",
+ [25] = "CHROMA_SUBS_CFG", /* 25 */
+ [26] = "OUT_CLAMP_CFG",
+ [27] = "FRAME_SKIP_CFG",
+ [31] = "UPDATE",
+ [32] = "BL_LVL_UPDATE",
+ [33] = "DEMUX_UPDATE",
+ [34] = "FOV_UPDATE",
+ [35] = "MAIN_SCALER_UPDATE", /* 35 */
+ [36] = "WB_UPDATE",
+ [37] = "COLOR_COR_UPDATE",
+ [38] = "RGB_G_UPDATE",
+ [39] = "LA_UPDATE",
+ [40] = "CHROMA_EN_UPDATE", /* 40 */
+ [41] = "CHROMA_SUP_UPDATE",
+ [42] = "MCE_UPDATE",
+ [43] = "SK_ENHAN_UPDATE",
+ [44] = "S2CbCr_UPDATE",
+ [45] = "S2Y_UPDATE", /* 45 */
+ [46] = "ASF_UPDATE",
+ [47] = "FRAME_SKIP_UPDATE",
+ [48] = "CAMIF_FRAME_UPDATE",
+ [49] = "STATS_AF_UPDATE",
+ [50] = "STATS_AE_UPDATE", /* 50 */
+ [51] = "STATS_AWB_UPDATE",
+ [52] = "STATS_RS_UPDATE",
+ [53] = "STATS_CS_UPDATE",
+ [54] = "STATS_SKIN_UPDATE",
+ [55] = "STATS_IHIST_UPDATE", /* 55 */
+ [57] = "EPOCH1_ACK",
+ [58] = "EPOCH2_ACK",
+ [59] = "START_RECORDING",
+ [60] = "STOP_RECORDING", /* 60 */
+ [63] = "CAPTURE",
+ [65] = "STOP", /* 65 */
+ [66] = "GET_HW_VERSION",
+ [67] = "GET_FRAME_SKIP_COUNTS",
+ [68] = "OUTPUT1_BUFFER_ENQ",
+ [69] = "OUTPUT2_BUFFER_ENQ",
+ [70] = "OUTPUT3_BUFFER_ENQ", /* 70 */
+ [71] = "JPEG_OUT_BUF_ENQ",
+ [72] = "RAW_OUT_BUF_ENQ",
+ [73] = "RAW_IN_BUF_ENQ",
+ [74] = "STATS_AF_ENQ",
+ [75] = "STATS_AE_ENQ", /* 75 */
+ [76] = "STATS_AWB_ENQ",
+ [77] = "STATS_RS_ENQ",
+ [78] = "STATS_CS_ENQ",
+ [79] = "STATS_SKIN_ENQ",
+ [80] = "STATS_IHIST_ENQ", /* 80 */
+ [82] = "JPEG_ENC_CFG",
+ [84] = "STATS_AF_START",
+ [85] = "STATS_AF_STOP", /* 85 */
+ [86] = "STATS_AE_START",
+ [87] = "STATS_AE_STOP",
+ [88] = "STATS_AWB_START",
+ [89] = "STATS_AWB_STOP",
+ [90] = "STATS_RS_START", /* 90 */
+ [91] = "STATS_RS_STOP",
+ [92] = "STATS_CS_START",
+ [93] = "STATS_CS_STOP",
+ [94] = "STATS_SKIN_START",
+ [95] = "STATS_SKIN_STOP", /* 95 */
+ [96] = "STATS_IHIST_START",
+ [97] = "STATS_IHIST_STOP",
+ [99] = "SYNC_TIMER_SETTING",
+ [100] = "ASYNC_TIMER_SETTING", /* 100 */
+ [101] = "LIVESHOT",
+ [102] = "LA_SETUP",
+ [103] = "LINEARIZATION_CFG",
+ [104] = "DEMOSAICV3",
+ [105] = "DEMOSAICV3_ABCC_CFG", /* 105 */
+ [106] = "DEMOSAICV3_DBCC_CFG",
+ [107] = "DEMOSAICV3_DBPC_CFG",
+ [108] = "DEMOSAICV3_ABF_CFG",
+ [109] = "DEMOSAICV3_ABCC_UPDATE",
+ [110] = "DEMOSAICV3_DBCC_UPDATE", /* 110 */
+ [111] = "DEMOSAICV3_DBPC_UPDATE",
+ [112] = "XBAR_CFG",
+ [113] = "EZTUNE_CFG",
+ [114] = "V40_ZSL",
+ [115] = "LINEARIZATION_UPDATE", /*115*/
+ [116] = "DEMOSAICV3_ABF_UPDATE",
+ [117] = "CLF_CFG",
+ [118] = "CLF_LUMA_UPDATE",
+ [119] = "CLF_CHROMA_UPDATE",
+ [120] = "PCA_ROLL_OFF_CFG", /*120*/
+ [121] = "PCA_ROLL_OFF_UPDATE",
+ [122] = "GET_REG_DUMP",
+ [123] = "GET_LINEARIZATON_TABLE",
+ [124] = "GET_MESH_ROLLOFF_TABLE",
+ [125] = "GET_PCA_ROLLOFF_TABLE", /*125*/
+ [126] = "GET_RGB_G_TABLE",
+ [127] = "GET_LA_TABLE",
+ [128] = "DEMOSAICV3_UPDATE",
+ [139] = "STATS_REQBUF",
+ [140] = "STATS_ENQUEUEBUF", /*140*/
+ [141] = "STATS_FLUSH_BUFQ",
+ [142] = "STATS_UNREGBUF",
+ [143] = "STATS_BG_START",
+ [144] = "STATS_BG_STOP",
+ [145] = "STATS_BF_START", /*145*/
+ [146] = "STATS_BF_STOP",
+ [147] = "STATS_BHIST_START",
+ [148] = "STATS_BHIST_STOP",
+ [149] = "RESET_2",
+};
+
+/*Temporary use fixed bus vectors in VFE */
+static struct msm_bus_vectors vfe_init_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_VFE,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 0,
+ .ib = 0,
+ },
+};
+
+static struct msm_bus_vectors vfe_preview_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_VFE,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 27648000,
+ .ib = 110592000,
+ },
+};
+
+static struct msm_bus_vectors vfe_video_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_VFE,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 154275840,
+ .ib = 617103360,
+ },
+};
+
+static struct msm_bus_vectors vfe_snapshot_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_VFE,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 274423680,
+ .ib = 1097694720,
+ },
+};
+
+static struct msm_bus_vectors vfe_zsl_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_VFE,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 302071680,
+ .ib = 1208286720,
+ },
+};
+
+static struct msm_bus_paths vfe_bus_client_config[] = {
+ {
+ ARRAY_SIZE(vfe_init_vectors),
+ vfe_init_vectors,
+ },
+ {
+ ARRAY_SIZE(vfe_preview_vectors),
+ vfe_preview_vectors,
+ },
+ {
+ ARRAY_SIZE(vfe_video_vectors),
+ vfe_video_vectors,
+ },
+ {
+ ARRAY_SIZE(vfe_snapshot_vectors),
+ vfe_snapshot_vectors,
+ },
+ {
+ ARRAY_SIZE(vfe_zsl_vectors),
+ vfe_zsl_vectors,
+ },
+};
+
+static struct msm_bus_scale_pdata vfe_bus_client_pdata = {
+ vfe_bus_client_config,
+ ARRAY_SIZE(vfe_bus_client_config),
+ .name = "msm_camera_vfe",
+};
+
+uint8_t vfe40_use_bayer_stats(struct vfe40_ctrl_type *vfe40_ctrl)
{
- unsigned long flags;
+ if (vfe40_ctrl->ver_num.main >= 4) {
+ /* VFE 4 or above uses bayer stats */
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
- atomic_set(&vfe40_ctrl->share_ctrl->vstate, 0);
+static void axi_enable_irq(struct vfe_share_ctrl_t *share_ctrl)
+{
+ uint32_t irq_mask;
+ uint16_t vfe_operation_mode =
+ share_ctrl->current_mode & ~(VFE_OUTPUTS_RDI0|
+ VFE_OUTPUTS_RDI1);
+ irq_mask =
+ msm_camera_io_r(share_ctrl->vfebase +
+ VFE_IRQ_MASK_0);
- /* for reset hw modules, and send msg when reset_irq comes.*/
- spin_lock_irqsave(&vfe40_ctrl->share_ctrl->stop_flag_lock, flags);
- vfe40_ctrl->share_ctrl->stop_ack_pending = TRUE;
- spin_unlock_irqrestore(&vfe40_ctrl->share_ctrl->stop_flag_lock, flags);
+ irq_mask |= VFE_IMASK_WHILE_STOPPING_0;
+
+ if (share_ctrl->current_mode & VFE_OUTPUTS_RDI0)
+ irq_mask |= VFE_IRQ_STATUS0_RDI0_REG_UPDATE_MASK;
+
+ if (share_ctrl->current_mode & VFE_OUTPUTS_RDI1)
+ irq_mask |= VFE_IRQ_STATUS0_RDI1_REG_UPDATE_MASK;
+
+ msm_camera_io_w(irq_mask, share_ctrl->vfebase +
+ VFE_IRQ_MASK_0);
+
+ if (vfe_operation_mode) {
+ irq_mask =
+ msm_camera_io_r(share_ctrl->vfebase +
+ VFE_IRQ_MASK_0);
+ irq_mask |= 0x00000021;
+ if (share_ctrl->stats_comp)
+ irq_mask |= VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK_0;
+ else
+ irq_mask |= 0x00FF0000;
+ msm_camera_io_w(irq_mask, share_ctrl->vfebase +
+ VFE_IRQ_MASK_0);
+ atomic_set(&share_ctrl->vstate, 1);
+ }
+ atomic_set(&share_ctrl->handle_common_irq, 1);
+}
+
+static void axi_disable_irq(struct vfe_share_ctrl_t *share_ctrl)
+{
/* disable all interrupts. */
+
+ uint32_t irq_mask = 0;
+ uint16_t vfe_operation_mode =
+ share_ctrl->current_mode & ~(VFE_OUTPUTS_RDI0|
+ VFE_OUTPUTS_RDI1);
+
+ if (share_ctrl->current_mode & VFE_OUTPUTS_RDI0) {
+ irq_mask =
+ msm_camera_io_r(share_ctrl->vfebase +
+ VFE_IRQ_MASK_0);
+ irq_mask &= ~(VFE_IRQ_STATUS0_RDI0_REG_UPDATE_MASK);
+ msm_camera_io_w(irq_mask, share_ctrl->vfebase +
+ VFE_IRQ_MASK_0);
+ msm_camera_io_w(VFE_IRQ_STATUS0_RDI0_REG_UPDATE_MASK,
+ share_ctrl->vfebase + VFE_IRQ_CLEAR_0);
+ }
+ if (share_ctrl->current_mode & VFE_OUTPUTS_RDI1) {
+ irq_mask =
+ msm_camera_io_r(share_ctrl->vfebase +
+ VFE_IRQ_MASK_0);
+ irq_mask &= ~(VFE_IRQ_STATUS0_RDI1_REG_UPDATE_MASK);
+ msm_camera_io_w(irq_mask, share_ctrl->vfebase +
+ VFE_IRQ_MASK_0);
+ msm_camera_io_w(VFE_IRQ_STATUS0_RDI1_REG_UPDATE_MASK,
+ share_ctrl->vfebase + VFE_IRQ_CLEAR_0);
+ }
+ if (vfe_operation_mode) {
+ atomic_set(&share_ctrl->vstate, 0);
+ irq_mask =
+ msm_camera_io_r(share_ctrl->vfebase +
+ VFE_IRQ_MASK_0);
+ irq_mask &= ~(0x00000011);
+ if (share_ctrl->stats_comp)
+ irq_mask &= ~(VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK_0);
+ else
+ irq_mask &= ~0x00FF0000;
+ msm_camera_io_w(irq_mask, share_ctrl->vfebase +
+ VFE_IRQ_MASK_0);
+ }
+
+ if (share_ctrl->axi_ref_cnt == 1) {
+ atomic_set(&share_ctrl->handle_common_irq, 0);
msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
- vfe40_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_0);
+ share_ctrl->vfebase + VFE_IRQ_MASK_0);
msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
- vfe40_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_1);
+ share_ctrl->vfebase + VFE_IRQ_MASK_1);
/* clear all pending interrupts*/
- msm_camera_io_w(VFE_CLEAR_ALL_IRQ0,
- vfe40_ctrl->share_ctrl->vfebase + VFE_IRQ_CLEAR_0);
- msm_camera_io_w(VFE_CLEAR_ALL_IRQ1,
- vfe40_ctrl->share_ctrl->vfebase + VFE_IRQ_CLEAR_1);
+ msm_camera_io_w(0xFFFFFFFF,
+ share_ctrl->vfebase + VFE_IRQ_CLEAR_0);
+ msm_camera_io_w(0xFFFFFFFF,
+ share_ctrl->vfebase + VFE_IRQ_CLEAR_1);
/* Ensure the write order while writing
to the command register using the barrier */
msm_camera_io_w_mb(1,
- vfe40_ctrl->share_ctrl->vfebase + VFE_IRQ_CMD);
+ share_ctrl->vfebase + VFE_IRQ_CMD);
+ }
+}
+
+static void vfe40_stop(struct vfe40_ctrl_type *vfe40_ctrl)
+{
/* in either continuous or snapshot mode, stop command can be issued
* at any time. stop camif immediately. */
msm_camera_io_w(CAMIF_COMMAND_STOP_IMMEDIATELY,
vfe40_ctrl->share_ctrl->vfebase + VFE_CAMIF_COMMAND);
+ vfe40_ctrl->share_ctrl->operation_mode &=
+ ~(vfe40_ctrl->share_ctrl->current_mode);
+ vfe40_ctrl->share_ctrl->current_mode = 0;
}
-void vfe40_subdev_notify(int id, int path, int image_mode,
+static void vfe40_subdev_notify(int id, int path, uint32_t inst_handle,
struct v4l2_subdev *sd, struct vfe_share_ctrl_t *share_ctrl)
{
struct msm_vfe_resp rp;
struct msm_frame_info frame_info;
unsigned long flags = 0;
spin_lock_irqsave(&share_ctrl->sd_notify_lock, flags);
- CDBG("%s: msgId = %d\n", __func__, id);
+ CDBG("vfe40_subdev_notify : msgId = %d\n", id);
memset(&rp, 0, sizeof(struct msm_vfe_resp));
rp.evt_msg.type = MSM_CAMERA_MSG;
- frame_info.image_mode = image_mode;
+ frame_info.inst_handle = inst_handle;
frame_info.path = path;
rp.evt_msg.data = &frame_info;
rp.type = id;
@@ -242,45 +613,249 @@
spin_unlock_irqrestore(&share_ctrl->sd_notify_lock, flags);
}
+static int vfe40_config_axi(
+ struct axi_ctrl_t *axi_ctrl, int mode, uint32_t *ao)
+{
+ uint32_t *ch_info;
+ uint32_t *axi_cfg = ao;
+ int vfe_mode = (mode & ~(OUTPUT_TERT1|OUTPUT_TERT2));
+
+ /* Update the corresponding write masters for each output*/
+ ch_info = axi_cfg + V40_AXI_CFG_LEN;
+ axi_ctrl->share_ctrl->outpath.out0.ch0 = 0x0000FFFF & *ch_info;
+ axi_ctrl->share_ctrl->outpath.out0.ch1 =
+ 0x0000FFFF & (*ch_info++ >> 16);
+ axi_ctrl->share_ctrl->outpath.out0.ch2 = 0x0000FFFF & *ch_info++;
+ axi_ctrl->share_ctrl->outpath.out0.inst_handle = *ch_info++;
+
+ axi_ctrl->share_ctrl->outpath.out1.ch0 = 0x0000FFFF & *ch_info;
+ axi_ctrl->share_ctrl->outpath.out1.ch1 =
+ 0x0000FFFF & (*ch_info++ >> 16);
+ axi_ctrl->share_ctrl->outpath.out1.ch2 = 0x0000FFFF & *ch_info++;
+ axi_ctrl->share_ctrl->outpath.out1.inst_handle = *ch_info++;
+
+ axi_ctrl->share_ctrl->outpath.out2.ch0 = 0x0000FFFF & *ch_info;
+ axi_ctrl->share_ctrl->outpath.out2.ch1 =
+ 0x0000FFFF & (*ch_info++ >> 16);
+ axi_ctrl->share_ctrl->outpath.out2.ch2 = 0x0000FFFF & *ch_info++;
+ axi_ctrl->share_ctrl->outpath.out2.inst_handle = *ch_info++;
+
+ axi_ctrl->share_ctrl->outpath.out3.ch0 = 0x0000FFFF & *ch_info;
+ axi_ctrl->share_ctrl->outpath.out3.ch1 =
+ 0x0000FFFF & (*ch_info++ >> 16);
+ axi_ctrl->share_ctrl->outpath.out3.ch2 = 0x0000FFFF & *ch_info++;
+ axi_ctrl->share_ctrl->outpath.out3.inst_handle = *ch_info++;
+
+ axi_ctrl->share_ctrl->outpath.output_mode = 0;
+
+ if (mode & OUTPUT_TERT1)
+ axi_ctrl->share_ctrl->outpath.output_mode |=
+ VFE40_OUTPUT_MODE_TERTIARY1;
+ if (mode & OUTPUT_TERT2)
+ axi_ctrl->share_ctrl->outpath.output_mode |=
+ VFE40_OUTPUT_MODE_TERTIARY2;
+ if (mode == OUTPUT_TERT1 || mode == OUTPUT_TERT1
+ || mode == (OUTPUT_TERT1|OUTPUT_TERT2))
+ goto bus_cfg;
+
+ switch (vfe_mode) {
+ case OUTPUT_PRIM:
+ axi_ctrl->share_ctrl->outpath.output_mode |=
+ VFE40_OUTPUT_MODE_PRIMARY;
+ break;
+ case OUTPUT_PRIM_ALL_CHNLS:
+ axi_ctrl->share_ctrl->outpath.output_mode |=
+ VFE40_OUTPUT_MODE_PRIMARY_ALL_CHNLS;
+ break;
+ case OUTPUT_PRIM|OUTPUT_SEC:
+ axi_ctrl->share_ctrl->outpath.output_mode |=
+ VFE40_OUTPUT_MODE_PRIMARY;
+ axi_ctrl->share_ctrl->outpath.output_mode |=
+ VFE40_OUTPUT_MODE_SECONDARY;
+ break;
+ case OUTPUT_PRIM|OUTPUT_SEC_ALL_CHNLS:
+ axi_ctrl->share_ctrl->outpath.output_mode |=
+ VFE40_OUTPUT_MODE_PRIMARY;
+ axi_ctrl->share_ctrl->outpath.output_mode |=
+ VFE40_OUTPUT_MODE_SECONDARY_ALL_CHNLS;
+ break;
+ case OUTPUT_PRIM_ALL_CHNLS|OUTPUT_SEC:
+ axi_ctrl->share_ctrl->outpath.output_mode |=
+ VFE40_OUTPUT_MODE_PRIMARY_ALL_CHNLS;
+ axi_ctrl->share_ctrl->outpath.output_mode |=
+ VFE40_OUTPUT_MODE_SECONDARY;
+ break;
+ default:
+ pr_err("%s Invalid AXI mode %d ", __func__, mode);
+ return -EINVAL;
+ }
+
+bus_cfg:
+ msm_camera_io_memcpy(axi_ctrl->share_ctrl->vfebase +
+ vfe40_cmd[VFE_CMD_AXI_OUT_CFG].offset, axi_cfg,
+ V40_AXI_BUS_CFG_LEN);
+ msm_camera_io_w(*ch_info++,
+ axi_ctrl->share_ctrl->vfebase + VFE_RDI0_CFG);
+ msm_camera_io_w(*ch_info++,
+ axi_ctrl->share_ctrl->vfebase + VFE_RDI1_CFG);
+ msm_camera_io_w(*ch_info++,
+ axi_ctrl->share_ctrl->vfebase + VFE_RDI2_CFG);
+ return 0;
+}
+
+static void axi_reset_internal_variables(
+ struct axi_ctrl_t *axi_ctrl)
+{
+ unsigned long flags;
+ /* state control variables */
+ axi_ctrl->share_ctrl->start_ack_pending = FALSE;
+ atomic_set(&irq_cnt, 0);
+
+ spin_lock_irqsave(&axi_ctrl->share_ctrl->stop_flag_lock, flags);
+ axi_ctrl->share_ctrl->stop_ack_pending = FALSE;
+ spin_unlock_irqrestore(&axi_ctrl->share_ctrl->stop_flag_lock, flags);
+
+ spin_lock_irqsave(&axi_ctrl->share_ctrl->update_ack_lock, flags);
+ axi_ctrl->share_ctrl->update_ack_pending = FALSE;
+ spin_unlock_irqrestore(&axi_ctrl->share_ctrl->update_ack_lock, flags);
+
+ axi_ctrl->share_ctrl->recording_state = VFE_STATE_IDLE;
+ axi_ctrl->share_ctrl->liveshot_state = VFE_STATE_IDLE;
+
+ atomic_set(&axi_ctrl->share_ctrl->vstate, 0);
+ atomic_set(&axi_ctrl->share_ctrl->handle_common_irq, 0);
+ atomic_set(&axi_ctrl->share_ctrl->pix0_update_ack_pending, 0);
+ atomic_set(&axi_ctrl->share_ctrl->rdi0_update_ack_pending, 0);
+ atomic_set(&axi_ctrl->share_ctrl->rdi1_update_ack_pending, 0);
+ atomic_set(&axi_ctrl->share_ctrl->rdi2_update_ack_pending, 0);
+
+ /* 0 for continuous mode, 1 for snapshot mode */
+ axi_ctrl->share_ctrl->operation_mode = 0;
+ axi_ctrl->share_ctrl->current_mode = 0;
+ axi_ctrl->share_ctrl->outpath.output_mode = 0;
+ axi_ctrl->share_ctrl->comp_output_mode = 0;
+ axi_ctrl->share_ctrl->vfe_capture_count = 0;
+
+ /* this is unsigned 32 bit integer. */
+ axi_ctrl->share_ctrl->vfeFrameId = 0;
+ axi_ctrl->share_ctrl->rdi0FrameId = 0;
+ axi_ctrl->share_ctrl->rdi1FrameId = 0;
+ axi_ctrl->share_ctrl->rdi2FrameId = 0;
+}
+
+static void vfe40_program_dmi_cfg(
+ enum VFE40_DMI_RAM_SEL bankSel,
+ struct vfe40_ctrl_type *vfe40_ctrl)
+{
+ /* set bit 8 for auto increment. */
+ uint32_t value = VFE_DMI_CFG_DEFAULT;
+ value += (uint32_t)bankSel;
+ CDBG("%s: banksel = %d\n", __func__, bankSel);
+
+ msm_camera_io_w(value, vfe40_ctrl->share_ctrl->vfebase +
+ VFE_DMI_CFG);
+ /* by default, always starts with offset 0.*/
+ msm_camera_io_w(0, vfe40_ctrl->share_ctrl->vfebase +
+ VFE_DMI_ADDR);
+}
+
+static void vfe40_reset_dmi_tables(
+ struct vfe40_ctrl_type *vfe40_ctrl)
+{
+ int i = 0;
+
+ /* Reset Histogram LUTs */
+ CDBG("Reset Bayer histogram LUT : 0\n");
+ vfe40_program_dmi_cfg(STATS_BHIST_RAM0, vfe40_ctrl);
+ /* Loop for configuring LUT */
+ for (i = 0; i < 256; i++) {
+ msm_camera_io_w(0, vfe40_ctrl->share_ctrl->vfebase +
+ VFE_DMI_DATA_HI);
+ msm_camera_io_w(0, vfe40_ctrl->share_ctrl->vfebase +
+ VFE_DMI_DATA_LO);
+ }
+ vfe40_program_dmi_cfg(NO_MEM_SELECTED, vfe40_ctrl);
+
+ CDBG("Reset Bayer Histogram LUT: 1\n");
+ vfe40_program_dmi_cfg(STATS_BHIST_RAM1, vfe40_ctrl);
+ /* Loop for configuring LUT */
+ for (i = 0; i < 256; i++) {
+ msm_camera_io_w(0, vfe40_ctrl->share_ctrl->vfebase +
+ VFE_DMI_DATA_HI);
+ msm_camera_io_w(0, vfe40_ctrl->share_ctrl->vfebase +
+ VFE_DMI_DATA_LO);
+ }
+ vfe40_program_dmi_cfg(NO_MEM_SELECTED, vfe40_ctrl);
+
+ CDBG("Reset IHistogram LUT\n");
+ vfe40_program_dmi_cfg(STATS_IHIST_RAM, vfe40_ctrl);
+ /* Loop for configuring LUT */
+ for (i = 0; i < 256; i++) {
+ msm_camera_io_w(0, vfe40_ctrl->share_ctrl->vfebase +
+ VFE_DMI_DATA_HI);
+ msm_camera_io_w(0, vfe40_ctrl->share_ctrl->vfebase +
+ VFE_DMI_DATA_LO);
+ }
+ vfe40_program_dmi_cfg(NO_MEM_SELECTED, vfe40_ctrl);
+}
+
+static void vfe40_set_default_reg_values(
+ struct vfe40_ctrl_type *vfe40_ctrl)
+{
+ msm_camera_io_w(0x800080,
+ vfe40_ctrl->share_ctrl->vfebase + VFE_DEMUX_GAIN_0);
+ msm_camera_io_w(0x800080,
+ vfe40_ctrl->share_ctrl->vfebase + VFE_DEMUX_GAIN_1);
+ msm_camera_io_w(0xFFFFF,
+ vfe40_ctrl->share_ctrl->vfebase + VFE_CGC_OVERRIDE);
+
+ msm_camera_io_w(0,
+ vfe40_ctrl->share_ctrl->vfebase + VFE_CLAMP_ENC_MIN);
+ msm_camera_io_w(0xFFFFFF,
+ vfe40_ctrl->share_ctrl->vfebase + VFE_CLAMP_ENC_MAX);
+ msm_camera_io_w(0,
+ vfe40_ctrl->share_ctrl->vfebase + VFE_CLAMP_VIEW_MIN);
+ msm_camera_io_w(0xFFFFFF,
+ vfe40_ctrl->share_ctrl->vfebase + VFE_CLAMP_VIEW_MAX);
+
+ /* stats UB config */
+ CDBG("%s: Use bayer stats = %d\n", __func__,
+ vfe40_use_bayer_stats(vfe40_ctrl));
+ msm_camera_io_w(0x350001F,
+ vfe40_ctrl->share_ctrl->vfebase +
+ VFE_BUS_STATS_HIST_WR_UB_CFG);
+ msm_camera_io_w(0x370002F,
+ vfe40_ctrl->share_ctrl->vfebase +
+ VFE_BUS_STATS_BG_WR_UB_CFG);
+ msm_camera_io_w(0x3A0002F,
+ vfe40_ctrl->share_ctrl->vfebase +
+ VFE_BUS_STATS_BF_WR_UB_CFG);
+ msm_camera_io_w(0x3D00007,
+ vfe40_ctrl->share_ctrl->vfebase +
+ VFE_BUS_STATS_RS_WR_UB_CFG);
+ msm_camera_io_w(0x3D8001F,
+ vfe40_ctrl->share_ctrl->vfebase +
+ VFE_BUS_STATS_CS_WR_UB_CFG);
+ msm_camera_io_w(0x3F80007,
+ vfe40_ctrl->share_ctrl->vfebase +
+ VFE_BUS_STATS_SKIN_WR_UB_CFG);
+ vfe40_reset_dmi_tables(vfe40_ctrl);
+}
+
static void vfe40_reset_internal_variables(
struct vfe40_ctrl_type *vfe40_ctrl)
{
- unsigned long flags;
- vfe40_ctrl->vfeImaskCompositePacked = 0;
- /* state control variables */
- vfe40_ctrl->start_ack_pending = FALSE;
- atomic_set(&vfe40_ctrl->share_ctrl->irq_cnt, 0);
-
- spin_lock_irqsave(&vfe40_ctrl->share_ctrl->stop_flag_lock, flags);
- vfe40_ctrl->share_ctrl->stop_ack_pending = FALSE;
- spin_unlock_irqrestore(&vfe40_ctrl->share_ctrl->stop_flag_lock, flags);
-
- vfe40_ctrl->reset_ack_pending = FALSE;
-
- spin_lock_irqsave(&vfe40_ctrl->update_ack_lock, flags);
- vfe40_ctrl->update_ack_pending = FALSE;
- spin_unlock_irqrestore(&vfe40_ctrl->update_ack_lock, flags);
-
- vfe40_ctrl->recording_state = VFE_STATE_IDLE;
- vfe40_ctrl->share_ctrl->liveshot_state = VFE_STATE_IDLE;
-
- atomic_set(&vfe40_ctrl->share_ctrl->vstate, 0);
-
- /* 0 for continuous mode, 1 for snapshot mode */
- vfe40_ctrl->share_ctrl->operation_mode = 0;
- vfe40_ctrl->share_ctrl->outpath.output_mode = 0;
- vfe40_ctrl->share_ctrl->vfe_capture_count = 0;
-
- /* this is unsigned 32 bit integer. */
- vfe40_ctrl->share_ctrl->vfeFrameId = 0;
/* Stats control variables. */
- memset(&(vfe40_ctrl->afStatsControl), 0,
+ memset(&(vfe40_ctrl->afbfStatsControl), 0,
sizeof(struct vfe_stats_control));
memset(&(vfe40_ctrl->awbStatsControl), 0,
sizeof(struct vfe_stats_control));
- memset(&(vfe40_ctrl->aecStatsControl), 0,
+ memset(&(vfe40_ctrl->aecbgStatsControl), 0,
+ sizeof(struct vfe_stats_control));
+
+ memset(&(vfe40_ctrl->bhistStatsControl), 0,
sizeof(struct vfe_stats_control));
memset(&(vfe40_ctrl->ihistStatsControl), 0,
@@ -295,32 +870,59 @@
vfe40_ctrl->frame_skip_cnt = 31;
vfe40_ctrl->frame_skip_pattern = 0xffffffff;
vfe40_ctrl->snapshot_frame_cnt = 0;
+ vfe40_set_default_reg_values(vfe40_ctrl);
}
-static void vfe40_reset(struct vfe40_ctrl_type *vfe40_ctrl)
+static int vfe40_reset(struct vfe40_ctrl_type *vfe40_ctrl)
{
- vfe40_reset_internal_variables(vfe40_ctrl);
+ uint32_t irq_mask;
+ atomic_set(&vfe40_ctrl->share_ctrl->vstate, 0);
+ msm_camera_io_w(VFE_MODULE_RESET_CMD,
+ vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_RESET);
+ msm_camera_io_w(0,
+ vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_RESET);
+
+ irq_mask =
+ msm_camera_io_r(vfe40_ctrl->share_ctrl->vfebase +
+ VFE_IRQ_MASK_0);
+ irq_mask &= ~(0x00FF0011|VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK_0);
+
+ /* enable reset_ack interrupt. */
+ irq_mask |= VFE_IMASK_WHILE_STOPPING_0;
+ msm_camera_io_w(irq_mask, vfe40_ctrl->share_ctrl->vfebase +
+ VFE_IRQ_MASK_0);
+
+ msm_camera_io_w_mb(VFE_ONLY_RESET_CMD,
+ vfe40_ctrl->share_ctrl->vfebase + VFE_GLOBAL_RESET);
+
+ return wait_for_completion_interruptible(
+ &vfe40_ctrl->share_ctrl->reset_complete);
+}
+
+static int axi_reset(struct axi_ctrl_t *axi_ctrl)
+{
+ axi_reset_internal_variables(axi_ctrl);
/* disable all interrupts. vfeImaskLocal is also reset to 0
* to begin with. */
msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
- vfe40_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_0);
+ axi_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_0);
msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
- vfe40_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_1);
+ axi_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_1);
/* clear all pending interrupts*/
- msm_camera_io_w(VFE_CLEAR_ALL_IRQS,
- vfe40_ctrl->share_ctrl->vfebase + VFE_IRQ_CLEAR_0);
- msm_camera_io_w(VFE_CLEAR_ALL_IRQS,
- vfe40_ctrl->share_ctrl->vfebase + VFE_IRQ_CLEAR_1);
+ msm_camera_io_w(VFE_CLEAR_ALL_IRQ0,
+ axi_ctrl->share_ctrl->vfebase + VFE_IRQ_CLEAR_0);
+ msm_camera_io_w(VFE_CLEAR_ALL_IRQ1,
+ axi_ctrl->share_ctrl->vfebase + VFE_IRQ_CLEAR_1);
/* Ensure the write order while writing
to the command register using the barrier */
- msm_camera_io_w_mb(1, vfe40_ctrl->share_ctrl->vfebase + VFE_IRQ_CMD);
+ msm_camera_io_w_mb(1, axi_ctrl->share_ctrl->vfebase + VFE_IRQ_CMD);
/* enable reset_ack interrupt. */
- msm_camera_io_w(VFE_IMASK_WHILE_STOPPING_1,
- vfe40_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_1);
+ msm_camera_io_w(VFE_IMASK_WHILE_STOPPING_0,
+ axi_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_0);
/* Write to VFE_GLOBAL_RESET_CMD to reset the vfe hardware. Once reset
* is done, hardware interrupt will be generated. VFE ist processes
@@ -330,24 +932,10 @@
/* Ensure the write order while writing
to the command register using the barrier */
msm_camera_io_w_mb(VFE_RESET_UPON_RESET_CMD,
- vfe40_ctrl->share_ctrl->vfebase + VFE_GLOBAL_RESET);
+ axi_ctrl->share_ctrl->vfebase + VFE_GLOBAL_RESET);
- msm_camera_io_w(0xAAAAAAAA,
- vfe40_ctrl->share_ctrl->vfebase + VFE_0_BUS_BDG_QOS_CFG_0);
- msm_camera_io_w(0xAAAAAAAA,
- vfe40_ctrl->share_ctrl->vfebase + VFE_0_BUS_BDG_QOS_CFG_1);
- msm_camera_io_w(0xAAAAAAAA,
- vfe40_ctrl->share_ctrl->vfebase + VFE_0_BUS_BDG_QOS_CFG_2);
- msm_camera_io_w(0xAAAAAAAA,
- vfe40_ctrl->share_ctrl->vfebase + VFE_0_BUS_BDG_QOS_CFG_3);
- msm_camera_io_w(0xAAAAAAAA,
- vfe40_ctrl->share_ctrl->vfebase + VFE_0_BUS_BDG_QOS_CFG_4);
- msm_camera_io_w(0xAAAAAAAA,
- vfe40_ctrl->share_ctrl->vfebase + VFE_0_BUS_BDG_QOS_CFG_5);
- msm_camera_io_w(0xAAAAAAAA,
- vfe40_ctrl->share_ctrl->vfebase + VFE_0_BUS_BDG_QOS_CFG_6);
- msm_camera_io_w(0x0002AAAA,
- vfe40_ctrl->share_ctrl->vfebase + VFE_0_BUS_BDG_QOS_CFG_7);
+ return wait_for_completion_interruptible(
+ &axi_ctrl->share_ctrl->reset_complete);
}
static int vfe40_operation_config(uint32_t *cmd,
@@ -355,7 +943,6 @@
{
uint32_t *p = cmd;
- vfe40_ctrl->share_ctrl->operation_mode = *p;
vfe40_ctrl->share_ctrl->stats_comp = *(++p);
vfe40_ctrl->hfr_mode = *(++p);
@@ -425,6 +1012,26 @@
return 0L;
}
+
+static unsigned long vfe40_stats_unregbuf(
+ struct vfe40_ctrl_type *vfe40_ctrl,
+ struct msm_stats_reqbuf *req_buf, int domain_num)
+{
+ int i = 0, rc = 0;
+
+ for (i = 0; i < req_buf->num_buf; i++) {
+ rc = vfe40_ctrl->stats_ops.buf_unprepare(
+ vfe40_ctrl->stats_ops.stats_ctrl,
+ req_buf->stats_type, i,
+ vfe40_ctrl->stats_ops.client, domain_num);
+ if (rc < 0) {
+ pr_err("%s: unreg stats buf (type = %d) err = %d",
+ __func__, req_buf->stats_type, rc);
+ return rc;
+ }
+ }
+ return 0L;
+}
static int vfe_stats_awb_buf_init(
struct vfe40_ctrl_type *vfe40_ctrl,
struct vfe_cmd_stats_buf *in)
@@ -456,14 +1063,18 @@
return 0;
}
-static int vfe_stats_aec_buf_init(
- struct vfe40_ctrl_type *vfe40_ctrl, struct vfe_cmd_stats_buf *in)
+static uint32_t vfe_stats_aec_bg_buf_init(
+ struct vfe40_ctrl_type *vfe40_ctrl)
{
uint32_t addr;
unsigned long flags;
+ uint32_t stats_type;
+ stats_type =
+ (!vfe40_use_bayer_stats(vfe40_ctrl)) ? MSM_STATS_TYPE_AEC
+ : MSM_STATS_TYPE_BG;
spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
- addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, MSM_STATS_TYPE_AEC);
+ addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, stats_type);
spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
if (!addr) {
pr_err("%s: dq aec ping buf from free buf queue",
@@ -472,9 +1083,9 @@
}
msm_camera_io_w(addr,
vfe40_ctrl->share_ctrl->vfebase +
- VFE_BUS_STATS_AEC_WR_PING_ADDR);
+ VFE_BUS_STATS_BG_WR_PING_ADDR);
spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
- addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, MSM_STATS_TYPE_AEC);
+ addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, stats_type);
spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
if (!addr) {
pr_err("%s: dq aec pong buf from free buf queue",
@@ -483,26 +1094,31 @@
}
msm_camera_io_w(addr,
vfe40_ctrl->share_ctrl->vfebase +
- VFE_BUS_STATS_AEC_WR_PONG_ADDR);
+ VFE_BUS_STATS_BG_WR_PONG_ADDR);
return 0;
}
-static int vfe_stats_af_buf_init(
- struct vfe40_ctrl_type *vfe40_ctrl, struct vfe_cmd_stats_buf *in)
+static int vfe_stats_af_bf_buf_init(
+ struct vfe40_ctrl_type *vfe40_ctrl)
{
uint32_t addr;
unsigned long flags;
int rc = 0;
+ uint32_t stats_type;
+ stats_type =
+ (!vfe40_use_bayer_stats(vfe40_ctrl)) ? MSM_STATS_TYPE_AF
+ : MSM_STATS_TYPE_BF;
+
spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
- rc = vfe40_stats_flush_enqueue(vfe40_ctrl, MSM_STATS_TYPE_AF);
+ rc = vfe40_stats_flush_enqueue(vfe40_ctrl, stats_type);
if (rc < 0) {
pr_err("%s: dq stats buf err = %d",
__func__, rc);
spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
return -EINVAL;
}
- addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, MSM_STATS_TYPE_AF);
+ addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, stats_type);
spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
if (!addr) {
pr_err("%s: dq af ping buf from free buf queue", __func__);
@@ -510,9 +1126,9 @@
}
msm_camera_io_w(addr,
vfe40_ctrl->share_ctrl->vfebase +
- VFE_BUS_STATS_AF_WR_PING_ADDR);
+ VFE_BUS_STATS_BF_WR_PING_ADDR);
spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
- addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, MSM_STATS_TYPE_AF);
+ addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, stats_type);
spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
if (!addr) {
pr_err("%s: dq af pong buf from free buf queue", __func__);
@@ -520,13 +1136,44 @@
}
msm_camera_io_w(addr,
vfe40_ctrl->share_ctrl->vfebase +
- VFE_BUS_STATS_AF_WR_PONG_ADDR);
+ VFE_BUS_STATS_BF_WR_PONG_ADDR);
+ return 0;
+}
+
+static uint32_t vfe_stats_bhist_buf_init(
+ struct vfe40_ctrl_type *vfe40_ctrl)
+{
+ uint32_t addr;
+ unsigned long flags;
+
+ spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
+ addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, MSM_STATS_TYPE_BHIST);
+ spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
+ if (!addr) {
+ pr_err("%s: dq ihist ping buf from free buf queue",
+ __func__);
+ return -ENOMEM;
+ }
+ msm_camera_io_w(addr,
+ vfe40_ctrl->share_ctrl->vfebase +
+ VFE_BUS_STATS_SKIN_WR_PING_ADDR);
+ spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
+ addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, MSM_STATS_TYPE_BHIST);
+ spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
+ if (!addr) {
+ pr_err("%s: dq ihist pong buf from free buf queue",
+ __func__);
+ return -ENOMEM;
+ }
+ msm_camera_io_w(addr,
+ vfe40_ctrl->share_ctrl->vfebase +
+ VFE_BUS_STATS_SKIN_WR_PONG_ADDR);
return 0;
}
static int vfe_stats_ihist_buf_init(
- struct vfe40_ctrl_type *vfe40_ctrl, struct vfe_cmd_stats_buf *in)
+ struct vfe40_ctrl_type *vfe40_ctrl)
{
uint32_t addr;
unsigned long flags;
@@ -558,7 +1205,7 @@
}
static int vfe_stats_rs_buf_init(
- struct vfe40_ctrl_type *vfe40_ctrl, struct vfe_cmd_stats_buf *in)
+ struct vfe40_ctrl_type *vfe40_ctrl)
{
uint32_t addr;
unsigned long flags;
@@ -587,7 +1234,7 @@
}
static int vfe_stats_cs_buf_init(
- struct vfe40_ctrl_type *vfe40_ctrl, struct vfe_cmd_stats_buf *in)
+ struct vfe40_ctrl_type *vfe40_ctrl)
{
uint32_t addr;
unsigned long flags;
@@ -614,39 +1261,45 @@
return 0;
}
+static void vfe40_cfg_qos_parms(struct vfe40_ctrl_type *vfe40_ctrl)
+{
+ void __iomem *vfebase = vfe40_ctrl->share_ctrl->vfebase;
+ msm_camera_io_w(0xAAAAAAAA, vfebase + VFE_0_BUS_BDG_QOS_CFG_0);
+ msm_camera_io_w(0xAAAAAAAA, vfebase + VFE_0_BUS_BDG_QOS_CFG_1);
+ msm_camera_io_w(0xAAAAAAAA, vfebase + VFE_0_BUS_BDG_QOS_CFG_2);
+ msm_camera_io_w(0xAAAAAAAA, vfebase + VFE_0_BUS_BDG_QOS_CFG_3);
+ msm_camera_io_w(0xAAAAAAAA, vfebase + VFE_0_BUS_BDG_QOS_CFG_4);
+ msm_camera_io_w(0xAAAAAAAA, vfebase + VFE_0_BUS_BDG_QOS_CFG_5);
+ msm_camera_io_w(0xAAAAAAAA, vfebase + VFE_0_BUS_BDG_QOS_CFG_6);
+ msm_camera_io_w(0x0002AAAA, vfebase + VFE_0_BUS_BDG_QOS_CFG_7);
+}
+
static void vfe40_start_common(struct vfe40_ctrl_type *vfe40_ctrl)
{
- uint32_t irq_mask = 0x1E000011;
- vfe40_ctrl->start_ack_pending = TRUE;
+ uint16_t vfe_operation_mode =
+ vfe40_ctrl->share_ctrl->current_mode & ~(VFE_OUTPUTS_RDI0|
+ VFE_OUTPUTS_RDI1);
CDBG("VFE opertaion mode = 0x%x, output mode = 0x%x\n",
- vfe40_ctrl->share_ctrl->operation_mode,
+ vfe40_ctrl->share_ctrl->current_mode,
vfe40_ctrl->share_ctrl->outpath.output_mode);
- msm_camera_io_w(irq_mask,
- vfe40_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_0);
- msm_camera_io_w(VFE_IMASK_WHILE_STOPPING_1,
- vfe40_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_1);
+ vfe40_cfg_qos_parms(vfe40_ctrl);
- /* Ensure the write order while writing
- to the command register using the barrier */
- msm_camera_io_w_mb(1,
- vfe40_ctrl->share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
- msm_camera_io_w_mb(1,
- vfe40_ctrl->share_ctrl->vfebase + VFE_CAMIF_COMMAND);
+ msm_camera_io_w_mb(0x1,
+ vfe40_ctrl->share_ctrl->vfebase +
+ VFE_REG_UPDATE_CMD);
- msm_camera_io_dump(vfe40_ctrl->share_ctrl->vfebase,
- vfe40_ctrl->share_ctrl->register_total*4);
-
- atomic_set(&vfe40_ctrl->share_ctrl->vstate, 1);
+ if (vfe_operation_mode) {
+ msm_camera_io_w_mb(1, vfe40_ctrl->share_ctrl->vfebase +
+ VFE_CAMIF_COMMAND);
+ }
}
static int vfe40_start_recording(
struct msm_cam_media_controller *pmctl,
struct vfe40_ctrl_type *vfe40_ctrl)
{
- msm_camio_bus_scale_cfg(
- pmctl->sdata->pdata->cam_bus_scale_table, S_VIDEO);
- vfe40_ctrl->recording_state = VFE_STATE_START_REQUESTED;
+ vfe40_ctrl->share_ctrl->recording_state = VFE_STATE_START_REQUESTED;
msm_camera_io_w_mb(1,
vfe40_ctrl->share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
return 0;
@@ -656,11 +1309,9 @@
struct msm_cam_media_controller *pmctl,
struct vfe40_ctrl_type *vfe40_ctrl)
{
- vfe40_ctrl->recording_state = VFE_STATE_STOP_REQUESTED;
+ vfe40_ctrl->share_ctrl->recording_state = VFE_STATE_STOP_REQUESTED;
msm_camera_io_w_mb(1,
vfe40_ctrl->share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
- msm_camio_bus_scale_cfg(
- pmctl->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
return 0;
}
@@ -678,97 +1329,21 @@
share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
}
+static void vfe40_stop_liveshot(
+ struct msm_cam_media_controller *pmctl,
+ struct vfe40_ctrl_type *vfe40_ctrl)
+{
+ vfe40_ctrl->share_ctrl->liveshot_state = VFE_STATE_STOP_REQUESTED;
+ msm_camera_io_w_mb(1,
+ vfe40_ctrl->share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+}
+
static int vfe40_zsl(
struct msm_cam_media_controller *pmctl,
struct vfe40_ctrl_type *vfe40_ctrl)
{
- uint32_t irq_comp_mask = 0;
- /* capture command is valid for both idle and active state. */
- irq_comp_mask =
- msm_camera_io_r(vfe40_ctrl->
- share_ctrl->vfebase + VFE_IRQ_COMP_MASK);
-
- CDBG("%s:op mode %d O/P Mode %d\n", __func__,
- vfe40_ctrl->share_ctrl->operation_mode,
- vfe40_ctrl->share_ctrl->outpath.output_mode);
-
- if (vfe40_ctrl->share_ctrl->outpath.output_mode &
- VFE40_OUTPUT_MODE_PRIMARY) {
- irq_comp_mask |= (
- (0x1 << (vfe40_ctrl->share_ctrl->outpath.out0.ch0)) |
- (0x1 << (vfe40_ctrl->share_ctrl->outpath.out0.ch1)));
- } else if (vfe40_ctrl->share_ctrl->outpath.output_mode &
- VFE40_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
- irq_comp_mask |= (
- (0x1 << (vfe40_ctrl->share_ctrl->outpath.out0.ch0)) |
- (0x1 << (vfe40_ctrl->share_ctrl->outpath.out0.ch1)) |
- (0x1 << (vfe40_ctrl->share_ctrl->outpath.out0.ch2)));
- }
-
- if (vfe40_ctrl->share_ctrl->outpath.output_mode &
- VFE40_OUTPUT_MODE_SECONDARY) {
- irq_comp_mask |= ((0x1 << (vfe40_ctrl->
- share_ctrl->outpath.out1.ch0 + 8)) |
- (0x1 << (vfe40_ctrl->
- share_ctrl->outpath.out1.ch1 + 8)));
- } else if (vfe40_ctrl->share_ctrl->outpath.output_mode &
- VFE40_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
- irq_comp_mask |= (
- (0x1 << (vfe40_ctrl->
- share_ctrl->outpath.out1.ch0 + 8)) |
- (0x1 << (vfe40_ctrl->
- share_ctrl->outpath.out1.ch1 + 8)) |
- (0x1 << (vfe40_ctrl->
- share_ctrl->outpath.out1.ch2 + 8)));
- }
-
- if (vfe40_ctrl->share_ctrl->outpath.output_mode &
- VFE40_OUTPUT_MODE_PRIMARY) {
- msm_camera_io_w(1, vfe40_ctrl->share_ctrl->vfebase +
- vfe40_AXI_WM_CFG[vfe40_ctrl->
- share_ctrl->outpath.out0.ch0]);
- msm_camera_io_w(1, vfe40_ctrl->share_ctrl->vfebase +
- vfe40_AXI_WM_CFG[vfe40_ctrl->
- share_ctrl->outpath.out0.ch1]);
- } else if (vfe40_ctrl->share_ctrl->outpath.output_mode &
- VFE40_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
- msm_camera_io_w(1, vfe40_ctrl->share_ctrl->vfebase +
- vfe40_AXI_WM_CFG[vfe40_ctrl->
- share_ctrl->outpath.out0.ch0]);
- msm_camera_io_w(1, vfe40_ctrl->share_ctrl->vfebase +
- vfe40_AXI_WM_CFG[vfe40_ctrl->
- share_ctrl->outpath.out0.ch1]);
- msm_camera_io_w(1, vfe40_ctrl->share_ctrl->vfebase +
- vfe40_AXI_WM_CFG[vfe40_ctrl->
- share_ctrl->outpath.out0.ch2]);
- }
-
- if (vfe40_ctrl->share_ctrl->outpath.output_mode &
- VFE40_OUTPUT_MODE_SECONDARY) {
- msm_camera_io_w(1, vfe40_ctrl->share_ctrl->vfebase +
- vfe40_AXI_WM_CFG[vfe40_ctrl->
- share_ctrl->outpath.out1.ch0]);
- msm_camera_io_w(1, vfe40_ctrl->share_ctrl->vfebase +
- vfe40_AXI_WM_CFG[vfe40_ctrl->
- share_ctrl->outpath.out1.ch1]);
- } else if (vfe40_ctrl->share_ctrl->outpath.output_mode &
- VFE40_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
- msm_camera_io_w(1, vfe40_ctrl->share_ctrl->vfebase +
- vfe40_AXI_WM_CFG[vfe40_ctrl->
- share_ctrl->outpath.out1.ch0]);
- msm_camera_io_w(1, vfe40_ctrl->share_ctrl->vfebase +
- vfe40_AXI_WM_CFG[vfe40_ctrl->
- share_ctrl->outpath.out1.ch1]);
- msm_camera_io_w(1, vfe40_ctrl->share_ctrl->vfebase +
- vfe40_AXI_WM_CFG[vfe40_ctrl->
- share_ctrl->outpath.out1.ch2]);
- }
-
- msm_camera_io_w(irq_comp_mask,
- vfe40_ctrl->share_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+ vfe40_ctrl->share_ctrl->start_ack_pending = TRUE;
vfe40_start_common(vfe40_ctrl);
- msm_camio_bus_scale_cfg(
- pmctl->sdata->pdata->cam_bus_scale_table, S_ZSL);
msm_camera_io_w(1, vfe40_ctrl->share_ctrl->vfebase + 0x18C);
msm_camera_io_w(1, vfe40_ctrl->share_ctrl->vfebase + 0x188);
@@ -779,28 +1354,8 @@
struct vfe40_ctrl_type *vfe40_ctrl,
uint32_t num_frames_capture)
{
- uint32_t irq_comp_mask = 0;
-
vfe40_ctrl->share_ctrl->outpath.out0.capture_cnt = num_frames_capture;
vfe40_ctrl->share_ctrl->vfe_capture_count = num_frames_capture;
-
- irq_comp_mask =
- msm_camera_io_r(
- vfe40_ctrl->share_ctrl->vfebase + VFE_IRQ_COMP_MASK);
-
- if (vfe40_ctrl->share_ctrl->outpath.output_mode &
- VFE40_OUTPUT_MODE_PRIMARY) {
- irq_comp_mask |=
- (0x1 << (vfe40_ctrl->share_ctrl->outpath.out0.ch0));
- msm_camera_io_w(1, vfe40_ctrl->share_ctrl->vfebase +
- vfe40_AXI_WM_CFG[vfe40_ctrl->
- share_ctrl->outpath.out0.ch0]);
- }
-
- msm_camera_io_w(irq_comp_mask,
- vfe40_ctrl->share_ctrl->vfebase + VFE_IRQ_COMP_MASK);
- msm_camio_bus_scale_cfg(
- pmctl->sdata->pdata->cam_bus_scale_table, S_CAPTURE);
vfe40_start_common(vfe40_ctrl);
return 0;
}
@@ -810,75 +1365,24 @@
uint32_t num_frames_capture,
struct vfe40_ctrl_type *vfe40_ctrl)
{
- uint32_t irq_comp_mask = 0;
-
/* capture command is valid for both idle and active state. */
vfe40_ctrl->share_ctrl->outpath.out1.capture_cnt = num_frames_capture;
- if (vfe40_ctrl->share_ctrl->operation_mode ==
+ if (vfe40_ctrl->share_ctrl->current_mode ==
VFE_OUTPUTS_MAIN_AND_THUMB ||
- vfe40_ctrl->share_ctrl->operation_mode ==
+ vfe40_ctrl->share_ctrl->current_mode ==
VFE_OUTPUTS_THUMB_AND_MAIN ||
- vfe40_ctrl->share_ctrl->operation_mode ==
+ vfe40_ctrl->share_ctrl->current_mode ==
VFE_OUTPUTS_JPEG_AND_THUMB ||
- vfe40_ctrl->share_ctrl->operation_mode ==
+ vfe40_ctrl->share_ctrl->current_mode ==
VFE_OUTPUTS_THUMB_AND_JPEG) {
vfe40_ctrl->share_ctrl->outpath.out0.capture_cnt =
num_frames_capture;
}
vfe40_ctrl->share_ctrl->vfe_capture_count = num_frames_capture;
- irq_comp_mask = msm_camera_io_r(
- vfe40_ctrl->share_ctrl->vfebase + VFE_IRQ_COMP_MASK);
-
- if (vfe40_ctrl->share_ctrl->operation_mode ==
- VFE_OUTPUTS_MAIN_AND_THUMB ||
- vfe40_ctrl->share_ctrl->operation_mode ==
- VFE_OUTPUTS_JPEG_AND_THUMB ||
- vfe40_ctrl->share_ctrl->operation_mode ==
- VFE_OUTPUTS_THUMB_AND_MAIN) {
- if (vfe40_ctrl->share_ctrl->outpath.output_mode &
- VFE40_OUTPUT_MODE_PRIMARY) {
- irq_comp_mask |= (0x1 << vfe40_ctrl->
- share_ctrl->outpath.out0.ch0 |
- 0x1 << vfe40_ctrl->
- share_ctrl->outpath.out0.ch1);
- }
- if (vfe40_ctrl->share_ctrl->outpath.output_mode &
- VFE40_OUTPUT_MODE_SECONDARY) {
- irq_comp_mask |=
- (0x1 << (vfe40_ctrl->
- share_ctrl->outpath.out1.ch0 + 8) |
- 0x1 << (vfe40_ctrl->
- share_ctrl->outpath.out1.ch1 + 8));
- }
- if (vfe40_ctrl->share_ctrl->outpath.output_mode &
- VFE40_OUTPUT_MODE_PRIMARY) {
- msm_camera_io_w(1, vfe40_ctrl->share_ctrl->vfebase +
- vfe40_AXI_WM_CFG[vfe40_ctrl->
- share_ctrl->outpath.out0.ch0]);
- msm_camera_io_w(1, vfe40_ctrl->share_ctrl->vfebase +
- vfe40_AXI_WM_CFG[vfe40_ctrl->
- share_ctrl->outpath.out0.ch1]);
- }
- if (vfe40_ctrl->share_ctrl->outpath.output_mode &
- VFE40_OUTPUT_MODE_SECONDARY) {
- msm_camera_io_w(1, vfe40_ctrl->share_ctrl->vfebase +
- vfe40_AXI_WM_CFG[vfe40_ctrl->
- share_ctrl->outpath.out1.ch0]);
- msm_camera_io_w(1, vfe40_ctrl->share_ctrl->vfebase +
- vfe40_AXI_WM_CFG[vfe40_ctrl->
- share_ctrl->outpath.out1.ch1]);
- }
- }
vfe40_ctrl->share_ctrl->vfe_capture_count = num_frames_capture;
- msm_camera_io_w(irq_comp_mask,
- vfe40_ctrl->share_ctrl->vfebase + VFE_IRQ_COMP_MASK);
- msm_camera_io_r(vfe40_ctrl->share_ctrl->vfebase + VFE_IRQ_COMP_MASK);
- msm_camio_bus_scale_cfg(
- pmctl->sdata->pdata->cam_bus_scale_table, S_CAPTURE);
-
vfe40_start_common(vfe40_ctrl);
/* for debug */
msm_camera_io_w(1, vfe40_ctrl->share_ctrl->vfebase + 0x18C);
@@ -890,41 +1394,6 @@
struct msm_cam_media_controller *pmctl,
struct vfe40_ctrl_type *vfe40_ctrl)
{
- uint32_t irq_comp_mask = 0;
- irq_comp_mask =
- msm_camera_io_r(vfe40_ctrl->share_ctrl->vfebase +
- VFE_IRQ_COMP_MASK);
-
- if (vfe40_ctrl->share_ctrl->outpath.output_mode &
- VFE40_OUTPUT_MODE_PRIMARY) {
- irq_comp_mask |= (
- 0x1 << vfe40_ctrl->share_ctrl->outpath.out0.ch0 |
- 0x1 << vfe40_ctrl->share_ctrl->outpath.out0.ch1);
- } else if (vfe40_ctrl->share_ctrl->outpath.output_mode &
- VFE40_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
- irq_comp_mask |= (
- 0x1 << vfe40_ctrl->share_ctrl->outpath.out0.ch0 |
- 0x1 << vfe40_ctrl->share_ctrl->outpath.out0.ch1 |
- 0x1 << vfe40_ctrl->share_ctrl->outpath.out0.ch2);
- }
- if (vfe40_ctrl->share_ctrl->outpath.output_mode &
- VFE40_OUTPUT_MODE_SECONDARY) {
- irq_comp_mask |= (
- 0x1 << (vfe40_ctrl->share_ctrl->outpath.out1.ch0 + 8) |
- 0x1 << (vfe40_ctrl->share_ctrl->outpath.out1.ch1 + 8));
- } else if (vfe40_ctrl->share_ctrl->outpath.output_mode &
- VFE40_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
- irq_comp_mask |= (
- 0x1 << (vfe40_ctrl->share_ctrl->outpath.out1.ch0 + 8) |
- 0x1 << (vfe40_ctrl->share_ctrl->outpath.out1.ch1 + 8) |
- 0x1 << (vfe40_ctrl->share_ctrl->outpath.out1.ch2 + 8));
- }
- msm_camera_io_w(irq_comp_mask,
- vfe40_ctrl->share_ctrl->vfebase + VFE_IRQ_COMP_MASK);
-
- /*
- msm_camio_bus_scale_cfg(
- pmctl->sdata->pdata->cam_bus_scale_table, S_PREVIEW);*/
vfe40_start_common(vfe40_ctrl);
return 0;
}
@@ -967,9 +1436,9 @@
vfe40_ctrl->update_gamma = false;
}
- spin_lock_irqsave(&vfe40_ctrl->update_ack_lock, flags);
- vfe40_ctrl->update_ack_pending = TRUE;
- spin_unlock_irqrestore(&vfe40_ctrl->update_ack_lock, flags);
+ spin_lock_irqsave(&vfe40_ctrl->share_ctrl->update_ack_lock, flags);
+ vfe40_ctrl->share_ctrl->update_ack_pending = TRUE;
+ spin_unlock_irqrestore(&vfe40_ctrl->share_ctrl->update_ack_lock, flags);
/* Ensure the write order while writing
to the command register using the barrier */
msm_camera_io_w_mb(1,
@@ -1031,7 +1500,7 @@
8 + ((vfe40_ctrl->sync_timer_number) * 12));
/* Sync Timer Pixel Duration */
value = *tbl++;
- val = vfe40_ctrl->share_ctrl->vfe_clk_rate / 10000;
+ val = vfe_clk_rate / 10000;
val = 10000000 / val;
val = value * 10000 / val;
CDBG("%s: Pixel Clk Cycles!!! %d\n", __func__, val);
@@ -1048,19 +1517,7 @@
vfe40_ctrl->share_ctrl->vfebase + V40_TIMER_SELECT_OFF);
}
-static void vfe40_program_dmi_cfg(
- enum VFE40_DMI_RAM_SEL bankSel,
- struct vfe40_ctrl_type *vfe40_ctrl)
-{
- /* set bit 8 for auto increment. */
- uint32_t value = VFE_DMI_CFG_DEFAULT;
- value += (uint32_t)bankSel;
- CDBG("%s: banksel = %d\n", __func__, bankSel);
- msm_camera_io_w(value, vfe40_ctrl->share_ctrl->vfebase + VFE_DMI_CFG);
- /* by default, always starts with offset 0.*/
- msm_camera_io_w(0, vfe40_ctrl->share_ctrl->vfebase + VFE_DMI_ADDR);
-}
static void vfe40_write_gamma_cfg(
enum VFE40_DMI_RAM_SEL channel_sel,
const uint32_t *tbl,
@@ -1119,7 +1576,7 @@
vfe40_program_dmi_cfg(NO_MEM_SELECTED, vfe40_ctrl);
}
-struct vfe40_output_ch *vfe40_get_ch(
+static struct vfe40_output_ch *vfe40_get_ch(
int path, struct vfe_share_ctrl_t *share_ctrl)
{
struct vfe40_output_ch *ch = NULL;
@@ -1128,6 +1585,10 @@
ch = &share_ctrl->outpath.out0;
else if (path == VFE_MSG_OUTPUT_SECONDARY)
ch = &share_ctrl->outpath.out1;
+ else if (path == VFE_MSG_OUTPUT_TERTIARY1)
+ ch = &share_ctrl->outpath.out2;
+ else if (path == VFE_MSG_OUTPUT_TERTIARY2)
+ ch = &share_ctrl->outpath.out3;
else
pr_err("%s: Invalid path %d\n", __func__,
path);
@@ -1135,49 +1596,76 @@
BUG_ON(ch == NULL);
return ch;
}
+static struct msm_free_buf *vfe40_check_free_buffer(
+ int id, int path, struct axi_ctrl_t *axi_ctrl)
+{
+ struct vfe40_output_ch *outch = NULL;
+ struct msm_free_buf *b = NULL;
+ uint32_t inst_handle = 0;
-static int vfe40_configure_pingpong_buffers(
- int id, int path, struct vfe40_ctrl_type *vfe40_ctrl)
+ if (path == VFE_MSG_OUTPUT_PRIMARY)
+ inst_handle = axi_ctrl->share_ctrl->outpath.out0.inst_handle;
+ else if (path == VFE_MSG_OUTPUT_SECONDARY)
+ inst_handle = axi_ctrl->share_ctrl->outpath.out1.inst_handle;
+ else if (path == VFE_MSG_OUTPUT_TERTIARY1)
+ inst_handle = axi_ctrl->share_ctrl->outpath.out2.inst_handle;
+ else if (path == VFE_MSG_OUTPUT_TERTIARY2)
+ inst_handle = axi_ctrl->share_ctrl->outpath.out3.inst_handle;
+
+ vfe40_subdev_notify(id, path, inst_handle,
+ &axi_ctrl->subdev, axi_ctrl->share_ctrl);
+ outch = vfe40_get_ch(path, axi_ctrl->share_ctrl);
+ if (outch->free_buf.ch_paddr[0])
+ b = &outch->free_buf;
+ return b;
+}
+static int configure_pingpong_buffers(
+ int id, int path, struct axi_ctrl_t *axi_ctrl)
{
struct vfe40_output_ch *outch = NULL;
int rc = 0;
- uint32_t image_mode = 0;
+ uint32_t inst_handle = 0;
if (path == VFE_MSG_OUTPUT_PRIMARY)
- image_mode = vfe40_ctrl->share_ctrl->outpath.out0.image_mode;
- else
- image_mode = vfe40_ctrl->share_ctrl->outpath.out1.image_mode;
+ inst_handle = axi_ctrl->share_ctrl->outpath.out0.inst_handle;
+ else if (path == VFE_MSG_OUTPUT_SECONDARY)
+ inst_handle = axi_ctrl->share_ctrl->outpath.out1.inst_handle;
+ else if (path == VFE_MSG_OUTPUT_TERTIARY1)
+ inst_handle = axi_ctrl->share_ctrl->outpath.out2.inst_handle;
+ else if (path == VFE_MSG_OUTPUT_TERTIARY2)
+ inst_handle = axi_ctrl->share_ctrl->outpath.out3.inst_handle;
- vfe40_subdev_notify(id, path, image_mode,
- &vfe40_ctrl->subdev, vfe40_ctrl->share_ctrl);
- outch = vfe40_get_ch(path, vfe40_ctrl->share_ctrl);
+ vfe40_subdev_notify(id, path, inst_handle,
+ &axi_ctrl->subdev, axi_ctrl->share_ctrl);
+ outch = vfe40_get_ch(path, axi_ctrl->share_ctrl);
if (outch->ping.ch_paddr[0] && outch->pong.ch_paddr[0]) {
/* Configure Preview Ping Pong */
- CDBG("%s Configure ping/pong address for %d",
+ pr_info("%s Configure ping/pong address for %d",
__func__, path);
vfe40_put_ch_ping_addr(
- vfe40_ctrl->share_ctrl->vfebase, outch->ch0,
+ axi_ctrl->share_ctrl->vfebase, outch->ch0,
outch->ping.ch_paddr[0]);
vfe40_put_ch_pong_addr(
- vfe40_ctrl->share_ctrl->vfebase, outch->ch0,
+ axi_ctrl->share_ctrl->vfebase, outch->ch0,
outch->pong.ch_paddr[0]);
- if (vfe40_ctrl->share_ctrl->operation_mode !=
- VFE_OUTPUTS_RAW) {
+ if ((axi_ctrl->share_ctrl->current_mode !=
+ VFE_OUTPUTS_RAW) && (path != VFE_MSG_OUTPUT_TERTIARY1)
+ && (path != VFE_MSG_OUTPUT_TERTIARY2)) {
vfe40_put_ch_ping_addr(
- vfe40_ctrl->share_ctrl->vfebase, outch->ch1,
+ axi_ctrl->share_ctrl->vfebase, outch->ch1,
outch->ping.ch_paddr[1]);
vfe40_put_ch_pong_addr(
- vfe40_ctrl->share_ctrl->vfebase, outch->ch1,
+ axi_ctrl->share_ctrl->vfebase, outch->ch1,
outch->pong.ch_paddr[1]);
}
if (outch->ping.num_planes > 2)
vfe40_put_ch_ping_addr(
- vfe40_ctrl->share_ctrl->vfebase, outch->ch2,
+ axi_ctrl->share_ctrl->vfebase, outch->ch2,
outch->ping.ch_paddr[2]);
if (outch->pong.num_planes > 2)
vfe40_put_ch_pong_addr(
- vfe40_ctrl->share_ctrl->vfebase, outch->ch2,
+ axi_ctrl->share_ctrl->vfebase, outch->ch2,
outch->pong.ch_paddr[2]);
/* avoid stale info */
@@ -1207,7 +1695,7 @@
vfe40_program_dmi_cfg(NO_MEM_SELECTED, vfe40_ctrl);
}
-void vfe40_send_isp_msg(
+static void vfe40_send_isp_msg(
struct v4l2_subdev *sd,
uint32_t vfeFrameId,
uint32_t isp_msg_id)
@@ -1227,142 +1715,76 @@
struct vfe40_ctrl_type *vfe40_ctrl)
{
int i , rc = 0;
- uint32_t old_val = 0 , new_val = 0;
+ uint32_t old_val = 0 , new_val = 0, module_val = 0;
uint32_t *cmdp = NULL;
uint32_t *cmdp_local = NULL;
uint32_t snapshot_cnt = 0;
uint32_t temp1 = 0, temp2 = 0;
+ struct msm_camera_vfe_params_t vfe_params;
CDBG("vfe40_proc_general: cmdID = %s, length = %d\n",
vfe40_general_cmd[cmd->id], cmd->length);
switch (cmd->id) {
case VFE_CMD_RESET:
- CDBG("vfe40_proc_general: cmdID = %s\n",
+ pr_info("vfe40_proc_general: cmdID = %s\n",
vfe40_general_cmd[cmd->id]);
+ vfe40_ctrl->share_ctrl->vfe_reset_flag = true;
vfe40_reset(vfe40_ctrl);
break;
case VFE_CMD_START:
- CDBG("vfe40_proc_general: cmdID = %s\n",
+ pr_info("vfe40_proc_general: cmdID = %s\n",
vfe40_general_cmd[cmd->id]);
- if ((vfe40_ctrl->share_ctrl->operation_mode ==
- VFE_OUTPUTS_PREVIEW_AND_VIDEO) ||
- (vfe40_ctrl->share_ctrl->operation_mode ==
- VFE_OUTPUTS_PREVIEW))
- /* Configure primary channel */
- rc = vfe40_configure_pingpong_buffers(
- VFE_MSG_START, VFE_MSG_OUTPUT_PRIMARY,
- vfe40_ctrl);
- else
- /* Configure secondary channel */
- rc = vfe40_configure_pingpong_buffers(
- VFE_MSG_START, VFE_MSG_OUTPUT_SECONDARY,
- vfe40_ctrl);
- if (rc < 0) {
- pr_err(
- "%s error configuring pingpong buffers for preview",
- __func__);
- rc = -EINVAL;
- goto proc_general_done;
+ if (copy_from_user(&vfe_params,
+ (void __user *)(cmd->value),
+ sizeof(struct msm_camera_vfe_params_t))) {
+ rc = -EFAULT;
+ goto proc_general_done;
}
+ vfe40_ctrl->share_ctrl->current_mode =
+ vfe_params.operation_mode;
+
rc = vfe40_start(pmctl, vfe40_ctrl);
break;
case VFE_CMD_UPDATE:
vfe40_update(vfe40_ctrl);
break;
case VFE_CMD_CAPTURE_RAW:
- CDBG("%s: cmdID = VFE_CMD_CAPTURE_RAW\n", __func__);
- if (copy_from_user(&snapshot_cnt, (void __user *)(cmd->value),
- sizeof(uint32_t))) {
- rc = -EFAULT;
- goto proc_general_done;
+ pr_info("%s: cmdID = VFE_CMD_CAPTURE_RAW\n", __func__);
+ if (copy_from_user(&vfe_params,
+ (void __user *)(cmd->value),
+ sizeof(struct msm_camera_vfe_params_t))) {
+ rc = -EFAULT;
+ goto proc_general_done;
}
- rc = vfe40_configure_pingpong_buffers(
- VFE_MSG_CAPTURE, VFE_MSG_OUTPUT_PRIMARY,
- vfe40_ctrl);
- if (rc < 0) {
- pr_err(
- "%s error configuring pingpong buffers for snapshot",
- __func__);
- rc = -EINVAL;
- goto proc_general_done;
- }
+
+ snapshot_cnt = vfe_params.capture_count;
+ vfe40_ctrl->share_ctrl->current_mode =
+ vfe_params.operation_mode;
rc = vfe40_capture_raw(pmctl, vfe40_ctrl, snapshot_cnt);
break;
case VFE_CMD_CAPTURE:
- if (copy_from_user(&snapshot_cnt, (void __user *)(cmd->value),
- sizeof(uint32_t))) {
- rc = -EFAULT;
- goto proc_general_done;
+ pr_info("%s: cmdID = VFE_CMD_CAPTURE\n", __func__);
+ if (copy_from_user(&vfe_params,
+ (void __user *)(cmd->value),
+ sizeof(struct msm_camera_vfe_params_t))) {
+ rc = -EFAULT;
+ goto proc_general_done;
}
- if (vfe40_ctrl->share_ctrl->operation_mode ==
- VFE_OUTPUTS_JPEG_AND_THUMB ||
- vfe40_ctrl->share_ctrl->operation_mode ==
- VFE_OUTPUTS_THUMB_AND_JPEG) {
- if (snapshot_cnt != 1) {
- pr_err("only support 1 inline snapshot\n");
- rc = -EINVAL;
- goto proc_general_done;
- }
- /* Configure primary channel for JPEG */
- rc = vfe40_configure_pingpong_buffers(
- VFE_MSG_JPEG_CAPTURE,
- VFE_MSG_OUTPUT_PRIMARY,
- vfe40_ctrl);
- } else {
- /* Configure primary channel */
- rc = vfe40_configure_pingpong_buffers(
- VFE_MSG_CAPTURE,
- VFE_MSG_OUTPUT_PRIMARY,
- vfe40_ctrl);
- }
- if (rc < 0) {
- pr_err(
- "%s error configuring pingpong buffers for primary output",
- __func__);
- rc = -EINVAL;
- goto proc_general_done;
- }
- /* Configure secondary channel */
- rc = vfe40_configure_pingpong_buffers(
- VFE_MSG_CAPTURE, VFE_MSG_OUTPUT_SECONDARY,
- vfe40_ctrl);
- if (rc < 0) {
- pr_err(
- "%s error configuring pingpong buffers for secondary output",
- __func__);
- rc = -EINVAL;
- goto proc_general_done;
- }
+ snapshot_cnt = vfe_params.capture_count;
+ vfe40_ctrl->share_ctrl->current_mode =
+ vfe_params.operation_mode;
+
rc = vfe40_capture(pmctl, snapshot_cnt, vfe40_ctrl);
break;
case VFE_CMD_START_RECORDING:
- CDBG("vfe40_proc_general: cmdID = %s\n",
+ pr_info("vfe40_proc_general: cmdID = %s\n",
vfe40_general_cmd[cmd->id]);
- if (vfe40_ctrl->share_ctrl->operation_mode ==
- VFE_OUTPUTS_PREVIEW_AND_VIDEO)
- rc = vfe40_configure_pingpong_buffers(
- VFE_MSG_START_RECORDING,
- VFE_MSG_OUTPUT_SECONDARY,
- vfe40_ctrl);
- else if (vfe40_ctrl->share_ctrl->operation_mode ==
- VFE_OUTPUTS_VIDEO_AND_PREVIEW)
- rc = vfe40_configure_pingpong_buffers(
- VFE_MSG_START_RECORDING,
- VFE_MSG_OUTPUT_PRIMARY,
- vfe40_ctrl);
- if (rc < 0) {
- pr_err(
- "%s error configuring pingpong buffers for video\n",
- __func__);
- rc = -EINVAL;
- goto proc_general_done;
- }
rc = vfe40_start_recording(pmctl, vfe40_ctrl);
break;
case VFE_CMD_STOP_RECORDING:
- CDBG("vfe40_proc_general: cmdID = %s\n",
+ pr_info("vfe40_proc_general: cmdID = %s\n",
vfe40_general_cmd[cmd->id]);
rc = vfe40_stop_recording(pmctl, vfe40_ctrl);
break;
@@ -1383,7 +1805,12 @@
break;
case VFE_CMD_STATS_AE_START: {
- rc = vfe_stats_aec_buf_init(vfe40_ctrl, NULL);
+ if (vfe40_use_bayer_stats(vfe40_ctrl)) {
+ /* Error */
+ rc = -EFAULT;
+ goto proc_general_done;
+ }
+ rc = vfe_stats_aec_bg_buf_init(vfe40_ctrl);
if (rc < 0) {
pr_err("%s: cannot config ping/pong address of AEC",
__func__);
@@ -1412,7 +1839,12 @@
}
break;
case VFE_CMD_STATS_AF_START: {
- rc = vfe_stats_af_buf_init(vfe40_ctrl, NULL);
+ if (vfe40_use_bayer_stats(vfe40_ctrl)) {
+ /* Error */
+ rc = -EFAULT;
+ goto proc_general_done;
+ }
+ rc = vfe_stats_af_bf_buf_init(vfe40_ctrl);
if (rc < 0) {
pr_err("%s: cannot config ping/pong address of AF",
__func__);
@@ -1440,8 +1872,12 @@
cmdp, (vfe40_cmd[cmd->id].length));
}
break;
-
case VFE_CMD_STATS_AWB_START: {
+ if (vfe40_use_bayer_stats(vfe40_ctrl)) {
+ /* Error */
+ rc = -EFAULT;
+ goto proc_general_done;
+ }
rc = vfe_stats_awb_buf_init(vfe40_ctrl, NULL);
if (rc < 0) {
pr_err("%s: cannot config ping/pong address of AWB",
@@ -1472,7 +1908,7 @@
break;
case VFE_CMD_STATS_IHIST_START: {
- rc = vfe_stats_ihist_buf_init(vfe40_ctrl, NULL);
+ rc = vfe_stats_ihist_buf_init(vfe40_ctrl);
if (rc < 0) {
pr_err("%s: cannot config ping/pong address of IHIST",
__func__);
@@ -1503,7 +1939,7 @@
case VFE_CMD_STATS_RS_START: {
- rc = vfe_stats_rs_buf_init(vfe40_ctrl, NULL);
+ rc = vfe_stats_rs_buf_init(vfe40_ctrl);
if (rc < 0) {
pr_err("%s: cannot config ping/pong address of RS",
__func__);
@@ -1528,7 +1964,7 @@
break;
case VFE_CMD_STATS_CS_START: {
- rc = vfe_stats_cs_buf_init(vfe40_ctrl, NULL);
+ rc = vfe_stats_cs_buf_init(vfe40_ctrl);
if (rc < 0) {
pr_err("%s: cannot config ping/pong address of CS",
__func__);
@@ -1552,6 +1988,65 @@
}
break;
+ case VFE_CMD_STATS_BG_START:
+ case VFE_CMD_STATS_BF_START:
+ case VFE_CMD_STATS_BHIST_START: {
+ if (!vfe40_use_bayer_stats(vfe40_ctrl)) {
+ /* Error */
+ rc = -EFAULT;
+ goto proc_general_done;
+ }
+ old_val = msm_camera_io_r(
+ vfe40_ctrl->share_ctrl->vfebase + VFE_STATS_CFG);
+ module_val = msm_camera_io_r(
+ vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+ if (VFE_CMD_STATS_BG_START == cmd->id) {
+ module_val |= BG_ENABLE_MASK;
+ rc = vfe_stats_aec_bg_buf_init(vfe40_ctrl);
+ if (rc < 0) {
+ pr_err("%s: cannot config ping/pong address of CS",
+ __func__);
+ goto proc_general_done;
+ }
+ } else if (VFE_CMD_STATS_BF_START == cmd->id) {
+ module_val |= BF_ENABLE_MASK;
+ rc = vfe_stats_af_bf_buf_init(vfe40_ctrl);
+ if (rc < 0) {
+ pr_err("%s: cannot config ping/pong address of CS",
+ __func__);
+ goto proc_general_done;
+ }
+ } else {
+ module_val |= BHIST_ENABLE_MASK;
+ old_val |= STATS_BHIST_ENABLE_MASK;
+ rc = vfe_stats_bhist_buf_init(vfe40_ctrl);
+ if (rc < 0) {
+ pr_err("%s: cannot config ping/pong address of CS",
+ __func__);
+ goto proc_general_done;
+ }
+ }
+ msm_camera_io_w(old_val, vfe40_ctrl->share_ctrl->vfebase +
+ VFE_STATS_CFG);
+ msm_camera_io_w(module_val,
+ vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+ cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+ if (!cmdp) {
+ rc = -ENOMEM;
+ goto proc_general_done;
+ }
+ if (copy_from_user(cmdp,
+ (void __user *)(cmd->value),
+ cmd->length)) {
+ rc = -EFAULT;
+ goto proc_general_done;
+ }
+ msm_camera_io_memcpy(
+ vfe40_ctrl->share_ctrl->vfebase +
+ vfe40_cmd[cmd->id].offset,
+ cmdp, (vfe40_cmd[cmd->id].length));
+ }
+ break;
case VFE_CMD_MCE_UPDATE:
case VFE_CMD_MCE_CFG:{
cmdp = kmalloc(cmd->length, GFP_ATOMIC);
@@ -1638,6 +2133,38 @@
rc = -EFAULT;
goto proc_general_done;
+ case VFE_CMD_MESH_ROLL_OFF_CFG: {
+ cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+ if (!cmdp) {
+ rc = -ENOMEM;
+ goto proc_general_done;
+ }
+ if (copy_from_user(cmdp,
+ (void __user *)(cmd->value) , cmd->length)) {
+ rc = -EFAULT;
+ goto proc_general_done;
+ }
+ cmdp_local = cmdp;
+ msm_camera_io_memcpy(
+ vfe40_ctrl->share_ctrl->vfebase +
+ vfe40_cmd[cmd->id].offset,
+ cmdp_local, V40_MESH_ROLL_OFF_CFG_LEN);
+ cmdp_local += 9;
+ vfe40_program_dmi_cfg(ROLLOFF_RAM0_BANK0, vfe40_ctrl);
+ /* for loop for extrcting table. */
+ for (i = 0; i < (V40_MESH_ROLL_OFF_TABLE_SIZE * 2); i++) {
+ msm_camera_io_w(*cmdp_local,
+ vfe40_ctrl->share_ctrl->vfebase +
+ VFE_DMI_DATA_LO);
+ cmdp_local++;
+ }
+ CDBG("done writing mesh table\n");
+ vfe40_program_dmi_cfg(NO_MEM_SELECTED, vfe40_ctrl);
+ }
+ break;
+ case VFE_CMD_GET_MESH_ROLLOFF_TABLE:
+ break;
+
case VFE_CMD_LA_CFG:
cmdp = kmalloc(cmd->length, GFP_ATOMIC);
if (!cmdp) {
@@ -1746,15 +2273,6 @@
case VFE_CMD_LIVESHOT:
/* Configure primary channel */
- rc = vfe40_configure_pingpong_buffers(VFE_MSG_CAPTURE,
- VFE_MSG_OUTPUT_PRIMARY, vfe40_ctrl);
- if (rc < 0) {
- pr_err(
- "%s error configuring pingpong buffers for primary output\n",
- __func__);
- rc = -EINVAL;
- goto proc_general_done;
- }
vfe40_start_liveshot(pmctl, vfe40_ctrl);
break;
@@ -1774,7 +2292,6 @@
vfe40_ctrl->share_ctrl->vfebase +
V40_LINEARIZATION_OFF1,
cmdp_local, V40_LINEARIZATION_LEN1);
-
cmdp_local = cmdp + 17;
vfe40_write_linear_cfg(BLACK_LUT_RAM_BANK0,
cmdp_local, vfe40_ctrl);
@@ -2126,6 +2643,11 @@
break;
case VFE_CMD_STATS_AWB_STOP: {
+ if (vfe40_use_bayer_stats(vfe40_ctrl)) {
+ /* Error */
+ rc = -EFAULT;
+ goto proc_general_done;
+ }
old_val = msm_camera_io_r(
vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
old_val &= ~AWB_ENABLE_MASK;
@@ -2133,27 +2655,30 @@
vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
}
break;
-
case VFE_CMD_STATS_AE_STOP: {
+ if (vfe40_use_bayer_stats(vfe40_ctrl)) {
+ /* Error */
+ rc = -EFAULT;
+ goto proc_general_done;
+ }
old_val = msm_camera_io_r(
vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
- old_val &= ~BG_ENABLE_MASK;
+ old_val &= BG_ENABLE_MASK;
msm_camera_io_w(old_val,
vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
}
break;
case VFE_CMD_STATS_AF_STOP: {
+ if (vfe40_use_bayer_stats(vfe40_ctrl)) {
+ /* Error */
+ rc = -EFAULT;
+ goto proc_general_done;
+ }
old_val = msm_camera_io_r(
vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
old_val &= ~BF_ENABLE_MASK;
msm_camera_io_w(old_val,
vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
- rc = vfe40_stats_flush_enqueue(vfe40_ctrl, MSM_STATS_TYPE_AF);
- if (rc < 0) {
- pr_err("%s: dq stats buf err = %d",
- __func__, rc);
- return -EINVAL;
- }
}
break;
@@ -2183,9 +2708,47 @@
vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
}
break;
+
+ case VFE_CMD_STATS_BG_STOP:
+ case VFE_CMD_STATS_BF_STOP:
+ case VFE_CMD_STATS_BHIST_STOP: {
+ if (!vfe40_use_bayer_stats(vfe40_ctrl)) {
+ /* Error */
+ rc = -EFAULT;
+ goto proc_general_done;
+ }
+ old_val = msm_camera_io_r(
+ vfe40_ctrl->share_ctrl->vfebase + VFE_STATS_CFG);
+
+ if (VFE_CMD_STATS_BHIST_STOP == cmd->id)
+ old_val &= ~STATS_BHIST_ENABLE_MASK;
+
+ msm_camera_io_w(old_val,
+ vfe40_ctrl->share_ctrl->vfebase + VFE_STATS_CFG);
+ if (VFE_CMD_STATS_BF_STOP == cmd->id) {
+ rc = vfe40_stats_flush_enqueue(vfe40_ctrl,
+ MSM_STATS_TYPE_BF);
+ if (rc < 0) {
+ pr_err("%s: dq stats buf err = %d",
+ __func__, rc);
+ return -EINVAL;
+ }
+ }
+ }
+ break;
+
case VFE_CMD_STOP:
- CDBG("vfe40_proc_general: cmdID = %s\n",
+ pr_info("vfe40_proc_general: cmdID = %s\n",
vfe40_general_cmd[cmd->id]);
+ if (copy_from_user(&vfe_params,
+ (void __user *)(cmd->value),
+ sizeof(struct msm_camera_vfe_params_t))) {
+ rc = -EFAULT;
+ goto proc_general_done;
+ }
+
+ vfe40_ctrl->share_ctrl->current_mode =
+ vfe_params.operation_mode;
vfe40_stop(vfe40_ctrl);
break;
@@ -2229,14 +2792,15 @@
break;
case VFE_CMD_ZSL:
- rc = vfe40_configure_pingpong_buffers(VFE_MSG_START,
- VFE_MSG_OUTPUT_PRIMARY, vfe40_ctrl);
- if (rc < 0)
- goto proc_general_done;
- rc = vfe40_configure_pingpong_buffers(VFE_MSG_START,
- VFE_MSG_OUTPUT_SECONDARY, vfe40_ctrl);
- if (rc < 0)
- goto proc_general_done;
+ if (copy_from_user(&vfe_params,
+ (void __user *)(cmd->value),
+ sizeof(struct msm_camera_vfe_params_t))) {
+ rc = -EFAULT;
+ goto proc_general_done;
+ }
+
+ vfe40_ctrl->share_ctrl->current_mode =
+ vfe_params.operation_mode;
rc = vfe40_zsl(pmctl, vfe40_ctrl);
break;
@@ -2331,6 +2895,10 @@
*cmdp & VFE_FRAME_SKIP_PERIOD_MASK) + 1;
vfe40_ctrl->frame_skip_pattern = (uint32_t)(*(cmdp + 2));
break;
+ case VFE_CMD_STOP_LIVESHOT:
+ CDBG("%s Stopping liveshot ", __func__);
+ vfe40_stop_liveshot(pmctl, vfe40_ctrl);
+ break;
default:
if (cmd->length != vfe40_cmd[cmd->id].length)
return -EINVAL;
@@ -2389,221 +2957,505 @@
}
+void axi_stop_pix(struct vfe_share_ctrl_t *share_ctrl)
+{
+ uint32_t operation_mode =
+ share_ctrl->current_mode & ~(VFE_OUTPUTS_RDI0|
+ VFE_OUTPUTS_RDI1);
+ uint32_t irq_comp_mask, irq_mask;
+ uint32_t reg_update = 0x1;
+
+ irq_comp_mask =
+ msm_camera_io_r(share_ctrl->vfebase +
+ VFE_IRQ_COMP_MASK);
+ irq_mask = msm_camera_io_r(share_ctrl->vfebase +
+ VFE_IRQ_MASK_0);
+
+ switch (share_ctrl->cmd_type) {
+ case AXI_CMD_PREVIEW: {
+ switch (operation_mode) {
+ case VFE_OUTPUTS_PREVIEW:
+ case VFE_OUTPUTS_PREVIEW_AND_VIDEO:
+ if (share_ctrl->comp_output_mode &
+ VFE40_OUTPUT_MODE_PRIMARY) {
+ msm_camera_io_w(0, share_ctrl->vfebase
+ + vfe40_AXI_WM_CFG[share_ctrl->
+ outpath.out0.ch0]);
+ msm_camera_io_w(0, share_ctrl->vfebase
+ + vfe40_AXI_WM_CFG[share_ctrl->
+ outpath.out0.ch1]);
+ irq_comp_mask &= ~(
+ 0x1 << share_ctrl->outpath.out0.ch0 |
+ 0x1 << share_ctrl->outpath.out0.ch1);
+ share_ctrl->outpath.output_mode |=
+ VFE40_OUTPUT_MODE_PRIMARY;
+ } else if (share_ctrl->comp_output_mode &
+ VFE40_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
+ msm_camera_io_w(0, share_ctrl->vfebase
+ + vfe40_AXI_WM_CFG[share_ctrl->
+ outpath.out0.ch0]);
+ msm_camera_io_w(0, share_ctrl->vfebase
+ + vfe40_AXI_WM_CFG[share_ctrl->
+ outpath.out0.ch1]);
+ msm_camera_io_w(0, share_ctrl->vfebase
+ + vfe40_AXI_WM_CFG[share_ctrl->
+ outpath.out0.ch2]);
+ irq_comp_mask &= ~(
+ 0x1 << share_ctrl->outpath.out0.ch0 |
+ 0x1 << share_ctrl->outpath.out0.ch1 |
+ 0x1 << share_ctrl->outpath.out0.ch2);
+ share_ctrl->outpath.output_mode |=
+ VFE40_OUTPUT_MODE_PRIMARY_ALL_CHNLS;
+ }
+ irq_mask &= ~VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK;
+ break;
+ default:
+ if (share_ctrl->comp_output_mode &
+ VFE40_OUTPUT_MODE_SECONDARY) {
+ msm_camera_io_w(0, share_ctrl->vfebase
+ + vfe40_AXI_WM_CFG[share_ctrl->
+ outpath.out1.ch0]);
+ msm_camera_io_w(0, share_ctrl->vfebase
+ + vfe40_AXI_WM_CFG[share_ctrl->
+ outpath.out1.ch1]);
+ irq_comp_mask &= ~(
+ 0x1 << share_ctrl->outpath.out1.ch0 |
+ 0x1 << share_ctrl->outpath.out1.ch1);
+ share_ctrl->outpath.output_mode |=
+ VFE40_OUTPUT_MODE_SECONDARY;
+ } else if (share_ctrl->comp_output_mode &
+ VFE40_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
+ msm_camera_io_w(0, share_ctrl->vfebase
+ + vfe40_AXI_WM_CFG[share_ctrl->
+ outpath.out1.ch0]);
+ msm_camera_io_w(0, share_ctrl->vfebase
+ + vfe40_AXI_WM_CFG[share_ctrl->
+ outpath.out1.ch1]);
+ msm_camera_io_w(0, share_ctrl->vfebase
+ + vfe40_AXI_WM_CFG[share_ctrl->
+ outpath.out1.ch2]);
+ irq_comp_mask &= ~(
+ 0x1 << share_ctrl->outpath.out1.ch0 |
+ 0x1 << share_ctrl->outpath.out1.ch1 |
+ 0x1 << share_ctrl->outpath.out1.ch2);
+ share_ctrl->outpath.output_mode |=
+ VFE40_OUTPUT_MODE_SECONDARY_ALL_CHNLS;
+ }
+ irq_mask &= ~VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK;
+ break;
+ }
+ }
+ break;
+ default:
+ if (share_ctrl->comp_output_mode &
+ VFE40_OUTPUT_MODE_PRIMARY) {
+ msm_camera_io_w(0, share_ctrl->vfebase +
+ vfe40_AXI_WM_CFG[share_ctrl->
+ outpath.out0.ch0]);
+ msm_camera_io_w(0, share_ctrl->vfebase +
+ vfe40_AXI_WM_CFG[share_ctrl->
+ outpath.out0.ch1]);
+ irq_comp_mask &= ~(
+ 0x1 << share_ctrl->outpath.out0.ch0 |
+ 0x1 << share_ctrl->outpath.out0.ch1);
+ irq_mask &= ~VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK;
+ share_ctrl->outpath.output_mode |=
+ VFE40_OUTPUT_MODE_PRIMARY;
+ } else if (share_ctrl->comp_output_mode &
+ VFE40_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
+ msm_camera_io_w(0, share_ctrl->vfebase +
+ vfe40_AXI_WM_CFG[share_ctrl->
+ outpath.out0.ch0]);
+ msm_camera_io_w(0, share_ctrl->vfebase +
+ vfe40_AXI_WM_CFG[share_ctrl->
+ outpath.out0.ch1]);
+ msm_camera_io_w(0, share_ctrl->vfebase +
+ vfe40_AXI_WM_CFG[share_ctrl->
+ outpath.out0.ch2]);
+ irq_comp_mask &= ~(
+ 0x1 << share_ctrl->outpath.out0.ch0 |
+ 0x1 << share_ctrl->outpath.out0.ch1 |
+ 0x1 << share_ctrl->outpath.out0.ch2);
+ irq_mask &= ~VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK;
+ share_ctrl->outpath.output_mode |=
+ VFE40_OUTPUT_MODE_PRIMARY_ALL_CHNLS;
+ }
+
+ if (share_ctrl->comp_output_mode &
+ VFE40_OUTPUT_MODE_SECONDARY) {
+ msm_camera_io_w(0, share_ctrl->vfebase +
+ vfe40_AXI_WM_CFG[share_ctrl->
+ outpath.out1.ch0]);
+ msm_camera_io_w(0, share_ctrl->vfebase +
+ vfe40_AXI_WM_CFG[share_ctrl->outpath.out1.ch1]);
+ irq_comp_mask &= ~(
+ 0x1 << share_ctrl->outpath.out1.ch0 |
+ 0x1 << share_ctrl->outpath.out1.ch1);
+ irq_mask &= ~VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK;
+ share_ctrl->outpath.output_mode |=
+ VFE40_OUTPUT_MODE_SECONDARY;
+ } else if (share_ctrl->comp_output_mode &
+ VFE40_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
+ msm_camera_io_w(0, share_ctrl->vfebase +
+ vfe40_AXI_WM_CFG[share_ctrl->outpath.out1.ch0]);
+ msm_camera_io_w(0, share_ctrl->vfebase +
+ vfe40_AXI_WM_CFG[share_ctrl->outpath.out1.ch1]);
+ msm_camera_io_w(0, share_ctrl->vfebase +
+ vfe40_AXI_WM_CFG[share_ctrl->outpath.out1.ch2]);
+ irq_comp_mask &= ~(
+ 0x1 << share_ctrl->outpath.out1.ch0 |
+ 0x1 << share_ctrl->outpath.out1.ch1 |
+ 0x1 << share_ctrl->outpath.out1.ch2);
+ irq_mask &= ~VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK;
+ share_ctrl->outpath.output_mode |=
+ VFE40_OUTPUT_MODE_SECONDARY_ALL_CHNLS;
+ }
+ break;
+ }
+
+ msm_camera_io_w_mb(reg_update,
+ share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+ msm_camera_io_w(irq_comp_mask,
+ share_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+ msm_camera_io_w(irq_mask, share_ctrl->vfebase +
+ VFE_IRQ_MASK_0);
+}
+
+void axi_stop_rdi0(struct vfe_share_ctrl_t *share_ctrl)
+{
+ uint32_t reg_update = 0x2;
+ uint32_t irq_mask;
+ irq_mask = msm_camera_io_r(share_ctrl->vfebase +
+ VFE_IRQ_MASK_0);
+
+ if (share_ctrl->current_mode & VFE_OUTPUTS_RDI0) {
+ msm_camera_io_w(0, share_ctrl->vfebase +
+ vfe40_AXI_WM_CFG[share_ctrl->outpath.out2.ch0]);
+ irq_mask &= ~(0x1 << (share_ctrl->outpath.out2.ch0 +
+ VFE_WM_OFFSET));
+ }
+ msm_camera_io_w_mb(reg_update,
+ share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+ msm_camera_io_w(irq_mask, share_ctrl->vfebase +
+ VFE_IRQ_MASK_0);
+}
+
+void axi_stop_rdi1(struct vfe_share_ctrl_t *share_ctrl)
+{
+ uint32_t reg_update = 0x4;
+ uint32_t irq_mask;
+ irq_mask = msm_camera_io_r(share_ctrl->vfebase +
+ VFE_IRQ_MASK_0);
+
+ if (share_ctrl->current_mode & VFE_OUTPUTS_RDI1) {
+ msm_camera_io_w(1, share_ctrl->vfebase +
+ vfe40_AXI_WM_CFG[share_ctrl->outpath.out3.ch0]);
+ irq_mask &= ~(0x1 << (share_ctrl->outpath.out3.ch0 +
+ VFE_WM_OFFSET));
+ }
+
+ msm_camera_io_w_mb(reg_update,
+ share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+ msm_camera_io_w(irq_mask, share_ctrl->vfebase +
+ VFE_IRQ_MASK_0);
+}
+
+void axi_stop_process(struct vfe_share_ctrl_t *share_ctrl)
+{
+ uint32_t operation_mode =
+ share_ctrl->current_mode & ~(VFE_OUTPUTS_RDI0|
+ VFE_OUTPUTS_RDI1);
+
+ if (share_ctrl->current_mode & VFE_OUTPUTS_RDI0) {
+ axi_stop_rdi0(share_ctrl);
+ share_ctrl->comp_output_mode &= ~VFE40_OUTPUT_MODE_TERTIARY1;
+ }
+ if (share_ctrl->current_mode & VFE_OUTPUTS_RDI1) {
+ axi_stop_rdi1(share_ctrl);
+ share_ctrl->comp_output_mode &= ~VFE40_OUTPUT_MODE_TERTIARY2;
+ }
+ if (operation_mode) {
+ axi_stop_pix(share_ctrl);
+ share_ctrl->comp_output_mode &=
+ ~(share_ctrl->outpath.output_mode);
+ }
+}
+
static void vfe40_process_reg_update_irq(
struct vfe40_ctrl_type *vfe40_ctrl)
{
unsigned long flags;
+ struct vfe_share_ctrl_t *share_ctrl = vfe40_ctrl->share_ctrl;
- if (vfe40_ctrl->recording_state == VFE_STATE_START_REQUESTED) {
- if (vfe40_ctrl->share_ctrl->operation_mode ==
+ if (atomic_cmpxchg(
+ &share_ctrl->pix0_update_ack_pending, 2, 0) == 2) {
+ axi_stop_pix(share_ctrl);
+ msm_camera_io_w_mb(
+ CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
+ share_ctrl->vfebase + VFE_CAMIF_COMMAND);
+ axi_disable_irq(share_ctrl);
+ vfe40_send_isp_msg(&vfe40_ctrl->subdev,
+ share_ctrl->vfeFrameId,
+ MSG_ID_PIX0_UPDATE_ACK);
+ share_ctrl->comp_output_mode &=
+ ~(share_ctrl->outpath.output_mode);
+ share_ctrl->current_mode &=
+ (VFE_OUTPUTS_RDI0|VFE_OUTPUTS_RDI0);
+ } else {
+ if (share_ctrl->recording_state == VFE_STATE_START_REQUESTED) {
+ if (share_ctrl->operation_mode &
VFE_OUTPUTS_VIDEO_AND_PREVIEW) {
- msm_camera_io_w(1, vfe40_ctrl->share_ctrl->vfebase +
- vfe40_AXI_WM_CFG[vfe40_ctrl->
+ msm_camera_io_w(1,
+ share_ctrl->vfebase + vfe40_AXI_WM_CFG[
share_ctrl->outpath.out0.ch0]);
- msm_camera_io_w(1, vfe40_ctrl->share_ctrl->vfebase +
- vfe40_AXI_WM_CFG[vfe40_ctrl->
+ msm_camera_io_w(1,
+ share_ctrl->vfebase + vfe40_AXI_WM_CFG[
share_ctrl->outpath.out0.ch1]);
- } else if (vfe40_ctrl->share_ctrl->operation_mode ==
+ } else if (share_ctrl->operation_mode &
VFE_OUTPUTS_PREVIEW_AND_VIDEO) {
- msm_camera_io_w(1, vfe40_ctrl->share_ctrl->vfebase +
- vfe40_AXI_WM_CFG[vfe40_ctrl->
+ msm_camera_io_w(1,
+ share_ctrl->vfebase + vfe40_AXI_WM_CFG[
share_ctrl->outpath.out1.ch0]);
- msm_camera_io_w(1, vfe40_ctrl->share_ctrl->vfebase +
- vfe40_AXI_WM_CFG[vfe40_ctrl->
+ msm_camera_io_w(1,
+ share_ctrl->vfebase + vfe40_AXI_WM_CFG[
share_ctrl->outpath.out1.ch1]);
}
- vfe40_ctrl->recording_state = VFE_STATE_STARTED;
+ share_ctrl->recording_state = VFE_STATE_STARTED;
msm_camera_io_w_mb(1,
- vfe40_ctrl->share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+ share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
CDBG("start video triggered .\n");
- } else if (vfe40_ctrl->recording_state ==
+ } else if (share_ctrl->recording_state ==
VFE_STATE_STOP_REQUESTED) {
- if (vfe40_ctrl->share_ctrl->operation_mode ==
+ if (share_ctrl->operation_mode &
VFE_OUTPUTS_VIDEO_AND_PREVIEW) {
- msm_camera_io_w(0, vfe40_ctrl->share_ctrl->vfebase +
- vfe40_AXI_WM_CFG[vfe40_ctrl->
+ msm_camera_io_w(0,
+ share_ctrl->vfebase + vfe40_AXI_WM_CFG[
share_ctrl->outpath.out0.ch0]);
- msm_camera_io_w(0, vfe40_ctrl->share_ctrl->vfebase +
- vfe40_AXI_WM_CFG[vfe40_ctrl->
+ msm_camera_io_w(0,
+ share_ctrl->vfebase + vfe40_AXI_WM_CFG[
share_ctrl->outpath.out0.ch1]);
- } else if (vfe40_ctrl->share_ctrl->operation_mode ==
+ } else if (share_ctrl->operation_mode &
VFE_OUTPUTS_PREVIEW_AND_VIDEO) {
- msm_camera_io_w(0, vfe40_ctrl->share_ctrl->vfebase +
- vfe40_AXI_WM_CFG[vfe40_ctrl->
+ msm_camera_io_w(0,
+ share_ctrl->vfebase + vfe40_AXI_WM_CFG[
share_ctrl->outpath.out1.ch0]);
- msm_camera_io_w(0, vfe40_ctrl->share_ctrl->vfebase +
- vfe40_AXI_WM_CFG[vfe40_ctrl->
+ msm_camera_io_w(0,
+ share_ctrl->vfebase + vfe40_AXI_WM_CFG[
share_ctrl->outpath.out1.ch1]);
}
CDBG("stop video triggered .\n");
}
- if (vfe40_ctrl->start_ack_pending == TRUE) {
+ if (atomic_cmpxchg(
+ &share_ctrl->pix0_update_ack_pending, 1, 0) == 1) {
+ share_ctrl->comp_output_mode |=
+ (share_ctrl->outpath.output_mode
+ & ~(VFE40_OUTPUT_MODE_TERTIARY1|
+ VFE40_OUTPUT_MODE_TERTIARY2));
vfe40_send_isp_msg(&vfe40_ctrl->subdev,
- vfe40_ctrl->share_ctrl->vfeFrameId, MSG_ID_START_ACK);
- vfe40_ctrl->start_ack_pending = FALSE;
+ share_ctrl->vfeFrameId, MSG_ID_PIX0_UPDATE_ACK);
+ share_ctrl->current_mode &=
+ (VFE_OUTPUTS_RDI0|VFE_OUTPUTS_RDI0);
} else {
- if (vfe40_ctrl->recording_state ==
- VFE_STATE_STOP_REQUESTED) {
- vfe40_ctrl->recording_state = VFE_STATE_STOPPED;
+ if (share_ctrl->recording_state ==
+ VFE_STATE_STOP_REQUESTED) {
+ share_ctrl->recording_state = VFE_STATE_STOPPED;
/* request a reg update and send STOP_REC_ACK
* when we process the next reg update irq.
*/
- msm_camera_io_w_mb(1,
- vfe40_ctrl->share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
- } else if (vfe40_ctrl->recording_state ==
+ msm_camera_io_w_mb(1, share_ctrl->vfebase +
+ VFE_REG_UPDATE_CMD);
+ } else if (share_ctrl->recording_state ==
VFE_STATE_STOPPED) {
vfe40_send_isp_msg(&vfe40_ctrl->subdev,
- vfe40_ctrl->share_ctrl->vfeFrameId,
+ share_ctrl->vfeFrameId,
MSG_ID_STOP_REC_ACK);
- vfe40_ctrl->recording_state = VFE_STATE_IDLE;
+ share_ctrl->recording_state = VFE_STATE_IDLE;
}
- spin_lock_irqsave(&vfe40_ctrl->update_ack_lock, flags);
- if (vfe40_ctrl->update_ack_pending == TRUE) {
- vfe40_ctrl->update_ack_pending = FALSE;
+ spin_lock_irqsave(&share_ctrl->update_ack_lock, flags);
+ if (share_ctrl->update_ack_pending == TRUE) {
+ share_ctrl->update_ack_pending = FALSE;
spin_unlock_irqrestore(
- &vfe40_ctrl->update_ack_lock, flags);
+ &share_ctrl->update_ack_lock, flags);
vfe40_send_isp_msg(&vfe40_ctrl->subdev,
- vfe40_ctrl->share_ctrl->vfeFrameId,
- MSG_ID_UPDATE_ACK);
+ share_ctrl->vfeFrameId, MSG_ID_UPDATE_ACK);
} else {
spin_unlock_irqrestore(
- &vfe40_ctrl->update_ack_lock, flags);
+ &share_ctrl->update_ack_lock, flags);
}
}
- if (vfe40_ctrl->share_ctrl->liveshot_state ==
- VFE_STATE_START_REQUESTED) {
+ switch (share_ctrl->liveshot_state) {
+ case VFE_STATE_START_REQUESTED:
CDBG("%s enabling liveshot output\n", __func__);
- if (vfe40_ctrl->share_ctrl->outpath.output_mode &
- VFE40_OUTPUT_MODE_PRIMARY) {
- msm_camera_io_w(1, vfe40_ctrl->share_ctrl->vfebase +
- vfe40_AXI_WM_CFG[vfe40_ctrl->
+ if (share_ctrl->comp_output_mode &
+ VFE40_OUTPUT_MODE_PRIMARY) {
+ msm_camera_io_w(1, share_ctrl->vfebase +
+ vfe40_AXI_WM_CFG[
share_ctrl->outpath.out0.ch0]);
- msm_camera_io_w(1, vfe40_ctrl->share_ctrl->vfebase +
- vfe40_AXI_WM_CFG[vfe40_ctrl->
+ msm_camera_io_w(1, share_ctrl->vfebase +
+ vfe40_AXI_WM_CFG[
share_ctrl->outpath.out0.ch1]);
- vfe40_ctrl->share_ctrl->liveshot_state =
+
+ share_ctrl->liveshot_state =
VFE_STATE_STARTED;
}
- }
-
- if (vfe40_ctrl->share_ctrl->liveshot_state == VFE_STATE_STARTED) {
- vfe40_ctrl->share_ctrl->vfe_capture_count--;
- if (!vfe40_ctrl->share_ctrl->vfe_capture_count)
- vfe40_ctrl->share_ctrl->liveshot_state =
- VFE_STATE_STOP_REQUESTED;
- msm_camera_io_w_mb(1, vfe40_ctrl->
- share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
- } else if (vfe40_ctrl->share_ctrl->liveshot_state ==
- VFE_STATE_STOP_REQUESTED) {
- CDBG("%s: disabling liveshot output\n", __func__);
- if (vfe40_ctrl->share_ctrl->outpath.output_mode &
- VFE40_OUTPUT_MODE_PRIMARY) {
- msm_camera_io_w(0, vfe40_ctrl->share_ctrl->vfebase +
- vfe40_AXI_WM_CFG[vfe40_ctrl->
+ break;
+ case VFE_STATE_STARTED:
+ share_ctrl->vfe_capture_count--;
+ if (!share_ctrl->vfe_capture_count &&
+ (share_ctrl->comp_output_mode &
+ VFE40_OUTPUT_MODE_PRIMARY)) {
+ msm_camera_io_w(0, share_ctrl->vfebase +
+ vfe40_AXI_WM_CFG[
share_ctrl->outpath.out0.ch0]);
- msm_camera_io_w(0, vfe40_ctrl->share_ctrl->vfebase +
- vfe40_AXI_WM_CFG[vfe40_ctrl->
+ msm_camera_io_w(0, share_ctrl->vfebase +
+ vfe40_AXI_WM_CFG[
share_ctrl->outpath.out0.ch1]);
- vfe40_ctrl->share_ctrl->liveshot_state =
- VFE_STATE_STOPPED;
- msm_camera_io_w_mb(1, vfe40_ctrl->share_ctrl->vfebase +
+ }
+ break;
+ case VFE_STATE_STOP_REQUESTED:
+ if (share_ctrl->comp_output_mode &
+ VFE40_OUTPUT_MODE_PRIMARY) {
+ /* Stop requested, stop write masters, and
+ * trigger REG_UPDATE. Send STOP_LS_ACK in
+ * next reg update. */
+ msm_camera_io_w(0, share_ctrl->vfebase +
+ vfe40_AXI_WM_CFG[
+ share_ctrl->outpath.out0.ch0]);
+ msm_camera_io_w(0, share_ctrl->vfebase +
+ vfe40_AXI_WM_CFG[
+ share_ctrl->outpath.out0.ch1]);
+
+ share_ctrl->liveshot_state = VFE_STATE_STOPPED;
+ msm_camera_io_w_mb(1, share_ctrl->vfebase +
VFE_REG_UPDATE_CMD);
}
- } else if (vfe40_ctrl->share_ctrl->liveshot_state ==
- VFE_STATE_STOPPED) {
- vfe40_ctrl->share_ctrl->liveshot_state = VFE_STATE_IDLE;
+ break;
+ case VFE_STATE_STOPPED:
+ CDBG("%s Sending STOP_LS ACK\n", __func__);
+ vfe40_send_isp_msg(&vfe40_ctrl->subdev,
+ share_ctrl->vfeFrameId, MSG_ID_STOP_LS_ACK);
+ share_ctrl->liveshot_state = VFE_STATE_IDLE;
+ break;
+ default:
+ break;
}
- if ((vfe40_ctrl->share_ctrl->operation_mode ==
- VFE_OUTPUTS_THUMB_AND_MAIN) ||
- (vfe40_ctrl->share_ctrl->operation_mode ==
- VFE_OUTPUTS_MAIN_AND_THUMB) ||
- (vfe40_ctrl->share_ctrl->operation_mode ==
- VFE_OUTPUTS_THUMB_AND_JPEG) ||
- (vfe40_ctrl->share_ctrl->operation_mode ==
- VFE_OUTPUTS_JPEG_AND_THUMB)) {
+ if ((share_ctrl->operation_mode & VFE_OUTPUTS_THUMB_AND_MAIN) ||
+ (share_ctrl->operation_mode &
+ VFE_OUTPUTS_MAIN_AND_THUMB) ||
+ (share_ctrl->operation_mode &
+ VFE_OUTPUTS_THUMB_AND_JPEG) ||
+ (share_ctrl->operation_mode &
+ VFE_OUTPUTS_JPEG_AND_THUMB)) {
/* in snapshot mode */
/* later we need to add check for live snapshot mode. */
if (vfe40_ctrl->frame_skip_pattern & (0x1 <<
(vfe40_ctrl->snapshot_frame_cnt %
vfe40_ctrl->frame_skip_cnt))) {
- vfe40_ctrl->share_ctrl->vfe_capture_count--;
+ share_ctrl->vfe_capture_count--;
/* if last frame to be captured: */
- if (vfe40_ctrl->share_ctrl->vfe_capture_count == 0) {
- /* stop the bus output:write master enable = 0*/
- if (vfe40_ctrl->share_ctrl->outpath.output_mode
+ if (share_ctrl->vfe_capture_count == 0) {
+ /* stop the bus output: */
+ if (share_ctrl->comp_output_mode
& VFE40_OUTPUT_MODE_PRIMARY) {
- msm_camera_io_w(0,
- vfe40_ctrl->share_ctrl->vfebase+
- vfe40_AXI_WM_CFG[vfe40_ctrl->
- share_ctrl->outpath.out0.ch0]);
- msm_camera_io_w(0,
- vfe40_ctrl->share_ctrl->vfebase+
- vfe40_AXI_WM_CFG[vfe40_ctrl->
- share_ctrl->outpath.out0.ch1]);
- }
- if (vfe40_ctrl->share_ctrl->outpath.output_mode&
+ msm_camera_io_w(0,
+ share_ctrl->vfebase+
+ vfe40_AXI_WM_CFG[
+ share_ctrl->
+ outpath.out0.ch0]);
+ msm_camera_io_w(0,
+ share_ctrl->vfebase+
+ vfe40_AXI_WM_CFG[
+ share_ctrl->
+ outpath.out0.ch1]);
+ }
+ if (share_ctrl->comp_output_mode &
VFE40_OUTPUT_MODE_SECONDARY) {
- msm_camera_io_w(0,
- vfe40_ctrl->share_ctrl->vfebase+
- vfe40_AXI_WM_CFG[vfe40_ctrl->
- share_ctrl->outpath.out1.ch0]);
- msm_camera_io_w(0,
- vfe40_ctrl->share_ctrl->vfebase+
- vfe40_AXI_WM_CFG[vfe40_ctrl->
- share_ctrl->outpath.out1.ch1]);
+ msm_camera_io_w(0,
+ share_ctrl->vfebase+
+ vfe40_AXI_WM_CFG[
+ share_ctrl->
+ outpath.out1.ch0]);
+ msm_camera_io_w(0,
+ share_ctrl->vfebase+
+ vfe40_AXI_WM_CFG[
+ share_ctrl->
+ outpath.out1.ch1]);
}
msm_camera_io_w_mb
(CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
- vfe40_ctrl->share_ctrl->vfebase +
+ share_ctrl->vfebase +
VFE_CAMIF_COMMAND);
vfe40_ctrl->snapshot_frame_cnt = -1;
vfe40_ctrl->frame_skip_cnt = 31;
- vfe40_ctrl->frame_skip_pattern = 0xffffffff;
+ vfe40_ctrl->frame_skip_pattern =
+ 0xffffffff;
} /*if snapshot count is 0*/
} /*if frame is not being dropped*/
vfe40_ctrl->snapshot_frame_cnt++;
/* then do reg_update. */
msm_camera_io_w(1,
- vfe40_ctrl->share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+ share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
} /* if snapshot mode. */
}
+}
-static void vfe40_set_default_reg_values(
- struct vfe40_ctrl_type *vfe40_ctrl)
+static void vfe40_process_rdi0_reg_update_irq(
+ struct vfe40_ctrl_type *vfe40_ctrl)
{
- msm_camera_io_w(0x800080,
- vfe40_ctrl->share_ctrl->vfebase + VFE_DEMUX_GAIN_0);
- msm_camera_io_w(0x800080,
- vfe40_ctrl->share_ctrl->vfebase + VFE_DEMUX_GAIN_1);
- /* What value should we program CGC_OVERRIDE to? */
- msm_camera_io_w(0xFFFFF,
- vfe40_ctrl->share_ctrl->vfebase + VFE_CGC_OVERRIDE);
+ if (atomic_cmpxchg(
+ &vfe40_ctrl->share_ctrl->rdi0_update_ack_pending, 2, 0) == 2) {
+ axi_stop_rdi0(vfe40_ctrl->share_ctrl);
+ axi_disable_irq(vfe40_ctrl->share_ctrl);
+ vfe40_send_isp_msg(&vfe40_ctrl->subdev,
+ vfe40_ctrl->share_ctrl->vfeFrameId,
+ MSG_ID_RDI0_UPDATE_ACK);
+ vfe40_ctrl->share_ctrl->comp_output_mode &=
+ ~VFE40_OUTPUT_MODE_TERTIARY1;
+ vfe40_ctrl->share_ctrl->current_mode &=
+ ~(VFE_OUTPUTS_RDI0);
+ }
- /* default frame drop period and pattern */
- msm_camera_io_w(0, vfe40_ctrl->share_ctrl->vfebase + VFE_CLAMP_ENC_MIN);
- msm_camera_io_w(0xFFFFFF,
- vfe40_ctrl->share_ctrl->vfebase + VFE_CLAMP_ENC_MAX);
- msm_camera_io_w(0,
- vfe40_ctrl->share_ctrl->vfebase + VFE_CLAMP_VIEW_MIN);
- msm_camera_io_w(0xFFFFFF,
- vfe40_ctrl->share_ctrl->vfebase + VFE_CLAMP_VIEW_MAX);
+ if (atomic_cmpxchg(
+ &vfe40_ctrl->share_ctrl->rdi0_update_ack_pending, 1, 0) == 1) {
+ vfe40_ctrl->share_ctrl->comp_output_mode |=
+ VFE40_OUTPUT_MODE_TERTIARY1;
+ vfe40_send_isp_msg(&vfe40_ctrl->subdev,
+ vfe40_ctrl->share_ctrl->vfeFrameId,
+ MSG_ID_RDI0_UPDATE_ACK);
+ vfe40_ctrl->share_ctrl->current_mode &=
+ ~(VFE_OUTPUTS_RDI0);
+ }
+}
- /* stats UB config */
- msm_camera_io_w(0x3980007,
- vfe40_ctrl->share_ctrl->vfebase + VFE_BUS_STATS_AEC_UB_CFG);
- msm_camera_io_w(0x3A00007,
- vfe40_ctrl->share_ctrl->vfebase + VFE_BUS_STATS_AF_UB_CFG);
- msm_camera_io_w(0x3A8000F,
- vfe40_ctrl->share_ctrl->vfebase + VFE_BUS_STATS_AWB_UB_CFG);
- msm_camera_io_w(0x3B80007,
- vfe40_ctrl->share_ctrl->vfebase + VFE_BUS_STATS_RS_UB_CFG);
- msm_camera_io_w(0x3C0001F,
- vfe40_ctrl->share_ctrl->vfebase + VFE_BUS_STATS_CS_UB_CFG);
- msm_camera_io_w(0x3E0001F,
- vfe40_ctrl->share_ctrl->vfebase + VFE_BUS_STATS_HIST_UB_CFG);
+static void vfe40_process_rdi1_reg_update_irq(
+ struct vfe40_ctrl_type *vfe40_ctrl)
+{
+ if (atomic_cmpxchg(
+ &vfe40_ctrl->share_ctrl->rdi1_update_ack_pending, 2, 0) == 2) {
+ axi_stop_rdi1(vfe40_ctrl->share_ctrl);
+ axi_disable_irq(vfe40_ctrl->share_ctrl);
+ vfe40_send_isp_msg(&vfe40_ctrl->subdev,
+ vfe40_ctrl->share_ctrl->vfeFrameId,
+ MSG_ID_RDI1_UPDATE_ACK);
+ vfe40_ctrl->share_ctrl->comp_output_mode &=
+ ~VFE40_OUTPUT_MODE_TERTIARY2;
+ vfe40_ctrl->share_ctrl->current_mode &=
+ ~(VFE_OUTPUTS_RDI1);
+ }
+
+ if (atomic_cmpxchg(
+ &vfe40_ctrl->share_ctrl->rdi1_update_ack_pending, 1, 0) == 1) {
+ vfe40_ctrl->share_ctrl->comp_output_mode |=
+ VFE40_OUTPUT_MODE_TERTIARY2;
+ vfe40_send_isp_msg(&vfe40_ctrl->subdev,
+ vfe40_ctrl->share_ctrl->vfeFrameId,
+ MSG_ID_RDI1_UPDATE_ACK);
+ vfe40_ctrl->share_ctrl->current_mode &=
+ ~(VFE_OUTPUTS_RDI1);
+ }
}
static void vfe40_process_reset_irq(
@@ -2612,39 +3464,45 @@
unsigned long flags;
atomic_set(&vfe40_ctrl->share_ctrl->vstate, 0);
+ atomic_set(&vfe40_ctrl->share_ctrl->handle_common_irq, 0);
spin_lock_irqsave(&vfe40_ctrl->share_ctrl->stop_flag_lock, flags);
if (vfe40_ctrl->share_ctrl->stop_ack_pending) {
vfe40_ctrl->share_ctrl->stop_ack_pending = FALSE;
spin_unlock_irqrestore(
&vfe40_ctrl->share_ctrl->stop_flag_lock, flags);
+ if (vfe40_ctrl->share_ctrl->sync_abort)
+ complete(&vfe40_ctrl->share_ctrl->reset_complete);
+ else
vfe40_send_isp_msg(&vfe40_ctrl->subdev,
- vfe40_ctrl->share_ctrl->vfeFrameId, MSG_ID_STOP_ACK);
+ vfe40_ctrl->share_ctrl->vfeFrameId,
+ MSG_ID_STOP_ACK);
} else {
spin_unlock_irqrestore(
&vfe40_ctrl->share_ctrl->stop_flag_lock, flags);
/* this is from reset command. */
- vfe40_set_default_reg_values(vfe40_ctrl);
-
+ vfe40_reset_internal_variables(vfe40_ctrl);
+ if (vfe40_ctrl->share_ctrl->vfe_reset_flag) {
+ vfe40_ctrl->share_ctrl->vfe_reset_flag = false;
+ msm_camera_io_w(0xFF00,
+ vfe40_ctrl->share_ctrl->vfebase + VFE_BUS_CMD);
+ } else {
/* reload all write masters. (frame & line)*/
- msm_camera_io_w(0x7FFF,
+ msm_camera_io_w(0xFF7F,
vfe40_ctrl->share_ctrl->vfebase + VFE_BUS_CMD);
- vfe40_send_isp_msg(&vfe40_ctrl->subdev,
- vfe40_ctrl->share_ctrl->vfeFrameId, MSG_ID_RESET_ACK);
+ }
+ complete(&vfe40_ctrl->share_ctrl->reset_complete);
}
}
static void vfe40_process_camif_sof_irq(
struct vfe40_ctrl_type *vfe40_ctrl)
{
- if (vfe40_ctrl->share_ctrl->operation_mode ==
+ if (vfe40_ctrl->share_ctrl->operation_mode &
VFE_OUTPUTS_RAW) {
- if (vfe40_ctrl->start_ack_pending) {
- vfe40_send_isp_msg(&vfe40_ctrl->subdev,
- vfe40_ctrl->share_ctrl->vfeFrameId,
- MSG_ID_START_ACK);
- vfe40_ctrl->start_ack_pending = FALSE;
- }
+ if (vfe40_ctrl->share_ctrl->start_ack_pending)
+ vfe40_ctrl->share_ctrl->start_ack_pending = FALSE;
+
vfe40_ctrl->share_ctrl->vfe_capture_count--;
/* if last frame to be captured: */
if (vfe40_ctrl->share_ctrl->vfe_capture_count == 0) {
@@ -2659,11 +3517,15 @@
VFE_MODE_OF_OPERATION_VIDEO) &&
(vfe40_ctrl->share_ctrl->vfeFrameId %
vfe40_ctrl->hfr_mode != 0)) {
- vfe40_ctrl->share_ctrl->vfeFrameId++;
+ if (vfe40_ctrl->vfe_sof_count_enable)
+ vfe40_ctrl->share_ctrl->vfeFrameId++;
CDBG("Skip the SOF notification when HFR enabled\n");
return;
}
- vfe40_ctrl->share_ctrl->vfeFrameId++;
+
+ if (vfe40_ctrl->vfe_sof_count_enable)
+ vfe40_ctrl->share_ctrl->vfeFrameId++;
+
vfe40_send_isp_msg(&vfe40_ctrl->subdev,
vfe40_ctrl->share_ctrl->vfeFrameId, MSG_ID_SOF_ACK);
CDBG("camif_sof_irq, frameId = %d\n",
@@ -2681,11 +3543,19 @@
struct axi_ctrl_t *axi_ctrl, uint32_t errStatus)
{
uint32_t reg_value;
+ if (errStatus & VFE40_IMASK_VIOLATION) {
+ pr_err("vfe40_irq: violation interrupt\n");
+ reg_value = msm_camera_io_r(
+ axi_ctrl->share_ctrl->vfebase + VFE_VIOLATION_STATUS);
+ pr_err("%s: violationStatus = 0x%x\n", __func__, reg_value);
+ }
if (errStatus & VFE40_IMASK_CAMIF_ERROR) {
pr_err("vfe40_irq: camif errors\n");
reg_value = msm_camera_io_r(
axi_ctrl->share_ctrl->vfebase + VFE_CAMIF_STATUS);
+ v4l2_subdev_notify(&axi_ctrl->subdev,
+ NOTIFY_VFE_CAMIF_ERROR, (void *)NULL);
pr_err("camifStatus = 0x%x\n", reg_value);
vfe40_send_isp_msg(&axi_ctrl->subdev,
axi_ctrl->share_ctrl->vfeFrameId, MSG_ID_CAMIF_ERROR);
@@ -2709,12 +3579,34 @@
if (errStatus & VFE40_IMASK_REALIGN_BUF_CR_OVFL)
pr_err("vfe40_irq: realign bug CR overflow\n");
- if (errStatus & VFE40_IMASK_VIOLATION) {
- pr_err("vfe40_irq: violation interrupt\n");
- reg_value = msm_camera_io_r(
- axi_ctrl->share_ctrl->vfebase + VFE_VIOLATION_STATUS);
- pr_err("%s: violationStatus = 0x%x\n", __func__, reg_value);
- }
+ if (errStatus & VFE40_IMASK_STATS_BE_BUS_OVFL)
+ pr_err("vfe40_irq: be stats bus overflow\n");
+
+ if (errStatus & VFE40_IMASK_STATS_BG_BUS_OVFL)
+ pr_err("vfe40_irq: bg stats bus overflow\n");
+
+ if (errStatus & VFE40_IMASK_STATS_BF_BUS_OVFL)
+ pr_err("vfe40_irq: bf stats bus overflow\n");
+
+ if (errStatus & VFE40_IMASK_STATS_AWB_BUS_OVFL)
+ pr_err("vfe40_irq: awb stats bus overflow\n");
+
+ if (errStatus & VFE40_IMASK_STATS_RS_BUS_OVFL)
+ pr_err("vfe40_irq: rs stats bus overflow\n");
+
+ if (errStatus & VFE40_IMASK_STATS_CS_BUS_OVFL)
+ pr_err("vfe40_irq: cs stats bus overflow\n");
+
+ if (errStatus & VFE40_IMASK_STATS_IHIST_BUS_OVFL)
+ pr_err("vfe40_irq: ihist stats bus overflow\n");
+
+ if (errStatus & VFE40_IMASK_STATS_SKIN_BHIST_BUS_OVFL)
+ pr_err("vfe40_irq: skin/bhist stats bus overflow\n");
+}
+
+static void vfe40_process_common_error_irq(
+ struct axi_ctrl_t *axi_ctrl, uint32_t errStatus)
+{
if (errStatus & VFE40_IMASK_IMG_MAST_0_BUS_OVFL)
pr_err("vfe40_irq: image master 0 bus overflow\n");
@@ -2737,29 +3629,294 @@
if (errStatus & VFE40_IMASK_IMG_MAST_6_BUS_OVFL)
pr_err("vfe40_irq: image master 6 bus overflow\n");
- if (errStatus & VFE40_IMASK_STATS_AE_BG_BUS_OVFL)
- pr_err("vfe40_irq: ae/bg stats bus overflow\n");
+}
- if (errStatus & VFE40_IMASK_STATS_AF_BF_BUS_OVFL)
- pr_err("vfe40_irq: af/bf stats bus overflow\n");
+static void vfe_send_outmsg(
+ struct axi_ctrl_t *axi_ctrl, uint8_t msgid,
+ uint32_t ch0_paddr, uint32_t ch1_paddr,
+ uint32_t ch2_paddr, uint32_t inst_handle)
+{
+ struct isp_msg_output msg;
- if (errStatus & VFE40_IMASK_STATS_AWB_BUS_OVFL)
- pr_err("vfe40_irq: awb stats bus overflow\n");
+ msg.output_id = msgid;
+ msg.buf.inst_handle = inst_handle;
+ msg.buf.ch_paddr[0] = ch0_paddr;
+ msg.buf.ch_paddr[1] = ch1_paddr;
+ msg.buf.ch_paddr[2] = ch2_paddr;
+ switch (msgid) {
+ case MSG_ID_OUTPUT_TERTIARY1:
+ msg.frameCounter = axi_ctrl->share_ctrl->rdi0FrameId;
+ break;
+ case MSG_ID_OUTPUT_TERTIARY2:
+ msg.frameCounter = axi_ctrl->share_ctrl->rdi1FrameId;
+ break;
+ default:
+ msg.frameCounter = axi_ctrl->share_ctrl->vfeFrameId;
+ break;
+ }
- if (errStatus & VFE40_IMASK_STATS_RS_BUS_OVFL)
- pr_err("vfe40_irq: rs stats bus overflow\n");
+ v4l2_subdev_notify(&axi_ctrl->subdev,
+ NOTIFY_VFE_MSG_OUT,
+ &msg);
+ return;
+}
- if (errStatus & VFE40_IMASK_STATS_CS_BUS_OVFL)
- pr_err("vfe40_irq: cs stats bus overflow\n");
+static void vfe40_process_output_path_irq_0(
+ struct axi_ctrl_t *axi_ctrl)
+{
+ uint32_t ping_pong;
+ uint32_t ch0_paddr, ch1_paddr, ch2_paddr;
+ uint8_t out_bool = 0;
+ struct msm_free_buf *free_buf = NULL;
- if (errStatus & VFE40_IMASK_STATS_IHIST_BUS_OVFL)
- pr_err("vfe40_irq: ihist stats bus overflow\n");
+ free_buf = vfe40_check_free_buffer(VFE_MSG_OUTPUT_IRQ,
+ VFE_MSG_OUTPUT_PRIMARY, axi_ctrl);
- if (errStatus & VFE40_IMASK_STATS_SKIN_BHIST_BUS_OVFL)
- pr_err("vfe40_irq: skin/bhist stats bus overflow\n");
+ /* we render frames in the following conditions:
+ 1. Continuous mode and the free buffer is avaialable.
+ 2. In snapshot shot mode, free buffer is not always available.
+ when pending snapshot count is <=1, then no need to use
+ free buffer.
+ */
+ out_bool = (
+ (axi_ctrl->share_ctrl->operation_mode &
+ VFE_OUTPUTS_THUMB_AND_MAIN ||
+ axi_ctrl->share_ctrl->operation_mode &
+ VFE_OUTPUTS_MAIN_AND_THUMB ||
+ axi_ctrl->share_ctrl->operation_mode &
+ VFE_OUTPUTS_THUMB_AND_JPEG ||
+ axi_ctrl->share_ctrl->operation_mode &
+ VFE_OUTPUTS_JPEG_AND_THUMB ||
+ axi_ctrl->share_ctrl->operation_mode &
+ VFE_OUTPUTS_RAW ||
+ axi_ctrl->share_ctrl->liveshot_state ==
+ VFE_STATE_STARTED ||
+ axi_ctrl->share_ctrl->liveshot_state ==
+ VFE_STATE_STOP_REQUESTED ||
+ axi_ctrl->share_ctrl->liveshot_state ==
+ VFE_STATE_STOPPED) &&
+ (axi_ctrl->share_ctrl->vfe_capture_count <= 1)) ||
+ free_buf;
- if (errStatus & VFE40_IMASK_AXI_ERROR)
- pr_err("vfe40_irq: axi error\n");
+ if (out_bool) {
+ ping_pong = msm_camera_io_r(axi_ctrl->share_ctrl->vfebase +
+ VFE_BUS_PING_PONG_STATUS);
+
+ /* Channel 0*/
+ ch0_paddr = vfe40_get_ch_addr(
+ ping_pong, axi_ctrl->share_ctrl->vfebase,
+ axi_ctrl->share_ctrl->outpath.out0.ch0);
+ /* Channel 1*/
+ ch1_paddr = vfe40_get_ch_addr(
+ ping_pong, axi_ctrl->share_ctrl->vfebase,
+ axi_ctrl->share_ctrl->outpath.out0.ch1);
+ /* Channel 2*/
+ ch2_paddr = vfe40_get_ch_addr(
+ ping_pong, axi_ctrl->share_ctrl->vfebase,
+ axi_ctrl->share_ctrl->outpath.out0.ch2);
+
+ CDBG("output path 0, ch0 = 0x%x, ch1 = 0x%x, ch2 = 0x%x\n",
+ ch0_paddr, ch1_paddr, ch2_paddr);
+ if (free_buf) {
+ /* Y channel */
+ vfe40_put_ch_addr(ping_pong,
+ axi_ctrl->share_ctrl->vfebase,
+ axi_ctrl->share_ctrl->outpath.out0.ch0,
+ free_buf->ch_paddr[0]);
+ /* Chroma channel */
+ vfe40_put_ch_addr(ping_pong,
+ axi_ctrl->share_ctrl->vfebase,
+ axi_ctrl->share_ctrl->outpath.out0.ch1,
+ free_buf->ch_paddr[1]);
+ if (free_buf->num_planes > 2)
+ vfe40_put_ch_addr(ping_pong,
+ axi_ctrl->share_ctrl->vfebase,
+ axi_ctrl->share_ctrl->outpath.out0.ch2,
+ free_buf->ch_paddr[2]);
+ }
+ if (axi_ctrl->share_ctrl->operation_mode &
+ VFE_OUTPUTS_THUMB_AND_MAIN ||
+ axi_ctrl->share_ctrl->operation_mode &
+ VFE_OUTPUTS_MAIN_AND_THUMB ||
+ axi_ctrl->share_ctrl->operation_mode &
+ VFE_OUTPUTS_THUMB_AND_JPEG ||
+ axi_ctrl->share_ctrl->operation_mode &
+ VFE_OUTPUTS_JPEG_AND_THUMB ||
+ axi_ctrl->share_ctrl->operation_mode &
+ VFE_OUTPUTS_RAW ||
+ axi_ctrl->share_ctrl->liveshot_state ==
+ VFE_STATE_STOPPED)
+ axi_ctrl->share_ctrl->outpath.out0.capture_cnt--;
+
+ vfe_send_outmsg(axi_ctrl,
+ MSG_ID_OUTPUT_PRIMARY, ch0_paddr,
+ ch1_paddr, ch2_paddr,
+ axi_ctrl->share_ctrl->outpath.out0.inst_handle);
+
+ } else {
+ axi_ctrl->share_ctrl->outpath.out0.frame_drop_cnt++;
+ CDBG("path_irq_0 - no free buffer!\n");
+ }
+}
+
+static void vfe40_process_output_path_irq_1(
+ struct axi_ctrl_t *axi_ctrl)
+{
+ uint32_t ping_pong;
+ uint32_t ch0_paddr, ch1_paddr, ch2_paddr;
+ /* this must be snapshot main image output. */
+ uint8_t out_bool = 0;
+ struct msm_free_buf *free_buf = NULL;
+
+ free_buf = vfe40_check_free_buffer(VFE_MSG_OUTPUT_IRQ,
+ VFE_MSG_OUTPUT_SECONDARY, axi_ctrl);
+ out_bool = ((axi_ctrl->share_ctrl->operation_mode &
+ VFE_OUTPUTS_THUMB_AND_MAIN ||
+ axi_ctrl->share_ctrl->operation_mode &
+ VFE_OUTPUTS_MAIN_AND_THUMB ||
+ axi_ctrl->share_ctrl->operation_mode &
+ VFE_OUTPUTS_RAW ||
+ axi_ctrl->share_ctrl->operation_mode &
+ VFE_OUTPUTS_JPEG_AND_THUMB) &&
+ (axi_ctrl->share_ctrl->vfe_capture_count <= 1)) ||
+ free_buf;
+
+ if (out_bool) {
+ ping_pong = msm_camera_io_r(axi_ctrl->share_ctrl->vfebase +
+ VFE_BUS_PING_PONG_STATUS);
+
+ /* Y channel */
+ ch0_paddr = vfe40_get_ch_addr(ping_pong,
+ axi_ctrl->share_ctrl->vfebase,
+ axi_ctrl->share_ctrl->outpath.out1.ch0);
+ /* Chroma channel */
+ ch1_paddr = vfe40_get_ch_addr(ping_pong,
+ axi_ctrl->share_ctrl->vfebase,
+ axi_ctrl->share_ctrl->outpath.out1.ch1);
+ ch2_paddr = vfe40_get_ch_addr(ping_pong,
+ axi_ctrl->share_ctrl->vfebase,
+ axi_ctrl->share_ctrl->outpath.out1.ch2);
+
+ CDBG("%s ch0 = 0x%x, ch1 = 0x%x, ch2 = 0x%x\n",
+ __func__, ch0_paddr, ch1_paddr, ch2_paddr);
+ if (free_buf) {
+ /* Y channel */
+ vfe40_put_ch_addr(ping_pong,
+ axi_ctrl->share_ctrl->vfebase,
+ axi_ctrl->share_ctrl->outpath.out1.ch0,
+ free_buf->ch_paddr[0]);
+ /* Chroma channel */
+ vfe40_put_ch_addr(ping_pong,
+ axi_ctrl->share_ctrl->vfebase,
+ axi_ctrl->share_ctrl->outpath.out1.ch1,
+ free_buf->ch_paddr[1]);
+ if (free_buf->num_planes > 2)
+ vfe40_put_ch_addr(ping_pong,
+ axi_ctrl->share_ctrl->vfebase,
+ axi_ctrl->share_ctrl->outpath.out1.ch2,
+ free_buf->ch_paddr[2]);
+ }
+ if (axi_ctrl->share_ctrl->operation_mode &
+ VFE_OUTPUTS_THUMB_AND_MAIN ||
+ axi_ctrl->share_ctrl->operation_mode &
+ VFE_OUTPUTS_MAIN_AND_THUMB ||
+ axi_ctrl->share_ctrl->operation_mode &
+ VFE_OUTPUTS_RAW ||
+ axi_ctrl->share_ctrl->operation_mode &
+ VFE_OUTPUTS_JPEG_AND_THUMB)
+ axi_ctrl->share_ctrl->outpath.out1.capture_cnt--;
+
+ vfe_send_outmsg(axi_ctrl,
+ MSG_ID_OUTPUT_SECONDARY, ch0_paddr,
+ ch1_paddr, ch2_paddr,
+ axi_ctrl->share_ctrl->outpath.out1.inst_handle);
+
+ } else {
+ axi_ctrl->share_ctrl->outpath.out1.frame_drop_cnt++;
+ CDBG("path_irq_1 - no free buffer!\n");
+ }
+}
+
+static void vfe40_process_output_path_irq_rdi0(
+ struct axi_ctrl_t *axi_ctrl)
+{
+ uint32_t ping_pong;
+ uint32_t ch0_paddr = 0;
+ /* this must be rdi image output. */
+ struct msm_free_buf *free_buf = NULL;
+ /*RDI0*/
+ if (axi_ctrl->share_ctrl->operation_mode & VFE_OUTPUTS_RDI0) {
+ free_buf = vfe40_check_free_buffer(VFE_MSG_OUTPUT_IRQ,
+ VFE_MSG_OUTPUT_TERTIARY1, axi_ctrl);
+ if (free_buf) {
+ ping_pong = msm_camera_io_r(axi_ctrl->
+ share_ctrl->vfebase +
+ VFE_BUS_PING_PONG_STATUS);
+
+ /* Y only channel */
+ ch0_paddr = vfe40_get_ch_addr(ping_pong,
+ axi_ctrl->share_ctrl->vfebase,
+ axi_ctrl->share_ctrl->outpath.out2.ch0);
+
+ pr_debug("%s ch0 = 0x%x\n",
+ __func__, ch0_paddr);
+
+ /* Y channel */
+ vfe40_put_ch_addr(ping_pong,
+ axi_ctrl->share_ctrl->vfebase,
+ axi_ctrl->share_ctrl->outpath.out2.ch0,
+ free_buf->ch_paddr[0]);
+
+ vfe_send_outmsg(axi_ctrl,
+ MSG_ID_OUTPUT_TERTIARY1, ch0_paddr,
+ 0, 0,
+ axi_ctrl->share_ctrl->outpath.out2.inst_handle);
+
+ } else {
+ axi_ctrl->share_ctrl->outpath.out2.frame_drop_cnt++;
+ pr_err("path_irq_2 irq - no free buffer for rdi0!\n");
+ }
+ }
+}
+
+static void vfe40_process_output_path_irq_rdi1(
+ struct axi_ctrl_t *axi_ctrl)
+{
+ uint32_t ping_pong;
+ uint32_t ch0_paddr = 0;
+ /* this must be rdi image output. */
+ struct msm_free_buf *free_buf = NULL;
+ /*RDI1*/
+ if (axi_ctrl->share_ctrl->operation_mode & VFE_OUTPUTS_RDI1) {
+ free_buf = vfe40_check_free_buffer(VFE_MSG_OUTPUT_IRQ,
+ VFE_MSG_OUTPUT_TERTIARY2, axi_ctrl);
+ if (free_buf) {
+ ping_pong = msm_camera_io_r(axi_ctrl->
+ share_ctrl->vfebase +
+ VFE_BUS_PING_PONG_STATUS);
+
+ /* Y channel */
+ ch0_paddr = vfe40_get_ch_addr(ping_pong,
+ axi_ctrl->share_ctrl->vfebase,
+ axi_ctrl->share_ctrl->outpath.out3.ch0);
+ pr_debug("%s ch0 = 0x%x\n",
+ __func__, ch0_paddr);
+
+ /* Y channel */
+ vfe40_put_ch_addr(ping_pong,
+ axi_ctrl->share_ctrl->vfebase,
+ axi_ctrl->share_ctrl->outpath.out3.ch0,
+ free_buf->ch_paddr[0]);
+
+ vfe_send_outmsg(axi_ctrl,
+ MSG_ID_OUTPUT_TERTIARY2, ch0_paddr,
+ 0, 0,
+ axi_ctrl->share_ctrl->outpath.out3.inst_handle);
+ } else {
+ axi_ctrl->share_ctrl->outpath.out3.frame_drop_cnt++;
+ pr_err("path_irq irq - no free buffer for rdi1!\n");
+ }
+ }
}
static uint32_t vfe40_process_stats_irq_common(
@@ -2786,8 +3943,8 @@
return returnAddr;
}
-static void
-vfe_send_stats_msg(struct vfe40_ctrl_type *vfe40_ctrl,
+static void vfe_send_stats_msg(
+ struct vfe40_ctrl_type *vfe40_ctrl,
uint32_t bufAddress, uint32_t statsNum)
{
int rc = 0;
@@ -2796,24 +3953,36 @@
/* @todo This is causing issues, need further investigate */
/* spin_lock_irqsave(&ctrl->state_lock, flags); */
struct isp_msg_stats msgStats;
+ uint32_t stats_type;
msgStats.frameCounter = vfe40_ctrl->share_ctrl->vfeFrameId;
+ if (vfe40_ctrl->simultaneous_sof_stat)
+ msgStats.frameCounter--;
msgStats.buffer = bufAddress;
-
switch (statsNum) {
case statsAeNum:{
- msgStats.id = MSG_ID_STATS_AEC;
+ msgStats.id =
+ (!vfe40_use_bayer_stats(vfe40_ctrl)) ? MSG_ID_STATS_AEC
+ : MSG_ID_STATS_BG;
+ stats_type =
+ (!vfe40_use_bayer_stats(vfe40_ctrl)) ?
+ MSM_STATS_TYPE_AEC : MSM_STATS_TYPE_BG;
rc = vfe40_ctrl->stats_ops.dispatch(
vfe40_ctrl->stats_ops.stats_ctrl,
- MSM_STATS_TYPE_AEC, bufAddress,
+ stats_type, bufAddress,
&msgStats.buf_idx, &vaddr, &msgStats.fd,
vfe40_ctrl->stats_ops.client);
}
break;
case statsAfNum:{
- msgStats.id = MSG_ID_STATS_AF;
+ msgStats.id =
+ (!vfe40_use_bayer_stats(vfe40_ctrl)) ? MSG_ID_STATS_AF
+ : MSG_ID_STATS_BF;
+ stats_type =
+ (!vfe40_use_bayer_stats(vfe40_ctrl)) ? MSM_STATS_TYPE_AF
+ : MSM_STATS_TYPE_BF;
rc = vfe40_ctrl->stats_ops.dispatch(
vfe40_ctrl->stats_ops.stats_ctrl,
- MSM_STATS_TYPE_AF, bufAddress,
+ stats_type, bufAddress,
&msgStats.buf_idx, &vaddr, &msgStats.fd,
vfe40_ctrl->stats_ops.client);
}
@@ -2855,6 +4024,15 @@
vfe40_ctrl->stats_ops.client);
}
break;
+ case statsSkinNum: {
+ msgStats.id = MSG_ID_STATS_BHIST;
+ rc = vfe40_ctrl->stats_ops.dispatch(
+ vfe40_ctrl->stats_ops.stats_ctrl,
+ MSM_STATS_TYPE_BHIST, bufAddress,
+ &msgStats.buf_idx, &vaddr, &msgStats.fd,
+ vfe40_ctrl->stats_ops.client);
+ }
+ break;
default:
goto stats_done;
@@ -2869,7 +4047,7 @@
__func__, msgStats.id, msgStats.buffer);
}
stats_done:
- spin_unlock_irqrestore(&ctrl->state_lock, flags);
+ /* spin_unlock_irqrestore(&ctrl->state_lock, flags); */
return;
}
@@ -2880,11 +4058,14 @@
uint32_t temp;
msgStats.frame_id = vfe40_ctrl->share_ctrl->vfeFrameId;
+ if (vfe40_ctrl->simultaneous_sof_stat)
+ msgStats.frame_id--;
+
msgStats.status_bits = status_bits;
- msgStats.aec.buff = vfe40_ctrl->aecStatsControl.bufToRender;
+ msgStats.aec.buff = vfe40_ctrl->aecbgStatsControl.bufToRender;
msgStats.awb.buff = vfe40_ctrl->awbStatsControl.bufToRender;
- msgStats.af.buff = vfe40_ctrl->afStatsControl.bufToRender;
+ msgStats.af.buff = vfe40_ctrl->afbfStatsControl.bufToRender;
msgStats.ihist.buff = vfe40_ctrl->ihistStatsControl.bufToRender;
msgStats.rs.buff = vfe40_ctrl->rsStatsControl.bufToRender;
@@ -2899,6 +4080,31 @@
&msgStats);
}
+static void vfe40_process_stats_bg_irq(struct vfe40_ctrl_type *vfe40_ctrl)
+{
+ unsigned long flags;
+ uint32_t addr;
+ uint32_t stats_type;
+ stats_type =
+ (!vfe40_use_bayer_stats(vfe40_ctrl)) ? MSM_STATS_TYPE_AEC
+ : MSM_STATS_TYPE_BG;
+ spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
+ addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, stats_type);
+ spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
+ if (addr) {
+ vfe40_ctrl->aecbgStatsControl.bufToRender =
+ vfe40_process_stats_irq_common(vfe40_ctrl, statsAeNum,
+ addr);
+
+ vfe_send_stats_msg(vfe40_ctrl,
+ vfe40_ctrl->aecbgStatsControl.bufToRender, statsAeNum);
+ } else{
+ vfe40_ctrl->aecbgStatsControl.droppedStatsFrameCount++;
+ CDBG("%s: droppedStatsFrameCount = %d", __func__,
+ vfe40_ctrl->aecbgStatsControl.droppedStatsFrameCount);
+ }
+}
+
static void vfe40_process_stats_awb_irq(struct vfe40_ctrl_type *vfe40_ctrl)
{
unsigned long flags;
@@ -2920,6 +4126,53 @@
}
}
+static void vfe40_process_stats_bf_irq(struct vfe40_ctrl_type *vfe40_ctrl)
+{
+ unsigned long flags;
+ uint32_t addr;
+ uint32_t stats_type;
+ stats_type =
+ (!vfe40_use_bayer_stats(vfe40_ctrl)) ? MSM_STATS_TYPE_AF
+ : MSM_STATS_TYPE_BF;
+ spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
+ addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, stats_type);
+ spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
+ if (addr) {
+ vfe40_ctrl->afbfStatsControl.bufToRender =
+ vfe40_process_stats_irq_common(vfe40_ctrl, statsAfNum,
+ addr);
+
+ vfe_send_stats_msg(vfe40_ctrl,
+ vfe40_ctrl->afbfStatsControl.bufToRender, statsAfNum);
+ } else{
+ vfe40_ctrl->afbfStatsControl.droppedStatsFrameCount++;
+ CDBG("%s: droppedStatsFrameCount = %d", __func__,
+ vfe40_ctrl->afbfStatsControl.droppedStatsFrameCount);
+ }
+}
+
+static void vfe40_process_stats_bhist_irq(struct vfe40_ctrl_type *vfe40_ctrl)
+{
+ unsigned long flags;
+ uint32_t addr;
+ spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
+ addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl, MSM_STATS_TYPE_BHIST);
+ spin_unlock_irqrestore(&vfe40_ctrl->stats_bufq_lock, flags);
+ if (addr) {
+ vfe40_ctrl->bhistStatsControl.bufToRender =
+ vfe40_process_stats_irq_common(vfe40_ctrl,
+ statsSkinNum, addr);
+
+ vfe_send_stats_msg(vfe40_ctrl,
+ vfe40_ctrl->bhistStatsControl.bufToRender,
+ statsSkinNum);
+ } else{
+ vfe40_ctrl->bhistStatsControl.droppedStatsFrameCount++;
+ CDBG("%s: droppedStatsFrameCount = %d", __func__,
+ vfe40_ctrl->bhistStatsControl.droppedStatsFrameCount);
+ }
+}
+
static void vfe40_process_stats_ihist_irq(struct vfe40_ctrl_type *vfe40_ctrl)
{
unsigned long flags;
@@ -2975,8 +4228,9 @@
vfe40_process_stats_irq_common(vfe40_ctrl, statsCsNum,
addr);
- vfe_send_stats_msg(vfe40_ctrl,
- vfe40_ctrl->csStatsControl.bufToRender, statsCsNum);
+ vfe_send_stats_msg(vfe40_ctrl,
+ vfe40_ctrl->csStatsControl.bufToRender,
+ statsCsNum);
} else {
vfe40_ctrl->csStatsControl.droppedStatsFrameCount++;
CDBG("%s: droppedStatsFrameCount = %d", __func__,
@@ -2990,9 +4244,30 @@
unsigned long flags;
int32_t process_stats = false;
uint32_t addr;
+ uint32_t stats_type;
CDBG("%s, stats = 0x%x\n", __func__, status_bits);
spin_lock_irqsave(&vfe40_ctrl->stats_bufq_lock, flags);
+ stats_type =
+ (!vfe40_use_bayer_stats(vfe40_ctrl)) ? MSM_STATS_TYPE_AEC
+ : MSM_STATS_TYPE_BG;
+
+ if (status_bits & VFE_IRQ_STATUS0_STATS_BG) {
+ addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl,
+ stats_type);
+ if (addr) {
+ vfe40_ctrl->aecbgStatsControl.bufToRender =
+ vfe40_process_stats_irq_common(
+ vfe40_ctrl, statsAeNum, addr);
+ process_stats = true;
+ } else{
+ vfe40_ctrl->aecbgStatsControl.bufToRender = 0;
+ vfe40_ctrl->aecbgStatsControl.droppedStatsFrameCount++;
+ }
+ } else {
+ vfe40_ctrl->aecbgStatsControl.bufToRender = 0;
+ }
+
if (status_bits & VFE_IRQ_STATUS0_STATS_AWB) {
addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl,
MSM_STATS_TYPE_AWB);
@@ -3010,6 +4285,26 @@
vfe40_ctrl->awbStatsControl.bufToRender = 0;
}
+ stats_type =
+ (!vfe40_use_bayer_stats(vfe40_ctrl)) ? MSM_STATS_TYPE_AF
+ : MSM_STATS_TYPE_BF;
+ if (status_bits & VFE_IRQ_STATUS0_STATS_BF) {
+ addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl,
+ stats_type);
+ if (addr) {
+ vfe40_ctrl->afbfStatsControl.bufToRender =
+ vfe40_process_stats_irq_common(
+ vfe40_ctrl, statsAfNum,
+ addr);
+ process_stats = true;
+ } else {
+ vfe40_ctrl->afbfStatsControl.bufToRender = 0;
+ vfe40_ctrl->afbfStatsControl.droppedStatsFrameCount++;
+ }
+ } else {
+ vfe40_ctrl->afbfStatsControl.bufToRender = 0;
+ }
+
if (status_bits & VFE_IRQ_STATUS0_STATS_IHIST) {
addr = (uint32_t)vfe40_stats_dqbuf(vfe40_ctrl,
MSM_STATS_TYPE_IHIST);
@@ -3071,7 +4366,6 @@
struct vfe40_ctrl_type *vfe40_ctrl, uint32_t irqstatus)
{
uint32_t status_bits = VFE_COM_STATUS & irqstatus;
-
if ((vfe40_ctrl->hfr_mode != HFR_MODE_OFF) &&
(vfe40_ctrl->share_ctrl->vfeFrameId %
vfe40_ctrl->hfr_mode != 0)) {
@@ -3101,14 +4395,34 @@
CDBG("irq regUpdateIrq\n");
vfe40_process_reg_update_irq(vfe40_ctrl);
break;
+ case VFE_IRQ_STATUS0_RDI0_REG_UPDATE:
+ CDBG("irq rdi0 regUpdateIrq\n");
+ vfe40_process_rdi0_reg_update_irq(vfe40_ctrl);
+ break;
+ case VFE_IRQ_STATUS0_RDI1_REG_UPDATE:
+ CDBG("irq rdi1 regUpdateIrq\n");
+ vfe40_process_rdi1_reg_update_irq(vfe40_ctrl);
+ break;
case VFE_IMASK_WHILE_STOPPING_0:
CDBG("irq resetAckIrq\n");
vfe40_process_reset_irq(vfe40_ctrl);
break;
+ case VFE_IRQ_STATUS0_STATS_BG:
+ CDBG("Stats BG irq occured.\n");
+ vfe40_process_stats_bg_irq(vfe40_ctrl);
+ break;
+ case VFE_IRQ_STATUS0_STATS_BF:
+ CDBG("Stats BF irq occured.\n");
+ vfe40_process_stats_bf_irq(vfe40_ctrl);
+ break;
case VFE_IRQ_STATUS0_STATS_AWB:
CDBG("Stats AWB irq occured.\n");
vfe40_process_stats_awb_irq(vfe40_ctrl);
break;
+ case VFE_IRQ_STATUS0_STATS_SKIN_BHIST:
+ CDBG("Stats BHIST irq occured.\n");
+ vfe40_process_stats_bhist_irq(vfe40_ctrl);
+ break;
case VFE_IRQ_STATUS0_STATS_IHIST:
CDBG("Stats IHIST irq occured.\n");
vfe40_process_stats_ihist_irq(vfe40_ctrl);
@@ -3148,15 +4462,17 @@
{
unsigned long flags;
struct axi_ctrl_t *axi_ctrl = (struct axi_ctrl_t *)data;
+ struct vfe40_ctrl_type *vfe40_ctrl = axi_ctrl->share_ctrl->vfe40_ctrl;
struct vfe40_isr_queue_cmd *qcmd = NULL;
+ int stat_interrupt;
CDBG("=== axi40_do_tasklet start ===\n");
- while (atomic_read(&axi_ctrl->share_ctrl->irq_cnt)) {
+ while (atomic_read(&irq_cnt)) {
spin_lock_irqsave(&axi_ctrl->tasklet_lock, flags);
qcmd = list_first_entry(&axi_ctrl->tasklet_q,
struct vfe40_isr_queue_cmd, list);
- atomic_sub(1, &axi_ctrl->share_ctrl->irq_cnt);
+ atomic_sub(1, &irq_cnt);
if (!qcmd) {
spin_unlock_irqrestore(&axi_ctrl->tasklet_lock,
@@ -3168,38 +4484,82 @@
spin_unlock_irqrestore(&axi_ctrl->tasklet_lock,
flags);
+ if (axi_ctrl->share_ctrl->stats_comp) {
+ stat_interrupt = (qcmd->vfeInterruptStatus0 &
+ VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK_0);
+ } else {
+ stat_interrupt =
+ (qcmd->vfeInterruptStatus0 &
+ VFE_IRQ_STATUS0_STATS_BG) |
+ (qcmd->vfeInterruptStatus0 &
+ VFE_IRQ_STATUS0_STATS_AWB) |
+ (qcmd->vfeInterruptStatus0 &
+ VFE_IRQ_STATUS0_STATS_BF) |
+ (qcmd->vfeInterruptStatus0 &
+ VFE_IRQ_STATUS0_STATS_IHIST) |
+ (qcmd->vfeInterruptStatus0 &
+ VFE_IRQ_STATUS0_STATS_RS) |
+ (qcmd->vfeInterruptStatus0 &
+ VFE_IRQ_STATUS0_STATS_CS);
+ }
if (qcmd->vfeInterruptStatus0 &
- VFE_IRQ_STATUS0_CAMIF_SOF_MASK)
- v4l2_subdev_notify(&axi_ctrl->subdev,
+ VFE_IRQ_STATUS0_CAMIF_SOF_MASK) {
+ if (stat_interrupt)
+ vfe40_ctrl->simultaneous_sof_stat = 1;
+ v4l2_subdev_notify(&vfe40_ctrl->subdev,
NOTIFY_VFE_IRQ,
(void *)VFE_IRQ_STATUS0_CAMIF_SOF_MASK);
+ }
/* interrupt to be processed, *qcmd has the payload. */
if (qcmd->vfeInterruptStatus0 &
- VFE_IRQ_STATUS0_REG_UPDATE_MASK) {
- v4l2_subdev_notify(&axi_ctrl->subdev,
+ VFE_IRQ_STATUS0_REG_UPDATE_MASK)
+ v4l2_subdev_notify(&vfe40_ctrl->subdev,
NOTIFY_VFE_IRQ,
(void *)VFE_IRQ_STATUS0_REG_UPDATE_MASK);
- }
+
+ if (qcmd->vfeInterruptStatus1 &
+ VFE_IRQ_STATUS0_RDI0_REG_UPDATE_MASK)
+ v4l2_subdev_notify(&vfe40_ctrl->subdev,
+ NOTIFY_VFE_IRQ,
+ (void *)VFE_IRQ_STATUS0_RDI0_REG_UPDATE);
+
+ if (qcmd->vfeInterruptStatus1 &
+ VFE_IRQ_STATUS0_RDI1_REG_UPDATE_MASK)
+ v4l2_subdev_notify(&vfe40_ctrl->subdev,
+ NOTIFY_VFE_IRQ,
+ (void *)VFE_IRQ_STATUS0_RDI1_REG_UPDATE);
if (qcmd->vfeInterruptStatus0 &
VFE_IMASK_WHILE_STOPPING_0)
- v4l2_subdev_notify(&axi_ctrl->subdev,
+ v4l2_subdev_notify(&vfe40_ctrl->subdev,
NOTIFY_VFE_IRQ,
(void *)VFE_IMASK_WHILE_STOPPING_0);
+ if (atomic_read(&axi_ctrl->share_ctrl->handle_common_irq)) {
+ if (qcmd->vfeInterruptStatus1 &
+ VFE40_IMASK_COMMON_ERROR_ONLY_1) {
+ pr_err("irq errorIrq\n");
+ vfe40_process_common_error_irq(
+ axi_ctrl,
+ qcmd->vfeInterruptStatus1 &
+ VFE40_IMASK_COMMON_ERROR_ONLY_1);
+ }
+
+ v4l2_subdev_notify(&axi_ctrl->subdev,
+ NOTIFY_AXI_IRQ,
+ (void *)qcmd->vfeInterruptStatus0);
+ }
+
if (atomic_read(&axi_ctrl->share_ctrl->vstate)) {
if (qcmd->vfeInterruptStatus1 &
- VFE40_IMASK_ERROR_ONLY_1) {
+ VFE40_IMASK_VFE_ERROR_ONLY_1) {
pr_err("irq errorIrq\n");
vfe40_process_error_irq(
axi_ctrl,
qcmd->vfeInterruptStatus1 &
- VFE40_IMASK_ERROR_ONLY_1);
+ VFE40_IMASK_VFE_ERROR_ONLY_1);
}
- v4l2_subdev_notify(&axi_ctrl->subdev,
- NOTIFY_AXI_IRQ,
- (void *)qcmd->vfeInterruptStatus0);
/* then process stats irq. */
if (axi_ctrl->share_ctrl->stats_comp) {
@@ -3207,54 +4567,74 @@
if (qcmd->vfeInterruptStatus0 &
VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK_0) {
CDBG("Stats composite irq occured.\n");
- v4l2_subdev_notify(&axi_ctrl->subdev,
+ v4l2_subdev_notify(&vfe40_ctrl->subdev,
NOTIFY_VFE_IRQ,
(void *)qcmd->vfeInterruptStatus0);
}
} else {
/* process individual stats interrupt. */
if (qcmd->vfeInterruptStatus0 &
+ VFE_IRQ_STATUS0_STATS_BG)
+ v4l2_subdev_notify(&vfe40_ctrl->subdev,
+ NOTIFY_VFE_IRQ,
+ (void *)VFE_IRQ_STATUS0_STATS_BG);
+
+ if (qcmd->vfeInterruptStatus0 &
VFE_IRQ_STATUS0_STATS_AWB)
- v4l2_subdev_notify(&axi_ctrl->subdev,
+ v4l2_subdev_notify(&vfe40_ctrl->subdev,
NOTIFY_VFE_IRQ,
(void *)VFE_IRQ_STATUS0_STATS_AWB);
+
+ if (qcmd->vfeInterruptStatus0 &
+ VFE_IRQ_STATUS0_STATS_BF)
+ v4l2_subdev_notify(&vfe40_ctrl->subdev,
+ NOTIFY_VFE_IRQ,
+ (void *)VFE_IRQ_STATUS0_STATS_BF);
+ if (qcmd->vfeInterruptStatus0 &
+ VFE_IRQ_STATUS0_STATS_SKIN_BHIST)
+ v4l2_subdev_notify(&vfe40_ctrl->subdev,
+ NOTIFY_VFE_IRQ,
+ (void *)
+ VFE_IRQ_STATUS0_STATS_SKIN_BHIST);
+
if (qcmd->vfeInterruptStatus0 &
VFE_IRQ_STATUS0_STATS_IHIST)
- v4l2_subdev_notify(&axi_ctrl->subdev,
+ v4l2_subdev_notify(&vfe40_ctrl->subdev,
NOTIFY_VFE_IRQ,
(void *)VFE_IRQ_STATUS0_STATS_IHIST);
if (qcmd->vfeInterruptStatus0 &
VFE_IRQ_STATUS0_STATS_RS)
- v4l2_subdev_notify(&axi_ctrl->subdev,
+ v4l2_subdev_notify(&vfe40_ctrl->subdev,
NOTIFY_VFE_IRQ,
(void *)VFE_IRQ_STATUS0_STATS_RS);
if (qcmd->vfeInterruptStatus0 &
VFE_IRQ_STATUS0_STATS_CS)
- v4l2_subdev_notify(&axi_ctrl->subdev,
+ v4l2_subdev_notify(&vfe40_ctrl->subdev,
NOTIFY_VFE_IRQ,
(void *)VFE_IRQ_STATUS0_STATS_CS);
if (qcmd->vfeInterruptStatus0 &
VFE_IRQ_STATUS1_SYNC_TIMER0)
- v4l2_subdev_notify(&axi_ctrl->subdev,
+ v4l2_subdev_notify(&vfe40_ctrl->subdev,
NOTIFY_VFE_IRQ,
(void *)VFE_IRQ_STATUS1_SYNC_TIMER0);
if (qcmd->vfeInterruptStatus0 &
VFE_IRQ_STATUS1_SYNC_TIMER1)
- v4l2_subdev_notify(&axi_ctrl->subdev,
+ v4l2_subdev_notify(&vfe40_ctrl->subdev,
NOTIFY_VFE_IRQ,
(void *)VFE_IRQ_STATUS1_SYNC_TIMER1);
if (qcmd->vfeInterruptStatus0 &
VFE_IRQ_STATUS1_SYNC_TIMER2)
- v4l2_subdev_notify(&axi_ctrl->subdev,
+ v4l2_subdev_notify(&vfe40_ctrl->subdev,
NOTIFY_VFE_IRQ,
(void *)VFE_IRQ_STATUS1_SYNC_TIMER2);
}
}
+ vfe40_ctrl->simultaneous_sof_stat = 0;
kfree(qcmd);
}
CDBG("=== axi40_do_tasklet end ===\n");
@@ -3299,12 +4679,22 @@
spin_lock_irqsave(&axi_ctrl->tasklet_lock, flags);
list_add_tail(&qcmd->list, &axi_ctrl->tasklet_q);
- atomic_add(1, &axi_ctrl->share_ctrl->irq_cnt);
+ atomic_add(1, &irq_cnt);
spin_unlock_irqrestore(&axi_ctrl->tasklet_lock, flags);
tasklet_schedule(&axi_ctrl->vfe40_tasklet);
return IRQ_HANDLED;
}
+int msm_axi_subdev_isr_routine(struct v4l2_subdev *sd,
+ u32 status, bool *handled)
+{
+ struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
+ irqreturn_t ret;
+ CDBG("%s E ", __func__);
+ ret = vfe40_parse_irq(axi_ctrl->vfeirq->start, axi_ctrl);
+ *handled = TRUE;
+ return 0;
+}
static long vfe_stats_bufq_sub_ioctl(
struct vfe40_ctrl_type *vfe_ctrl,
@@ -3378,6 +4768,22 @@
vfe_ctrl->stats_ops.client);
}
break;
+ case VFE_CMD_STATS_UNREGBUF:
+ {
+ struct msm_stats_reqbuf *req_buf = NULL;
+ req_buf = (struct msm_stats_reqbuf *)cmd->value;
+ if (sizeof(struct msm_stats_reqbuf) != cmd->length) {
+ /* error. the length not match */
+ pr_err("%s: stats reqbuf input size = %d,\n"
+ "struct size = %d, mitch match\n",
+ __func__, cmd->length,
+ sizeof(struct msm_stats_reqbuf));
+ rc = -EINVAL ;
+ goto end;
+ }
+ rc = vfe40_stats_unregbuf(vfe_ctrl, req_buf, domain_num);
+ }
+ break;
default:
rc = -1;
pr_err("%s: cmd_type %d not supported", __func__,
@@ -3396,10 +4802,9 @@
struct vfe40_ctrl_type *vfe40_ctrl =
(struct vfe40_ctrl_type *)v4l2_get_subdevdata(sd);
struct msm_isp_cmd vfecmd;
- struct msm_camvfe_params *vfe_params =
- (struct msm_camvfe_params *)arg;
- struct msm_vfe_cfg_cmd *cmd = vfe_params->vfe_cfg;
- void *data = vfe_params->data;
+ struct msm_camvfe_params *vfe_params;
+ struct msm_vfe_cfg_cmd *cmd;
+ void *data;
long rc = 0;
struct vfe_cmd_stats_buf *scfg = NULL;
@@ -3410,6 +4815,17 @@
return -EFAULT;
}
+ CDBG("%s\n", __func__);
+ if (subdev_cmd == VIDIOC_MSM_VFE_INIT) {
+ CDBG("%s init\n", __func__);
+ return msm_vfe_subdev_init(sd);
+ } else if (subdev_cmd == VIDIOC_MSM_VFE_RELEASE) {
+ msm_vfe_subdev_release(sd);
+ return 0;
+ }
+ vfe_params = (struct msm_camvfe_params *)arg;
+ cmd = vfe_params->vfe_cfg;
+ data = vfe_params->data;
switch (cmd->cmd_type) {
case CMD_VFE_PROCESS_IRQ:
vfe40_process_irq(vfe40_ctrl, (uint32_t) data);
@@ -3417,27 +4833,33 @@
case VFE_CMD_STATS_REQBUF:
case VFE_CMD_STATS_ENQUEUEBUF:
case VFE_CMD_STATS_FLUSH_BUFQ:
+ case VFE_CMD_STATS_UNREGBUF:
/* for easy porting put in one envelope */
rc = vfe_stats_bufq_sub_ioctl(vfe40_ctrl,
cmd, vfe_params->data, pmctl->domain_num);
return rc;
default:
if (cmd->cmd_type != CMD_CONFIG_PING_ADDR &&
- cmd->cmd_type != CMD_CONFIG_PONG_ADDR &&
- cmd->cmd_type != CMD_CONFIG_FREE_BUF_ADDR &&
- cmd->cmd_type != CMD_STATS_AEC_BUF_RELEASE &&
- cmd->cmd_type != CMD_STATS_AWB_BUF_RELEASE &&
- cmd->cmd_type != CMD_STATS_IHIST_BUF_RELEASE &&
- cmd->cmd_type != CMD_STATS_RS_BUF_RELEASE &&
- cmd->cmd_type != CMD_STATS_CS_BUF_RELEASE &&
- cmd->cmd_type != CMD_STATS_AF_BUF_RELEASE) {
- if (copy_from_user(&vfecmd,
+ cmd->cmd_type != CMD_CONFIG_PONG_ADDR &&
+ cmd->cmd_type != CMD_CONFIG_FREE_BUF_ADDR &&
+ cmd->cmd_type != CMD_STATS_AEC_BUF_RELEASE &&
+ cmd->cmd_type != CMD_STATS_AWB_BUF_RELEASE &&
+ cmd->cmd_type != CMD_STATS_IHIST_BUF_RELEASE &&
+ cmd->cmd_type != CMD_STATS_RS_BUF_RELEASE &&
+ cmd->cmd_type != CMD_STATS_CS_BUF_RELEASE &&
+ cmd->cmd_type != CMD_STATS_AF_BUF_RELEASE &&
+ cmd->cmd_type != CMD_STATS_BG_BUF_RELEASE &&
+ cmd->cmd_type != CMD_STATS_BF_BUF_RELEASE &&
+ cmd->cmd_type != CMD_STATS_BHIST_BUF_RELEASE &&
+ cmd->cmd_type != CMD_VFE_PIX_SOF_COUNT_UPDATE &&
+ cmd->cmd_type != CMD_VFE_COUNT_PIX_SOF_ENABLE) {
+ if (copy_from_user(&vfecmd,
(void __user *)(cmd->value),
sizeof(vfecmd))) {
- pr_err("%s %d: copy_from_user failed\n",
- __func__, __LINE__);
- return -EFAULT;
- }
+ pr_err("%s %d: copy_from_user failed\n",
+ __func__, __LINE__);
+ return -EFAULT;
+ }
} else {
/* here eith stats release or frame release. */
if (cmd->cmd_type != CMD_CONFIG_PING_ADDR &&
@@ -3459,6 +4881,25 @@
sack->nextStatsBuf = *(uint32_t *)data;
}
}
+ }
+
+ CDBG("%s: cmdType = %d\n", __func__, cmd->cmd_type);
+
+ if ((cmd->cmd_type == CMD_STATS_AF_ENABLE) ||
+ (cmd->cmd_type == CMD_STATS_AWB_ENABLE) ||
+ (cmd->cmd_type == CMD_STATS_IHIST_ENABLE) ||
+ (cmd->cmd_type == CMD_STATS_RS_ENABLE) ||
+ (cmd->cmd_type == CMD_STATS_CS_ENABLE) ||
+ (cmd->cmd_type == CMD_STATS_AEC_ENABLE) ||
+ (cmd->cmd_type == CMD_STATS_BG_ENABLE) ||
+ (cmd->cmd_type == CMD_STATS_BF_ENABLE) ||
+ (cmd->cmd_type == CMD_STATS_BHIST_ENABLE)) {
+ struct axidata *axid;
+ axid = data;
+ if (!axid) {
+ rc = -EFAULT;
+ goto vfe40_config_done;
+ }
CDBG("%s: cmdType = %d\n", __func__, cmd->cmd_type);
if ((cmd->cmd_type == CMD_STATS_AF_ENABLE) ||
@@ -3472,39 +4913,69 @@
goto vfe40_config_done;
}
switch (cmd->cmd_type) {
- case CMD_GENERAL:
- rc = vfe40_proc_general(pmctl, &vfecmd, vfe40_ctrl);
- break;
- case CMD_CONFIG_PING_ADDR: {
- int path = *((int *)cmd->value);
- struct vfe40_output_ch *outch =
- vfe40_get_ch(path, vfe40_ctrl->share_ctrl);
- outch->ping = *((struct msm_free_buf *)data);
- }
- break;
-
- case CMD_CONFIG_PONG_ADDR: {
- int path = *((int *)cmd->value);
- struct vfe40_output_ch *outch =
- vfe40_get_ch(path, vfe40_ctrl->share_ctrl);
- outch->pong = *((struct msm_free_buf *)data);
- }
- break;
-
- case CMD_CONFIG_FREE_BUF_ADDR: {
- int path = *((int *)cmd->value);
- struct vfe40_output_ch *outch =
- vfe40_get_ch(path, vfe40_ctrl->share_ctrl);
- outch->free_buf = *((struct msm_free_buf *)data);
- }
- break;
- case CMD_SNAP_BUF_RELEASE:
- break;
+ case CMD_STATS_AEC_ENABLE:
+ case CMD_STATS_BG_ENABLE:
+ case CMD_STATS_BF_ENABLE:
+ case CMD_STATS_BHIST_ENABLE:
+ case CMD_STATS_AWB_ENABLE:
+ case CMD_STATS_IHIST_ENABLE:
+ case CMD_STATS_RS_ENABLE:
+ case CMD_STATS_CS_ENABLE:
default:
- pr_err("%s Unsupported AXI configuration %x ", __func__,
- cmd->cmd_type);
- break;
+ pr_err("%s Unsupported cmd type %d",
+ __func__, cmd->cmd_type);
+ break;
}
+ goto vfe40_config_done;
+ }
+ switch (cmd->cmd_type) {
+ case CMD_GENERAL:
+ rc = vfe40_proc_general(pmctl, &vfecmd, vfe40_ctrl);
+ break;
+ case CMD_VFE_COUNT_PIX_SOF_ENABLE: {
+ int enable = *((int *)cmd->value);
+ if (enable)
+ vfe40_ctrl->vfe_sof_count_enable = TRUE;
+ else
+ vfe40_ctrl->vfe_sof_count_enable = false;
+ }
+ break;
+ case CMD_VFE_PIX_SOF_COUNT_UPDATE:
+ if (!vfe40_ctrl->vfe_sof_count_enable)
+ vfe40_ctrl->share_ctrl->vfeFrameId =
+ *((uint32_t *)vfe_params->data);
+ break;
+ case CMD_CONFIG_PING_ADDR: {
+ int path = *((int *)cmd->value);
+ struct vfe40_output_ch *outch =
+ vfe40_get_ch(path, vfe40_ctrl->share_ctrl);
+ outch->ping = *((struct msm_free_buf *)data);
+ }
+ break;
+
+ case CMD_CONFIG_PONG_ADDR: {
+ int path = *((int *)cmd->value);
+ struct vfe40_output_ch *outch =
+ vfe40_get_ch(path, vfe40_ctrl->share_ctrl);
+ outch->pong = *((struct msm_free_buf *)data);
+ }
+ break;
+
+ case CMD_CONFIG_FREE_BUF_ADDR: {
+ int path = *((int *)cmd->value);
+ struct vfe40_output_ch *outch =
+ vfe40_get_ch(path, vfe40_ctrl->share_ctrl);
+ outch->free_buf = *((struct msm_free_buf *)data);
+ }
+ break;
+
+ case CMD_SNAP_BUF_RELEASE:
+ break;
+
+ default:
+ pr_err("%s Unsupported AXI configuration %x ", __func__,
+ cmd->cmd_type);
+ break;
}
vfe40_config_done:
kfree(scfg);
@@ -3513,6 +4984,39 @@
return rc;
}
+static struct msm_cam_clk_info vfe40_clk_info[] = {
+ {"camss_top_ahb_clk", -1},
+ {"vfe_clk_src", 266670000},
+ {"camss_vfe_vfe_clk", -1},
+ {"camss_csi_vfe_clk", -1},
+ {"iface_clk", -1},
+ {"bus_clk", -1},
+ {"alt_bus_clk", -1},
+};
+
+static int msm_axi_subdev_s_crystal_freq(struct v4l2_subdev *sd,
+ u32 freq, u32 flags)
+{
+ int rc = 0;
+ int round_rate;
+ struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
+
+ round_rate = clk_round_rate(axi_ctrl->vfe_clk[1], freq);
+ if (rc < 0) {
+ pr_err("%s: clk_round_rate failed %d\n",
+ __func__, rc);
+ return rc;
+ }
+
+ vfe_clk_rate = round_rate;
+ rc = clk_set_rate(axi_ctrl->vfe_clk[1], round_rate);
+ if (rc < 0)
+ pr_err("%s: clk_set_rate failed %d\n",
+ __func__, rc);
+
+ return rc;
+}
+
static const struct v4l2_subdev_core_ops msm_vfe_subdev_core_ops = {
.ioctl = msm_vfe_subdev_ioctl,
};
@@ -3521,46 +5025,1088 @@
.core = &msm_vfe_subdev_core_ops,
};
-int msm_vfe_subdev_init(struct v4l2_subdev *sd,
- struct msm_cam_media_controller *mctl)
+static void msm_vfe40_init_vbif_parms(void __iomem *vfe_vbif_base)
+{
+ msm_camera_io_w_mb(0x1,
+ vfe_vbif_base + VFE40_VBIF_CLKON);
+ msm_camera_io_w_mb(0x1,
+ vfe_vbif_base + VFE40_VBIF_ROUND_ROBIN_QOS_ARB);
+ msm_camera_io_w_mb(0xFFFF,
+ vfe_vbif_base + VFE40_VBIF_OUT_AXI_AOOO_EN);
+ msm_camera_io_w_mb(0xFFFFFFFF,
+ vfe_vbif_base + VFE40_VBIF_OUT_AXI_AOOO);
+
+ msm_camera_io_w_mb(0x10101010,
+ vfe_vbif_base + VFE40_VBIF_IN_RD_LIM_CONF0);
+ msm_camera_io_w_mb(0x10101010,
+ vfe_vbif_base + VFE40_VBIF_IN_RD_LIM_CONF1);
+ msm_camera_io_w_mb(0x10101010,
+ vfe_vbif_base + VFE40_VBIF_IN_RD_LIM_CONF2);
+ msm_camera_io_w_mb(0x10101010,
+ vfe_vbif_base + VFE40_VBIF_IN_WR_LIM_CONF0);
+ msm_camera_io_w_mb(0x10101010,
+ vfe_vbif_base + VFE40_VBIF_IN_WR_LIM_CONF1);
+ msm_camera_io_w_mb(0x10101010,
+ vfe_vbif_base + VFE40_VBIF_IN_WR_LIM_CONF2);
+ msm_camera_io_w_mb(0x00001010,
+ vfe_vbif_base + VFE40_VBIF_OUT_RD_LIM_CONF0);
+ msm_camera_io_w_mb(0x00001010,
+ vfe_vbif_base + VFE40_VBIF_OUT_WR_LIM_CONF0);
+ msm_camera_io_w_mb(0x00000707,
+ vfe_vbif_base + VFE40_VBIF_DDR_OUT_MAX_BURST);
+ msm_camera_io_w_mb(0x00000030,
+ vfe_vbif_base + VFE40_VBIF_ARB_CTL);
+ msm_camera_io_w_mb(0x04210842,
+ vfe_vbif_base + VFE40_VBIF_DDR_ARB_CONF0);
+ msm_camera_io_w_mb(0x04210842,
+ vfe_vbif_base + VFE40_VBIF_DDR_ARB_CONF1);
+}
+
+int msm_axi_subdev_init(struct v4l2_subdev *sd)
+{
+ int rc = 0;
+ struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
+ struct msm_cam_media_controller *mctl;
+ mctl = v4l2_get_subdev_hostdata(sd);
+ if (mctl == NULL) {
+ pr_err("%s: mctl is NULL\n", __func__);
+ rc = -EINVAL;
+ goto mctl_failed;
+ }
+ axi_ctrl->share_ctrl->axi_ref_cnt++;
+ if (axi_ctrl->share_ctrl->axi_ref_cnt > 1)
+ return rc;
+
+ spin_lock_init(&axi_ctrl->tasklet_lock);
+ INIT_LIST_HEAD(&axi_ctrl->tasklet_q);
+ spin_lock_init(&axi_ctrl->share_ctrl->sd_notify_lock);
+
+ axi_ctrl->share_ctrl->vfebase = ioremap(axi_ctrl->vfemem->start,
+ resource_size(axi_ctrl->vfemem));
+ if (!axi_ctrl->share_ctrl->vfebase) {
+ rc = -ENOMEM;
+ pr_err("%s: vfe ioremap failed\n", __func__);
+ goto remap_failed;
+ }
+
+ axi_ctrl->share_ctrl->vfe_vbif_base =
+ ioremap(axi_ctrl->vfe_vbif_mem->start,
+ resource_size(axi_ctrl->vfe_vbif_mem));
+ if (!axi_ctrl->share_ctrl->vfe_vbif_base) {
+ rc = -ENOMEM;
+ pr_err("%s: vfe ioremap failed\n", __func__);
+ goto remap_failed;
+ }
+
+ if (axi_ctrl->fs_vfe) {
+ rc = regulator_enable(axi_ctrl->fs_vfe);
+ if (rc) {
+ pr_err("%s: Regulator enable failed\n", __func__);
+ goto fs_failed;
+ }
+ }
+
+ rc = msm_cam_clk_enable(&axi_ctrl->pdev->dev, vfe40_clk_info,
+ axi_ctrl->vfe_clk, ARRAY_SIZE(vfe40_clk_info), 1);
+ if (rc < 0)
+ goto clk_enable_failed;
+
+ axi_ctrl->bus_perf_client =
+ msm_bus_scale_register_client(&vfe_bus_client_pdata);
+ if (!axi_ctrl->bus_perf_client) {
+ pr_err("%s: Registration Failed!\n", __func__);
+ axi_ctrl->bus_perf_client = 0;
+ goto bus_scale_register_failed;
+ }
+
+ msm_camera_bus_scale_cfg(axi_ctrl->bus_perf_client, S_PREVIEW);
+
+ rc = iommu_attach_device(mctl->domain, axi_ctrl->iommu_ctx);
+ if (rc < 0) {
+ pr_err("%s: imgwr attach failed rc = %d\n", __func__, rc);
+ rc = -ENODEV;
+ goto device_imgwr_attach_failed;
+ }
+
+ msm_vfe40_init_vbif_parms(axi_ctrl->share_ctrl->vfe_vbif_base);
+
+ axi_ctrl->share_ctrl->register_total = VFE40_REGISTER_TOTAL;
+
+ spin_lock_init(&axi_ctrl->share_ctrl->stop_flag_lock);
+ spin_lock_init(&axi_ctrl->share_ctrl->update_ack_lock);
+ spin_lock_init(&axi_ctrl->share_ctrl->start_ack_lock);
+ init_completion(&axi_ctrl->share_ctrl->reset_complete);
+
+ if (!axi_ctrl->use_irq_router)
+ enable_irq(axi_ctrl->vfeirq->start);
+
+ return rc;
+
+bus_scale_register_failed:
+ msm_cam_clk_enable(&axi_ctrl->pdev->dev, vfe40_clk_info,
+ axi_ctrl->vfe_clk, ARRAY_SIZE(vfe40_clk_info), 0);
+clk_enable_failed:
+ if (axi_ctrl->fs_vfe)
+ regulator_disable(axi_ctrl->fs_vfe);
+fs_failed:
+ iounmap(axi_ctrl->share_ctrl->vfebase);
+ axi_ctrl->share_ctrl->vfebase = NULL;
+remap_failed:
+ iommu_detach_device(mctl->domain, axi_ctrl->iommu_ctx);
+device_imgwr_attach_failed:
+ if (!axi_ctrl->use_irq_router)
+ disable_irq(axi_ctrl->vfeirq->start);
+mctl_failed:
+ return rc;
+}
+
+int msm_vfe_subdev_init(struct v4l2_subdev *sd)
{
int rc = 0;
struct vfe40_ctrl_type *vfe40_ctrl =
(struct vfe40_ctrl_type *)v4l2_get_subdevdata(sd);
- v4l2_set_subdev_hostdata(sd, mctl);
- spin_lock_init(&vfe40_ctrl->share_ctrl->stop_flag_lock);
spin_lock_init(&vfe40_ctrl->state_lock);
- spin_lock_init(&vfe40_ctrl->io_lock);
- spin_lock_init(&vfe40_ctrl->update_ack_lock);
spin_lock_init(&vfe40_ctrl->stats_bufq_lock);
-
vfe40_ctrl->update_linear = false;
vfe40_ctrl->update_rolloff = false;
vfe40_ctrl->update_la = false;
vfe40_ctrl->update_gamma = false;
+ vfe40_ctrl->vfe_sof_count_enable = true;
vfe40_ctrl->hfr_mode = HFR_MODE_OFF;
+ memset(&vfe40_ctrl->stats_ctrl, 0,
+ sizeof(struct msm_stats_bufq_ctrl));
+ memset(&vfe40_ctrl->stats_ops, 0, sizeof(struct msm_stats_ops));
+
return rc;
}
+void msm_axi_subdev_release(struct v4l2_subdev *sd)
+{
+ struct msm_cam_media_controller *pmctl =
+ (struct msm_cam_media_controller *)v4l2_get_subdev_hostdata(sd);
+ struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
+ if (!axi_ctrl->share_ctrl->vfebase) {
+ pr_err("%s: base address unmapped\n", __func__);
+ return;
+ }
+
+ CDBG("%s, free_irq\n", __func__);
+ axi_ctrl->share_ctrl->axi_ref_cnt--;
+ if (axi_ctrl->share_ctrl->axi_ref_cnt > 0)
+ return;
+ if (!axi_ctrl->use_irq_router)
+ disable_irq(axi_ctrl->vfeirq->start);
+ tasklet_kill(&axi_ctrl->vfe40_tasklet);
+
+ iommu_detach_device(pmctl->domain, axi_ctrl->iommu_ctx);
+
+ msm_cam_clk_enable(&axi_ctrl->pdev->dev, vfe40_clk_info,
+ axi_ctrl->vfe_clk, ARRAY_SIZE(vfe40_clk_info), 0);
+ if (axi_ctrl->fs_vfe)
+ regulator_disable(axi_ctrl->fs_vfe);
+
+ iounmap(axi_ctrl->share_ctrl->vfebase);
+ iounmap(axi_ctrl->share_ctrl->vfe_vbif_base);
+ axi_ctrl->share_ctrl->vfebase = NULL;
+
+ if (atomic_read(&irq_cnt))
+ pr_warning("%s, Warning IRQ Count not ZERO\n", __func__);
+
+ msm_camera_bus_scale_cfg(axi_ctrl->bus_perf_client, S_EXIT);
+ axi_ctrl->bus_perf_client = 0;
+
+ msm_vfe_subdev_release(&axi_ctrl->share_ctrl->vfe40_ctrl->subdev);
+}
+
void msm_vfe_subdev_release(struct v4l2_subdev *sd)
{
struct vfe40_ctrl_type *vfe40_ctrl =
(struct vfe40_ctrl_type *)v4l2_get_subdevdata(sd);
- if (!vfe40_ctrl->share_ctrl->vfebase)
- vfe40_ctrl->share_ctrl->vfebase = NULL;
+ CDBG("vfe subdev release %p\n",
+ vfe40_ctrl->share_ctrl->vfebase);
}
+void axi_abort(struct axi_ctrl_t *axi_ctrl)
+{
+ uint8_t axi_busy_flag = true;
+ unsigned long flags;
+ /* axi halt command. */
+
+ spin_lock_irqsave(&axi_ctrl->share_ctrl->stop_flag_lock, flags);
+ axi_ctrl->share_ctrl->stop_ack_pending = TRUE;
+ spin_unlock_irqrestore(&axi_ctrl->share_ctrl->stop_flag_lock, flags);
+ msm_camera_io_w(AXI_HALT,
+ axi_ctrl->share_ctrl->vfebase + VFE_AXI_CMD);
+ wmb();
+ while (axi_busy_flag) {
+ if (msm_camera_io_r(
+ axi_ctrl->share_ctrl->vfebase + VFE_AXI_STATUS) & 0x1)
+ axi_busy_flag = false;
+ }
+ /* Ensure the write order while writing
+ * to the command register using the barrier */
+ msm_camera_io_w_mb(AXI_HALT_CLEAR,
+ axi_ctrl->share_ctrl->vfebase + VFE_AXI_CMD);
+
+ /* after axi halt, then ok to apply global reset.
+ * enable reset_ack and async timer interrupt only while
+ * stopping the pipeline.*/
+ msm_camera_io_w(0x80000000,
+ axi_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_0);
+ msm_camera_io_w(0xF0000000,
+ axi_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_1);
+
+ /* Ensure the write order while writing
+ * to the command register using the barrier */
+ msm_camera_io_w_mb(VFE_RESET_UPON_STOP_CMD,
+ axi_ctrl->share_ctrl->vfebase + VFE_GLOBAL_RESET);
+ if (axi_ctrl->share_ctrl->sync_abort)
+ wait_for_completion_interruptible(
+ &axi_ctrl->share_ctrl->reset_complete);
+}
+
+int axi_config_buffers(struct axi_ctrl_t *axi_ctrl,
+ struct msm_camera_vfe_params_t vfe_params)
+{
+ uint16_t vfe_mode = axi_ctrl->share_ctrl->current_mode
+ & ~(VFE_OUTPUTS_RDI0|VFE_OUTPUTS_RDI1);
+ int rc = 0;
+ switch (vfe_params.cmd_type) {
+ case AXI_CMD_PREVIEW:
+ if (vfe_mode) {
+ if ((axi_ctrl->share_ctrl->current_mode &
+ VFE_OUTPUTS_PREVIEW_AND_VIDEO) ||
+ (axi_ctrl->share_ctrl->current_mode &
+ VFE_OUTPUTS_PREVIEW))
+ /* Configure primary channel */
+ rc = configure_pingpong_buffers(
+ VFE_MSG_START,
+ VFE_MSG_OUTPUT_PRIMARY,
+ axi_ctrl);
+ else
+ /* Configure secondary channel */
+ rc = configure_pingpong_buffers(
+ VFE_MSG_START,
+ VFE_MSG_OUTPUT_SECONDARY,
+ axi_ctrl);
+ }
+ if (axi_ctrl->share_ctrl->current_mode &
+ VFE_OUTPUTS_RDI0)
+ rc = configure_pingpong_buffers(
+ VFE_MSG_START, VFE_MSG_OUTPUT_TERTIARY1,
+ axi_ctrl);
+ if (axi_ctrl->share_ctrl->current_mode &
+ VFE_OUTPUTS_RDI1)
+ rc = configure_pingpong_buffers(
+ VFE_MSG_START, VFE_MSG_OUTPUT_TERTIARY2,
+ axi_ctrl);
+
+ if (rc < 0) {
+ pr_err("%s error configuring pingpong buffers for preview",
+ __func__);
+ rc = -EINVAL;
+ goto config_done;
+ }
+ break;
+ case AXI_CMD_RAW_CAPTURE:
+ rc = configure_pingpong_buffers(
+ VFE_MSG_CAPTURE, VFE_MSG_OUTPUT_PRIMARY,
+ axi_ctrl);
+ if (rc < 0) {
+ pr_err("%s error configuring pingpong buffers for snapshot",
+ __func__);
+ rc = -EINVAL;
+ goto config_done;
+ }
+ break;
+ case AXI_CMD_ZSL:
+ rc = configure_pingpong_buffers(VFE_MSG_START,
+ VFE_MSG_OUTPUT_PRIMARY, axi_ctrl);
+ if (rc < 0)
+ goto config_done;
+ rc = configure_pingpong_buffers(VFE_MSG_START,
+ VFE_MSG_OUTPUT_SECONDARY, axi_ctrl);
+ if (rc < 0)
+ goto config_done;
+ break;
+ case AXI_CMD_RECORD:
+ if (axi_ctrl->share_ctrl->current_mode &
+ VFE_OUTPUTS_PREVIEW_AND_VIDEO) {
+ axi_ctrl->share_ctrl->outpath.out1.inst_handle =
+ vfe_params.inst_handle;
+ rc = configure_pingpong_buffers(
+ VFE_MSG_START_RECORDING,
+ VFE_MSG_OUTPUT_SECONDARY,
+ axi_ctrl);
+ } else if (axi_ctrl->share_ctrl->current_mode &
+ VFE_OUTPUTS_VIDEO_AND_PREVIEW) {
+ axi_ctrl->share_ctrl->outpath.out0.inst_handle =
+ vfe_params.inst_handle;
+ rc = configure_pingpong_buffers(
+ VFE_MSG_START_RECORDING,
+ VFE_MSG_OUTPUT_PRIMARY,
+ axi_ctrl);
+ }
+ if (rc < 0) {
+ pr_err("%s error configuring pingpong buffers for video",
+ __func__);
+ rc = -EINVAL;
+ goto config_done;
+ }
+ break;
+ case AXI_CMD_LIVESHOT:
+ axi_ctrl->share_ctrl->outpath.out0.inst_handle =
+ vfe_params.inst_handle;
+ rc = configure_pingpong_buffers(VFE_MSG_CAPTURE,
+ VFE_MSG_OUTPUT_PRIMARY, axi_ctrl);
+ if (rc < 0) {
+ pr_err("%s error configuring pingpong buffers for primary output",
+ __func__);
+ rc = -EINVAL;
+ goto config_done;
+ }
+ break;
+ case AXI_CMD_CAPTURE:
+ if (axi_ctrl->share_ctrl->current_mode ==
+ VFE_OUTPUTS_JPEG_AND_THUMB ||
+ axi_ctrl->share_ctrl->current_mode ==
+ VFE_OUTPUTS_THUMB_AND_JPEG) {
+
+ /* Configure primary channel for JPEG */
+ rc = configure_pingpong_buffers(
+ VFE_MSG_JPEG_CAPTURE,
+ VFE_MSG_OUTPUT_PRIMARY,
+ axi_ctrl);
+ } else {
+ /* Configure primary channel */
+ rc = configure_pingpong_buffers(
+ VFE_MSG_CAPTURE,
+ VFE_MSG_OUTPUT_PRIMARY,
+ axi_ctrl);
+ }
+ if (rc < 0) {
+ pr_err("%s error configuring pingpong buffers for primary output",
+ __func__);
+ rc = -EINVAL;
+ goto config_done;
+ }
+ /* Configure secondary channel */
+ rc = configure_pingpong_buffers(
+ VFE_MSG_CAPTURE, VFE_MSG_OUTPUT_SECONDARY,
+ axi_ctrl);
+ if (rc < 0) {
+ pr_err("%s error configuring pingpong buffers for secondary output",
+ __func__);
+ rc = -EINVAL;
+ goto config_done;
+ }
+ break;
+ default:
+ rc = -EINVAL;
+ break;
+
+ }
+config_done:
+ return rc;
+}
+
+void axi_start(struct msm_cam_media_controller *pmctl,
+ struct axi_ctrl_t *axi_ctrl, struct msm_camera_vfe_params_t vfe_params)
+{
+ uint32_t irq_comp_mask = 0, irq_mask = 0;
+ int rc = 0;
+ uint32_t reg_update = 0;
+ uint16_t operation_mode =
+ (axi_ctrl->share_ctrl->current_mode &
+ ~(VFE_OUTPUTS_RDI0|VFE_OUTPUTS_RDI1));
+ rc = axi_config_buffers(axi_ctrl, vfe_params);
+ if (rc < 0)
+ return;
+
+ switch (vfe_params.cmd_type) {
+ case AXI_CMD_PREVIEW:
+ msm_camera_bus_scale_cfg(axi_ctrl->bus_perf_client, S_PREVIEW);
+ break;
+ case AXI_CMD_CAPTURE:
+ case AXI_CMD_RAW_CAPTURE:
+ msm_camera_bus_scale_cfg(axi_ctrl->bus_perf_client, S_CAPTURE);
+ break;
+ case AXI_CMD_RECORD:
+ msm_camera_bus_scale_cfg(axi_ctrl->bus_perf_client, S_VIDEO);
+ return;
+ case AXI_CMD_ZSL:
+ msm_camera_bus_scale_cfg(axi_ctrl->bus_perf_client, S_ZSL);
+ break;
+ case AXI_CMD_LIVESHOT:
+ msm_camera_bus_scale_cfg(axi_ctrl->bus_perf_client, S_LIVESHOT);
+ return;
+ default:
+ return;
+ }
+
+ irq_comp_mask =
+ msm_camera_io_r(axi_ctrl->share_ctrl->vfebase +
+ VFE_IRQ_COMP_MASK);
+ irq_mask = msm_camera_io_r(axi_ctrl->share_ctrl->vfebase +
+ VFE_IRQ_MASK_0);
+
+ if (axi_ctrl->share_ctrl->outpath.output_mode &
+ VFE40_OUTPUT_MODE_PRIMARY) {
+ irq_comp_mask |= (
+ 0x1 << axi_ctrl->share_ctrl->outpath.out0.ch0 |
+ 0x1 << axi_ctrl->share_ctrl->outpath.out0.ch1);
+ irq_mask |= VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK;
+ } else if (axi_ctrl->share_ctrl->outpath.output_mode &
+ VFE40_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
+ irq_comp_mask |= (
+ 0x1 << axi_ctrl->share_ctrl->outpath.out0.ch0 |
+ 0x1 << axi_ctrl->share_ctrl->outpath.out0.ch1 |
+ 0x1 << axi_ctrl->share_ctrl->outpath.out0.ch2);
+ irq_mask |= VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK;
+ }
+ if (axi_ctrl->share_ctrl->outpath.output_mode &
+ VFE40_OUTPUT_MODE_SECONDARY) {
+ irq_comp_mask |= (
+ 0x1 << (axi_ctrl->share_ctrl->outpath.out1.ch0 + 8) |
+ 0x1 << (axi_ctrl->share_ctrl->outpath.out1.ch1 + 8));
+ irq_mask |= VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK;
+ } else if (axi_ctrl->share_ctrl->outpath.output_mode &
+ VFE40_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
+ irq_comp_mask |= (
+ 0x1 << (axi_ctrl->share_ctrl->outpath.out1.ch0 + 8) |
+ 0x1 << (axi_ctrl->share_ctrl->outpath.out1.ch1 + 8) |
+ 0x1 << (axi_ctrl->share_ctrl->outpath.out1.ch2 + 8));
+ irq_mask |= VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK;
+ }
+ if (axi_ctrl->share_ctrl->outpath.output_mode &
+ VFE40_OUTPUT_MODE_TERTIARY1) {
+ irq_mask |= (0x1 << (axi_ctrl->share_ctrl->outpath.out2.ch0 +
+ VFE_WM_OFFSET));
+ }
+ if (axi_ctrl->share_ctrl->outpath.output_mode &
+ VFE40_OUTPUT_MODE_TERTIARY2) {
+ irq_mask |= (0x1 << (axi_ctrl->share_ctrl->outpath.out3.ch0 +
+ VFE_WM_OFFSET));
+ }
+
+ msm_camera_io_w(irq_comp_mask,
+ axi_ctrl->share_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+ msm_camera_io_w(irq_mask, axi_ctrl->share_ctrl->vfebase +
+ VFE_IRQ_MASK_0);
+
+ switch (vfe_params.cmd_type) {
+ case AXI_CMD_PREVIEW: {
+ switch (operation_mode) {
+ case VFE_OUTPUTS_PREVIEW:
+ case VFE_OUTPUTS_PREVIEW_AND_VIDEO:
+ if (axi_ctrl->share_ctrl->outpath.output_mode &
+ VFE40_OUTPUT_MODE_PRIMARY) {
+ msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
+ + vfe40_AXI_WM_CFG[axi_ctrl->
+ share_ctrl->outpath.out0.ch0]);
+ msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
+ + vfe40_AXI_WM_CFG[axi_ctrl->
+ share_ctrl->outpath.out0.ch1]);
+ } else if (axi_ctrl->share_ctrl->outpath.output_mode &
+ VFE40_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
+ msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
+ + vfe40_AXI_WM_CFG[axi_ctrl->
+ share_ctrl->outpath.out0.ch0]);
+ msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
+ + vfe40_AXI_WM_CFG[axi_ctrl->
+ share_ctrl->outpath.out0.ch1]);
+ msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
+ + vfe40_AXI_WM_CFG[axi_ctrl->
+ share_ctrl->outpath.out0.ch2]);
+ }
+ break;
+ default:
+ if (axi_ctrl->share_ctrl->outpath.output_mode &
+ VFE40_OUTPUT_MODE_SECONDARY) {
+ msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
+ + vfe40_AXI_WM_CFG[axi_ctrl->
+ share_ctrl->outpath.out1.ch0]);
+ msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
+ + vfe40_AXI_WM_CFG[axi_ctrl->
+ share_ctrl->outpath.out1.ch1]);
+ } else if (axi_ctrl->share_ctrl->outpath.output_mode &
+ VFE40_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
+ msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
+ + vfe40_AXI_WM_CFG[axi_ctrl->
+ share_ctrl->outpath.out1.ch0]);
+ msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
+ + vfe40_AXI_WM_CFG[axi_ctrl->
+ share_ctrl->outpath.out1.ch1]);
+ msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase
+ + vfe40_AXI_WM_CFG[axi_ctrl->
+ share_ctrl->outpath.out1.ch2]);
+ }
+ break;
+ }
+ }
+ break;
+ default:
+ if (axi_ctrl->share_ctrl->outpath.output_mode &
+ VFE40_OUTPUT_MODE_PRIMARY) {
+ msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+ vfe40_AXI_WM_CFG[axi_ctrl->
+ share_ctrl->outpath.out0.ch0]);
+ msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+ vfe40_AXI_WM_CFG[axi_ctrl->
+ share_ctrl->outpath.out0.ch1]);
+ } else if (axi_ctrl->share_ctrl->outpath.output_mode &
+ VFE40_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
+ msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+ vfe40_AXI_WM_CFG[axi_ctrl->
+ share_ctrl->outpath.out0.ch0]);
+ msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+ vfe40_AXI_WM_CFG[axi_ctrl->
+ share_ctrl->outpath.out0.ch1]);
+ msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+ vfe40_AXI_WM_CFG[axi_ctrl->
+ share_ctrl->outpath.out0.ch2]);
+ }
+
+ if (axi_ctrl->share_ctrl->outpath.output_mode &
+ VFE40_OUTPUT_MODE_SECONDARY) {
+ msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+ vfe40_AXI_WM_CFG[axi_ctrl->
+ share_ctrl->outpath.out1.ch0]);
+ msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+ vfe40_AXI_WM_CFG[axi_ctrl->
+ share_ctrl->outpath.out1.ch1]);
+ } else if (axi_ctrl->share_ctrl->outpath.output_mode &
+ VFE40_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
+ msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+ vfe40_AXI_WM_CFG[axi_ctrl->
+ share_ctrl->outpath.out1.ch0]);
+ msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+ vfe40_AXI_WM_CFG[axi_ctrl->
+ share_ctrl->outpath.out1.ch1]);
+ msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+ vfe40_AXI_WM_CFG[axi_ctrl->
+ share_ctrl->outpath.out1.ch2]);
+ }
+ break;
+ }
+ if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI0)
+ msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+ vfe40_AXI_WM_CFG[axi_ctrl->share_ctrl->
+ outpath.out2.ch0]);
+ if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI1)
+ msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
+ vfe40_AXI_WM_CFG[axi_ctrl->share_ctrl->
+ outpath.out3.ch0]);
+
+ if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI0) {
+ irq_mask |= VFE_IRQ_STATUS0_RDI0_REG_UPDATE_MASK;
+ if (!atomic_cmpxchg(
+ &axi_ctrl->share_ctrl->rdi0_update_ack_pending,
+ 0, 1))
+ reg_update |= 0x2;
+ }
+ if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI1) {
+ irq_mask |= VFE_IRQ_STATUS0_RDI1_REG_UPDATE_MASK;
+ if (!atomic_cmpxchg(
+ &axi_ctrl->share_ctrl->rdi1_update_ack_pending,
+ 0, 1))
+ reg_update |= 0x4;
+ }
+ msm_camera_io_w(irq_mask, axi_ctrl->share_ctrl->vfebase +
+ VFE_IRQ_MASK_0);
+ if (operation_mode) {
+ if (!atomic_cmpxchg(
+ &axi_ctrl->share_ctrl->pix0_update_ack_pending,
+ 0, 1))
+ reg_update |= 0x1;
+ }
+
+ msm_camera_io_w_mb(reg_update,
+ axi_ctrl->share_ctrl->vfebase +
+ VFE_REG_UPDATE_CMD);
+ axi_ctrl->share_ctrl->operation_mode |=
+ axi_ctrl->share_ctrl->current_mode;
+ axi_enable_irq(axi_ctrl->share_ctrl);
+}
+
+void axi_stop(struct msm_cam_media_controller *pmctl,
+ struct axi_ctrl_t *axi_ctrl, struct msm_camera_vfe_params_t vfe_params)
+{
+ uint32_t reg_update = 0;
+ uint32_t operation_mode =
+ axi_ctrl->share_ctrl->current_mode & ~(VFE_OUTPUTS_RDI0|
+ VFE_OUTPUTS_RDI1);
+
+ switch (vfe_params.cmd_type) {
+ case AXI_CMD_PREVIEW:
+ case AXI_CMD_CAPTURE:
+ case AXI_CMD_RAW_CAPTURE:
+ case AXI_CMD_ZSL:
+ break;
+ case AXI_CMD_RECORD:
+ msm_camera_bus_scale_cfg(axi_ctrl->bus_perf_client, S_PREVIEW);
+ return;
+ case AXI_CMD_LIVESHOT:
+ msm_camera_bus_scale_cfg(axi_ctrl->bus_perf_client, S_VIDEO);
+ return;
+ default:
+ return;
+ }
+
+ if (axi_ctrl->share_ctrl->stop_immediately) {
+ axi_disable_irq(axi_ctrl->share_ctrl);
+ axi_stop_process(axi_ctrl->share_ctrl);
+ return;
+ }
+
+ if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI0) {
+ if (!atomic_cmpxchg(
+ &axi_ctrl->share_ctrl->rdi0_update_ack_pending, 0, 2))
+ reg_update |= 0x2;
+ }
+ if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI1) {
+ if (!atomic_cmpxchg(
+ &axi_ctrl->share_ctrl->rdi1_update_ack_pending, 0, 2))
+ reg_update |= 0x4;
+ }
+ if (operation_mode) {
+ if (!atomic_cmpxchg(
+ &axi_ctrl->share_ctrl->pix0_update_ack_pending, 0, 2))
+ reg_update |= 0x1;
+ }
+ msm_camera_io_w_mb(reg_update,
+ axi_ctrl->share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+}
+
+static int msm_axi_config(struct v4l2_subdev *sd, void __user *arg)
+{
+ struct msm_vfe_cfg_cmd cfgcmd;
+ struct msm_isp_cmd vfecmd;
+ struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
+ struct msm_cam_media_controller *pmctl =
+ (struct msm_cam_media_controller *)v4l2_get_subdev_hostdata(sd);
+ int rc = 0, vfe_cmd_type = 0, rdi_mode = 0;
+
+ if (!axi_ctrl->share_ctrl->vfebase) {
+ pr_err("%s: base address unmapped\n", __func__);
+ return -EFAULT;
+ }
+ memset(&cfgcmd, 0, sizeof(struct msm_vfe_cfg_cmd));
+ if (NULL != arg) {
+ if (copy_from_user(&cfgcmd, arg, sizeof(cfgcmd))) {
+ ERR_COPY_FROM_USER();
+ return -EFAULT;
+ }
+ }
+ memset(&vfecmd, 0, sizeof(struct msm_isp_cmd));
+ if (NULL != cfgcmd.value) {
+ if (copy_from_user(&vfecmd,
+ (void __user *)(cfgcmd.value),
+ sizeof(vfecmd))) {
+ pr_err("%s %d: copy_from_user failed\n", __func__,
+ __LINE__);
+ return -EFAULT;
+ }
+ }
+
+ vfe_cmd_type = (cfgcmd.cmd_type & ~(CMD_AXI_CFG_TERT1|
+ CMD_AXI_CFG_TERT2));
+ switch (cfgcmd.cmd_type) {
+ case CMD_AXI_CFG_TERT1:{
+ uint32_t *axio = NULL;
+ axio = kmalloc(vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length,
+ GFP_ATOMIC);
+ if (!axio)
+ return -ENOMEM;
+
+ if (copy_from_user(axio, (void __user *)(vfecmd.value),
+ vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+ kfree(axio);
+ return -EFAULT;
+ }
+ vfe40_config_axi(axi_ctrl, OUTPUT_TERT1, axio);
+ kfree(axio);
+ return rc;
+ }
+ case CMD_AXI_CFG_TERT2:{
+ uint32_t *axio = NULL;
+ axio = kmalloc(vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length,
+ GFP_ATOMIC);
+ if (!axio)
+ return -ENOMEM;
+
+ if (copy_from_user(axio, (void __user *)(vfecmd.value),
+ vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+ kfree(axio);
+ return -EFAULT;
+ }
+ vfe40_config_axi(axi_ctrl, OUTPUT_TERT2, axio);
+ kfree(axio);
+ return rc;
+ }
+ case CMD_AXI_CFG_TERT1|CMD_AXI_CFG_TERT2:{
+ uint32_t *axio = NULL;
+ axio = kmalloc(vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length,
+ GFP_ATOMIC);
+ if (!axio)
+ return -ENOMEM;
+
+ if (copy_from_user(axio, (void __user *)(vfecmd.value),
+ vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+ kfree(axio);
+ return -EFAULT;
+ }
+ vfe40_config_axi(axi_ctrl, OUTPUT_TERT1|OUTPUT_TERT2, axio);
+ kfree(axio);
+ return rc;
+ }
+ default:
+ if (cfgcmd.cmd_type & CMD_AXI_CFG_TERT1)
+ rdi_mode |= OUTPUT_TERT1;
+ if (cfgcmd.cmd_type & CMD_AXI_CFG_TERT2)
+ rdi_mode |= OUTPUT_TERT2;
+ }
+ switch (vfe_cmd_type) {
+ case CMD_AXI_CFG_PRIM: {
+ uint32_t *axio = NULL;
+ axio = kmalloc(vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length,
+ GFP_ATOMIC);
+ if (!axio) {
+ rc = -ENOMEM;
+ break;
+ }
+
+ if (copy_from_user(axio, (void __user *)(vfecmd.value),
+ vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+ kfree(axio);
+ rc = -EFAULT;
+ break;
+ }
+ vfe40_config_axi(axi_ctrl, rdi_mode|OUTPUT_PRIM, axio);
+ kfree(axio);
+ break;
+ }
+ case CMD_AXI_CFG_PRIM_ALL_CHNLS: {
+ uint32_t *axio = NULL;
+ axio = kmalloc(vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length,
+ GFP_ATOMIC);
+ if (!axio) {
+ rc = -ENOMEM;
+ break;
+ }
+
+ if (copy_from_user(axio, (void __user *)(vfecmd.value),
+ vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+ kfree(axio);
+ rc = -EFAULT;
+ break;
+ }
+ vfe40_config_axi(axi_ctrl, rdi_mode|OUTPUT_PRIM_ALL_CHNLS,
+ axio);
+ kfree(axio);
+ break;
+ }
+ case CMD_AXI_CFG_PRIM|CMD_AXI_CFG_SEC: {
+ uint32_t *axio = NULL;
+ axio = kmalloc(vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length,
+ GFP_ATOMIC);
+ if (!axio) {
+ rc = -ENOMEM;
+ break;
+ }
+
+ if (copy_from_user(axio, (void __user *)(vfecmd.value),
+ vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+ kfree(axio);
+ rc = -EFAULT;
+ break;
+ }
+ vfe40_config_axi(axi_ctrl,
+ rdi_mode|OUTPUT_PRIM|OUTPUT_SEC, axio);
+ kfree(axio);
+ break;
+ }
+ case CMD_AXI_CFG_PRIM|CMD_AXI_CFG_SEC_ALL_CHNLS: {
+ uint32_t *axio = NULL;
+ axio = kmalloc(vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length,
+ GFP_ATOMIC);
+ if (!axio) {
+ rc = -ENOMEM;
+ break;
+ }
+
+ if (copy_from_user(axio, (void __user *)(vfecmd.value),
+ vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+ kfree(axio);
+ rc = -EFAULT;
+ break;
+ }
+ vfe40_config_axi(axi_ctrl,
+ rdi_mode|OUTPUT_PRIM|OUTPUT_SEC_ALL_CHNLS, axio);
+ kfree(axio);
+ break;
+ }
+ case CMD_AXI_CFG_PRIM_ALL_CHNLS|CMD_AXI_CFG_SEC: {
+ uint32_t *axio = NULL;
+ axio = kmalloc(vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length,
+ GFP_ATOMIC);
+ if (!axio) {
+ rc = -ENOMEM;
+ break;
+ }
+
+ if (copy_from_user(axio, (void __user *)(vfecmd.value),
+ vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+ kfree(axio);
+ rc = -EFAULT;
+ break;
+ }
+ vfe40_config_axi(axi_ctrl,
+ rdi_mode|OUTPUT_PRIM_ALL_CHNLS|OUTPUT_SEC, axio);
+ kfree(axio);
+ break;
+ }
+
+ case CMD_AXI_CFG_PRIM_ALL_CHNLS|CMD_AXI_CFG_SEC_ALL_CHNLS:
+ pr_err("%s Invalid/Unsupported AXI configuration %x",
+ __func__, cfgcmd.cmd_type);
+ break;
+ case CMD_AXI_START: {
+ struct msm_camera_vfe_params_t vfe_params;
+ if (copy_from_user(&vfe_params,
+ (void __user *)(vfecmd.value),
+ sizeof(struct msm_camera_vfe_params_t))) {
+ return -EFAULT;
+ }
+ axi_ctrl->share_ctrl->current_mode =
+ vfe_params.operation_mode;
+ axi_start(pmctl, axi_ctrl, vfe_params);
+ }
+ break;
+ case CMD_AXI_STOP: {
+ struct msm_camera_vfe_params_t vfe_params;
+ if (copy_from_user(&vfe_params,
+ (void __user *)(vfecmd.value),
+ sizeof(struct msm_camera_vfe_params_t))) {
+ return -EFAULT;
+ }
+ axi_ctrl->share_ctrl->current_mode =
+ vfe_params.operation_mode;
+ axi_ctrl->share_ctrl->stop_immediately =
+ vfe_params.stop_immediately;
+ axi_stop(pmctl, axi_ctrl, vfe_params);
+ }
+ break;
+ case CMD_AXI_RESET:
+ axi_reset(axi_ctrl);
+ break;
+ case CMD_AXI_ABORT:
+ if (copy_from_user(&axi_ctrl->share_ctrl->sync_abort,
+ (void __user *)(vfecmd.value),
+ sizeof(uint8_t))) {
+ return -EFAULT;
+ }
+ axi_abort(axi_ctrl);
+ break;
+ default:
+ pr_err("%s Unsupported AXI configuration %x ", __func__,
+ cfgcmd.cmd_type);
+ break;
+ }
+ return rc;
+}
+
+static void msm_axi_process_irq(struct v4l2_subdev *sd, void *arg)
+{
+ struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
+ uint32_t irqstatus = (uint32_t) arg;
+
+ if (!axi_ctrl->share_ctrl->vfebase) {
+ pr_err("%s: base address unmapped\n", __func__);
+ return;
+ }
+
+ /* next, check output path related interrupts. */
+ if (irqstatus &
+ VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK) {
+ CDBG("Image composite done 0 irq occured.\n");
+ vfe40_process_output_path_irq_0(axi_ctrl);
+ }
+ if (irqstatus &
+ VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK) {
+ CDBG("Image composite done 1 irq occured.\n");
+ vfe40_process_output_path_irq_1(axi_ctrl);
+ }
+
+ if (axi_ctrl->share_ctrl->comp_output_mode &
+ VFE40_OUTPUT_MODE_TERTIARY1)
+ if (irqstatus & (0x1 << (axi_ctrl->share_ctrl->outpath.out2.ch0
+ + VFE_WM_OFFSET)))
+ vfe40_process_output_path_irq_rdi0(axi_ctrl);
+ if (axi_ctrl->share_ctrl->comp_output_mode &
+ VFE40_OUTPUT_MODE_TERTIARY2)
+ if (irqstatus & (0x1 << (axi_ctrl->share_ctrl->outpath.out3.ch0
+ + VFE_WM_OFFSET)))
+ vfe40_process_output_path_irq_rdi1(axi_ctrl);
+
+ /* in snapshot mode if done then send
+ snapshot done message */
+ if (
+ axi_ctrl->share_ctrl->operation_mode &
+ VFE_OUTPUTS_THUMB_AND_MAIN ||
+ axi_ctrl->share_ctrl->operation_mode &
+ VFE_OUTPUTS_MAIN_AND_THUMB ||
+ axi_ctrl->share_ctrl->operation_mode &
+ VFE_OUTPUTS_THUMB_AND_JPEG ||
+ axi_ctrl->share_ctrl->operation_mode &
+ VFE_OUTPUTS_JPEG_AND_THUMB ||
+ axi_ctrl->share_ctrl->operation_mode &
+ VFE_OUTPUTS_RAW) {
+ if ((axi_ctrl->share_ctrl->outpath.out0.capture_cnt == 0)
+ && (axi_ctrl->share_ctrl->outpath.out1.
+ capture_cnt == 0)) {
+ msm_camera_io_w_mb(
+ CAMIF_COMMAND_STOP_IMMEDIATELY,
+ axi_ctrl->share_ctrl->vfebase +
+ VFE_CAMIF_COMMAND);
+ axi_disable_irq(axi_ctrl->share_ctrl);
+ vfe40_send_isp_msg(&axi_ctrl->subdev,
+ axi_ctrl->share_ctrl->vfeFrameId,
+ MSG_ID_PIX0_UPDATE_ACK);
+ vfe40_send_isp_msg(&axi_ctrl->subdev,
+ axi_ctrl->share_ctrl->vfeFrameId,
+ MSG_ID_SNAPSHOT_DONE);
+ }
+ }
+}
+
+static int msm_axi_buf_cfg(struct v4l2_subdev *sd, void __user *arg)
+{
+ struct msm_camvfe_params *vfe_params =
+ (struct msm_camvfe_params *)arg;
+ struct msm_vfe_cfg_cmd *cmd = vfe_params->vfe_cfg;
+ struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
+ void *data = vfe_params->data;
+ int rc = 0;
+
+ if (!axi_ctrl->share_ctrl->vfebase) {
+ pr_err("%s: base address unmapped\n", __func__);
+ return -EFAULT;
+ }
+
+ switch (cmd->cmd_type) {
+ case CMD_CONFIG_PING_ADDR: {
+ int path = *((int *)cmd->value);
+ struct vfe40_output_ch *outch =
+ vfe40_get_ch(path, axi_ctrl->share_ctrl);
+ outch->ping = *((struct msm_free_buf *)data);
+ }
+ break;
+
+ case CMD_CONFIG_PONG_ADDR: {
+ int path = *((int *)cmd->value);
+ struct vfe40_output_ch *outch =
+ vfe40_get_ch(path, axi_ctrl->share_ctrl);
+ outch->pong = *((struct msm_free_buf *)data);
+ }
+ break;
+
+ case CMD_CONFIG_FREE_BUF_ADDR: {
+ int path = *((int *)cmd->value);
+ struct vfe40_output_ch *outch =
+ vfe40_get_ch(path, axi_ctrl->share_ctrl);
+ outch->free_buf = *((struct msm_free_buf *)data);
+ }
+ break;
+ default:
+ pr_err("%s Unsupported AXI Buf config %x ", __func__,
+ cmd->cmd_type);
+ }
+ return rc;
+};
+
static const struct v4l2_subdev_internal_ops msm_vfe_internal_ops;
+static long msm_axi_subdev_ioctl(struct v4l2_subdev *sd,
+ unsigned int cmd, void *arg)
+{
+ int rc = -ENOIOCTLCMD;
+ switch (cmd) {
+ case VIDIOC_MSM_AXI_INIT:
+ rc = msm_axi_subdev_init(sd);
+ break;
+ case VIDIOC_MSM_AXI_CFG:
+ rc = msm_axi_config(sd, arg);
+ break;
+ case VIDIOC_MSM_AXI_IRQ:
+ msm_axi_process_irq(sd, arg);
+ rc = 0;
+ break;
+ case VIDIOC_MSM_AXI_BUF_CFG:
+ msm_axi_buf_cfg(sd, arg);
+ rc = 0;
+ break;
+ case VIDIOC_MSM_AXI_RELEASE:
+ msm_axi_subdev_release(sd);
+ rc = 0;
+ break;
+ case VIDIOC_MSM_AXI_RDI_COUNT_UPDATE: {
+ struct rdi_count_msg *msg = (struct rdi_count_msg *)arg;
+ struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
+ switch (msg->rdi_interface) {
+ case RDI_0:
+ axi_ctrl->share_ctrl->rdi0FrameId = msg->count;
+ rc = 0;
+ break;
+ case RDI_1:
+ axi_ctrl->share_ctrl->rdi1FrameId = msg->count;
+ rc = 0;
+ break;
+ case RDI_2:
+ axi_ctrl->share_ctrl->rdi2FrameId = msg->count;
+ rc = 0;
+ break;
+ default:
+ pr_err("%s: Incorrect interface sent\n", __func__);
+ rc = -EINVAL;
+ break;
+ }
+ break;
+ }
+ default:
+ pr_err("%s: command %d not found\n", __func__,
+ _IOC_NR(cmd));
+ break;
+ }
+ return rc;
+}
+
+static const struct v4l2_subdev_core_ops msm_axi_subdev_core_ops = {
+ .ioctl = msm_axi_subdev_ioctl,
+ .interrupt_service_routine = msm_axi_subdev_isr_routine,
+};
+
+static const struct v4l2_subdev_video_ops msm_axi_subdev_video_ops = {
+ .s_crystal_freq = msm_axi_subdev_s_crystal_freq,
+};
+
+static const struct v4l2_subdev_ops msm_axi_subdev_ops = {
+ .core = &msm_axi_subdev_core_ops,
+ .video = &msm_axi_subdev_video_ops,
+};
+
+static const struct v4l2_subdev_internal_ops msm_axi_internal_ops;
+
static int __devinit vfe40_probe(struct platform_device *pdev)
{
int rc = 0;
struct axi_ctrl_t *axi_ctrl;
struct vfe40_ctrl_type *vfe40_ctrl;
struct vfe_share_ctrl_t *share_ctrl;
+ struct intr_table_entry irq_req;
struct msm_cam_subdev_info sd_info;
CDBG("%s: device id = %d\n", __func__, pdev->id);
@@ -3593,8 +6139,25 @@
share_ctrl->vfe40_ctrl = vfe40_ctrl;
axi_ctrl->share_ctrl = share_ctrl;
vfe40_ctrl->share_ctrl = share_ctrl;
+ axi_ctrl->share_ctrl->axi_ref_cnt = 0;
+ v4l2_subdev_init(&axi_ctrl->subdev, &msm_axi_subdev_ops);
+ axi_ctrl->subdev.internal_ops = &msm_axi_internal_ops;
+ axi_ctrl->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+ snprintf(axi_ctrl->subdev.name,
+ sizeof(axi_ctrl->subdev.name), "axi");
+ v4l2_set_subdevdata(&axi_ctrl->subdev, axi_ctrl);
axi_ctrl->pdev = pdev;
- vfe40_axi_probe(axi_ctrl);
+
+ sd_info.sdev_type = AXI_DEV;
+ sd_info.sd_index = pdev->id;
+ sd_info.irq_num = 0;
+ msm_cam_register_subdev_node(&axi_ctrl->subdev, &sd_info);
+
+ media_entity_init(&axi_ctrl->subdev.entity, 0, NULL, 0);
+ axi_ctrl->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+ axi_ctrl->subdev.entity.group_id = AXI_DEV;
+ axi_ctrl->subdev.entity.name = pdev->name;
+ axi_ctrl->subdev.entity.revision = axi_ctrl->subdev.devnode->num;
v4l2_subdev_init(&vfe40_ctrl->subdev, &msm_vfe_subdev_ops);
vfe40_ctrl->subdev.internal_ops = &msm_vfe_internal_ops;
@@ -3611,6 +6174,15 @@
rc = -ENODEV;
goto vfe40_no_resource;
}
+
+ axi_ctrl->vfe_vbif_mem = platform_get_resource_byname(pdev,
+ IORESOURCE_MEM, "vfe_vbif");
+ if (!axi_ctrl->vfe_vbif_mem) {
+ pr_err("%s: no mem resource?\n", __func__);
+ rc = -ENODEV;
+ goto vfe40_no_resource;
+ }
+
axi_ctrl->vfeirq = platform_get_resource_byname(pdev,
IORESOURCE_IRQ, "vfe");
if (!axi_ctrl->vfeirq) {
@@ -3627,26 +6199,83 @@
goto vfe40_no_resource;
}
- rc = request_irq(axi_ctrl->vfeirq->start, vfe40_parse_irq,
- IRQF_TRIGGER_RISING, "vfe", axi_ctrl);
- if (rc < 0) {
- release_mem_region(axi_ctrl->vfemem->start,
- resource_size(axi_ctrl->vfemem));
- pr_err("%s: irq request fail\n", __func__);
- rc = -EBUSY;
+ axi_ctrl->fs_vfe = regulator_get(&pdev->dev, "vdd");
+ if (IS_ERR(axi_ctrl->fs_vfe)) {
+ pr_err("%s: Regulator get failed %ld\n", __func__,
+ PTR_ERR(axi_ctrl->fs_vfe));
+ axi_ctrl->fs_vfe = NULL;
+ }
+
+ /* Register subdev node before requesting irq since
+ * irq_num is needed by msm_cam_server */
+ sd_info.sdev_type = VFE_DEV;
+ sd_info.sd_index = pdev->id;
+ sd_info.irq_num = axi_ctrl->vfeirq->start;
+ msm_cam_register_subdev_node(&vfe40_ctrl->subdev, &sd_info);
+
+ media_entity_init(&vfe40_ctrl->subdev.entity, 0, NULL, 0);
+ vfe40_ctrl->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+ vfe40_ctrl->subdev.entity.group_id = VFE_DEV;
+ vfe40_ctrl->subdev.entity.name = pdev->name;
+ vfe40_ctrl->subdev.entity.revision = vfe40_ctrl->subdev.devnode->num;
+
+ /* Request for this device irq from the camera server. If the
+ * IRQ Router is present on this target, the interrupt will be
+ * handled by the camera server and the interrupt service
+ * routine called. If the request_irq call returns ENXIO, then
+ * the IRQ Router hardware is not present on this target. We
+ * have to request for the irq ourselves and register the
+ * appropriate interrupt handler. */
+ axi_ctrl->use_irq_router = true;
+ irq_req.cam_hw_idx = MSM_CAM_HW_VFE0 + pdev->id;
+ irq_req.dev_name = "vfe";
+ irq_req.irq_idx = CAMERA_SS_IRQ_8;
+ irq_req.irq_num = axi_ctrl->vfeirq->start;
+ irq_req.is_composite = 0;
+ irq_req.irq_trigger_type = IRQF_TRIGGER_RISING;
+ irq_req.num_hwcore = 1;
+ irq_req.subdev_list[0] = &axi_ctrl->subdev;
+ irq_req.data = (void *)axi_ctrl;
+ rc = msm_cam_server_request_irq(&irq_req);
+ if (rc == -ENXIO) {
+ /* IRQ Router hardware is not present on this hardware.
+ * Request for the IRQ and register the interrupt handler. */
+ axi_ctrl->use_irq_router = false;
+ rc = request_irq(axi_ctrl->vfeirq->start, vfe40_parse_irq,
+ IRQF_TRIGGER_RISING, "vfe", axi_ctrl);
+ if (rc < 0) {
+ release_mem_region(axi_ctrl->vfemem->start,
+ resource_size(axi_ctrl->vfemem));
+ pr_err("%s: irq request fail\n", __func__);
+ rc = -EBUSY;
+ goto vfe40_no_resource;
+ }
+ disable_irq(axi_ctrl->vfeirq->start);
+ } else if (rc < 0) {
+ pr_err("%s Error registering irq ", __func__);
goto vfe40_no_resource;
}
- disable_irq(axi_ctrl->vfeirq->start);
+ /*get device context for IOMMU*/
+ if (pdev->id == 0)
+ axi_ctrl->iommu_ctx = msm_iommu_get_ctx("vfe0");
+ else if (pdev->id == 1)
+ axi_ctrl->iommu_ctx = msm_iommu_get_ctx("vfe1");
+ if (!axi_ctrl->iommu_ctx) {
+ release_mem_region(axi_ctrl->vfemem->start,
+ resource_size(axi_ctrl->vfemem));
+ pr_err("%s: No iommu fw context found\n", __func__);
+ rc = -ENODEV;
+ goto vfe40_no_resource;
+ }
tasklet_init(&axi_ctrl->vfe40_tasklet,
axi40_do_tasklet, (unsigned long)axi_ctrl);
vfe40_ctrl->pdev = pdev;
- sd_info.sdev_type = VFE_DEV;
- sd_info.sd_index = pdev->id;
- sd_info.irq_num = axi_ctrl->vfeirq->start;
- msm_cam_register_subdev_node(&vfe40_ctrl->subdev, &sd_info);
+ /*disable bayer stats by default*/
+ vfe40_ctrl->ver_num.main = 0;
+
return 0;
vfe40_no_resource:
diff --git a/drivers/media/video/msm/vfe/msm_vfe40.h b/drivers/media/video/msm/vfe/msm_vfe40.h
index ab913e2..5b73751 100644
--- a/drivers/media/video/msm/vfe/msm_vfe40.h
+++ b/drivers/media/video/msm/vfe/msm_vfe40.h
@@ -50,7 +50,16 @@
/* reset the pipeline when reset command.
* bit 26-32 = 0, domain reset, bit 0-9 = 1 for module reset. */
-#define VFE_RESET_UPON_RESET_CMD 0x000001ff
+#define VFE_RESET_UPON_RESET_CMD 0x000003ff
+
+/* reset the vfe only when reset command*/
+#define VFE_ONLY_RESET_CMD 0x00000002
+
+/*Vfe module reset command*/
+#define VFE_MODULE_RESET_CMD 0x07ffffff
+
+/* wm bit offset for IRQ MASK and IRQ STATUS register */
+#define VFE_WM_OFFSET 6
/* constants for irq registers */
#define VFE_DISABLE_ALL_IRQS 0
@@ -60,6 +69,9 @@
#define VFE_IRQ_STATUS0_CAMIF_SOF_MASK (0x00000001<<0)
#define VFE_IRQ_STATUS0_REG_UPDATE_MASK (0x00000001<<4)
+#define VFE_IRQ_STATUS0_RDI0_REG_UPDATE_MASK (0x00000001<<5)
+#define VFE_IRQ_STATUS0_RDI1_REG_UPDATE_MASK (0x00000001<<6)
+#define VFE_IRQ_STATUS0_RDI2_REG_UPDATE_MASK (0x00000001<<7)
#define VFE_IRQ_STATUS0_STATS_BE (0x00000001<<16)
#define VFE_IRQ_STATUS0_STATS_BG (0x00000001<<17)
#define VFE_IRQ_STATUS0_STATS_BF (0x00000001<<18)
@@ -84,13 +96,22 @@
#define VFE_IRQ_STATUS1_ASYNC_TIMER2 (0x00000001<<30)
#define VFE_IRQ_STATUS1_ASYNC_TIMER3 (0x00000001<<31)
+/*TODOs the irq status passed from axi to vfe irq handler does not account
+* for 2 irq status registers. So below macro is added to differentiate between
+* same bit set on both irq status registers. This wil be fixed later by passing
+*entire payload to vfe irq handler and parsing there instead of passing just the
+*status bit*/
+
+#define VFE_IRQ_STATUS0_RDI0_REG_UPDATE VFE_IRQ_STATUS0_RDI0_REG_UPDATE_MASK
+#define VFE_IRQ_STATUS0_RDI1_REG_UPDATE VFE_IRQ_STATUS0_RDI1_REG_UPDATE_MASK
+
/* imask for while waiting for stop ack, driver has already
* requested stop, waiting for reset irq, and async timer irq.
- * For irq_status_0, bit 28-32 are for async timer. For
- * irq_status_1, bit 22 for reset irq, bit 23 for axi_halt_ack
+ * For irq_status_1, bit 28-32 are for async timer. For
+ * irq_status_0, bit 31 for reset irq, bit 23 for axi_halt_ack
irq */
#define VFE_IMASK_WHILE_STOPPING_0 0x80000000
-#define VFE_IMASK_WHILE_STOPPING_1 0x00000100
+#define VFE_IMASK_WHILE_STOPPING_1 0xF0000000
/* For ABF bit 4 is set to zero and other's 1 */
#define ABF_MASK 0xFFFFFFF7
@@ -118,9 +139,12 @@
#define CS_ENABLE_MASK (0x00000001<<10)
#define CLF_ENABLE_MASK (0x00000001<<12)
#define IHIST_ENABLE_MASK (0x00000001<<15)
+#define BHIST_ENABLE_MASK (0x00000001<<18)
#define RS_CS_ENABLE_MASK (RS_ENABLE_MASK|CS_ENABLE_MASK)
#define STATS_ENABLE_MASK 0x000487E0 /* bit 18,15,10,9,8,7,6,5*/
+#define STATS_BHIST_ENABLE_MASK (0x00000001<<1)
+
#define VFE_DMI_CFG_DEFAULT 0x00000100
#define HFR_MODE_OFF 1
@@ -175,9 +199,9 @@
#define V40_OPERATION_CFG_LEN 32
-#define V40_AXI_OUT_OFF 0x0000004C
-#define V40_AXI_OUT_LEN 424
-#define V40_AXI_CH_INF_LEN 32
+#define V40_AXI_BUS_CMD_OFF 0x0000004C
+#define V40_AXI_BUS_CFG_LEN 284
+#define V40_AXI_OUT_LEN 344
#define V40_AXI_CFG_LEN 71
#define V40_FOV_ENC_OFF 0x00000854
@@ -213,7 +237,6 @@
#define V40_MESH_ROLL_OFF_CFG_LEN 36
#define V40_MESH_ROLL_OFF_TABLE_SIZE 130
-
#define V40_COLOR_COR_OFF 0x000005D0
#define V40_COLOR_COR_LEN 52
@@ -309,29 +332,6 @@
#define VFE40_LINEARIZATON_TABLE_LENGTH 36
-#define VFE_WM_CFG_BASE 0x0070
-#define VFE_WM_CFG_LEN 0x0024
-
-#define vfe40_get_ch_ping_addr(base, chn) \
- (msm_camera_io_r((base) + VFE_WM_CFG_BASE + VFE_WM_CFG_LEN * (chn)))
-#define vfe40_get_ch_pong_addr(base, chn) \
- (msm_camera_io_r((base) + VFE_WM_CFG_BASE + VFE_WM_CFG_LEN * (chn) + 4))
-#define vfe40_get_ch_addr(ping_pong, base, chn) \
- ((((ping_pong) & (1 << (chn))) == 0) ? \
- (vfe40_get_ch_pong_addr((base), chn)) : \
- (vfe40_get_ch_ping_addr((base), chn)))
-
-#define vfe40_put_ch_ping_addr(base, chn, addr) \
- (msm_camera_io_w((addr), \
- (base) + VFE_WM_CFG_BASE + VFE_WM_CFG_LEN * (chn)))
-#define vfe40_put_ch_pong_addr(base, chn, addr) \
- (msm_camera_io_w((addr), \
- (base) + VFE_WM_CFG_BASE + VFE_WM_CFG_LEN * (chn) + 4))
-#define vfe40_put_ch_addr(ping_pong, base, chn, addr) \
- (((ping_pong) & (1 << (chn))) == 0 ? \
- vfe40_put_ch_pong_addr((base), (chn), (addr)) : \
- vfe40_put_ch_ping_addr((base), (chn), (addr)))
-
struct vfe_cmd_hw_version {
uint32_t minorVersion;
uint32_t majorVersion;
@@ -704,7 +704,7 @@
struct vfe40_output_ch {
struct list_head free_buf_queue;
spinlock_t free_buf_lock;
- uint16_t image_mode;
+ uint32_t inst_handle;
int8_t ch0;
int8_t ch1;
int8_t ch2;
@@ -719,7 +719,8 @@
#define VFE40_IMASK_ERROR_ONLY_0 0x0
/* when normal case, don't want to block error status. */
/* bit 0-21 are error irq bits */
-#define VFE40_IMASK_ERROR_ONLY_1 0x005FFFFF
+#define VFE40_IMASK_COMMON_ERROR_ONLY_1 0x0000FE00
+#define VFE40_IMASK_VFE_ERROR_ONLY_1 0x00FF01FF
#define VFE40_IMASK_CAMIF_ERROR (0x00000001<<0)
#define VFE40_IMASK_BHIST_OVWR (0x00000001<<1)
#define VFE40_IMASK_STATS_CS_OVWR (0x00000001<<2)
@@ -728,21 +729,21 @@
#define VFE40_IMASK_REALIGN_BUF_CB_OVFL (0x00000001<<5)
#define VFE40_IMASK_REALIGN_BUF_CR_OVFL (0x00000001<<6)
#define VFE40_IMASK_VIOLATION (0x00000001<<7)
-#define VFE40_IMASK_IMG_MAST_0_BUS_OVFL (0x00000001<<8)
-#define VFE40_IMASK_IMG_MAST_1_BUS_OVFL (0x00000001<<9)
-#define VFE40_IMASK_IMG_MAST_2_BUS_OVFL (0x00000001<<10)
-#define VFE40_IMASK_IMG_MAST_3_BUS_OVFL (0x00000001<<11)
-#define VFE40_IMASK_IMG_MAST_4_BUS_OVFL (0x00000001<<12)
-#define VFE40_IMASK_IMG_MAST_5_BUS_OVFL (0x00000001<<13)
-#define VFE40_IMASK_IMG_MAST_6_BUS_OVFL (0x00000001<<14)
-#define VFE40_IMASK_STATS_AE_BG_BUS_OVFL (0x00000001<<15)
-#define VFE40_IMASK_STATS_AF_BF_BUS_OVFL (0x00000001<<16)
-#define VFE40_IMASK_STATS_AWB_BUS_OVFL (0x00000001<<17)
-#define VFE40_IMASK_STATS_RS_BUS_OVFL (0x00000001<<18)
-#define VFE40_IMASK_STATS_CS_BUS_OVFL (0x00000001<<19)
-#define VFE40_IMASK_STATS_IHIST_BUS_OVFL (0x00000001<<20)
-#define VFE40_IMASK_STATS_SKIN_BHIST_BUS_OVFL (0x00000001<<21)
-#define VFE40_IMASK_AXI_ERROR (0x00000001<<22)
+#define VFE40_IMASK_IMG_MAST_0_BUS_OVFL (0x00000001<<9)
+#define VFE40_IMASK_IMG_MAST_1_BUS_OVFL (0x00000001<<10)
+#define VFE40_IMASK_IMG_MAST_2_BUS_OVFL (0x00000001<<11)
+#define VFE40_IMASK_IMG_MAST_3_BUS_OVFL (0x00000001<<12)
+#define VFE40_IMASK_IMG_MAST_4_BUS_OVFL (0x00000001<<13)
+#define VFE40_IMASK_IMG_MAST_5_BUS_OVFL (0x00000001<<14)
+#define VFE40_IMASK_IMG_MAST_6_BUS_OVFL (0x00000001<<15)
+#define VFE40_IMASK_STATS_BE_BUS_OVFL (0x00000001<<16)
+#define VFE40_IMASK_STATS_BG_BUS_OVFL (0x00000001<<17)
+#define VFE40_IMASK_STATS_BF_BUS_OVFL (0x00000001<<18)
+#define VFE40_IMASK_STATS_AWB_BUS_OVFL (0x00000001<<19)
+#define VFE40_IMASK_STATS_RS_BUS_OVFL (0x00000001<<10)
+#define VFE40_IMASK_STATS_CS_BUS_OVFL (0x00000001<<21)
+#define VFE40_IMASK_STATS_IHIST_BUS_OVFL (0x00000001<<22)
+#define VFE40_IMASK_STATS_SKIN_BHIST_BUS_OVFL (0x00000001<<23)
#define VFE_COM_STATUS 0x000FE000
@@ -751,7 +752,8 @@
struct vfe40_output_ch out0; /* preview and thumbnail */
struct vfe40_output_ch out1; /* snapshot */
- struct vfe40_output_ch out2; /* video */
+ struct vfe40_output_ch out2; /* rdi0 */
+ struct vfe40_output_ch out3; /* rdi01 */
};
struct vfe40_frame_extra {
@@ -769,9 +771,7 @@
uint32_t frameCounter;
};
-#define VFE_CLEAR_ALL_IRQS 0xffffffff
-
-#define VFE_HW_VERSION 0x00000000
+#define VFE_HW_VERSION 0x00000000
#define VFE_GLOBAL_RESET 0x0000000C
#define VFE_MODULE_RESET 0x00000010
#define VFE_CGC_OVERRIDE 0x00000014
@@ -786,32 +786,67 @@
#define VFE_IRQ_STATUS_1 0x0000003C
#define VFE_IRQ_COMP_MASK 0x00000040
#define VFE_BUS_CMD 0x0000004C
-#define VFE_BUS_PING_PONG_STATUS 0x00000180
-#define VFE_AXI_CMD 0x000001D8
-#define VFE_AXI_STATUS 0x000002C0
-#define VFE_BUS_STATS_PING_PONG_BASE 0x000000F4
+#define VFE_BUS_PING_PONG_STATUS 0x00000268
+#define VFE_AXI_CMD 0x000002C0
+#define VFE_AXI_STATUS 0x000002E4
+#define VFE_BUS_STATS_PING_PONG_BASE 0x00000168
-#define VFE_BUS_STATS_AEC_WR_PING_ADDR 0x000000F4
-#define VFE_BUS_STATS_AEC_WR_PONG_ADDR 0x000000F8
-#define VFE_BUS_STATS_AEC_UB_CFG 0x000000FC
-#define VFE_BUS_STATS_AF_WR_PING_ADDR 0x00000100
-#define VFE_BUS_STATS_AF_WR_PONG_ADDR 0x00000104
-#define VFE_BUS_STATS_AF_UB_CFG 0x00000108
-#define VFE_BUS_STATS_AWB_WR_PING_ADDR 0x0000010C
-#define VFE_BUS_STATS_AWB_WR_PONG_ADDR 0x00000110
-#define VFE_BUS_STATS_AWB_UB_CFG 0x00000114
-#define VFE_BUS_STATS_RS_WR_PING_ADDR 0x00000118
-#define VFE_BUS_STATS_RS_WR_PONG_ADDR 0x0000011C
-#define VFE_BUS_STATS_RS_UB_CFG 0x00000120
-#define VFE_BUS_STATS_CS_WR_PING_ADDR 0x00000124
-#define VFE_BUS_STATS_CS_WR_PONG_ADDR 0x00000128
-#define VFE_BUS_STATS_CS_UB_CFG 0x0000012C
-#define VFE_BUS_STATS_HIST_WR_PING_ADDR 0x00000130
-#define VFE_BUS_STATS_HIST_WR_PONG_ADDR 0x00000134
-#define VFE_BUS_STATS_HIST_UB_CFG 0x00000138
-#define VFE_BUS_STATS_SKIN_WR_PING_ADDR 0x0000013C
-#define VFE_BUS_STATS_SKIN_WR_PONG_ADDR 0x00000140
-#define VFE_BUS_STATS_SKIN_UB_CFG 0x00000144
+#define VFE_BUS_STATS_BE_WR_PING_ADDR 0x00000168
+#define VFE_BUS_STATS_BE_WR_PONG_ADDR 0x0000016C
+#define VFE_BUS_STATS_BE_WR_ADDR_CFG 0x00000170
+#define VFE_BUS_STATS_BE_UB_CFG 0x00000174
+#define VFE_BUS_STATS_BE_WR_FRAMEDROP_PATTERN 0x00000178
+#define VFE_BUS_STATS_BE_WR_IRQ_SUBSAMPLE_PATTERN 0x0000017C
+
+#define VFE_BUS_STATS_BG_WR_PING_ADDR 0x00000180
+#define VFE_BUS_STATS_BG_WR_PONG_ADDR 0x00000184
+#define VFE_BUS_STATS_BG_WR_ADDR_CFG 0x00000188
+#define VFE_BUS_STATS_BG_WR_UB_CFG 0x0000018C
+#define VFE_BUS_STATS_BG_WR_FRAMEDROP_PATTERN 0x00000190
+#define VFE_BUS_STATS_BG_WR_IRQ_SUBSAMPLE_PATTERN 0x00000194
+
+#define VFE_BUS_STATS_BF_WR_PING_ADDR 0x00000198
+#define VFE_BUS_STATS_BF_WR_PONG_ADDR 0x0000019C
+#define VFE_BUS_STATS_BF_WR_ADDR_CFG 0x000001A0
+#define VFE_BUS_STATS_BF_WR_UB_CFG 0x000001A4
+#define VFE_BUS_STATS_BF_WR_FRAMEDROP_PATTERN 0x000001A8
+#define VFE_BUS_STATS_BF_WR_IRQ_SUBSAMPLE_PATTERN 0x000001AC
+
+#define VFE_BUS_STATS_AWB_WR_PING_ADDR 0x000001B0
+#define VFE_BUS_STATS_AWB_WR_PONG_ADDR 0x000001B4
+#define VFE_BUS_STATS_AWB_WR_ADDR_CFG 0x000001B8
+#define VFE_BUS_STATS_AWB_WR_UB_CFG 0x000001BC
+#define VFE_BUS_STATS_AWB_WR_FRAMEDROP_PATTERN 0x000001C0
+#define VFE_BUS_STATS_AWB_WR_IRQ_SUBSAMPLE_PATTERN 0x000001C4
+
+#define VFE_BUS_STATS_RS_WR_PING_ADDR 0x000001C8
+#define VFE_BUS_STATS_RS_WR_PONG_ADDR 0x000001CC
+#define VFE_BUS_STATS_RS_WR_ADDR_CFG 0x000001D0
+#define VFE_BUS_STATS_RS_WR_UB_CFG 0x000001D4
+#define VFE_BUS_STATS_RS_WR_FRAMEDROP_PATTERN 0x000001D8
+#define VFE_BUS_STATS_RS_WR_IRQ_SUBSAMPLE_PATTERN 0x000001DC
+
+#define VFE_BUS_STATS_CS_WR_PING_ADDR 0x000001E0
+#define VFE_BUS_STATS_CS_WR_PONG_ADDR 0x000001E4
+#define VFE_BUS_STATS_CS_WR_ADDR_CFG 0x000001E8
+#define VFE_BUS_STATS_CS_WR_UB_CFG 0x000001EC
+#define VFE_BUS_STATS_CS_WR_FRAMEDROP_PATTERN 0x000001F0
+#define VFE_BUS_STATS_CS_WR_IRQ_SUBSAMPLE_PATTERN 0x000001F4
+
+#define VFE_BUS_STATS_HIST_WR_PING_ADDR 0x000001F8
+#define VFE_BUS_STATS_HIST_WR_PONG_ADDR 0x000001FC
+#define VFE_BUS_STATS_HIST_WR_ADDR_CFG 0x00000200
+#define VFE_BUS_STATS_HIST_WR_UB_CFG 0x00000204
+#define VFE_BUS_STATS_HIST_WR_FRAMEDROP_PATTERN 0x00000208
+#define VFE_BUS_STATS_HIST_WR_IRQ_SUBSAMPLE_PATTERN 0x0000020C
+
+
+#define VFE_BUS_STATS_SKIN_WR_PING_ADDR 0x00000210
+#define VFE_BUS_STATS_SKIN_WR_PONG_ADDR 0x00000214
+#define VFE_BUS_STATS_SKIN_WR_ADDR_CFG 0x00000218
+#define VFE_BUS_STATS_SKIN_WR_UB_CFG 0x0000021C
+#define VFE_BUS_STATS_SKIN_WR_FRAMEDROP_PATTERN 0x00000220
+#define VFE_BUS_STATS_SKIN_WR_IRQ_SUBSAMPLE_PATTERN 0x00000224
#define VFE_0_BUS_BDG_QOS_CFG_0 0x000002C4
#define VFE_0_BUS_BDG_QOS_CFG_1 0x000002C8
@@ -839,13 +874,14 @@
#define VFE_STATS_AWB_SGW_CFG 0x000008CC
#define VFE_DMI_CFG 0x00000910
#define VFE_DMI_ADDR 0x00000914
+#define VFE_DMI_DATA_HI 0x00000918
#define VFE_DMI_DATA_LO 0x0000091C
#define VFE_BUS_IO_FORMAT_CFG 0x00000054
#define VFE_RDI0_CFG 0x000002E8
#define VFE_RDI1_CFG 0x000002EC
#define VFE_RDI2_CFG 0x000002F0
-#define VFE_VIOLATION_STATUS 0x000007B4
+#define VFE_VIOLATION_STATUS 0x00000048
#define VFE40_DMI_DATA_HI 0x00000918
#define VFE40_DMI_DATA_LO 0x0000091C
@@ -860,6 +896,25 @@
#define VFE40_OUTPUT_MODE_PRIMARY_ALL_CHNLS BIT(7)
#define VFE40_OUTPUT_MODE_SECONDARY BIT(8)
#define VFE40_OUTPUT_MODE_SECONDARY_ALL_CHNLS BIT(9)
+#define VFE40_OUTPUT_MODE_TERTIARY1 BIT(10)
+#define VFE40_OUTPUT_MODE_TERTIARY2 BIT(11)
+
+#define VFE40_VBIF_CLKON 0x4
+#define VFE40_VBIF_IN_RD_LIM_CONF0 0xB0
+#define VFE40_VBIF_IN_RD_LIM_CONF1 0xB4
+#define VFE40_VBIF_IN_RD_LIM_CONF2 0xB8
+#define VFE40_VBIF_IN_WR_LIM_CONF0 0xC0
+#define VFE40_VBIF_IN_WR_LIM_CONF1 0xC4
+#define VFE40_VBIF_IN_WR_LIM_CONF2 0xC8
+#define VFE40_VBIF_OUT_RD_LIM_CONF0 0xD0
+#define VFE40_VBIF_OUT_WR_LIM_CONF0 0xD4
+#define VFE40_VBIF_DDR_OUT_MAX_BURST 0xD8
+#define VFE40_VBIF_ARB_CTL 0xF0
+#define VFE40_VBIF_DDR_ARB_CONF0 0xF4
+#define VFE40_VBIF_DDR_ARB_CONF1 0xF8
+#define VFE40_VBIF_ROUND_ROBIN_QOS_ARB 0x124
+#define VFE40_VBIF_OUT_AXI_AOOO_EN 0x178
+#define VFE40_VBIF_OUT_AXI_AOOO 0x17C
struct vfe_stats_control {
uint32_t droppedStatsFrameCount;
@@ -870,26 +925,50 @@
struct vfe_share_ctrl_t {
void __iomem *vfebase;
+ void __iomem *vfe_vbif_base;
uint32_t register_total;
atomic_t vstate;
+ atomic_t handle_common_irq;
uint32_t vfeFrameId;
+ uint32_t rdi0FrameId;
+ uint32_t rdi1FrameId;
+ uint32_t rdi2FrameId;
uint32_t stats_comp;
+ spinlock_t sd_notify_lock;
spinlock_t stop_flag_lock;
int8_t stop_ack_pending;
enum vfe_output_state liveshot_state;
uint32_t vfe_capture_count;
- uint16_t operation_mode; /* streaming or snapshot */
+ uint32_t operation_mode; /* streaming or snapshot */
+ uint32_t current_mode;
struct vfe40_output_path outpath;
- uint32_t ref_count;
- spinlock_t sd_notify_lock;
- uint32_t vfe_clk_rate;
+ uint16_t port_info;
+ uint8_t stop_immediately;
+ uint8_t sync_abort;
+ uint16_t cmd_type;
+ uint8_t vfe_reset_flag;
- atomic_t irq_cnt;
+ uint8_t axi_ref_cnt;
+ uint16_t comp_output_mode;
+
+ struct completion reset_complete;
+
+ spinlock_t update_ack_lock;
+ spinlock_t start_ack_lock;
+
struct axi_ctrl_t *axi_ctrl;
struct vfe40_ctrl_type *vfe40_ctrl;
+ int8_t start_ack_pending;
+ int8_t update_ack_pending;
+ enum vfe_output_state recording_state;
+
+ atomic_t pix0_update_ack_pending;
+ atomic_t rdi0_update_ack_pending;
+ atomic_t rdi1_update_ack_pending;
+ atomic_t rdi2_update_ack_pending;
};
struct axi_ctrl_t {
@@ -902,27 +981,25 @@
void *syncdata;
struct resource *vfemem;
+ struct resource *vfe_vbif_mem;
struct resource *vfeio;
+ struct resource *vfe_vbif_io;
struct regulator *fs_vfe;
- struct clk *vfe_clk[3];
+ struct clk *vfe_clk[7];
struct tasklet_struct vfe40_tasklet;
struct vfe_share_ctrl_t *share_ctrl;
+ struct device *iommu_ctx;
+ uint32_t bus_perf_client;
+ uint32_t use_irq_router;
};
struct vfe40_ctrl_type {
- uint32_t vfeImaskCompositePacked;
-
- spinlock_t update_ack_lock;
spinlock_t state_lock;
- spinlock_t io_lock;
spinlock_t stats_bufq_lock;
uint32_t extlen;
void *extdata;
- int8_t start_ack_pending;
- int8_t reset_ack_pending;
- int8_t update_ack_pending;
- enum vfe_output_state recording_state;
+ int8_t vfe_sof_count_enable;
int8_t update_linear;
int8_t update_rolloff;
int8_t update_la;
@@ -934,18 +1011,14 @@
uint32_t sync_timer_state;
uint32_t sync_timer_number;
- uint32_t output1Pattern;
- uint32_t output1Period;
- uint32_t output2Pattern;
- uint32_t output2Period;
- uint32_t vfeFrameSkipCount;
- uint32_t vfeFrameSkipPeriod;
- struct vfe_stats_control afStatsControl;
+ struct msm_ver_num_info ver_num;
+ struct vfe_stats_control afbfStatsControl;
struct vfe_stats_control awbStatsControl;
- struct vfe_stats_control aecStatsControl;
+ struct vfe_stats_control aecbgStatsControl;
struct vfe_stats_control ihistStatsControl;
struct vfe_stats_control rsStatsControl;
struct vfe_stats_control csStatsControl;
+ struct vfe_stats_control bhistStatsControl;
/* v4l2 subdev */
struct v4l2_subdev subdev;
@@ -956,6 +1029,8 @@
uint32_t snapshot_frame_cnt;
struct msm_stats_bufq_ctrl stats_ctrl;
struct msm_stats_ops stats_ops;
+
+ uint32_t simultaneous_sof_stat;
};
#define statsAeNum 0
@@ -976,227 +1051,4 @@
uint32_t statsBuf[VFE_STATS_BUFFER_COUNT];
};
-void vfe40_subdev_notify(int id, int path, int image_mode,
- struct v4l2_subdev *sd, struct vfe_share_ctrl_t *share_ctrl);
-struct vfe40_output_ch *vfe40_get_ch(
- int path, struct vfe_share_ctrl_t *share_ctrl);
-void vfe40_send_isp_msg(struct v4l2_subdev *sd,
- uint32_t vfeFrameId, uint32_t isp_msg_id);
-void vfe40_axi_probe(struct axi_ctrl_t *axi_ctrl);
-
-static const uint32_t vfe40_AXI_WM_CFG[] = {
- 0x0000006C,
- 0x00000090,
- 0x000000B4,
- 0x000000D8,
- 0x000000FC,
- 0x00000120,
- 0x00000144,
-};
-
-static struct vfe40_cmd_type vfe40_cmd[] = {
-/*0*/
- {VFE_CMD_DUMMY_0},
- {VFE_CMD_SET_CLK},
- {VFE_CMD_RESET},
- {VFE_CMD_START},
- {VFE_CMD_TEST_GEN_START},
-/*5*/
- {VFE_CMD_OPERATION_CFG, V40_OPERATION_CFG_LEN},
- {VFE_CMD_AXI_OUT_CFG, V40_AXI_OUT_LEN, V40_AXI_OUT_OFF, 0xFF},
- {VFE_CMD_CAMIF_CFG, V40_CAMIF_LEN, V40_CAMIF_OFF, 0xFF},
- {VFE_CMD_AXI_INPUT_CFG},
- {VFE_CMD_BLACK_LEVEL_CFG},
-/*10*/
- {VFE_CMD_MESH_ROLL_OFF_CFG},
- {VFE_CMD_DEMUX_CFG, V40_DEMUX_LEN, V40_DEMUX_OFF, 0xFF},
- {VFE_CMD_FOV_CFG},
- {VFE_CMD_MAIN_SCALER_CFG},
- {VFE_CMD_WB_CFG, V40_WB_LEN, V40_WB_OFF, 0xFF},
-/*15*/
- {VFE_CMD_COLOR_COR_CFG, V40_COLOR_COR_LEN, V40_COLOR_COR_OFF, 0xFF},
- {VFE_CMD_RGB_G_CFG, V40_RGB_G_LEN, V40_RGB_G_OFF, 0xFF},
- {VFE_CMD_LA_CFG, V40_LA_LEN, V40_LA_OFF, 0xFF },
- {VFE_CMD_CHROMA_EN_CFG, V40_CHROMA_EN_LEN, V40_CHROMA_EN_OFF, 0xFF},
- {VFE_CMD_CHROMA_SUP_CFG, V40_CHROMA_SUP_LEN, V40_CHROMA_SUP_OFF, 0xFF},
-/*20*/
- {VFE_CMD_MCE_CFG, V40_MCE_LEN, V40_MCE_OFF, 0xFF},
- {VFE_CMD_SK_ENHAN_CFG, V40_SCE_LEN, V40_SCE_OFF, 0xFF},
- {VFE_CMD_ASF_CFG, V40_ASF_LEN, V40_ASF_OFF, 0xFF},
- {VFE_CMD_S2Y_CFG},
- {VFE_CMD_S2CbCr_CFG},
-/*25*/
- {VFE_CMD_CHROMA_SUBS_CFG},
- {VFE_CMD_OUT_CLAMP_CFG, V40_OUT_CLAMP_LEN, V40_OUT_CLAMP_OFF, 0xFF},
- {VFE_CMD_FRAME_SKIP_CFG},
- {VFE_CMD_DUMMY_1},
- {VFE_CMD_DUMMY_2},
-/*30*/
- {VFE_CMD_DUMMY_3},
- {VFE_CMD_UPDATE},
- {VFE_CMD_BL_LVL_UPDATE},
- {VFE_CMD_DEMUX_UPDATE, V40_DEMUX_LEN, V40_DEMUX_OFF, 0xFF},
- {VFE_CMD_FOV_UPDATE},
-/*35*/
- {VFE_CMD_MAIN_SCALER_UPDATE},
- {VFE_CMD_WB_UPDATE, V40_WB_LEN, V40_WB_OFF, 0xFF},
- {VFE_CMD_COLOR_COR_UPDATE, V40_COLOR_COR_LEN, V40_COLOR_COR_OFF, 0xFF},
- {VFE_CMD_RGB_G_UPDATE, V40_RGB_G_LEN, V40_CHROMA_EN_OFF, 0xFF},
- {VFE_CMD_LA_UPDATE, V40_LA_LEN, V40_LA_OFF, 0xFF },
-/*40*/
- {VFE_CMD_CHROMA_EN_UPDATE, V40_CHROMA_EN_LEN, V40_CHROMA_EN_OFF, 0xFF},
- {VFE_CMD_CHROMA_SUP_UPDATE, V40_CHROMA_SUP_LEN,
- V40_CHROMA_SUP_OFF, 0xFF},
- {VFE_CMD_MCE_UPDATE, V40_MCE_LEN, V40_MCE_OFF, 0xFF},
- {VFE_CMD_SK_ENHAN_UPDATE, V40_SCE_LEN, V40_SCE_OFF, 0xFF},
- {VFE_CMD_S2CbCr_UPDATE},
-/*45*/
- {VFE_CMD_S2Y_UPDATE},
- {VFE_CMD_ASF_UPDATE, V40_ASF_UPDATE_LEN, V40_ASF_OFF, 0xFF},
- {VFE_CMD_FRAME_SKIP_UPDATE},
- {VFE_CMD_CAMIF_FRAME_UPDATE},
- {VFE_CMD_STATS_AF_UPDATE},
-/*50*/
- {VFE_CMD_STATS_AE_UPDATE},
- {VFE_CMD_STATS_AWB_UPDATE, V40_STATS_AWB_LEN, V40_STATS_AWB_OFF},
- {VFE_CMD_STATS_RS_UPDATE, V40_STATS_RS_LEN, V40_STATS_RS_OFF},
- {VFE_CMD_STATS_CS_UPDATE, V40_STATS_CS_LEN, V40_STATS_CS_OFF},
- {VFE_CMD_STATS_SKIN_UPDATE},
-/*55*/
- {VFE_CMD_STATS_IHIST_UPDATE, V40_STATS_IHIST_LEN, V40_STATS_IHIST_OFF},
- {VFE_CMD_DUMMY_4},
- {VFE_CMD_EPOCH1_ACK},
- {VFE_CMD_EPOCH2_ACK},
- {VFE_CMD_START_RECORDING},
-/*60*/
- {VFE_CMD_STOP_RECORDING},
- {VFE_CMD_DUMMY_5},
- {VFE_CMD_DUMMY_6},
- {VFE_CMD_CAPTURE, V40_CAPTURE_LEN, 0xFF},
- {VFE_CMD_DUMMY_7},
-/*65*/
- {VFE_CMD_STOP},
- {VFE_CMD_GET_HW_VERSION, V40_GET_HW_VERSION_LEN,
- V40_GET_HW_VERSION_OFF},
- {VFE_CMD_GET_FRAME_SKIP_COUNTS},
- {VFE_CMD_OUTPUT1_BUFFER_ENQ},
- {VFE_CMD_OUTPUT2_BUFFER_ENQ},
-/*70*/
- {VFE_CMD_OUTPUT3_BUFFER_ENQ},
- {VFE_CMD_JPEG_OUT_BUF_ENQ},
- {VFE_CMD_RAW_OUT_BUF_ENQ},
- {VFE_CMD_RAW_IN_BUF_ENQ},
- {VFE_CMD_STATS_AF_ENQ},
-/*75*/
- {VFE_CMD_STATS_AE_ENQ},
- {VFE_CMD_STATS_AWB_ENQ},
- {VFE_CMD_STATS_RS_ENQ},
- {VFE_CMD_STATS_CS_ENQ},
- {VFE_CMD_STATS_SKIN_ENQ},
-/*80*/
- {VFE_CMD_STATS_IHIST_ENQ},
- {VFE_CMD_DUMMY_8},
- {VFE_CMD_JPEG_ENC_CFG},
- {VFE_CMD_DUMMY_9},
- {VFE_CMD_STATS_AF_START},
-/*85*/
- {VFE_CMD_STATS_AF_STOP},
- {VFE_CMD_STATS_AE_START},
- {VFE_CMD_STATS_AE_STOP},
- {VFE_CMD_STATS_AWB_START, V40_STATS_AWB_LEN, V40_STATS_AWB_OFF},
- {VFE_CMD_STATS_AWB_STOP},
-/*90*/
- {VFE_CMD_STATS_RS_START, V40_STATS_RS_LEN, V40_STATS_RS_OFF},
- {VFE_CMD_STATS_RS_STOP},
- {VFE_CMD_STATS_CS_START, V40_STATS_CS_LEN, V40_STATS_CS_OFF},
- {VFE_CMD_STATS_CS_STOP},
- {VFE_CMD_STATS_SKIN_START},
-/*95*/
- {VFE_CMD_STATS_SKIN_STOP},
- {VFE_CMD_STATS_IHIST_START, V40_STATS_IHIST_LEN, V40_STATS_IHIST_OFF},
- {VFE_CMD_STATS_IHIST_STOP},
- {VFE_CMD_DUMMY_10},
- {VFE_CMD_SYNC_TIMER_SETTING, V40_SYNC_TIMER_LEN, V40_SYNC_TIMER_OFF},
-/*100*/
- {VFE_CMD_ASYNC_TIMER_SETTING, V40_ASYNC_TIMER_LEN, V40_ASYNC_TIMER_OFF},
- {VFE_CMD_LIVESHOT},
- {VFE_CMD_LA_SETUP},
- {VFE_CMD_LINEARIZATION_CFG, V40_LINEARIZATION_LEN1,
- V40_LINEARIZATION_OFF1},
- {VFE_CMD_DEMOSAICV3},
-/*105*/
- {VFE_CMD_DEMOSAICV3_ABCC_CFG},
- {VFE_CMD_DEMOSAICV3_DBCC_CFG, V40_DEMOSAICV3_DBCC_LEN,
- V40_DEMOSAICV3_DBCC_OFF},
- {VFE_CMD_DEMOSAICV3_DBPC_CFG},
- {VFE_CMD_DEMOSAICV3_ABF_CFG, V40_DEMOSAICV3_ABF_LEN,
- V40_DEMOSAICV3_ABF_OFF},
- {VFE_CMD_DEMOSAICV3_ABCC_UPDATE},
-/*110*/
- {VFE_CMD_DEMOSAICV3_DBCC_UPDATE, V40_DEMOSAICV3_DBCC_LEN,
- V40_DEMOSAICV3_DBCC_OFF},
- {VFE_CMD_DEMOSAICV3_DBPC_UPDATE},
- {VFE_CMD_XBAR_CFG},
- {VFE_CMD_MODULE_CFG, V40_MODULE_CFG_LEN, V40_MODULE_CFG_OFF},
- {VFE_CMD_ZSL},
-/*115*/
- {VFE_CMD_LINEARIZATION_UPDATE, V40_LINEARIZATION_LEN1,
- V40_LINEARIZATION_OFF1},
- {VFE_CMD_DEMOSAICV3_ABF_UPDATE, V40_DEMOSAICV3_ABF_LEN,
- V40_DEMOSAICV3_ABF_OFF},
- {VFE_CMD_CLF_CFG, V40_CLF_CFG_LEN, V40_CLF_CFG_OFF},
- {VFE_CMD_CLF_LUMA_UPDATE, V40_CLF_LUMA_UPDATE_LEN,
- V40_CLF_LUMA_UPDATE_OFF},
- {VFE_CMD_CLF_CHROMA_UPDATE, V40_CLF_CHROMA_UPDATE_LEN,
- V40_CLF_CHROMA_UPDATE_OFF},
-/*120*/
- {VFE_CMD_PCA_ROLL_OFF_CFG},
- {VFE_CMD_PCA_ROLL_OFF_UPDATE},
- {VFE_CMD_GET_REG_DUMP},
- {VFE_CMD_GET_LINEARIZATON_TABLE},
- {VFE_CMD_GET_MESH_ROLLOFF_TABLE},
-/*125*/
- {VFE_CMD_GET_PCA_ROLLOFF_TABLE},
- {VFE_CMD_GET_RGB_G_TABLE},
- {VFE_CMD_GET_LA_TABLE},
- {VFE_CMD_DEMOSAICV3_UPDATE},
- {VFE_CMD_ACTIVE_REGION_CFG},
-/*130*/
- {VFE_CMD_COLOR_PROCESSING_CONFIG},
- {VFE_CMD_STATS_WB_AEC_CONFIG},
- {VFE_CMD_STATS_WB_AEC_UPDATE},
- {VFE_CMD_Y_GAMMA_CONFIG},
- {VFE_CMD_SCALE_OUTPUT1_CONFIG},
-/*135*/
- {VFE_CMD_SCALE_OUTPUT2_CONFIG},
- {VFE_CMD_CAPTURE_RAW},
- {VFE_CMD_STOP_LIVESHOT},
- {VFE_CMD_RECONFIG_VFE},
- {VFE_CMD_STATS_REQBUF},
-/*140*/
- {VFE_CMD_STATS_ENQUEUEBUF},
- {VFE_CMD_STATS_FLUSH_BUFQ},
- {VFE_CMD_FOV_ENC_CFG, V40_FOV_ENC_LEN, V40_FOV_ENC_OFF, 0xFF},
- {VFE_CMD_FOV_VIEW_CFG, V40_FOV_VIEW_LEN, V40_FOV_VIEW_OFF, 0xFF},
- {VFE_CMD_FOV_ENC_UPDATE, V40_FOV_ENC_LEN, V40_FOV_ENC_OFF, 0xFF},
-/*145*/
- {VFE_CMD_FOV_VIEW_UPDATE, V40_FOV_VIEW_LEN, V40_FOV_VIEW_OFF, 0xFF},
- {VFE_CMD_SCALER_ENC_CFG, V40_SCALER_ENC_LEN, V40_SCALER_ENC_OFF, 0xFF},
- {VFE_CMD_SCALER_VIEW_CFG, V40_SCALER_VIEW_LEN,
- V40_SCALER_VIEW_OFF, 0xFF},
- {VFE_CMD_SCALER_ENC_UPDATE, V40_SCALER_ENC_LEN,
- V40_SCALER_ENC_OFF, 0xFF},
- {VFE_CMD_SCALER_VIEW_UPDATE, V40_SCALER_VIEW_LEN,
- V40_SCALER_VIEW_OFF, 0xFF},
-/*150*/
- {VFE_CMD_COLORXFORM_ENC_CFG, V40_COLORXFORM_ENC_CFG_LEN,
- V40_COLORXFORM_ENC_CFG_OFF, 0xFF},
- {VFE_CMD_COLORXFORM_VIEW_CFG, V40_COLORXFORM_VIEW_CFG_LEN,
- V40_COLORXFORM_VIEW_CFG_OFF},
- {VFE_CMD_COLORXFORM_ENC_UPDATE, V40_COLORXFORM_ENC_CFG_LEN,
- V40_COLORXFORM_ENC_CFG_OFF, 0xFF},
- {VFE_CMD_COLORXFORM_VIEW_UPDATE, V40_COLORXFORM_VIEW_CFG_LEN,
- V40_COLORXFORM_VIEW_CFG_OFF, 0xFF},
-};
-
#endif /* __MSM_VFE40_H__ */
diff --git a/drivers/media/video/vcap_v4l2.c b/drivers/media/video/vcap_v4l2.c
index e8d9e04..407bf2e 100644
--- a/drivers/media/video/vcap_v4l2.c
+++ b/drivers/media/video/vcap_v4l2.c
@@ -1117,6 +1117,12 @@
return -ENOTRECOVERABLE;
}
+ if (!dev->vp_dummy_complete) {
+ pr_err("VCAP Err: %s: VP dummy read not complete",
+ __func__);
+ return -EINVAL;
+ }
+
switch (c_data->op_mode) {
case VC_VCAP_OP:
mutex_lock(&dev->dev_mutex);
@@ -1390,19 +1396,13 @@
}
dev->vc_resource = 0;
mutex_unlock(&dev->dev_mutex);
+ c_data->streaming = 0;
rc = vb2_streamoff(&c_data->vc_vidq,
V4L2_BUF_TYPE_VIDEO_CAPTURE);
- if (rc >= 0) {
- c_data->streaming = 0;
+ if (rc >= 0)
atomic_set(&c_data->dev->vc_enabled, 0);
- }
return rc;
case VP_VCAP_OP:
- if (!dev->vp_dummy_complete) {
- pr_err("VCAP Err: %s: VP dummy read not complete",
- __func__);
- return -EINVAL;
- }
if (c_data != dev->vp_client) {
pr_err("VCAP Err: %s: VP held by other client",
__func__);
@@ -1441,11 +1441,6 @@
atomic_set(&c_data->dev->vp_enabled, 0);
return rc;
case VC_AND_VP_VCAP_OP:
- if (!dev->vp_dummy_complete) {
- pr_err("VCAP Err: %s: VP dummy read not complete",
- __func__);
- return -EINVAL;
- }
if (c_data != dev->vp_client || c_data != dev->vc_client) {
pr_err("VCAP Err: %s: VC/VP held by other client",
__func__);
diff --git a/drivers/media/video/vcap_vc.c b/drivers/media/video/vcap_vc.c
index 62cc306..966fa4b 100644
--- a/drivers/media/video/vcap_vc.c
+++ b/drivers/media/video/vcap_vc.c
@@ -120,6 +120,13 @@
dprintk(1, "%s: irq=0x%08x\n", __func__, irq);
+ c_data = dev->vc_client;
+ if (!c_data->streaming) {
+ writel_iowmb(irq, VCAP_VC_INT_CLEAR);
+ pr_err("VC no longer streaming\n");
+ return IRQ_HANDLED;
+ }
+
v4l2_evt.id = 0;
if (irq & 0x8000200) {
v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
@@ -161,7 +168,6 @@
pr_err("VC: There is no active vc client\n");
return IRQ_HANDLED;
}
- c_data = dev->vc_client;
spin_lock(&dev->vc_client->cap_slock);
if (list_empty(&dev->vc_client->vid_vc_action.active)) {
@@ -316,15 +322,34 @@
void vc_stop_capture(struct vcap_client_data *c_data)
{
struct vcap_dev *dev = c_data->dev;
- int rc;
+ unsigned int reg;
+ int timeout;
- rc = readl_relaxed(VCAP_VC_CTRL);
- writel_iowmb(rc & ~(0x1), VCAP_VC_CTRL);
-
- if (atomic_read(&dev->vc_enabled) == 1)
- disable_irq(dev->vcirq->start);
-
+ writel_iowmb(0x00000102, VCAP_VC_NPL_CTRL);
+ writel_iowmb(0x0, VCAP_VC_INT_MASK);
flush_workqueue(dev->vcap_wq);
+ if (atomic_read(&dev->vc_enabled) == 1)
+ disable_irq_nosync(dev->vcirq->start);
+
+ writel_iowmb(0x00000000, VCAP_VC_CTRL);
+ writel_iowmb(0x00000001, VCAP_SW_RESET_REQ);
+ timeout = 10000;
+ while (1) {
+ reg = (readl_relaxed(VCAP_SW_RESET_STATUS) & 0x1);
+ if (!reg)
+ break;
+ timeout--;
+ if (timeout == 0) {
+ /* This should not happen */
+ pr_err("VC is not resetting properly\n");
+ writel_iowmb(0x00000000, VCAP_SW_RESET_REQ);
+ break;
+ }
+ }
+
+ reg = readl_relaxed(VCAP_VC_NPL_CTRL);
+ reg = readl_relaxed(VCAP_VC_NPL_CTRL);
+ writel_iowmb(0x00000002, VCAP_VC_NPL_CTRL);
}
int config_vc_format(struct vcap_client_data *c_data)
@@ -336,21 +361,20 @@
dev = c_data->dev;
/* restart VC */
- writel_relaxed(0x00000001, VCAP_SW_RESET_REQ);
+ writel_iowmb(0x00000102, VCAP_VC_NPL_CTRL);
+ writel_iowmb(0x00000001, VCAP_SW_RESET_REQ);
timeout = 10000;
while (1) {
- rc = (readl_relaxed(VCAP_SW_RESET_STATUS) & 0x1);
- if (!rc)
+ if (!(readl_relaxed(VCAP_SW_RESET_STATUS) & 0x1))
break;
timeout--;
if (timeout == 0) {
pr_err("VC is not resetting properly\n");
+ writel_iowmb(0x00000002, VCAP_VC_NPL_CTRL);
return -EINVAL;
}
}
- writel_relaxed(0x00000000, VCAP_SW_RESET_REQ);
- writel_iowmb(0x00000102, VCAP_VC_NPL_CTRL);
rc = readl_relaxed(VCAP_VC_NPL_CTRL);
rc = readl_relaxed(VCAP_VC_NPL_CTRL);
writel_iowmb(0x00000002, VCAP_VC_NPL_CTRL);
diff --git a/drivers/media/video/vcap_vc.h b/drivers/media/video/vcap_vc.h
index 792fb14..76693bb 100644
--- a/drivers/media/video/vcap_vc.h
+++ b/drivers/media/video/vcap_vc.h
@@ -19,14 +19,8 @@
#define VCAP_HARDWARE_VERSION 0x10000000
-#define VCAP_BASE (dev->vcapbase)
-#define VCAP_OFFSET(off) (VCAP_BASE + off)
-
#define VCAP_HARDWARE_VERSION_REG (VCAP_BASE + 0x0000)
-#define VCAP_SW_RESET_REQ (VCAP_BASE + 0x0024)
-#define VCAP_SW_RESET_STATUS (VCAP_BASE + 0x0028)
-
#define VCAP_VC_CTRL (VCAP_BASE + 0x0800)
#define VCAP_VC_NPL_CTRL (VCAP_BASE + 0x0804)
#define VCAP_VC_POLARITY (VCAP_BASE + 0x081c)
diff --git a/drivers/media/video/vcap_vp.c b/drivers/media/video/vcap_vp.c
index ba053f2..f8f27d4 100644
--- a/drivers/media/video/vcap_vp.c
+++ b/drivers/media/video/vcap_vp.c
@@ -74,6 +74,12 @@
dev = c_data->dev;
dprintk(2, "Start setup buffers\n");
+ if (dev->vp_shutdown) {
+ dprintk(1, "%s: VP shutting down, no buf setup\n",
+ __func__);
+ return -EPERM;
+ }
+
/* No need to verify vp_client is not NULL caller does so */
vp_act = &dev->vp_client->vid_vp_action;
@@ -262,6 +268,8 @@
writel_relaxed(0x00000000, VCAP_VP_INTERRUPT_ENABLE);
writel_iowmb(irq, VCAP_VP_INT_CLEAR);
atomic_set(&dev->vp_enabled, 0);
+ if (dev->vp_shutdown)
+ wake_up(&dev->vp_dummy_waitq);
return;
}
@@ -350,30 +358,60 @@
return IRQ_HANDLED;
}
+int vp_sw_reset(struct vcap_dev *dev)
+{
+ int timeout;
+ writel_iowmb(0x00000010, VCAP_SW_RESET_REQ);
+ timeout = 10000;
+ while (1) {
+ if (!(readl_relaxed(VCAP_SW_RESET_STATUS) & 0x10))
+ break;
+ timeout--;
+ if (timeout == 0) {
+ /* This should not happen */
+ pr_err("VP is not resetting properly\n");
+ writel_iowmb(0x00000000, VCAP_SW_RESET_REQ);
+ return -EINVAL;
+ }
+ }
+ return 0;
+}
+
void vp_stop_capture(struct vcap_client_data *c_data)
{
struct vcap_dev *dev = c_data->dev;
+ int rc;
- writel_iowmb(0x00000000, VCAP_VP_CTRL);
+ dev->vp_shutdown = true;
flush_workqueue(dev->vcap_wq);
- if (atomic_read(&dev->vp_enabled) == 1)
- disable_irq(dev->vpirq->start);
+ if (atomic_read(&dev->vp_enabled) == 1) {
+ rc = wait_event_interruptible_timeout(dev->vp_dummy_waitq,
+ !atomic_read(&dev->vp_enabled),
+ msecs_to_jiffies(50));
+ if (rc == 0 && atomic_read(&dev->vp_enabled) == 1) {
+ /* This should not happen, if it does hw is stuck */
+ pr_err("%s: VP Timeout and VP still running\n",
+ __func__);
+ }
+ }
- writel_iowmb(0x00000001, VCAP_VP_SW_RESET);
- writel_iowmb(0x00000000, VCAP_VP_SW_RESET);
+ vp_sw_reset(dev);
+ dev->vp_shutdown = false;
}
int config_vp_format(struct vcap_client_data *c_data)
{
struct vcap_dev *dev = c_data->dev;
+ int rc;
INIT_WORK(&dev->vp_to_vc_work.work, mov_buf_to_vc);
dev->vp_to_vc_work.cd = c_data;
/* SW restart VP */
- writel_iowmb(0x00000001, VCAP_VP_SW_RESET);
- writel_iowmb(0x00000000, VCAP_VP_SW_RESET);
+ rc = vp_sw_reset(dev);
+ if (rc < 0)
+ return rc;
/* Film Mode related settings */
writel_iowmb(0x00000000, VCAP_VP_FILM_PROJECTION_T0);
@@ -668,20 +706,18 @@
dev->vp_dummy_event = true;
+ enable_irq(dev->vpirq->start);
writel_relaxed(0x01100101, VCAP_VP_INTERRUPT_ENABLE);
writel_iowmb(0x00000000, VCAP_VP_CTRL);
writel_iowmb(0x00010000, VCAP_VP_CTRL);
- enable_irq(dev->vpirq->start);
rc = wait_event_interruptible_timeout(dev->vp_dummy_waitq,
dev->vp_dummy_complete, msecs_to_jiffies(50));
if (!rc && !dev->vp_dummy_complete) {
pr_err("%s: VP dummy event timeout", __func__);
rc = -ETIME;
- writel_iowmb(0x00000000, VCAP_VP_CTRL);
- writel_iowmb(0x00000001, VCAP_VP_SW_RESET);
- writel_iowmb(0x00000000, VCAP_VP_SW_RESET);
+ vp_sw_reset(dev);
dev->vp_dummy_complete = false;
}
diff --git a/drivers/media/video/vcap_vp.h b/drivers/media/video/vcap_vp.h
index b2b00e9..2ad5848 100644
--- a/drivers/media/video/vcap_vp.h
+++ b/drivers/media/video/vcap_vp.h
@@ -17,9 +17,6 @@
#include <media/vcap_v4l2.h>
-#define VCAP_BASE (dev->vcapbase)
-#define VCAP_OFFSET(off) (VCAP_BASE + off)
-
#define VCAP_VP_INT_STATUS (VCAP_BASE + 0x404)
#define VCAP_VP_INT_CLEAR (VCAP_BASE + 0x40C)
diff --git a/drivers/mfd/pm8xxx-misc.c b/drivers/mfd/pm8xxx-misc.c
index 0af013e..6bb1441 100644
--- a/drivers/mfd/pm8xxx-misc.c
+++ b/drivers/mfd/pm8xxx-misc.c
@@ -564,6 +564,7 @@
: SLEEP_CTRL_SMPL_EN_PWR_OFF));
break;
case PM8XXX_VERSION_8921:
+ case PM8XXX_VERSION_8917:
rc = pm8xxx_misc_masked_write(chip,
REG_PM8921_SLEEP_CTRL, SLEEP_CTRL_SMPL_EN_MASK,
(enable ? SLEEP_CTRL_SMPL_EN_RESET
@@ -624,6 +625,7 @@
delay);
break;
case PM8XXX_VERSION_8921:
+ case PM8XXX_VERSION_8917:
rc = pm8xxx_misc_masked_write(chip,
REG_PM8921_SLEEP_CTRL, SLEEP_CTRL_SMPL_SEL_MASK,
delay);
@@ -703,6 +705,7 @@
REG_PM8058_COIN_CHG, reg);
break;
case PM8XXX_VERSION_8921:
+ case PM8XXX_VERSION_8917:
rc = pm8xxx_writeb(chip->dev->parent,
REG_PM8921_COIN_CHG, reg);
break;
@@ -747,6 +750,7 @@
case PM8XXX_VERSION_8018:
case PM8XXX_VERSION_8058:
case PM8XXX_VERSION_8921:
+ case PM8XXX_VERSION_8917:
rc = pm8xxx_misc_masked_write(chip,
REG_PM8XXX_PON_CTRL_1, PON_CTRL_1_WD_EN_MASK,
(enable ? PON_CTRL_1_WD_EN_RESET
@@ -793,6 +797,7 @@
case PM8XXX_VERSION_8018:
case PM8XXX_VERSION_8058:
case PM8XXX_VERSION_8921:
+ case PM8XXX_VERSION_8917:
rc = pm8xxx_writeb(chip->dev->parent,
REG_PM8XXX_GP_TEST_1, PM8XXX_STAY_ON_CFG);
break;
@@ -884,6 +889,7 @@
REG_PM8901_PON_CNTL_4, REG_PM8901_PON_CNTL_5);
break;
case PM8XXX_VERSION_8921:
+ case PM8XXX_VERSION_8917:
__pm8xxx_hard_reset_config(chip, config,
REG_PM8921_PON_CNTL_4, REG_PM8921_PON_CNTL_5);
break;
@@ -941,6 +947,7 @@
case PM8XXX_VERSION_8018:
case PM8XXX_VERSION_8058:
case PM8XXX_VERSION_8921:
+ case PM8XXX_VERSION_8917:
rc = pm8xxx_misc_masked_write(chip,
REG_PM8XXX_GPIO_MUX_CTRL, UART_PATH_SEL_MASK,
uart_path_sel << UART_PATH_SEL_SHIFT);
@@ -1091,6 +1098,7 @@
switch (chip->version) {
case PM8XXX_VERSION_8038:
case PM8XXX_VERSION_8921:
+ case PM8XXX_VERSION_8917:
pm8xxx_misc_masked_write(chip,
REG_PM8XXX_XO_CNTRL_2, clk_mask, value);
break;
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 2b278be..a86798d 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -1351,9 +1351,11 @@
*/
if (!(data->mrq->cmd->opcode == MMC_BUS_TEST_W
|| data->mrq->cmd->opcode == MMC_BUS_TEST_R)) {
- pr_err("%s: CMD%d: Data timeout\n",
+ pr_err("%s: CMD%d: Data timeout. DAT0 => %d\n",
mmc_hostname(host->mmc),
- data->mrq->cmd->opcode);
+ data->mrq->cmd->opcode,
+ (readl_relaxed(host->base
+ + MCI_TEST_INPUT) & 0x2) ? 1 : 0);
data->error = -ETIMEDOUT;
msmsdcc_dump_sdcc_state(host);
}
@@ -3358,10 +3360,10 @@
{
struct device *dev = mmc_dev(host->mmc);
- pr_info("%s: PM: sdcc_suspended=%d, pending_resume=%d, sdcc_suspending=%d\n",
+ pr_err("%s: PM: sdcc_suspended=%d, pending_resume=%d, sdcc_suspending=%d\n",
mmc_hostname(host->mmc), host->sdcc_suspended,
host->pending_resume, host->sdcc_suspending);
- pr_info("%s: RPM: runtime_status=%d, usage_count=%d,"
+ pr_err("%s: RPM: runtime_status=%d, usage_count=%d,"
" is_suspended=%d, disable_depth=%d, runtime_error=%d,"
" request_pending=%d, request=%d\n",
mmc_hostname(host->mmc), dev->power.runtime_status,
@@ -4847,10 +4849,10 @@
if (!base)
return;
- pr_info("===== %s: Register Dumps @phys_base=0x%x, @virt_base=0x%x"
+ pr_err("===== %s: Register Dumps @phys_base=0x%x, @virt_base=0x%x"
" =====\n", name, phys_base, (u32)base);
for (i = 0; i < no_of_regs; i = i + 4) {
- pr_info("Reg=0x%.2x: 0x%.8x, 0x%.8x, 0x%.8x, 0x%.8x\n", i*4,
+ pr_err("Reg=0x%.2x: 0x%.8x, 0x%.8x, 0x%.8x, 0x%.8x\n", i*4,
(u32)readl_relaxed(base + i*4),
(u32)readl_relaxed(base + ((i+1)*4)),
(u32)readl_relaxed(base + ((i+2)*4)),
@@ -4861,25 +4863,29 @@
static void msmsdcc_dump_sdcc_state(struct msmsdcc_host *host)
{
/* Dump current state of SDCC clocks, power and irq */
- pr_info("%s: SDCC PWR is %s\n", mmc_hostname(host->mmc),
+ pr_err("%s: SDCC PWR is %s\n", mmc_hostname(host->mmc),
(host->pwr ? "ON" : "OFF"));
- pr_info("%s: SDCC clks are %s, MCLK rate=%d\n",
+ pr_err("%s: SDCC clks are %s, MCLK rate=%d\n",
mmc_hostname(host->mmc),
(atomic_read(&host->clks_on) ? "ON" : "OFF"),
(u32)clk_get_rate(host->clk));
- pr_info("%s: SDCC irq is %s\n", mmc_hostname(host->mmc),
+ pr_err("%s: SDCC irq is %s\n", mmc_hostname(host->mmc),
(host->sdcc_irq_disabled ? "disabled" : "enabled"));
/* Now dump SDCC registers. Don't print FIFO registers */
- if (atomic_read(&host->clks_on))
+ if (atomic_read(&host->clks_on)) {
msmsdcc_print_regs("SDCC-CORE", host->base,
host->core_memres->start, 28);
+ pr_err("%s: MCI_TEST_INPUT = 0x%.8x\n",
+ mmc_hostname(host->mmc),
+ readl_relaxed(host->base + MCI_TEST_INPUT));
+ }
if (host->curr.data) {
if (!msmsdcc_is_dma_possible(host, host->curr.data))
- pr_info("%s: PIO mode\n", mmc_hostname(host->mmc));
+ pr_err("%s: PIO mode\n", mmc_hostname(host->mmc));
else if (is_dma_mode(host))
- pr_info("%s: ADM mode: busy=%d, chnl=%d, crci=%d\n",
+ pr_err("%s: ADM mode: busy=%d, chnl=%d, crci=%d\n",
mmc_hostname(host->mmc), host->dma.busy,
host->dma.channel, host->dma.crci);
else if (is_sps_mode(host)) {
@@ -4887,16 +4893,16 @@
msmsdcc_print_regs("SDCC-DML", host->dml_base,
host->dml_memres->start,
16);
- pr_info("%s: SPS mode: busy=%d\n",
+ pr_err("%s: SPS mode: busy=%d\n",
mmc_hostname(host->mmc), host->sps.busy);
}
- pr_info("%s: xfer_size=%d, data_xfered=%d, xfer_remain=%d\n",
+ pr_err("%s: xfer_size=%d, data_xfered=%d, xfer_remain=%d\n",
mmc_hostname(host->mmc), host->curr.xfer_size,
host->curr.data_xfered, host->curr.xfer_remain);
}
- pr_info("%s: got_dataend=%d, prog_enable=%d,"
+ pr_err("%s: got_dataend=%d, prog_enable=%d,"
" wait_for_auto_prog_done=%d, got_auto_prog_done=%d,"
" req_tout_ms=%d\n", mmc_hostname(host->mmc),
host->curr.got_dataend, host->prog_enable,
diff --git a/drivers/net/ethernet/msm/msm_rmnet_bam.c b/drivers/net/ethernet/msm/msm_rmnet_bam.c
index fbe8d3c..295c55c 100644
--- a/drivers/net/ethernet/msm/msm_rmnet_bam.c
+++ b/drivers/net/ethernet/msm/msm_rmnet_bam.c
@@ -29,6 +29,7 @@
#include <linux/if_arp.h>
#include <linux/msm_rmnet.h>
#include <linux/platform_device.h>
+#include <net/pkt_sched.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
@@ -638,6 +639,16 @@
dev->name);
break;
+ case RMNET_IOCTL_FLOW_ENABLE:
+ tc_qdisc_flow_control(dev, (u32)ifr->ifr_data, 1);
+ DBG0("[%s] rmnet_ioctl(): enabled flow", dev->name);
+ break;
+
+ case RMNET_IOCTL_FLOW_DISABLE:
+ tc_qdisc_flow_control(dev, (u32)ifr->ifr_data, 0);
+ DBG0("[%s] rmnet_ioctl(): disabled flow", dev->name);
+ break;
+
case RMNET_IOCTL_GET_QOS: /* Get QoS header state */
ifr->ifr_ifru.ifru_data =
(void *)(p->operation_mode & RMNET_MODE_QOS);
diff --git a/drivers/platform/msm/usb_bam.c b/drivers/platform/msm/usb_bam.c
index a347984..551c0a7 100644
--- a/drivers/platform/msm/usb_bam.c
+++ b/drivers/platform/msm/usb_bam.c
@@ -539,6 +539,9 @@
return NULL;
}
+ pdata->ignore_core_reset_ack = of_property_read_bool(node,
+ "qcom,ignore-core-reset-ack");
+
for_each_child_of_node(pdev->dev.of_node, node)
pipe_entry++;
@@ -684,6 +687,12 @@
usb_props.summing_threshold = USB_SUMMING_THRESHOLD;
usb_props.event_threshold = 512;
usb_props.num_pipes = pdata->usb_bam_num_pipes;
+ /*
+ * HSUSB and HSIC Cores don't support RESET ACK signal to BAMs
+ * Hence, let BAM to ignore acknowledge from USB while resetting PIPE
+ */
+ if (pdata->ignore_core_reset_ack && pdata->usb_active_bam != SSUSB_BAM)
+ usb_props.options = SPS_BAM_NO_EXT_P_RST;
ret = sps_register_bam_device(&usb_props, &h_usb);
if (ret < 0) {
diff --git a/drivers/power/pm8921-charger.c b/drivers/power/pm8921-charger.c
index 6a4e50c..cfe1efb 100644
--- a/drivers/power/pm8921-charger.c
+++ b/drivers/power/pm8921-charger.c
@@ -270,6 +270,7 @@
int rconn_mohm;
enum pm8921_chg_led_src_config led_src_config;
bool host_mode;
+ bool has_dc_supply;
u8 active_path;
int recent_reported_soc;
};
@@ -1195,6 +1196,12 @@
case POWER_SUPPLY_PROP_PRESENT:
case POWER_SUPPLY_PROP_ONLINE:
val->intval = 0;
+
+ if (the_chip->has_dc_supply) {
+ val->intval = 1;
+ return 0;
+ }
+
if (charging_disabled)
return 0;
@@ -1669,8 +1676,7 @@
*/
if (!get_prop_batt_present(the_chip)
&& !is_dc_chg_plugged_in(the_chip)) {
- if (get_prop_batt_current(the_chip) <
- the_chip->min_voltage_mv) {
+ if (!the_chip->has_dc_supply) {
pr_err("rejected: no other power source connected\n");
return;
}
@@ -4037,6 +4043,7 @@
chip->hot_thr = pdata->hot_thr;
chip->rconn_mohm = pdata->rconn_mohm;
chip->led_src_config = pdata->led_src_config;
+ chip->has_dc_supply = pdata->has_dc_supply;
rc = pm8921_chg_hw_init(chip);
if (rc) {
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index 522e3a4..882aa7f 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -1378,6 +1378,7 @@
struct platform_device *dwc3;
struct dwc3_msm *msm;
struct resource *res;
+ void __iomem *tcsr;
int ret = 0;
msm = devm_kzalloc(&pdev->dev, sizeof(*msm), GFP_KERNEL);
@@ -1484,6 +1485,25 @@
goto free_hs_ldo_init;
}
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!res) {
+ dev_dbg(&pdev->dev, "missing TCSR memory resource\n");
+ } else {
+ tcsr = devm_ioremap_nocache(&pdev->dev, res->start,
+ resource_size(res));
+ if (!tcsr) {
+ dev_dbg(&pdev->dev, "tcsr ioremap failed\n");
+ } else {
+ /* Enable USB3 on the primary USB port. */
+ writel_relaxed(0x1, tcsr);
+ /*
+ * Ensure that TCSR write is completed before
+ * USB registers initialization.
+ */
+ mb();
+ }
+ }
+
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(&pdev->dev, "missing memory base resource\n");
diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c
index c16ff97..40b79a2 100644
--- a/drivers/usb/gadget/udc-core.c
+++ b/drivers/usb/gadget/udc-core.c
@@ -348,7 +348,6 @@
driver->unbind(udc->gadget);
goto err1;
}
- usb_gadget_connect(udc->gadget);
} else {
ret = usb_gadget_start(udc->gadget, driver, bind);
diff --git a/drivers/usb/host/ehci-msm-hsic.c b/drivers/usb/host/ehci-msm-hsic.c
index b396593..2126ff0 100644
--- a/drivers/usb/host/ehci-msm-hsic.c
+++ b/drivers/usb/host/ehci-msm-hsic.c
@@ -27,6 +27,7 @@
#include <linux/err.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
+#include <linux/wakelock.h>
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
@@ -58,13 +59,14 @@
struct clk *phy_clk;
struct clk *cal_clk;
struct regulator *hsic_vddcx;
+ bool async_int;
atomic_t in_lpm;
+ struct wake_lock wlock;
int peripheral_status_irq;
int wakeup_irq;
int wakeup_gpio;
bool wakeup_irq_enabled;
- bool irq_enabled;
- bool async_int;
+ atomic_t pm_usage_cnt;
uint32_t bus_perf_client;
uint32_t wakeup_int_cnt;
enum usb_vdd_type vdd_type;
@@ -624,15 +626,13 @@
disable_irq(hcd->irq);
- /* make sure we don't race against the root hub being resumed */
- if (HCD_RH_RUNNING(hcd) || HCD_WAKEUP_PENDING(hcd) ||
+ /* make sure we don't race against a remote wakeup */
+ if (test_bit(HCD_FLAG_WAKEUP_PENDING, &hcd->flags) ||
readl_relaxed(USB_PORTSC) & PORT_RESUME) {
- dev_warn(mehci->dev, "%s: Root hub is not suspended\n",
- __func__);
+ dev_dbg(mehci->dev, "wakeup pending, aborting suspend\n");
enable_irq(hcd->irq);
return -EBUSY;
}
- mehci->irq_enabled = false;
/*
* PHY may take some time or even fail to enter into low power
@@ -690,13 +690,14 @@
}
atomic_set(&mehci->in_lpm, 1);
- mehci->irq_enabled = true;
enable_irq(hcd->irq);
mehci->wakeup_irq_enabled = 1;
enable_irq_wake(mehci->wakeup_irq);
enable_irq(mehci->wakeup_irq);
+ wake_unlock(&mehci->wlock);
+
dev_info(mehci->dev, "HSIC-USB in low power mode\n");
return 0;
@@ -720,6 +721,8 @@
mehci->wakeup_irq_enabled = 0;
}
+ wake_lock(&mehci->wlock);
+
if (mehci->bus_perf_client && debug_bus_voting_enabled) {
mehci->bus_vote = true;
queue_work(ehci_wq, &mehci->bus_vote_w);
@@ -775,14 +778,13 @@
if (mehci->async_int) {
mehci->async_int = false;
pm_runtime_put_noidle(mehci->dev);
- }
-
- if (!mehci->irq_enabled) {
enable_irq(hcd->irq);
- mehci->irq_enabled = true;
}
- pm_relax(mehci->dev);
+ if (atomic_read(&mehci->pm_usage_cnt)) {
+ atomic_set(&mehci->pm_usage_cnt, 0);
+ pm_runtime_put_noidle(mehci->dev);
+ }
dev_info(mehci->dev, "HSIC-USB exited from low power mode\n");
@@ -809,11 +811,9 @@
if (atomic_read(&mehci->in_lpm)) {
disable_irq_nosync(hcd->irq);
- mehci->irq_enabled = false;
dev_dbg(mehci->dev, "phy async intr\n");
mehci->async_int = true;
pm_runtime_get(mehci->dev);
- pm_stay_awake(mehci->dev);
return IRQ_HANDLED;
}
@@ -1030,9 +1030,7 @@
dev_dbg(mehci->dev, "%s: hsic remote wakeup interrupt cnt: %u\n",
__func__, mehci->wakeup_int_cnt);
- mehci->async_int = true;
- pm_runtime_get(mehci->dev);
- pm_stay_awake(mehci->dev);
+ wake_lock(&mehci->wlock);
if (mehci->wakeup_irq_enabled) {
mehci->wakeup_irq_enabled = 0;
@@ -1040,6 +1038,11 @@
disable_irq_nosync(irq);
}
+ if (!atomic_read(&mehci->pm_usage_cnt)) {
+ atomic_set(&mehci->pm_usage_cnt, 1);
+ pm_runtime_get(mehci->dev);
+ }
+
return IRQ_HANDLED;
}
@@ -1345,8 +1348,9 @@
goto unconfig_gpio;
}
- mehci->irq_enabled = true;
device_init_wakeup(&pdev->dev, 1);
+ wake_lock_init(&mehci->wlock, WAKE_LOCK_SUSPEND, dev_name(&pdev->dev));
+ wake_lock(&mehci->wlock);
if (mehci->peripheral_status_irq) {
ret = request_threaded_irq(mehci->peripheral_status_irq,
@@ -1460,6 +1464,7 @@
msm_hsic_init_vddcx(mehci, 0);
msm_hsic_init_clocks(mehci, 0);
+ wake_lock_destroy(&mehci->wlock);
iounmap(hcd->regs);
usb_put_hcd(hcd);
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 0ef8249..f5bad19 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -760,6 +760,14 @@
test_bit(A_BUS_SUSPEND, &motg->inputs) &&
motg->caps & ALLOW_LPM_ON_DEV_SUSPEND;
dcp = motg->chg_type == USB_DCP_CHARGER;
+
+ /* charging detection in progress due to cable plug-in */
+ if (test_bit(B_SESS_VLD, &motg->inputs) && !device_bus_suspend &&
+ !dcp) {
+ enable_irq(motg->irq);
+ return -EBUSY;
+ }
+
/*
* Chipidea 45-nm PHY suspend sequence:
*
diff --git a/drivers/video/msm/mdp4_overlay.c b/drivers/video/msm/mdp4_overlay.c
index 31e62b2..a1ec2db 100644
--- a/drivers/video/msm/mdp4_overlay.c
+++ b/drivers/video/msm/mdp4_overlay.c
@@ -3222,9 +3222,7 @@
return 0;
}
- if (pipe->mixer_num == MDP4_MIXER2 ||
- ctrl->panel_mode & MDP4_PANEL_MDDI)
- mutex_lock(&mfd->dma->ov_mutex);
+ mutex_lock(&mfd->dma->ov_mutex);
img = &req->data;
get_img(img, info, pipe, 0, &start, &len, &srcp0_file,
@@ -3354,6 +3352,7 @@
mdp4_dtv_pipe_queue(0, pipe);/* cndx = 0 */
}
+ mutex_unlock(&mfd->dma->ov_mutex);
return ret;
mddi:
@@ -3385,8 +3384,10 @@
if (!(pipe->flags & MDP_OV_PLAY_NOWAIT))
mdp4_iommu_unmap(pipe);
mdp4_stat.overlay_play[pipe->mixer_num]++;
- mutex_unlock(&mfd->dma->ov_mutex);
+
end:
+ mutex_unlock(&mfd->dma->ov_mutex);
+
#ifdef CONFIG_ANDROID_PMEM
if (srcp0_file)
put_pmem_file(srcp0_file);
diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c
index 1a1bb07..1f83b2b 100644
--- a/drivers/video/msm/mdss/mdss_fb.c
+++ b/drivers/video/msm/mdss/mdss_fb.c
@@ -186,7 +186,7 @@
/*
* alloc framebuffer info + par data
*/
- fbi = framebuffer_alloc(sizeof(struct msm_fb_data_type), &pdev->dev);
+ fbi = framebuffer_alloc(sizeof(struct msm_fb_data_type), NULL);
if (fbi == NULL) {
pr_err("can't allocate framebuffer info data!\n");
return -ENOMEM;
diff --git a/drivers/video/msm/mdss/mdss_mdp.h b/drivers/video/msm/mdss/mdss_mdp.h
index 17281d5..a282c3a 100644
--- a/drivers/video/msm/mdss/mdss_mdp.h
+++ b/drivers/video/msm/mdss/mdss_mdp.h
@@ -107,6 +107,9 @@
MDSS_MDP_MAX_CSC
};
+struct mdss_mdp_ctl;
+typedef void (*mdp_vsync_handler_t)(struct mdss_mdp_ctl *, ktime_t);
+
struct mdss_mdp_ctl {
u32 num;
u32 ref_cnt;
@@ -138,6 +141,7 @@
int (*stop_fnc) (struct mdss_mdp_ctl *ctl);
int (*prepare_fnc) (struct mdss_mdp_ctl *ctl, void *arg);
int (*display_fnc) (struct mdss_mdp_ctl *ctl, void *arg);
+ int (*set_vsync_handler) (struct mdss_mdp_ctl *, mdp_vsync_handler_t);
void *priv_data;
};
diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c
index d29ecd6..21f4071 100644
--- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
+++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c
@@ -533,6 +533,11 @@
mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_PACK_3D, 0);
}
+ /* request bus bandwidth for panel commands */
+ ctl->clk_rate = MDP_CLK_DEFAULT_RATE;
+ ctl->bus_ib_quota = SZ_1M;
+ mdss_mdp_ctl_perf_commit(MDSS_MDP_PERF_UPDATE_ALL);
+
ret = pdata->on(pdata);
start_fail:
diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_video.c b/drivers/video/msm/mdss/mdss_mdp_intf_video.c
index bc64d2e..6f92474 100644
--- a/drivers/video/msm/mdss/mdss_mdp_intf_video.c
+++ b/drivers/video/msm/mdss/mdss_mdp_intf_video.c
@@ -13,6 +13,8 @@
#define pr_fmt(fmt) "%s: " fmt, __func__
+#include <linux/workqueue.h>
+
#include "mdss_fb.h"
#include "mdss_mdp.h"
@@ -44,6 +46,12 @@
u8 timegen_en;
struct completion pp_comp;
struct completion vsync_comp;
+
+ struct mutex vsync_lock;
+ struct work_struct vsync_work;
+ mdp_vsync_handler_t vsync_handler;
+ void *vsync_ptr;
+ ktime_t vsync_time;
};
struct mdss_mdp_video_ctx mdss_mdp_video_ctx_list[MAX_SESSIONS];
@@ -141,6 +149,47 @@
return 0;
}
+static void send_vsync_work(struct work_struct *work)
+{
+ struct mdss_mdp_video_ctx *ctx;
+
+ ctx = container_of(work, typeof(*ctx), vsync_work);
+ mutex_lock(&ctx->vsync_lock);
+ if (ctx->vsync_handler)
+ ctx->vsync_handler(ctx->vsync_ptr, ctx->vsync_time);
+ mutex_unlock(&ctx->vsync_lock);
+}
+
+static int mdss_mdp_video_set_vsync_handler(struct mdss_mdp_ctl *ctl,
+ mdp_vsync_handler_t vsync_handler)
+{
+ struct mdss_mdp_video_ctx *ctx;
+
+ ctx = (struct mdss_mdp_video_ctx *) ctl->priv_data;
+ if (!ctx) {
+ pr_err("invalid ctx for ctl=%d\n", ctl->num);
+ return -ENODEV;
+ }
+ if (mutex_lock_interruptible(&ctx->vsync_lock))
+ return -EINTR;
+
+ if (!ctx->timegen_en) {
+ ctx->vsync_time = ktime_get();
+ schedule_work(&ctx->vsync_work);
+ }
+
+ if (!ctx->vsync_handler && vsync_handler)
+ mdss_mdp_irq_enable(MDSS_MDP_IRQ_INTF_VSYNC, ctl->intf_num);
+ else if (ctx->vsync_handler && !vsync_handler)
+ mdss_mdp_irq_disable(MDSS_MDP_IRQ_INTF_VSYNC, ctl->intf_num);
+
+ ctx->vsync_handler = vsync_handler;
+ ctx->vsync_ptr = ctl;
+ mutex_unlock(&ctx->vsync_lock);
+
+ return 0;
+}
+
static int mdss_mdp_video_stop(struct mdss_mdp_ctl *ctl)
{
struct mdss_mdp_video_ctx *ctx;
@@ -161,6 +210,11 @@
ctx->timegen_en = false;
}
+ mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_INTF_VSYNC, ctl->intf_num,
+ NULL, NULL);
+ mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_PING_PONG_COMP, ctx->pp_num,
+ NULL, NULL);
+
memset(ctx, 0, sizeof(*ctx));
return 0;
@@ -190,10 +244,13 @@
pr_err("invalid ctx\n");
return;
}
+ ctx->vsync_time = ktime_get();
pr_debug("intr ctl=%d\n", ctx->ctl_num);
complete(&ctx->vsync_comp);
+ if (ctx->vsync_handler)
+ schedule_work(&ctx->vsync_work);
}
static int mdss_mdp_video_prepare(struct mdss_mdp_ctl *ctl, void *arg)
@@ -207,15 +264,10 @@
}
if (ctx->timegen_en) {
- u32 intr_type = MDSS_MDP_IRQ_PING_PONG_COMP;
-
pr_debug("waiting for ping pong %d done\n", ctx->pp_num);
- mdss_mdp_set_intr_callback(intr_type, ctx->pp_num,
- mdss_mdp_video_pp_intr_done, ctx);
- mdss_mdp_irq_enable(intr_type, ctx->pp_num);
-
+ mdss_mdp_irq_enable(MDSS_MDP_IRQ_PING_PONG_COMP, ctx->pp_num);
wait_for_completion_interruptible(&ctx->pp_comp);
- mdss_mdp_irq_disable(intr_type, ctx->pp_num);
+ mdss_mdp_irq_disable(MDSS_MDP_IRQ_PING_PONG_COMP, ctx->pp_num);
}
return 0;
@@ -224,7 +276,6 @@
static int mdss_mdp_video_display(struct mdss_mdp_ctl *ctl, void *arg)
{
struct mdss_mdp_video_ctx *ctx;
- u32 intr_type = MDSS_MDP_IRQ_INTF_VSYNC;
pr_debug("kickoff ctl=%d\n", ctl->num);
@@ -233,9 +284,12 @@
pr_err("invalid ctx\n");
return -ENODEV;
}
- mdss_mdp_set_intr_callback(intr_type, ctl->intf_num,
- mdss_mdp_video_vsync_intr_done, ctx);
- mdss_mdp_irq_enable(intr_type, ctl->intf_num);
+ INIT_COMPLETION(ctx->vsync_comp);
+
+ if (mutex_lock_interruptible(&ctx->vsync_lock))
+ return -EINTR;
+ if (!ctx->vsync_handler)
+ mdss_mdp_irq_enable(MDSS_MDP_IRQ_INTF_VSYNC, ctl->intf_num);
if (!ctx->timegen_en) {
int off = MDSS_MDP_REG_INTF_OFFSET(ctl->intf_num);
@@ -249,7 +303,9 @@
}
wait_for_completion_interruptible(&ctx->vsync_comp);
- mdss_mdp_irq_disable(intr_type, ctl->intf_num);
+ if (!ctx->vsync_handler)
+ mdss_mdp_irq_disable(MDSS_MDP_IRQ_INTF_VSYNC, ctl->intf_num);
+ mutex_unlock(&ctx->vsync_lock);
return 0;
}
@@ -293,6 +349,13 @@
init_completion(&ctx->pp_comp);
init_completion(&ctx->vsync_comp);
+ INIT_WORK(&ctx->vsync_work, send_vsync_work);
+ mutex_init(&ctx->vsync_lock);
+ mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_INTF_VSYNC, ctl->intf_num,
+ mdss_mdp_video_vsync_intr_done, ctx);
+ mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_PING_PONG_COMP, ctx->pp_num,
+ mdss_mdp_video_pp_intr_done, ctx);
+
itp.width = pinfo->xres + pinfo->lcdc.xres_pad;
itp.height = pinfo->yres + pinfo->lcdc.yres_pad;
itp.border_clr = pinfo->lcdc.border_clr;
@@ -316,6 +379,7 @@
ctl->stop_fnc = mdss_mdp_video_stop;
ctl->prepare_fnc = mdss_mdp_video_prepare;
ctl->display_fnc = mdss_mdp_video_display;
+ ctl->set_vsync_handler = mdss_mdp_video_set_vsync_handler;
return 0;
}
diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
index d4d889b..1cb474d 100644
--- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
+++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c
@@ -615,6 +615,49 @@
mfd->kickoff_fnc(mfd->ctl);
}
+static void mdss_mdp_overlay_handle_vsync(struct mdss_mdp_ctl *ctl, ktime_t t)
+{
+ struct device *dev;
+ char buf[64];
+ char *envp[2];
+
+ if (!ctl || !ctl->mfd || !ctl->mfd->fbi) {
+ pr_warn("Invalid handle for vsync\n");
+ return;
+ }
+
+ dev = ctl->mfd->fbi->dev;
+
+ snprintf(buf, sizeof(buf), "VSYNC=%llu", ktime_to_ns(t));
+ envp[0] = buf;
+ envp[1] = NULL;
+ kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
+
+ pr_debug("sent vsync on ctl=%d ts=%llu\n", ctl->num, ktime_to_ns(t));
+}
+
+static int mdss_mdp_overlay_vsync_ctrl(struct msm_fb_data_type *mfd, int en)
+{
+ struct mdss_mdp_ctl *ctl = mfd->ctl;
+ int rc;
+
+ if (!ctl)
+ return -ENODEV;
+ if (!ctl->set_vsync_handler)
+ return -ENOTSUPP;
+
+ pr_debug("vsync en=%d\n", en);
+
+ mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
+ if (en)
+ rc = ctl->set_vsync_handler(ctl, mdss_mdp_overlay_handle_vsync);
+ else
+ rc = ctl->set_vsync_handler(ctl, NULL);
+ mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
+
+ return rc;
+}
+
static int mdss_mdp_hw_cursor_update(struct msm_fb_data_type *mfd,
struct fb_cursor *cursor)
{
@@ -822,6 +865,16 @@
}
break;
+ case MSMFB_VSYNC_CTRL:
+ case MSMFB_OVERLAY_VSYNC_CTRL:
+ if (!copy_from_user(&val, argp, sizeof(val))) {
+ ret = mdss_mdp_overlay_vsync_ctrl(mfd, val);
+ } else {
+ pr_err("MSMFB_OVERLAY_VSYNC_CTRL failed (%d)\n", ret);
+ ret = -EFAULT;
+ }
+ break;
+
default:
if (mfd->panel_info.type == WRITEBACK_PANEL)
ret = mdss_mdp_wb_ioctl_handler(mfd, cmd, argp);
diff --git a/drivers/video/msm/mdss/mdss_mdp_util.c b/drivers/video/msm/mdss/mdss_mdp_util.c
index 7f61a14..7567db1 100644
--- a/drivers/video/msm/mdss/mdss_mdp_util.c
+++ b/drivers/video/msm/mdss/mdss_mdp_util.c
@@ -102,8 +102,6 @@
spin_lock(&mdss_mdp_intr_lock);
fnc = mdp_intr_cb[index].func;
arg = mdp_intr_cb[index].arg;
- if (fnc != NULL)
- mdp_intr_cb[index].func = NULL;
spin_unlock(&mdss_mdp_intr_lock);
if (fnc)
fnc(arg);
diff --git a/include/linux/mfd/pm8xxx/pm8921-charger.h b/include/linux/mfd/pm8xxx/pm8921-charger.h
index 6bd4cb2..7b389c5 100644
--- a/include/linux/mfd/pm8xxx/pm8921-charger.h
+++ b/include/linux/mfd/pm8xxx/pm8921-charger.h
@@ -93,6 +93,7 @@
* however, this should only be enabled for devices which
* control the DC OVP FETs otherwise this option should
* remain disabled
+ * @has_dc_supply: report DC online if this bit is set in board file
* @trkl_voltage: the trkl voltage in (mV) below which hw controlled
* trkl charging happens with linear charger
* @weak_voltage: the weak voltage (mV) below which hw controlled
@@ -142,6 +143,7 @@
int64_t batt_id_max;
bool keep_btm_on_suspend;
bool dc_unplug_check;
+ bool has_dc_supply;
int trkl_voltage;
int weak_voltage;
int trkl_current;
diff --git a/include/linux/msm_rmnet.h b/include/linux/msm_rmnet.h
index 9f52464..063a8f1 100644
--- a/include/linux/msm_rmnet.h
+++ b/include/linux/msm_rmnet.h
@@ -40,6 +40,8 @@
RMNET_IOCTL_GET_OPMODE = 0x000089F7, /* Get operation mode */
RMNET_IOCTL_OPEN = 0x000089F8, /* Open transport port */
RMNET_IOCTL_CLOSE = 0x000089F9, /* Close transport port */
+ RMNET_IOCTL_FLOW_ENABLE = 0x000089FA, /* Flow enable */
+ RMNET_IOCTL_FLOW_DISABLE = 0x000089FB, /* Flow disable */
RMNET_IOCTL_MAX
};
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index 468a410..59ba64b 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -438,6 +438,7 @@
* @usb_bam_num_pipes: max number of pipes to use.
* @active_conn_num: number of active pipe connections.
* @usb_base_address: BAM physical address.
+ * @ignore_core_reset_ack: BAM can ignore ACK from USB core during PIPE RESET
*/
struct msm_usb_bam_platform_data {
struct usb_bam_pipe_connect *connections;
@@ -445,6 +446,7 @@
int usb_bam_num_pipes;
u32 total_bam_num;
u32 usb_base_address;
+ bool ignore_core_reset_ack;
};
enum usb_bam {
diff --git a/include/media/vcap_v4l2.h b/include/media/vcap_v4l2.h
index cf99435..d56e534 100644
--- a/include/media/vcap_v4l2.h
+++ b/include/media/vcap_v4l2.h
@@ -38,6 +38,12 @@
writel_relaxed(val, addr); \
} while (0)
+#define VCAP_BASE (dev->vcapbase)
+#define VCAP_OFFSET(off) (VCAP_BASE + off)
+
+#define VCAP_SW_RESET_REQ (VCAP_BASE + 0x024)
+#define VCAP_SW_RESET_STATUS (VCAP_BASE + 0x028)
+
struct vcap_client_data;
enum rdy_buf {
@@ -167,6 +173,7 @@
bool vp_resource;
bool vp_dummy_event;
bool vp_dummy_complete;
+ bool vp_shutdown;
wait_queue_head_t vp_dummy_waitq;
struct workqueue_struct *vcap_wq;
diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h
index fffdc60..95ec28b 100644
--- a/include/net/pkt_sched.h
+++ b/include/net/pkt_sched.h
@@ -103,7 +103,8 @@
struct tcf_result *res);
extern int tc_classify(struct sk_buff *skb, const struct tcf_proto *tp,
struct tcf_result *res);
-
+extern void tc_qdisc_flow_control(struct net_device *dev, u32 tcm_handle,
+ int flow_enable);
/* Calculate maximal size of packet seen by hard_start_xmit
routine of this device.
*/
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 3d8981f..60e2fa9 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -1030,6 +1030,35 @@
}
/*
+ * enable/disable flow on qdisc.
+ */
+void
+tc_qdisc_flow_control(struct net_device *dev, u32 tcm_handle, int enable_flow)
+{
+ struct Qdisc *q;
+ struct __qdisc_change_req {
+ struct nlattr attr;
+ struct tc_prio_qopt data;
+ } req = {
+ .attr = {sizeof(struct __qdisc_change_req), TCA_OPTIONS},
+ .data = {3, {1, 2, 2, 2, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1}, 1}
+ };
+
+ /* override flow bit */
+ req.data.enable_flow = enable_flow;
+
+ /* look up using tcm handle */
+ q = qdisc_lookup(dev, tcm_handle);
+
+ /* call registered change function */
+ if (q) {
+ if (q->ops->change(q, &(req.attr)) != 0)
+ pr_err("tc_qdisc_flow_control: qdisc change failed");
+ }
+}
+EXPORT_SYMBOL(tc_qdisc_flow_control);
+
+/*
* Create/change qdisc.
*/
diff --git a/sound/soc/msm/mpq8064.c b/sound/soc/msm/mpq8064.c
index 3b880ed..be0395b 100644
--- a/sound/soc/msm/mpq8064.c
+++ b/sound/soc/msm/mpq8064.c
@@ -133,7 +133,7 @@
static int msm_ext_top_spk_pamp;
static int msm_slim_0_rx_ch = 1;
static int msm_slim_0_tx_ch = 1;
-static int msm_hdmi_rx_ch = 2;
+static int msm_hdmi_rx_ch = 8;
static struct clk *codec_clk;
static int clk_users;
@@ -515,14 +515,15 @@
static const char *spk_function[] = {"Off", "On"};
static const char *slim0_rx_ch_text[] = {"One", "Two"};
static const char *slim0_tx_ch_text[] = {"One", "Two", "Three", "Four"};
-static const char *hdmi_rx_ch_text[] = {"Two", "Three", "Four", "Five", "Six"};
+static const char * const hdmi_rx_ch_text[] = {"Two", "Three", "Four",
+ "Five", "Six", "Seven", "Eight"};
static const struct soc_enum msm_enum[] = {
SOC_ENUM_SINGLE_EXT(2, spk_function),
SOC_ENUM_SINGLE_EXT(2, slim0_rx_ch_text),
SOC_ENUM_SINGLE_EXT(4, slim0_tx_ch_text),
- SOC_ENUM_SINGLE_EXT(5, hdmi_rx_ch_text),
+ SOC_ENUM_SINGLE_EXT(7, hdmi_rx_ch_text),
};
diff --git a/sound/soc/msm/msm-compr-q6.c b/sound/soc/msm/msm-compr-q6.c
index 5df132b..dd576c4 100644
--- a/sound/soc/msm/msm-compr-q6.c
+++ b/sound/soc/msm/msm-compr-q6.c
@@ -26,6 +26,7 @@
#include <sound/initval.h>
#include <sound/control.h>
#include <sound/q6asm.h>
+#include <sound/pcm_params.h>
#include <asm/dma.h>
#include <linux/dma-mapping.h>
#include <linux/android_pmem.h>
@@ -82,7 +83,7 @@
.rate_min = 8000,
.rate_max = 48000,
.channels_min = 1,
- .channels_max = 2,
+ .channels_max = 8,
.buffer_bytes_max = 1200 * 1024 * 2,
.period_bytes_min = 2400,
.period_bytes_max = 1200 * 1024,
@@ -134,8 +135,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);
@@ -814,7 +813,17 @@
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,
diff --git a/sound/soc/msm/msm-dai-fe.c b/sound/soc/msm/msm-dai-fe.c
index 011ff29..011912e 100644
--- a/sound/soc/msm/msm-dai-fe.c
+++ b/sound/soc/msm/msm-dai-fe.c
@@ -82,7 +82,7 @@
SNDRV_PCM_RATE_KNOT),
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.channels_min = 1,
- .channels_max = 6,
+ .channels_max = 8,
.rate_min = 8000,
.rate_max = 48000,
},
@@ -173,7 +173,7 @@
SNDRV_PCM_RATE_KNOT),
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.channels_min = 1,
- .channels_max = 6,
+ .channels_max = 8,
.rate_min = 8000,
.rate_max = 48000,
},
diff --git a/sound/soc/msm/msm-dai-q6-hdmi.c b/sound/soc/msm/msm-dai-q6-hdmi.c
index c082ed7..2b3dd5f 100644
--- a/sound/soc/msm/msm-dai-q6-hdmi.c
+++ b/sound/soc/msm/msm-dai-q6-hdmi.c
@@ -111,6 +111,13 @@
dai_data->port_config.hdmi_multi_ch.channel_allocation =
channel_allocation;
break;
+ case 8:
+ channel_allocation = 0x1F;
+ hdmi_msm_audio_info_setup(1, MSM_HDMI_AUDIO_CHANNEL_8,
+ channel_allocation, level_shift, down_mix);
+ dai_data->port_config.hdmi_multi_ch.channel_allocation =
+ channel_allocation;
+ break;
default:
dev_err(dai->dev, "invalid Channels = %u\n",
dai_data->channels);
diff --git a/sound/soc/msm/msm-dai-q6.c b/sound/soc/msm/msm-dai-q6.c
index 89b709f..ee1ab79 100644
--- a/sound/soc/msm/msm-dai-q6.c
+++ b/sound/soc/msm/msm-dai-q6.c
@@ -465,6 +465,9 @@
dai_data->channels = params_channels(params);
switch (dai_data->channels) {
case 2:
+ case 4:
+ case 6:
+ case 8:
dai_data->port_config.mi2s.channel = MSM_AFE_STEREO;
break;
case 1:
diff --git a/sound/soc/msm/msm-multi-ch-pcm-q6.c b/sound/soc/msm/msm-multi-ch-pcm-q6.c
index a13d4da..10b8f7a 100644
--- a/sound/soc/msm/msm-multi-ch-pcm-q6.c
+++ b/sound/soc/msm/msm-multi-ch-pcm-q6.c
@@ -83,7 +83,7 @@
.rate_min = 8000,
.rate_max = 48000,
.channels_min = 1,
- .channels_max = 6,
+ .channels_max = 8,
.buffer_bytes_max = PLAYBACK_NUM_PERIODS * PLAYBACK_MAX_PERIOD_SIZE,
.period_bytes_min = PLAYBACK_MIN_PERIOD_SIZE,
.period_bytes_max = PLAYBACK_MAX_PERIOD_SIZE,
diff --git a/sound/soc/msm/msm-pcm-routing.c b/sound/soc/msm/msm-pcm-routing.c
index 374357d..5f0a20e 100644
--- a/sound/soc/msm/msm-pcm-routing.c
+++ b/sound/soc/msm/msm-pcm-routing.c
@@ -1302,6 +1302,9 @@
SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_INT_BT_SCO_RX,
MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_INT_BT_SCO_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new int_fm_rx_mixer_controls[] = {
@@ -1317,6 +1320,9 @@
SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_INT_FM_RX,
MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_INT_FM_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new afe_pcm_rx_mixer_controls[] = {
@@ -1332,6 +1338,9 @@
SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_AFE_PCM_RX,
MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_AFE_PCM_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new auxpcm_rx_mixer_controls[] = {
@@ -1347,6 +1356,9 @@
SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_AUXPCM_RX,
MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_AUXPCM_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new sec_auxpcm_rx_mixer_controls[] = {
@@ -1407,6 +1419,18 @@
SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX,
MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MI2S_TX", MSM_BACKEND_DAI_MI2S_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
@@ -2322,6 +2346,7 @@
{"MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
{"MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
{"MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
+ {"MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"},
{"MI2S_RX", NULL, "MI2S_RX Audio Mixer"},
{"MultiMedia1 Mixer", "PRI_TX", "PRI_I2S_TX"},
@@ -2336,24 +2361,30 @@
{"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
{"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
{"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
+ {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia5", "MM_DL5"},
{"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX Audio Mixer"},
{"INTERNAL_FM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
{"INTERNAL_FM_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
{"INTERNAL_FM_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
{"INTERNAL_FM_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
+ {"INTERNAL_FM_RX Audio Mixer", "MultiMedia5", "MM_DL5"},
{"INT_FM_RX", NULL, "INTERNAL_FM_RX Audio Mixer"},
{"AFE_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
{"AFE_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
{"AFE_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
{"AFE_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
+ {"AFE_PCM_RX Audio Mixer", "MultiMedia5", "MM_DL5"},
{"PCM_RX", NULL, "AFE_PCM_RX Audio Mixer"},
{"MultiMedia1 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
+ {"MultiMedia5 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
{"MultiMedia1 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
+ {"MultiMedia5 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
{"MultiMedia1 Mixer", "AFE_PCM_TX", "PCM_TX"},
+ {"MultiMedia5 Mixer", "AFE_PCM_TX", "PCM_TX"},
{"MM_UL1", NULL, "MultiMedia1 Mixer"},
{"MultiMedia2 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
{"MM_UL2", NULL, "MultiMedia2 Mixer"},
@@ -2364,6 +2395,7 @@
{"AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
{"AUX_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
{"AUX_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
+ {"AUX_PCM_RX Audio Mixer", "MultiMedia5", "MM_DL5"},
{"AUX_PCM_RX", NULL, "AUX_PCM_RX Audio Mixer"},
{"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
diff --git a/sound/soc/msm/msm8930.c b/sound/soc/msm/msm8930.c
index a577b6a..c8d4b02 100644
--- a/sound/soc/msm/msm8930.c
+++ b/sound/soc/msm/msm8930.c
@@ -38,6 +38,7 @@
#define SPK_AMP_POS 0x1
#define SPK_AMP_NEG 0x2
#define SPKR_BOOST_GPIO 15
+#define LEFT_SPKR_AMPL_GPIO 15
#define DEFAULT_PMIC_SPK_GAIN 0x0D
#define SITAR_EXT_CLK_RATE 12288000
@@ -121,6 +122,24 @@
return 1;
}
+static int msm8930_cfg_spkr_gpio(int gpio,
+ int enable, const char *gpio_label)
+{
+ int ret = 0;
+
+ pr_debug("%s: Configure %s GPIO %u",
+ __func__, gpio_label, gpio);
+ ret = gpio_request(gpio, gpio_label);
+ if (ret)
+ return ret;
+
+ pr_debug("%s: Enable %s gpio %u\n",
+ __func__, gpio_label, gpio);
+ gpio_direction_output(gpio, enable);
+
+ return ret;
+}
+
static void msm8960_ext_spk_power_amp_on(u32 spk)
{
int ret = 0;
@@ -139,24 +158,30 @@
if ((msm8930_ext_spk_pamp & SPK_AMP_POS) &&
(msm8930_ext_spk_pamp & SPK_AMP_NEG)) {
- if (machine_is_msm8930_mtp()
- || machine_is_msm8930_fluid()) {
- pr_debug("%s: Configure Speaker Boost GPIO %u",
- __func__, SPKR_BOOST_GPIO);
- ret = gpio_request(SPKR_BOOST_GPIO,
- "SPKR_BOOST_EN");
+ if (socinfo_get_pmic_model() == PMIC_MODEL_PM8917) {
+ ret = msm8930_cfg_spkr_gpio(
+ LEFT_SPKR_AMPL_GPIO,
+ 1, "LEFT_SPKR_AMPL");
if (ret) {
- pr_err("%s: Failed to configure speaker boost "
- "gpio %u\n", __func__, SPKR_BOOST_GPIO);
+ pr_err("%s: Failed to config ampl gpio %u\n",
+ __func__, LEFT_SPKR_AMPL_GPIO);
return;
}
+ } else {
- pr_debug("%s: Enable Speaker boost gpio %u\n",
- __func__, SPKR_BOOST_GPIO);
- gpio_direction_output(SPKR_BOOST_GPIO, 1);
+ if (machine_is_msm8930_mtp()
+ || machine_is_msm8930_fluid()) {
+ ret = msm8930_cfg_spkr_gpio(
+ SPKR_BOOST_GPIO, 1, "SPKR_BOOST");
+ if (ret) {
+ pr_err("%s: Failure: spkr boost gpio %u\n",
+ __func__, SPKR_BOOST_GPIO);
+ return;
+ }
+ }
+ pm8xxx_spk_enable(MSM8930_SPK_ON);
}
- pm8xxx_spk_enable(MSM8930_SPK_ON);
pr_debug("%s: slepping 4 ms after turning on external "
" Left Speaker Ampl\n", __func__);
usleep_range(4000, 4000);
@@ -175,6 +200,13 @@
if (spk & (SPK_AMP_POS | SPK_AMP_NEG)) {
if (!msm8930_ext_spk_pamp)
return;
+
+ if (socinfo_get_pmic_model() == PMIC_MODEL_PM8917) {
+ gpio_free(LEFT_SPKR_AMPL_GPIO);
+ msm8930_ext_spk_pamp = 0;
+ return;
+ }
+
if (machine_is_msm8930_mtp()
|| machine_is_msm8930_fluid()) {
pr_debug("%s: Free speaker boost gpio %u\n",
@@ -463,7 +495,8 @@
{
int ret = 0;
msm8930_pmic_spk_gain = ucontrol->value.integer.value[0];
- ret = pm8xxx_spk_gain(msm8930_pmic_spk_gain);
+ if (socinfo_get_pmic_model() != PMIC_MODEL_PM8917)
+ ret = pm8xxx_spk_gain(msm8930_pmic_spk_gain);
pr_debug("%s: msm8930_pmic_spk_gain = %d"
" ucontrol->value.integer.value[0] = %d\n", __func__,
msm8930_pmic_spk_gain,
@@ -660,8 +693,10 @@
mbhc_cfg.gpio_irq = gpio_to_irq(mbhc_cfg.gpio);
sitar_hs_detect(codec, &mbhc_cfg);
- /* Initialize default PMIC speaker gain */
- pm8xxx_spk_gain(DEFAULT_PMIC_SPK_GAIN);
+ if (socinfo_get_pmic_model() != PMIC_MODEL_PM8917) {
+ /* Initialize default PMIC speaker gain */
+ pm8xxx_spk_gain(DEFAULT_PMIC_SPK_GAIN);
+ }
return 0;
}