Merge remote-tracking branch 'remotes/quic/jb_3.2' into HEAD
Conflicts:
drivers/gpu/msm/adreno.h
drivers/video/msm/mdss/mdss_mdp.h
Change-Id: Ieed8c5392255cb6633ced85695877a3d81cc0d2c
Signed-off-by: Zhoulu Luo <zluo@codeaurora.org>
diff --git a/Documentation/devicetree/bindings/arm/msm/spm-v2.txt b/Documentation/devicetree/bindings/arm/msm/spm-v2.txt
index d9a0d59..f969e2f 100644
--- a/Documentation/devicetree/bindings/arm/msm/spm-v2.txt
+++ b/Documentation/devicetree/bindings/arm/msm/spm-v2.txt
@@ -40,6 +40,8 @@
- qcom,saw2-spm-cmd-wfi: The WFI command sequence
- qcom,saw2-spm-cmd-ret: The Retention command sequence
- qcom,saw2-spm-cmd-spc: The Standalone PC command sequence
+- qcom,saw2-spm-cmd-pc-no-rpm: The Power Collapse command sequence where APPS
+ proc won't inform the RPM.
- qcom,saw2-spm-cmd-pc: The Power Collapse command sequence
- qcom,saw2-spm-cmd-gdhs: L2 GDHS command sequence
- qcom,L2-spm-is-apcs-master: Boolean indicates if the target uses L2 SAW to
diff --git a/Documentation/devicetree/bindings/usb/msm-hsusb.txt b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
index e7eae76..714311e 100644
--- a/Documentation/devicetree/bindings/usb/msm-hsusb.txt
+++ b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
@@ -86,6 +86,11 @@
for detection of dp line transition during VDD minimization.
- qcom,hsusb-otg-dmsehv-int: If present, indicates mpm interrupt to be configured
for detection of dm line transition during VDD minimization.
+- qcom,ahb-async-bridge-bypass: If present, indicates that enable AHB2AHB By Pass
+ mode with device controller for better throughput. With this mode, USB Core
+ runs using PNOC clock and synchronous to it. Hence it is must to have proper
+ "qcom,msm_bus,vectors" to have high bus frequency. User shouldn't try to
+ enable this feature without proper bus voting.
Example HSUSB OTG controller device node :
usb@f9690000 {
@@ -176,12 +181,19 @@
- qcom,android-usb-cdrom : if this property is present then device creates
a new LUN as CD-ROM
- qcom,android-usb-internal-ums : if this property is present then device
- creates a new LUN as internal usb mass storage
+ creates a new LUN as internal usb mass storage.
+- qcom,streaming-func : add list of usb function name. If mention usb function
+ is being enable as part of USB composition, streaming mode is enable with
+ usb device controller to get better throughput. NOTE: Inverted CRC and
+ turnaround timeout is observed on enabling streaming. Hence it is required
+ to see these errors and number of erros on enabling this at USB level to make
+ final decision to enable this feature or not.
Example Android USB device node :
android_usb@fc42b0c8 {
compatible = "qcom,android-usb";
reg = <0xfc42b0c8 0xc8>;
qcom,android-usb-swfi-latency = <1>;
+ qcom,streaming-func = "rndis","mtp";
};
diff --git a/arch/arm/boot/dts/msm8226-1080p-cdp.dtsi b/arch/arm/boot/dts/msm8226-1080p-cdp.dtsi
index e310c17..bb66538 100644
--- a/arch/arm/boot/dts/msm8226-1080p-cdp.dtsi
+++ b/arch/arm/boot/dts/msm8226-1080p-cdp.dtsi
@@ -27,13 +27,23 @@
vcc_i2c-supply = <&pm8226_lvs1>;
synaptics,reset-gpio = <&msmgpio 16 0x00>;
synaptics,irq-gpio = <&msmgpio 17 0x2008>;
- synaptics,button-map = <139 102 158>;
+ synaptics,display-coords = <0 0 1079 1919>;
synaptics,i2c-pull-up;
synaptics,power-down;
synaptics,disable-gpios;
};
};
+ gen-vkeys {
+ compatible = "qcom,gen-vkeys";
+ label = "synaptics_rmi4_i2c";
+ qcom,disp-maxx = <1079>;
+ qcom,disp-maxy = <1919>;
+ qcom,panel-maxx = <1079>;
+ qcom,panel-maxy = <2084>;
+ qcom,key-codes = <158 139 102 217>;
+ };
+
i2c@f9925000 { /* BLSP1 QUP3 */
nfc-nci@0e {
compatible = "qcom,nfc-nci";
diff --git a/arch/arm/boot/dts/msm8226-1080p-mtp.dtsi b/arch/arm/boot/dts/msm8226-1080p-mtp.dtsi
index e58c321..31624de 100644
--- a/arch/arm/boot/dts/msm8226-1080p-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8226-1080p-mtp.dtsi
@@ -27,13 +27,23 @@
vcc_i2c-supply = <&pm8226_lvs1>;
synaptics,reset-gpio = <&msmgpio 16 0x00>;
synaptics,irq-gpio = <&msmgpio 17 0x2008>;
- synaptics,button-map = <139 102 158>;
+ synaptics,display-coords = <0 0 1079 1919>;
synaptics,i2c-pull-up;
synaptics,power-down;
synaptics,disable-gpios;
};
};
+ gen-vkeys {
+ compatible = "qcom,gen-vkeys";
+ label = "synaptics_rmi4_i2c";
+ qcom,disp-maxx = <1079>;
+ qcom,disp-maxy = <1919>;
+ qcom,panel-maxx = <1079>;
+ qcom,panel-maxy = <2084>;
+ qcom,key-codes = <158 139 102 217>;
+ };
+
i2c@f9925000 { /* BLSP1 QUP3 */
nfc-nci@0e {
compatible = "qcom,nfc-nci";
diff --git a/arch/arm/boot/dts/msm8226-mdss.dtsi b/arch/arm/boot/dts/msm8226-mdss.dtsi
index 3e2507ff..e2891d1 100644
--- a/arch/arm/boot/dts/msm8226-mdss.dtsi
+++ b/arch/arm/boot/dts/msm8226-mdss.dtsi
@@ -36,7 +36,7 @@
qcom,mdss-wb-off = <0x00011100 0x00013100>;
qcom,mdss-intf-off = <0x00000000 0x00021300>;
qcom,mdss-rot-block-size = <64>;
- qcom,mdss-smp-mb-per-pipe = <2>;
+ qcom,mdss-smp-mb-per-pipe = <4>;
vdd-cx-supply = <&pm8226_s1_corner>;
qcom,vbif-settings = <0x004 0x00000001>,
diff --git a/arch/arm/boot/dts/msm8226.dtsi b/arch/arm/boot/dts/msm8226.dtsi
index 51a0795..3ef0d6d 100644
--- a/arch/arm/boot/dts/msm8226.dtsi
+++ b/arch/arm/boot/dts/msm8226.dtsi
@@ -39,7 +39,7 @@
qsecom_mem: qsecom_region {
linux,contiguous-region;
- reg = <0 0x780000>;
+ reg = <0 0xd00000>;
label = "qsecom_mem";
};
};
@@ -283,6 +283,7 @@
qcom,hsusb-otg-otg-control = <2>;
qcom,hsusb-otg-disable-reset;
qcom,dp-manual-pullup;
+ qcom,ahb-async-bridge-bypass;
qcom,msm-bus,name = "usb";
qcom,msm-bus,num-cases = <3>;
@@ -297,6 +298,7 @@
compatible = "qcom,android-usb";
reg = <0xfe8050c8 0xc8>;
qcom,android-usb-swfi-latency = <1>;
+ qcom,streaming-func = "rndis";
};
hsic_host: hsic@f9a00000 {
diff --git a/arch/arm/boot/dts/msm8610-v1-pm.dtsi b/arch/arm/boot/dts/msm8610-v1-pm.dtsi
index 6296692..62aa0f4 100644
--- a/arch/arm/boot/dts/msm8610-v1-pm.dtsi
+++ b/arch/arm/boot/dts/msm8610-v1-pm.dtsi
@@ -56,10 +56,10 @@
qcom,saw2-spm-dly= <0x3c102800>;
qcom,saw2-spm-ctl = <0x8>;
qcom,saw2-spm-cmd-wfi = [60 03 60 0b 0f];
- qcom,saw2-spm-cmd-spc = [00 20 10 80 30 90 5b 60 03 60 3b 76 76
- 0b 94 5b 80 10 06 26 30 0f];
- qcom,saw2-spm-cmd-pc = [00 20 10 80 30 90 5b 60 03 60 3b 76 76
- 0b 94 5b 80 10 06 26 30 0f];
+ qcom,saw2-spm-cmd-spc = [20 10 80 30 90 5b 60 03 60 3b 76 76
+ 0b 94 5b 80 10 26 30 0f];
+ qcom,saw2-spm-cmd-pc = [20 10 80 30 90 5b 60 03 60 3b 76 76
+ 0b 94 5b 80 10 26 30 0f];
};
qcom,spm@f90b9000 {
@@ -99,6 +99,9 @@
qcom,saw2-spm-cmd-pc = [00 32 b0 10 e0 d0 6b c0 42 f0
11 07 01 b0 50 4e 02 02 c0 d0 12 e0 6b 02 32
50 f0 0f]; /*APCS_PMIC_OFF_L2RAM_OFF*/
+ qcom,saw2-spm-cmd-pc-no-rpm = [00 32 b0 10 e0 d0 6b c0 42 f0
+ 11 03 01 b0 50 4e 02 02 c0 d0 12 e0 6b 02 32
+ 50 f0 0f]; /*APCS_PMIC_OFF_L2RAM_OFF*/
qcom,L2-spm-is-apcs-master;
};
@@ -125,28 +128,29 @@
qcom,latency-us = <500>;
qcom,ss-power = <410>;
qcom,energy-overhead = <603400>;
- qcom,time-overhead = <1200>;
+ qcom,time-overhead = <1410>;
};
qcom,lpm-level@2 {
reg = <0x2>;
qcom,mode = "pc";
- qcom,l2 = "l2_cache_retention";
- qcom,latency-us = <520>;
- qcom,ss-power = <460>;
- qcom,energy-overhead = <704900>;
- qcom,time-overhead = <1300>;
+ qcom,l2 = "l2_cache_pc_no_rpm";
+ qcom,latency-us = <1000>;
+ qcom,ss-power = <315>;
+ qcom,energy-overhead = <1027150>;
+ qcom,time-overhead = <2400>;
};
qcom,lpm-level@3 {
reg = <0x3>;
qcom,mode = "pc";
qcom,l2 = "l2_cache_pc";
- qcom,latency-us = <11700>;
+ qcom,latency-us = <12700>;
qcom,ss-power = <315>;
qcom,energy-overhead = <1027150>;
qcom,time-overhead = <2400>;
};
+
};
qcom,pm-boot {
diff --git a/arch/arm/boot/dts/msm8610-v2-pm.dtsi b/arch/arm/boot/dts/msm8610-v2-pm.dtsi
index 6c7f2f6..e401f7a 100644
--- a/arch/arm/boot/dts/msm8610-v2-pm.dtsi
+++ b/arch/arm/boot/dts/msm8610-v2-pm.dtsi
@@ -56,10 +56,10 @@
qcom,saw2-spm-dly= <0x3c102800>;
qcom,saw2-spm-ctl = <0x8>;
qcom,saw2-spm-cmd-wfi = [60 03 60 0b 0f];
- qcom,saw2-spm-cmd-spc = [00 20 10 80 30 90 5b 60 03 60 3b 76 76
- 0b 94 5b 80 10 06 26 30 0f];
- qcom,saw2-spm-cmd-pc = [00 20 10 80 30 90 5b 60 03 60 3b 76 76
- 0b 94 5b 80 10 06 26 30 0f];
+ qcom,saw2-spm-cmd-spc = [20 10 80 30 90 5b 60 03 60 3b 76 76
+ 0b 94 5b 80 10 26 30 0f];
+ qcom,saw2-spm-cmd-pc = [20 10 80 30 90 5b 60 03 60 3b 76 76
+ 0b 94 5b 80 10 26 30 0f];
};
qcom,spm@f90b9000 {
@@ -101,6 +101,9 @@
qcom,saw2-spm-cmd-pc = [00 32 b0 10 e0 d0 6b c0 42 f0
11 07 01 b0 50 4e 02 02 c0 d0 12 e0 6b 02 32
50 f0 0f]; /*APCS_PMIC_OFF_L2RAM_OFF*/
+ qcom,saw2-spm-cmd-pc-no-rpm = [00 32 b0 10 e0 d0 6b c0 42 f0
+ 11 03 01 b0 50 4e 02 02 c0 d0 12 e0 6b 02 32
+ 50 f0 0f]; /*APCS_PMIC_OFF_L2RAM_OFF*/
qcom,L2-spm-is-apcs-master;
};
@@ -134,17 +137,27 @@
reg = <0x2>;
qcom,mode = "pc";
qcom,l2 = "l2_cache_gdhs";
- qcom,latency-us = <10700>;
- qcom,ss-power = <325>;
- qcom,energy-overhead = <441250>;
- qcom,time-overhead = <1020>;
+ qcom,latency-us = <11700>;
+ qcom,ss-power = <372>;
+ qcom,energy-overhead = <738750>;
+ qcom,time-overhead = <1410>;
};
qcom,lpm-level@3 {
reg = <0x3>;
qcom,mode = "pc";
+ qcom,l2 = "l2_cache_pc_no_rpm";
+ qcom,latency-us = <1000>;
+ qcom,ss-power = <315>;
+ qcom,energy-overhead = <1027150>;
+ qcom,time-overhead = <2400>;
+ };
+
+ qcom,lpm-level@4 {
+ reg = <0x4>;
+ qcom,mode = "pc";
qcom,l2 = "l2_cache_pc";
- qcom,latency-us = <11700>;
+ qcom,latency-us = <12700>;
qcom,ss-power = <315>;
qcom,energy-overhead = <1027150>;
qcom,time-overhead = <2400>;
diff --git a/arch/arm/boot/dts/msm8610.dtsi b/arch/arm/boot/dts/msm8610.dtsi
index 9406b75..42b7887 100644
--- a/arch/arm/boot/dts/msm8610.dtsi
+++ b/arch/arm/boot/dts/msm8610.dtsi
@@ -239,6 +239,7 @@
qcom,hsusb-otg-otg-control = <2>;
qcom,hsusb-otg-disable-reset;
qcom,dp-manual-pullup;
+ qcom,ahb-async-bridge-bypass;
qcom,msm-bus,name = "usb2";
qcom,msm-bus,num-cases = <2>;
@@ -253,6 +254,7 @@
compatible = "qcom,android-usb";
reg = <0xfe8050c8 0xc8>;
qcom,android-usb-swfi-latency = <1>;
+ qcom,streaming-func = "rndis";
};
sdcc1: qcom,sdcc@f9824000 {
@@ -422,7 +424,6 @@
compatible = "qcom,rpm-smd";
rpm-channel-name = "rpm_requests";
rpm-channel-type = <15>; /* SMD_APPS_RPM */
- rpm-standalone;
};
qcom,bcl {
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index e000e5e..edb73b4 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -440,12 +440,18 @@
*/
thumb = handler & 1;
+#if __LINUX_ARM_ARCH__ >= 7
+ /*
+ * Clear the If-Then Thumb-2 execution state
+ * ARM spec requires this to be all 000s in ARM mode
+ * Snapdragon S4/Krait misbehaves on a Thumb=>ARM
+ * signal transition without this.
+ */
+ cpsr &= ~PSR_IT_MASK;
+#endif
+
if (thumb) {
cpsr |= PSR_T_BIT;
-#if __LINUX_ARM_ARCH__ >= 7
- /* clear the If-Then Thumb-2 execution state */
- cpsr &= ~PSR_IT_MASK;
-#endif
} else
cpsr &= ~PSR_T_BIT;
}
diff --git a/arch/arm/lib/memset.S b/arch/arm/lib/memset.S
index 650d592..94b0650 100644
--- a/arch/arm/lib/memset.S
+++ b/arch/arm/lib/memset.S
@@ -14,27 +14,15 @@
.text
.align 5
- .word 0
-
-1: subs r2, r2, #4 @ 1 do we have enough
- blt 5f @ 1 bytes to align with?
- cmp r3, #2 @ 1
- strltb r1, [r0], #1 @ 1
- strleb r1, [r0], #1 @ 1
- strb r1, [r0], #1 @ 1
- add r2, r2, r3 @ 1 (r2 = r2 - (4 - r3))
-/*
- * The pointer is now aligned and the length is adjusted. Try doing the
- * memset again.
- */
ENTRY(memset)
ands r3, r0, #3 @ 1 unaligned?
- bne 1b @ 1
+ mov ip, r0 @ preserve r0 as return value
+ bne 6f @ 1
/*
- * we know that the pointer in r0 is aligned to a word boundary.
+ * we know that the pointer in ip is aligned to a word boundary.
*/
- orr r1, r1, r1, lsl #8
+1: orr r1, r1, r1, lsl #8
orr r1, r1, r1, lsl #16
mov r3, r1
cmp r2, #16
@@ -43,29 +31,28 @@
#if ! CALGN(1)+0
/*
- * We need an extra register for this loop - save the return address and
- * use the LR
+ * We need 2 extra registers for this loop - use r8 and the LR
*/
- str lr, [sp, #-4]!
- mov ip, r1
+ stmfd sp!, {r8, lr}
+ mov r8, r1
mov lr, r1
2: subs r2, r2, #64
- stmgeia r0!, {r1, r3, ip, lr} @ 64 bytes at a time.
- stmgeia r0!, {r1, r3, ip, lr}
- stmgeia r0!, {r1, r3, ip, lr}
- stmgeia r0!, {r1, r3, ip, lr}
+ stmgeia ip!, {r1, r3, r8, lr} @ 64 bytes at a time.
+ stmgeia ip!, {r1, r3, r8, lr}
+ stmgeia ip!, {r1, r3, r8, lr}
+ stmgeia ip!, {r1, r3, r8, lr}
bgt 2b
- ldmeqfd sp!, {pc} @ Now <64 bytes to go.
+ ldmeqfd sp!, {r8, pc} @ Now <64 bytes to go.
/*
* No need to correct the count; we're only testing bits from now on
*/
tst r2, #32
- stmneia r0!, {r1, r3, ip, lr}
- stmneia r0!, {r1, r3, ip, lr}
+ stmneia ip!, {r1, r3, r8, lr}
+ stmneia ip!, {r1, r3, r8, lr}
tst r2, #16
- stmneia r0!, {r1, r3, ip, lr}
- ldr lr, [sp], #4
+ stmneia ip!, {r1, r3, r8, lr}
+ ldmfd sp!, {r8, lr}
#else
@@ -74,54 +61,63 @@
* whole cache lines at once.
*/
- stmfd sp!, {r4-r7, lr}
+ stmfd sp!, {r4-r8, lr}
mov r4, r1
mov r5, r1
mov r6, r1
mov r7, r1
- mov ip, r1
+ mov r8, r1
mov lr, r1
cmp r2, #96
- tstgt r0, #31
+ tstgt ip, #31
ble 3f
- and ip, r0, #31
- rsb ip, ip, #32
- sub r2, r2, ip
- movs ip, ip, lsl #(32 - 4)
- stmcsia r0!, {r4, r5, r6, r7}
- stmmiia r0!, {r4, r5}
- tst ip, #(1 << 30)
- mov ip, r1
- strne r1, [r0], #4
+ and r8, ip, #31
+ rsb r8, r8, #32
+ sub r2, r2, r8
+ movs r8, r8, lsl #(32 - 4)
+ stmcsia ip!, {r4, r5, r6, r7}
+ stmmiia ip!, {r4, r5}
+ tst r8, #(1 << 30)
+ mov r8, r1
+ strne r1, [ip], #4
3: subs r2, r2, #64
- stmgeia r0!, {r1, r3-r7, ip, lr}
- stmgeia r0!, {r1, r3-r7, ip, lr}
+ stmgeia ip!, {r1, r3-r8, lr}
+ stmgeia ip!, {r1, r3-r8, lr}
bgt 3b
- ldmeqfd sp!, {r4-r7, pc}
+ ldmeqfd sp!, {r4-r8, pc}
tst r2, #32
- stmneia r0!, {r1, r3-r7, ip, lr}
+ stmneia ip!, {r1, r3-r8, lr}
tst r2, #16
- stmneia r0!, {r4-r7}
- ldmfd sp!, {r4-r7, lr}
+ stmneia ip!, {r4-r7}
+ ldmfd sp!, {r4-r8, lr}
#endif
4: tst r2, #8
- stmneia r0!, {r1, r3}
+ stmneia ip!, {r1, r3}
tst r2, #4
- strne r1, [r0], #4
+ strne r1, [ip], #4
/*
* When we get here, we've got less than 4 bytes to zero. We
* may have an unaligned pointer as well.
*/
5: tst r2, #2
- strneb r1, [r0], #1
- strneb r1, [r0], #1
+ strneb r1, [ip], #1
+ strneb r1, [ip], #1
tst r2, #1
- strneb r1, [r0], #1
+ strneb r1, [ip], #1
mov pc, lr
+
+6: subs r2, r2, #4 @ 1 do we have enough
+ blt 5b @ 1 bytes to align with?
+ cmp r3, #2 @ 1
+ strltb r1, [ip], #1 @ 1
+ strleb r1, [ip], #1 @ 1
+ strb r1, [ip], #1 @ 1
+ add r2, r2, r3 @ 1 (r2 = r2 - (4 - r3))
+ b 1b
ENDPROC(memset)
diff --git a/arch/arm/mach-msm/acpuclock-8974.c b/arch/arm/mach-msm/acpuclock-8974.c
index 60be20a..5117949 100644
--- a/arch/arm/mach-msm/acpuclock-8974.c
+++ b/arch/arm/mach-msm/acpuclock-8974.c
@@ -95,159 +95,7 @@
},
};
-static struct msm_bus_paths bw_level_tbl_v1[] __initdata = {
- [0] = BW_MBPS(600), /* At least 75 MHz on bus. */
- [1] = BW_MBPS(800), /* At least 100 MHz on bus. */
- [2] = BW_MBPS(1200), /* At least 150 MHz on bus. */
- [3] = BW_MBPS(1600), /* At least 200 MHz on bus. */
- [4] = BW_MBPS(2224), /* At least 278 MHz on bus. */
- [5] = BW_MBPS(3200), /* At least 400 MHz on bus. */
- [6] = BW_MBPS(4448), /* At least 556 MHz on bus. */
- [7] = BW_MBPS(6400), /* At least 800 MHz on bus. */
-};
-
-static struct l2_level l2_freq_tbl_v1[] __initdata = {
- [0] = { { 300000, PLL_0, 0, 0 }, LVL_LOW, 950000, 0 },
- [1] = { { 345600, HFPLL, 2, 36 }, LVL_NOM, 950000, 1 },
- [2] = { { 422400, HFPLL, 2, 44 }, LVL_NOM, 950000, 1 },
- [3] = { { 499200, HFPLL, 2, 52 }, LVL_NOM, 950000, 2 },
- [4] = { { 576000, HFPLL, 1, 30 }, LVL_NOM, 950000, 3 },
- [5] = { { 652800, HFPLL, 1, 34 }, LVL_NOM, 950000, 3 },
- [6] = { { 729600, HFPLL, 1, 38 }, LVL_NOM, 950000, 3 },
- [7] = { { 806400, HFPLL, 1, 42 }, LVL_HIGH, 1050000, 4 },
- [8] = { { 883200, HFPLL, 1, 46 }, LVL_HIGH, 1050000, 4 },
- [9] = { { 960000, HFPLL, 1, 50 }, LVL_HIGH, 1050000, 4 },
- [10] = { { 1036800, HFPLL, 1, 54 }, LVL_HIGH, 1050000, 5 },
- [11] = { { 1113600, HFPLL, 1, 58 }, LVL_HIGH, 1050000, 5 },
- [12] = { { 1190400, HFPLL, 1, 62 }, LVL_HIGH, 1050000, 6 },
- [13] = { { 1267200, HFPLL, 1, 66 }, LVL_HIGH, 1050000, 6 },
- [14] = { { 1344000, HFPLL, 1, 70 }, LVL_HIGH, 1050000, 7 },
- [15] = { { 1420800, HFPLL, 1, 74 }, LVL_HIGH, 1050000, 7 },
- [16] = { { 1497600, HFPLL, 1, 78 }, LVL_HIGH, 1050000, 7 },
- { }
-};
-
-static struct acpu_level acpu_freq_tbl_v1_pvs0[] __initdata = {
- { 1, { 300000, PLL_0, 0, 0 }, L2(0), 825000, 73 },
- { 0, { 345600, HFPLL, 2, 36 }, L2(3), 825000, 85 },
- { 1, { 422400, HFPLL, 2, 44 }, L2(3), 825000, 104 },
- { 0, { 499200, HFPLL, 2, 52 }, L2(6), 825000, 124 },
- { 1, { 576000, HFPLL, 1, 30 }, L2(6), 825000, 144 },
- { 1, { 652800, HFPLL, 1, 34 }, L2(7), 825000, 165 },
- { 1, { 729600, HFPLL, 1, 38 }, L2(7), 825000, 186 },
- { 0, { 806400, HFPLL, 1, 42 }, L2(10), 835000, 208 },
- { 1, { 883200, HFPLL, 1, 46 }, L2(10), 845000, 229 },
- { 0, { 960000, HFPLL, 1, 50 }, L2(10), 860000, 252 },
- { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 880000, 275 },
- { 0, { 1113600, HFPLL, 1, 58 }, L2(12), 905000, 298 },
- { 0, { 1190400, HFPLL, 1, 62 }, L2(12), 920000, 321 },
- { 0, { 1267200, HFPLL, 1, 66 }, L2(12), 940000, 346 },
- { 1, { 1344000, HFPLL, 1, 70 }, L2(12), 960000, 371 },
- { 0, { 1420800, HFPLL, 1, 74 }, L2(16), 980000, 397 },
- { 0, { 1497600, HFPLL, 1, 78 }, L2(16), 995000, 423 },
- { 0, { 1574400, HFPLL, 1, 82 }, L2(16), 1015000, 450 },
- { 0, { 1651200, HFPLL, 1, 86 }, L2(16), 1030000, 477 },
- { 1, { 1728000, HFPLL, 1, 90 }, L2(16), 1050000, 506 },
- { 0, { 0 } }
-};
-
-static struct acpu_level acpu_freq_tbl_v1_pvs1[] __initdata = {
- { 1, { 300000, PLL_0, 0, 0 }, L2(0), 825000, 73 },
- { 0, { 345600, HFPLL, 2, 36 }, L2(3), 825000, 85 },
- { 1, { 422400, HFPLL, 2, 44 }, L2(3), 825000, 104 },
- { 0, { 499200, HFPLL, 2, 52 }, L2(6), 825000, 124 },
- { 1, { 576000, HFPLL, 1, 30 }, L2(6), 825000, 144 },
- { 1, { 652800, HFPLL, 1, 34 }, L2(7), 825000, 165 },
- { 1, { 729600, HFPLL, 1, 38 }, L2(7), 825000, 186 },
- { 0, { 806400, HFPLL, 1, 42 }, L2(10), 835000, 208 },
- { 1, { 883200, HFPLL, 1, 46 }, L2(10), 845000, 229 },
- { 0, { 960000, HFPLL, 1, 50 }, L2(10), 860000, 252 },
- { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 880000, 275 },
- { 0, { 1113600, HFPLL, 1, 58 }, L2(12), 905000, 298 },
- { 0, { 1190400, HFPLL, 1, 62 }, L2(12), 920000, 321 },
- { 0, { 1267200, HFPLL, 1, 66 }, L2(12), 940000, 346 },
- { 1, { 1344000, HFPLL, 1, 70 }, L2(12), 960000, 371 },
- { 0, { 1420800, HFPLL, 1, 74 }, L2(16), 980000, 397 },
- { 0, { 1497600, HFPLL, 1, 78 }, L2(16), 995000, 423 },
- { 0, { 1574400, HFPLL, 1, 82 }, L2(16), 1015000, 450 },
- { 0, { 1651200, HFPLL, 1, 86 }, L2(16), 1030000, 477 },
- { 1, { 1728000, HFPLL, 1, 90 }, L2(16), 1050000, 506 },
- { 0, { 0 } }
-};
-
-static struct acpu_level acpu_freq_tbl_v1_pvs2[] __initdata = {
- { 1, { 300000, PLL_0, 0, 0 }, L2(0), 825000, 73 },
- { 0, { 345600, HFPLL, 2, 36 }, L2(3), 825000, 85 },
- { 1, { 422400, HFPLL, 2, 44 }, L2(3), 825000, 104 },
- { 0, { 499200, HFPLL, 2, 52 }, L2(6), 825000, 124 },
- { 1, { 576000, HFPLL, 1, 30 }, L2(6), 825000, 144 },
- { 1, { 652800, HFPLL, 1, 34 }, L2(7), 825000, 165 },
- { 1, { 729600, HFPLL, 1, 38 }, L2(7), 825000, 186 },
- { 0, { 806400, HFPLL, 1, 42 }, L2(10), 825000, 208 },
- { 1, { 883200, HFPLL, 1, 46 }, L2(10), 825000, 229 },
- { 0, { 960000, HFPLL, 1, 50 }, L2(10), 835000, 252 },
- { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 855000, 275 },
- { 0, { 1113600, HFPLL, 1, 58 }, L2(12), 875000, 298 },
- { 0, { 1190400, HFPLL, 1, 62 }, L2(12), 895000, 321 },
- { 0, { 1267200, HFPLL, 1, 66 }, L2(12), 915000, 346 },
- { 1, { 1344000, HFPLL, 1, 70 }, L2(12), 930000, 371 },
- { 0, { 1420800, HFPLL, 1, 74 }, L2(16), 945000, 397 },
- { 0, { 1497600, HFPLL, 1, 78 }, L2(16), 960000, 423 },
- { 0, { 1574400, HFPLL, 1, 82 }, L2(16), 975000, 450 },
- { 0, { 1651200, HFPLL, 1, 86 }, L2(16), 990000, 477 },
- { 1, { 1728000, HFPLL, 1, 90 }, L2(16), 1000000, 506 },
- { 0, { 0 } }
-};
-
-static struct acpu_level acpu_freq_tbl_v1_pvs3[] __initdata = {
- { 1, { 300000, PLL_0, 0, 0 }, L2(0), 825000, 73 },
- { 0, { 345600, HFPLL, 2, 36 }, L2(3), 825000, 85 },
- { 1, { 422400, HFPLL, 2, 44 }, L2(3), 825000, 104 },
- { 0, { 499200, HFPLL, 2, 52 }, L2(6), 825000, 124 },
- { 1, { 576000, HFPLL, 1, 30 }, L2(6), 825000, 144 },
- { 1, { 652800, HFPLL, 1, 34 }, L2(7), 825000, 165 },
- { 1, { 729600, HFPLL, 1, 38 }, L2(7), 825000, 186 },
- { 0, { 806400, HFPLL, 1, 42 }, L2(10), 825000, 208 },
- { 1, { 883200, HFPLL, 1, 46 }, L2(10), 825000, 229 },
- { 0, { 960000, HFPLL, 1, 50 }, L2(10), 835000, 252 },
- { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 855000, 275 },
- { 0, { 1113600, HFPLL, 1, 58 }, L2(12), 875000, 298 },
- { 0, { 1190400, HFPLL, 1, 62 }, L2(12), 895000, 321 },
- { 0, { 1267200, HFPLL, 1, 66 }, L2(12), 915000, 346 },
- { 1, { 1344000, HFPLL, 1, 70 }, L2(12), 930000, 371 },
- { 0, { 1420800, HFPLL, 1, 74 }, L2(16), 945000, 397 },
- { 0, { 1497600, HFPLL, 1, 78 }, L2(16), 960000, 423 },
- { 0, { 1574400, HFPLL, 1, 82 }, L2(16), 975000, 450 },
- { 0, { 1651200, HFPLL, 1, 86 }, L2(16), 990000, 477 },
- { 1, { 1728000, HFPLL, 1, 90 }, L2(16), 1000000, 506 },
- { 0, { 0 } }
-};
-
-static struct acpu_level acpu_freq_tbl_v1_pvs4[] __initdata = {
- { 1, { 300000, PLL_0, 0, 0 }, L2(0), 825000, 73 },
- { 0, { 345600, HFPLL, 2, 36 }, L2(3), 825000, 85 },
- { 1, { 422400, HFPLL, 2, 44 }, L2(3), 825000, 104 },
- { 0, { 499200, HFPLL, 2, 52 }, L2(6), 825000, 124 },
- { 1, { 576000, HFPLL, 1, 30 }, L2(6), 825000, 144 },
- { 1, { 652800, HFPLL, 1, 34 }, L2(7), 825000, 165 },
- { 1, { 729600, HFPLL, 1, 38 }, L2(7), 825000, 186 },
- { 0, { 806400, HFPLL, 1, 42 }, L2(10), 825000, 208 },
- { 1, { 883200, HFPLL, 1, 46 }, L2(10), 825000, 229 },
- { 0, { 960000, HFPLL, 1, 50 }, L2(10), 825000, 252 },
- { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 825000, 275 },
- { 0, { 1113600, HFPLL, 1, 58 }, L2(12), 835000, 298 },
- { 0, { 1190400, HFPLL, 1, 62 }, L2(12), 855000, 321 },
- { 0, { 1267200, HFPLL, 1, 66 }, L2(12), 870000, 346 },
- { 1, { 1344000, HFPLL, 1, 70 }, L2(12), 885000, 371 },
- { 0, { 1420800, HFPLL, 1, 74 }, L2(16), 900000, 397 },
- { 0, { 1497600, HFPLL, 1, 78 }, L2(16), 910000, 423 },
- { 0, { 1574400, HFPLL, 1, 82 }, L2(16), 925000, 450 },
- { 0, { 1651200, HFPLL, 1, 86 }, L2(16), 940000, 477 },
- { 1, { 1728000, HFPLL, 1, 90 }, L2(16), 950000, 506 },
- { 0, { 0 } }
-};
-
-static struct msm_bus_paths bw_level_tbl_v2[] __initdata = {
+static struct msm_bus_paths bw_level_tbl[] __initdata = {
[0] = BW_MBPS(600), /* At least 75 MHz on bus. */
[1] = BW_MBPS(800), /* At least 100 MHz on bus. */
[2] = BW_MBPS(1200), /* At least 150 MHz on bus. */
@@ -259,7 +107,7 @@
[8] = BW_MBPS(7448), /* At least 931 MHz on bus. */
};
-static struct l2_level l2_freq_tbl_v2[] __initdata = {
+static struct l2_level l2_freq_tbl[] __initdata = {
[0] = { { 300000, PLL_0, 0, 0 }, LVL_LOW, 950000, 0 },
[1] = { { 345600, HFPLL, 2, 36 }, LVL_LOW, 950000, 1 },
[2] = { { 422400, HFPLL, 2, 44 }, LVL_LOW, 950000, 2 },
@@ -2440,15 +2288,6 @@
{ 0, { 0 } }
};
-static struct pvs_table pvs_v1[NUM_PVS_REVS][NUM_SPEED_BINS][NUM_PVS] __initdata = {
- /* 8974v1 1.7GHz Parts */
- [0][0][0] = { acpu_freq_tbl_v1_pvs0, sizeof(acpu_freq_tbl_v1_pvs0) },
- [0][0][1] = { acpu_freq_tbl_v1_pvs1, sizeof(acpu_freq_tbl_v1_pvs1) },
- [0][0][2] = { acpu_freq_tbl_v1_pvs2, sizeof(acpu_freq_tbl_v1_pvs2) },
- [0][0][3] = { acpu_freq_tbl_v1_pvs3, sizeof(acpu_freq_tbl_v1_pvs3) },
- [0][0][4] = { acpu_freq_tbl_v1_pvs4, sizeof(acpu_freq_tbl_v1_pvs4) },
-};
-
static struct pvs_table pvs_v2[NUM_PVS_REVS][NUM_SPEED_BINS][NUM_PVS] __initdata = {
/* 8974v2 2.0GHz Parts */
[0][0][0] = { acpu_freq_tbl_2g_pvs0, sizeof(acpu_freq_tbl_2g_pvs0) },
@@ -2560,8 +2399,8 @@
};
static struct msm_bus_scale_pdata bus_scale_data __initdata = {
- .usecase = bw_level_tbl_v2,
- .num_usecases = ARRAY_SIZE(bw_level_tbl_v2),
+ .usecase = bw_level_tbl,
+ .num_usecases = ARRAY_SIZE(bw_level_tbl),
.active_only = 1,
.name = "acpuclk-8974",
};
@@ -2570,68 +2409,23 @@
.scalable = scalable,
.scalable_size = sizeof(scalable),
.hfpll_data = &hfpll_data,
- .pvs_tables = pvs_v2,
- .l2_freq_tbl = l2_freq_tbl_v2,
- .l2_freq_tbl_size = sizeof(l2_freq_tbl_v2),
+ .l2_freq_tbl = l2_freq_tbl,
+ .l2_freq_tbl_size = sizeof(l2_freq_tbl),
.bus_scale = &bus_scale_data,
.pte_efuse_phys = 0xFC4B80B0,
.get_bin_info = get_krait_bin_format_b,
.stby_khz = 300000,
};
-static void __init apply_pro_bringup_workaround(void)
-{
- acpuclk_8974_params.pvs_tables = pvs_pro;
-}
-
-static void __init apply_v1_l2_workaround(void)
-{
- static struct l2_level resticted_l2_tbl[] __initdata = {
- [0] = { { 300000, PLL_0, 0, 0 }, LVL_LOW, 1050000, 0 },
- [1] = { { 1497600, HFPLL, 1, 78 }, LVL_HIGH, 1050000, 7 },
- { }
- };
- struct acpu_level *l;
- int s, p, r;
-
- for (r = 0; r < NUM_PVS_REVS; r++)
- for (s = 0; s < NUM_SPEED_BINS; s++)
- for (p = 0; p < NUM_PVS; p++) {
- l = pvs_v1[r][s][p].table;
- for (; l && l->speed.khz; l++)
- l->l2_level = l->l2_level > 5 ? 1 : 0;
- }
-
- acpuclk_8974_params.l2_freq_tbl = resticted_l2_tbl;
- acpuclk_8974_params.l2_freq_tbl_size = sizeof(resticted_l2_tbl);
-}
-
#define cpu_is_msm8974pro() (cpu_is_msm8974pro_aa() || cpu_is_msm8974pro_ab() \
|| cpu_is_msm8974pro_ac())
static int __init acpuclk_8974_probe(struct platform_device *pdev)
{
- if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) == 1
- && cpu_is_msm8974()) {
- acpuclk_8974_params.pvs_tables = pvs_v1;
- acpuclk_8974_params.l2_freq_tbl = l2_freq_tbl_v1;
- bus_scale_data.usecase = bw_level_tbl_v1;
- bus_scale_data.num_usecases = ARRAY_SIZE(bw_level_tbl_v1);
- acpuclk_8974_params.l2_freq_tbl_size = sizeof(l2_freq_tbl_v1);
-
- /*
- * 8974 hardware revisions older than v1.2 may experience L2
- * parity errors when running at some performance points between
- * 300MHz and 1497.6MHz (non-inclusive), or when vdd_mx is less
- * than 1.05V. Restrict L2 operation to safe performance points
- * on these devices.
- */
- if (SOCINFO_VERSION_MINOR(socinfo_get_version()) < 2)
- apply_v1_l2_workaround();
- }
-
if (cpu_is_msm8974pro())
- apply_pro_bringup_workaround();
+ acpuclk_8974_params.pvs_tables = pvs_pro;
+ else
+ acpuclk_8974_params.pvs_tables = pvs_v2;
return acpuclk_krait_init(&pdev->dev, &acpuclk_8974_params);
}
diff --git a/arch/arm/mach-msm/cpuidle.c b/arch/arm/mach-msm/cpuidle.c
index 7c06268..c480e56 100644
--- a/arch/arm/mach-msm/cpuidle.c
+++ b/arch/arm/mach-msm/cpuidle.c
@@ -112,8 +112,8 @@
continue;
state = &msm_cpuidle_driver.states[state_count];
- snprintf(state->name, CPUIDLE_NAME_LEN, cstate->name);
- snprintf(state->desc, CPUIDLE_DESC_LEN, cstate->desc);
+ snprintf(state->name, CPUIDLE_NAME_LEN, "%s", cstate->name);
+ snprintf(state->desc, CPUIDLE_DESC_LEN, "%s", cstate->desc);
state->flags = 0;
state->exit_latency = 0;
state->power_usage = 0;
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c b/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
index a1463bc..5fa7b1b 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
@@ -179,6 +179,16 @@
pr_err("%s[%p]: pause cmd failed rc=%d\n",
__func__, audio, rc);
+ if (rc == 0) {
+ /* Send suspend only if pause was successful */
+ rc = q6asm_cmd(audio->ac, CMD_SUSPEND);
+ if (rc < 0)
+ pr_err("%s[%p]: suspend cmd failed rc=%d\n",
+ __func__, audio, rc);
+ } else
+ pr_err("%s[%p]: not sending suspend since pause failed\n",
+ __func__, audio);
+
} else
pr_err("%s[%p]: Driver not enabled\n", __func__, audio);
return rc;
diff --git a/arch/arm/mach-msm/rpm-regulator-smd.c b/arch/arm/mach-msm/rpm-regulator-smd.c
index 923e647..faf774f 100644
--- a/arch/arm/mach-msm/rpm-regulator-smd.c
+++ b/arch/arm/mach-msm/rpm-regulator-smd.c
@@ -1266,14 +1266,16 @@
{
struct device *dev = &pdev->dev;
struct rpm_regulator *reg;
+ struct rpm_vreg *rpm_vreg;
reg = platform_get_drvdata(pdev);
if (reg) {
- rpm_vreg_lock(reg->rpm_vreg);
+ rpm_vreg = reg->rpm_vreg;
+ rpm_vreg_lock(rpm_vreg);
regulator_unregister(reg->rdev);
list_del(®->list);
kfree(reg);
- rpm_vreg_unlock(reg->rpm_vreg);
+ rpm_vreg_unlock(rpm_vreg);
} else {
dev_err(dev, "%s: drvdata missing\n", __func__);
return -EINVAL;
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index 1d12b07..9a1a2eb 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -85,6 +85,7 @@
}
#ifdef CONFIG_SMP
thread->vfpstate.hard.cpu = NR_CPUS;
+ vfp_current_hw_state[cpu] = NULL;
#endif
}
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index 19ff6f4..f7c0d24 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -1485,26 +1485,25 @@
return err;
}
if (pkt_type == CALLBACK_DATA_TYPE) {
- if (payload_size > itemsize) {
+ if (payload_size > driver->itemsize) {
pr_err("diag: Dropping packet, packet payload size crosses 4KB limit. Current payload size %d\n",
payload_size);
driver->dropped_count++;
return -EBADMSG;
}
- mutex_lock(&driver->diagchar_mutex);
buf_copy = diagmem_alloc(driver, payload_size, POOL_TYPE_COPY);
if (!buf_copy) {
driver->dropped_count++;
- mutex_unlock(&driver->diagchar_mutex);
return -ENOMEM;
}
err = copy_from_user(buf_copy, buf + 4, payload_size);
if (err) {
pr_err("diag: copy failed for user space data\n");
- ret = -EIO;
- goto fail_free_copy;
+ diagmem_free(driver, buf_copy, POOL_TYPE_COPY);
+ buf_copy = NULL;
+ return -EIO;
}
/* Check for proc_type */
remote_proc = diag_get_remote(*(int *)buf_copy);
@@ -1513,7 +1512,9 @@
wait_event_interruptible(driver->wait_q,
(driver->in_busy_pktdata == 0));
ret = diag_process_apps_pkt(buf_copy, payload_size);
- goto fail_free_copy;
+ diagmem_free(driver, buf_copy, POOL_TYPE_COPY);
+ buf_copy = NULL;
+ return ret;
}
/* The packet is for the remote processor */
token_offset = 4;
@@ -1526,7 +1527,7 @@
1 + payload_size);
send.terminate = 1;
-
+ mutex_lock(&driver->diagchar_mutex);
if (!buf_hdlc)
buf_hdlc = diagmem_alloc(driver, HDLC_OUT_BUF_SIZE,
POOL_TYPE_HDLC);
diff --git a/drivers/gpu/msm/a3xx_reg.h b/drivers/gpu/msm/a3xx_reg.h
index 676f46d..be179ac 100644
--- a/drivers/gpu/msm/a3xx_reg.h
+++ b/drivers/gpu/msm/a3xx_reg.h
@@ -775,6 +775,9 @@
#define SP0_ICL1_MISSES 0x1A
#define SP_FS_CFLOW_INSTRUCTIONS 0x0C
+/* COUNTABLE FOR TSE PERFCOUNTER */
+#define TSE_INPUT_PRIM_NUM 0x0
+
/* VBIF PERFCOUNTER ENA/CLR values */
#define VBIF_PERF_CNT_0 BIT(0)
#define VBIF_PERF_CNT_1 BIT(1)
diff --git a/drivers/gpu/msm/adreno_a3xx.c b/drivers/gpu/msm/adreno_a3xx.c
index df1794f..732e8c7 100644
--- a/drivers/gpu/msm/adreno_a3xx.c
+++ b/drivers/gpu/msm/adreno_a3xx.c
@@ -3824,7 +3824,9 @@
* USP L1 instruction miss request.
* Set SP to count SP_FS_FULL_ALU_INSTRUCTIONS, it
* counts USP flow control instruction execution.
- * we will use this to augment our hang detection
+ * Set TSE to count TSE_INPUT_PRIM_NUM, it counts
+ * number of input primitives in TSE.
+ * we will use above countables for our hang detection
*/
if (adreno_dev->fast_hang_detect) {
ret = adreno_perfcounter_get(adreno_dev,
@@ -3848,6 +3850,10 @@
if (ret)
goto err;
ft_detect_regs[11] = ft_detect_regs[10] + 1;
+ adreno_perfcounter_get(adreno_dev, KGSL_PERFCOUNTER_GROUP_TSE,
+ TSE_INPUT_PRIM_NUM, &ft_detect_regs[12],
+ PERFCOUNTER_FLAG_KERNEL);
+ ft_detect_regs[13] = ft_detect_regs[12] + 1;
}
ret = adreno_perfcounter_get(adreno_dev, KGSL_PERFCOUNTER_GROUP_SP,
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index fe6b34c..1c2d096 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -60,6 +60,9 @@
struct sg_table *table;
};
+static void kgsl_put_process_private(struct kgsl_device *device,
+ struct kgsl_process_private *private);
+
static void kgsl_mem_entry_detach_process(struct kgsl_mem_entry *entry);
static void
@@ -341,14 +344,19 @@
*/
static int
kgsl_mem_entry_attach_process(struct kgsl_mem_entry *entry,
- struct kgsl_process_private *process)
+ struct kgsl_device_private *dev_priv)
{
int ret;
+ struct kgsl_process_private *process = dev_priv->process_priv;
+
+ ret = kref_get_unless_zero(&process->refcount);
+ if (!ret)
+ return -EBADF;
while (1) {
if (idr_pre_get(&process->mem_idr, GFP_KERNEL) == 0) {
ret = -ENOMEM;
- goto err;
+ goto err_put_proc_priv;
}
spin_lock(&process->mem_lock);
@@ -359,9 +367,10 @@
if (ret == 0)
break;
else if (ret != -EAGAIN)
- goto err;
+ goto err_put_proc_priv;
}
entry->priv = process;
+ entry->dev_priv = dev_priv;
spin_lock(&process->mem_lock);
ret = kgsl_mem_entry_track_gpuaddr(process, entry);
@@ -369,14 +378,17 @@
idr_remove(&process->mem_idr, entry->id);
spin_unlock(&process->mem_lock);
if (ret)
- goto err;
+ goto err_put_proc_priv;
/* map the memory after unlocking if gpuaddr has been assigned */
if (entry->memdesc.gpuaddr) {
ret = kgsl_mmu_map(process->pagetable, &entry->memdesc);
if (ret)
kgsl_mem_entry_detach_process(entry);
}
-err:
+ return ret;
+
+err_put_proc_priv:
+ kgsl_put_process_private(dev_priv->device, process);
return ret;
}
@@ -399,6 +411,7 @@
entry->priv->stats[entry->memtype].cur -= entry->memdesc.size;
spin_unlock(&entry->priv->mem_lock);
+ kgsl_put_process_private(entry->dev_priv->device, entry->priv);
entry->priv = NULL;
}
@@ -767,11 +780,6 @@
*/
static void kgsl_destroy_process_private(struct kref *kref)
{
-
- struct kgsl_mem_entry *entry = NULL;
- int next = 0;
-
-
struct kgsl_process_private *private = container_of(kref,
struct kgsl_process_private, refcount);
@@ -795,20 +803,6 @@
if (private->debug_root)
debugfs_remove_recursive(private->debug_root);
- while (1) {
- spin_lock(&private->mem_lock);
- entry = idr_get_next(&private->mem_idr, &next);
- spin_unlock(&private->mem_lock);
- if (entry == NULL)
- break;
- kgsl_mem_entry_put(entry);
- /*
- * Always start back at the beginning, to
- * ensure all entries are removed,
- * like list_for_each_entry_safe.
- */
- next = 0;
- }
idr_destroy(&private->mem_idr);
kgsl_mmu_putpagetable(private->pagetable);
@@ -953,6 +947,7 @@
struct kgsl_process_private *private = dev_priv->process_priv;
struct kgsl_device *device = dev_priv->device;
struct kgsl_context *context;
+ struct kgsl_mem_entry *entry;
int next = 0;
filep->private_data = NULL;
@@ -981,6 +976,25 @@
next = next + 1;
}
+ next = 0;
+ while (1) {
+ spin_lock(&private->mem_lock);
+ entry = idr_get_next(&private->mem_idr, &next);
+ spin_unlock(&private->mem_lock);
+ if (entry == NULL)
+ break;
+ /*
+ * If the free pending flag is not set it means that user space
+ * did not free it's reference to this entry, in that case
+ * free a reference to this entry, other references are from
+ * within kgsl so they will be freed eventually by kgsl
+ */
+ if (entry->dev_priv == dev_priv && !entry->pending_free) {
+ entry->pending_free = 1;
+ kgsl_mem_entry_put(entry);
+ }
+ next = next + 1;
+ }
/*
* Clean up any to-be-freed entries that belong to this
* process and this device. This is done after the context
@@ -2743,7 +2757,7 @@
/* echo back flags */
param->flags = entry->memdesc.flags;
- result = kgsl_mem_entry_attach_process(entry, private);
+ result = kgsl_mem_entry_attach_process(entry, dev_priv);
if (result)
goto error_attach;
@@ -3031,7 +3045,7 @@
if (result)
return result;
- result = kgsl_mem_entry_attach_process(entry, private);
+ result = kgsl_mem_entry_attach_process(entry, dev_priv);
if (result != 0)
goto err;
@@ -3064,7 +3078,7 @@
if (result != 0)
goto err;
- result = kgsl_mem_entry_attach_process(entry, private);
+ result = kgsl_mem_entry_attach_process(entry, dev_priv);
if (result != 0)
goto err;
diff --git a/drivers/gpu/msm/kgsl.h b/drivers/gpu/msm/kgsl.h
index ee7a485..6da4a86 100644
--- a/drivers/gpu/msm/kgsl.h
+++ b/drivers/gpu/msm/kgsl.h
@@ -200,6 +200,7 @@
struct kgsl_process_private *priv;
/* Initialized to 0, set to 1 when entry is marked for freeing */
int pending_free;
+ struct kgsl_device_private *dev_priv;
};
#ifdef CONFIG_MSM_KGSL_MMU_PAGE_FAULT
diff --git a/drivers/input/misc/mma8x5x.c b/drivers/input/misc/mma8x5x.c
index a325d54..91aa928 100644
--- a/drivers/input/misc/mma8x5x.c
+++ b/drivers/input/misc/mma8x5x.c
@@ -53,6 +53,7 @@
#define MMA8X5X_BUF_SIZE 7
#define MMA_SHUTTEDDOWN (1 << 31)
+#define MMA_STATE_MASK (~MMA_SHUTTEDDOWN)
struct sensor_regulator {
struct regulator *vreg;
@@ -349,7 +350,7 @@
struct input_polled_dev *poll_dev = pdata->poll_dev;
struct mma8x5x_data_axis data;
mutex_lock(&pdata->data_lock);
- if (pdata->active == MMA_STANDBY) {
+ if ((pdata->active & MMA_STATE_MASK) == MMA_STANDBY) {
poll_dev->poll_interval = POLL_STOP_TIME;
/* if standby ,set as 10s to slow the poll. */
goto out;
diff --git a/drivers/input/touchscreen/ft5x06_ts.c b/drivers/input/touchscreen/ft5x06_ts.c
index f366364..9a4301e 100644
--- a/drivers/input/touchscreen/ft5x06_ts.c
+++ b/drivers/input/touchscreen/ft5x06_ts.c
@@ -717,7 +717,9 @@
if (r_buf[0] != info.upgrade_id_1
|| r_buf[1] != info.upgrade_id_2) {
- dev_err(&client->dev, "Upgrade ID mismatch(%d)\n", i);
+ dev_err(&client->dev, "Upgrade ID mismatch(%d), IC=0x%x 0x%x, info=0x%x 0x%x\n",
+ i, r_buf[0], r_buf[1],
+ info.upgrade_id_1, info.upgrade_id_2);
} else
break;
}
@@ -743,6 +745,10 @@
else
is_5336_new_bootloader = FT_BLOADER_VERSION_LZ4;
+ dev_dbg(&client->dev, "bootloader type=%d, r_buf=0x%x, family_id=0x%x\n",
+ is_5336_new_bootloader, r_buf[0], ts_data->family_id);
+ /* is_5336_new_bootloader = FT_BLOADER_VERSION_GZF; */
+
/* erase app and panel paramenter area */
w_buf[0] = FT_ERASE_APP_REG;
ft5x06_i2c_write(client, w_buf, 1);
@@ -1537,7 +1543,7 @@
goto free_reset_gpio;
}
- data->family_id = reg_value;
+ data->family_id = pdata->family_id;
err = request_threaded_irq(client->irq, NULL,
ft5x06_ts_interrupt, pdata->irqflags,
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c
index 916df1d..8cd3889 100644
--- a/drivers/media/platform/msm/vidc/venus_hfi.c
+++ b/drivers/media/platform/msm/vidc/venus_hfi.c
@@ -1057,30 +1057,32 @@
dprintk(VIDC_ERR, "cannot write to shared Q's");
goto err_q_null;
}
- mutex_lock(&device->clk_pwr_lock);
- result = venus_hfi_clk_gating_off(device);
- if (result) {
- dprintk(VIDC_ERR, "%s : Clock enable failed\n",
- __func__);
- goto err_q_write;
- }
- result = venus_hfi_scale_clocks(device, device->clk_load);
- if (result) {
- dprintk(VIDC_ERR, "Clock scaling failed\n");
- goto err_q_write;
- }
if (!venus_hfi_write_queue(q_info, (u8 *)pkt, &rx_req_is_set)) {
+ mutex_lock(&device->clk_pwr_lock);
+ result = venus_hfi_clk_gating_off(device);
+ if (result) {
+ dprintk(VIDC_ERR, "%s : Clock enable failed\n",
+ __func__);
+ mutex_unlock(&device->clk_pwr_lock);
+ goto err_q_write;
+ }
+ result = venus_hfi_scale_clocks(device, device->clk_load);
+ if (result) {
+ dprintk(VIDC_ERR, "Clock scaling failed\n");
+ mutex_unlock(&device->clk_pwr_lock);
+ goto err_q_write;
+ }
if (rx_req_is_set)
venus_hfi_write_register(
device,
VIDC_CPU_IC_SOFTINT,
1 << VIDC_CPU_IC_SOFTINT_H2A_SHFT, 0);
result = 0;
+ mutex_unlock(&device->clk_pwr_lock);
} else {
dprintk(VIDC_ERR, "venus_hfi_iface_cmdq_write:queue_full");
}
err_q_write:
- mutex_unlock(&device->clk_pwr_lock);
err_q_null:
mutex_unlock(&device->write_lock);
return result;
@@ -1104,26 +1106,27 @@
goto read_error_null;
}
q_info = &device->iface_queues[VIDC_IFACEQ_MSGQ_IDX];
- mutex_lock(&device->clk_pwr_lock);
- rc = venus_hfi_clk_gating_off(device);
- if (rc) {
- dprintk(VIDC_ERR,
- "%s : Clock enable failed\n", __func__);
- goto read_error;
- }
if (!venus_hfi_read_queue(q_info, (u8 *)pkt, &tx_req_is_set)) {
+ mutex_lock(&device->clk_pwr_lock);
+ rc = venus_hfi_clk_gating_off(device);
+ if (rc) {
+ dprintk(VIDC_ERR,
+ "%s : Clock enable failed\n", __func__);
+ mutex_unlock(&device->clk_pwr_lock);
+ goto read_error;
+ }
if (tx_req_is_set)
venus_hfi_write_register(
device,
VIDC_CPU_IC_SOFTINT,
1 << VIDC_CPU_IC_SOFTINT_H2A_SHFT, 0);
rc = 0;
+ mutex_unlock(&device->clk_pwr_lock);
} else {
dprintk(VIDC_INFO, "venus_hfi_iface_msgq_read:queue_empty");
rc = -ENODATA;
}
read_error:
- mutex_unlock(&device->clk_pwr_lock);
read_error_null:
mutex_unlock(&device->read_lock);
return rc;
@@ -1146,27 +1149,28 @@
rc = -ENODATA;
goto dbg_error_null;
}
- mutex_lock(&device->clk_pwr_lock);
- rc = venus_hfi_clk_gating_off(device);
- if (rc) {
- dprintk(VIDC_ERR,
- "%s : Clock enable failed\n", __func__);
- goto dbg_error;
- }
q_info = &device->iface_queues[VIDC_IFACEQ_DBGQ_IDX];
if (!venus_hfi_read_queue(q_info, (u8 *)pkt, &tx_req_is_set)) {
+ mutex_lock(&device->clk_pwr_lock);
+ rc = venus_hfi_clk_gating_off(device);
+ if (rc) {
+ dprintk(VIDC_ERR,
+ "%s : Clock enable failed\n", __func__);
+ mutex_unlock(&device->clk_pwr_lock);
+ goto dbg_error;
+ }
if (tx_req_is_set)
venus_hfi_write_register(
device,
VIDC_CPU_IC_SOFTINT,
1 << VIDC_CPU_IC_SOFTINT_H2A_SHFT, 0);
rc = 0;
+ mutex_unlock(&device->clk_pwr_lock);
} else {
dprintk(VIDC_INFO, "venus_hfi_iface_dbgq_read:queue_empty");
rc = -ENODATA;
}
dbg_error:
- mutex_unlock(&device->clk_pwr_lock);
dbg_error_null:
mutex_unlock(&device->read_lock);
return rc;
@@ -1251,7 +1255,7 @@
for (i = 0; i < num_entries; i++) {
rc = msm_iommu_map_contig_buffer(venus_qdss_entries[i][0],
- domain, 1 , venus_qdss_entries[i][1],
+ domain, partition, venus_qdss_entries[i][1],
SZ_4K, 0, &iova);
if (rc) {
dprintk(VIDC_ERR,
@@ -1567,20 +1571,59 @@
return 0;
}
+static int venus_hfi_is_cmd_pending(struct venus_hfi_device *dev)
+{
+ struct hfi_queue_header *queue;
+ struct vidc_iface_q_info *q_info;
+ u32 write_ptr, read_ptr;
+ u32 rc = 0;
+ q_info = &dev->iface_queues[VIDC_IFACEQ_CMDQ_IDX];
+ if (!q_info)
+ dprintk(VIDC_ERR, "cannot read shared Q's");
+ queue = (struct hfi_queue_header *) q_info->q_hdr;
+ if (!queue) {
+ dprintk(VIDC_ERR, "queue not present");
+ return -ENOENT;
+ }
+ write_ptr = (u32)queue->qhdr_write_idx;
+ read_ptr = (u32)queue->qhdr_read_idx;
+ rc = read_ptr - write_ptr;
+ return rc;
+}
+
+static inline void venus_hfi_clk_gating_on(struct venus_hfi_device *device)
+{
+ if (!device) {
+ dprintk(VIDC_ERR, "Invalid params: %p\n", device);
+ return;
+ }
+ if (!device->clocks_enabled) {
+ dprintk(VIDC_DBG, "Clocks are already disabled");
+ goto already_disabled;
+ }
+ venus_hfi_clk_disable(device);
+ if (!queue_delayed_work(device->venus_pm_workq, &venus_hfi_pm_work,
+ msecs_to_jiffies(msm_vidc_pwr_collapse_delay)))
+ dprintk(VIDC_DBG, "PM work already scheduled\n");
+already_disabled:
+ device->clocks_enabled = 0;
+}
+
static void venus_hfi_core_clear_interrupt(struct venus_hfi_device *device)
{
u32 intr_status = 0;
- int rc = 0;
+ int rc = 0, ctrl_status;
if (!device->callback)
return;
+
+ mutex_lock(&device->write_lock);
mutex_lock(&device->clk_pwr_lock);
rc = venus_hfi_clk_gating_off(device);
if (rc) {
dprintk(VIDC_ERR,
"%s : Clock enable failed\n", __func__);
- mutex_unlock(&device->clk_pwr_lock);
- return;
+ goto err_clk_gating_off;
}
intr_status = venus_hfi_read_register(
device,
@@ -1603,8 +1646,23 @@
VIDC_CPU_CS_A2HSOFTINTCLR, 1, 0);
venus_hfi_write_register(device,
VIDC_WRAPPER_INTR_CLEAR, intr_status, 0);
- mutex_unlock(&device->clk_pwr_lock);
+ rc = venus_hfi_is_cmd_pending(device);
+ ctrl_status = venus_hfi_read_register(
+ device,
+ VIDC_CPU_CS_SCIACMDARG0);
+ dprintk(VIDC_INFO,
+ "CLEAR INTERRUPT - cmd_pending %d, ctrl_status 0x%x\n",
+ rc, ctrl_status);
+ if ((ctrl_status & VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_IDLE_MSG_BMSK)
+ && !rc) {
+ dprintk(VIDC_DBG, "SYS_IDLE interrupt, disable clocks\n");
+ venus_hfi_clk_gating_on(device);
+ }
+
dprintk(VIDC_DBG, "Cleared WRAPPER/A2H interrupt");
+err_clk_gating_off:
+ mutex_unlock(&device->clk_pwr_lock);
+ mutex_unlock(&device->write_lock);
}
static int venus_hfi_core_set_resource(void *device,
@@ -2321,26 +2379,6 @@
device->callback(SYS_WATCHDOG_TIMEOUT, &cmd_done);
}
-static int venus_hfi_is_cmd_pending(struct venus_hfi_device *dev)
-{
- struct hfi_queue_header *queue;
- struct vidc_iface_q_info *q_info;
- u32 write_ptr, read_ptr;
- u32 rc = 0;
- q_info = &dev->iface_queues[VIDC_IFACEQ_CMDQ_IDX];
- if (!q_info)
- dprintk(VIDC_ERR, "cannot read shared Q's");
- queue = (struct hfi_queue_header *) q_info->q_hdr;
- if (!queue) {
- dprintk(VIDC_ERR, "queue not present");
- return -ENOENT;
- }
- write_ptr = (u32)queue->qhdr_write_idx;
- read_ptr = (u32)queue->qhdr_read_idx;
- rc = read_ptr - write_ptr;
- return rc;
-}
-
static int venus_hfi_core_pc_prep(void *device)
{
struct hfi_cmd_sys_pc_prep_packet pkt;
@@ -2408,24 +2446,6 @@
mutex_unlock(&device->clk_pwr_lock);
}
-static inline void venus_hfi_clk_gating_on(struct venus_hfi_device *device)
-{
- if (!device) {
- dprintk(VIDC_ERR, "Invalid params: %p\n", device);
- return;
- }
- if (!device->clocks_enabled) {
- dprintk(VIDC_DBG, "Clocks are already disabled");
- goto already_disabled;
- }
- venus_hfi_clk_disable(device);
- if (!queue_delayed_work(device->venus_pm_workq, &venus_hfi_pm_work,
- msecs_to_jiffies(msm_vidc_pwr_collapse_delay)))
- dprintk(VIDC_DBG, "PM work already scheduled\n");
-already_disabled:
- device->clocks_enabled = 0;
-}
-
static int venus_hfi_try_clk_gating(struct venus_hfi_device *device)
{
int rc = 0;
@@ -2506,10 +2526,12 @@
(struct hfi_msg_sys_debug_packet *) packet;
dprintk(VIDC_FW, "FW-SAYS: %s", pkt->rg_msg_data);
}
- if (rc == HFI_MSG_SYS_IDLE)
+ if (rc == HFI_MSG_SYS_IDLE) {
+ dprintk(VIDC_DBG, "Received HFI_MSG_SYS_IDLE\n");
rc = venus_hfi_try_clk_gating(device);
- else if (rc == HFI_MSG_SYS_PC_PREP_DONE) {
- dprintk(VIDC_DBG, "Received HFI_MSG_SYS_PC_PREP_DONE");
+ } else if (rc == HFI_MSG_SYS_PC_PREP_DONE) {
+ dprintk(VIDC_DBG,
+ "Received HFI_MSG_SYS_PC_PREP_DONE\n");
rc = venus_hfi_try_clk_gating(device);
if (rc)
dprintk(VIDC_ERR,
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 995d9e4..a296e48 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -61,6 +61,7 @@
/* Flushing a large amount of cached data may take a long time. */
#define MMC_FLUSH_REQ_TIMEOUT_MS 90000 /* msec */
+#define MMC_CACHE_DISBALE_TIMEOUT_MS 180000 /* msec */
static struct workqueue_struct *workqueue;
@@ -3393,14 +3394,14 @@
if (card->ext_csd.cache_ctrl ^ enable) {
if (!enable)
- timeout = MMC_FLUSH_REQ_TIMEOUT_MS;
+ timeout = MMC_CACHE_DISBALE_TIMEOUT_MS;
err = mmc_switch_ignore_timeout(card,
EXT_CSD_CMD_SET_NORMAL,
EXT_CSD_CACHE_CTRL, enable, timeout);
if (err == -ETIMEDOUT && !enable) {
- pr_debug("%s:cache disable operation timeout\n",
+ pr_err("%s:cache disable operation timeout\n",
mmc_hostname(card->host));
rc = mmc_interrupt_hpi(card);
if (rc)
diff --git a/drivers/tty/serial/msm_serial_hs.c b/drivers/tty/serial/msm_serial_hs.c
index a243a05..078929b 100644
--- a/drivers/tty/serial/msm_serial_hs.c
+++ b/drivers/tty/serial/msm_serial_hs.c
@@ -155,7 +155,6 @@
struct tasklet_struct tlet;
struct msm_hs_sps_ep_conn_data prod;
};
-
enum buffer_states {
NONE_PENDING = 0x0,
FIFO_OVERRUN = 0x1,
@@ -219,6 +218,7 @@
struct msm_bus_scale_pdata *bus_scale_table;
bool rx_discard_flush_issued;
int rx_count_callback;
+ bool rx_bam_inprogress;
unsigned int *reg_ptr;
};
@@ -998,6 +998,14 @@
mutex_lock(&msm_uport->clk_mutex);
msm_hs_write(uport, UART_DM_IMR, 0);
+ /* Clear the Rx Ready Ctl bit - This ensures that
+ * flow control lines stop the other side from sending
+ * data while we change the parameters
+ */
+ data = msm_hs_read(uport, UART_DM_MR1);
+ data &= ~UARTDM_MR1_RX_RDY_CTL_BMSK;
+ msm_hs_write(uport, UART_DM_MR1, data);
+
/*
* Disable Rx channel of UARTDM
* DMA Rx Stall happens if enqueue and flush of Rx command happens
@@ -1071,18 +1079,6 @@
/* write parity/bits per char/stop bit configuration */
msm_hs_write(uport, UART_DM_MR2, data);
- /* Configure HW flow control */
- data = msm_hs_read(uport, UART_DM_MR1);
-
- data &= ~(UARTDM_MR1_CTS_CTL_BMSK | UARTDM_MR1_RX_RDY_CTL_BMSK);
-
- if (c_cflag & CRTSCTS) {
- data |= UARTDM_MR1_CTS_CTL_BMSK;
- data |= UARTDM_MR1_RX_RDY_CTL_BMSK;
- }
-
- msm_hs_write(uport, UART_DM_MR1, data);
-
uport->ignore_status_mask = termios->c_iflag & INPCK;
uport->ignore_status_mask |= termios->c_iflag & IGNPAR;
uport->ignore_status_mask |= termios->c_iflag & IGNBRK;
@@ -1106,6 +1102,10 @@
*/
mb();
if (is_blsp_uart(msm_uport)) {
+ if (msm_uport->rx_bam_inprogress)
+ ret = wait_event_timeout(msm_uport->rx.wait,
+ msm_uport->rx_bam_inprogress == false,
+ RX_FLUSH_COMPLETE_TIMEOUT);
ret = sps_disconnect(sps_pipe_handle);
if (ret)
pr_err("%s(): sps_disconnect failed\n",
@@ -1127,6 +1127,20 @@
}
}
+ /* Configure HW flow control
+ * UART Core would see status of CTS line when it is sending data
+ * to remote uart to confirm that it can receive or not.
+ * UART Core would trigger RFR if it is not having any space with
+ * RX FIFO.
+ */
+ data = msm_hs_read(uport, UART_DM_MR1);
+ data &= ~(UARTDM_MR1_CTS_CTL_BMSK | UARTDM_MR1_RX_RDY_CTL_BMSK);
+ if (c_cflag & CRTSCTS) {
+ data |= UARTDM_MR1_CTS_CTL_BMSK;
+ data |= UARTDM_MR1_RX_RDY_CTL_BMSK;
+ }
+ msm_hs_write(uport, UART_DM_MR1, data);
+
msm_hs_write(uport, UART_DM_IMR, msm_uport->imr_reg);
mb();
mutex_unlock(&msm_uport->clk_mutex);
@@ -1358,10 +1372,13 @@
msm_uport->rx.flush = FLUSH_NONE;
if (is_blsp_uart(msm_uport)) {
+ msm_uport->rx_bam_inprogress = true;
sps_pipe_handle = rx->prod.pipe_handle;
/* Queue transfer request to SPS */
sps_transfer_one(sps_pipe_handle, rx->rbuffer,
UARTDM_RX_BUF_SIZE, msm_uport, flags);
+ msm_uport->rx_bam_inprogress = false;
+ wake_up(&msm_uport->rx.wait);
} else {
msm_dmov_enqueue_cmd(msm_uport->dma_rx_channel,
&msm_uport->rx.xfer);
@@ -1531,10 +1548,13 @@
if (!msm_uport->rx.buffer_pending) {
if (is_blsp_uart(msm_uport)) {
msm_uport->rx.flush = FLUSH_NONE;
+ msm_uport->rx_bam_inprogress = true;
sps_pipe_handle = rx->prod.pipe_handle;
/* Queue transfer request to SPS */
sps_transfer_one(sps_pipe_handle, rx->rbuffer,
UARTDM_RX_BUF_SIZE, msm_uport, sps_flags);
+ msm_uport->rx_bam_inprogress = false;
+ wake_up(&msm_uport->rx.wait);
} else {
msm_hs_start_rx_locked(uport);
}
@@ -2832,9 +2852,9 @@
/* Now save the sps pipe handle */
ep->pipe_handle = sps_pipe_handle;
pr_debug("msm_serial_hs: success !! %s: pipe_handle=0x%x\n"
- "desc_fifo.phys_base=0x%x\n",
+ "desc_fifo.phys_base=0x%llx\n",
is_producer ? "READ" : "WRITE",
- (u32)sps_pipe_handle, sps_config->desc.phys_base);
+ (u32) sps_pipe_handle, (u64) sps_config->desc.phys_base);
return 0;
get_config_err:
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index 554cce8..97592c4 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -2288,8 +2288,12 @@
if (mdwc->otg_xceiv && !mdwc->ext_inuse &&
(mdwc->ext_xceiv.otg_capability || !init)) {
mdwc->ext_xceiv.bsv = val->intval;
+ /*
+ * set debouncing delay to 120msec. Otherwise battery
+ * charging CDP complaince test fails if delay > 120ms.
+ */
queue_delayed_work(system_nrt_wq,
- &mdwc->resume_work, 20);
+ &mdwc->resume_work, 12);
if (!init)
init = true;
diff --git a/drivers/usb/dwc3/dwc3_otg.c b/drivers/usb/dwc3/dwc3_otg.c
index 9599936..cacd635 100644
--- a/drivers/usb/dwc3/dwc3_otg.c
+++ b/drivers/usb/dwc3/dwc3_otg.c
@@ -93,6 +93,19 @@
return 0;
}
+static void dwc3_otg_set_hsphy_auto_suspend(struct dwc3_otg *dotg, bool susp)
+{
+ struct dwc3 *dwc = dotg->dwc;
+ u32 reg;
+
+ reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
+ if (susp)
+ reg |= DWC3_GUSB2PHYCFG_SUSPHY;
+ else
+ reg &= ~(DWC3_GUSB2PHYCFG_SUSPHY);
+ dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
+}
+
/**
* dwc3_otg_set_host_power - Enable port power control for host operation
*
@@ -194,6 +207,7 @@
* remove_hcd, But we may not use standard set_host method
* anymore.
*/
+ dwc3_otg_set_hsphy_auto_suspend(dotg, true);
dwc3_otg_set_host_regs(dotg);
/*
* FIXME If micro A cable is disconnected during system suspend,
@@ -242,6 +256,7 @@
ext_xceiv->ext_block_reset)
ext_xceiv->ext_block_reset(ext_xceiv, true);
+ dwc3_otg_set_hsphy_auto_suspend(dotg, false);
dwc3_otg_set_peripheral_regs(dotg);
/* re-init core and OTG registers as block reset clears these */
@@ -309,12 +324,14 @@
ext_xceiv->ext_block_reset)
ext_xceiv->ext_block_reset(ext_xceiv, false);
+ dwc3_otg_set_hsphy_auto_suspend(dotg, true);
dwc3_otg_set_peripheral_regs(dotg);
usb_gadget_vbus_connect(otg->gadget);
} else {
dev_dbg(otg->phy->dev, "%s: turn off gadget %s\n",
__func__, otg->gadget->name);
usb_gadget_vbus_disconnect(otg->gadget);
+ dwc3_otg_set_hsphy_auto_suspend(dotg, false);
}
return 0;
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 38c4b86..ad3a3a9 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -2623,13 +2623,10 @@
}
}
- /*
- * Notify suspend only to gadget driver, but not resume. Resume is
- * notified as part of wakeup event in dwc3_gadget_wakeup_interrupt().
- */
if (next == DWC3_LINK_STATE_U0) {
if (dwc->link_state == DWC3_LINK_STATE_U3) {
dbg_event(0xFF, "RESUME", 0);
+ dwc->gadget_driver->resume(&dwc->gadget);
}
} else if (next == DWC3_LINK_STATE_U3) {
dbg_event(0xFF, "SUSPEND", 0);
@@ -2920,7 +2917,11 @@
dwc3_writel(dwc->regs, DWC3_DCTL, reg);
- dwc3_gadget_usb2_phy_suspend(dwc, true);
+ /*
+ * Clear autosuspend bit in dwc3 register for USB2. It will be
+ * enabled before setting run/stop bit.
+ */
+ dwc3_gadget_usb2_phy_suspend(dwc, false);
dwc3_gadget_usb3_phy_suspend(dwc, true);
}
diff --git a/drivers/usb/gadget/android.c b/drivers/usb/gadget/android.c
index 6765078..c65ed25 100644
--- a/drivers/usb/gadget/android.c
+++ b/drivers/usb/gadget/android.c
@@ -2181,6 +2181,22 @@
}
}
+static inline void check_streaming_func(struct usb_gadget *gadget,
+ struct android_usb_platform_data *pdata,
+ char *name)
+{
+ int i;
+
+ for (i = 0; i < pdata->streaming_func_count; i++) {
+ if (!strcmp(name,
+ pdata->streaming_func[i])) {
+ pr_debug("set streaming_enabled to true\n");
+ gadget->streaming_enabled = true;
+ break;
+ }
+ }
+}
+
static int android_enable_function(struct android_dev *dev,
struct android_configuration *conf,
char *name)
@@ -2188,6 +2204,9 @@
struct android_usb_function **functions = dev->functions;
struct android_usb_function *f;
struct android_usb_function_holder *f_holder;
+ struct android_usb_platform_data *pdata = dev->pdata;
+ struct usb_gadget *gadget = dev->cdev->gadget;
+
while ((f = *functions++)) {
if (!strcmp(name, f->name)) {
if (f->android_dev && f->android_dev != dev)
@@ -2205,6 +2224,13 @@
f_holder->f = f;
list_add_tail(&f_holder->enabled_list,
&conf->enabled_functions);
+ pr_debug("func:%s is enabled.\n", f->name);
+ /*
+ * compare enable function with streaming func
+ * list and based on the same request streaming.
+ */
+ check_streaming_func(gadget, pdata, f->name);
+
return 0;
}
}
@@ -2577,6 +2603,10 @@
{
struct android_dev *dev = cdev_to_android_dev(c->cdev);
+ if (c->cdev->gadget->streaming_enabled) {
+ c->cdev->gadget->streaming_enabled = false;
+ pr_debug("setting streaming_enabled to false.\n");
+ }
android_unbind_enabled_functions(dev, c);
}
@@ -2745,8 +2775,10 @@
unsigned long flags;
spin_lock_irqsave(&cdev->lock, flags);
- dev->suspended = 1;
- schedule_work(&dev->work);
+ if (!dev->suspended) {
+ dev->suspended = 1;
+ schedule_work(&dev->work);
+ }
spin_unlock_irqrestore(&cdev->lock, flags);
composite_suspend(gadget);
@@ -2759,8 +2791,10 @@
unsigned long flags;
spin_lock_irqsave(&cdev->lock, flags);
- dev->suspended = 0;
- schedule_work(&dev->work);
+ if (dev->suspended) {
+ dev->suspended = 0;
+ schedule_work(&dev->work);
+ }
spin_unlock_irqrestore(&cdev->lock, flags);
composite_resume(gadget);
@@ -2895,7 +2929,7 @@
struct android_usb_platform_data *pdata;
struct android_dev *android_dev;
struct resource *res;
- int ret = 0;
+ int ret = 0, i, len = 0;
if (pdev->dev.of_node) {
dev_dbg(&pdev->dev, "device tree enabled\n");
@@ -2912,6 +2946,33 @@
"qcom,android-usb-cdrom");
pdata->internal_ums = of_property_read_bool(pdev->dev.of_node,
"qcom,android-usb-internal-ums");
+ len = of_property_count_strings(pdev->dev.of_node,
+ "qcom,streaming-func");
+ if (len > MAX_STREAMING_FUNCS) {
+ pr_err("Invalid number of functions used.\n");
+ return -EINVAL;
+ }
+
+ for (i = 0; i < len; i++) {
+ const char *name = NULL;
+
+ of_property_read_string_index(pdev->dev.of_node,
+ "qcom,streaming-func", i, &name);
+ if (!name)
+ continue;
+
+ if (sizeof(name) > FUNC_NAME_LEN) {
+ pr_err("Function name is bigger than allowed.\n");
+ continue;
+ }
+
+ strlcpy(pdata->streaming_func[i], name,
+ sizeof(pdata->streaming_func[i]));
+ pr_debug("name of streaming function:%s\n",
+ pdata->streaming_func[i]);
+ }
+
+ pdata->streaming_func_count = len;
} else {
pdata = pdev->dev.platform_data;
}
diff --git a/drivers/usb/gadget/ci13xxx_msm.c b/drivers/usb/gadget/ci13xxx_msm.c
index a9c073b..f1e4220 100644
--- a/drivers/usb/gadget/ci13xxx_msm.c
+++ b/drivers/usb/gadget/ci13xxx_msm.c
@@ -271,6 +271,10 @@
1 << (pdata->log2_itc-1);
is_l1_supported = pdata->l1_supported;
+ /* Set ahb2ahb bypass flag if it is requested. */
+ if (pdata->enable_ahb2ahb_bypass)
+ ci13xxx_msm_udc_driver.flags |=
+ CI13XXX_ENABLE_AHB2AHB_BYPASS;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c
index 3f8d924..6a92684 100644
--- a/drivers/usb/gadget/ci13xxx_udc.c
+++ b/drivers/usb/gadget/ci13xxx_udc.c
@@ -70,10 +70,6 @@
#include <mach/usb_trace.h>
#include "ci13xxx_udc.h"
-/* Turns on streaming. overrides CI13XXX_DISABLE_STREAMING */
-static unsigned int streaming;
-module_param(streaming, uint, S_IRUGO | S_IWUSR);
-
/******************************************************************************
* DEFINE
*****************************************************************************/
@@ -392,20 +388,32 @@
static int hw_device_state(u32 dma)
{
struct ci13xxx *udc = _udc;
+ struct usb_gadget *gadget = &udc->gadget;
if (dma) {
- if (streaming || !(udc->udc_driver->flags &
- CI13XXX_DISABLE_STREAMING))
+ if (gadget->streaming_enabled || !(udc->udc_driver->flags &
+ CI13XXX_DISABLE_STREAMING)) {
hw_cwrite(CAP_USBMODE, USBMODE_SDIS, 0);
- else
+ pr_debug("%s(): streaming mode is enabled. USBMODE:%x\n",
+ __func__, hw_cread(CAP_USBMODE, ~0));
+ } else {
hw_cwrite(CAP_USBMODE, USBMODE_SDIS, USBMODE_SDIS);
-
+ pr_debug("%s(): streaming mode is disabled. USBMODE:%x\n",
+ __func__, hw_cread(CAP_USBMODE, ~0));
+ }
hw_cwrite(CAP_ENDPTLISTADDR, ~0, dma);
if (udc->udc_driver->notify_event)
udc->udc_driver->notify_event(udc,
CI13XXX_CONTROLLER_CONNECT_EVENT);
+ /* Set BIT(31) to enable AHB2AHB Bypass functionality */
+ if (udc->udc_driver->flags & CI13XXX_ENABLE_AHB2AHB_BYPASS) {
+ hw_awrite(ABS_AHBMODE, AHB2AHB_BYPASS, AHB2AHB_BYPASS);
+ pr_debug("%s(): ByPass Mode is enabled. AHBMODE:%x\n",
+ __func__, hw_aread(ABS_AHBMODE, ~0));
+ }
+
/* interrupt, error, port change, reset, sleep/suspend */
hw_cwrite(CAP_USBINTR, ~0,
USBi_UI|USBi_UEI|USBi_PCI|USBi_URI|USBi_SLI);
@@ -413,6 +421,12 @@
} else {
hw_cwrite(CAP_USBCMD, USBCMD_RS, 0);
hw_cwrite(CAP_USBINTR, ~0, 0);
+ /* Clear BIT(31) to disable AHB2AHB Bypass functionality */
+ if (udc->udc_driver->flags & CI13XXX_ENABLE_AHB2AHB_BYPASS) {
+ hw_awrite(ABS_AHBMODE, AHB2AHB_BYPASS, 0);
+ pr_debug("%s(): ByPass Mode is disabled. AHBMODE:%x\n",
+ __func__, hw_aread(ABS_AHBMODE, ~0));
+ }
}
return 0;
}
diff --git a/drivers/usb/gadget/ci13xxx_udc.h b/drivers/usb/gadget/ci13xxx_udc.h
index f90ea86..47fe138 100644
--- a/drivers/usb/gadget/ci13xxx_udc.h
+++ b/drivers/usb/gadget/ci13xxx_udc.h
@@ -136,6 +136,7 @@
#define CI13XXX_DISABLE_STREAMING BIT(3)
#define CI13XXX_ZERO_ITC BIT(4)
#define CI13XXX_IS_OTG BIT(5)
+#define CI13XXX_ENABLE_AHB2AHB_BYPASS BIT(6)
#define CI13XXX_CONTROLLER_RESET_EVENT 0
#define CI13XXX_CONTROLLER_CONNECT_EVENT 1
@@ -197,6 +198,9 @@
/* TESTMODE */
#define TESTMODE_FORCE BIT(0)
+/* AHB_MODE */
+#define AHB2AHB_BYPASS BIT(31)
+
/* USBCMD */
#define USBCMD_RS BIT(0)
#define USBCMD_RST BIT(1)
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 276bbb0..45fbfa8 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -470,6 +470,20 @@
int ret;
struct msm_otg_platform_data *pdata = motg->pdata;
+ /*
+ * AHB2AHB Bypass mode shouldn't be enable before doing
+ * async clock reset. If it is enable, disable the same.
+ */
+ val = readl_relaxed(USB_AHBMODE);
+ if (val & AHB2AHB_BYPASS) {
+ pr_err("%s(): AHB2AHB_BYPASS SET: AHBMODE:%x\n",
+ __func__, val);
+ val &= ~AHB2AHB_BYPASS_BIT_MASK;
+ writel_relaxed(val | AHB2AHB_BYPASS_CLEAR, USB_AHBMODE);
+ pr_err("%s(): AHBMODE: %x\n", __func__,
+ readl_relaxed(USB_AHBMODE));
+ }
+
ret = msm_otg_link_clk_reset(motg, 1);
if (ret)
return ret;
@@ -1275,7 +1289,8 @@
else if (motg->chg_type == USB_CDP_CHARGER)
charger_type = POWER_SUPPLY_TYPE_USB_CDP;
else if (motg->chg_type == USB_DCP_CHARGER ||
- motg->chg_type == USB_PROPRIETARY_CHARGER)
+ motg->chg_type == USB_PROPRIETARY_CHARGER ||
+ motg->chg_type == USB_FLOATED_CHARGER)
charger_type = POWER_SUPPLY_TYPE_USB_DCP;
else if ((motg->chg_type == USB_ACA_DOCK_CHARGER ||
motg->chg_type == USB_ACA_A_CHARGER ||
@@ -3834,6 +3849,8 @@
ci_pdata.log2_itc = otg_pdata->log2_itc;
ci_pdata.usb_core_id = 0;
ci_pdata.l1_supported = otg_pdata->l1_supported;
+ ci_pdata.enable_ahb2ahb_bypass =
+ otg_pdata->enable_ahb2ahb_bypass;
retval = platform_device_add_data(pdev, &ci_pdata,
sizeof(ci_pdata));
if (retval)
@@ -4164,6 +4181,8 @@
pdata->l1_supported = of_property_read_bool(node,
"qcom,hsusb-l1-supported");
+ pdata->enable_ahb2ahb_bypass = of_property_read_bool(node,
+ "qcom,ahb-async-bridge-bypass");
return pdata;
}
diff --git a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c
index 5c3960d..31e93a5 100644
--- a/drivers/video/fbcmap.c
+++ b/drivers/video/fbcmap.c
@@ -166,6 +166,9 @@
int tooff = 0, fromoff = 0;
int size;
+ if (!to || !from)
+ return -EINVAL;
+
if (to->start > from->start)
fromoff = to->start - from->start;
else
@@ -177,9 +180,12 @@
return -EINVAL;
size *= sizeof(u16);
- memcpy(to->red+tooff, from->red+fromoff, size);
- memcpy(to->green+tooff, from->green+fromoff, size);
- memcpy(to->blue+tooff, from->blue+fromoff, size);
+ if (from->red && to->red)
+ memcpy(to->red+tooff, from->red+fromoff, size);
+ if (from->green && to->green)
+ memcpy(to->green+tooff, from->green+fromoff, size);
+ if (from->blue && to->blue)
+ memcpy(to->blue+tooff, from->blue+fromoff, size);
if (from->transp && to->transp)
memcpy(to->transp+tooff, from->transp+fromoff, size);
return 0;
@@ -190,6 +196,9 @@
int tooff = 0, fromoff = 0;
int size;
+ if (!to || !from)
+ return -EINVAL;
+
if (to->start > from->start)
fromoff = to->start - from->start;
else
@@ -201,12 +210,15 @@
return -EINVAL;
size *= sizeof(u16);
- if (copy_to_user(to->red+tooff, from->red+fromoff, size))
- return -EFAULT;
- if (copy_to_user(to->green+tooff, from->green+fromoff, size))
- return -EFAULT;
- if (copy_to_user(to->blue+tooff, from->blue+fromoff, size))
- return -EFAULT;
+ if (from->red && to->red)
+ if (copy_to_user(to->red+tooff, from->red+fromoff, size))
+ return -EFAULT;
+ if (from->green && to->green)
+ if (copy_to_user(to->green+tooff, from->green+fromoff, size))
+ return -EFAULT;
+ if (from->blue && to->blue)
+ if (copy_to_user(to->blue+tooff, from->blue+fromoff, size))
+ return -EFAULT;
if (from->transp && to->transp)
if (copy_to_user(to->transp+tooff, from->transp+fromoff, size))
return -EFAULT;
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index d6a664a..6b84107 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1113,6 +1113,10 @@
if (copy_from_user(&cmap, argp, sizeof(cmap)))
return -EFAULT;
ret = fb_set_user_cmap(&cmap, info);
+ if (ret) {
+ if (info)
+ fb_dealloc_cmap(&info->cmap);
+ }
break;
case FBIOGETCMAP:
if (copy_from_user(&cmap, argp, sizeof(cmap)))
diff --git a/drivers/video/msm/mdss/mdp3_ctrl.c b/drivers/video/msm/mdss/mdp3_ctrl.c
index 994e3e0..b123ccb 100644
--- a/drivers/video/msm/mdss/mdp3_ctrl.c
+++ b/drivers/video/msm/mdss/mdp3_ctrl.c
@@ -509,6 +509,9 @@
panel = mdp3_session->panel;
mutex_lock(&mdp3_session->lock);
+ if (panel && panel->set_backlight)
+ panel->set_backlight(panel, 0);
+
if (!mdp3_session->status) {
pr_debug("fb%d is off already", mfd->index);
goto off_error;
diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c
index 211b540..81473db 100644
--- a/drivers/video/msm/mdss/mdss_fb.c
+++ b/drivers/video/msm/mdss/mdss_fb.c
@@ -98,8 +98,10 @@
void mdss_fb_no_update_notify_timer_cb(unsigned long data)
{
struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)data;
- if (!mfd)
+ if (!mfd) {
pr_err("%s mfd NULL\n", __func__);
+ return;
+ }
mfd->no_update.value = NOTIFY_TYPE_NO_UPDATE;
complete(&mfd->no_update.comp);
}
@@ -107,9 +109,10 @@
static int mdss_fb_notify_update(struct msm_fb_data_type *mfd,
unsigned long *argp)
{
- int ret, notify, to_user;
+ int ret;
+ unsigned long notify = 0x0, to_user = 0x0;
- ret = copy_from_user(¬ify, argp, sizeof(int));
+ ret = copy_from_user(¬ify, argp, sizeof(unsigned long));
if (ret) {
pr_err("%s:ioctl failed\n", __func__);
return ret;
@@ -122,12 +125,12 @@
INIT_COMPLETION(mfd->update.comp);
ret = wait_for_completion_interruptible_timeout(
&mfd->update.comp, 4 * HZ);
- to_user = mfd->update.value;
+ to_user = (unsigned int)mfd->update.value;
} else if (notify == NOTIFY_UPDATE_STOP) {
INIT_COMPLETION(mfd->no_update.comp);
ret = wait_for_completion_interruptible_timeout(
&mfd->no_update.comp, 4 * HZ);
- to_user = mfd->no_update.value;
+ to_user = (unsigned int)mfd->no_update.value;
} else {
if (mfd->panel_power_on) {
INIT_COMPLETION(mfd->power_off_comp);
@@ -139,7 +142,7 @@
if (ret == 0)
ret = -ETIMEDOUT;
else if (ret > 0)
- ret = copy_to_user(argp, &to_user, sizeof(int));
+ ret = copy_to_user(argp, &to_user, sizeof(unsigned long));
return ret;
}
@@ -1412,7 +1415,7 @@
u32 wait_for_finish = disp_commit->wait_for_finish;
int ret = 0;
- if ((!mfd->op_enable) || (!mfd->panel_power_on))
+ if (!mfd || (!mfd->op_enable) || (!mfd->panel_power_on))
return -EPERM;
if (var->xoffset > (info->var.xres_virtual - info->var.xres))
diff --git a/drivers/video/msm/mdss/mdss_mdp.h b/drivers/video/msm/mdss/mdss_mdp.h
index c1a4a63..d140ea0 100644
--- a/drivers/video/msm/mdss/mdss_mdp.h
+++ b/drivers/video/msm/mdss/mdss_mdp.h
@@ -37,7 +37,6 @@
#define MAX_IMG_HEIGHT 0x3FFF
#define MAX_DST_W MAX_MIXER_WIDTH
#define MAX_DST_H MAX_MIXER_HEIGHT
-#define MAX_PLANES 4
#define MAX_DOWNSCALE_RATIO 4
#define MAX_UPSCALE_RATIO 20
#define MAX_DECIMATION 4
@@ -52,6 +51,11 @@
/* wait for at most 2 vsync for lowest refresh rate (24hz) */
#define KOFF_TIMEOUT msecs_to_jiffies(84)
+#define OVERFETCH_DISABLE_TOP BIT(0)
+#define OVERFETCH_DISABLE_BOTTOM BIT(1)
+#define OVERFETCH_DISABLE_LEFT BIT(2)
+#define OVERFETCH_DISABLE_RIGHT BIT(3)
+
#ifdef MDSS_MDP_DEBUG_REG
static inline void mdss_mdp_reg_write(u32 addr, u32 val)
{
@@ -341,9 +345,6 @@
u8 vert_deci;
struct mdss_mdp_img_rect src;
struct mdss_mdp_img_rect dst;
- u32 phase_step_x;
- u32 phase_step_y;
-
struct mdss_mdp_format_params *src_fmt;
struct mdss_mdp_plane_sizes src_planes;
@@ -370,6 +371,9 @@
struct mdp_overlay_pp_params pp_cfg;
struct mdss_pipe_pp_res pp_res;
+ struct mdp_scale_data scale;
+ u8 chroma_sample_h;
+ u8 chroma_sample_v;
};
struct mdss_mdp_writeback_arg {
@@ -632,6 +636,7 @@
int mdss_mdp_wb_set_secure(struct msm_fb_data_type *mfd, int enable);
int mdss_mdp_wb_get_secure(struct msm_fb_data_type *mfd, uint8_t *enable);
+int mdss_mdp_pipe_program_pixel_extn(struct mdss_mdp_pipe *pipe);
#define mfd_to_mdp5_data(mfd) (mfd->mdp.private1)
#define mfd_to_mdata(mfd) (((struct mdss_overlay_private *)\
(mfd->mdp.private1))->mdata)
diff --git a/drivers/video/msm/mdss/mdss_mdp_hwio.h b/drivers/video/msm/mdss/mdss_mdp_hwio.h
index c8af903..52ca42c 100644
--- a/drivers/video/msm/mdss/mdss_mdp_hwio.h
+++ b/drivers/video/msm/mdss/mdss_mdp_hwio.h
@@ -201,6 +201,9 @@
#define MDSS_MDP_REG_SSPP_CURRENT_SRC2_ADDR 0x0AC
#define MDSS_MDP_REG_SSPP_CURRENT_SRC3_ADDR 0x0B0
#define MDSS_MDP_REG_SSPP_DECIMATION_CONFIG 0x0B4
+#define MDSS_MDP_REG_SSPP_SW_PIX_EXT_C0_LR 0x100
+#define MDSS_MDP_REG_SSPP_SW_PIX_EXT_C0_TB 0x104
+#define MDSS_MDP_REG_SSPP_SW_PIX_EXT_C0_REQ_PIXELS 0x108
#define MDSS_MDP_REG_VIG_OP_MODE 0x200
#define MDSS_MDP_REG_VIG_QSEED2_CONFIG 0x204
diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
index 4726ca9..0fb01ad 100644
--- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
+++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c
@@ -282,7 +282,12 @@
int rc;
src = pipe->src.w >> pipe->horz_deci;
- rc = mdss_mdp_calc_phase_step(src, pipe->dst.w, &pipe->phase_step_x);
+
+ if (pipe->scale.enable_pxl_ext)
+ return 0;
+ memset(&pipe->scale, 0, sizeof(struct mdp_scale_data));
+ rc = mdss_mdp_calc_phase_step(src, pipe->dst.w,
+ &pipe->scale.phase_step_x[0]);
if (rc) {
pr_err("Horizontal scaling calculation failed=%d! %d->%d\n",
rc, src, pipe->dst.w);
@@ -290,16 +295,43 @@
}
src = pipe->src.h >> pipe->vert_deci;
- rc = mdss_mdp_calc_phase_step(src, pipe->dst.h, &pipe->phase_step_y);
+ rc = mdss_mdp_calc_phase_step(src, pipe->dst.h,
+ &pipe->scale.phase_step_y[0]);
if (rc) {
pr_err("Vertical scaling calculation failed=%d! %d->%d\n",
rc, src, pipe->dst.h);
return rc;
}
-
+ pipe->scale.init_phase_x[0] = (pipe->scale.phase_step_x[0] -
+ (1 << PHASE_STEP_SHIFT)) / 2;
+ pipe->scale.init_phase_y[0] = (pipe->scale.phase_step_y[0] -
+ (1 << PHASE_STEP_SHIFT)) / 2;
return 0;
}
+static inline void __mdss_mdp_overlay_set_chroma_sample(
+ struct mdss_mdp_pipe *pipe)
+{
+ pipe->chroma_sample_v = pipe->chroma_sample_h = 0;
+
+ switch (pipe->src_fmt->chroma_sample) {
+ case MDSS_MDP_CHROMA_H1V2:
+ pipe->chroma_sample_v = 1;
+ break;
+ case MDSS_MDP_CHROMA_H2V1:
+ pipe->chroma_sample_h = 1;
+ break;
+ case MDSS_MDP_CHROMA_420:
+ pipe->chroma_sample_v = 1;
+ pipe->chroma_sample_h = 1;
+ break;
+ }
+ if (pipe->horz_deci)
+ pipe->chroma_sample_h = 0;
+ if (pipe->vert_deci)
+ pipe->chroma_sample_v = 0;
+}
+
static int mdss_mdp_overlay_pipe_setup(struct msm_fb_data_type *mfd,
struct mdp_overlay *req,
struct mdss_mdp_pipe **ppipe)
@@ -442,7 +474,10 @@
pipe->dst.h = req->dst_rect.h;
pipe->horz_deci = req->horz_deci;
pipe->vert_deci = req->vert_deci;
+
+ memcpy(&pipe->scale, &req->scale, sizeof(struct mdp_scale_data));
pipe->src_fmt = fmt;
+ __mdss_mdp_overlay_set_chroma_sample(pipe);
pipe->mixer_stage = req->z_order;
pipe->is_fg = req->is_fg;
@@ -458,8 +493,17 @@
pr_debug("Unintended blend_op %d on layer with no alpha plane\n",
pipe->blend_op);
- pipe->overfetch_disable = fmt->is_yuv &&
- !(pipe->flags & MDP_SOURCE_ROTATED_90);
+ if (fmt->is_yuv && !(pipe->flags & MDP_SOURCE_ROTATED_90) &&
+ !pipe->scale.enable_pxl_ext) {
+ pipe->overfetch_disable = OVERFETCH_DISABLE_BOTTOM;
+
+ if (!(pipe->flags & MDSS_MDP_DUAL_PIPE) ||
+ (pipe->flags & MDSS_MDP_RIGHT_MIXER))
+ pipe->overfetch_disable |= OVERFETCH_DISABLE_RIGHT;
+ pr_debug("overfetch flags=%x\n", pipe->overfetch_disable);
+ } else {
+ pipe->overfetch_disable = 0;
+ }
req->id = pipe->ndx;
pipe->req_data = *req;
@@ -516,7 +560,7 @@
}
}
- if (pipe->flags & MDP_DEINTERLACE) {
+ if ((pipe->flags & MDP_DEINTERLACE) && !pipe->scale.enable_pxl_ext) {
if (pipe->flags & MDP_SOURCE_ROTATED_90) {
pipe->src.w /= 2;
pipe->img_width /= 2;
@@ -539,6 +583,12 @@
!mdp5_data->mdata->has_wfd_blk)
mdss_mdp_smp_release(pipe);
+ /*
+ * Clear previous SMP reservations and reserve according to the
+ * latest configuration
+ */
+ mdss_mdp_smp_unreserve(pipe);
+
ret = mdss_mdp_smp_reserve(pipe);
if (ret) {
pr_debug("mdss_mdp_smp_reserve failed. ret=%d\n", ret);
@@ -2122,7 +2172,7 @@
u32 cmd, void __user *argp)
{
struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);
- struct mdp_overlay req;
+ struct mdp_overlay *req = NULL;
int val, ret = -ENOSYS;
struct msmfb_metadata metadata;
@@ -2138,12 +2188,15 @@
break;
case MSMFB_OVERLAY_GET:
- ret = copy_from_user(&req, argp, sizeof(req));
+ req = kmalloc(sizeof(struct mdp_overlay), GFP_KERNEL);
+ if (!req)
+ return -ENOMEM;
+ ret = copy_from_user(req, argp, sizeof(*req));
if (!ret) {
- ret = mdss_mdp_overlay_get(mfd, &req);
+ ret = mdss_mdp_overlay_get(mfd, req);
if (!IS_ERR_VALUE(ret))
- ret = copy_to_user(argp, &req, sizeof(req));
+ ret = copy_to_user(argp, req, sizeof(*req));
}
if (ret)
@@ -2151,12 +2204,15 @@
break;
case MSMFB_OVERLAY_SET:
- ret = copy_from_user(&req, argp, sizeof(req));
+ req = kmalloc(sizeof(struct mdp_overlay), GFP_KERNEL);
+ if (!req)
+ return -ENOMEM;
+ ret = copy_from_user(req, argp, sizeof(*req));
if (!ret) {
- ret = mdss_mdp_overlay_set(mfd, &req);
+ ret = mdss_mdp_overlay_set(mfd, req);
if (!IS_ERR_VALUE(ret))
- ret = copy_to_user(argp, &req, sizeof(req));
+ ret = copy_to_user(argp, req, sizeof(*req));
}
if (ret)
pr_debug("OVERLAY_SET failed (%d)\n", ret);
@@ -2241,6 +2297,7 @@
break;
}
+ kfree(req);
return ret;
}
diff --git a/drivers/video/msm/mdss/mdss_mdp_pipe.c b/drivers/video/msm/mdss/mdss_mdp_pipe.c
index 72c8759..25cb9dd 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pipe.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pipe.c
@@ -581,6 +581,8 @@
mdss_mdp_smp_free(pipe);
pipe->flags = 0;
pipe->bwc_mode = 0;
+ memset(&pipe->scale, 0, sizeof(struct mdp_scale_data));
+
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
return 0;
@@ -736,17 +738,35 @@
dst_size = (dst.h << 16) | dst.w;
dst_xy = (dst.y << 16) | dst.x;
- img_size = (height << 16) | width;
-
ystride0 = (pipe->src_planes.ystride[0]) |
(pipe->src_planes.ystride[1] << 16);
ystride1 = (pipe->src_planes.ystride[2]) |
(pipe->src_planes.ystride[3] << 16);
- if (pipe->overfetch_disable) {
- img_size = src_size;
- src_xy = 0;
+ /*
+ * Software overfetch is used when scalar pixel extension is
+ * not enabled
+ */
+ if (pipe->overfetch_disable && !pipe->scale.enable_pxl_ext) {
+ if (pipe->overfetch_disable & OVERFETCH_DISABLE_BOTTOM) {
+ height = pipe->src.h;
+ if (!(pipe->overfetch_disable & OVERFETCH_DISABLE_TOP))
+ height += pipe->src.y;
+ }
+ if (pipe->overfetch_disable & OVERFETCH_DISABLE_RIGHT) {
+ width = pipe->src.w;
+ if (!(pipe->overfetch_disable & OVERFETCH_DISABLE_LEFT))
+ width += pipe->src.x;
+ }
+ if (pipe->overfetch_disable & OVERFETCH_DISABLE_LEFT)
+ src_xy &= ~0xFFFF;
+ if (pipe->overfetch_disable & OVERFETCH_DISABLE_TOP)
+ src_xy &= ~(0xFFFF << 16);
+
+ pr_debug("overfetch w=%d/%d h=%d/%d src_xy=0x%08x\n", width,
+ pipe->img_width, height, pipe->img_height, src_xy);
}
+ img_size = (height << 16) | width;
mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_SRC_IMG_SIZE, img_size);
mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_SRC_SIZE, src_size);
@@ -813,6 +833,9 @@
mdss_mdp_pipe_sspp_setup(pipe, &opmode);
+ if (pipe->scale.enable_pxl_ext)
+ opmode |= (1 << 31);
+
mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_SRC_FORMAT, src_format);
mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_SRC_UNPACK_PATTERN, unpack);
mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_SRC_OP_MODE, opmode);
@@ -844,33 +867,42 @@
}
static int mdss_mdp_src_addr_setup(struct mdss_mdp_pipe *pipe,
- struct mdss_mdp_data *data)
+ struct mdss_mdp_data *src_data)
{
struct mdss_data_type *mdata = mdss_mdp_get_mdata();
+ struct mdss_mdp_data data = *src_data;
int ret = 0;
pr_debug("pnum=%d\n", pipe->num);
- data->bwc_enabled = pipe->bwc_mode;
+ data.bwc_enabled = pipe->bwc_mode;
- ret = mdss_mdp_data_check(data, &pipe->src_planes);
+ ret = mdss_mdp_data_check(&data, &pipe->src_planes);
if (ret)
return ret;
- if (pipe->overfetch_disable)
- mdss_mdp_data_calc_offset(data, pipe->src.x, pipe->src.y,
+ if (pipe->overfetch_disable && !pipe->scale.enable_pxl_ext) {
+ u32 x = 0, y = 0;
+
+ if (pipe->overfetch_disable & OVERFETCH_DISABLE_LEFT)
+ x = pipe->src.x;
+ if (pipe->overfetch_disable & OVERFETCH_DISABLE_TOP)
+ y = pipe->src.y;
+
+ mdss_mdp_data_calc_offset(&data, x, y,
&pipe->src_planes, pipe->src_fmt);
+ }
/* planar format expects YCbCr, swap chroma planes if YCrCb */
if (mdata->mdp_rev < MDSS_MDP_HW_REV_102 &&
(pipe->src_fmt->fetch_planes == MDSS_MDP_PLANE_PLANAR)
&& (pipe->src_fmt->element[0] == C1_B_Cb))
- swap(data->p[1].addr, data->p[2].addr);
+ swap(data.p[1].addr, data.p[2].addr);
- mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_SRC0_ADDR, data->p[0].addr);
- mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_SRC1_ADDR, data->p[1].addr);
- mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_SRC2_ADDR, data->p[2].addr);
- mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_SRC3_ADDR, data->p[3].addr);
+ mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_SRC0_ADDR, data.p[0].addr);
+ mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_SRC1_ADDR, data.p[1].addr);
+ mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_SRC2_ADDR, data.p[2].addr);
+ mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_SRC3_ADDR, data.p[3].addr);
return 0;
}
@@ -901,8 +933,9 @@
struct mdss_mdp_data *src_data)
{
int ret = 0;
- u32 params_changed, opmode;
struct mdss_mdp_ctl *ctl;
+ u32 params_changed;
+ u32 opmode = 0;
if (!pipe) {
pr_err("pipe not setup properly for queue\n");
@@ -983,3 +1016,53 @@
{
return (pipe == pipe->mixer->stage_pipe[pipe->mixer_stage]);
}
+
+static inline void __mdss_mdp_pipe_program_pixel_extn_helper(
+ struct mdss_mdp_pipe *pipe, u32 plane, u32 off)
+{
+ u32 src_h = pipe->src.h >> pipe->vert_deci;
+ u32 mask = 0xFF;
+
+ /*
+ * CB CR plane required pxls need to be accounted
+ * for chroma decimation.
+ */
+ if (plane == 1)
+ src_h >>= pipe->chroma_sample_v;
+ writel_relaxed(((pipe->scale.right_ftch[plane] & mask) << 24)|
+ ((pipe->scale.right_rpt[plane] & mask) << 16)|
+ ((pipe->scale.left_ftch[plane] & mask) << 8)|
+ (pipe->scale.left_rpt[plane] & mask), pipe->base +
+ MDSS_MDP_REG_SSPP_SW_PIX_EXT_C0_LR + off);
+ writel_relaxed(((pipe->scale.btm_ftch[plane] & mask) << 24)|
+ ((pipe->scale.btm_rpt[plane] & mask) << 16)|
+ ((pipe->scale.top_ftch[plane] & mask) << 8)|
+ (pipe->scale.top_rpt[plane] & mask), pipe->base +
+ MDSS_MDP_REG_SSPP_SW_PIX_EXT_C0_TB + off);
+ mask = 0xFFFF;
+ writel_relaxed((((src_h + pipe->scale.num_ext_pxls_top[plane] +
+ pipe->scale.num_ext_pxls_btm[plane]) & mask) << 16) |
+ ((pipe->scale.roi_w[plane] +
+ pipe->scale.num_ext_pxls_left[plane] +
+ pipe->scale.num_ext_pxls_right[plane]) & mask), pipe->base +
+ MDSS_MDP_REG_SSPP_SW_PIX_EXT_C0_REQ_PIXELS + off);
+}
+
+/**
+ * mdss_mdp_pipe_program_pixel_extn - Program the source pipe's
+ * sw pixel extension
+ * @pipe: Source pipe struct containing pixel extn values
+ *
+ * Function programs the pixel extn values calculated during
+ * scale setup.
+ */
+int mdss_mdp_pipe_program_pixel_extn(struct mdss_mdp_pipe *pipe)
+{
+ /* Y plane pixel extn */
+ __mdss_mdp_pipe_program_pixel_extn_helper(pipe, 0, 0);
+ /* CB CR plane pixel extn */
+ __mdss_mdp_pipe_program_pixel_extn_helper(pipe, 1, 16);
+ /* Alpha plane pixel extn */
+ __mdss_mdp_pipe_program_pixel_extn_helper(pipe, 3, 32);
+ return 0;
+}
diff --git a/drivers/video/msm/mdss/mdss_mdp_pp.c b/drivers/video/msm/mdss/mdss_mdp_pp.c
index b31f6c1..dc7b8b3 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pp.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pp.c
@@ -629,7 +629,7 @@
}
}
- *op = opmode;
+ *op |= opmode;
return 0;
}
@@ -637,12 +637,15 @@
static int mdss_mdp_scale_setup(struct mdss_mdp_pipe *pipe)
{
u32 scale_config = 0;
- u32 phasex_step = 0, phasey_step = 0;
+ int init_phasex = 0, init_phasey = 0;
+ int phasex_step = 0, phasey_step = 0;
u32 chroma_sample;
u32 filter_mode;
struct mdss_data_type *mdata;
u32 src_w, src_h;
+ pr_debug("pipe=%d, change pxl ext=%d\n", pipe->num,
+ pipe->scale.enable_pxl_ext);
mdata = mdss_mdp_get_mdata();
if (mdata->mdp_rev >= MDSS_MDP_HW_REV_102 && pipe->src_fmt->is_yuv)
filter_mode = MDSS_MDP_SCALE_FILTER_CA;
@@ -689,7 +692,8 @@
if ((src_h != pipe->dst.h) ||
(pipe->pp_res.pp_sts.sharp_sts & PP_STS_ENABLE) ||
(chroma_sample == MDSS_MDP_CHROMA_420) ||
- (chroma_sample == MDSS_MDP_CHROMA_H1V2)) {
+ (chroma_sample == MDSS_MDP_CHROMA_H1V2) ||
+ pipe->scale.enable_pxl_ext) {
pr_debug("scale y - src_h=%d dst_h=%d\n", src_h, pipe->dst.h);
if ((src_h / MAX_DOWNSCALE_RATIO) > pipe->dst.h) {
@@ -699,7 +703,8 @@
}
scale_config |= MDSS_MDP_SCALEY_EN;
- phasey_step = pipe->phase_step_y;
+ phasey_step = pipe->scale.phase_step_y[0];
+ init_phasey = pipe->scale.init_phase_y[0];
if (pipe->type == MDSS_MDP_PIPE_TYPE_VIG) {
u32 chroma_shift = 0;
@@ -708,11 +713,11 @@
(chroma_sample == MDSS_MDP_CHROMA_H1V2)))
chroma_shift = 1; /* 2x upsample chroma */
- if (src_h <= pipe->dst.h) {
+ if (src_h <= pipe->dst.h)
scale_config |= /* G/Y, A */
(filter_mode << 10) |
(MDSS_MDP_SCALE_FILTER_BIL << 18);
- } else
+ else
scale_config |= /* G/Y, A */
(MDSS_MDP_SCALE_FILTER_PCMN << 10) |
(MDSS_MDP_SCALE_FILTER_PCMN << 18);
@@ -724,6 +729,8 @@
scale_config |= /* CrCb */
(MDSS_MDP_SCALE_FILTER_PCMN << 14);
+ writel_relaxed(init_phasey, pipe->base +
+ MDSS_MDP_REG_VIG_QSEED2_C12_INIT_PHASEY);
writel_relaxed(phasey_step >> chroma_shift, pipe->base +
MDSS_MDP_REG_VIG_QSEED2_C12_PHASESTEPY);
} else {
@@ -741,7 +748,8 @@
if ((src_w != pipe->dst.w) ||
(pipe->pp_res.pp_sts.sharp_sts & PP_STS_ENABLE) ||
(chroma_sample == MDSS_MDP_CHROMA_420) ||
- (chroma_sample == MDSS_MDP_CHROMA_H2V1)) {
+ (chroma_sample == MDSS_MDP_CHROMA_H2V1) ||
+ pipe->scale.enable_pxl_ext) {
pr_debug("scale x - src_w=%d dst_w=%d\n", src_w, pipe->dst.w);
if ((src_w / MAX_DOWNSCALE_RATIO) > pipe->dst.w) {
@@ -751,7 +759,8 @@
}
scale_config |= MDSS_MDP_SCALEX_EN;
- phasex_step = pipe->phase_step_x;
+ init_phasex = pipe->scale.init_phase_x[0];
+ phasex_step = pipe->scale.phase_step_x[0];
if (pipe->type == MDSS_MDP_PIPE_TYPE_VIG) {
u32 chroma_shift = 0;
@@ -761,11 +770,11 @@
(chroma_sample == MDSS_MDP_CHROMA_H2V1)))
chroma_shift = 1; /* 2x upsample chroma */
- if (src_w <= pipe->dst.w) {
+ if (src_w <= pipe->dst.w)
scale_config |= /* G/Y, A */
(filter_mode << 8) |
(MDSS_MDP_SCALE_FILTER_BIL << 16);
- } else
+ else
scale_config |= /* G/Y, A */
(MDSS_MDP_SCALE_FILTER_PCMN << 8) |
(MDSS_MDP_SCALE_FILTER_PCMN << 16);
@@ -777,6 +786,8 @@
scale_config |= /* CrCb */
(MDSS_MDP_SCALE_FILTER_PCMN << 12);
+ writel_relaxed(init_phasex, pipe->base +
+ MDSS_MDP_REG_VIG_QSEED2_C12_INIT_PHASEX);
writel_relaxed(phasex_step >> chroma_shift, pipe->base +
MDSS_MDP_REG_VIG_QSEED2_C12_PHASESTEPX);
} else {
@@ -791,12 +802,44 @@
}
}
+ if (pipe->scale.enable_pxl_ext &&
+ pipe->type == MDSS_MDP_PIPE_TYPE_VIG) {
+
+ /*program x,y initial phase and phase step*/
+ writel_relaxed(pipe->scale.init_phase_x[0],
+ pipe->base + MDSS_MDP_REG_VIG_QSEED2_C03_INIT_PHASEX);
+ writel_relaxed(pipe->scale.phase_step_x[0],
+ pipe->base + MDSS_MDP_REG_VIG_QSEED2_C03_PHASESTEPX);
+ writel_relaxed(pipe->scale.init_phase_x[1],
+ pipe->base + MDSS_MDP_REG_VIG_QSEED2_C12_INIT_PHASEX);
+ writel_relaxed(pipe->scale.phase_step_x[1],
+ pipe->base + MDSS_MDP_REG_VIG_QSEED2_C12_PHASESTEPX);
+
+ writel_relaxed(pipe->scale.init_phase_y[0],
+ pipe->base + MDSS_MDP_REG_VIG_QSEED2_C03_INIT_PHASEY);
+ writel_relaxed(pipe->scale.phase_step_y[0],
+ pipe->base + MDSS_MDP_REG_VIG_QSEED2_C03_PHASESTEPY);
+ writel_relaxed(pipe->scale.init_phase_y[1],
+ pipe->base + MDSS_MDP_REG_VIG_QSEED2_C12_INIT_PHASEY);
+ writel_relaxed(pipe->scale.phase_step_y[1],
+ pipe->base + MDSS_MDP_REG_VIG_QSEED2_C12_PHASESTEPY);
+
+ /*program pixel extn values for the SSPP*/
+ mdss_mdp_pipe_program_pixel_extn(pipe);
+ } else {
+ writel_relaxed(phasex_step, pipe->base +
+ MDSS_MDP_REG_SCALE_PHASE_STEP_X);
+ writel_relaxed(phasey_step, pipe->base +
+ MDSS_MDP_REG_SCALE_PHASE_STEP_Y);
+ writel_relaxed(init_phasex, pipe->base +
+ MDSS_MDP_REG_SCALE_INIT_PHASE_X);
+ writel_relaxed(init_phasey, pipe->base +
+ MDSS_MDP_REG_SCALE_INIT_PHASE_Y);
+ }
+
writel_relaxed(scale_config, pipe->base +
MDSS_MDP_REG_SCALE_CONFIG);
- writel_relaxed(phasex_step, pipe->base +
- MDSS_MDP_REG_SCALE_PHASE_STEP_X);
- writel_relaxed(phasey_step, pipe->base +
- MDSS_MDP_REG_SCALE_PHASE_STEP_Y);
+
return 0;
}
diff --git a/drivers/video/msm/mdss/mdss_mdp_util.c b/drivers/video/msm/mdss/mdss_mdp_util.c
index 1170d1e..b680823 100644
--- a/drivers/video/msm/mdss/mdss_mdp_util.c
+++ b/drivers/video/msm/mdss/mdss_mdp_util.c
@@ -592,7 +592,7 @@
return -EINVAL;
unit = 1 << PHASE_STEP_SHIFT;
- *out_phase = mult_frac(src, unit, dst);
+ *out_phase = mult_frac(unit, src, dst);
/* check if overflow is possible */
if (src > dst) {
diff --git a/drivers/video/msm/mdss/mdss_mdp_wb.c b/drivers/video/msm/mdss/mdss_mdp_wb.c
index 9aefe8a..5789341 100644
--- a/drivers/video/msm/mdss/mdss_mdp_wb.c
+++ b/drivers/video/msm/mdss/mdss_mdp_wb.c
@@ -164,6 +164,16 @@
return -EINVAL;
}
+ if (!ctl || !ctl->mdata) {
+ pr_err("%s : ctl is NULL", __func__);
+ return -EINVAL;
+ }
+
+ if (!wb) {
+ pr_err("unable to start, writeback is not initialized\n");
+ return -ENODEV;
+ }
+
ctl->is_secure = enable;
wb->is_secure = enable;
diff --git a/include/linux/msm_mdp.h b/include/linux/msm_mdp.h
index cd80920..09429df 100644
--- a/include/linux/msm_mdp.h
+++ b/include/linux/msm_mdp.h
@@ -156,6 +156,7 @@
#define MDSS_MDP_ROT_ONLY 0x80
#define MDSS_MDP_RIGHT_MIXER 0x100
+#define MDSS_MDP_DUAL_PIPE 0x200
/* mdp_blit_req flag values */
#define MDP_ROT_NOP 0
@@ -442,6 +443,33 @@
BLEND_OP_MAX,
};
+#define MAX_PLANES 4
+struct mdp_scale_data {
+ uint8_t enable_pxl_ext;
+
+ int init_phase_x[MAX_PLANES];
+ int phase_step_x[MAX_PLANES];
+ int init_phase_y[MAX_PLANES];
+ int phase_step_y[MAX_PLANES];
+
+ int num_ext_pxls_left[MAX_PLANES];
+ int num_ext_pxls_right[MAX_PLANES];
+ int num_ext_pxls_top[MAX_PLANES];
+ int num_ext_pxls_btm[MAX_PLANES];
+
+ int left_ftch[MAX_PLANES];
+ int left_rpt[MAX_PLANES];
+ int right_ftch[MAX_PLANES];
+ int right_rpt[MAX_PLANES];
+
+ int top_rpt[MAX_PLANES];
+ int btm_rpt[MAX_PLANES];
+ int top_ftch[MAX_PLANES];
+ int btm_ftch[MAX_PLANES];
+
+ uint32_t roi_w[MAX_PLANES];
+};
+
struct mdp_overlay {
struct msmfb_img src;
struct mdp_rect src_rect;
@@ -457,6 +485,7 @@
uint8_t horz_deci;
uint8_t vert_deci;
struct mdp_overlay_pp_params overlay_pp_cfg;
+ struct mdp_scale_data scale;
};
struct msmfb_overlay_3d {
diff --git a/include/linux/usb/android.h b/include/linux/usb/android.h
index e17e978..8d5e51b 100644
--- a/include/linux/usb/android.h
+++ b/include/linux/usb/android.h
@@ -19,12 +19,16 @@
#include <linux/usb/composite.h>
+#define MAX_STREAMING_FUNCS 3
+#define FUNC_NAME_LEN 10
struct android_usb_platform_data {
int (*update_pid_and_serial_num)(uint32_t, const char *);
u32 swfi_latency;
u8 usb_core_id;
bool cdrom;
bool internal_ums;
+ char streaming_func[MAX_STREAMING_FUNCS][FUNC_NAME_LEN];
+ int streaming_func_count;
};
#ifndef CONFIG_TARGET_CORE
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index fea832e..3844f41 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -508,6 +508,7 @@
* @dev: Driver model state for this abstract device.
* @usb_core_id: Identifies the usb core controlled by this usb_gadget.
* Used in case of more then one core operates concurrently.
+ * @streaming_enabled: Enable streaming mode with usb core.
*
* Gadgets have a mostly-portable "gadget driver" implementing device
* functions, handling all usb configurations and interfaces. Gadget
@@ -546,6 +547,7 @@
struct device dev;
u8 usb_core_id;
bool l1_supported;
+ bool streaming_enabled;
};
static inline void set_gadget_data(struct usb_gadget *gadget, void *data)
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index 07f9b90..9eb9cd8 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -229,7 +229,9 @@
* between 1 to 7.
* @l1_supported: enable link power management support.
* @dpdm_pulldown_added: Indicates whether pull down resistors are
- connected on data lines or not.
+ * connected on data lines or not.
+ * @enable_ahb2ahb_bypass: Indicates whether enable AHB2AHB BYPASS
+ * mode with controller in device mode.
*/
struct msm_otg_platform_data {
int *phy_init_seq;
@@ -258,6 +260,7 @@
int log2_itc;
bool l1_supported;
bool dpdm_pulldown_added;
+ bool enable_ahb2ahb_bypass;
};
/* phy related flags */
@@ -462,6 +465,7 @@
int log2_itc;
void *prv_data;
bool l1_supported;
+ bool enable_ahb2ahb_bypass;
};
/**
diff --git a/include/linux/usb/msm_hsusb_hw.h b/include/linux/usb/msm_hsusb_hw.h
index 58ab4eb..2a5ebd4 100644
--- a/include/linux/usb/msm_hsusb_hw.h
+++ b/include/linux/usb/msm_hsusb_hw.h
@@ -49,6 +49,10 @@
#define L1_CONFIG_PHY_LPM BIT(10)
#define L1_CONFIG_PLL BIT(11)
+#define AHB2AHB_BYPASS BIT(31)
+#define AHB2AHB_BYPASS_BIT_MASK BIT(31)
+#define AHB2AHB_BYPASS_CLEAR (0 << 31)
+
#define PORTSC_PHCD (1 << 23) /* phy suspend mode */
#define PORTSC_PTS_MASK (3 << 30)
#define PORTSC_PTS_ULPI (3 << 30)
diff --git a/include/sound/apr_audio-v2.h b/include/sound/apr_audio-v2.h
index 3f6c25c..b62a759 100644
--- a/include/sound/apr_audio-v2.h
+++ b/include/sound/apr_audio-v2.h
@@ -3676,6 +3676,7 @@
} __packed;
#define ASM_SESSION_CMD_PAUSE 0x00010BD3
+#define ASM_SESSION_CMD_SUSPEND 0x00010DEC
#define ASM_SESSION_CMD_GET_SESSIONTIME_V3 0x00010D9D
#define ASM_SESSION_CMD_REGISTER_FOR_RX_UNDERFLOW_EVENTS 0x00010BD5
diff --git a/include/sound/q6asm-v2.h b/include/sound/q6asm-v2.h
index 2adec8b..eb3b41a 100644
--- a/include/sound/q6asm-v2.h
+++ b/include/sound/q6asm-v2.h
@@ -54,6 +54,7 @@
#define CMD_EOS 0x0003
#define CMD_CLOSE 0x0004
#define CMD_OUT_FLUSH 0x0005
+#define CMD_SUSPEND 0x0006
/* bit 0:1 represents priority of stream */
#define STREAM_PRIORITY_NORMAL 0x0000
diff --git a/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c
index fb362a1..b626fa4 100755
--- a/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c
@@ -987,7 +987,7 @@
struct snd_dec_ddp *ddp =
&compr->info.codec_param.codec.options.ddp;
uint32_t params_length = ddp->params_length*sizeof(int);
- if(params_length > MAX_AC3_PARAM_SIZE) {
+ if (params_length > MAX_AC3_PARAM_SIZE) {
/*MAX is 36*sizeof(int) this should not happen*/
pr_err("params_length(%d) is greater than %d",
params_length, MAX_AC3_PARAM_SIZE);
@@ -1024,7 +1024,7 @@
struct snd_dec_ddp *ddp =
&compr->info.codec_param.codec.options.ddp;
uint32_t params_length = ddp->params_length*sizeof(int);
- if(params_length > MAX_AC3_PARAM_SIZE) {
+ if (params_length > MAX_AC3_PARAM_SIZE) {
/*MAX is 36*sizeof(int) this should not happen*/
pr_err("params_length(%d) is greater than %d",
params_length, MAX_AC3_PARAM_SIZE);
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c
index d80ca19..0612805 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c
@@ -40,8 +40,8 @@
#define MIN_CAPTURE_PERIOD_SIZE (128 * 2 * 4)
#define MAX_CAPTURE_PERIOD_SIZE (128 * 2 * 2 * 6 * 4)
-#define MIN_CAPTURE_NUM_PERIODS (32)
-#define MAX_CAPTURE_NUM_PERIODS (384)
+#define MIN_CAPTURE_NUM_PERIODS (32 * 4)
+#define MAX_CAPTURE_NUM_PERIODS (384 * 4)
static struct snd_pcm_hardware msm_afe_hardware_playback = {
.info = (SNDRV_PCM_INFO_MMAP |
diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c
index 962fee4..3ae5221 100644
--- a/sound/soc/msm/qdsp6v2/q6asm.c
+++ b/sound/soc/msm/qdsp6v2/q6asm.c
@@ -1230,6 +1230,7 @@
data->payload_size))
break;
case ASM_SESSION_CMD_PAUSE:
+ case ASM_SESSION_CMD_SUSPEND:
case ASM_DATA_CMD_EOS:
case ASM_STREAM_CMD_CLOSE:
case ASM_STREAM_CMD_FLUSH:
@@ -3947,6 +3948,11 @@
hdr.opcode = ASM_SESSION_CMD_PAUSE;
state = &ac->cmd_state;
break;
+ case CMD_SUSPEND:
+ pr_debug("%s:CMD_SUSPEND\n", __func__);
+ hdr.opcode = ASM_SESSION_CMD_SUSPEND;
+ state = &ac->cmd_state;
+ break;
case CMD_FLUSH:
pr_debug("%s:CMD_FLUSH\n", __func__);
hdr.opcode = ASM_STREAM_CMD_FLUSH;