Merge "mdss: mdp3: verify return value from enabling clocks"
diff --git a/arch/arm/boot/dts/dsi-panel-hx8379a-wvga-video.dtsi b/arch/arm/boot/dts/dsi-panel-hx8379a-wvga-video.dtsi
index 645e91b..9d244d8 100644
--- a/arch/arm/boot/dts/dsi-panel-hx8379a-wvga-video.dtsi
+++ b/arch/arm/boot/dts/dsi-panel-hx8379a-wvga-video.dtsi
@@ -26,13 +26,13 @@
qcom,mdss-dsi-stream = <0>;
qcom,mdss-dsi-panel-width = <480>;
qcom,mdss-dsi-panel-height = <800>;
- qcom,mdss-dsi-h-front-porch = <90>;
- qcom,mdss-dsi-h-back-porch = <90>;
- qcom,mdss-dsi-h-pulse-width = <17>;
+ qcom,mdss-dsi-h-front-porch = <70>;
+ qcom,mdss-dsi-h-back-porch = <100>;
+ qcom,mdss-dsi-h-pulse-width = <40>;
qcom,mdss-dsi-h-sync-skew = <0>;
- qcom,mdss-dsi-v-back-porch = <2>;
- qcom,mdss-dsi-v-front-porch = <11>;
- qcom,mdss-dsi-v-pulse-width = <3>;
+ qcom,mdss-dsi-v-back-porch = <6>;
+ qcom,mdss-dsi-v-front-porch = <6>;
+ qcom,mdss-dsi-v-pulse-width = <4>;
qcom,mdss-dsi-h-left-border = <0>;
qcom,mdss-dsi-h-right-border = <0>;
qcom,mdss-dsi-v-top-border = <0>;
@@ -41,17 +41,63 @@
qcom,mdss-dsi-color-order = <0>;
qcom,mdss-dsi-underflow-color = <0xff>;
qcom,mdss-dsi-border-color = <0>;
- qcom,mdss-dsi-on-command = [29 01 00 00 01 00 04 B9 FF 83 79
- 23 01 00 00 01 00 02 BA 51
- 29 01 00 00 01 00 14 B1 00 50 44 EA 8D 08 11 0F 0F 24 2C 9A 1A 42 0B 6E F1 00 E6
- 29 01 00 00 01 00 0e B2 00 00 3C 08 04 19 22 00 FF 08 04 19 20
- 29 01 00 00 01 00 20 B4 80 08 00 32 10 03 32 13 70 32 10 08 37 01 28 05 37 08 3C 20 44 44 08 00 40 08 28 08 30 30 04
- 23 01 00 00 01 00 02 cc 02
- 29 01 00 00 01 00 30 D5 00 00 08 00 01 05 00 03 00 88 88 88 88 23 01 67 45 02 13 88 88 88 88 88 88 88 88 88 88 54 76 10 32 31 20 88 88 88 88 88 88 00 00 00 00 00 00
- 29 01 00 00 01 00 24 E0 79 00 00 02 1C 1F 33 28 3E 07 0E 0F 15 17 16 16 13 19 00 00 02 1C 1F 33 28 3E 07 0E 0F 15 17 16 16 13 19
- 29 01 00 00 01 00 05 B6 00 A6 00 A6
- 05 01 00 00 96 00 02 11 00
- 05 01 00 00 78 00 02 29 00];
+ qcom,mdss-dsi-on-command = [
+ 39 01 00 00 00 00 04
+ B9 FF 83 79
+ 39 01 00 00 00 00 03
+ BA 51 93
+ 39 01 00 00 00 00 14
+ B1 00 50 44
+ EA 8D 08 11
+ 11 11 27 2F
+ 9A 1A 42 0B
+ 6E F1 00 E6
+ 39 01 00 00 00 00 0E
+ B2 00 00 3C
+ 08 04 19 22
+ 00 FF 08 04
+ 19 20
+ 39 01 00 00 00 00 20
+ B4 82 08 00
+ 32 10 03 32
+ 13 70 32 10
+ 08 37 01 28
+ 07 37 08 3C
+ 08 44 44 08
+ 00 40 08 28
+ 08 30 30 04
+ 39 01 00 00 00 00 30
+ D5 00 00 0A
+ 00 01 05 00
+ 03 00 88 88
+ 88 88 23 01
+ 67 45 02 13
+ 88 88 88 88
+ 88 88 88 88
+ 88 88 54 76
+ 10 32 31 20
+ 88 88 88 88
+ 88 88 00 00
+ 00 00 00 00
+ 39 01 00 00 00 00 24
+ E0 79 05 0F
+ 14 26 29 3F
+ 2B 44 04 0E
+ 12 15 18 16
+ 16 12 15 05
+ 0F 14 26 29
+ 3F 2B 44 04
+ 0E 12 15 18
+ 16 16 12 15
+ 23 01 00 00 00 00 02
+ cc 02
+ 39 01 00 00 00 00 05
+ B6 00 9C 00 9C
+ 05 01 00 00 96 00 02
+ 11 00
+ 05 01 00 00 78 00 02
+ 29 00
+ ];
qcom,mdss-dsi-off-command = [05 01 00 00 32 00 02 28 00
05 01 00 00 78 00 02 10 00];
qcom,mdss-dsi-on-command-state = "dsi_lp_mode";
@@ -63,7 +109,7 @@
qcom,mdss-dsi-bllp-power-mode;
qcom,mdss-dsi-lane-0-state;
qcom,mdss-dsi-lane-1-state;
- qcom,mdss-dsi-panel-timings = [5d 12 0c 00 33 39 10 16 15 03 04 00];
+ qcom,mdss-dsi-panel-timings = [75 1A 11 00 3D 45 15 1D 1C 03 04 00];
qcom,mdss-dsi-t-clk-post = <0x04>;
qcom,mdss-dsi-t-clk-pre = <0x1b>;
qcom,mdss-dsi-bl-min-level = <1>;
diff --git a/arch/arm/boot/dts/dsi-panel-otm8018b-fwvga-video.dtsi b/arch/arm/boot/dts/dsi-panel-otm8018b-fwvga-video.dtsi
index 74e7ffc..89a5063 100644
--- a/arch/arm/boot/dts/dsi-panel-otm8018b-fwvga-video.dtsi
+++ b/arch/arm/boot/dts/dsi-panel-otm8018b-fwvga-video.dtsi
@@ -25,7 +25,7 @@
qcom,mdss-dsi-virtual-channel-id = <0>;
qcom,mdss-dsi-stream = <0>;
qcom,mdss-dsi-panel-width = <480>;
- qcom,mdss-dsi-panel-height = <800>;
+ qcom,mdss-dsi-panel-height = <854>;
qcom,mdss-dsi-h-front-porch = <80>;
qcom,mdss-dsi-h-back-porch = <54>;
qcom,mdss-dsi-h-pulse-width = <8>;
@@ -41,96 +41,213 @@
qcom,mdss-dsi-color-order = <0>;
qcom,mdss-dsi-underflow-color = <0xff>;
qcom,mdss-dsi-border-color = <0>;
- qcom,mdss-dsi-on-command = [29 01 00 00 00 00 02 00 00
- 29 01 00 00 00 00 04 ff 80 09 01
- 29 01 00 00 00 00 02 00 80
- 29 01 00 00 00 00 03 ff 80 09
- 29 01 00 00 00 00 02 00 80
- 29 01 00 00 00 00 02 d6 48
- 29 01 00 00 00 00 02 00 03
- 29 01 00 00 00 00 02 ff 01
- 29 01 00 00 00 00 02 00 B4
- 29 01 00 00 00 00 02 C0 10
- 29 01 00 00 00 00 02 00 82
- 29 01 00 00 00 00 02 C5 A3
- 29 01 00 00 00 00 02 00 90
- 29 01 00 00 00 00 03 C5 96 87
- 29 01 00 00 00 00 02 00 00
- 29 01 00 00 00 00 03 D8 74 72
- 29 01 00 00 00 00 02 00 00
- 29 01 00 00 00 00 02 D9 56
- 29 01 00 00 00 00 02 00 00
- 29 01 00 00 00 00 11 E1 00 06 0A 07 03 16 08 0A 04 06 07 08 0F 23 22 05
- 29 01 00 00 00 00 02 00 00
- 29 01 00 00 00 00 11 E2 00 06 0A 07 03 16 08 0A 04 06 07 08 0F 23 22 05
- 29 01 00 00 00 00 02 00 81
- 29 01 00 00 00 00 02 C1 77
- 29 01 00 00 00 00 02 00 A0
- 29 01 00 00 00 00 02 C1 EA
- 29 01 00 00 00 00 02 00 A1
- 29 01 00 00 00 00 02 C1 08
- 29 01 00 00 00 00 02 00 89
- 29 01 00 00 00 00 02 C4 08
- 29 01 00 00 00 00 02 00 81
- 29 01 00 00 00 00 02 C4 83
- 29 01 00 00 00 00 02 00 92
- 29 01 00 00 00 00 02 C5 01
- 29 01 00 00 00 00 02 00 B1
- 29 01 00 00 00 00 02 C5 A9
- 29 01 00 00 00 00 02 00 92
- 29 01 00 00 00 00 02 B3 45
- 29 01 00 00 00 00 02 00 90
- 29 01 00 00 00 00 02 B3 02
- 29 01 00 00 00 00 02 00 80
- 29 01 00 00 00 00 06 C0 00 58 00 14 16
- 29 01 00 00 00 00 02 00 80
- 29 01 00 00 00 00 02 C4 30
- 29 01 00 00 00 00 02 00 90
- 29 01 00 00 00 00 07 C0 00 44 00 00 00 03
- 29 01 00 00 00 00 02 00 A6
- 29 01 00 00 00 00 04 C1 01 00 00
- 29 01 00 00 00 00 02 00 80
- 29 01 00 00 00 00 0D CE 87 03 00 85 03 00 86 03 00 84 03 00
- 29 01 00 00 00 00 02 00 A0
- 29 01 00 00 00 00 0f CE 38 03 03 58 00 00 00 38 02 03 59 00 00 00
- 29 01 00 00 00 00 02 00 B0
- 29 01 00 00 00 00 0f CE 38 01 03 5A 00 00 00 38 00 03 5B 00 00 00
- 29 01 00 00 00 00 02 00 C0
- 29 01 00 00 00 00 0f CE 30 00 03 5C 00 00 00 30 01 03 5D 00 00 00
- 29 01 00 00 00 00 02 00 D0
- 29 01 00 00 00 00 0f CE 30 02 03 5E 00 00 00 30 03 03 5F 00 00 00
- 29 01 00 00 00 00 02 00 C7
- 29 01 00 00 00 00 02 CF 00
- 29 01 00 00 00 00 02 00 C9
- 29 01 00 00 00 00 02 CF 00
- 29 01 00 00 00 00 02 00 D0
- 29 01 00 00 00 00 02 CF 00
- 29 01 00 00 00 00 02 00 C4
- 29 01 00 00 00 00 07 CB 04 04 04 04 04 04
- 29 01 00 00 00 00 02 00 D9
- 29 01 00 00 00 00 07 CB 04 04 04 04 04 04
- 29 01 00 00 00 00 02 00 84
- 29 01 00 00 00 00 07 CC 0C 0A 10 0E 03 04
- 29 01 00 00 00 00 02 00 9E
- 29 01 00 00 00 00 02 CC 0B
- 29 01 00 00 00 00 02 00 A0
- 29 01 00 00 00 00 06 CC 09 0F 0D 01 02
- 29 01 00 00 00 00 02 00 B4
- 29 01 00 00 00 00 07 CC 0D 0F 09 0B 02 01
- 29 01 00 00 00 00 02 00 CE
- 29 01 00 00 00 00 02 CC 0E
- 29 01 00 00 00 00 02 00 D0
- 29 01 00 00 00 00 06 CC 10 0A 0C 04 03
- 29 01 00 00 00 00 02 00 00
- 29 01 00 00 00 00 04 ff ff ff ff
- 05 01 00 00 78 00 02 11 00
- 05 01 00 00 32 00 02 29 00];
+ qcom,mdss-dsi-on-command = [
+ 29 01 00 00 00 00 02
+ 00 00
+ 29 01 00 00 00 00 04
+ ff 80 09 01
+ 29 01 00 00 00 00 02
+ 00 80
+ 29 01 00 00 00 00 03
+ ff 80 09
+ 29 01 00 00 00 00 02
+ 00 80
+ 29 01 00 00 00 00 02
+ d6 48
+ 29 01 00 00 00 00 02
+ 00 03
+ 29 01 00 00 00 00 02
+ ff 01
+ 29 01 00 00 00 00 02
+ 00 B4
+ 29 01 00 00 00 00 02
+ C0 10
+ 29 01 00 00 00 00 02
+ 00 82
+ 29 01 00 00 00 00 02
+ C5 A3
+ 29 01 00 00 00 00 02
+ 00 90
+ 29 01 00 00 00 00 03
+ C5 96 87
+ 29 01 00 00 00 00 02
+ 00 00
+ 29 01 00 00 00 00 03
+ D8 74 72
+ 29 01 00 00 00 00 02
+ 00 00
+ 29 01 00 00 00 00 02
+ D9 56
+ 29 01 00 00 00 00 02
+ 00 00
+ 29 01 00 00 00 00 11
+ E1 00 06 0A
+ 07 03 16 08
+ 0A 04 06 07
+ 08 0F 23 22
+ 05
+ 29 01 00 00 00 00 02
+ 00 00
+ 29 01 00 00 00 00 11
+ E2 00 06 0A
+ 07 03 16 08
+ 0A 04 06 07
+ 08 0F 23 22
+ 05
+ 29 01 00 00 00 00 02
+ 00 81
+ 29 01 00 00 00 00 02
+ C1 77
+ 29 01 00 00 00 00 02
+ 00 A0
+ 29 01 00 00 00 00 02
+ C1 EA
+ 29 01 00 00 00 00 02
+ 00 A1
+ 29 01 00 00 00 00 02
+ C1 08
+ 29 01 00 00 00 00 02
+ 00 89
+ 29 01 00 00 00 00 02
+ C4 08
+ 29 01 00 00 00 00 02
+ 00 81
+ 29 01 00 00 00 00 02
+ C4 83
+ 29 01 00 00 00 00 02
+ 00 92
+ 29 01 00 00 00 00 02
+ C5 01
+ 29 01 00 00 00 00 02
+ 00 B1
+ 29 01 00 00 00 00 02
+ C5 A9
+ 29 01 00 00 00 00 02
+ 00 92
+ 29 01 00 00 00 00 02
+ B3 45
+ 29 01 00 00 00 00 02
+ 00 90
+ 29 01 00 00 00 00 02
+ B3 02
+ 29 01 00 00 00 00 02
+ 00 80
+ 29 01 00 00 00 00 06
+ C0 00 58 00
+ 14 16
+ 29 01 00 00 00 00 02
+ 00 80
+ 29 01 00 00 00 00 02
+ C4 30
+ 29 01 00 00 00 00 02
+ 00 90
+ 29 01 00 00 00 00 07
+ C0 00 44 00
+ 00 00 03
+ 29 01 00 00 00 00 02
+ 00 A6
+ 29 01 00 00 00 00 04
+ C1 01 00 00
+ 29 01 00 00 00 00 02
+ 00 80
+ 29 01 00 00 00 00 0D
+ CE 87 03 00
+ 85 03 00 86
+ 03 00 84 03
+ 00
+ 29 01 00 00 00 00 02
+ 00 A0
+ 29 01 00 00 00 00 0f
+ CE 38 03 03
+ 58 00 00 00
+ 38 02 03 59
+ 00 00 00
+ 29 01 00 00 00 00 02
+ 00 B0
+ 29 01 00 00 00 00 0f
+ CE 38 01 03
+ 5A 00 00 00
+ 38 00 03 5B
+ 00 00 00
+ 29 01 00 00 00 00 02
+ 00 C0
+ 29 01 00 00 00 00 0f
+ CE 30 00 03
+ 5C 00 00 00
+ 30 01 03 5D
+ 00 00 00
+ 29 01 00 00 00 00 02
+ 00 D0
+ 29 01 00 00 00 00 0f
+ CE 30 02 03
+ 5E 00 00 00
+ 30 03 03 5F
+ 00 00 00
+ 29 01 00 00 00 00 02
+ 00 C7
+ 29 01 00 00 00 00 02
+ CF 00
+ 29 01 00 00 00 00 02
+ 00 C9
+ 29 01 00 00 00 00 02
+ CF 00
+ 29 01 00 00 00 00 02
+ 00 D0
+ 29 01 00 00 00 00 02
+ CF 00
+ 29 01 00 00 00 00 02
+ 00 C4
+ 29 01 00 00 00 00 07
+ CB 04 04 04
+ 04 04 04
+ 29 01 00 00 00 00 02
+ 00 D9
+ 29 01 00 00 00 00 07
+ CB 04 04 04
+ 04 04 04
+ 29 01 00 00 00 00 02
+ 00 84
+ 29 01 00 00 00 00 07
+ CC 0C 0A 10
+ 0E 03 04
+ 29 01 00 00 00 00 02
+ 00 9E
+ 29 01 00 00 00 00 02
+ CC 0B
+ 29 01 00 00 00 00 02
+ 00 A0
+ 29 01 00 00 00 00 06
+ CC 09 0F 0D
+ 01 02
+ 29 01 00 00 00 00 02
+ 00 B4
+ 29 01 00 00 00 00 07
+ CC 0D 0F 09
+ 0B 02 01
+ 29 01 00 00 00 00 02
+ 00 CE
+ 29 01 00 00 00 00 02
+ CC 0E
+ 29 01 00 00 00 00 02
+ 00 D0
+ 29 01 00 00 00 00 06
+ CC 10 0A 0C
+ 04 03
+ 29 01 00 00 00 00 02
+ 00 00
+ 29 01 00 00 00 00 04
+ ff ff ff ff
+ 05 01 00 00 78 00 02
+ 11 00
+ 05 01 00 00 32 00 02
+ 29 00
+ ];
qcom,mdss-dsi-off-command = [05 01 00 00 32 00 02 28 00
05 01 00 00 78 00 02 10 00];
qcom,mdss-dsi-on-command-state = "dsi_lp_mode";
qcom,mdss-dsi-off-command-state = "dsi_lp_mode";
- qcom,mdss-dsi-h-sync-pulse = <1>;
- qcom,mdss-dsi-traffic-mode = <2>;
+ qcom,mdss-dsi-h-sync-pulse = <0>;
+ qcom,mdss-dsi-traffic-mode = <1>;
qcom,mdss-dsi-lane-map = <1>;
qcom,mdss-dsi-bllp-eof-power-mode;
qcom,mdss-dsi-bllp-power-mode;
diff --git a/arch/arm/boot/dts/dsi-panel-truly-wvga-cmd.dtsi b/arch/arm/boot/dts/dsi-panel-truly-wvga-cmd.dtsi
index f0957f8..f6e6df8 100644
--- a/arch/arm/boot/dts/dsi-panel-truly-wvga-cmd.dtsi
+++ b/arch/arm/boot/dts/dsi-panel-truly-wvga-cmd.dtsi
@@ -42,31 +42,105 @@
qcom,mdss-dsi-color-order = <0>;
qcom,mdss-dsi-underflow-color = <0xff>;
qcom,mdss-dsi-border-color = <0>;
- qcom,mdss-dsi-on-command = [05 01 00 00 00 00 02 01 00
- 23 01 00 00 00 00 02 b0 04
- 29 01 00 00 00 00 03 b3 02 00
- 23 01 00 00 00 00 02 bd 00
- 29 01 00 00 00 00 03 c0 18 66
- 29 01 00 00 00 00 10 c1 23 31 99 21 20 00 30 28 0c 0c 00 00 00 21 01
- 29 01 00 00 00 00 07 c2 00 06 06 01 03 00
- 29 01 00 00 00 00 19 c8 04 10 18 20 2e 46 3c 28 1f 18 10 04 04 10 18 20 2e 46 3c 28 1f 18 10 04
- 29 01 00 00 00 00 19 c9 04 10 18 20 2e 46 3c 28 1f 18 10 04 04 10 18 20 2e 46 3c 28 1f 18 10 04
- 29 01 00 00 00 00 19 ca 04 10 18 20 2e 46 3c 28 1f 18 10 04 04 10 18 20 2e 46 3c 28 1f 18 10 04
- 29 01 00 00 00 00 11 d0 29 03 ce a6 00 43 20 10 01 00 01 01 00 03 01 00
- 29 01 00 00 00 00 08 d1 18 0C 23 03 75 02 50
- 23 01 00 00 00 00 02 d3 11
- 29 01 00 00 00 00 03 d5 2a 2a
- 29 01 00 00 00 00 03 de 01 51
- 23 01 00 00 00 00 02 e6 51
- 23 01 00 00 00 00 02 fa 03
- 23 01 00 00 64 00 02 d6 28
- 15 01 00 00 64 00 02 36 41
- 39 01 00 00 00 00 05 2a 00 00 01 df
- 39 01 00 00 00 00 05 2b 00 00 03 1f
- 15 01 00 00 00 00 02 35 00
- 39 01 00 00 00 00 03 44 00 50
- 05 01 00 00 7D 00 02 11 00
- 05 01 00 00 14 00 02 29 00];
+ qcom,mdss-dsi-on-command = [
+ 05 01 00 00 00 00 02
+ 01 00
+ 23 01 00 00 00 00 02
+ b0 04
+ 29 01 00 00 00 00 03
+ b3 02 00
+ 29 01 00 00 00 00 03
+ b6 51 83
+ 29 01 00 00 00 00 05
+ b7 00 80 15 25
+ 29 01 00 00 00 00 14
+ b8 00 07 07 ff c8 c8 01 18 10 10
+ 37 5a 87 de ff 00 00 00 00
+ 29 01 00 00 00 00 05
+ b9 00 00 00 00
+ 23 01 00 00 00 00 02
+ bd 00
+ 29 01 00 00 00 00 03
+ c0 02 43
+ 29 01 00 00 00 00 10
+ c1 43 31 99 21 20 00 10 28 0c 0c
+ 00 00 00 21 01
+ 29 01 00 00 00 00 07
+ c2 28 06 06 01 03 00
+ 29 01 00 00 00 00 04
+ c3 40 00 03
+ 29 01 00 00 00 00 03
+ 6f 03 00
+ 29 01 00 00 00 00 03
+ c4 00 01
+ 29 01 00 00 00 00 03
+ c6 00 00
+ 29 01 00 00 00 00 06
+ c7 11 8d a0 f5 27
+ 29 01 00 00 00 00 19
+ c8 01 0a 12 1c 2b 45 3f 29 17 13
+ 0f 04 01 0a 12 1c 2b 45 3f 29 17 13 0f 04
+ 29 01 00 00 00 00 19
+ c9 01 0a 12 1c 2b 45 3f 29 17 13
+ 0f 04 01 0a 12 1c 2b 45 3f 29 17 13 0f 04
+ 29 01 00 00 00 00 19
+ ca 01 0a 12 1c 2b 45 3f 29 17 13
+ 0f 04 01 0a 12 1c 2b 45 3f 29 17 13 0f 04
+ 29 01 00 00 00 00 11
+ d0 99 03 ce a6 00 43 20 10 01 00
+ 01 01 00 03 01 00
+ 29 01 00 00 00 00 08
+ d1 18 0C 23 03 75 02 50
+ 23 01 00 00 00 00 02
+ d3 33
+ 29 01 00 00 00 00 03
+ d5 2a 2a
+ 29 01 00 00 00 00 02
+ d6 28
+ 29 01 00 00 00 00 10
+ d7 01 00 aa c0 2a 2c 22 12 71 0a 12 00 a0
+ 00 03
+ 29 01 00 00 00 00 09
+ d8 44 44 22 44 21 46 42 40
+ 29 01 00 00 00 00 04
+ d9 cf 2d 51
+ 29 01 00 00 00 00 02
+ da 01
+ 29 01 00 00 00 00 03
+ de 01 4f
+ 29 01 00 00 00 00 07
+ e1 00 00 00 00 00 00
+ 23 01 00 00 00 00 02
+ e6 4f
+ 29 01 00 00 00 00 06
+ f3 06 00 00 24 00
+ 29 01 00 00 00 00 02
+ f8 00
+ 23 01 00 00 00 00 02
+ fa 03
+ 29 01 00 00 00 00 04
+ fb 00 00 00
+ 29 01 00 00 00 00 06
+ fc 00 00 00 00 00
+ 29 01 00 00 00 00 05
+ fd 00 00 70 00
+ 39 01 00 00 00 00 05
+ 2a 00 00 01 df
+ 39 01 00 00 00 00 05
+ 2b 00 00 03 1f
+ 15 01 00 00 00 00 02
+ 35 00
+ 39 01 00 00 00 00 03
+ 44 00 50
+ 15 01 00 00 00 00 02
+ 36 41
+ 15 01 00 00 00 00 02
+ 3a 77
+ 05 01 00 00 7D 00 02
+ 11 00
+ 05 01 00 00 3c 00 02
+ 29 00
+ ];
qcom,mdss-dsi-off-command = [05 01 00 00 32 00 02 28 00
05 01 00 00 78 00 02 10 00];
qcom,mdss-dsi-on-command-state = "dsi_lp_mode";
@@ -80,6 +154,7 @@
qcom,mdss-dsi-lane-1-state;
qcom,mdss-dsi-te-pin-select = <1>;
qcom,mdss-dsi-te-v-sync-rd-ptr-irq-line = <0x2c>;
+ qcom,mdss-dsi-te-v-sync-continues-lines = <0x3c>;
qcom,mdss-dsi-te-dcs-command = <1>;
qcom,mdss-dsi-te-check-enable;
qcom,mdss-dsi-te-using-te-pin;
diff --git a/arch/arm/boot/dts/dsi-panel-truly-wvga-video.dtsi b/arch/arm/boot/dts/dsi-panel-truly-wvga-video.dtsi
index 32af837..fae4834 100644
--- a/arch/arm/boot/dts/dsi-panel-truly-wvga-video.dtsi
+++ b/arch/arm/boot/dts/dsi-panel-truly-wvga-video.dtsi
@@ -42,34 +42,111 @@
qcom,mdss-dsi-color-order = <0>;
qcom,mdss-dsi-underflow-color = <0xff>;
qcom,mdss-dsi-border-color = <0>;
- qcom,mdss-dsi-on-command = [05 01 00 00 00 00 02 01 00
- 23 01 00 00 00 00 02 b0 04
- 29 01 00 00 00 00 03 b3 02 00
- 23 01 00 00 00 00 02 bd 00
- 29 01 00 00 00 00 03 c0 18 66
- 29 01 00 00 00 00 10 c1 23 31 99 21 20 00 30 28 0c 0c 00 00 00 21 01
- 29 01 00 00 00 00 07 c2 00 06 06 01 03 00
- 29 01 00 00 00 00 19 c8 04 10 18 20 2e 46 3c 28 1f 18 10 04 04 10 18 20 2e 46 3c 28 1f 18 10 04
- 29 01 00 00 00 00 19 c9 04 10 18 20 2e 46 3c 28 1f 18 10 04 04 10 18 20 2e 46 3c 28 1f 18 10 04
- 29 01 00 00 00 00 19 ca 04 10 18 20 2e 46 3c 28 1f 18 10 04 04 10 18 20 2e 46 3c 28 1f 18 10 04
- 29 01 00 00 00 00 11 d0 29 03 ce a6 00 43 20 10 01 00 01 01 00 03 01 00
- 29 01 00 00 00 00 08 d1 18 0C 23 03 75 02 50
- 23 01 00 00 00 00 02 d3 11
- 29 01 00 00 00 00 03 d5 2a 2a
- 29 01 00 00 00 00 03 de 01 51
- 23 01 00 00 00 00 02 e6 51
- 23 01 00 00 00 00 02 fa 03
- 23 01 00 00 64 00 02 d6 28
- 39 01 00 00 00 00 05 2a 00 00 01 df
- 39 01 00 00 00 00 05 2b 00 00 03 1f
- 15 01 00 00 00 00 02 35 00
- 39 01 00 00 00 00 03 44 00 50
- 15 01 00 00 00 00 02 36 c1
- 15 01 00 00 00 00 02 3a 77
- 05 01 00 00 00 00 02 11 00
- 05 01 00 00 00 00 02 29 00];
+ qcom,mdss-dsi-on-command = [
+ 05 01 00 00 00 00 02
+ 01 00
+ 23 01 00 00 00 00 02
+ b0 04
+ 29 01 00 00 00 00 03
+ b3 02 00
+ 29 01 00 00 00 00 03
+ b6 51 83
+ 29 01 00 00 00 00 05
+ b7 00 80 15 25
+ 29 01 00 00 00 00 14
+ b8 00 07 07 ff c8 c8 01 18 10 10
+ 37 5a 87 de ff 00 00 00 00
+ 29 01 00 00 00 00 05
+ b9 00 00 00 00
+ 23 01 00 00 00 00 02
+ bd 00
+ 29 01 00 00 00 00 03
+ c0 02 43
+ 29 01 00 00 00 00 10
+ c1 43 31 99 21 20 00 10 28 0c 0c
+ 00 00 00 21 01
+ 29 01 00 00 00 00 07
+ c2 28 06 06 01 03 00
+ 29 01 00 00 00 00 04
+ c3 40 00 03
+ 29 01 00 00 00 00 03
+ 6f 03 00
+ 29 01 00 00 00 00 03
+ c4 00 01
+ 29 01 00 00 00 00 03
+ c6 00 00
+ 29 01 00 00 00 00 06
+ c7 11 8d a0 f5 27
+ 29 01 00 00 00 00 19
+ c8 01 0a 12 1c 2b 45 3f 29 17 13
+ 0f 04 01 0a 12 1c 2b 45 3f 29 17 13 0f 04
+ 29 01 00 00 00 00 19
+ c9 01 0a 12 1c 2b 45 3f 29 17 13
+ 0f 04 01 0a 12 1c 2b 45 3f 29 17 13 0f 04
+ 29 01 00 00 00 00 19
+ ca 01 0a 12 1c 2b 45 3f 29 17 13
+ 0f 04 01 0a 12 1c 2b 45 3f 29 17 13 0f 04
+ 29 01 00 00 00 00 11
+ d0 99 03 ce a6 00 43 20 10 01 00
+ 01 01 00 03 01 00
+ 29 01 00 00 00 00 08
+ d1 18 0C 23 03 75 02 50
+ 23 01 00 00 00 00 02
+ d3 33
+ 29 01 00 00 00 00 03
+ d5 2a 2a
+ 29 01 00 00 00 00 02
+ d6 28
+ 29 01 00 00 00 00 10
+ d7 01 00 aa c0 2a 2c 22 12 71 0a 12 00 a0
+ 00 03
+ 29 01 00 00 00 00 09
+ d8 44 44 22 44 21 46 42 40
+ 29 01 00 00 00 00 04
+ d9 cf 2d 51
+ 29 01 00 00 00 00 02
+ da 01
+ 29 01 00 00 00 00 03
+ de 01 4f
+ 29 01 00 00 00 00 07
+ e1 00 00 00 00 00 00
+ 23 01 00 00 00 00 02
+ e6 4f
+ 29 01 00 00 00 00 06
+ f3 06 00 00 24 00
+ 29 01 00 00 00 00 02
+ f8 00
+ 23 01 00 00 00 00 02
+ fa 03
+ 29 01 00 00 00 00 04
+ fb 00 00 00
+ 29 01 00 00 00 00 06
+ fc 00 00 00 00 00
+ 29 01 00 00 00 00 05
+ fd 00 00 70 00
+ 39 01 00 00 00 00 05
+ 2a 00 00 01 df
+ 39 01 00 00 00 00 05
+ 2b 00 00 03 1f
+ 15 01 00 00 00 00 02
+ 35 00
+ 39 01 00 00 00 00 03
+ 44 00 50
+ 15 01 00 00 00 00 02
+ 36 c1
+ 15 01 00 00 00 00 02
+ 3a 77
+ 05 01 00 00 7D 00 02
+ 11 00
+ 05 01 00 00 3c 00 02
+ 29 00
+ ];
qcom,mdss-dsi-off-command = [05 01 00 00 32 00 02 28 00
- 05 01 00 00 78 00 02 10 00];
+ 05 01 00 00 78 00 02 10 00
+ 23 01 00 00 10 00 02
+ b0 04
+ 23 01 00 00 20 00 02
+ b1 01];
qcom,mdss-dsi-on-command-state = "dsi_lp_mode";
qcom,mdss-dsi-off-command-state = "dsi_lp_mode";
qcom,mdss-dsi-h-sync-pulse = <0>;
diff --git a/arch/arm/boot/dts/msm8226-qrd.dtsi b/arch/arm/boot/dts/msm8226-qrd.dtsi
index a574bb0..3a18514 100644
--- a/arch/arm/boot/dts/msm8226-qrd.dtsi
+++ b/arch/arm/boot/dts/msm8226-qrd.dtsi
@@ -114,10 +114,10 @@
"MIC BIAS1 External", "Handset Mic",
"AMIC2", "MIC BIAS2 External",
"MIC BIAS2 External", "Headset Mic",
- "AMIC4", "MIC BIAS2 External",
- "MIC BIAS2 External", "ANCRight Headset Mic",
- "AMIC5", "MIC BIAS2 External",
- "MIC BIAS2 External", "ANCLeft Headset Mic";
+ "AMIC3", "MIC BIAS1 External",
+ "MIC BIAS1 External", "Analog Mic3",
+ "AMIC4", "MIC BIAS3 External",
+ "MIC BIAS3 External", "Analog Mic4";
qcom,cdc-mclk-gpios = <&pm8226_gpios 1 0>;
qcom,cdc-vdd-spkr-gpios = <&pm8226_gpios 2 0>;
@@ -454,6 +454,7 @@
&slim_msm {
tapan_codec {
qcom,cdc-micbias1-ext-cap;
+ qcom,cdc-micbias3-ext-cap;
};
};
diff --git a/arch/arm/boot/dts/msm8226-regulator.dtsi b/arch/arm/boot/dts/msm8226-regulator.dtsi
index 5b3da9b..415912f 100644
--- a/arch/arm/boot/dts/msm8226-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8226-regulator.dtsi
@@ -43,7 +43,7 @@
qcom,pvs-bin-process = <0 0 0 0 0 1 1 1 1 1 2 2 2 2 2 2
2 2 2 2 3 3 3 3 3 3 3 3 0 0 0 0>;
- qcom,pvs-corner-ceiling-slow = <1050000 1160000 1275000>;
+ qcom,pvs-corner-ceiling-slow = <1050000 1150000 1275000>;
qcom,pvs-corner-ceiling-nom = <1050000 1075000 1200000>;
qcom,pvs-corner-ceiling-fast = <1050000 1050000 1140000>;
vdd-apc-supply = <&pm8226_s2>;
diff --git a/arch/arm/boot/dts/msm8226-v2.dtsi b/arch/arm/boot/dts/msm8226-v2.dtsi
index c2ce546..8f22ceb 100644
--- a/arch/arm/boot/dts/msm8226-v2.dtsi
+++ b/arch/arm/boot/dts/msm8226-v2.dtsi
@@ -54,7 +54,7 @@
&apc_vreg_corner {
qcom,pvs-bin-process = <1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2
2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3>;
- qcom,pvs-corner-ceiling-slow = <1050000 1160000 1280000>;
+ qcom,pvs-corner-ceiling-slow = <1050000 1150000 1280000>;
qcom,pvs-corner-ceiling-nom = <1050000 1080000 1200000>;
qcom,pvs-corner-ceiling-fast = <1050000 1050000 1140000>;
qcom,cpr-step-quotient = <30>;
diff --git a/arch/arm/mach-msm/bam_dmux.c b/arch/arm/mach-msm/bam_dmux.c
index 820bcf9..6281395 100644
--- a/arch/arm/mach-msm/bam_dmux.c
+++ b/arch/arm/mach-msm/bam_dmux.c
@@ -195,6 +195,7 @@
static struct sps_register_event rx_register_event;
static bool satellite_mode;
static uint32_t num_buffers;
+static unsigned long long last_rx_pkt_timestamp;
static struct bam_ch_info bam_ch[BAM_DMUX_NUM_CHANNELS];
static int bam_mux_initialized;
@@ -1117,6 +1118,29 @@
queue_work_on(0, bam_mux_rx_workqueue, &rx_timer_work);
}
+/**
+ * store_rx_timestamp() - store the current raw time as as a timestamp for when
+ * the last rx packet was processed
+ */
+static void store_rx_timestamp(void)
+{
+ last_rx_pkt_timestamp = sched_clock();
+}
+
+/**
+ * log_rx_timestamp() - Log the stored rx pkt timestamp in a human readable
+ * format
+ */
+static void log_rx_timestamp(void)
+{
+ unsigned long long t = last_rx_pkt_timestamp;
+ unsigned long nanosec_rem;
+
+ nanosec_rem = do_div(t, 1000000000U);
+ BAM_DMUX_LOG("Last rx pkt processed at [%6u.%09lu]\n", (unsigned)t,
+ nanosec_rem);
+}
+
static void rx_timer_work_func(struct work_struct *work)
{
struct sps_iovec iov;
@@ -1125,20 +1149,26 @@
int ret;
u32 buffs_unused, buffs_used;
+ BAM_DMUX_LOG("%s: polling start\n", __func__);
while (bam_connection_is_active) { /* timer loop */
++inactive_cycles;
while (bam_connection_is_active) { /* deplete queue loop */
- if (in_global_reset)
+ if (in_global_reset) {
+ BAM_DMUX_LOG(
+ "%s: polling exit, global reset detected\n",
+ __func__);
return;
+ }
ret = sps_get_iovec(bam_rx_pipe, &iov);
if (ret) {
- pr_err("%s: sps_get_iovec failed %d\n",
+ DMUX_LOG_KERR("%s: sps_get_iovec failed %d\n",
__func__, ret);
break;
}
if (iov.addr == 0)
break;
+ store_rx_timestamp();
inactive_cycles = 0;
mutex_lock(&bam_rx_pool_mutexlock);
if (unlikely(list_empty(&bam_rx_pool))) {
@@ -1171,6 +1201,7 @@
}
if (inactive_cycles >= POLLING_INACTIVITY) {
+ BAM_DMUX_LOG("%s: polling exit, no data\n", __func__);
rx_switch_to_interrupt_mode();
break;
}
@@ -1182,7 +1213,8 @@
&buffs_unused);
if (ret) {
- pr_err("%s: error getting num buffers unused after sleep\n",
+ DMUX_LOG_KERR(
+ "%s: error getting num buffers unused after sleep\n",
__func__);
break;
@@ -1768,6 +1800,7 @@
if (time_remaining == 0) {
DMUX_LOG_KERR("%s: shutdown completion timed out\n",
__func__);
+ log_rx_timestamp();
ssrestart_check();
}
}
diff --git a/arch/arm/mach-msm/board-8226-gpiomux.c b/arch/arm/mach-msm/board-8226-gpiomux.c
index dcce820..5dd9bab 100644
--- a/arch/arm/mach-msm/board-8226-gpiomux.c
+++ b/arch/arm/mach-msm/board-8226-gpiomux.c
@@ -73,17 +73,22 @@
.pull = GPIOMUX_PULL_NONE,
};
-static struct gpiomux_setting gpio_spi_config = {
+static struct gpiomux_setting gpio_spi_act_config = {
.func = GPIOMUX_FUNC_1,
.drv = GPIOMUX_DRV_8MA,
.pull = GPIOMUX_PULL_NONE,
};
-static struct gpiomux_setting gpio_spi_cs_config = {
+static struct gpiomux_setting gpio_spi_cs_act_config = {
.func = GPIOMUX_FUNC_1,
.drv = GPIOMUX_DRV_6MA,
.pull = GPIOMUX_PULL_DOWN,
};
+static struct gpiomux_setting gpio_spi_susp_config = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
static struct gpiomux_setting gpio_spi_cs_eth_config = {
.func = GPIOMUX_FUNC_4,
@@ -160,25 +165,29 @@
{
.gpio = 0, /* BLSP1 QUP1 SPI_DATA_MOSI */
.settings = {
- [GPIOMUX_SUSPENDED] = &gpio_spi_config,
+ [GPIOMUX_ACTIVE] = &gpio_spi_act_config,
+ [GPIOMUX_SUSPENDED] = &gpio_spi_susp_config,
},
},
{
.gpio = 1, /* BLSP1 QUP1 SPI_DATA_MISO */
.settings = {
- [GPIOMUX_SUSPENDED] = &gpio_spi_config,
+ [GPIOMUX_ACTIVE] = &gpio_spi_act_config,
+ [GPIOMUX_SUSPENDED] = &gpio_spi_susp_config,
},
},
{
.gpio = 2, /* BLSP1 QUP1 SPI_CS1 */
.settings = {
- [GPIOMUX_SUSPENDED] = &gpio_spi_cs_config,
+ [GPIOMUX_ACTIVE] = &gpio_spi_cs_act_config,
+ [GPIOMUX_SUSPENDED] = &gpio_spi_susp_config,
},
},
{
.gpio = 3, /* BLSP1 QUP1 SPI_CLK */
.settings = {
- [GPIOMUX_SUSPENDED] = &gpio_spi_config,
+ [GPIOMUX_ACTIVE] = &gpio_spi_act_config,
+ [GPIOMUX_SUSPENDED] = &gpio_spi_susp_config,
},
},
{
diff --git a/arch/arm/mach-msm/clock-8974.c b/arch/arm/mach-msm/clock-8974.c
index 3b80374..654dbd3 100644
--- a/arch/arm/mach-msm/clock-8974.c
+++ b/arch/arm/mach-msm/clock-8974.c
@@ -4897,10 +4897,29 @@
CLK_DUMMY("core_clk", NULL, "fdc84000.qcom,iommu", oFF),
};
-static struct clk_lookup msm_clocks_8974ac_only[] __initdata = {
+static struct clk_lookup msm_clocks_8974pro_only[] __initdata = {
CLK_LOOKUP("gpll4", gpll4_clk_src.c, ""),
CLK_LOOKUP("sleep_clk", gcc_sdcc1_cdccal_sleep_clk.c, "msm_sdcc.1"),
CLK_LOOKUP("cal_clk", gcc_sdcc1_cdccal_ff_clk.c, "msm_sdcc.1"),
+ CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "6e.qcom,camera"),
+ CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "20.qcom,camera"),
+ CLK_LOOKUP("cam_src_clk", mclk2_clk_src.c, "6c.qcom,camera"),
+ CLK_LOOKUP("cam_src_clk", mclk1_clk_src.c, "90.qcom,camera"),
+ CLK_LOOKUP("cam_clk", camss_mclk0_clk.c, "6e.qcom,camera"),
+ CLK_LOOKUP("cam_clk", camss_mclk0_clk.c, "20.qcom,camera"),
+ CLK_LOOKUP("cam_clk", camss_mclk2_clk.c, "6c.qcom,camera"),
+ CLK_LOOKUP("cam_clk", camss_mclk1_clk.c, "90.qcom,camera"),
+};
+
+static struct clk_lookup msm_clocks_8974_only[] __initdata = {
+ CLK_LOOKUP("cam_src_clk", mmss_gp0_clk_src.c, "6e.qcom,camera"),
+ CLK_LOOKUP("cam_src_clk", mmss_gp0_clk_src.c, "20.qcom,camera"),
+ CLK_LOOKUP("cam_src_clk", gp1_clk_src.c, "6c.qcom,camera"),
+ CLK_LOOKUP("cam_src_clk", mmss_gp1_clk_src.c, "90.qcom,camera"),
+ CLK_LOOKUP("cam_clk", camss_gp0_clk.c, "6e.qcom,camera"),
+ CLK_LOOKUP("cam_clk", camss_gp0_clk.c, "20.qcom,camera"),
+ CLK_LOOKUP("cam_clk", gcc_gp1_clk.c, "6c.qcom,camera"),
+ CLK_LOOKUP("cam_clk", camss_gp1_clk.c, "90.qcom,camera"),
};
static struct clk_lookup msm_clocks_8974_common[] __initdata = {
@@ -5076,22 +5095,16 @@
CLK_LOOKUP("core_clk_src", mdp_clk_src.c, "mdp.0"),
CLK_LOOKUP("vsync_clk", mdss_vsync_clk.c, "mdp.0"),
- /* MM sensor clocks */
- CLK_LOOKUP("cam_src_clk", mmss_gp0_clk_src.c, "6e.qcom,camera"),
- CLK_LOOKUP("cam_src_clk", mmss_gp0_clk_src.c, "20.qcom,camera"),
- CLK_LOOKUP("cam_src_clk", gp1_clk_src.c, "6c.qcom,camera"),
- CLK_LOOKUP("cam_src_clk", mmss_gp1_clk_src.c, "90.qcom,camera"),
- CLK_LOOKUP("cam_clk", camss_gp0_clk.c, "6e.qcom,camera"),
- CLK_LOOKUP("cam_clk", camss_gp0_clk.c, "20.qcom,camera"),
- CLK_LOOKUP("cam_clk", gcc_gp1_clk.c, "6c.qcom,camera"),
- CLK_LOOKUP("cam_clk", camss_gp1_clk.c, "90.qcom,camera"),
- CLK_LOOKUP("cam_clk", camss_mclk1_clk.c, ""),
- CLK_LOOKUP("cam_clk", camss_mclk2_clk.c, ""),
- CLK_LOOKUP("cam_clk", camss_mclk3_clk.c, ""),
- CLK_LOOKUP("cam_gp0_src_clk", mmss_gp0_clk_src.c, ""),
- CLK_LOOKUP("cam_gp1_src_clk", mmss_gp1_clk_src.c, ""),
- CLK_LOOKUP("cam_gp0_clk", camss_gp0_clk.c, ""),
- CLK_LOOKUP("cam_gp1_clk", camss_gp1_clk.c, ""),
+ /* MM sensor clocks placeholder */
+ CLK_LOOKUP("", camss_mclk0_clk.c, ""),
+ CLK_LOOKUP("", camss_mclk1_clk.c, ""),
+ CLK_LOOKUP("", camss_mclk2_clk.c, ""),
+ CLK_LOOKUP("", camss_mclk3_clk.c, ""),
+ CLK_LOOKUP("", mmss_gp0_clk_src.c, ""),
+ CLK_LOOKUP("", mmss_gp1_clk_src.c, ""),
+ CLK_LOOKUP("", camss_gp0_clk.c, ""),
+ CLK_LOOKUP("", camss_gp1_clk.c, ""),
+
/* CCI clocks */
CLK_LOOKUP("camss_top_ahb_clk", camss_top_ahb_clk.c,
"fda0c000.qcom,cci"),
@@ -5450,7 +5463,8 @@
};
static struct clk_lookup msm_clocks_8974[ARRAY_SIZE(msm_clocks_8974_common)
- + ARRAY_SIZE(msm_clocks_8974ac_only)];
+ + ARRAY_SIZE(msm_clocks_8974_only)
+ + ARRAY_SIZE(msm_clocks_8974pro_only)];
static struct pll_config_regs mmpll0_regs __initdata = {
.l_reg = (void __iomem *)MMPLL0_L_REG,
@@ -5797,18 +5811,26 @@
memcpy(msm_clocks_8974, msm_clocks_8974_common,
sizeof(msm_clocks_8974_common));
- msm8974_clock_init_data.size -= ARRAY_SIZE(msm_clocks_8974ac_only);
- /* version specific changes */
+ /* version specific clock changes */
if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) >= 2
|| cpu_is_msm8974pro())
msm8974_v2_clock_override();
- if (cpu_is_msm8974pro()) {
+ if (cpu_is_msm8974pro())
msm8974_pro_clock_override();
+
+ /* version specific lookup table changes */
+ if (cpu_is_msm8974()) {
memcpy(msm_clocks_8974 + ARRAY_SIZE(msm_clocks_8974_common),
- msm_clocks_8974ac_only, sizeof(msm_clocks_8974ac_only));
+ msm_clocks_8974_only, sizeof(msm_clocks_8974_only));
msm8974_clock_init_data.size +=
- ARRAY_SIZE(msm_clocks_8974ac_only);
+ ARRAY_SIZE(msm_clocks_8974_only);
+ } else if (cpu_is_msm8974pro()) {
+ memcpy(msm_clocks_8974 + ARRAY_SIZE(msm_clocks_8974_common),
+ msm_clocks_8974pro_only,
+ sizeof(msm_clocks_8974pro_only));
+ msm8974_clock_init_data.size +=
+ ARRAY_SIZE(msm_clocks_8974pro_only);
}
clk_ops_pixel_clock = clk_ops_pixel;
@@ -5841,7 +5863,7 @@
struct clock_init_data msm8974_clock_init_data __initdata = {
.table = msm_clocks_8974,
- .size = ARRAY_SIZE(msm_clocks_8974),
+ .size = ARRAY_SIZE(msm_clocks_8974_common),
.pre_init = msm8974_clock_pre_init,
.post_init = msm8974_clock_post_init,
};
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_core.h b/arch/arm/mach-msm/msm_bus/msm_bus_core.h
index 87719e3..7e4a513 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_core.h
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_core.h
@@ -36,7 +36,8 @@
(((slv >= MSM_BUS_SLAVE_FIRST) && (slv <= MSM_BUS_SLAVE_LAST)) ? 1 : 0)
#define INTERLEAVED_BW(fab_pdata, bw, ports) \
- ((fab_pdata->il_flag) ? msm_bus_div64((ports), (bw)) : (bw))
+ ((fab_pdata->il_flag) ? ((bw < 0) \
+ ? -msm_bus_div64((ports), (-bw)) : msm_bus_div64((ports), (bw))) : (bw))
#define INTERLEAVED_VAL(fab_pdata, n) \
((fab_pdata->il_flag) ? (n) : 1)
diff --git a/drivers/media/platform/msm/camera_v2/sensor/flash/Makefile b/drivers/media/platform/msm/camera_v2/sensor/flash/Makefile
index 62102cb..9fc3817 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/flash/Makefile
+++ b/drivers/media/platform/msm/camera_v2/sensor/flash/Makefile
@@ -4,3 +4,4 @@
obj-$(CONFIG_MSMB_CAMERA) += msm_led_trigger.o
obj-$(CONFIG_MSMB_CAMERA) += msm_led_i2c_trigger.o
obj-$(CONFIG_MSMB_CAMERA) += adp1660.o
+obj-$(CONFIG_MSMB_CAMERA) += msm_led_torch.o
diff --git a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_torch.c b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_torch.c
new file mode 100644
index 0000000..ff63696
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_torch.c
@@ -0,0 +1,60 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#define pr_fmt(fmt) "%s:%d " fmt, __func__, __LINE__
+
+#include <linux/module.h>
+#include "msm_led_flash.h"
+
+static struct led_trigger *torch_trigger;
+
+static void msm_led_torch_brightness_set(struct led_classdev *led_cdev,
+ enum led_brightness value)
+{
+ if (!torch_trigger) {
+ pr_err("No torch trigger found, can't set brightness\n");
+ return;
+ }
+
+ led_trigger_event(torch_trigger, value);
+};
+
+static struct led_classdev msm_torch_led = {
+ .name = "torch-light",
+ .brightness_set = msm_led_torch_brightness_set,
+ .brightness = LED_OFF,
+};
+
+int32_t msm_led_torch_create_classdev(struct platform_device *pdev,
+ void *data)
+{
+ int rc;
+ struct msm_led_flash_ctrl_t *fctrl =
+ (struct msm_led_flash_ctrl_t *)data;
+
+ if (!fctrl || !fctrl->torch_trigger) {
+ pr_err("Invalid fctrl or torch trigger\n");
+ return -EINVAL;
+ }
+
+ torch_trigger = fctrl->torch_trigger;
+ msm_led_torch_brightness_set(&msm_torch_led, LED_OFF);
+
+ rc = led_classdev_register(&pdev->dev, &msm_torch_led);
+ if (rc) {
+ pr_err("Failed to register led dev. rc = %d\n", rc);
+ return rc;
+ }
+
+ return 0;
+};
diff --git a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_trigger.c b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_trigger.c
index 1b0ec44..20905c9 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_trigger.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_trigger.c
@@ -26,6 +26,9 @@
#define CDBG(fmt, args...) do { } while (0)
#endif
+extern int32_t msm_led_torch_create_classdev(
+ struct platform_device *pdev, void *data);
+
static struct msm_led_flash_ctrl_t fctrl;
static int32_t msm_led_trigger_get_subdev_id(struct msm_led_flash_ctrl_t *fctrl,
@@ -209,7 +212,11 @@
of_node_put(flash_src_node);
}
}
+
rc = msm_led_flash_create_v4lsubdev(pdev, &fctrl);
+ if (!rc)
+ msm_led_torch_create_classdev(pdev, &fctrl);
+
return rc;
}
diff --git a/drivers/misc/isa1200.c b/drivers/misc/isa1200.c
index c6d08d1..8090b95 100644
--- a/drivers/misc/isa1200.c
+++ b/drivers/misc/isa1200.c
@@ -44,6 +44,7 @@
struct timed_output_dev dev;
struct work_struct work;
struct mutex lock;
+ struct mutex lock_clk;
unsigned int enable;
unsigned int period_ns;
bool is_len_gpio_valid;
@@ -120,16 +121,19 @@
}
}
+ mutex_lock(&haptic->lock_clk);
/* vote for clock */
if (haptic->pdata->need_pwm_clk && !haptic->clk_on) {
rc = clk_prepare_enable(haptic->pwm_clk);
if (rc < 0) {
pr_err("%s: clk enable failed\n",
__func__);
+ mutex_unlock(&haptic->lock_clk);
goto dis_clk_cb;
}
haptic->clk_on = true;
}
+ mutex_unlock(&haptic->lock_clk);
rc = isa1200_write_reg(haptic->client,
ISA1200_HCTRL5,
@@ -162,11 +166,13 @@
if (rc < 0)
pr_err("%s: stop vibartion fail\n", __func__);
+ mutex_lock(&haptic->lock_clk);
/* de-vote clock */
if (haptic->pdata->need_pwm_clk && haptic->clk_on) {
clk_disable_unprepare(haptic->pwm_clk);
haptic->clk_on = false;
}
+ mutex_unlock(&haptic->lock_clk);
/* check for board specific clk callback */
if (haptic->pdata->clk_enable) {
rc = haptic->pdata->clk_enable(false);
@@ -180,10 +186,12 @@
return;
dis_clk:
+ mutex_lock(&haptic->lock_clk);
if (haptic->pdata->need_pwm_clk && haptic->clk_on) {
clk_disable_unprepare(haptic->pwm_clk);
haptic->clk_on = false;
}
+ mutex_unlock(&haptic->lock_clk);
dis_clk_cb:
if (haptic->pdata->clk_enable) {
@@ -649,6 +657,7 @@
}
mutex_init(&haptic->lock);
+ mutex_init(&haptic->lock_clk);
INIT_WORK(&haptic->work, isa1200_chip_work);
haptic->clk_on = false;
@@ -787,6 +796,7 @@
/* destroy mutex */
mutex_destroy(&haptic->lock);
+ mutex_destroy(&haptic->lock_clk);
/* power-off the chip */
if (haptic->pdata->regulator_info) {
diff --git a/drivers/video/msm/mdss/dsi_host_v2.c b/drivers/video/msm/mdss/dsi_host_v2.c
index 1f2f6f9..5264005 100644
--- a/drivers/video/msm/mdss/dsi_host_v2.c
+++ b/drivers/video/msm/mdss/dsi_host_v2.c
@@ -482,6 +482,8 @@
if (rc == 0) {
pr_err("DSI command transaction time out\n");
rc = -ETIME;
+ } else if (!IS_ERR_VALUE(rc)) {
+ rc = 0;
}
dma_unmap_single(&dsi_host_private->dis_dev, tp->dmap, size,
@@ -524,7 +526,7 @@
{
struct dsi_cmd_desc *cm;
u32 dsi_ctrl, ctrl;
- int i, video_mode;
+ int i, video_mode, rc = 0;
unsigned char *ctrl_base = dsi_host_private->dsi_base;
/* turn on cmd mode
@@ -546,6 +548,11 @@
dsi_buf_init(tp);
dsi_cmd_dma_add(tp, cm);
msm_dsi_cmd_dma_tx(tp);
+ rc = msm_dsi_cmd_dma_tx(tp);
+ if (IS_ERR_VALUE(rc)) {
+ pr_err("%s: failed to call cmd_dma_tx\n", __func__);
+ break;
+ }
if (cm->dchdr.wait)
msleep(cm->dchdr.wait);
cm++;
@@ -555,7 +562,7 @@
if (video_mode)
MIPI_OUTP(ctrl_base + DSI_CTRL, dsi_ctrl);
- return 0;
+ return rc;
}
/* MDSS_DSI_MRPS, Maximum Return Packet Size */
@@ -582,7 +589,7 @@
struct dsi_buf *tp, struct dsi_buf *rp,
struct dsi_cmd_desc *cmds, int rlen)
{
- int cnt, len, diff, pkt_size;
+ int cnt, len, diff, pkt_size, rc = 0;
char cmd;
if (pdata->panel_info.mipi.no_max_pkt_size)
@@ -618,7 +625,13 @@
max_pktsize[0] = pkt_size;
dsi_buf_init(tp);
dsi_cmd_dma_add(tp, pkt_size_cmd);
- msm_dsi_cmd_dma_tx(tp);
+ rc = msm_dsi_cmd_dma_tx(tp);
+ if (IS_ERR_VALUE(rc)) {
+ msm_dsi_disable_irq();
+ pr_err("%s: dma_tx failed\n", __func__);
+ rp->len = 0;
+ goto end;
+ }
pr_debug("%s: Max packet size sent\n", __func__);
}
@@ -627,6 +640,12 @@
/* transmit read comamnd to client */
msm_dsi_cmd_dma_tx(tp);
+ if (IS_ERR_VALUE(rc)) {
+ msm_dsi_disable_irq();
+ pr_err("%s: dma_tx failed\n", __func__);
+ rp->len = 0;
+ goto end;
+ }
/*
* once cmd_dma_done interrupt received,
* return data from client is ready and stored
@@ -680,6 +699,7 @@
break;
}
+end:
return rp->len;
}
diff --git a/drivers/video/msm/mdss/mdp3.c b/drivers/video/msm/mdss/mdp3.c
index 6121c03..8a5f1ee 100644
--- a/drivers/video/msm/mdss/mdp3.c
+++ b/drivers/video/msm/mdss/mdp3.c
@@ -15,6 +15,7 @@
#include <linux/clk.h>
#include <linux/debugfs.h>
+#include <linux/dma-buf.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/interrupt.h>
@@ -120,8 +121,19 @@
};
struct mdp3_iommu_domain_map mdp3_iommu_domains[MDP3_IOMMU_DOMAIN_MAX] = {
- [MDP3_IOMMU_DOMAIN] = {
- .domain_type = MDP3_IOMMU_DOMAIN,
+ [MDP3_PPP_IOMMU_DOMAIN] = {
+ .domain_type = MDP3_PPP_IOMMU_DOMAIN,
+ .client_name = "mdp_ppp",
+ .partitions = {
+ {
+ .start = SZ_128K,
+ .size = SZ_1G - SZ_128K,
+ },
+ },
+ .npartitions = 1,
+ },
+ [MDP3_DMA_IOMMU_DOMAIN] = {
+ .domain_type = MDP3_DMA_IOMMU_DOMAIN,
.client_name = "mdp_dma",
.partitions = {
{
@@ -136,27 +148,27 @@
struct mdp3_iommu_ctx_map mdp3_iommu_contexts[MDP3_IOMMU_CTX_MAX] = {
[MDP3_IOMMU_CTX_PPP_0] = {
.ctx_type = MDP3_IOMMU_CTX_PPP_0,
- .domain = &mdp3_iommu_domains[MDP3_IOMMU_DOMAIN],
+ .domain = &mdp3_iommu_domains[MDP3_PPP_IOMMU_DOMAIN],
.ctx_name = "mdpe_0",
.attached = 0,
},
[MDP3_IOMMU_CTX_PPP_1] = {
.ctx_type = MDP3_IOMMU_CTX_PPP_1,
- .domain = &mdp3_iommu_domains[MDP3_IOMMU_DOMAIN],
+ .domain = &mdp3_iommu_domains[MDP3_PPP_IOMMU_DOMAIN],
.ctx_name = "mdpe_1",
.attached = 0,
},
[MDP3_IOMMU_CTX_DMA_0] = {
.ctx_type = MDP3_IOMMU_CTX_DMA_0,
- .domain = &mdp3_iommu_domains[MDP3_IOMMU_DOMAIN],
+ .domain = &mdp3_iommu_domains[MDP3_DMA_IOMMU_DOMAIN],
.ctx_name = "mdps_0",
.attached = 0,
},
[MDP3_IOMMU_CTX_DMA_1] = {
.ctx_type = MDP3_IOMMU_CTX_DMA_1,
- .domain = &mdp3_iommu_domains[MDP3_IOMMU_DOMAIN],
+ .domain = &mdp3_iommu_domains[MDP3_DMA_IOMMU_DOMAIN],
.ctx_name = "mdps_1",
.attached = 0,
},
@@ -685,6 +697,8 @@
{
int ret;
+ mutex_init(&mdp3_res->iommu_lock);
+
ret = mdp3_iommu_domain_init();
if (ret) {
pr_err("mdp3 iommu domain init fails\n");
@@ -1032,17 +1046,335 @@
return 0;
}
-int mdp3_put_img(struct mdp3_img_data *data)
+static void mdp3_iommu_heap_unmap_iommu(struct mdp3_iommu_meta *meta)
+{
+ unsigned int domain_num;
+ unsigned int partition_num = 0;
+ struct iommu_domain *domain;
+
+ domain_num = (mdp3_res->domains + MDP3_PPP_IOMMU_DOMAIN)->domain_idx;
+ domain = msm_get_iommu_domain(domain_num);
+
+ if (!domain) {
+ pr_err("Could not get domain %d. Corruption?\n", domain_num);
+ return;
+ }
+
+ iommu_unmap_range(domain, meta->iova_addr, meta->mapped_size);
+ msm_free_iova_address(meta->iova_addr, domain_num, partition_num,
+ meta->mapped_size);
+
+ return;
+}
+
+static void mdp3_iommu_meta_destroy(struct kref *kref)
+{
+ struct mdp3_iommu_meta *meta =
+ container_of(kref, struct mdp3_iommu_meta, ref);
+
+ rb_erase(&meta->node, &mdp3_res->iommu_root);
+ mdp3_iommu_heap_unmap_iommu(meta);
+ dma_buf_put(meta->dbuf);
+ kfree(meta);
+}
+
+
+static void mdp3_iommu_meta_put(struct mdp3_iommu_meta *meta)
+{
+ /* Need to lock here to prevent race against map/unmap */
+ mutex_lock(&mdp3_res->iommu_lock);
+ kref_put(&meta->ref, mdp3_iommu_meta_destroy);
+ mutex_unlock(&mdp3_res->iommu_lock);
+}
+
+static struct mdp3_iommu_meta *mdp3_iommu_meta_lookup(struct sg_table *table)
+{
+ struct rb_root *root = &mdp3_res->iommu_root;
+ struct rb_node **p = &root->rb_node;
+ struct rb_node *parent = NULL;
+ struct mdp3_iommu_meta *entry = NULL;
+
+ while (*p) {
+ parent = *p;
+ entry = rb_entry(parent, struct mdp3_iommu_meta, node);
+
+ if (table < entry->table)
+ p = &(*p)->rb_left;
+ else if (table > entry->table)
+ p = &(*p)->rb_right;
+ else
+ return entry;
+ }
+ return NULL;
+}
+
+void mdp3_unmap_iommu(struct ion_client *client, struct ion_handle *handle)
+{
+ struct mdp3_iommu_meta *meta;
+ struct sg_table *table;
+
+ table = ion_sg_table(client, handle);
+
+ mutex_lock(&mdp3_res->iommu_lock);
+ meta = mdp3_iommu_meta_lookup(table);
+ if (!meta) {
+ WARN(1, "%s: buffer was never mapped for %p\n", __func__,
+ handle);
+ mutex_unlock(&mdp3_res->iommu_lock);
+ goto out;
+ }
+ mutex_unlock(&mdp3_res->iommu_lock);
+
+ mdp3_iommu_meta_put(meta);
+out:
+ return;
+}
+
+static void mdp3_iommu_meta_add(struct mdp3_iommu_meta *meta)
+{
+ struct rb_root *root = &mdp3_res->iommu_root;
+ struct rb_node **p = &root->rb_node;
+ struct rb_node *parent = NULL;
+ struct mdp3_iommu_meta *entry;
+
+ while (*p) {
+ parent = *p;
+ entry = rb_entry(parent, struct mdp3_iommu_meta, node);
+
+ if (meta->table < entry->table) {
+ p = &(*p)->rb_left;
+ } else if (meta->table > entry->table) {
+ p = &(*p)->rb_right;
+ } else {
+ pr_err("%s: handle %p already exists\n", __func__,
+ entry->handle);
+ BUG();
+ }
+ }
+
+ rb_link_node(&meta->node, parent, p);
+ rb_insert_color(&meta->node, root);
+}
+
+static int mdp3_iommu_map_iommu(struct mdp3_iommu_meta *meta,
+ unsigned long align, unsigned long iova_length,
+ unsigned int padding, unsigned long flags)
+{
+ struct iommu_domain *domain;
+ int ret = 0;
+ unsigned long size;
+ unsigned long unmap_size;
+ struct sg_table *table;
+ int prot = IOMMU_WRITE | IOMMU_READ;
+ unsigned int domain_num = (mdp3_res->domains +
+ MDP3_PPP_IOMMU_DOMAIN)->domain_idx;
+ unsigned int partition_num = 0;
+
+ size = meta->size;
+ table = meta->table;
+
+ /* Use the biggest alignment to allow bigger IOMMU mappings.
+ * Use the first entry since the first entry will always be the
+ * biggest entry. To take advantage of bigger mapping sizes both the
+ * VA and PA addresses have to be aligned to the biggest size.
+ */
+ if (sg_dma_len(table->sgl) > align)
+ align = sg_dma_len(table->sgl);
+
+ ret = msm_allocate_iova_address(domain_num, partition_num,
+ meta->mapped_size, align, &meta->iova_addr);
+
+ if (ret)
+ goto out;
+
+ domain = msm_get_iommu_domain(domain_num);
+
+ if (!domain) {
+ ret = -ENOMEM;
+ goto out1;
+ }
+
+ /* Adding padding to before buffer */
+ if (padding) {
+ unsigned long phys_addr = sg_phys(table->sgl);
+ ret = msm_iommu_map_extra(domain, meta->iova_addr, phys_addr,
+ padding, SZ_4K, prot);
+ if (ret)
+ goto out1;
+ }
+
+ /* Mapping actual buffer */
+ ret = iommu_map_range(domain, meta->iova_addr + padding,
+ table->sgl, size, prot);
+ if (ret) {
+ pr_err("%s: could not map %lx in domain %p\n",
+ __func__, meta->iova_addr, domain);
+ unmap_size = padding;
+ goto out2;
+ }
+
+ /* Adding padding to end of buffer */
+ if (padding) {
+ unsigned long phys_addr = sg_phys(table->sgl);
+ unsigned long extra_iova_addr = meta->iova_addr +
+ padding + size;
+ ret = msm_iommu_map_extra(domain, extra_iova_addr, phys_addr,
+ padding, SZ_4K, prot);
+ if (ret) {
+ unmap_size = padding + size;
+ goto out2;
+ }
+ }
+ return ret;
+
+out2:
+ iommu_unmap_range(domain, meta->iova_addr, unmap_size);
+out1:
+ msm_free_iova_address(meta->iova_addr, domain_num, partition_num,
+ iova_length);
+
+out:
+ return ret;
+}
+
+static struct mdp3_iommu_meta *mdp3_iommu_meta_create(struct ion_client *client,
+ struct ion_handle *handle, struct sg_table *table, unsigned long size,
+ unsigned long align, unsigned long iova_length, unsigned int padding,
+ unsigned long flags, unsigned long *iova)
+{
+ struct mdp3_iommu_meta *meta;
+ int ret;
+
+ meta = kzalloc(sizeof(*meta), GFP_KERNEL);
+
+ if (!meta)
+ return ERR_PTR(-ENOMEM);
+
+ meta->handle = handle;
+ meta->table = table;
+ meta->size = size;
+ meta->mapped_size = iova_length;
+ meta->dbuf = ion_share_dma_buf(client, handle);
+ kref_init(&meta->ref);
+
+ ret = mdp3_iommu_map_iommu(meta,
+ align, iova_length, padding, flags);
+ if (ret < 0) {
+ pr_err("%s: Unable to map buffer\n", __func__);
+ goto out;
+ }
+
+ *iova = meta->iova_addr;
+ mdp3_iommu_meta_add(meta);
+
+ return meta;
+out:
+ kfree(meta);
+ return ERR_PTR(ret);
+}
+
+/*
+ * PPP hw reads in tiles of 16 which might be outside mapped region
+ * need to map buffers ourseleve to add extra padding
+ */
+int mdp3_self_map_iommu(struct ion_client *client, struct ion_handle *handle,
+ unsigned long align, unsigned long padding, unsigned long *iova,
+ unsigned long *buffer_size, unsigned long flags,
+ unsigned long iommu_flags)
+{
+ struct mdp3_iommu_meta *iommu_meta = NULL;
+ struct sg_table *table;
+ struct scatterlist *sg;
+ unsigned long size = 0, iova_length = 0;
+ int ret = 0;
+ int i;
+
+ table = ion_sg_table(client, handle);
+ if (IS_ERR_OR_NULL(table))
+ return PTR_ERR(table);
+
+ for_each_sg(table->sgl, sg, table->nents, i)
+ size += sg_dma_len(sg);
+
+ padding = PAGE_ALIGN(padding);
+
+ /* Adding 16 lines padding before and after buffer */
+ iova_length = size + 2 * padding;
+
+ if (size & ~PAGE_MASK) {
+ pr_debug("%s: buffer size %lx is not aligned to %lx", __func__,
+ size, PAGE_SIZE);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (iova_length & ~PAGE_MASK) {
+ pr_debug("%s: iova_length %lx is not aligned to %lx", __func__,
+ iova_length, PAGE_SIZE);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ mutex_lock(&mdp3_res->iommu_lock);
+ iommu_meta = mdp3_iommu_meta_lookup(table);
+
+ if (!iommu_meta) {
+ iommu_meta = mdp3_iommu_meta_create(client, handle, table, size,
+ align, iova_length, padding, flags, iova);
+ if (!IS_ERR_OR_NULL(iommu_meta)) {
+ iommu_meta->flags = iommu_flags;
+ ret = 0;
+ } else {
+ ret = PTR_ERR(iommu_meta);
+ goto out_unlock;
+ }
+ } else {
+ if (iommu_meta->flags != iommu_flags) {
+ pr_err("%s: handle %p is already mapped with diff flag\n",
+ __func__, handle);
+ ret = -EINVAL;
+ goto out_unlock;
+ } else if (iommu_meta->mapped_size != iova_length) {
+ pr_err("%s: handle %p is already mapped with diff len\n",
+ __func__, handle);
+ ret = -EINVAL;
+ goto out_unlock;
+ } else {
+ kref_get(&iommu_meta->ref);
+ *iova = iommu_meta->iova_addr;
+ }
+ }
+ BUG_ON(iommu_meta->size != size);
+ mutex_unlock(&mdp3_res->iommu_lock);
+
+ *iova = *iova + padding;
+ *buffer_size = size;
+ return ret;
+
+out_unlock:
+ mutex_unlock(&mdp3_res->iommu_lock);
+out:
+ mdp3_iommu_meta_put(iommu_meta);
+ return ret;
+}
+
+int mdp3_put_img(struct mdp3_img_data *data, int client)
{
struct ion_client *iclient = mdp3_res->ion_client;
- int dom = (mdp3_res->domains + MDP3_IOMMU_DOMAIN)->domain_idx;
+ int dom;
if (data->flags & MDP_MEMORY_ID_TYPE_FB) {
pr_info("mdp3_put_img fb mem buf=0x%x\n", data->addr);
fput_light(data->srcp_file, data->p_need);
data->srcp_file = NULL;
} else if (!IS_ERR_OR_NULL(data->srcp_ihdl)) {
- ion_unmap_iommu(iclient, data->srcp_ihdl, dom, 0);
+ if (client == MDP3_CLIENT_DMA_P) {
+ dom = (mdp3_res->domains +
+ MDP3_DMA_IOMMU_DOMAIN)->domain_idx;
+ ion_unmap_iommu(iclient, data->srcp_ihdl, dom, 0);
+ } else {
+ mdp3_unmap_iommu(iclient, data->srcp_ihdl);
+ }
ion_free(iclient, data->srcp_ihdl);
data->srcp_ihdl = NULL;
} else {
@@ -1051,14 +1383,15 @@
return 0;
}
-int mdp3_get_img(struct msmfb_data *img, struct mdp3_img_data *data)
+int mdp3_get_img(struct msmfb_data *img, struct mdp3_img_data *data,
+ int client)
{
struct file *file;
int ret = -EINVAL;
int fb_num;
unsigned long *start, *len;
struct ion_client *iclient = mdp3_res->ion_client;
- int dom = (mdp3_res->domains + MDP3_IOMMU_DOMAIN)->domain_idx;
+ int dom;
start = (unsigned long *) &data->addr;
len = (unsigned long *) &data->len;
@@ -1100,10 +1433,15 @@
data->srcp_ihdl = NULL;
return ret;
}
-
- ret = ion_map_iommu(iclient, data->srcp_ihdl, dom,
- 0, SZ_4K, 0, start, len, 0, 0);
-
+ if (client == MDP3_CLIENT_DMA_P) {
+ dom = (mdp3_res->domains +
+ MDP3_DMA_IOMMU_DOMAIN)->domain_idx;
+ ret = ion_map_iommu(iclient, data->srcp_ihdl, dom,
+ 0, SZ_4K, 0, start, len, 0, 0);
+ } else {
+ ret = mdp3_self_map_iommu(iclient, data->srcp_ihdl,
+ SZ_4K, data->padding, start, len, 0, 0);
+ }
if (IS_ERR_VALUE(ret)) {
ion_free(iclient, data->srcp_ihdl);
pr_err("failed to map ion handle (%d)\n", ret);
@@ -1118,7 +1456,7 @@
pr_debug("mem=%d ihdl=%p buf=0x%x len=0x%x\n", img->memory_id,
data->srcp_ihdl, data->addr, data->len);
} else {
- mdp3_put_img(data);
+ mdp3_put_img(data, client);
return -EINVAL;
}
@@ -1288,7 +1626,7 @@
{
if (!mdp3_res)
return -ENODEV;
- return mdp3_res->domains[MDP3_IOMMU_DOMAIN].domain_idx;
+ return mdp3_res->domains[MDP3_DMA_IOMMU_DOMAIN].domain_idx;
}
int mdp3_continuous_splash_copy(struct mdss_panel_data *pdata)
diff --git a/drivers/video/msm/mdss/mdp3.h b/drivers/video/msm/mdss/mdp3.h
index 3f081ba..2f73c42 100644
--- a/drivers/video/msm/mdss/mdp3.h
+++ b/drivers/video/msm/mdss/mdp3.h
@@ -41,8 +41,9 @@
};
enum {
- MDP3_IOMMU_DOMAIN,
- MDP3_IOMMU_DOMAIN_MAX
+ MDP3_DMA_IOMMU_DOMAIN,
+ MDP3_PPP_IOMMU_DOMAIN,
+ MDP3_IOMMU_DOMAIN_MAX,
};
enum {
@@ -58,6 +59,12 @@
MDP3_CLIENT_PPP,
};
+enum {
+ DI_PARTITION_NUM = 0,
+ DI_DOMAIN_NUM = 1,
+ DI_MAX,
+};
+
struct mdp3_bus_handle_map {
struct msm_bus_vectors *bus_vector;
struct msm_bus_paths *usecases;
@@ -83,6 +90,19 @@
int attached;
};
+struct mdp3_iommu_meta {
+ struct rb_node node;
+ struct ion_handle *handle;
+ struct rb_root iommu_maps;
+ struct kref ref;
+ struct sg_table *table;
+ struct dma_buf *dbuf;
+ int mapped_size;
+ unsigned long size;
+ unsigned long iova_addr;
+ unsigned long flags;
+};
+
#define MDP3_MAX_INTR 28
struct mdp3_intr_cb {
@@ -111,6 +131,8 @@
struct mdp3_iommu_domain_map *domains;
struct mdp3_iommu_ctx_map *iommu_contexts;
struct ion_handle *ion_handle;
+ struct mutex iommu_lock;
+ struct rb_root iommu_root;
void *virt;
unsigned long phys;
size_t size;
@@ -132,6 +154,7 @@
struct mdp3_img_data {
u32 addr;
u32 len;
+ u32 padding;
u32 flags;
int p_need;
struct file *srcp_file;
@@ -151,8 +174,9 @@
int mdp3_clk_set_rate(int clk_type, unsigned long clk_rate, int client);
int mdp3_clk_enable(int enable);
int mdp3_bus_scale_set_quota(int client, u64 ab_quota, u64 ib_quota);
-int mdp3_put_img(struct mdp3_img_data *data);
-int mdp3_get_img(struct msmfb_data *img, struct mdp3_img_data *data);
+int mdp3_put_img(struct mdp3_img_data *data, int client);
+int mdp3_get_img(struct msmfb_data *img, struct mdp3_img_data *data,
+ int client);
int mdp3_iommu_enable(int client);
int mdp3_iommu_disable(int client);
int mdp3_iommu_is_attached(int client);
diff --git a/drivers/video/msm/mdss/mdp3_ctrl.c b/drivers/video/msm/mdss/mdp3_ctrl.c
index 341c98f..bf5b643 100644
--- a/drivers/video/msm/mdss/mdp3_ctrl.c
+++ b/drivers/video/msm/mdss/mdp3_ctrl.c
@@ -50,7 +50,7 @@
while (count--) {
struct mdp3_img_data *data = &bufq->img_data[bufq->pop_idx];
bufq->pop_idx = (bufq->pop_idx + 1) % MDP3_MAX_BUF_QUEUE;
- mdp3_put_img(data);
+ mdp3_put_img(data, MDP3_CLIENT_DMA_P);
}
bufq->count = 0;
bufq->push_idx = 0;
@@ -706,7 +706,7 @@
struct msmfb_data *img = &req->data;
struct mdp3_img_data data;
- rc = mdp3_get_img(img, &data);
+ rc = mdp3_get_img(img, &data, MDP3_CLIENT_DMA_P);
if (rc) {
pr_err("fail to get overlay buffer\n");
return rc;
@@ -715,7 +715,7 @@
rc = mdp3_bufq_push(&mdp3_session->bufq_in, &data);
if (rc) {
pr_err("fail to queue the overlay buffer, buffer drop\n");
- mdp3_put_img(&data);
+ mdp3_put_img(&data, MDP3_CLIENT_DMA_P);
return rc;
}
return 0;
@@ -779,7 +779,7 @@
if (mdp3_bufq_count(&mdp3_session->bufq_out) > 2) {
data = mdp3_bufq_pop(&mdp3_session->bufq_out);
- mdp3_put_img(data);
+ mdp3_put_img(data, MDP3_CLIENT_DMA_P);
}
mutex_unlock(&mdp3_session->lock);
diff --git a/drivers/video/msm/mdss/mdp3_ppp.c b/drivers/video/msm/mdss/mdp3_ppp.c
index 6de4d8c..9a42810 100644
--- a/drivers/video/msm/mdss/mdp3_ppp.c
+++ b/drivers/video/msm/mdss/mdp3_ppp.c
@@ -119,11 +119,22 @@
struct mdp3_img_data *data)
{
struct msmfb_data fb_data;
+ uint32_t stride;
+ int bpp = ppp_bpp(img->format);
+
+ if (bpp <= 0) {
+ pr_err("%s incorrect format %d\n", __func__, img->format);
+ return -EINVAL;
+ }
+
fb_data.flags = img->priv;
fb_data.memory_id = img->memory_id;
fb_data.offset = 0;
- return mdp3_get_img(&fb_data, data);
+ stride = img->width * bpp;
+ data->padding = 16 * stride;
+
+ return mdp3_get_img(&fb_data, data, MDP3_CLIENT_PPP);
}
/* Check format */
@@ -950,8 +961,10 @@
&req->src_data[i],
&req->dst_data[i]);
}
- mdp3_put_img(&req->src_data[i]);
- mdp3_put_img(&req->dst_data[i]);
+ mdp3_put_img(&req->src_data[i],
+ MDP3_CLIENT_PPP);
+ mdp3_put_img(&req->dst_data[i],
+ MDP3_CLIENT_PPP);
}
}
/* Signal to release fence */
@@ -1022,7 +1035,7 @@
rc = mdp3_ppp_get_img(&req->req_list[i].dst,
&req->req_list[i], &req->dst_data[i]);
if (rc < 0 || req->dst_data[i].len == 0) {
- mdp3_put_img(&req->src_data[i]);
+ mdp3_put_img(&req->src_data[i], MDP3_CLIENT_PPP);
pr_err("mdp_ppp: couldn't retrieve dest img from mem\n");
goto parse_err_1;
}
@@ -1065,8 +1078,8 @@
put_unused_fd(req->cur_rel_fen_fd);
parse_err_1:
for (i--; i >= 0; i--) {
- mdp3_put_img(&req->src_data[i]);
- mdp3_put_img(&req->dst_data[i]);
+ mdp3_put_img(&req->src_data[i], MDP3_CLIENT_PPP);
+ mdp3_put_img(&req->dst_data[i], MDP3_CLIENT_PPP);
}
mdp3_ppp_deinit_buf_sync(req);
mutex_unlock(&ppp_stat->req_mutex);
diff --git a/drivers/video/msm/mdss/mdp3_ppp_hwio.c b/drivers/video/msm/mdss/mdp3_ppp_hwio.c
index 199387f..a051037 100644
--- a/drivers/video/msm/mdss/mdp3_ppp_hwio.c
+++ b/drivers/video/msm/mdss/mdp3_ppp_hwio.c
@@ -361,38 +361,6 @@
return rgb;
}
-uint8_t *mdp_bg_adjust_rot_addr(struct ppp_blit_op *iBuf,
- uint8_t *addr, uint32_t bpp, uint32_t uv)
-{
- uint32_t dest_ystride = iBuf->bg.prop.width * bpp;
- uint32_t h_slice = 1, min_val;
-
- if (uv && ((iBuf->bg.color_fmt == MDP_Y_CBCR_H2V2) ||
- (iBuf->bg.color_fmt == MDP_Y_CRCB_H2V2)))
- h_slice = 2;
-
- if (((iBuf->mdp_op & MDPOP_ROT90) == MDPOP_ROT90) ^
- ((iBuf->mdp_op & MDPOP_LR) == MDPOP_LR)) {
- min_val = (iBuf->bg.roi.width + iBuf->bg.roi.x) % 16;
- if (!min_val)
- min_val = 16;
- addr +=
- (iBuf->bg.roi.width -
- MIN(min_val, iBuf->bg.roi.width)) * bpp;
- }
- if ((iBuf->mdp_op & MDPOP_UD) == MDPOP_UD) {
- min_val = (iBuf->bg.roi.height + iBuf->bg.roi.y) % 16;
- if (!min_val)
- min_val = 16;
- addr +=
- ((iBuf->bg.roi.height -
- MIN(min_val, iBuf->bg.roi.height))/h_slice) *
- dest_ystride;
- }
-
- return addr;
-}
-
uint8_t *mdp_dst_adjust_rot_addr(struct ppp_blit_op *iBuf,
uint8_t *addr, uint32_t bpp, uint32_t uv)
{
@@ -434,9 +402,7 @@
img->p0 += (x + y * ALIGN(width, 128)) * bpp;
else
img->p0 += (x + y * width) * bpp;
- if (layer == 1)
- img->p0 = mdp_bg_adjust_rot_addr(blit_op, img->p0, bpp, 0);
- else if (layer == 2)
+ if (layer != 0)
img->p0 = mdp_dst_adjust_rot_addr(blit_op, img->p0, bpp, 0);
if (img->p1) {
@@ -454,13 +420,9 @@
img->p1 += ((x / h_slice) * h_slice +
((y == 0) ? 0 : ((y + 1) / v_slice - 1) * width)) * bpp;
- if (layer == 1) {
- img->p0 = mdp_bg_adjust_rot_addr(blit_op,
- img->p0, bpp, 0);
- } else if (layer == 2) {
+ if (layer != 0)
img->p0 = mdp_dst_adjust_rot_addr(blit_op,
img->p0, bpp, 0);
- }
}
}
diff --git a/drivers/video/msm/mdss/mdss_dsi.h b/drivers/video/msm/mdss/mdss_dsi.h
index ec21db2..2d63532 100644
--- a/drivers/video/msm/mdss/mdss_dsi.h
+++ b/drivers/video/msm/mdss/mdss_dsi.h
@@ -323,6 +323,7 @@
struct clk *esc_clk;
struct clk *pixel_clk;
u8 ctrl_state;
+ int panel_mode;
int irq_cnt;
int mdss_dsi_clk_on;
int rst_gpio;
diff --git a/drivers/video/msm/mdss/mdss_dsi_host.c b/drivers/video/msm/mdss/mdss_dsi_host.c
index e48d0d2..62bc7e6 100644
--- a/drivers/video/msm/mdss/mdss_dsi_host.c
+++ b/drivers/video/msm/mdss/mdss_dsi_host.c
@@ -25,6 +25,8 @@
#include "mdss.h"
#include "mdss_dsi.h"
+#define VSYNC_PERIOD 17
+
static struct mdss_dsi_ctrl_pdata *left_ctrl_pdata;
static struct mdss_dsi_ctrl_pdata *ctrl_list[DSI_CTRL_MAX];
@@ -766,6 +768,8 @@
pinfo->rgb_swap = DSI_RGB_SWAP_RGB;
+ ctrl_pdata->panel_mode = pinfo->mode;
+
if (pinfo->mode == DSI_VIDEO_MODE) {
data = 0;
if (pinfo->pulse_mode_hsa_he)
@@ -1135,6 +1139,8 @@
return 4;
}
+static int mdss_dsi_wait4video_eng_busy(struct mdss_dsi_ctrl_pdata *ctrl);
+
static int mdss_dsi_cmd_dma_tx(struct mdss_dsi_ctrl_pdata *ctrl,
struct dsi_buf *tp);
@@ -1147,7 +1153,7 @@
struct dsi_buf *tp;
struct dsi_cmd_desc *cm;
struct dsi_ctrl_hdr *dchdr;
- int len, tot = 0;
+ int len, wait, tot = 0;
tp = &ctrl->tx_buf;
mdss_dsi_buf_init(tp);
@@ -1164,6 +1170,9 @@
tot += len;
if (dchdr->last) {
tp->data = tp->start; /* begin of buf */
+
+ wait = mdss_dsi_wait4video_eng_busy(ctrl);
+
mdss_dsi_enable_irq(ctrl, DSI_CMD_TERM);
len = mdss_dsi_cmd_dma_tx(ctrl, tp);
if (IS_ERR_VALUE(len)) {
@@ -1172,7 +1181,8 @@
__func__, cmds->payload[0]);
return -EINVAL;
}
- if (dchdr->wait)
+
+ if (!wait || dchdr->wait > VSYNC_PERIOD)
usleep(dchdr->wait * 1000);
mdss_dsi_buf_init(tp);
@@ -1357,6 +1367,9 @@
rp->len = 0;
goto end;
}
+
+ mdss_dsi_wait4video_eng_busy(ctrl);
+
mdss_dsi_enable_irq(ctrl, DSI_CMD_TERM);
ret = mdss_dsi_cmd_dma_tx(ctrl, tp);
if (IS_ERR_VALUE(ret)) {
@@ -1377,6 +1390,8 @@
goto end;
}
+ mdss_dsi_wait4video_eng_busy(ctrl);
+
mdss_dsi_enable_irq(ctrl, DSI_CMD_TERM);
/* transmit read comamnd to client */
ret = mdss_dsi_cmd_dma_tx(ctrl, tp);
@@ -1541,7 +1556,6 @@
return rlen;
}
-#define VSYNC_PERIOD 17
void mdss_dsi_wait4video_done(struct mdss_dsi_ctrl_pdata *ctrl)
{
@@ -1567,11 +1581,21 @@
MIPI_OUTP((ctrl->ctrl_base) + 0x0110, data);
}
-static void mdss_dsi_wait4video_eng_busy(struct mdss_dsi_ctrl_pdata *ctrl)
+static int mdss_dsi_wait4video_eng_busy(struct mdss_dsi_ctrl_pdata *ctrl)
{
- mdss_dsi_wait4video_done(ctrl);
- /* delay 4 ms to skip BLLP */
- usleep(4000);
+ int ret = 0;
+
+ if (ctrl->panel_mode == DSI_CMD_MODE)
+ return ret;
+
+ if (ctrl->ctrl_state & CTRL_STATE_MDP_ACTIVE) {
+ mdss_dsi_wait4video_done(ctrl);
+ /* delay 4 ms to skip BLLP */
+ usleep(4000);
+ ret = 1;
+ }
+
+ return ret;
}
void mdss_dsi_cmd_mdp_start(struct mdss_dsi_ctrl_pdata *ctrl)
@@ -1638,7 +1662,6 @@
void mdss_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp)
{
struct dcs_cmd_req *req;
- u32 data;
mutex_lock(&ctrl->cmd_mutex);
req = mdss_dsi_cmdlist_get(ctrl);
@@ -1646,26 +1669,14 @@
/* make sure dsi_cmd_mdp is idle */
mdss_dsi_cmd_mdp_busy(ctrl);
+ pr_debug("%s: from_mdp=%d pid=%d\n", __func__, from_mdp, current->pid);
+
if (req == NULL)
goto need_lock;
pr_debug("%s: from_mdp=%d pid=%d\n", __func__, from_mdp, current->pid);
mdss_dsi_clk_ctrl(ctrl, 1);
- data = MIPI_INP((ctrl->ctrl_base) + 0x0004);
- if (data & 0x02) {
- /* video mode, make sure video engine is busy
- * so dcs command will be sent at start of BLLP
- */
- mdss_dsi_wait4video_eng_busy(ctrl);
- } else {
- /* command mode */
- if (!from_mdp) { /* cmdlist_put */
- /* make sure dsi_cmd_mdp is idle */
- mdss_dsi_cmd_mdp_busy(ctrl);
- }
- }
-
if (req->flags & CMD_REQ_RX)
mdss_dsi_cmdlist_rx(ctrl, req);
else
diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
index c79b672..8e805da 100644
--- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
+++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c
@@ -2153,10 +2153,11 @@
mdp5_data->ctl = ctl;
}
- if (!mfd->panel_info->cont_splash_enabled) {
+ if (!mfd->panel_info->cont_splash_enabled &&
+ (mfd->panel_info->type != DTV_PANEL) &&
+ (mfd->panel_info->type != WRITEBACK_PANEL)) {
rc = mdss_mdp_overlay_start(mfd);
- if (!IS_ERR_VALUE(rc) && (mfd->panel_info->type != DTV_PANEL) &&
- (mfd->panel_info->type != WRITEBACK_PANEL))
+ if (!IS_ERR_VALUE(rc))
rc = mdss_mdp_overlay_kickoff(mfd);
} else {
rc = mdss_mdp_ctl_setup(mdp5_data->ctl);
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 38877cc..c9be394 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -403,6 +403,7 @@
#define V4L2_PIX_FMT_DIVX v4l2_fourcc('D', 'I', 'V', 'X') /* DIVX */
#define V4L2_PIX_FMT_VP8 v4l2_fourcc('V', 'P', '8', '0') /* ON2 VP8 stream */
#define V4L2_PIX_FMT_HEVC v4l2_fourcc('H', 'E', 'V', 'C') /* for HEVC stream */
+#define V4L2_PIX_FMT_HEVC_HYBRID v4l2_fourcc('H', 'V', 'C', 'H')
/* Vendor-specific formats */
#define V4L2_PIX_FMT_CPIA1 v4l2_fourcc('C', 'P', 'I', 'A') /* cpia1 YUV */
diff --git a/sound/soc/codecs/wcd9306.c b/sound/soc/codecs/wcd9306.c
index a6ef992..4e07d7f 100644
--- a/sound/soc/codecs/wcd9306.c
+++ b/sound/soc/codecs/wcd9306.c
@@ -48,6 +48,12 @@
/* RX_HPH_CNP_WG_TIME increases by 0.24ms */
#define TAPAN_WG_TIME_FACTOR_US 240
+#define TAPAN_SB_PGD_PORT_RX_BASE 0x40
+#define TAPAN_SB_PGD_PORT_TX_BASE 0x50
+#define TAPAN_REGISTER_START_OFFSET 0x800
+
+#define CODEC_REG_CFG_MINOR_VER 1
+
static struct regulator *tapan_codec_find_regulator(
struct snd_soc_codec *codec,
const char *name);
@@ -106,6 +112,54 @@
*/
#define TAPAN_ZDET_MUL_FACTOR 1852
+static struct afe_param_cdc_reg_cfg audio_reg_cfg[] = {
+ {
+ CODEC_REG_CFG_MINOR_VER,
+ (TAPAN_REGISTER_START_OFFSET + TAPAN_SB_PGD_PORT_TX_BASE),
+ SB_PGD_PORT_TX_WATERMARK_N, 0x1E, 8, 0x1
+ },
+ {
+ CODEC_REG_CFG_MINOR_VER,
+ (TAPAN_REGISTER_START_OFFSET + TAPAN_SB_PGD_PORT_TX_BASE),
+ SB_PGD_PORT_TX_ENABLE_N, 0x1, 8, 0x1
+ },
+ {
+ CODEC_REG_CFG_MINOR_VER,
+ (TAPAN_REGISTER_START_OFFSET + TAPAN_SB_PGD_PORT_RX_BASE),
+ SB_PGD_PORT_RX_WATERMARK_N, 0x1E, 8, 0x1
+ },
+ {
+ CODEC_REG_CFG_MINOR_VER,
+ (TAPAN_REGISTER_START_OFFSET + TAPAN_SB_PGD_PORT_RX_BASE),
+ SB_PGD_PORT_RX_ENABLE_N, 0x1, 8, 0x1
+ },
+ {
+ CODEC_REG_CFG_MINOR_VER,
+ (TAPAN_REGISTER_START_OFFSET + TAPAN_A_CDC_ANC1_IIR_B1_CTL),
+ AANC_FF_GAIN_ADAPTIVE, 0x4, 8, 0
+ },
+ {
+ CODEC_REG_CFG_MINOR_VER,
+ (TAPAN_REGISTER_START_OFFSET + TAPAN_A_CDC_ANC1_IIR_B1_CTL),
+ AANC_FFGAIN_ADAPTIVE_EN, 0x8, 8, 0
+ },
+ {
+ CODEC_REG_CFG_MINOR_VER,
+ (TAPAN_REGISTER_START_OFFSET + TAPAN_A_CDC_ANC1_GAIN_CTL),
+ AANC_GAIN_CONTROL, 0xFF, 8, 0
+ },
+};
+
+static struct afe_param_cdc_reg_cfg_data tapan_audio_reg_cfg = {
+ .num_registers = ARRAY_SIZE(audio_reg_cfg),
+ .reg_data = audio_reg_cfg,
+};
+
+static struct afe_param_id_cdc_aanc_version tapan_cdc_aanc_version = {
+ .cdc_aanc_minor_version = AFE_API_VERSION_CDC_AANC_VERSION,
+ .aanc_hw_version = AANC_HW_BLOCK_VERSION_2,
+};
+
enum {
AIF1_PB = 0,
AIF1_CAP,
@@ -250,6 +304,8 @@
bool spkr_pa_widget_on;
+ struct afe_param_cdc_slimbus_slave_cfg slimbus_slave_cfg;
+
/* resmgr module */
struct wcd9xxx_resmgr resmgr;
/* mbhc module */
@@ -266,6 +322,9 @@
* end of impedance measurement
*/
struct list_head reg_save_restore;
+
+ int (*machine_codec_event_cb)(struct snd_soc_codec *codec,
+ enum wcd9xxx_codec_event);
};
static const u32 comp_shift[] = {
@@ -2964,6 +3023,9 @@
static int tapan_volatile(struct snd_soc_codec *ssc, unsigned int reg)
{
+
+ int i = 0;
+
/* Registers lower than 0x100 are top level registers which can be
* written by the Tapan core driver.
*/
@@ -2997,6 +3059,11 @@
if (reg == TAPAN_A_MBHC_INSERT_DET_STATUS)
return 1;
+ for (i = 0; i < ARRAY_SIZE(audio_reg_cfg); i++)
+ if (audio_reg_cfg[i].reg_logical_addr -
+ TAPAN_REGISTER_START_OFFSET == reg)
+ return 1;
+
return 0;
}
@@ -4822,6 +4889,46 @@
{TAPAN_A_RX_HPH_CHOP_CTL, 0xFF, 0x24},
};
+void *tapan_get_afe_config(struct snd_soc_codec *codec,
+ enum afe_config_type config_type)
+{
+ struct tapan_priv *priv = snd_soc_codec_get_drvdata(codec);
+
+ switch (config_type) {
+ case AFE_SLIMBUS_SLAVE_CONFIG:
+ return &priv->slimbus_slave_cfg;
+ case AFE_CDC_REGISTERS_CONFIG:
+ return &tapan_audio_reg_cfg;
+ case AFE_AANC_VERSION:
+ return &tapan_cdc_aanc_version;
+ default:
+ pr_err("%s: Unknown config_type 0x%x\n", __func__, config_type);
+ return NULL;
+ }
+}
+
+static void tapan_init_slim_slave_cfg(struct snd_soc_codec *codec)
+{
+ struct tapan_priv *priv = snd_soc_codec_get_drvdata(codec);
+ struct afe_param_cdc_slimbus_slave_cfg *cfg;
+ struct wcd9xxx *wcd9xxx = codec->control_data;
+ uint64_t eaddr = 0;
+
+ pr_debug("%s\n", __func__);
+ cfg = &priv->slimbus_slave_cfg;
+ cfg->minor_version = 1;
+ cfg->tx_slave_port_offset = 0;
+ cfg->rx_slave_port_offset = 16;
+
+ memcpy(&eaddr, &wcd9xxx->slim->e_addr, sizeof(wcd9xxx->slim->e_addr));
+ /* e-addr is 6-byte elemental address of the device */
+ WARN_ON(sizeof(wcd9xxx->slim->e_addr) != 6);
+ cfg->device_enum_addr_lsw = eaddr & 0xFFFFFFFF;
+ cfg->device_enum_addr_msw = eaddr >> 32;
+
+ pr_debug("%s: slimbus logical address 0x%llx\n", __func__, eaddr);
+}
+
static void tapan_codec_init_reg(struct snd_soc_codec *codec)
{
u32 i;
@@ -5209,6 +5316,16 @@
}
EXPORT_SYMBOL(tapan_hs_detect_exit);
+void tapan_event_register(
+ int (*machine_event_cb)(struct snd_soc_codec *codec,
+ enum wcd9xxx_codec_event),
+ struct snd_soc_codec *codec)
+{
+ struct tapan_priv *tapan = snd_soc_codec_get_drvdata(codec);
+ tapan->machine_codec_event_cb = machine_event_cb;
+}
+EXPORT_SYMBOL(tapan_event_register);
+
static int tapan_device_down(struct wcd9xxx *wcd9xxx)
{
struct snd_soc_codec *codec;
@@ -5278,6 +5395,8 @@
if (ret)
pr_err("%s: Failed to setup irq: %d\n", __func__, ret);
+ tapan->machine_codec_event_cb(codec, WCD9XXX_CODEC_EVENT_CODEC_UP);
+
mutex_unlock(&codec->mutex);
return ret;
}
@@ -5523,6 +5642,7 @@
INIT_LIST_HEAD(&tapan->dai[i].wcd9xxx_ch_list);
init_waitqueue_head(&tapan->dai[i].dai_wait);
}
+ tapan_init_slim_slave_cfg(codec);
}
if (codec_ver == WCD9306) {
diff --git a/sound/soc/codecs/wcd9306.h b/sound/soc/codecs/wcd9306.h
index c4788cc..07b2175 100644
--- a/sound/soc/codecs/wcd9306.h
+++ b/sound/soc/codecs/wcd9306.h
@@ -14,9 +14,11 @@
#include <sound/soc.h>
#include <sound/jack.h>
+#include <sound/apr_audio-v2.h>
#include <linux/mfd/wcd9xxx/wcd9xxx-slimslave.h>
#include "wcd9xxx-mbhc.h"
#include "wcd9xxx-resmgr.h"
+#include "wcd9xxx-common.h"
#define TAPAN_NUM_REGISTERS 0x400
#define TAPAN_MAX_REGISTER (TAPAN_NUM_REGISTERS-1)
@@ -77,5 +79,10 @@
bool dapm);
extern int tapan_hs_detect(struct snd_soc_codec *codec,
struct wcd9xxx_mbhc_config *mbhc_cfg);
-
+extern void *tapan_get_afe_config(struct snd_soc_codec *codec,
+ enum afe_config_type config_type);
+extern void tapan_event_register(
+ int (*machine_event_cb)(struct snd_soc_codec *codec,
+ enum wcd9xxx_codec_event),
+ struct snd_soc_codec *codec);
#endif
diff --git a/sound/soc/codecs/wcd9320.c b/sound/soc/codecs/wcd9320.c
index e52eb9d..4ce9b4a 100644
--- a/sound/soc/codecs/wcd9320.c
+++ b/sound/soc/codecs/wcd9320.c
@@ -72,63 +72,6 @@
.num_channels = 1
};
-enum {
- RESERVED = 0,
- AANC_LPF_FF_FB = 1,
- AANC_LPF_COEFF_MSB,
- AANC_LPF_COEFF_LSB,
- HW_MAD_AUDIO_ENABLE,
- HW_MAD_ULTR_ENABLE,
- HW_MAD_BEACON_ENABLE,
- HW_MAD_AUDIO_SLEEP_TIME,
- HW_MAD_ULTR_SLEEP_TIME,
- HW_MAD_BEACON_SLEEP_TIME,
- HW_MAD_TX_AUDIO_SWITCH_OFF,
- HW_MAD_TX_ULTR_SWITCH_OFF,
- HW_MAD_TX_BEACON_SWITCH_OFF,
- MAD_AUDIO_INT_DEST_SELECT_REG,
- MAD_ULT_INT_DEST_SELECT_REG,
- MAD_BEACON_INT_DEST_SELECT_REG,
- MAD_CLIP_INT_DEST_SELECT_REG,
- MAD_VBAT_INT_DEST_SELECT_REG,
- MAD_AUDIO_INT_MASK_REG,
- MAD_ULT_INT_MASK_REG,
- MAD_BEACON_INT_MASK_REG,
- MAD_CLIP_INT_MASK_REG,
- MAD_VBAT_INT_MASK_REG,
- MAD_AUDIO_INT_STATUS_REG,
- MAD_ULT_INT_STATUS_REG,
- MAD_BEACON_INT_STATUS_REG,
- MAD_CLIP_INT_STATUS_REG,
- MAD_VBAT_INT_STATUS_REG,
- MAD_AUDIO_INT_CLEAR_REG,
- MAD_ULT_INT_CLEAR_REG,
- MAD_BEACON_INT_CLEAR_REG,
- MAD_CLIP_INT_CLEAR_REG,
- MAD_VBAT_INT_CLEAR_REG,
- SB_PGD_PORT_TX_WATERMARK_n,
- SB_PGD_PORT_TX_ENABLE_n,
- SB_PGD_PORT_RX_WATERMARK_n,
- SB_PGD_PORT_RX_ENABLE_n,
- SB_PGD_TX_PORTn_MULTI_CHNL_0,
- SB_PGD_TX_PORTn_MULTI_CHNL_1,
- SB_PGD_RX_PORTn_MULTI_CHNL_0,
- SB_PGD_RX_PORTn_MULTI_CHNL_1,
- AANC_FF_GAIN_ADAPTIVE,
- AANC_FFGAIN_ADAPTIVE_EN,
- AANC_GAIN_CONTROL,
- SPKR_CLIP_PIPE_BANK_SEL,
- SPKR_CLIPDET_VAL0,
- SPKR_CLIPDET_VAL1,
- SPKR_CLIPDET_VAL2,
- SPKR_CLIPDET_VAL3,
- SPKR_CLIPDET_VAL4,
- SPKR_CLIPDET_VAL5,
- SPKR_CLIPDET_VAL6,
- SPKR_CLIPDET_VAL7,
- MAX_CFG_REGISTERS,
-};
-
static struct afe_param_cdc_reg_cfg audio_reg_cfg[] = {
{
1,
@@ -168,22 +111,22 @@
{
1,
(TAIKO_REGISTER_START_OFFSET + TAIKO_SB_PGD_PORT_TX_BASE),
- SB_PGD_PORT_TX_WATERMARK_n, 0x1E, 8, 0x1
+ SB_PGD_PORT_TX_WATERMARK_N, 0x1E, 8, 0x1
},
{
1,
(TAIKO_REGISTER_START_OFFSET + TAIKO_SB_PGD_PORT_TX_BASE),
- SB_PGD_PORT_TX_ENABLE_n, 0x1, 8, 0x1
+ SB_PGD_PORT_TX_ENABLE_N, 0x1, 8, 0x1
},
{
1,
(TAIKO_REGISTER_START_OFFSET + TAIKO_SB_PGD_PORT_RX_BASE),
- SB_PGD_PORT_RX_WATERMARK_n, 0x1E, 8, 0x1
+ SB_PGD_PORT_RX_WATERMARK_N, 0x1E, 8, 0x1
},
{
1,
(TAIKO_REGISTER_START_OFFSET + TAIKO_SB_PGD_PORT_RX_BASE),
- SB_PGD_PORT_RX_ENABLE_n, 0x1, 8, 0x1
+ SB_PGD_PORT_RX_ENABLE_N, 0x1, 8, 0x1
},
{ 1,
(TAIKO_REGISTER_START_OFFSET + TAIKO_A_CDC_ANC1_IIR_B1_CTL),
diff --git a/sound/soc/codecs/wcd9xxx-common.h b/sound/soc/codecs/wcd9xxx-common.h
index 9fba8e3..e63d36a 100644
--- a/sound/soc/codecs/wcd9xxx-common.h
+++ b/sound/soc/codecs/wcd9xxx-common.h
@@ -93,4 +93,61 @@
uint8_t value, int delay);
extern void wcd9xxx_restore_registers(struct snd_soc_codec *codec,
struct list_head *lh);
+enum {
+ RESERVED = 0,
+ AANC_LPF_FF_FB = 1,
+ AANC_LPF_COEFF_MSB,
+ AANC_LPF_COEFF_LSB,
+ HW_MAD_AUDIO_ENABLE,
+ HW_MAD_ULTR_ENABLE,
+ HW_MAD_BEACON_ENABLE,
+ HW_MAD_AUDIO_SLEEP_TIME,
+ HW_MAD_ULTR_SLEEP_TIME,
+ HW_MAD_BEACON_SLEEP_TIME,
+ HW_MAD_TX_AUDIO_SWITCH_OFF,
+ HW_MAD_TX_ULTR_SWITCH_OFF,
+ HW_MAD_TX_BEACON_SWITCH_OFF,
+ MAD_AUDIO_INT_DEST_SELECT_REG,
+ MAD_ULT_INT_DEST_SELECT_REG,
+ MAD_BEACON_INT_DEST_SELECT_REG,
+ MAD_CLIP_INT_DEST_SELECT_REG,
+ MAD_VBAT_INT_DEST_SELECT_REG,
+ MAD_AUDIO_INT_MASK_REG,
+ MAD_ULT_INT_MASK_REG,
+ MAD_BEACON_INT_MASK_REG,
+ MAD_CLIP_INT_MASK_REG,
+ MAD_VBAT_INT_MASK_REG,
+ MAD_AUDIO_INT_STATUS_REG,
+ MAD_ULT_INT_STATUS_REG,
+ MAD_BEACON_INT_STATUS_REG,
+ MAD_CLIP_INT_STATUS_REG,
+ MAD_VBAT_INT_STATUS_REG,
+ MAD_AUDIO_INT_CLEAR_REG,
+ MAD_ULT_INT_CLEAR_REG,
+ MAD_BEACON_INT_CLEAR_REG,
+ MAD_CLIP_INT_CLEAR_REG,
+ MAD_VBAT_INT_CLEAR_REG,
+ SB_PGD_PORT_TX_WATERMARK_N,
+ SB_PGD_PORT_TX_ENABLE_N,
+ SB_PGD_PORT_RX_WATERMARK_N,
+ SB_PGD_PORT_RX_ENABLE_N,
+ SB_PGD_TX_PORTn_MULTI_CHNL_0,
+ SB_PGD_TX_PORTn_MULTI_CHNL_1,
+ SB_PGD_RX_PORTn_MULTI_CHNL_0,
+ SB_PGD_RX_PORTn_MULTI_CHNL_1,
+ AANC_FF_GAIN_ADAPTIVE,
+ AANC_FFGAIN_ADAPTIVE_EN,
+ AANC_GAIN_CONTROL,
+ SPKR_CLIP_PIPE_BANK_SEL,
+ SPKR_CLIPDET_VAL0,
+ SPKR_CLIPDET_VAL1,
+ SPKR_CLIPDET_VAL2,
+ SPKR_CLIPDET_VAL3,
+ SPKR_CLIPDET_VAL4,
+ SPKR_CLIPDET_VAL5,
+ SPKR_CLIPDET_VAL6,
+ SPKR_CLIPDET_VAL7,
+ MAX_CFG_REGISTERS,
+};
+
#endif
diff --git a/sound/soc/msm/Kconfig b/sound/soc/msm/Kconfig
index 40661ff..86dd840 100644
--- a/sound/soc/msm/Kconfig
+++ b/sound/soc/msm/Kconfig
@@ -215,6 +215,7 @@
select SND_SOC_MSM_HOSTLESS_PCM
select SND_SOC_WCD9306
select SND_DYNAMIC_MINORS
+ select DOLBY_DAP
help
To add support for SoC audio on MSM8226.
This will enable sound soc drivers which
diff --git a/sound/soc/msm/msm8226.c b/sound/soc/msm/msm8226.c
index 57cd525..9460ec0 100644
--- a/sound/soc/msm/msm8226.c
+++ b/sound/soc/msm/msm8226.c
@@ -17,16 +17,20 @@
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/mfd/pm8xxx/pm8921.h>
+#include <linux/io.h>
#include <sound/core.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
#include <sound/pcm.h>
#include <sound/jack.h>
+#include <sound/q6afe-v2.h>
#include <asm/mach-types.h>
#include <mach/socinfo.h>
+#include <mach/subsystem_notif.h>
#include <qdsp6v2/msm-pcm-routing-v2.h>
+#include "qdsp6v2/q6core.h"
+#include "../codecs/wcd9xxx-common.h"
#include "../codecs/wcd9306.h"
-#include <linux/io.h>
#define DRV_NAME "msm8226-asoc-tapan"
@@ -50,6 +54,10 @@
#define LO_1_SPK_AMP 0x1
#define LO_2_SPK_AMP 0x2
+#define ADSP_STATE_READY_TIMEOUT_MS 3000
+
+static void *adsp_state_notifier;
+
static int msm8226_auxpcm_rate = 8000;
static atomic_t auxpcm_rsc_ref;
static const char *const auxpcm_rate_text[] = {"rate_8000", "rate_16000"};
@@ -336,6 +344,9 @@
SND_SOC_DAPM_MIC("Digital Mic5", NULL),
SND_SOC_DAPM_MIC("Digital Mic6", NULL),
+ SND_SOC_DAPM_MIC("Analog Mic3", NULL),
+ SND_SOC_DAPM_MIC("Analog Mic4", NULL),
+
SND_SOC_DAPM_SPK("Lineout_1 amp", msm8226_ext_spkramp_event),
SND_SOC_DAPM_SPK("Lineout_2 amp", msm8226_ext_spkramp_event),
@@ -696,6 +707,107 @@
msm_proxy_rx_ch_get, msm_proxy_rx_ch_put),
};
+static int msm_afe_set_config(struct snd_soc_codec *codec)
+{
+ int rc;
+ void *config_data;
+
+ pr_debug("%s: enter\n", __func__);
+ config_data = tapan_get_afe_config(codec, AFE_CDC_REGISTERS_CONFIG);
+ rc = afe_set_config(AFE_CDC_REGISTERS_CONFIG, config_data, 0);
+ if (rc) {
+ pr_err("%s: Failed to set codec registers config %d\n",
+ __func__, rc);
+ return rc;
+ }
+ config_data = tapan_get_afe_config(codec, AFE_SLIMBUS_SLAVE_CONFIG);
+ rc = afe_set_config(AFE_SLIMBUS_SLAVE_CONFIG, config_data, 0);
+ if (rc) {
+ pr_err("%s: Failed to set slimbus slave config %d\n", __func__,
+ rc);
+ return rc;
+ }
+ config_data = tapan_get_afe_config(codec, AFE_AANC_VERSION);
+ rc = afe_set_config(AFE_AANC_VERSION, config_data, 0);
+ if (rc) {
+ pr_err("%s: Failed to set AANC version %d\n", __func__,
+ rc);
+ return rc;
+ }
+ return 0;
+}
+
+static void msm_afe_clear_config(void)
+{
+ afe_clear_config(AFE_CDC_REGISTERS_CONFIG);
+ afe_clear_config(AFE_SLIMBUS_SLAVE_CONFIG);
+ afe_clear_config(AFE_AANC_VERSION);
+}
+
+static int msm8226_adsp_state_callback(struct notifier_block *nb,
+ unsigned long value, void *priv)
+{
+ if (value == SUBSYS_BEFORE_SHUTDOWN) {
+ pr_debug("%s: ADSP is about to shutdown. Clearing AFE config\n",
+ __func__);
+ msm_afe_clear_config();
+ } else if (value == SUBSYS_AFTER_POWERUP) {
+ pr_debug("%s: ADSP is up\n", __func__);
+ }
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block adsp_state_notifier_block = {
+ .notifier_call = msm8226_adsp_state_callback,
+ .priority = -INT_MAX,
+};
+
+static int msm8226_tapan_codec_up(struct snd_soc_codec *codec)
+{
+ int err;
+ unsigned long timeout;
+ int adsp_ready = 0;
+
+ pr_debug("%s\n", __func__);
+ timeout = jiffies +
+ msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS);
+
+ do {
+ if (!q6core_is_adsp_ready()) {
+ pr_err("%s: ADSP Audio isn't ready\n", __func__);
+ } else {
+ pr_debug("%s: ADSP Audio is ready\n", __func__);
+ adsp_ready = 1;
+ break;
+ }
+ } while (time_after(timeout, jiffies));
+
+ if (!adsp_ready) {
+ pr_err("%s: timed out waiting for ADSP Audio\n", __func__);
+ return -ETIMEDOUT;
+ }
+
+ err = msm_afe_set_config(codec);
+ if (err)
+ pr_err("%s: Failed to set AFE config. err %d\n",
+ __func__, err);
+ return err;
+}
+
+static int msm8226_tapan_event_cb(struct snd_soc_codec *codec,
+ enum wcd9xxx_codec_event codec_event)
+{
+ switch (codec_event) {
+ case WCD9XXX_CODEC_EVENT_CODEC_UP:
+ return msm8226_tapan_codec_up(codec);
+ default:
+ pr_err("%s: UnSupported codec event %d\n",
+ __func__, codec_event);
+ return -EINVAL;
+ }
+}
+
static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd)
{
int err;
@@ -736,13 +848,37 @@
snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch),
tx_ch, ARRAY_SIZE(rx_ch), rx_ch);
+ err = msm_afe_set_config(codec);
+ if (err) {
+ pr_err("%s: Failed to set AFE config %d\n",
+ __func__, err);
+ return err;
+ }
+
/* start mbhc */
mbhc_cfg.calibration = def_tapan_mbhc_cal();
- if (mbhc_cfg.calibration)
+ if (mbhc_cfg.calibration) {
err = tapan_hs_detect(codec, &mbhc_cfg);
- else
+ } else {
err = -ENOMEM;
+ goto out;
+ }
+ adsp_state_notifier =
+ subsys_notif_register_notifier("adsp",
+ &adsp_state_notifier_block);
+
+ if (!adsp_state_notifier) {
+ pr_err("%s: Failed to register adsp state notifier\n",
+ __func__);
+ err = -EFAULT;
+ goto out;
+ }
+
+ tapan_event_register(msm8226_tapan_event_cb, rtd->codec);
+ return 0;
+
+out:
return err;
}