Merge "diag: Add support for diag dci restart"
diff --git a/Documentation/devicetree/bindings/media/video/msm-camera-flash.txt b/Documentation/devicetree/bindings/media/video/msm-camera-flash.txt
new file mode 100644
index 0000000..72b32be
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/video/msm-camera-flash.txt
@@ -0,0 +1,23 @@
+* Qualcomm MSM CAMERA FLASH
+
+Required properties:
+- cell-index : Should contain flash source index to diffentiate
+ between different flash devices. These indexes represent flash devices
+ for multiple sensors.
+ - 0, 1, 2, 3
+- compatible :
+ - "qcom,camera-led-flash"
+- qcom,flash-type : Should contain type flash device
+ - 1 for LED flash
+ - 2 for strobe flash
+- qcom,flash-source : Should contain array of phandles to flash source nodes.
+ - pm8941_flash0 pm8941_flash1
+
+Example:
+
+qcom,camera-led-flash {
+ cell-index = <0>;
+ compatible = "qcom,camera-led-flash";
+ qcom,flash-type = <1>;
+ qcom,flash-source = <&pm8941_flash0 &pm8941_flash1>;
+};
diff --git a/Documentation/devicetree/bindings/media/video/msm-cci.txt b/Documentation/devicetree/bindings/media/video/msm-cci.txt
index 6b03fab..e256265 100644
--- a/Documentation/devicetree/bindings/media/video/msm-cci.txt
+++ b/Documentation/devicetree/bindings/media/video/msm-cci.txt
@@ -62,9 +62,9 @@
- 1 -> yuv format
Optional properties:
-- qcom,flash-type : should contain flash type if flash is supported for this
- sensor
- - 0 if flash is not supported, 1 if flash is supported
+- qcom,flash-src-index : should contain phandle to flash source node if flash
+ is supported for this sensor
+ - led_flash0, led_flash1
- qcom,mount-angle : should contain the physical mount angle of the sensor on
the target
- 0, 90, 180, 360
diff --git a/Documentation/dvb/qcom-mpq.txt b/Documentation/dvb/qcom-mpq.txt
index 28f5d39..1196da0 100644
--- a/Documentation/dvb/qcom-mpq.txt
+++ b/Documentation/dvb/qcom-mpq.txt
@@ -123,17 +123,15 @@
Background Processing
---------------------
-When demux receives notifications from underlying HW drivers about new
-data, it schedules work to a single-threaded workqueue to process the
-notification.
+Demux allocates a kernel thread for each live-input to process
+the TS packets notified from the HW for specific input. There
+are two such inputs (TSIF0 and TSIF1), both can be processed in
+parallel by two seperate threads.
The processing is the action of demuxing of the new data; it may sleep
as it locks against the demux data-structure that may be accessed by
user-space in the meanwhile.
-A single threaded workqueue exists for each live input (TSIF0 or TSIF1)
-to process the inputs in parallel.
-
Dependencies
------------
The demux driver depends on the following kernel drivers and subsystems:
diff --git a/arch/arm/boot/dts/msm8974-camera-sensor-liquid.dtsi b/arch/arm/boot/dts/msm8974-camera-sensor-liquid.dtsi
index 25f79f8..c9b999f 100644
--- a/arch/arm/boot/dts/msm8974-camera-sensor-liquid.dtsi
+++ b/arch/arm/boot/dts/msm8974-camera-sensor-liquid.dtsi
@@ -19,7 +19,7 @@
reg = <0x6e 0x0>;
qcom,csi-if = <1>;
qcom,csid-core = <0>;
- qcom,flash-type = <0>;
+ qcom,flash-src-index = <&led_flash0>;
qcom,mount-angle = <0>;
qcom,sensor-name = "s5k3l1yx";
cam_vdig-supply = <&pm8941_l3>;
@@ -61,7 +61,6 @@
reg = <0x6c 0x0>;
qcom,csi-if = <1>;
qcom,csid-core = <0>;
- qcom,flash-type = <0>;
qcom,mount-angle = <180>;
qcom,sensor-name = "ov2720";
cam_vdig-supply = <&pm8941_l3>;
diff --git a/arch/arm/boot/dts/msm8974-camera-sensor.dtsi b/arch/arm/boot/dts/msm8974-camera-sensor.dtsi
index d804355..68da844 100644
--- a/arch/arm/boot/dts/msm8974-camera-sensor.dtsi
+++ b/arch/arm/boot/dts/msm8974-camera-sensor.dtsi
@@ -18,7 +18,7 @@
reg = <0x6e 0x0>;
qcom,csi-if = <1>;
qcom,csid-core = <0>;
- qcom,flash-type = <0>;
+ qcom,flash-src-index = <&led_flash0>;
qcom,mount-angle = <90>;
qcom,sensor-name = "s5k3l1yx";
cam_vdig-supply = <&pm8941_l3>;
@@ -60,7 +60,6 @@
reg = <0x6c 0x0>;
qcom,csi-if = <1>;
qcom,csid-core = <0>;
- qcom,flash-type = <0>;
qcom,mount-angle = <180>;
qcom,sensor-name = "ov2720";
cam_vdig-supply = <&pm8941_l3>;
diff --git a/arch/arm/boot/dts/msm8974-camera.dtsi b/arch/arm/boot/dts/msm8974-camera.dtsi
index 4b96811..48dd4dc 100644
--- a/arch/arm/boot/dts/msm8974-camera.dtsi
+++ b/arch/arm/boot/dts/msm8974-camera.dtsi
@@ -165,6 +165,13 @@
vdd-supply = <&gdsc_vfe>;
};
+ led_flash0: qcom,camera-led-flash {
+ cell-index = <0>;
+ compatible = "qcom,camera-led-flash";
+ qcom,flash-type = <1>;
+ qcom,flash-source = <&pm8941_flash0 &pm8941_flash1>;
+ };
+
cci: qcom,cci@fda0C000 {
cell-index = <0>;
compatible = "qcom,cci";
@@ -189,7 +196,6 @@
reg = <0x90 0x0>;
qcom,csi-if = <1>;
qcom,csid-core = <0>;
- qcom,flash-type = <0>;
qcom,mount-angle = <0>;
qcom,sensor-name = "mt9m114";
cam_vdig-supply = <&pm8941_l3>;
diff --git a/arch/arm/boot/dts/msm8974-cdp.dtsi b/arch/arm/boot/dts/msm8974-cdp.dtsi
index 7557fd1..468c283 100644
--- a/arch/arm/boot/dts/msm8974-cdp.dtsi
+++ b/arch/arm/boot/dts/msm8974-cdp.dtsi
@@ -11,8 +11,8 @@
*/
/include/ "dsi-panel-toshiba-720p-video.dtsi"
-/include/ "msm8974-camera-sensor.dtsi"
/include/ "msm8974-leds.dtsi"
+/include/ "msm8974-camera-sensor.dtsi"
/ {
serial@f991e000 {
diff --git a/arch/arm/boot/dts/msm8974-leds.dtsi b/arch/arm/boot/dts/msm8974-leds.dtsi
index 89bb687..8ba3470 100644
--- a/arch/arm/boot/dts/msm8974-leds.dtsi
+++ b/arch/arm/boot/dts/msm8974-leds.dtsi
@@ -45,13 +45,13 @@
status = "disabled";
};
- qcom,leds@d2000 {
+ qcom,leds@d200 {
status = "disabled";
};
qcom,leds@d300 {
status = "okay";
- qcom,flash_0 {
+ pm8941_flash0: qcom,flash_0 {
qcom,max-current = <1000>;
qcom,default-state = "off";
qcom,headroom = <0>;
@@ -67,7 +67,7 @@
qcom,current = <625>;
};
- qcom,flash_1 {
+ pm8941_flash1: qcom,flash_1 {
qcom,max-current = <1000>;
qcom,default-state = "off";
qcom,headroom = <0>;
diff --git a/arch/arm/boot/dts/msm8974-liquid.dtsi b/arch/arm/boot/dts/msm8974-liquid.dtsi
index 0f65dc8..ec723a7 100644
--- a/arch/arm/boot/dts/msm8974-liquid.dtsi
+++ b/arch/arm/boot/dts/msm8974-liquid.dtsi
@@ -10,8 +10,8 @@
* GNU General Public License for more details.
*/
-/include/ "msm8974-camera-sensor-liquid.dtsi"
/include/ "msm8974-leds.dtsi"
+/include/ "msm8974-camera-sensor-liquid.dtsi"
/ {
serial@f991e000 {
diff --git a/arch/arm/boot/dts/msm8974-rumi.dtsi b/arch/arm/boot/dts/msm8974-rumi.dtsi
index 33656cd..4919391 100644
--- a/arch/arm/boot/dts/msm8974-rumi.dtsi
+++ b/arch/arm/boot/dts/msm8974-rumi.dtsi
@@ -10,6 +10,7 @@
* GNU General Public License for more details.
*/
+/include/ "msm8974-leds.dtsi"
/include/ "msm8974-camera-sensor.dtsi"
/ {
@@ -106,4 +107,36 @@
qcom,mss@fc880000 {
status = "disable";
};
+
+ qcom,kgsl-3d0@fdb00000 {
+ status = "disabled";
+ };
+};
+
+&gdsc_venus {
+ status = "disabled";
+};
+
+&gdsc_mdss {
+ status = "disabled";
+};
+
+&gdsc_jpeg {
+ status = "disabled";
+};
+
+&gdsc_vfe {
+ status = "disabled";
+};
+
+&gdsc_oxili_gx {
+ status = "disabled";
+};
+
+&gdsc_oxili_cx {
+ status = "disabled";
+};
+
+&gdsc_usb_hsic {
+ status = "disabled";
};
diff --git a/arch/arm/boot/dts/msm8974-sim.dtsi b/arch/arm/boot/dts/msm8974-sim.dtsi
index 8e8b3c3..fb638f7 100644
--- a/arch/arm/boot/dts/msm8974-sim.dtsi
+++ b/arch/arm/boot/dts/msm8974-sim.dtsi
@@ -11,6 +11,7 @@
*/
/include/ "dsi-panel-sim-video.dtsi"
+/include/ "msm8974-leds.dtsi"
/include/ "msm8974-camera-sensor.dtsi"
/ {
diff --git a/arch/arm/configs/msm9625_defconfig b/arch/arm/configs/msm9625_defconfig
index d47870e..80f16d4 100644
--- a/arch/arm/configs/msm9625_defconfig
+++ b/arch/arm/configs/msm9625_defconfig
@@ -111,7 +111,7 @@
# CONFIG_NET_VENDOR_SEEQ is not set
# CONFIG_NET_VENDOR_SMSC is not set
# CONFIG_NET_VENDOR_STMICRO is not set
-# CONFIG_WLAN is not set
+CONFIG_ATH6K_LEGACY_EXT=y
# CONFIG_INPUT_MOUSEDEV is not set
CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_KEYBOARD is not set
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index 2464140..3a52ddc 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -439,12 +439,12 @@
if (plat && plat->request_pmu_irq)
armpmu->request_pmu_irq = plat->request_pmu_irq;
- else
+ else if (!armpmu->request_pmu_irq)
armpmu->request_pmu_irq = armpmu_generic_request_irq;
if (plat && plat->free_pmu_irq)
armpmu->free_pmu_irq = plat->free_pmu_irq;
- else
+ else if (!armpmu->request_pmu_irq)
armpmu->free_pmu_irq = armpmu_generic_free_irq;
irqs = min(pmu_device->num_resources, num_possible_cpus());
diff --git a/arch/arm/mach-msm/acpuclock-8930.c b/arch/arm/mach-msm/acpuclock-8930.c
index e46599a..948ecdd 100644
--- a/arch/arm/mach-msm/acpuclock-8930.c
+++ b/arch/arm/mach-msm/acpuclock-8930.c
@@ -155,19 +155,19 @@
static struct acpu_level acpu_freq_tbl_slow[] __initdata = {
{ 1, { 384000, PLL_8, 0, 0x00 }, L2(0), 950000 },
- { 1, { 432000, HFPLL, 2, 0x20 }, L2(5), 975000 },
+ { 0, { 432000, HFPLL, 2, 0x20 }, L2(5), 975000 },
{ 1, { 486000, HFPLL, 2, 0x24 }, L2(5), 975000 },
- { 1, { 540000, HFPLL, 2, 0x28 }, L2(5), 1000000 },
+ { 0, { 540000, HFPLL, 2, 0x28 }, L2(5), 1000000 },
{ 1, { 594000, HFPLL, 1, 0x16 }, L2(5), 1000000 },
- { 1, { 648000, HFPLL, 1, 0x18 }, L2(5), 1025000 },
+ { 0, { 648000, HFPLL, 1, 0x18 }, L2(5), 1025000 },
{ 1, { 702000, HFPLL, 1, 0x1A }, L2(5), 1025000 },
- { 1, { 756000, HFPLL, 1, 0x1C }, L2(10), 1075000 },
+ { 0, { 756000, HFPLL, 1, 0x1C }, L2(10), 1075000 },
{ 1, { 810000, HFPLL, 1, 0x1E }, L2(10), 1075000 },
- { 1, { 864000, HFPLL, 1, 0x20 }, L2(10), 1100000 },
+ { 0, { 864000, HFPLL, 1, 0x20 }, L2(10), 1100000 },
{ 1, { 918000, HFPLL, 1, 0x22 }, L2(10), 1100000 },
- { 1, { 972000, HFPLL, 1, 0x24 }, L2(10), 1125000 },
+ { 0, { 972000, HFPLL, 1, 0x24 }, L2(10), 1125000 },
{ 1, { 1026000, HFPLL, 1, 0x26 }, L2(10), 1125000 },
- { 1, { 1080000, HFPLL, 1, 0x28 }, L2(15), 1175000 },
+ { 0, { 1080000, HFPLL, 1, 0x28 }, L2(15), 1175000 },
{ 1, { 1134000, HFPLL, 1, 0x2A }, L2(15), 1175000 },
{ 1, { 1188000, HFPLL, 1, 0x2C }, L2(15), 1200000 },
{ 0, { 0 } }
@@ -175,19 +175,19 @@
static struct acpu_level acpu_freq_tbl_nom[] __initdata = {
{ 1, { 384000, PLL_8, 0, 0x00 }, L2(0), 925000 },
- { 1, { 432000, HFPLL, 2, 0x20 }, L2(5), 950000 },
+ { 0, { 432000, HFPLL, 2, 0x20 }, L2(5), 950000 },
{ 1, { 486000, HFPLL, 2, 0x24 }, L2(5), 950000 },
- { 1, { 540000, HFPLL, 2, 0x28 }, L2(5), 975000 },
+ { 0, { 540000, HFPLL, 2, 0x28 }, L2(5), 975000 },
{ 1, { 594000, HFPLL, 1, 0x16 }, L2(5), 975000 },
- { 1, { 648000, HFPLL, 1, 0x18 }, L2(5), 1000000 },
+ { 0, { 648000, HFPLL, 1, 0x18 }, L2(5), 1000000 },
{ 1, { 702000, HFPLL, 1, 0x1A }, L2(5), 1000000 },
- { 1, { 756000, HFPLL, 1, 0x1C }, L2(10), 1050000 },
+ { 0, { 756000, HFPLL, 1, 0x1C }, L2(10), 1050000 },
{ 1, { 810000, HFPLL, 1, 0x1E }, L2(10), 1050000 },
- { 1, { 864000, HFPLL, 1, 0x20 }, L2(10), 1075000 },
+ { 0, { 864000, HFPLL, 1, 0x20 }, L2(10), 1075000 },
{ 1, { 918000, HFPLL, 1, 0x22 }, L2(10), 1075000 },
- { 1, { 972000, HFPLL, 1, 0x24 }, L2(10), 1100000 },
+ { 0, { 972000, HFPLL, 1, 0x24 }, L2(10), 1100000 },
{ 1, { 1026000, HFPLL, 1, 0x26 }, L2(10), 1100000 },
- { 1, { 1080000, HFPLL, 1, 0x28 }, L2(15), 1150000 },
+ { 0, { 1080000, HFPLL, 1, 0x28 }, L2(15), 1150000 },
{ 1, { 1134000, HFPLL, 1, 0x2A }, L2(15), 1150000 },
{ 1, { 1188000, HFPLL, 1, 0x2C }, L2(15), 1175000 },
{ 0, { 0 } }
@@ -195,19 +195,19 @@
static struct acpu_level acpu_freq_tbl_fast[] __initdata = {
{ 1, { 384000, PLL_8, 0, 0x00 }, L2(0), 900000 },
- { 1, { 432000, HFPLL, 2, 0x20 }, L2(5), 900000 },
+ { 0, { 432000, HFPLL, 2, 0x20 }, L2(5), 900000 },
{ 1, { 486000, HFPLL, 2, 0x24 }, L2(5), 900000 },
- { 1, { 540000, HFPLL, 2, 0x28 }, L2(5), 925000 },
+ { 0, { 540000, HFPLL, 2, 0x28 }, L2(5), 925000 },
{ 1, { 594000, HFPLL, 1, 0x16 }, L2(5), 925000 },
- { 1, { 648000, HFPLL, 1, 0x18 }, L2(5), 950000 },
+ { 0, { 648000, HFPLL, 1, 0x18 }, L2(5), 950000 },
{ 1, { 702000, HFPLL, 1, 0x1A }, L2(5), 950000 },
- { 1, { 756000, HFPLL, 1, 0x1C }, L2(10), 1000000 },
+ { 0, { 756000, HFPLL, 1, 0x1C }, L2(10), 1000000 },
{ 1, { 810000, HFPLL, 1, 0x1E }, L2(10), 1000000 },
- { 1, { 864000, HFPLL, 1, 0x20 }, L2(10), 1025000 },
+ { 0, { 864000, HFPLL, 1, 0x20 }, L2(10), 1025000 },
{ 1, { 918000, HFPLL, 1, 0x22 }, L2(10), 1025000 },
- { 1, { 972000, HFPLL, 1, 0x24 }, L2(10), 1050000 },
+ { 0, { 972000, HFPLL, 1, 0x24 }, L2(10), 1050000 },
{ 1, { 1026000, HFPLL, 1, 0x26 }, L2(10), 1050000 },
- { 1, { 1080000, HFPLL, 1, 0x28 }, L2(15), 1100000 },
+ { 0, { 1080000, HFPLL, 1, 0x28 }, L2(15), 1100000 },
{ 1, { 1134000, HFPLL, 1, 0x2A }, L2(15), 1100000 },
{ 1, { 1188000, HFPLL, 1, 0x2C }, L2(15), 1125000 },
{ 0, { 0 } }
diff --git a/arch/arm/mach-msm/acpuclock-8930aa.c b/arch/arm/mach-msm/acpuclock-8930aa.c
index 9d2b6fc..8d48b54 100644
--- a/arch/arm/mach-msm/acpuclock-8930aa.c
+++ b/arch/arm/mach-msm/acpuclock-8930aa.c
@@ -119,23 +119,23 @@
static struct acpu_level acpu_freq_tbl_slow[] __initdata = {
{ 1, { 384000, PLL_8, 0, 0x00 }, L2(0), 950000 },
- { 1, { 432000, HFPLL, 2, 0x20 }, L2(5), 975000 },
+ { 0, { 432000, HFPLL, 2, 0x20 }, L2(5), 975000 },
{ 1, { 486000, HFPLL, 2, 0x24 }, L2(5), 975000 },
- { 1, { 540000, HFPLL, 2, 0x28 }, L2(5), 1000000 },
+ { 0, { 540000, HFPLL, 2, 0x28 }, L2(5), 1000000 },
{ 1, { 594000, HFPLL, 1, 0x16 }, L2(5), 1000000 },
- { 1, { 648000, HFPLL, 1, 0x18 }, L2(5), 1025000 },
+ { 0, { 648000, HFPLL, 1, 0x18 }, L2(5), 1025000 },
{ 1, { 702000, HFPLL, 1, 0x1A }, L2(5), 1025000 },
- { 1, { 756000, HFPLL, 1, 0x1C }, L2(10), 1075000 },
+ { 0, { 756000, HFPLL, 1, 0x1C }, L2(10), 1075000 },
{ 1, { 810000, HFPLL, 1, 0x1E }, L2(10), 1075000 },
- { 1, { 864000, HFPLL, 1, 0x20 }, L2(10), 1100000 },
+ { 0, { 864000, HFPLL, 1, 0x20 }, L2(10), 1100000 },
{ 1, { 918000, HFPLL, 1, 0x22 }, L2(10), 1100000 },
- { 1, { 972000, HFPLL, 1, 0x24 }, L2(10), 1125000 },
+ { 0, { 972000, HFPLL, 1, 0x24 }, L2(10), 1125000 },
{ 1, { 1026000, HFPLL, 1, 0x26 }, L2(10), 1125000 },
- { 1, { 1080000, HFPLL, 1, 0x28 }, L2(15), 1175000 },
+ { 0, { 1080000, HFPLL, 1, 0x28 }, L2(15), 1175000 },
{ 1, { 1134000, HFPLL, 1, 0x2A }, L2(15), 1175000 },
- { 1, { 1188000, HFPLL, 1, 0x2C }, L2(15), 1200000 },
+ { 0, { 1188000, HFPLL, 1, 0x2C }, L2(15), 1200000 },
{ 1, { 1242000, HFPLL, 1, 0x2E }, L2(15), 1200000 },
- { 1, { 1296000, HFPLL, 1, 0x30 }, L2(15), 1225000 },
+ { 0, { 1296000, HFPLL, 1, 0x30 }, L2(15), 1225000 },
{ 1, { 1350000, HFPLL, 1, 0x32 }, L2(15), 1225000 },
{ 1, { 1404000, HFPLL, 1, 0x34 }, L2(15), 1237500 },
{ 0, { 0 } }
@@ -143,23 +143,23 @@
static struct acpu_level acpu_freq_tbl_nom[] __initdata = {
{ 1, { 384000, PLL_8, 0, 0x00 }, L2(0), 925000 },
- { 1, { 432000, HFPLL, 2, 0x20 }, L2(5), 950000 },
+ { 0, { 432000, HFPLL, 2, 0x20 }, L2(5), 950000 },
{ 1, { 486000, HFPLL, 2, 0x24 }, L2(5), 950000 },
- { 1, { 540000, HFPLL, 2, 0x28 }, L2(5), 975000 },
+ { 0, { 540000, HFPLL, 2, 0x28 }, L2(5), 975000 },
{ 1, { 594000, HFPLL, 1, 0x16 }, L2(5), 975000 },
- { 1, { 648000, HFPLL, 1, 0x18 }, L2(5), 1000000 },
+ { 0, { 648000, HFPLL, 1, 0x18 }, L2(5), 1000000 },
{ 1, { 702000, HFPLL, 1, 0x1A }, L2(5), 1000000 },
- { 1, { 756000, HFPLL, 1, 0x1C }, L2(10), 1050000 },
+ { 0, { 756000, HFPLL, 1, 0x1C }, L2(10), 1050000 },
{ 1, { 810000, HFPLL, 1, 0x1E }, L2(10), 1050000 },
- { 1, { 864000, HFPLL, 1, 0x20 }, L2(10), 1075000 },
+ { 0, { 864000, HFPLL, 1, 0x20 }, L2(10), 1075000 },
{ 1, { 918000, HFPLL, 1, 0x22 }, L2(10), 1075000 },
- { 1, { 972000, HFPLL, 1, 0x24 }, L2(10), 1100000 },
+ { 0, { 972000, HFPLL, 1, 0x24 }, L2(10), 1100000 },
{ 1, { 1026000, HFPLL, 1, 0x26 }, L2(10), 1100000 },
- { 1, { 1080000, HFPLL, 1, 0x28 }, L2(15), 1150000 },
+ { 0, { 1080000, HFPLL, 1, 0x28 }, L2(15), 1150000 },
{ 1, { 1134000, HFPLL, 1, 0x2A }, L2(15), 1150000 },
- { 1, { 1188000, HFPLL, 1, 0x2C }, L2(15), 1175000 },
+ { 0, { 1188000, HFPLL, 1, 0x2C }, L2(15), 1175000 },
{ 1, { 1242000, HFPLL, 1, 0x2E }, L2(15), 1175000 },
- { 1, { 1296000, HFPLL, 1, 0x30 }, L2(15), 1200000 },
+ { 0, { 1296000, HFPLL, 1, 0x30 }, L2(15), 1200000 },
{ 1, { 1350000, HFPLL, 1, 0x32 }, L2(15), 1200000 },
{ 1, { 1404000, HFPLL, 1, 0x34 }, L2(15), 1212500 },
{ 0, { 0 } }
@@ -167,23 +167,23 @@
static struct acpu_level acpu_freq_tbl_fast[] __initdata = {
{ 1, { 384000, PLL_8, 0, 0x00 }, L2(0), 900000 },
- { 1, { 432000, HFPLL, 2, 0x20 }, L2(5), 900000 },
+ { 0, { 432000, HFPLL, 2, 0x20 }, L2(5), 900000 },
{ 1, { 486000, HFPLL, 2, 0x24 }, L2(5), 900000 },
- { 1, { 540000, HFPLL, 2, 0x28 }, L2(5), 925000 },
+ { 0, { 540000, HFPLL, 2, 0x28 }, L2(5), 925000 },
{ 1, { 594000, HFPLL, 1, 0x16 }, L2(5), 925000 },
- { 1, { 648000, HFPLL, 1, 0x18 }, L2(5), 950000 },
+ { 0, { 648000, HFPLL, 1, 0x18 }, L2(5), 950000 },
{ 1, { 702000, HFPLL, 1, 0x1A }, L2(5), 950000 },
- { 1, { 756000, HFPLL, 1, 0x1C }, L2(10), 1000000 },
+ { 0, { 756000, HFPLL, 1, 0x1C }, L2(10), 1000000 },
{ 1, { 810000, HFPLL, 1, 0x1E }, L2(10), 1000000 },
- { 1, { 864000, HFPLL, 1, 0x20 }, L2(10), 1025000 },
+ { 0, { 864000, HFPLL, 1, 0x20 }, L2(10), 1025000 },
{ 1, { 918000, HFPLL, 1, 0x22 }, L2(10), 1025000 },
- { 1, { 972000, HFPLL, 1, 0x24 }, L2(10), 1050000 },
+ { 0, { 972000, HFPLL, 1, 0x24 }, L2(10), 1050000 },
{ 1, { 1026000, HFPLL, 1, 0x26 }, L2(10), 1050000 },
- { 1, { 1080000, HFPLL, 1, 0x28 }, L2(15), 1100000 },
+ { 0, { 1080000, HFPLL, 1, 0x28 }, L2(15), 1100000 },
{ 1, { 1134000, HFPLL, 1, 0x2A }, L2(15), 1100000 },
- { 1, { 1188000, HFPLL, 1, 0x2C }, L2(15), 1125000 },
+ { 0, { 1188000, HFPLL, 1, 0x2C }, L2(15), 1125000 },
{ 1, { 1242000, HFPLL, 1, 0x2E }, L2(15), 1125000 },
- { 1, { 1296000, HFPLL, 1, 0x30 }, L2(15), 1150000 },
+ { 0, { 1296000, HFPLL, 1, 0x30 }, L2(15), 1150000 },
{ 1, { 1350000, HFPLL, 1, 0x32 }, L2(15), 1150000 },
{ 1, { 1404000, HFPLL, 1, 0x34 }, L2(15), 1162500 },
{ 0, { 0 } }
diff --git a/arch/arm/mach-msm/acpuclock-8930ab.c b/arch/arm/mach-msm/acpuclock-8930ab.c
index 764ae41..96029b4 100644
--- a/arch/arm/mach-msm/acpuclock-8930ab.c
+++ b/arch/arm/mach-msm/acpuclock-8930ab.c
@@ -153,29 +153,29 @@
static struct acpu_level acpu_freq_tbl_slow[] __initdata = {
{ 1, { 384000, PLL_8, 0, 0x00 }, L2(0), 950000 },
- { 1, { 432000, HFPLL, 2, 0x20 }, L2(5), 975000 },
+ { 0, { 432000, HFPLL, 2, 0x20 }, L2(5), 975000 },
{ 1, { 486000, HFPLL, 2, 0x24 }, L2(5), 975000 },
- { 1, { 540000, HFPLL, 2, 0x28 }, L2(5), 1000000 },
+ { 0, { 540000, HFPLL, 2, 0x28 }, L2(5), 1000000 },
{ 1, { 594000, HFPLL, 1, 0x16 }, L2(5), 1000000 },
- { 1, { 648000, HFPLL, 1, 0x18 }, L2(5), 1025000 },
+ { 0, { 648000, HFPLL, 1, 0x18 }, L2(5), 1025000 },
{ 1, { 702000, HFPLL, 1, 0x1A }, L2(5), 1025000 },
- { 1, { 756000, HFPLL, 1, 0x1C }, L2(10), 1075000 },
+ { 0, { 756000, HFPLL, 1, 0x1C }, L2(10), 1075000 },
{ 1, { 810000, HFPLL, 1, 0x1E }, L2(10), 1075000 },
- { 1, { 864000, HFPLL, 1, 0x20 }, L2(10), 1100000 },
+ { 0, { 864000, HFPLL, 1, 0x20 }, L2(10), 1100000 },
{ 1, { 918000, HFPLL, 1, 0x22 }, L2(10), 1100000 },
- { 1, { 972000, HFPLL, 1, 0x24 }, L2(10), 1125000 },
+ { 0, { 972000, HFPLL, 1, 0x24 }, L2(10), 1125000 },
{ 1, { 1026000, HFPLL, 1, 0x26 }, L2(10), 1125000 },
- { 1, { 1080000, HFPLL, 1, 0x28 }, L2(15), 1175000 },
+ { 0, { 1080000, HFPLL, 1, 0x28 }, L2(15), 1175000 },
{ 1, { 1134000, HFPLL, 1, 0x2A }, L2(15), 1175000 },
- { 1, { 1188000, HFPLL, 1, 0x2C }, L2(15), 1200000 },
+ { 0, { 1188000, HFPLL, 1, 0x2C }, L2(15), 1200000 },
{ 1, { 1242000, HFPLL, 1, 0x2E }, L2(15), 1200000 },
- { 1, { 1296000, HFPLL, 1, 0x30 }, L2(15), 1225000 },
+ { 0, { 1296000, HFPLL, 1, 0x30 }, L2(15), 1225000 },
{ 1, { 1350000, HFPLL, 1, 0x32 }, L2(15), 1225000 },
- { 1, { 1404000, HFPLL, 1, 0x34 }, L2(15), 1237500 },
+ { 0, { 1404000, HFPLL, 1, 0x34 }, L2(15), 1237500 },
{ 1, { 1458000, HFPLL, 1, 0x36 }, L2(15), 1237500 },
- { 1, { 1512000, HFPLL, 1, 0x38 }, L2(15), 1250000 },
+ { 0, { 1512000, HFPLL, 1, 0x38 }, L2(15), 1250000 },
{ 1, { 1566000, HFPLL, 1, 0x3A }, L2(15), 1250000 },
- { 1, { 1620000, HFPLL, 1, 0x3C }, L2(15), 1262500 },
+ { 0, { 1620000, HFPLL, 1, 0x3C }, L2(15), 1262500 },
{ 1, { 1674000, HFPLL, 1, 0x3E }, L2(15), 1262500 },
{ 1, { 1728000, HFPLL, 1, 0x40 }, L2(15), 1287500 },
{ 0, { 0 } }
@@ -183,29 +183,29 @@
static struct acpu_level acpu_freq_tbl_nom[] __initdata = {
{ 1, { 384000, PLL_8, 0, 0x00 }, L2(0), 950000 },
- { 1, { 432000, HFPLL, 2, 0x20 }, L2(5), 975000 },
+ { 0, { 432000, HFPLL, 2, 0x20 }, L2(5), 975000 },
{ 1, { 486000, HFPLL, 2, 0x24 }, L2(5), 975000 },
- { 1, { 540000, HFPLL, 2, 0x28 }, L2(5), 1000000 },
+ { 0, { 540000, HFPLL, 2, 0x28 }, L2(5), 1000000 },
{ 1, { 594000, HFPLL, 1, 0x16 }, L2(5), 1000000 },
- { 1, { 648000, HFPLL, 1, 0x18 }, L2(5), 1025000 },
+ { 0, { 648000, HFPLL, 1, 0x18 }, L2(5), 1025000 },
{ 1, { 702000, HFPLL, 1, 0x1A }, L2(5), 1025000 },
- { 1, { 756000, HFPLL, 1, 0x1C }, L2(10), 1075000 },
+ { 0, { 756000, HFPLL, 1, 0x1C }, L2(10), 1075000 },
{ 1, { 810000, HFPLL, 1, 0x1E }, L2(10), 1075000 },
- { 1, { 864000, HFPLL, 1, 0x20 }, L2(10), 1100000 },
+ { 0, { 864000, HFPLL, 1, 0x20 }, L2(10), 1100000 },
{ 1, { 918000, HFPLL, 1, 0x22 }, L2(10), 1100000 },
- { 1, { 972000, HFPLL, 1, 0x24 }, L2(10), 1125000 },
+ { 0, { 972000, HFPLL, 1, 0x24 }, L2(10), 1125000 },
{ 1, { 1026000, HFPLL, 1, 0x26 }, L2(10), 1125000 },
- { 1, { 1080000, HFPLL, 1, 0x28 }, L2(15), 1175000 },
+ { 0, { 1080000, HFPLL, 1, 0x28 }, L2(15), 1175000 },
{ 1, { 1134000, HFPLL, 1, 0x2A }, L2(15), 1175000 },
- { 1, { 1188000, HFPLL, 1, 0x2C }, L2(15), 1200000 },
+ { 0, { 1188000, HFPLL, 1, 0x2C }, L2(15), 1200000 },
{ 1, { 1242000, HFPLL, 1, 0x2E }, L2(15), 1200000 },
- { 1, { 1296000, HFPLL, 1, 0x30 }, L2(15), 1225000 },
+ { 0, { 1296000, HFPLL, 1, 0x30 }, L2(15), 1225000 },
{ 1, { 1350000, HFPLL, 1, 0x32 }, L2(15), 1225000 },
- { 1, { 1404000, HFPLL, 1, 0x34 }, L2(15), 1237500 },
+ { 0, { 1404000, HFPLL, 1, 0x34 }, L2(15), 1237500 },
{ 1, { 1458000, HFPLL, 1, 0x36 }, L2(15), 1237500 },
- { 1, { 1512000, HFPLL, 1, 0x38 }, L2(15), 1250000 },
+ { 0, { 1512000, HFPLL, 1, 0x38 }, L2(15), 1250000 },
{ 1, { 1566000, HFPLL, 1, 0x3A }, L2(15), 1250000 },
- { 1, { 1620000, HFPLL, 1, 0x3C }, L2(15), 1262500 },
+ { 0, { 1620000, HFPLL, 1, 0x3C }, L2(15), 1262500 },
{ 1, { 1674000, HFPLL, 1, 0x3E }, L2(15), 1262500 },
{ 1, { 1728000, HFPLL, 1, 0x40 }, L2(15), 1287500 },
{ 0, { 0 } }
@@ -213,29 +213,29 @@
static struct acpu_level acpu_freq_tbl_fast[] __initdata = {
{ 1, { 384000, PLL_8, 0, 0x00 }, L2(0), 950000 },
- { 1, { 432000, HFPLL, 2, 0x20 }, L2(5), 975000 },
+ { 0, { 432000, HFPLL, 2, 0x20 }, L2(5), 975000 },
{ 1, { 486000, HFPLL, 2, 0x24 }, L2(5), 975000 },
- { 1, { 540000, HFPLL, 2, 0x28 }, L2(5), 1000000 },
+ { 0, { 540000, HFPLL, 2, 0x28 }, L2(5), 1000000 },
{ 1, { 594000, HFPLL, 1, 0x16 }, L2(5), 1000000 },
- { 1, { 648000, HFPLL, 1, 0x18 }, L2(5), 1025000 },
+ { 0, { 648000, HFPLL, 1, 0x18 }, L2(5), 1025000 },
{ 1, { 702000, HFPLL, 1, 0x1A }, L2(5), 1025000 },
- { 1, { 756000, HFPLL, 1, 0x1C }, L2(10), 1075000 },
+ { 0, { 756000, HFPLL, 1, 0x1C }, L2(10), 1075000 },
{ 1, { 810000, HFPLL, 1, 0x1E }, L2(10), 1075000 },
- { 1, { 864000, HFPLL, 1, 0x20 }, L2(10), 1100000 },
+ { 0, { 864000, HFPLL, 1, 0x20 }, L2(10), 1100000 },
{ 1, { 918000, HFPLL, 1, 0x22 }, L2(10), 1100000 },
- { 1, { 972000, HFPLL, 1, 0x24 }, L2(10), 1125000 },
+ { 0, { 972000, HFPLL, 1, 0x24 }, L2(10), 1125000 },
{ 1, { 1026000, HFPLL, 1, 0x26 }, L2(10), 1125000 },
- { 1, { 1080000, HFPLL, 1, 0x28 }, L2(15), 1175000 },
+ { 0, { 1080000, HFPLL, 1, 0x28 }, L2(15), 1175000 },
{ 1, { 1134000, HFPLL, 1, 0x2A }, L2(15), 1175000 },
- { 1, { 1188000, HFPLL, 1, 0x2C }, L2(15), 1200000 },
+ { 0, { 1188000, HFPLL, 1, 0x2C }, L2(15), 1200000 },
{ 1, { 1242000, HFPLL, 1, 0x2E }, L2(15), 1200000 },
- { 1, { 1296000, HFPLL, 1, 0x30 }, L2(15), 1225000 },
+ { 0, { 1296000, HFPLL, 1, 0x30 }, L2(15), 1225000 },
{ 1, { 1350000, HFPLL, 1, 0x32 }, L2(15), 1225000 },
- { 1, { 1404000, HFPLL, 1, 0x34 }, L2(15), 1237500 },
+ { 0, { 1404000, HFPLL, 1, 0x34 }, L2(15), 1237500 },
{ 1, { 1458000, HFPLL, 1, 0x36 }, L2(15), 1237500 },
- { 1, { 1512000, HFPLL, 1, 0x38 }, L2(15), 1250000 },
+ { 0, { 1512000, HFPLL, 1, 0x38 }, L2(15), 1250000 },
{ 1, { 1566000, HFPLL, 1, 0x3A }, L2(15), 1250000 },
- { 1, { 1620000, HFPLL, 1, 0x3C }, L2(15), 1262500 },
+ { 0, { 1620000, HFPLL, 1, 0x3C }, L2(15), 1262500 },
{ 1, { 1674000, HFPLL, 1, 0x3E }, L2(15), 1262500 },
{ 1, { 1728000, HFPLL, 1, 0x40 }, L2(15), 1287500 },
{ 0, { 0 } }
diff --git a/arch/arm/mach-msm/board-8974.c b/arch/arm/mach-msm/board-8974.c
index c47b688..ca8f68a 100644
--- a/arch/arm/mach-msm/board-8974.c
+++ b/arch/arm/mach-msm/board-8974.c
@@ -304,8 +304,6 @@
"usb_bam", NULL),
OF_DEV_AUXDATA("qcom,spi-qup-v2", 0xF9924000, \
"spi_qsd.1", NULL),
- OF_DEV_AUXDATA("qcom,spmi-pmic-arb", 0xFC4C0000, \
- "spmi-pmic-arb.0", NULL),
OF_DEV_AUXDATA("qcom,msm-sdcc", 0xF9824000, \
"msm_sdcc.1", NULL),
OF_DEV_AUXDATA("qcom,msm-sdcc", 0xF98A4000, \
diff --git a/arch/arm/mach-msm/clock-8974.c b/arch/arm/mach-msm/clock-8974.c
index 68bffa5..216de11 100644
--- a/arch/arm/mach-msm/clock-8974.c
+++ b/arch/arm/mach-msm/clock-8974.c
@@ -522,6 +522,14 @@
#define dsipll0_pixel_mm_source_val 1
#define hdmipll_mm_source_val 3
+#define F_GCC_GND \
+ { \
+ .freq_hz = 0, \
+ .m_val = 0, \
+ .n_val = 0, \
+ .div_src_val = BVAL(4, 0, 1) | BVAL(10, 8, gnd_source_val), \
+ }
+
#define F(f, s, div, m, n) \
{ \
.freq_hz = (f), \
@@ -914,6 +922,7 @@
};
static struct clk_freq_tbl ftbl_gcc_blsp1_2_uart1_6_apps_clk[] = {
+ F_GCC_GND,
F( 3686400, gpll0, 1, 96, 15625),
F( 7372800, gpll0, 1, 192, 15625),
F(14745600, gpll0, 1, 384, 15625),
diff --git a/arch/arm/mach-msm/clock-9625.c b/arch/arm/mach-msm/clock-9625.c
index b284168..d3a4bba 100644
--- a/arch/arm/mach-msm/clock-9625.c
+++ b/arch/arm/mach-msm/clock-9625.c
@@ -246,6 +246,14 @@
#define lpapll0_lpass_source_val 1
#define gpll0_lpass_source_val 5
+#define F_GCC_GND \
+ { \
+ .freq_hz = 0, \
+ .m_val = 0, \
+ .n_val = 0, \
+ .div_src_val = BVAL(4, 0, 1) | BVAL(10, 8, gnd_source_val), \
+ }
+
#define F(f, s, div, m, n) \
{ \
.freq_hz = (f), \
@@ -611,6 +619,7 @@
};
static struct clk_freq_tbl ftbl_gcc_blsp1_uart1_6_apps_clk[] = {
+ F_GCC_GND,
F( 3686400, gpll0, 1, 96, 15625),
F( 7372800, gpll0, 1, 192, 15625),
F(14745600, gpll0, 1, 384, 15625),
diff --git a/arch/arm/mach-msm/include/mach/irqs-8092.h b/arch/arm/mach-msm/include/mach/irqs-8092.h
index ae9634e..dfe21c2 100644
--- a/arch/arm/mach-msm/include/mach/irqs-8092.h
+++ b/arch/arm/mach-msm/include/mach/irqs-8092.h
@@ -34,12 +34,5 @@
#define TLMM_MSM_SUMMARY_IRQ (GIC_SPI_START + 208)
#define SPS_BAM_DMA_IRQ (GIC_SPI_START + 105)
-#define NR_MSM_IRQS 1020 /* Should be 256 - but higher due to bug in sim */
-#define NR_GPIO_IRQS 146
-#define NR_QPNP_IRQS 32768 /* SPARSE_IRQ is required to support this */
-#define NR_BOARD_IRQS NR_QPNP_IRQS
-#define NR_TLMM_MSM_DIR_CONN_IRQ 8
-#define NR_MSM_GPIOS NR_GPIO_IRQS
-
#endif
diff --git a/arch/arm/mach-msm/include/mach/irqs-8226.h b/arch/arm/mach-msm/include/mach/irqs-8226.h
index 72602b1..abc62d2 100644
--- a/arch/arm/mach-msm/include/mach/irqs-8226.h
+++ b/arch/arm/mach-msm/include/mach/irqs-8226.h
@@ -31,11 +31,4 @@
#define SC_SICL2PERFMONIRPTREQ APCC_QGICL2PERFMONIRPTREQ
#define TLMM_MSM_SUMMARY_IRQ (GIC_SPI_START + 208)
-#define NR_MSM_IRQS 256
-#define NR_GPIO_IRQS 117
-#define NR_QPNP_IRQS 32768 /* SPARSE_IRQ is required to support this */
-#define NR_BOARD_IRQS NR_QPNP_IRQS
-#define NR_TLMM_MSM_DIR_CONN_IRQ 8
-#define NR_MSM_GPIOS NR_GPIO_IRQS
-
#endif
diff --git a/arch/arm/mach-msm/include/mach/irqs-8910.h b/arch/arm/mach-msm/include/mach/irqs-8910.h
index e883214..635c044 100644
--- a/arch/arm/mach-msm/include/mach/irqs-8910.h
+++ b/arch/arm/mach-msm/include/mach/irqs-8910.h
@@ -30,11 +30,4 @@
#define SC_SICL2PERFMONIRPTREQ APCC_QGICL2PERFMONIRPTREQ
#define TLMM_MSM_SUMMARY_IRQ (GIC_SPI_START + 208)
-#define NR_MSM_IRQS 256
-#define NR_GPIO_IRQS 102
-#define NR_QPNP_IRQS 32768 /* SPARSE_IRQ is required to support this */
-#define NR_BOARD_IRQS NR_QPNP_IRQS
-#define NR_TLMM_MSM_DIR_CONN_IRQ 8
-#define NR_MSM_GPIOS NR_GPIO_IRQS
-
#endif
diff --git a/arch/arm/mach-msm/include/mach/irqs-8974.h b/arch/arm/mach-msm/include/mach/irqs-8974.h
index 8152eca..150b2ee 100644
--- a/arch/arm/mach-msm/include/mach/irqs-8974.h
+++ b/arch/arm/mach-msm/include/mach/irqs-8974.h
@@ -32,12 +32,5 @@
#define TLMM_MSM_SUMMARY_IRQ (GIC_SPI_START + 208)
#define SPS_BAM_DMA_IRQ (GIC_SPI_START + 105)
-#define NR_MSM_IRQS 1020 /* Should be 256 - but higher due to bug in sim */
-#define NR_GPIO_IRQS 146
-#define NR_QPNP_IRQS 32768 /* SPARSE_IRQ is required to support this */
-#define NR_BOARD_IRQS NR_QPNP_IRQS
-#define NR_TLMM_MSM_DIR_CONN_IRQ 8
-#define NR_MSM_GPIOS NR_GPIO_IRQS
-
#endif
diff --git a/arch/arm/mach-msm/include/mach/irqs.h b/arch/arm/mach-msm/include/mach/irqs.h
index 8d96192..7837c79 100644
--- a/arch/arm/mach-msm/include/mach/irqs.h
+++ b/arch/arm/mach-msm/include/mach/irqs.h
@@ -19,7 +19,40 @@
#define MSM_IRQ_BIT(irq) (1 << ((irq) & 31))
-#if defined(CONFIG_ARCH_MSM8960) || defined(CONFIG_ARCH_APQ8064) || \
+#if defined(CONFIG_ARCH_MSM8974) || defined(CONFIG_ARCH_MPQ8092)
+
+#ifdef CONFIG_ARCH_MSM8974
+#include "irqs-8974.h"
+#endif
+
+#ifdef CONFIG_ARCH_MPQ8092
+#include "irqs-8092.h"
+#endif
+
+#define NR_MSM_IRQS 1020 /* Should be 256 - but higher due to bug in sim */
+#define NR_GPIO_IRQS 146
+#define NR_QPNP_IRQS 32768
+#define NR_BOARD_IRQS NR_QPNP_IRQS
+#define NR_TLMM_MSM_DIR_CONN_IRQ 8
+#define NR_MSM_GPIOS NR_GPIO_IRQS
+
+#elif defined(CONFIG_ARCH_MSM8910) || defined(CONFIG_ARCH_MSM8226)
+#ifdef CONFIG_ARCH_MSM8910
+#include "irqs-8910.h"
+#endif
+
+#ifdef CONFIG_ARCH_MSM8226
+#include "irqs-8226.h"
+#endif
+
+#define NR_MSM_IRQS 256
+#define NR_GPIO_IRQS 117
+#define NR_QPNP_IRQS 32768
+#define NR_BOARD_IRQS NR_QPNP_IRQS
+#define NR_TLMM_MSM_DIR_CONN_IRQ 8
+#define NR_MSM_GPIOS NR_GPIO_IRQS
+
+#elif defined(CONFIG_ARCH_MSM8960) || defined(CONFIG_ARCH_APQ8064) || \
defined(CONFIG_ARCH_MSM8930)
#ifdef CONFIG_ARCH_MSM8960
@@ -56,18 +89,10 @@
#else
-#if defined(CONFIG_ARCH_MSM8974)
-#include "irqs-8974.h"
-#elif defined(CONFIG_ARCH_MSM8910)
-#include "irqs-8910.h"
-#elif defined(CONFIG_ARCH_MPQ8092)
-#include "irqs-8092.h"
-#elif defined(CONFIG_ARCH_MSM9615)
+#if defined(CONFIG_ARCH_MSM9615)
#include "irqs-9615.h"
#elif defined(CONFIG_ARCH_MSM9625)
#include "irqs-9625.h"
-#elif defined(CONFIG_ARCH_MSM8226)
-#include "irqs-8226.h"
#elif defined(CONFIG_ARCH_MSM7X30)
#include "irqs-7x30.h"
#elif defined(CONFIG_ARCH_QSD8X50)
diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c
index 0933d20..b1d2464 100644
--- a/arch/arm/mach-msm/platsmp.c
+++ b/arch/arm/mach-msm/platsmp.c
@@ -175,6 +175,9 @@
{
BUG_ON(cpu >= get_core_count());
+ if (machine_is_msm8974_rumi())
+ return 0;
+
if (cpu_is_msm8x60())
return scorpion_release_secondary();
diff --git a/arch/arm/mach-msm/qdsp6v2/ultrasound/usfcdev.c b/arch/arm/mach-msm/qdsp6v2/ultrasound/usfcdev.c
index f566e82..94192cf 100644
--- a/arch/arm/mach-msm/qdsp6v2/ultrasound/usfcdev.c
+++ b/arch/arm/mach-msm/qdsp6v2/ultrasound/usfcdev.c
@@ -16,15 +16,38 @@
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/input/mt.h>
+#include <linux/syscalls.h>
#include "usfcdev.h"
+#define UNDEF_ID 0xffffffff
+#define SLOT_CMD_ID 0
+#define MAX_RETRIES 10
+
+
+
+enum usdev_event_status {
+ USFCDEV_EVENT_ENABLED,
+ USFCDEV_EVENT_DISABLING,
+ USFCDEV_EVENT_DISABLED,
+};
+
struct usfcdev_event {
bool (*match_cb)(uint16_t, struct input_dev *dev);
bool registered_event;
- bool filter;
+ bool interleaved;
+ enum usdev_event_status event_status;
};
static struct usfcdev_event s_usfcdev_events[MAX_EVENT_TYPE_NUM];
+struct usfcdev_input_command {
+ unsigned int type;
+ unsigned int code;
+ unsigned int value;
+};
+
+static long s_usf_pid;
+
static bool usfcdev_filter(struct input_handle *handle,
unsigned int type, unsigned int code, int value);
static bool usfcdev_match(struct input_handler *handler,
@@ -83,6 +106,22 @@
},
};
+static struct usfcdev_input_command initial_clear_cmds[] = {
+ {EV_ABS, ABS_PRESSURE, 0},
+ {EV_KEY, BTN_TOUCH, 0},
+};
+
+static struct usfcdev_input_command slot_clear_cmds[] = {
+ {EV_ABS, ABS_MT_SLOT, 0},
+ {EV_ABS, ABS_MT_TRACKING_ID, UNDEF_ID},
+};
+
+static struct usfcdev_input_command no_filter_cmds[] = {
+ {EV_ABS, ABS_MT_SLOT, 0},
+ {EV_ABS, ABS_MT_TRACKING_ID, UNDEF_ID},
+ {EV_SYN, SYN_REPORT, 0},
+};
+
static bool usfcdev_match(struct input_handler *handler, struct input_dev *dev)
{
bool rc = false;
@@ -91,7 +130,7 @@
pr_debug("%s: name=[%s]; ind=%d\n", __func__, dev->name, ind);
if (s_usfcdev_events[ind].registered_event &&
- s_usfcdev_events[ind].match_cb) {
+ s_usfcdev_events[ind].match_cb) {
rc = (*s_usfcdev_events[ind].match_cb)((uint16_t)ind, dev);
pr_debug("%s: [%s]; rc=%d\n", __func__, dev->name, rc);
}
@@ -139,16 +178,39 @@
static bool usfcdev_filter(struct input_handle *handle,
unsigned int type, unsigned int code, int value)
{
+ uint16_t i = 0;
uint16_t ind = (uint16_t)handle->handler->minor;
+ bool rc = (s_usfcdev_events[ind].event_status != USFCDEV_EVENT_ENABLED);
- pr_debug("%s: event_type=%d; filter=%d; abs_xy=%ld; abs_y_mt[]=%ld\n",
- __func__,
- ind,
- s_usfcdev_events[ind].filter,
- usfc_tsc_ids[0].absbit[0],
- usfc_tsc_ids[1].absbit[1]);
+ if (s_usf_pid == sys_getpid()) {
+ /* Pass events from usfcdev driver */
+ rc = false;
+ pr_debug("%s: event_type=%d; type=%d; code=%d; val=%d",
+ __func__,
+ ind,
+ type,
+ code,
+ value);
+ } else if (s_usfcdev_events[ind].event_status ==
+ USFCDEV_EVENT_DISABLING) {
+ uint32_t u_value = value;
+ s_usfcdev_events[ind].interleaved = true;
+ /* Pass events for freeing slots from TSC driver */
+ for (i = 0; i < ARRAY_SIZE(no_filter_cmds); ++i) {
+ if ((no_filter_cmds[i].type == type) &&
+ (no_filter_cmds[i].code == code) &&
+ (no_filter_cmds[i].value <= u_value)) {
+ rc = false;
+ pr_debug("%s: no_filter_cmds[%d]; %d",
+ __func__,
+ i,
+ no_filter_cmds[i].value);
+ break;
+ }
+ }
+ }
- return s_usfcdev_events[ind].filter;
+ return rc;
}
bool usfcdev_register(
@@ -175,7 +237,7 @@
s_usfcdev_events[event_type_ind].registered_event = true;
s_usfcdev_events[event_type_ind].match_cb = match_cb;
- s_usfcdev_events[event_type_ind].filter = false;
+ s_usfcdev_events[event_type_ind].event_status = USFCDEV_EVENT_ENABLED;
ret = input_register_handler(&s_usfc_handlers[event_type_ind]);
if (!ret) {
rc = true;
@@ -209,7 +271,64 @@
event_type_ind);
s_usfcdev_events[event_type_ind].registered_event = false;
s_usfcdev_events[event_type_ind].match_cb = NULL;
- s_usfcdev_events[event_type_ind].filter = false;
+ s_usfcdev_events[event_type_ind].event_status =
+ USFCDEV_EVENT_ENABLED;
+
+ }
+}
+
+static inline void usfcdev_send_cmd(
+ struct input_dev *dev,
+ struct usfcdev_input_command cmd)
+{
+ input_event(dev, cmd.type, cmd.code, cmd.value);
+}
+
+static void usfcdev_clean_dev(uint16_t event_type_ind)
+{
+ struct input_dev *dev = NULL;
+ int i;
+ int j;
+ int retries = 0;
+
+ if (event_type_ind >= MAX_EVENT_TYPE_NUM) {
+ pr_err("%s: wrong input: event_type_ind=%d\n",
+ __func__,
+ event_type_ind);
+ return;
+ }
+
+ dev = s_usfc_handles[event_type_ind].dev;
+
+ for (i = 0; i < ARRAY_SIZE(initial_clear_cmds); i++)
+ usfcdev_send_cmd(dev, initial_clear_cmds[i]);
+ input_sync(dev);
+
+ /* Send commands to free all slots */
+ for (i = 0; i < dev->mtsize; i++) {
+ s_usfcdev_events[event_type_ind].interleaved = false;
+ if (input_mt_get_value(&(dev->mt[i]), ABS_MT_TRACKING_ID) < 0) {
+ pr_debug("%s: skipping slot %d",
+ __func__, i);
+ continue;
+ }
+ slot_clear_cmds[SLOT_CMD_ID].value = i;
+ for (j = 0; j < ARRAY_SIZE(slot_clear_cmds); j++)
+ usfcdev_send_cmd(dev, slot_clear_cmds[j]);
+
+ if (s_usfcdev_events[event_type_ind].interleaved) {
+ pr_debug("%s: interleaved(%d): slot(%d)",
+ __func__, i, dev->slot);
+ if (retries++ < MAX_RETRIES) {
+ --i;
+ continue;
+ }
+ pr_warning("%s: index(%d) reached max retires",
+ __func__, i);
+ }
+
+ retries = 0;
+ input_sync(dev);
}
}
@@ -225,12 +344,22 @@
}
if (s_usfcdev_events[event_type_ind].registered_event) {
- s_usfcdev_events[event_type_ind].filter = filter;
+
pr_debug("%s: event_type[%d]; filter=%d\n",
__func__,
event_type_ind,
filter
);
+ if (filter) {
+ s_usfcdev_events[event_type_ind].event_status =
+ USFCDEV_EVENT_DISABLING;
+ s_usf_pid = sys_getpid();
+ usfcdev_clean_dev(event_type_ind);
+ s_usfcdev_events[event_type_ind].event_status =
+ USFCDEV_EVENT_DISABLED;
+ } else
+ s_usfcdev_events[event_type_ind].event_status =
+ USFCDEV_EVENT_ENABLED;
} else {
pr_err("%s: event_type[%d] isn't registered\n",
__func__,
diff --git a/arch/arm/mach-msm/rpm-smd.c b/arch/arm/mach-msm/rpm-smd.c
index a59b338..1db3d34 100644
--- a/arch/arm/mach-msm/rpm-smd.c
+++ b/arch/arm/mach-msm/rpm-smd.c
@@ -973,7 +973,7 @@
static bool msm_rpm_set_standalone(void)
{
- if (machine_is_msm9625()) {
+ if (machine_is_msm9625() || machine_is_msm8974_rumi()) {
pr_warn("%s(): Running in standalone mode, requests "
"will not be sent to RPM\n", __func__);
standalone = true;
diff --git a/drivers/bluetooth/hci_ath.c b/drivers/bluetooth/hci_ath.c
index 50b3362..b5531d6 100644
--- a/drivers/bluetooth/hci_ath.c
+++ b/drivers/bluetooth/hci_ath.c
@@ -43,6 +43,9 @@
#include <net/bluetooth/hci_core.h>
#include "hci_uart.h"
+#ifdef CONFIG_SERIAL_MSM_HS
+#include <mach/msm_serial_hs.h>
+#endif
unsigned int enableuartsleep = 1;
module_param(enableuartsleep, uint, 0644);
@@ -52,8 +55,8 @@
/** Global state flags */
static unsigned long flags;
-/** Tasklet to respond to change in hostwake line */
-static struct tasklet_struct hostwake_task;
+/** Workqueue to respond to change in hostwake line */
+static void wakeup_host_work(struct work_struct *work);
/** Transmission timer */
static void bluesleep_tx_timer_expire(unsigned long data);
@@ -89,11 +92,23 @@
struct sk_buff_head txq;
struct work_struct ctxtsw;
+ struct work_struct ws_sleep;
};
-static void hostwake_interrupt(unsigned long data)
+static void hsuart_serial_clock_on(struct tty_struct *tty)
{
- BT_INFO(" wakeup host\n");
+ struct uart_state *state = tty->driver_data;
+ struct uart_port *port = state->uart_port;
+ BT_DBG("");
+ msm_hs_request_clock_on(port);
+}
+
+static void hsuart_serial_clock_off(struct tty_struct *tty)
+{
+ struct uart_state *state = tty->driver_data;
+ struct uart_port *port = state->uart_port;
+ BT_DBG("");
+ msm_hs_request_clock_off(port);
}
static void modify_timer_task(void)
@@ -109,6 +124,7 @@
{
int status = 0;
if (test_bit(BT_TXEXPIRED, &flags)) {
+ hsuart_serial_clock_on(tty);
BT_INFO("wakeup device\n");
gpio_set_value(bsi->ext_wake, 0);
msleep(20);
@@ -118,6 +134,19 @@
return status;
}
+static void wakeup_host_work(struct work_struct *work)
+{
+ struct ath_struct *ath =
+ container_of(work, struct ath_struct, ws_sleep);
+
+ BT_INFO("wake up host");
+ if (test_bit(BT_SLEEPENABLE, &flags)) {
+ if (test_bit(BT_TXEXPIRED, &flags))
+ hsuart_serial_clock_on(ath->hu->tty);
+ }
+ modify_timer_task();
+}
+
static void ath_hci_uart_work(struct work_struct *work)
{
int status;
@@ -141,11 +170,14 @@
static irqreturn_t bluesleep_hostwake_isr(int irq, void *dev_id)
{
/* schedule a tasklet to handle the change in the host wake line */
- tasklet_schedule(&hostwake_task);
+ struct ath_struct *ath = (struct ath_struct *)dev_id;
+
+ schedule_work(&ath->ws_sleep);
+
return IRQ_HANDLED;
}
-static int ath_bluesleep_gpio_config(int on)
+static int ath_bluesleep_gpio_config(struct ath_struct *ath, int on)
{
int ret = 0;
@@ -193,19 +225,16 @@
/* Initialize timer */
init_timer(&tx_timer);
tx_timer.function = bluesleep_tx_timer_expire;
- tx_timer.data = 0;
-
- /* initialize host wake tasklet */
- tasklet_init(&hostwake_task, hostwake_interrupt, 0);
+ tx_timer.data = (u_long)ath->hu;
if (bsi->irq_polarity == POLARITY_LOW) {
ret = request_irq(bsi->host_wake_irq, bluesleep_hostwake_isr,
IRQF_DISABLED | IRQF_TRIGGER_FALLING,
- "bluetooth hostwake", NULL);
+ "bluetooth hostwake", (void *)ath);
} else {
ret = request_irq(bsi->host_wake_irq, bluesleep_hostwake_isr,
IRQF_DISABLED | IRQF_TRIGGER_RISING,
- "bluetooth hostwake", NULL);
+ "bluetooth hostwake", (void *)ath);
}
if (ret < 0) {
BT_ERR("Couldn't acquire BT_HOST_WAKE IRQ");
@@ -221,7 +250,7 @@
return 0;
free_host_wake_irq:
- free_irq(bsi->host_wake_irq, NULL);
+ free_irq(bsi->host_wake_irq, (void *)ath);
delete_timer:
del_timer(&tx_timer);
gpio_ext_wake:
@@ -242,11 +271,6 @@
if (!bsi)
return -EIO;
- if (ath_bluesleep_gpio_config(1) < 0) {
- BT_ERR("HCIATH3K GPIO Config failed");
- return -EIO;
- }
-
ath = kzalloc(sizeof(*ath), GFP_ATOMIC);
if (!ath)
return -ENOMEM;
@@ -256,13 +280,20 @@
hu->priv = ath;
ath->hu = hu;
+ if (ath_bluesleep_gpio_config(ath, 1) < 0) {
+ BT_ERR("HCIATH3K GPIO Config failed");
+ hu->priv = NULL;
+ kfree(ath);
+ return -EIO;
+ }
+
ath->cur_sleep = enableuartsleep;
if (ath->cur_sleep == 1) {
set_bit(BT_SLEEPENABLE, &flags);
modify_timer_task();
}
INIT_WORK(&ath->ctxtsw, ath_hci_uart_work);
-
+ INIT_WORK(&ath->ws_sleep, wakeup_host_work);
return 0;
}
@@ -289,11 +320,13 @@
cancel_work_sync(&ath->ctxtsw);
- hu->priv = NULL;
- kfree(ath);
+ cancel_work_sync(&ath->ws_sleep);
if (bsi)
- ath_bluesleep_gpio_config(0);
+ ath_bluesleep_gpio_config(ath, 0);
+
+ hu->priv = NULL;
+ kfree(ath);
return 0;
}
@@ -383,11 +416,14 @@
static void bluesleep_tx_timer_expire(unsigned long data)
{
+ struct hci_uart *hu = (struct hci_uart *) data;
+
if (!test_bit(BT_SLEEPENABLE, &flags))
return;
BT_INFO("Tx timer expired\n");
set_bit(BT_TXEXPIRED, &flags);
+ hsuart_serial_clock_off(hu->tty);
}
static struct hci_uart_proto athp = {
diff --git a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.h b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.h
index 3500eda..e9987c2 100644
--- a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.h
+++ b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.h
@@ -30,7 +30,7 @@
/**
* TSIF alias name length
*/
-#define TSIF_NAME_LENGTH 10
+#define TSIF_NAME_LENGTH 20
#define MPQ_MAX_FOUND_PATTERNS 5
diff --git a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tsif.c b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tsif.c
index 2e783f6..bbf9d0a 100644
--- a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tsif.c
+++ b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tsif.c
@@ -13,7 +13,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/tsif_api.h>
-#include <linux/workqueue.h>
+#include <linux/kthread.h>
#include <linux/moduleparam.h>
#include "mpq_dvb_debug.h"
#include "mpq_dmx_plugin_common.h"
@@ -38,17 +38,8 @@
static int tsif_mode = DMX_TSIF_DRIVER_MODE_DEF;
static int clock_inv;
module_param(threshold, int, S_IRUGO);
-module_param(tsif_mode, int, S_IRUGO);
-module_param(clock_inv, int, S_IRUGO);
-
-/*
- * Work scheduled each time TSIF notifies dmx
- * of new TS packet
- */
-struct tsif_work {
- struct work_struct work;
- int tsif_id;
-};
+module_param(tsif_mode, int, S_IRUGO | S_IWUSR);
+module_param(clock_inv, int, S_IRUGO | S_IWUSR);
/*
@@ -78,11 +69,12 @@
{
/* Information for each TSIF input processing */
struct {
- /* work used to submit to workqueue for processing */
- struct tsif_work work;
+ /* thread processing TS packets from TSIF */
+ struct task_struct *thread;
+ wait_queue_head_t wait_queue;
- /* workqueue that processes TS packets from specific TSIF */
- struct workqueue_struct *workqueue;
+ /* Counter for data notifications from TSIF */
+ atomic_t data_cnt;
/* TSIF alias */
char name[TSIF_NAME_LENGTH];
@@ -103,94 +95,72 @@
/**
- * Worker function that processes the TS packets notified by the TSIF driver.
+ * Demux thread function handling data from specific TSIF.
*
- * @worker: the executed work
+ * @arg: TSIF number
*/
-static void mpq_dmx_tsif_work(struct work_struct *worker)
+static int mpq_dmx_tsif_thread(void *arg)
{
- struct tsif_work *tsif_work =
- container_of(worker, struct tsif_work, work);
struct mpq_demux *mpq_demux;
struct tsif_driver_info *tsif_driver;
size_t packets = 0;
- int tsif = tsif_work->tsif_id;
+ int tsif = (int)arg;
+ int ret;
- mpq_demux = mpq_dmx_tsif_info.tsif[tsif].mpq_demux;
- tsif_driver = &(mpq_dmx_tsif_info.tsif[tsif].tsif_driver);
+ do {
+ ret = wait_event_interruptible(
+ mpq_dmx_tsif_info.tsif[tsif].wait_queue,
+ (atomic_read(
+ &mpq_dmx_tsif_info.tsif[tsif].data_cnt) != 0) ||
+ kthread_should_stop());
- MPQ_DVB_DBG_PRINT(
- "%s executed, tsif = %d\n",
- __func__,
- tsif);
+ if ((ret < 0) || kthread_should_stop()) {
+ MPQ_DVB_DBG_PRINT("%s: exit\n", __func__);
+ break;
+ }
- if (mutex_lock_interruptible(&mpq_dmx_tsif_info.tsif[tsif].mutex))
- return;
+ if (mutex_lock_interruptible(
+ &mpq_dmx_tsif_info.tsif[tsif].mutex))
+ return -ERESTARTSYS;
- /* Check if driver handler is still valid */
- if (tsif_driver->tsif_handler == NULL) {
- mutex_unlock(&mpq_dmx_tsif_info.tsif[tsif].mutex);
- MPQ_DVB_ERR_PRINT("%s: tsif_driver->tsif_handler is NULL!\n",
+ tsif_driver = &(mpq_dmx_tsif_info.tsif[tsif].tsif_driver);
+ mpq_demux = mpq_dmx_tsif_info.tsif[tsif].mpq_demux;
+
+ /* Check if driver handler is still valid */
+ if (tsif_driver->tsif_handler == NULL) {
+ mutex_unlock(&mpq_dmx_tsif_info.tsif[tsif].mutex);
+ MPQ_DVB_DBG_PRINT(
+ "%s: tsif was detached\n",
__func__);
- return;
- }
+ continue;
+ }
- tsif_get_state(tsif_driver->tsif_handler, &(tsif_driver->ri),
- &(tsif_driver->wi), &(tsif_driver->state));
+ tsif_get_state(
+ tsif_driver->tsif_handler, &(tsif_driver->ri),
+ &(tsif_driver->wi), &(tsif_driver->state));
- if ((tsif_driver->wi == tsif_driver->ri) ||
- (tsif_driver->state == tsif_state_stopped) ||
- (tsif_driver->state == tsif_state_error)) {
+ if ((tsif_driver->wi == tsif_driver->ri) ||
+ (tsif_driver->state == tsif_state_stopped) ||
+ (tsif_driver->state == tsif_state_error)) {
- mpq_demux->hw_notification_size = 0;
+ mpq_demux->hw_notification_size = 0;
- mutex_unlock(&mpq_dmx_tsif_info.tsif[tsif].mutex);
+ mutex_unlock(&mpq_dmx_tsif_info.tsif[tsif].mutex);
- MPQ_DVB_ERR_PRINT(
- "%s: invalid TSIF state (%d), wi = (%d), ri = (%d)\n",
- __func__,
- tsif_driver->state, tsif_driver->wi, tsif_driver->ri);
- return;
- }
+ MPQ_DVB_DBG_PRINT(
+ "%s: TSIF invalid state %d, %d, %d\n",
+ __func__,
+ tsif_driver->state,
+ tsif_driver->wi,
+ tsif_driver->ri);
+ continue;
+ }
- if (tsif_driver->wi > tsif_driver->ri) {
- packets = (tsif_driver->wi - tsif_driver->ri);
- mpq_demux->hw_notification_size = packets;
+ atomic_dec(&mpq_dmx_tsif_info.tsif[tsif].data_cnt);
- dvb_dmx_swfilter_format(
- &mpq_demux->demux,
- (tsif_driver->data_buffer +
- (tsif_driver->ri * TSIF_PKT_SIZE)),
- (packets * TSIF_PKT_SIZE),
- DMX_TSP_FORMAT_192_TAIL);
-
- tsif_driver->ri =
- (tsif_driver->ri + packets) % tsif_driver->buffer_size;
-
- tsif_reclaim_packets(tsif_driver->tsif_handler,
- tsif_driver->ri);
- } else {
- /*
- * wi < ri, means wraparound on cyclic buffer.
- * Handle in two stages.
- */
- packets = (tsif_driver->buffer_size - tsif_driver->ri);
- mpq_demux->hw_notification_size = packets;
-
- dvb_dmx_swfilter_format(
- &mpq_demux->demux,
- (tsif_driver->data_buffer +
- (tsif_driver->ri * TSIF_PKT_SIZE)),
- (packets * TSIF_PKT_SIZE),
- DMX_TSP_FORMAT_192_TAIL);
-
- /* tsif_driver->ri should be 0 after this */
- tsif_driver->ri =
- (tsif_driver->ri + packets) % tsif_driver->buffer_size;
-
- packets = tsif_driver->wi;
- if (packets > 0) {
- mpq_demux->hw_notification_size += packets;
+ if (tsif_driver->wi > tsif_driver->ri) {
+ packets = (tsif_driver->wi - tsif_driver->ri);
+ mpq_demux->hw_notification_size = packets;
dvb_dmx_swfilter_format(
&mpq_demux->demux,
@@ -202,13 +172,55 @@
tsif_driver->ri =
(tsif_driver->ri + packets) %
tsif_driver->buffer_size;
+
+ tsif_reclaim_packets(
+ tsif_driver->tsif_handler,
+ tsif_driver->ri);
+ } else {
+ /*
+ * wi < ri, means wraparound on cyclic buffer.
+ * Handle in two stages.
+ */
+ packets = (tsif_driver->buffer_size - tsif_driver->ri);
+ mpq_demux->hw_notification_size = packets;
+
+ dvb_dmx_swfilter_format(
+ &mpq_demux->demux,
+ (tsif_driver->data_buffer +
+ (tsif_driver->ri * TSIF_PKT_SIZE)),
+ (packets * TSIF_PKT_SIZE),
+ DMX_TSP_FORMAT_192_TAIL);
+
+ /* tsif_driver->ri should be 0 after this */
+ tsif_driver->ri =
+ (tsif_driver->ri + packets) %
+ tsif_driver->buffer_size;
+
+ packets = tsif_driver->wi;
+ if (packets > 0) {
+ mpq_demux->hw_notification_size += packets;
+
+ dvb_dmx_swfilter_format(
+ &mpq_demux->demux,
+ (tsif_driver->data_buffer +
+ (tsif_driver->ri * TSIF_PKT_SIZE)),
+ (packets * TSIF_PKT_SIZE),
+ DMX_TSP_FORMAT_192_TAIL);
+
+ tsif_driver->ri =
+ (tsif_driver->ri + packets) %
+ tsif_driver->buffer_size;
+ }
+
+ tsif_reclaim_packets(
+ tsif_driver->tsif_handler,
+ tsif_driver->ri);
}
- tsif_reclaim_packets(tsif_driver->tsif_handler,
- tsif_driver->ri);
- }
+ mutex_unlock(&mpq_dmx_tsif_info.tsif[tsif].mutex);
+ } while (1);
- mutex_unlock(&mpq_dmx_tsif_info.tsif[tsif].mutex);
+ return 0;
}
@@ -220,7 +232,6 @@
static void mpq_tsif_callback(void *user)
{
int tsif = (int)user;
- struct work_struct *work;
struct mpq_demux *mpq_demux;
MPQ_DVB_DBG_PRINT("%s executed, tsif = %d\n", __func__, tsif);
@@ -229,11 +240,8 @@
mpq_demux = mpq_dmx_tsif_info.tsif[tsif].mpq_demux;
mpq_dmx_update_hw_statistics(mpq_demux);
- work = &mpq_dmx_tsif_info.tsif[tsif].work.work;
-
- /* Scheudle a new work to demux workqueue */
- if (!work_pending(work))
- queue_work(mpq_dmx_tsif_info.tsif[tsif].workqueue, work);
+ atomic_inc(&mpq_dmx_tsif_info.tsif[tsif].data_cnt);
+ wake_up(&mpq_dmx_tsif_info.tsif[tsif].wait_queue);
}
@@ -376,20 +384,10 @@
tsif_driver = &(mpq_dmx_tsif_info.tsif[tsif].tsif_driver);
tsif_stop(tsif_driver->tsif_handler);
tsif_detach(tsif_driver->tsif_handler);
- /*
- * temporarily release mutex and flush the work queue
- * before setting tsif_handler to NULL
- */
- mutex_unlock(&mpq_dmx_tsif_info.tsif[tsif].mutex);
- flush_workqueue(mpq_dmx_tsif_info.tsif[tsif].workqueue);
- /* re-acquire mutex */
- if (mutex_lock_interruptible(
- &mpq_dmx_tsif_info.tsif[tsif].mutex))
- return -ERESTARTSYS;
-
tsif_driver->tsif_handler = NULL;
tsif_driver->data_buffer = NULL;
tsif_driver->buffer_size = 0;
+ atomic_set(&mpq_dmx_tsif_info.tsif[tsif].data_cnt, 0);
mpq_dmx_tsif_info.tsif[tsif].mpq_demux = NULL;
}
@@ -708,31 +706,28 @@
}
for (i = 0; i < TSIF_COUNT; i++) {
- mpq_dmx_tsif_info.tsif[i].work.tsif_id = i;
-
- INIT_WORK(&mpq_dmx_tsif_info.tsif[i].work.work,
- mpq_dmx_tsif_work);
-
snprintf(mpq_dmx_tsif_info.tsif[i].name,
TSIF_NAME_LENGTH,
- "tsif_%d",
+ "dmx_tsif%d",
i);
- mpq_dmx_tsif_info.tsif[i].workqueue =
- create_singlethread_workqueue(
+ atomic_set(&mpq_dmx_tsif_info.tsif[i].data_cnt, 0);
+ init_waitqueue_head(&mpq_dmx_tsif_info.tsif[i].wait_queue);
+ mpq_dmx_tsif_info.tsif[i].thread =
+ kthread_run(
+ mpq_dmx_tsif_thread, (void *)i,
mpq_dmx_tsif_info.tsif[i].name);
- if (mpq_dmx_tsif_info.tsif[i].workqueue == NULL) {
+ if (IS_ERR(mpq_dmx_tsif_info.tsif[i].thread)) {
int j;
for (j = 0; j < i; j++) {
- destroy_workqueue(
- mpq_dmx_tsif_info.tsif[j].workqueue);
+ kthread_stop(mpq_dmx_tsif_info.tsif[j].thread);
mutex_destroy(&mpq_dmx_tsif_info.tsif[j].mutex);
}
MPQ_DVB_ERR_PRINT(
- "%s: create_singlethread_workqueue failed\n",
+ "%s: kthread_run failed\n",
__func__);
return -ENOMEM;
@@ -753,7 +748,7 @@
ret);
for (i = 0; i < TSIF_COUNT; i++) {
- destroy_workqueue(mpq_dmx_tsif_info.tsif[i].workqueue);
+ kthread_stop(mpq_dmx_tsif_info.tsif[i].thread);
mutex_destroy(&mpq_dmx_tsif_info.tsif[i].mutex);
}
}
@@ -781,16 +776,13 @@
if (tsif_driver->tsif_handler)
tsif_stop(tsif_driver->tsif_handler);
}
+
/* Detach from TSIF driver to avoid further notifications. */
if (tsif_driver->tsif_handler)
tsif_detach(tsif_driver->tsif_handler);
- /* release mutex to allow work queue to finish scheduled work */
mutex_unlock(&mpq_dmx_tsif_info.tsif[i].mutex);
- /* flush the work queue and destroy it */
- flush_workqueue(mpq_dmx_tsif_info.tsif[i].workqueue);
- destroy_workqueue(mpq_dmx_tsif_info.tsif[i].workqueue);
-
+ kthread_stop(mpq_dmx_tsif_info.tsif[i].thread);
mutex_destroy(&mpq_dmx_tsif_info.tsif[i].mutex);
}
diff --git a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tspp_v1.c b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tspp_v1.c
index 360d96a..f5c01e1 100644
--- a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tspp_v1.c
+++ b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tspp_v1.c
@@ -12,12 +12,11 @@
#include <linux/init.h>
#include <linux/module.h>
-#include <linux/workqueue.h>
+#include <linux/kthread.h>
#include <mach/msm_tspp.h>
#include "mpq_dvb_debug.h"
#include "mpq_dmx_plugin_common.h"
-
#define TSIF_COUNT 2
#define TSPP_MAX_PID_FILTER_NUM 16
@@ -28,6 +27,7 @@
/* For each TSIF we allocate two pipes, one for PES and one for sections */
#define TSPP_PES_CHANNEL 0
#define TSPP_SECTION_CHANNEL 1
+#define TSPP_CHANNEL_COUNT 2
/* the channel_id set to TSPP driver based on TSIF number and channel type */
#define TSPP_CHANNEL_ID(tsif, ch) ((tsif << 1) + ch)
@@ -84,18 +84,10 @@
static int clock_inv;
static int tsif_mode = 2;
static int allocation_mode = MPQ_DMX_TSPP_INTERNAL_ALLOC;
-module_param(tsif_mode, int, S_IRUGO);
-module_param(clock_inv, int, S_IRUGO);
+module_param(tsif_mode, int, S_IRUGO | S_IWUSR);
+module_param(clock_inv, int, S_IRUGO | S_IWUSR);
module_param(allocation_mode, int, S_IRUGO);
-/*
- * Work scheduled each time TSPP notifies dmx
- * of new TS packet in some channel
- */
-struct tspp_work {
- struct work_struct work;
- int channel_id;
-};
/* The following structure hold singelton information
* required for dmx implementation on top of TSPP.
@@ -111,8 +103,8 @@
*/
int pes_channel_ref;
- /* work used to submit to workqueue to process pes channel */
- struct tspp_work pes_work;
+ /* Counter for data notifications on PES pipe */
+ atomic_t pes_data_cnt;
/* ION handle used for TSPP data buffer allocation */
struct ion_handle *pes_mem_heap_handle;
@@ -130,8 +122,8 @@
*/
int section_channel_ref;
- /* work used to submit to workqueue to process pes channel */
- struct tspp_work section_work;
+ /* Counter for data notifications on section pipe */
+ atomic_t section_data_cnt;
/* ION handle used for TSPP data buffer allocation */
struct ion_handle *section_mem_heap_handle;
@@ -151,8 +143,9 @@
int ref_count;
} filters[TSPP_MAX_PID_FILTER_NUM];
- /* workqueue that processes TS packets from specific TSIF */
- struct workqueue_struct *workqueue;
+ /* thread processing TS packets from TSPP */
+ struct task_struct *thread;
+ wait_queue_head_t wait_queue;
/* TSIF alias */
char name[TSIF_NAME_LENGTH];
@@ -274,55 +267,93 @@
}
/**
- * Worker function that processes the TS packets notified by TSPP.
+ * Demux thread function handling data from specific TSIF.
*
- * @worker: the executed work
+ * @arg: TSIF number
*/
-static void mpq_dmx_tspp_work(struct work_struct *worker)
+static int mpq_dmx_tspp_thread(void *arg)
{
- struct tspp_work *tspp_work =
- container_of(worker, struct tspp_work, work);
+ int tsif = (int)arg;
struct mpq_demux *mpq_demux;
- int channel_id = tspp_work->channel_id;
- int tsif = TSPP_GET_TSIF_NUM(channel_id);
const struct tspp_data_descriptor *tspp_data_desc;
+ atomic_t *data_cnt;
int ref_count;
+ int ret;
+ int i;
- mpq_demux = mpq_dmx_tspp_info.tsif[tsif].mpq_demux;
+ do {
+ ret = wait_event_interruptible(
+ mpq_dmx_tspp_info.tsif[tsif].wait_queue,
+ (atomic_read(
+ &mpq_dmx_tspp_info.tsif[tsif].pes_data_cnt)) ||
+ (atomic_read(
+ &mpq_dmx_tspp_info.tsif[tsif].section_data_cnt)) ||
+ kthread_should_stop());
- /* Lock against the TSPP filters data-structure */
- if (mutex_lock_interruptible(&mpq_dmx_tspp_info.tsif[tsif].mutex))
- return;
+ if ((ret < 0) || kthread_should_stop()) {
+ MPQ_DVB_ERR_PRINT("%s: exit\n", __func__);
+ break;
+ }
- /* Make sure channel is still active */
- if (TSPP_IS_PES_CHANNEL(channel_id))
- ref_count = mpq_dmx_tspp_info.tsif[tsif].pes_channel_ref;
- else
- ref_count = mpq_dmx_tspp_info.tsif[tsif].section_channel_ref;
+ /* Lock against the TSPP filters data-structure */
+ if (mutex_lock_interruptible(
+ &mpq_dmx_tspp_info.tsif[tsif].mutex))
+ return -ERESTARTSYS;
- if (ref_count == 0) {
+ for (i = 0; i < TSPP_CHANNEL_COUNT; i++) {
+ int channel_id = TSPP_CHANNEL_ID(tsif, i);
+
+ if (TSPP_IS_PES_CHANNEL(channel_id)) {
+ ref_count =
+ mpq_dmx_tspp_info.tsif[tsif].pes_channel_ref;
+ data_cnt =
+ &mpq_dmx_tspp_info.tsif[tsif].pes_data_cnt;
+ } else {
+ ref_count =
+ mpq_dmx_tspp_info.tsif[tsif].
+ section_channel_ref;
+ data_cnt =
+ &mpq_dmx_tspp_info.tsif[tsif].section_data_cnt;
+ }
+
+ /* Make sure channel is still active */
+ if (ref_count == 0)
+ continue;
+
+ atomic_dec(data_cnt);
+
+ mpq_demux = mpq_dmx_tspp_info.tsif[tsif].mpq_demux;
+ mpq_demux->hw_notification_size = 0;
+
+ /*
+ * Go through all filled descriptors
+ * and perform demuxing on them
+ */
+ while ((tspp_data_desc =
+ tspp_get_buffer(0, channel_id)) != NULL) {
+ mpq_demux->hw_notification_size +=
+ (tspp_data_desc->size /
+ TSPP_RAW_TTS_SIZE);
+
+ dvb_dmx_swfilter_format(
+ &mpq_demux->demux,
+ tspp_data_desc->virt_base,
+ tspp_data_desc->size,
+ DMX_TSP_FORMAT_192_TAIL);
+
+ /*
+ * Notify TSPP that the buffer
+ * is no longer needed
+ */
+ tspp_release_buffer(0,
+ channel_id, tspp_data_desc->id);
+ }
+ }
+
mutex_unlock(&mpq_dmx_tspp_info.tsif[tsif].mutex);
- return;
- }
+ } while (1);
- mpq_demux->hw_notification_size = 0;
-
- /* Go through all filled descriptors and perform demuxing on them */
- while ((tspp_data_desc = tspp_get_buffer(0, channel_id)) != NULL) {
- mpq_demux->hw_notification_size +=
- (tspp_data_desc->size / TSPP_RAW_TTS_SIZE);
-
- dvb_dmx_swfilter_format(
- &mpq_demux->demux,
- tspp_data_desc->virt_base,
- tspp_data_desc->size,
- DMX_TSP_FORMAT_192_TAIL);
-
- /* Notify TSPP that the buffer is no longer needed */
- tspp_release_buffer(0, channel_id, tspp_data_desc->id);
- }
-
- mutex_unlock(&mpq_dmx_tspp_info.tsif[tsif].mutex);
+ return 0;
}
/**
@@ -334,7 +365,6 @@
static void mpq_tspp_callback(int channel_id, void *user)
{
int tsif = (int)user;
- struct work_struct *work;
struct mpq_demux *mpq_demux;
/* Save statistics on TSPP notifications */
@@ -342,13 +372,11 @@
mpq_dmx_update_hw_statistics(mpq_demux);
if (TSPP_IS_PES_CHANNEL(channel_id))
- work = &mpq_dmx_tspp_info.tsif[tsif].pes_work.work;
+ atomic_inc(&mpq_dmx_tspp_info.tsif[tsif].pes_data_cnt);
else
- work = &mpq_dmx_tspp_info.tsif[tsif].section_work.work;
+ atomic_inc(&mpq_dmx_tspp_info.tsif[tsif].section_data_cnt);
- /* Scheudle a new work to demux workqueue */
- if (!work_pending(work))
- queue_work(mpq_dmx_tspp_info.tsif[tsif].workqueue, work);
+ wake_up(&mpq_dmx_tspp_info.tsif[tsif].wait_queue);
}
/**
@@ -586,6 +614,7 @@
int tsif;
int ret;
int channel_id;
+ atomic_t *data_cnt;
int *channel_ref_count;
struct tspp_filter tspp_filter;
struct mpq_demux *mpq_demux = feed->demux->priv;
@@ -613,10 +642,12 @@
channel_id = TSPP_CHANNEL_ID(tsif, TSPP_PES_CHANNEL);
channel_ref_count =
&mpq_dmx_tspp_info.tsif[tsif].pes_channel_ref;
+ data_cnt = &mpq_dmx_tspp_info.tsif[tsif].pes_data_cnt;
} else {
channel_id = TSPP_CHANNEL_ID(tsif, TSPP_SECTION_CHANNEL);
channel_ref_count =
&mpq_dmx_tspp_info.tsif[tsif].section_channel_ref;
+ data_cnt = &mpq_dmx_tspp_info.tsif[tsif].section_data_cnt;
}
/* check if required TSPP pipe is already allocated or not */
@@ -677,6 +708,7 @@
tspp_unregister_notification(0, channel_id);
tspp_close_channel(0, channel_id);
tspp_close_stream(0, channel_id);
+ atomic_set(data_cnt, 0);
}
mutex_unlock(&mpq_dmx_tspp_info.tsif[tsif].mutex);
@@ -1079,24 +1111,14 @@
mpq_dmx_tspp_info.tsif[i].pes_mem_heap_handle = NULL;
mpq_dmx_tspp_info.tsif[i].pes_mem_heap_virt_base = NULL;
mpq_dmx_tspp_info.tsif[i].pes_mem_heap_phys_base = 0;
-
- mpq_dmx_tspp_info.tsif[i].pes_work.channel_id =
- TSPP_CHANNEL_ID(i, TSPP_PES_CHANNEL);
-
- INIT_WORK(&mpq_dmx_tspp_info.tsif[i].pes_work.work,
- mpq_dmx_tspp_work);
+ atomic_set(&mpq_dmx_tspp_info.tsif[i].pes_data_cnt, 0);
mpq_dmx_tspp_info.tsif[i].section_channel_ref = 0;
mpq_dmx_tspp_info.tsif[i].section_index = 0;
mpq_dmx_tspp_info.tsif[i].section_mem_heap_handle = NULL;
mpq_dmx_tspp_info.tsif[i].section_mem_heap_virt_base = NULL;
mpq_dmx_tspp_info.tsif[i].section_mem_heap_phys_base = 0;
-
- mpq_dmx_tspp_info.tsif[i].section_work.channel_id =
- TSPP_CHANNEL_ID(i, TSPP_SECTION_CHANNEL);
-
- INIT_WORK(&mpq_dmx_tspp_info.tsif[i].section_work.work,
- mpq_dmx_tspp_work);
+ atomic_set(&mpq_dmx_tspp_info.tsif[i].section_data_cnt, 0);
for (j = 0; j < TSPP_MAX_PID_FILTER_NUM; j++) {
mpq_dmx_tspp_info.tsif[i].filters[j].pid = -1;
@@ -1105,22 +1127,23 @@
snprintf(mpq_dmx_tspp_info.tsif[i].name,
TSIF_NAME_LENGTH,
- "tsif_%d",
+ "dmx_tsif%d",
i);
- mpq_dmx_tspp_info.tsif[i].workqueue =
- create_singlethread_workqueue(
+ init_waitqueue_head(&mpq_dmx_tspp_info.tsif[i].wait_queue);
+ mpq_dmx_tspp_info.tsif[i].thread =
+ kthread_run(
+ mpq_dmx_tspp_thread, (void *)i,
mpq_dmx_tspp_info.tsif[i].name);
- if (mpq_dmx_tspp_info.tsif[i].workqueue == NULL) {
+ if (IS_ERR(mpq_dmx_tspp_info.tsif[i].thread)) {
for (j = 0; j < i; j++) {
- destroy_workqueue(
- mpq_dmx_tspp_info.tsif[j].workqueue);
-
+ kthread_stop(mpq_dmx_tspp_info.tsif[j].thread);
mutex_destroy(&mpq_dmx_tspp_info.tsif[j].mutex);
}
+
MPQ_DVB_ERR_PRINT(
- "%s: create_singlethread_workqueue failed\n",
+ "%s: kthread_run failed\n",
__func__);
return -ENOMEM;
@@ -1138,7 +1161,7 @@
ret);
for (i = 0; i < TSIF_COUNT; i++) {
- destroy_workqueue(mpq_dmx_tspp_info.tsif[i].workqueue);
+ kthread_stop(mpq_dmx_tspp_info.tsif[i].thread);
mutex_destroy(&mpq_dmx_tspp_info.tsif[i].mutex);
}
}
@@ -1179,8 +1202,7 @@
mpq_dmx_tsif_ion_cleanup(i);
mutex_unlock(&mpq_dmx_tspp_info.tsif[i].mutex);
- flush_workqueue(mpq_dmx_tspp_info.tsif[i].workqueue);
- destroy_workqueue(mpq_dmx_tspp_info.tsif[i].workqueue);
+ kthread_stop(mpq_dmx_tspp_info.tsif[i].thread);
mutex_destroy(&mpq_dmx_tspp_info.tsif[i].mutex);
}
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_hw_reg.h b/drivers/media/video/msm/jpeg_10/msm_jpeg_hw_reg.h
index ff99aa3..31286dd 100644
--- a/drivers/media/video/msm/jpeg_10/msm_jpeg_hw_reg.h
+++ b/drivers/media/video/msm/jpeg_10/msm_jpeg_hw_reg.h
@@ -126,5 +126,11 @@
#define JPEG_VBIF_OUT_WR_LIM_CONF0 0xD4
#define JPEG_VBIF_DDR_OUT_MAX_BURST 0xD8
#define JPEG_VBIF_OCMEM_OUT_MAX_BURST 0xDC
+#define JPEG_VBIF_ARB_CTL 0xF0
+#define JPEG_VBIF_OUT_AXI_AOOO_EN 0x178
+#define JPEG_VBIF_OUT_AXI_AOOO 0x17c
+#define JPEG_VBIF_ROUND_ROBIN_QOS_ARB 0x124
+#define JPEG_VBIF_OUT_AXI_AMEMTYPE_CONF0 0x160
+#define JPEG_VBIF_OUT_AXI_AMEMTYPE_CONF1 0x164
#endif /* MSM_JPEG_HW_REG_H */
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_platform.c b/drivers/media/video/msm/jpeg_10/msm_jpeg_platform.c
index 06135ec..38a0ffb 100644
--- a/drivers/media/video/msm/jpeg_10/msm_jpeg_platform.c
+++ b/drivers/media/video/msm/jpeg_10/msm_jpeg_platform.c
@@ -108,12 +108,26 @@
jpeg_vbif_base + JPEG_VBIF_IN_WR_LIM_CONF2);
writel_relaxed(0x00001010,
jpeg_vbif_base + JPEG_VBIF_OUT_RD_LIM_CONF0);
- writel_relaxed(0x00001010,
+ writel_relaxed(0x00000110,
jpeg_vbif_base + JPEG_VBIF_OUT_WR_LIM_CONF0);
writel_relaxed(0x00000707,
jpeg_vbif_base + JPEG_VBIF_DDR_OUT_MAX_BURST);
- writel_relaxed(0x00000707,
+ writel_relaxed(0x7,
jpeg_vbif_base + JPEG_VBIF_OCMEM_OUT_MAX_BURST);
+ writel_relaxed(0x00000030,
+ jpeg_vbif_base + JPEG_VBIF_ARB_CTL);
+ writel_relaxed(0x00000FFF,
+ jpeg_vbif_base + JPEG_VBIF_OUT_AXI_AOOO_EN);
+ writel_relaxed(0x0FFF0FFF,
+ jpeg_vbif_base + JPEG_VBIF_OUT_AXI_AOOO);
+ /*FE and WE QOS configuration need to be set when
+ QOS RR arbitration is enabled*/
+ writel_relaxed(0x00000001,
+ jpeg_vbif_base + JPEG_VBIF_ROUND_ROBIN_QOS_ARB);
+ writel_relaxed(0x22222222,
+ jpeg_vbif_base + JPEG_VBIF_OUT_AXI_AMEMTYPE_CONF0);
+ writel_relaxed(0x2222,
+ jpeg_vbif_base + JPEG_VBIF_OUT_AXI_AMEMTYPE_CONF1);
}
diff --git a/drivers/media/video/msm/sensors/msm_sensor.c b/drivers/media/video/msm/sensors/msm_sensor.c
index 63cf38e..907523c 100644
--- a/drivers/media/video/msm/sensors/msm_sensor.c
+++ b/drivers/media/video/msm/sensors/msm_sensor.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -603,6 +603,8 @@
{
int32_t rc = 0;
uint32_t val = 0;
+ struct msm_camera_sensor_flash_data *flash_data = NULL;
+ struct device_node *flash_src_node = NULL;
sensordata->flash_data = kzalloc(sizeof(
struct msm_camera_sensor_flash_data), GFP_KERNEL);
@@ -611,16 +613,42 @@
return -ENOMEM;
}
- rc = of_property_read_u32(of_node, "qcom,flash-type", &val);
+ if (!of_get_property(of_node, "qcom,flash-src-index", &val)) {
+ CDBG("%s flash not available\n", __func__);
+ return rc;
+ }
+ flash_data = sensordata->flash_data;
+
+ flash_src_node = of_parse_phandle(of_node, "qcom,flash-src-index", 0);
+ if (!flash_src_node) {
+ pr_err("%s:%d flash_src_node NULL\n", __func__,
+ __LINE__);
+ goto ERROR1;
+ }
+
+ rc = of_property_read_u32(flash_src_node, "qcom,flash-type", &val);
CDBG("%s qcom,flash-type %d, rc %d\n", __func__, val, rc);
if (rc < 0) {
pr_err("%s failed %d\n", __func__, __LINE__);
- goto ERROR;
+ goto ERROR2;
}
- sensordata->flash_data->flash_type = val;
+ flash_data->flash_type = val;
+
+ rc = of_property_read_u32(flash_src_node, "cell-index", &val);
+ CDBG("%s qcom,flash-src-index %d, rc %d\n", __func__, val, rc);
+ if (rc < 0) {
+ pr_err("%s failed %d\n", __func__, __LINE__);
+ goto ERROR2;
+ }
+ flash_data->flash_src_index = val;
+
+ of_node_put(flash_src_node);
+
return rc;
-ERROR:
- kfree(sensordata->flash_data);
+ERROR2:
+ of_node_put(flash_src_node);
+ERROR1:
+ flash_data->flash_type = MSM_CAMERA_FLASH_NONE;
return rc;
}
diff --git a/drivers/media/video/msm/vfe/msm_vfe40.c b/drivers/media/video/msm/vfe/msm_vfe40.c
index 287c77c..81a6dd2 100644
--- a/drivers/media/video/msm/vfe/msm_vfe40.c
+++ b/drivers/media/video/msm/vfe/msm_vfe40.c
@@ -5170,39 +5170,44 @@
static void msm_vfe40_init_vbif_parms(void __iomem *vfe_vbif_base)
{
- msm_camera_io_w_mb(0x1,
+ msm_camera_io_w(0x1,
vfe_vbif_base + VFE40_VBIF_CLKON);
- msm_camera_io_w_mb(0x1,
- vfe_vbif_base + VFE40_VBIF_ROUND_ROBIN_QOS_ARB);
- msm_camera_io_w_mb(0xFFFF,
- vfe_vbif_base + VFE40_VBIF_OUT_AXI_AOOO_EN);
- msm_camera_io_w_mb(0xFFFFFFFF,
- vfe_vbif_base + VFE40_VBIF_OUT_AXI_AOOO);
-
- msm_camera_io_w_mb(0x10101010,
+ msm_camera_io_w(0x01010101,
vfe_vbif_base + VFE40_VBIF_IN_RD_LIM_CONF0);
- msm_camera_io_w_mb(0x10101010,
+ msm_camera_io_w(0x01010101,
vfe_vbif_base + VFE40_VBIF_IN_RD_LIM_CONF1);
- msm_camera_io_w_mb(0x10101010,
+ msm_camera_io_w(0x10010110,
vfe_vbif_base + VFE40_VBIF_IN_RD_LIM_CONF2);
- msm_camera_io_w_mb(0x10101010,
+ msm_camera_io_w(0x10101010,
vfe_vbif_base + VFE40_VBIF_IN_WR_LIM_CONF0);
- msm_camera_io_w_mb(0x10101010,
+ msm_camera_io_w(0x10101010,
vfe_vbif_base + VFE40_VBIF_IN_WR_LIM_CONF1);
- msm_camera_io_w_mb(0x10101010,
+ msm_camera_io_w(0x10101010,
vfe_vbif_base + VFE40_VBIF_IN_WR_LIM_CONF2);
- msm_camera_io_w_mb(0x00001010,
+ msm_camera_io_w(0x00001010,
vfe_vbif_base + VFE40_VBIF_OUT_RD_LIM_CONF0);
- msm_camera_io_w_mb(0x00001010,
+ msm_camera_io_w(0x00001010,
vfe_vbif_base + VFE40_VBIF_OUT_WR_LIM_CONF0);
- msm_camera_io_w_mb(0x00000707,
+ msm_camera_io_w(0x00000707,
vfe_vbif_base + VFE40_VBIF_DDR_OUT_MAX_BURST);
- msm_camera_io_w_mb(0x00000030,
+ msm_camera_io_w(0x00000707,
+ vfe_vbif_base + VFE40_VBIF_OCMEM_OUT_MAX_BURST);
+ msm_camera_io_w(0x00000030,
vfe_vbif_base + VFE40_VBIF_ARB_CTL);
- msm_camera_io_w_mb(0x04210842,
+ msm_camera_io_w(0x04210842,
vfe_vbif_base + VFE40_VBIF_DDR_ARB_CONF0);
- msm_camera_io_w_mb(0x04210842,
+ msm_camera_io_w(0x04210842,
vfe_vbif_base + VFE40_VBIF_DDR_ARB_CONF1);
+ msm_camera_io_w(0x00000001,
+ vfe_vbif_base + VFE40_VBIF_ROUND_ROBIN_QOS_ARB);
+ msm_camera_io_w(0x22222222,
+ vfe_vbif_base + VFE40_VBIF_OUT_AXI_AMEMTYPE_CONF0);
+ msm_camera_io_w(0x00002222,
+ vfe_vbif_base + VFE40_VBIF_OUT_AXI_AMEMTYPE_CONF1);
+ msm_camera_io_w(0x00000FFF,
+ vfe_vbif_base + VFE40_VBIF_OUT_AXI_AOOO_EN);
+ msm_camera_io_w(0x0FFF0FFF,
+ vfe_vbif_base + VFE40_VBIF_OUT_AXI_AOOO);
}
int msm_axi_subdev_init(struct v4l2_subdev *sd)
diff --git a/drivers/media/video/msm/vfe/msm_vfe40.h b/drivers/media/video/msm/vfe/msm_vfe40.h
index 4acc7e4..a94c428 100644
--- a/drivers/media/video/msm/vfe/msm_vfe40.h
+++ b/drivers/media/video/msm/vfe/msm_vfe40.h
@@ -901,22 +901,25 @@
#define VFE40_OUTPUT_MODE_TERTIARY1 BIT(10)
#define VFE40_OUTPUT_MODE_TERTIARY2 BIT(11)
-#define VFE40_VBIF_CLKON 0x4
-#define VFE40_VBIF_IN_RD_LIM_CONF0 0xB0
-#define VFE40_VBIF_IN_RD_LIM_CONF1 0xB4
-#define VFE40_VBIF_IN_RD_LIM_CONF2 0xB8
-#define VFE40_VBIF_IN_WR_LIM_CONF0 0xC0
-#define VFE40_VBIF_IN_WR_LIM_CONF1 0xC4
-#define VFE40_VBIF_IN_WR_LIM_CONF2 0xC8
-#define VFE40_VBIF_OUT_RD_LIM_CONF0 0xD0
-#define VFE40_VBIF_OUT_WR_LIM_CONF0 0xD4
-#define VFE40_VBIF_DDR_OUT_MAX_BURST 0xD8
-#define VFE40_VBIF_ARB_CTL 0xF0
-#define VFE40_VBIF_DDR_ARB_CONF0 0xF4
-#define VFE40_VBIF_DDR_ARB_CONF1 0xF8
-#define VFE40_VBIF_ROUND_ROBIN_QOS_ARB 0x124
-#define VFE40_VBIF_OUT_AXI_AOOO_EN 0x178
-#define VFE40_VBIF_OUT_AXI_AOOO 0x17C
+#define VFE40_VBIF_CLKON 0x4
+#define VFE40_VBIF_IN_RD_LIM_CONF0 0xB0
+#define VFE40_VBIF_IN_RD_LIM_CONF1 0xB4
+#define VFE40_VBIF_IN_RD_LIM_CONF2 0xB8
+#define VFE40_VBIF_IN_WR_LIM_CONF0 0xC0
+#define VFE40_VBIF_IN_WR_LIM_CONF1 0xC4
+#define VFE40_VBIF_IN_WR_LIM_CONF2 0xC8
+#define VFE40_VBIF_OUT_RD_LIM_CONF0 0xD0
+#define VFE40_VBIF_OUT_WR_LIM_CONF0 0xD4
+#define VFE40_VBIF_DDR_OUT_MAX_BURST 0xD8
+#define VFE40_VBIF_OCMEM_OUT_MAX_BURST 0xDC
+#define VFE40_VBIF_ARB_CTL 0xF0
+#define VFE40_VBIF_DDR_ARB_CONF0 0xF4
+#define VFE40_VBIF_DDR_ARB_CONF1 0xF8
+#define VFE40_VBIF_ROUND_ROBIN_QOS_ARB 0x124
+#define VFE40_VBIF_OUT_AXI_AMEMTYPE_CONF0 0x160
+#define VFE40_VBIF_OUT_AXI_AMEMTYPE_CONF1 0x164
+#define VFE40_VBIF_OUT_AXI_AOOO_EN 0x178
+#define VFE40_VBIF_OUT_AXI_AOOO 0x17C
struct vfe_stats_control {
uint32_t droppedStatsFrameCount;
diff --git a/drivers/media/video/msm_vidc/msm_smem.c b/drivers/media/video/msm_vidc/msm_smem.c
index 83f33a1..e1b73ef 100644
--- a/drivers/media/video/msm_vidc/msm_smem.c
+++ b/drivers/media/video/msm_vidc/msm_smem.c
@@ -32,8 +32,6 @@
clnt, hndl, iova, buffer_size);
return -EINVAL;
}
- if (align < 4096)
- align = 4096;
dprintk(VIDC_DBG, "domain: %d, partition: %d\n",
domain_num, partition_num);
if (flags & SMEM_SECURE) {
@@ -74,6 +72,7 @@
unsigned long iova = 0;
unsigned long buffer_size = 0;
int rc = 0;
+ int align = SZ_4K;
hndl = ion_import_dma_buf(client->clnt, fd);
if (IS_ERR_OR_NULL(hndl)) {
dprintk(VIDC_ERR, "Failed to get handle: %p, %d, %d, %p\n",
@@ -85,8 +84,12 @@
mem->domain = domain;
mem->partition_num = partition;
mem->flags = flags;
+
+ if (flags & SMEM_SECURE)
+ align = ALIGN(align, SZ_1M);
+
rc = get_device_address(client->clnt, hndl, mem->domain,
- mem->partition_num, 4096, &iova, &buffer_size, flags);
+ mem->partition_num, align, &iova, &buffer_size, flags);
if (rc) {
dprintk(VIDC_ERR, "Failed to get device address: %d\n", rc);
goto fail_device_address;
@@ -121,15 +124,16 @@
else
ionflags = ION_SET_UNCACHED(ionflags);
+ align = ALIGN(align, SZ_4K);
+ size = ALIGN(size, SZ_4K);
+
if (flags & SMEM_SECURE) {
ionflags |= ION_SECURE;
- size = (size + 0xfffff) & (~0xfffff);
+ size = ALIGN(size, SZ_1M);
+ align = ALIGN(align, SZ_1M);
}
heap_mask = ION_HEAP(ION_CP_MM_HEAP_ID);
- if (align < 4096)
- align = 4096;
- size = (size + 4095) & (~4095);
dprintk(VIDC_DBG, "domain: %d, partition: %d\n",
domain, partition);
hndl = ion_alloc(client->clnt, size, align, heap_mask, ionflags);
diff --git a/drivers/media/video/msm_vidc/msm_vdec.c b/drivers/media/video/msm_vidc/msm_vdec.c
index c281f9c..e0a341a 100644
--- a/drivers/media/video/msm_vidc/msm_vdec.c
+++ b/drivers/media/video/msm_vidc/msm_vdec.c
@@ -462,7 +462,7 @@
b->m.planes[extra_idx].m.userptr;
else
buffer_info.extradata_addr = 0;
-
+ buffer_info.response_required = false;
rc = vidc_hal_session_release_buffers(
(void *)inst->session, &buffer_info);
if (rc)
diff --git a/drivers/media/video/msm_vidc/msm_venc.c b/drivers/media/video/msm_vidc/msm_venc.c
index f4c973f..f436cf3 100644
--- a/drivers/media/video/msm_vidc/msm_venc.c
+++ b/drivers/media/video/msm_vidc/msm_venc.c
@@ -1569,6 +1569,7 @@
b->m.planes[i].m.userptr;
buffer_info.extradata_size = 0;
buffer_info.extradata_addr = 0;
+ buffer_info.response_required = false;
rc = vidc_hal_session_release_buffers(
(void *)inst->session, &buffer_info);
if (rc)
diff --git a/drivers/media/video/msm_vidc/msm_vidc_common.c b/drivers/media/video/msm_vidc/msm_vidc_common.c
index 87f53ac..46a88c2 100644
--- a/drivers/media/video/msm_vidc/msm_vidc_common.c
+++ b/drivers/media/video/msm_vidc/msm_vidc_common.c
@@ -354,6 +354,48 @@
}
}
+static void handle_session_release_buf_done(enum command_response cmd,
+ void *data)
+{
+ struct msm_vidc_cb_cmd_done *response = data;
+ struct msm_vidc_inst *inst;
+ struct internal_buf *buf;
+ struct list_head *ptr, *next;
+ struct hal_buffer_info *buffer;
+ u32 address, buf_found = false;
+
+ if (!response || !response->data) {
+ dprintk(VIDC_ERR, "Invalid release_buf_done response\n");
+ return;
+ }
+
+ inst = (struct msm_vidc_inst *)response->session_id;
+ buffer = (struct hal_buffer_info *) response->data;
+ address = (u32) buffer->buffer_addr;
+
+ list_for_each_safe(ptr, next, &inst->internalbufs) {
+ buf = list_entry(ptr, struct internal_buf, list);
+ if (address == buf->handle->device_addr) {
+ dprintk(VIDC_DBG, "releasing scratch: 0x%x",
+ (u32) buf->handle->device_addr);
+ buf_found = true;
+ }
+ }
+
+ list_for_each_safe(ptr, next, &inst->persistbufs) {
+ buf = list_entry(ptr, struct internal_buf, list);
+ if (address == (u32) buf->handle->device_addr) {
+ dprintk(VIDC_DBG, "releasing persist: 0x%x",
+ (u32) buf->handle->device_addr);
+ buf_found = true;
+ }
+ }
+
+ if (!buf_found)
+ dprintk(VIDC_ERR, "invalid buffer received from firmware");
+ complete(&inst->completions[SESSION_MSG_INDEX(cmd)]);
+}
+
static void handle_sys_release_res_done(
enum command_response cmd, void *data)
{
@@ -892,6 +934,9 @@
case SESSION_ERROR:
handle_session_error(cmd, data);
break;
+ case SESSION_RELEASE_BUFFER_DONE:
+ handle_session_release_buf_done(cmd, data);
+ break;
default:
dprintk(VIDC_ERR, "response unhandled\n");
break;
@@ -1225,6 +1270,12 @@
goto core_already_inited;
}
+ rc = msm_comm_scale_bus(core, inst->session_type, DDR_MEM);
+ if (rc) {
+ dprintk(VIDC_ERR, "Failed to scale DDR bus: %d\n", rc);
+ goto fail_scale_bus;
+ }
+
rc = msm_comm_load_fw(core);
if (rc) {
dprintk(VIDC_ERR, "Failed to load video firmware\n");
@@ -1236,11 +1287,6 @@
goto fail_core_init;
}
- rc = msm_comm_scale_bus(core, inst->session_type, DDR_MEM);
- if (rc) {
- dprintk(VIDC_ERR, "Failed to scale DDR bus: %d\n", rc);
- goto fail_core_init;
- }
init_completion(&core->completions[SYS_MSG_INDEX(SYS_INIT_DONE)]);
rc = vidc_hal_core_init(core->device,
core->resources.io_map[NS_MAP].domain);
@@ -1257,8 +1303,9 @@
return rc;
fail_core_init:
msm_comm_unload_fw(core);
- msm_comm_unvote_buses(core, DDR_MEM);
fail_load_fw:
+ msm_comm_unvote_buses(core, DDR_MEM);
+fail_scale_bus:
mutex_unlock(&core->sync_lock);
return rc;
}
@@ -1838,6 +1885,10 @@
buffer_info.align_device_addr = handle->device_addr;
if (inst->state != MSM_VIDC_CORE_INVALID &&
core->state != VIDC_CORE_INVALID) {
+ buffer_info.response_required = true;
+ init_completion(
+ &inst->completions[SESSION_MSG_INDEX
+ (SESSION_RELEASE_BUFFER_DONE)]);
rc = vidc_hal_session_release_buffers(
(void *) inst->session,
&buffer_info);
@@ -1846,6 +1897,10 @@
"Rel scrtch buf fail:0x%x, %d",
buffer_info.align_device_addr,
buffer_info.buffer_size);
+ spin_unlock_irqrestore(&inst->lock, flags);
+ rc = wait_for_sess_signal_receipt(inst,
+ SESSION_RELEASE_BUFFER_DONE);
+ spin_lock_irqsave(&inst->lock, flags);
}
list_del(&buf->list);
spin_unlock_irqrestore(&inst->lock, flags);
@@ -1890,6 +1945,10 @@
buffer_info.align_device_addr = handle->device_addr;
if (inst->state != MSM_VIDC_CORE_INVALID &&
core->state != VIDC_CORE_INVALID) {
+ buffer_info.response_required = true;
+ init_completion(
+ &inst->completions[SESSION_MSG_INDEX
+ (SESSION_RELEASE_BUFFER_DONE)]);
rc = vidc_hal_session_release_buffers(
(void *) inst->session,
&buffer_info);
@@ -1898,6 +1957,10 @@
"Rel prst buf fail:0x%x, %d",
buffer_info.align_device_addr,
buffer_info.buffer_size);
+ spin_unlock_irqrestore(&inst->lock, flags);
+ rc = wait_for_sess_signal_receipt(inst,
+ SESSION_RELEASE_BUFFER_DONE);
+ spin_lock_irqsave(&inst->lock, flags);
}
list_del(&buf->list);
spin_unlock_irqrestore(&inst->lock, flags);
@@ -1980,6 +2043,8 @@
buffer_info.buffer_type = HAL_BUFFER_INTERNAL_SCRATCH;
buffer_info.num_buffers = 1;
buffer_info.align_device_addr = handle->device_addr;
+ dprintk(VIDC_DBG, "Scratch buffer address: %x",
+ buffer_info.align_device_addr);
rc = vidc_hal_session_set_buffers(
(void *) inst->session, &buffer_info);
if (rc) {
@@ -2051,6 +2116,8 @@
buffer_info.buffer_type = HAL_BUFFER_INTERNAL_PERSIST;
buffer_info.num_buffers = 1;
buffer_info.align_device_addr = handle->device_addr;
+ dprintk(VIDC_DBG, "Persist buffer address: %x",
+ buffer_info.align_device_addr);
rc = vidc_hal_session_set_buffers(
(void *) inst->session, &buffer_info);
if (rc) {
diff --git a/drivers/media/video/msm_vidc/vidc_hal.c b/drivers/media/video/msm_vidc/vidc_hal.c
index e449821..207bfe4 100644
--- a/drivers/media/video/msm_vidc/vidc_hal.c
+++ b/drivers/media/video/msm_vidc/vidc_hal.c
@@ -1954,6 +1954,7 @@
pkt->size = sizeof(struct hfi_cmd_session_set_buffers_packet) +
((buffer_info->num_buffers - 1) * sizeof(u32));
}
+ pkt->response_req = buffer_info->response_required;
buffer = get_hfi_buffer(buffer_info->buffer_type);
if (buffer)
pkt->buffer_type = buffer;
diff --git a/drivers/media/video/msm_vidc/vidc_hal_api.h b/drivers/media/video/msm_vidc/vidc_hal_api.h
index 9d20a31..3b83424 100644
--- a/drivers/media/video/msm_vidc/vidc_hal_api.h
+++ b/drivers/media/video/msm_vidc/vidc_hal_api.h
@@ -777,6 +777,12 @@
u32 align_device_addr;
u32 extradata_size;
u32 extradata_addr;
+ u32 response_required;
+};
+
+struct hal_buffer_info {
+ u32 buffer_addr;
+ u32 extra_data_addr;
};
struct vidc_frame_plane_config {
diff --git a/drivers/media/video/msm_vidc/vidc_hal_interrupt_handler.c b/drivers/media/video/msm_vidc/vidc_hal_interrupt_handler.c
index 8231bd4..abce25f 100644
--- a/drivers/media/video/msm_vidc/vidc_hal_interrupt_handler.c
+++ b/drivers/media/video/msm_vidc/vidc_hal_interrupt_handler.c
@@ -732,6 +732,31 @@
device->callback(SESSION_RELEASE_RESOURCE_DONE, &cmd_done);
}
+static void hal_process_session_rel_buf_done(struct hal_device *device,
+ struct hfi_msg_session_release_buffers_done_packet *pkt)
+{
+ struct msm_vidc_cb_cmd_done cmd_done;
+ if (!pkt || pkt->size !=
+ sizeof(struct
+ hfi_msg_session_release_buffers_done_packet)) {
+ dprintk(VIDC_ERR, "bad packet/packet size: %d", pkt->size);
+ return;
+ }
+ memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
+ cmd_done.device_id = device->device_id;
+ cmd_done.size = sizeof(struct msm_vidc_cb_cmd_done);
+ cmd_done.session_id =
+ ((struct hal_session *) pkt->session_id)->session_id;
+ cmd_done.status = vidc_map_hal_err_status((u32)pkt->error_type);
+ if (pkt->rg_buffer_info) {
+ cmd_done.data = (void *) &pkt->rg_buffer_info;
+ cmd_done.size = sizeof(struct hfi_buffer_info);
+ } else {
+ dprintk(VIDC_ERR, "invalid payload in rel_buff_done\n");
+ }
+ device->callback(SESSION_RELEASE_BUFFER_DONE, &cmd_done);
+}
+
static void hal_process_session_end_done(struct hal_device *device,
struct hfi_msg_sys_session_end_done_packet *pkt)
{
@@ -870,6 +895,11 @@
hfi_msg_session_get_sequence_header_done_packet
*) msg_hdr);
break;
+ case HFI_MSG_SESSION_RELEASE_BUFFERS_DONE:
+ hal_process_session_rel_buf_done(device, (struct
+ hfi_msg_session_release_buffers_done_packet
+ *) msg_hdr);
+ break;
default:
dprintk(VIDC_ERR, "UNKNOWN_MSG_TYPE : %d", msg_hdr->packet);
break;
diff --git a/drivers/media/video/msm_wfd/enc-mfc-subdev.c b/drivers/media/video/msm_wfd/enc-mfc-subdev.c
index 45532a9..21fc719 100644
--- a/drivers/media/video/msm_wfd/enc-mfc-subdev.c
+++ b/drivers/media/video/msm_wfd/enc-mfc-subdev.c
@@ -40,6 +40,7 @@
int secure;
struct mem_region unqueued_op_bufs;
bool streaming;
+ enum venc_framerate_modes framerate_mode;
};
struct venc {
@@ -301,6 +302,8 @@
inst->cbdata = vmops->cbdata;
inst->secure = vmops->secure;
inst->streaming = false;
+ inst->framerate_mode = VENC_MODE_VFR;
+
if (vmops->secure) {
WFD_MSG_ERR("OPENING SECURE SESSION\n");
flags |= VCD_CP_SESSION;
@@ -1123,6 +1126,14 @@
return rc;
}
+static long venc_set_framerate_mode(struct v4l2_subdev *sd,
+ void *arg)
+{
+ struct venc_inst *inst = sd->dev_priv;
+ inst->framerate_mode = *(enum venc_framerate_modes *)arg;
+ return 0;
+}
+
static long venc_set_qp_value(struct video_client_ctx *client_ctx,
__s32 frametype, __s32 qp)
{
@@ -1400,6 +1411,51 @@
return rc;
}
+static long venc_set_vui_timing_info(struct video_client_ctx *client_ctx,
+ struct venc_inst *inst, __s32 flag)
+{
+ struct vcd_property_hdr vcd_property_hdr;
+ struct vcd_property_vui_timing_info_enable vui_timing_info_enable;
+
+ if (!client_ctx)
+ return -EINVAL;
+ if (inst->framerate_mode == VENC_MODE_VFR) {
+ WFD_MSG_ERR("VUI timing info not suported in VFR mode ");
+ return -EINVAL;
+ }
+ vcd_property_hdr.prop_id = VCD_I_ENABLE_VUI_TIMING_INFO;
+ vcd_property_hdr.sz =
+ sizeof(struct vcd_property_vui_timing_info_enable);
+ vui_timing_info_enable.vui_timing_info = flag;
+ return vcd_set_property(client_ctx->vcd_handle,
+ &vcd_property_hdr, &vui_timing_info_enable);
+}
+
+static long venc_get_vui_timing_info(struct video_client_ctx *client_ctx,
+ __s32 *flag)
+{
+ struct vcd_property_hdr vcd_property_hdr;
+ struct vcd_property_vui_timing_info_enable vui_timing_info_enable;
+ int rc = 0;
+
+ if (!client_ctx || !flag)
+ return -EINVAL;
+
+ vcd_property_hdr.prop_id = VCD_I_ENABLE_VUI_TIMING_INFO;
+ vcd_property_hdr.sz =
+ sizeof(struct vcd_property_vui_timing_info_enable);
+ rc = vcd_get_property(client_ctx->vcd_handle,
+ &vcd_property_hdr, &vui_timing_info_enable);
+
+ if (rc < 0) {
+ WFD_MSG_ERR("Failed getting property for VUI timing info");
+ return rc;
+ }
+
+ *flag = vui_timing_info_enable.vui_timing_info;
+ return rc;
+}
+
static long venc_set_header_mode(struct video_client_ctx *client_ctx,
__s32 mode)
{
@@ -2285,6 +2341,9 @@
case V4L2_CID_MPEG_VIDC_VIDEO_H264_AU_DELIMITER:
rc = venc_set_avc_delimiter(client_ctx, ctrl->value);
break;
+ case V4L2_CID_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO:
+ rc = venc_set_vui_timing_info(client_ctx, inst, ctrl->value);
+ break;
case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:
rc = venc_set_entropy_mode(client_ctx, ctrl->value);
break;
@@ -2359,6 +2418,9 @@
case V4L2_CID_MPEG_VIDC_VIDEO_H264_AU_DELIMITER:
rc = venc_get_avc_delimiter(client_ctx, &ctrl->value);
break;
+ case V4L2_CID_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO:
+ rc = venc_get_vui_timing_info(client_ctx, &ctrl->value);
+ break;
default:
WFD_MSG_ERR("Get property not suported: %d\n", ctrl->id);
rc = -ENOTSUPP;
@@ -2503,6 +2565,9 @@
case ENC_MUNMAP:
rc = venc_munmap(sd, arg);
break;
+ case SET_FRAMERATE_MODE:
+ rc = venc_set_framerate_mode(sd, arg);
+ break;
default:
rc = -1;
break;
diff --git a/drivers/media/video/msm_wfd/enc-subdev.h b/drivers/media/video/msm_wfd/enc-subdev.h
index c6c854e..25373e4 100644
--- a/drivers/media/video/msm_wfd/enc-subdev.h
+++ b/drivers/media/video/msm_wfd/enc-subdev.h
@@ -20,6 +20,11 @@
#include <media/videobuf2-core.h>
#define VENC_MAGIC_IOCTL 'V'
+enum venc_framerate_modes {
+ VENC_MODE_CFR,
+ VENC_MODE_VFR,
+};
+
struct mem_region {
struct list_head list;
u8 *kvaddr;
@@ -101,6 +106,7 @@
#define ENCODE_FLUSH _IO('V', 24)
#define ENC_MMAP _IOWR('V', 25, struct mem_region_map *)
#define ENC_MUNMAP _IOWR('V', 26, struct mem_region_map *)
+#define SET_FRAMERATE_MODE _IO('V', 27)
extern int venc_init(struct v4l2_subdev *sd, u32 val);
extern int venc_load_fw(struct v4l2_subdev *sd);
diff --git a/drivers/media/video/msm_wfd/wfd-ioctl.c b/drivers/media/video/msm_wfd/wfd-ioctl.c
index 5f67a96..99dc0d0 100644
--- a/drivers/media/video/msm_wfd/wfd-ioctl.c
+++ b/drivers/media/video/msm_wfd/wfd-ioctl.c
@@ -240,6 +240,7 @@
int rc;
unsigned long flags;
struct mdp_buf_info mdp_buf = {0};
+ struct mem_region_map mmap_context = {0};
spin_lock_irqsave(&inst->inst_lock, flags);
if (inst->input_bufs_allocated) {
spin_unlock_irqrestore(&inst->inst_lock, flags);
@@ -249,7 +250,6 @@
spin_unlock_irqrestore(&inst->inst_lock, flags);
for (i = 0; i < VENC_INPUT_BUFFERS; ++i) {
- struct mem_region_map mmap_context = {0};
mpair = kzalloc(sizeof(*mpair), GFP_KERNEL);
enc_mregion = kzalloc(sizeof(*enc_mregion), GFP_KERNEL);
mdp_mregion = kzalloc(sizeof(*enc_mregion), GFP_KERNEL);
@@ -278,6 +278,10 @@
rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl,
SET_INPUT_BUFFER, (void *)enc_mregion);
+ if (rc) {
+ WFD_MSG_ERR("Setting enc input buffer failed\n");
+ goto set_input_fail;
+ }
/* map the buffer from encoder to mdp */
mdp_mregion->kvaddr = enc_mregion->kvaddr;
@@ -301,7 +305,7 @@
mdp_mregion->kvaddr = NULL;
mdp_mregion->paddr = NULL;
mdp_mregion->ion_handle = NULL;
- goto alloc_fail;
+ goto mdp_mmap_fail;
}
mdp_buf.inst = inst->mdp_inst;
@@ -314,34 +318,58 @@
((int)mdp_mregion->paddr + mdp_mregion->size),
mdp_mregion->kvaddr);
- INIT_LIST_HEAD(&mpair->list);
- mpair->enc = enc_mregion;
- mpair->mdp = mdp_mregion;
- list_add_tail(&mpair->list, &inst->input_mem_list);
-
rc = v4l2_subdev_call(&wfd_dev->mdp_sdev, core, ioctl,
MDP_Q_BUFFER, (void *)&mdp_buf);
if (rc) {
WFD_MSG_ERR("Unable to queue the"
" buffer to mdp\n");
- break;
+ goto mdp_q_fail;
} else {
wfd_stats_update(&inst->stats,
WFD_STAT_EVENT_MDP_QUEUE);
}
+
+ INIT_LIST_HEAD(&mpair->list);
+ mpair->enc = enc_mregion;
+ mpair->mdp = mdp_mregion;
+ list_add_tail(&mpair->list, &inst->input_mem_list);
+
}
+
rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl,
ALLOC_RECON_BUFFERS, NULL);
if (rc) {
WFD_MSG_ERR("Failed to allocate recon buffers\n");
- goto alloc_fail;
+ goto recon_alloc_fail;
}
return rc;
+ /*
+ * Clean up only the buffer that we failed in setting up.
+ * Caller will clean up the rest by calling free_input_buffers()
+ */
+mdp_q_fail:
+ memset(&mmap_context, 0, sizeof(mmap_context));
+ mmap_context.mregion = mdp_mregion;
+ mmap_context.ion_client = wfd_dev->ion_client;
+ mmap_context.cookie = inst->mdp_inst;
+ v4l2_subdev_call(&wfd_dev->mdp_sdev, core, ioctl,
+ MDP_MUNMAP, (void *)&mmap_context);
+mdp_mmap_fail:
+ v4l2_subdev_call(&wfd_dev->enc_sdev,
+ core, ioctl, FREE_INPUT_BUFFER,
+ (void *)enc_mregion);
+set_input_fail:
+ memset(&mmap_context, 0, sizeof(mmap_context));
+ mmap_context.ion_client = wfd_dev->ion_client;
+ mmap_context.mregion = enc_mregion;
+ v4l2_subdev_call(&wfd_dev->enc_sdev, core, ioctl,
+ ENC_MUNMAP, &mmap_context);
alloc_fail:
kfree(mpair);
kfree(enc_mregion);
kfree(mdp_mregion);
+recon_alloc_fail:
return rc;
}
void wfd_free_input_buffers(struct wfd_device *wfd_dev,
@@ -1047,7 +1075,8 @@
struct v4l2_qcom_frameskip frameskip;
int64_t frame_interval, max_frame_interval;
void *extendedmode = NULL;
- enum vsg_modes mode = VSG_MODE_VFR;
+ enum vsg_modes vsg_mode = VSG_MODE_VFR;
+ enum venc_framerate_modes venc_mode = VENC_MODE_VFR;
if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
@@ -1069,6 +1098,7 @@
rc = -EINVAL;
goto set_parm_fail;
}
+ venc_mode = VENC_MODE_CFR;
frame_interval =
a->parm.capture.timeperframe.numerator * NSEC_PER_SEC /
a->parm.capture.timeperframe.denominator;
@@ -1097,7 +1127,7 @@
goto set_parm_fail;
max_frame_interval = (int64_t)frameskip.maxframeinterval;
- mode = VSG_MODE_VFR;
+ vsg_mode = VSG_MODE_VFR;
rc = v4l2_subdev_call(&wfd_dev->vsg_sdev, core,
ioctl, VSG_SET_MAX_FRAME_INTERVAL,
@@ -1107,19 +1137,23 @@
goto set_parm_fail;
rc = v4l2_subdev_call(&wfd_dev->vsg_sdev, core,
- ioctl, VSG_SET_MODE, &mode);
+ ioctl, VSG_SET_MODE, &vsg_mode);
if (rc)
goto set_parm_fail;
} else {
- mode = VSG_MODE_CFR;
+ vsg_mode = VSG_MODE_CFR;
rc = v4l2_subdev_call(&wfd_dev->vsg_sdev, core,
- ioctl, VSG_SET_MODE, &mode);
+ ioctl, VSG_SET_MODE, &vsg_mode);
if (rc)
goto set_parm_fail;
}
+ rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core,
+ ioctl, SET_FRAMERATE_MODE,
+ &venc_mode);
+
set_parm_fail:
return rc;
}
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 8810b46..fde13c7 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -298,13 +298,33 @@
{
int value;
struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev));
+ struct mmc_card *card = md->queue.card;
+ int ret = count;
+
+ if (!card) {
+ ret = -EINVAL;
+ goto exit;
+ }
sscanf(buf, "%d", &value);
- if (value >= 0)
- md->queue.num_wr_reqs_to_start_packing = value;
+ if (value >= 0) {
+ md->queue.num_wr_reqs_to_start_packing =
+ min_t(int, value, (int)card->ext_csd.max_packed_writes);
+
+ pr_debug("%s: trigger to pack: new value = %d",
+ mmc_hostname(card->host),
+ md->queue.num_wr_reqs_to_start_packing);
+ } else {
+ pr_err("%s: value %d is not valid. old value remains = %d",
+ mmc_hostname(card->host), value,
+ md->queue.num_wr_reqs_to_start_packing);
+ ret = -EINVAL;
+ }
+
+exit:
mmc_blk_put(md);
- return count;
+ return ret;
}
static ssize_t
@@ -317,13 +337,13 @@
int ret;
if (!card)
- return -EINVAL;
-
- min_sectors_to_check_bkops_status =
- card->bkops_info.min_sectors_to_queue_delayed_work;
-
- ret = snprintf(buf, PAGE_SIZE, "%d\n",
- min_sectors_to_check_bkops_status);
+ ret = -EINVAL;
+ else {
+ min_sectors_to_check_bkops_status =
+ card->bkops_info.min_sectors_to_queue_delayed_work;
+ ret = snprintf(buf, PAGE_SIZE, "%d\n",
+ min_sectors_to_check_bkops_status);
+ }
mmc_blk_put(md);
return ret;
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index 8897f18a..8eb787d 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -210,7 +210,9 @@
mq->mqrq_cur = mqrq_cur;
mq->mqrq_prev = mqrq_prev;
mq->queue->queuedata = mq;
- mq->num_wr_reqs_to_start_packing = DEFAULT_NUM_REQS_TO_START_PACK;
+ mq->num_wr_reqs_to_start_packing =
+ min_t(int, (int)card->ext_csd.max_packed_writes,
+ DEFAULT_NUM_REQS_TO_START_PACK);
blk_queue_prep_rq(mq->queue, mmc_prep_request);
queue_flag_set_unlocked(QUEUE_FLAG_NONROT, mq->queue);
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index fd18560..4e76f61 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -162,10 +162,7 @@
if (ret)
goto out;
- if (card->host->caps &
- (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
- MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 |
- MMC_CAP_UHS_DDR50)) {
+ if (mmc_host_uhs(card->host)) {
if (data & SDIO_UHS_DDR50)
card->sw_caps.sd3_bus_mode
|= SD_MODE_UHS_DDR50;
@@ -480,8 +477,7 @@
* If the host doesn't support any of the UHS-I modes, fallback on
* default speed.
*/
- if (!(card->host->caps & (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
- MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_DDR50)))
+ if (!mmc_host_uhs(card->host))
return 0;
bus_speed = SDIO_SPEED_SDR12;
@@ -491,23 +487,27 @@
bus_speed = SDIO_SPEED_SDR104;
timing = MMC_TIMING_UHS_SDR104;
card->sw_caps.uhs_max_dtr = UHS_SDR104_MAX_DTR;
+ card->sd_bus_speed = UHS_SDR104_BUS_SPEED;
} else if ((card->host->caps & MMC_CAP_UHS_DDR50) &&
(card->sw_caps.sd3_bus_mode & SD_MODE_UHS_DDR50)) {
bus_speed = SDIO_SPEED_DDR50;
timing = MMC_TIMING_UHS_DDR50;
card->sw_caps.uhs_max_dtr = UHS_DDR50_MAX_DTR;
+ card->sd_bus_speed = UHS_DDR50_BUS_SPEED;
} else if ((card->host->caps & (MMC_CAP_UHS_SDR104 |
MMC_CAP_UHS_SDR50)) && (card->sw_caps.sd3_bus_mode &
SD_MODE_UHS_SDR50)) {
bus_speed = SDIO_SPEED_SDR50;
timing = MMC_TIMING_UHS_SDR50;
card->sw_caps.uhs_max_dtr = UHS_SDR50_MAX_DTR;
+ card->sd_bus_speed = UHS_SDR50_BUS_SPEED;
} else if ((card->host->caps & (MMC_CAP_UHS_SDR104 |
MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25)) &&
(card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR25)) {
bus_speed = SDIO_SPEED_SDR25;
timing = MMC_TIMING_UHS_SDR25;
card->sw_caps.uhs_max_dtr = UHS_SDR25_MAX_DTR;
+ card->sd_bus_speed = UHS_SDR25_BUS_SPEED;
} else if ((card->host->caps & (MMC_CAP_UHS_SDR104 |
MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25 |
MMC_CAP_UHS_SDR12)) && (card->sw_caps.sd3_bus_mode &
@@ -515,6 +515,7 @@
bus_speed = SDIO_SPEED_SDR12;
timing = MMC_TIMING_UHS_SDR12;
card->sw_caps.uhs_max_dtr = UHS_SDR12_MAX_DTR;
+ card->sd_bus_speed = UHS_SDR12_BUS_SPEED;
}
err = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &speed);
@@ -653,11 +654,7 @@
* systems that claim 1.8v signalling in fact do not support
* it.
*/
- if ((ocr & R4_18V_PRESENT) &&
- (host->caps &
- (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
- MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 |
- MMC_CAP_UHS_DDR50))) {
+ if ((ocr & R4_18V_PRESENT) && mmc_host_uhs(host)) {
err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180,
true);
if (err) {
@@ -1056,6 +1053,10 @@
goto out;
}
+ if (mmc_host_uhs(host))
+ /* to query card if 1.8V signalling is supported */
+ host->ocr |= R4_18V_PRESENT;
+
ret = mmc_sdio_init_card(host, host->ocr, host->card,
mmc_card_keep_power(host));
if (!ret && host->sdio_irqs)
@@ -1121,6 +1122,10 @@
/*
* Detect and init the card.
*/
+ if (mmc_host_uhs(host))
+ /* to query card if 1.8V signalling is supported */
+ host->ocr |= R4_18V_PRESENT;
+
err = mmc_sdio_init_card(host, host->ocr, NULL, 0);
if (err) {
if (err == -EAGAIN) {
@@ -1238,79 +1243,6 @@
int sdio_reset_comm(struct mmc_card *card)
{
- struct mmc_host *host = card->host;
- u32 ocr;
- int err;
-
- printk("%s():\n", __func__);
- mmc_claim_host(host);
-
- mmc_go_idle(host);
-
- mmc_set_clock(host, host->f_min);
-
- err = mmc_send_io_op_cond(host, 0, &ocr);
- if (err)
- goto err;
-
- host->ocr = mmc_select_voltage(host, ocr);
- if (!host->ocr) {
- err = -EINVAL;
- goto err;
- }
-
- err = mmc_send_io_op_cond(host, host->ocr, &ocr);
- if (err)
- goto err;
-
- if (mmc_host_is_spi(host)) {
- err = mmc_spi_set_crc(host, use_spi_crc);
- if (err)
- goto err;
- }
-
- if (!mmc_host_is_spi(host)) {
- err = mmc_send_relative_addr(host, &card->rca);
- if (err)
- goto err;
- mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL);
- }
- if (!mmc_host_is_spi(host)) {
- err = mmc_select_card(card);
- if (err)
- goto err;
- }
-
- /*
- * Switch to high-speed (if supported).
- */
- err = sdio_enable_hs(card);
- if (err > 0)
- mmc_sd_go_highspeed(card);
- else if (err)
- goto err;
-
- /*
- * Change to the card's maximum speed.
- */
- mmc_set_clock(host, mmc_sdio_get_max_clock(card));
-
- err = sdio_enable_4bit_bus(card);
- if (err > 0) {
- if (host->caps & MMC_CAP_8_BIT_DATA)
- mmc_set_bus_width(host, MMC_BUS_WIDTH_8);
- else if (host->caps & MMC_CAP_4_BIT_DATA)
- mmc_set_bus_width(host, MMC_BUS_WIDTH_4);
- }
- else if (err)
- goto err;
-
- mmc_release_host(host);
- return 0;
-err:
- printk("%s: Error resetting SDIO communications (%d)\n",
- mmc_hostname(host), err);
- mmc_release_host(host);
- return err;
+ return mmc_power_restore_host(card->host);
}
EXPORT_SYMBOL(sdio_reset_comm);
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 96234fc..c8b47b9 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -162,6 +162,7 @@
static int msmsdcc_runtime_resume(struct device *dev);
static int msmsdcc_dt_get_array(struct device *dev, const char *prop_name,
u32 **out_array, int *len, int size);
+static int msmsdcc_execute_tuning(struct mmc_host *mmc, u32 opcode);
static inline unsigned short msmsdcc_get_nr_sg(struct msmsdcc_host *host)
{
@@ -1201,8 +1202,9 @@
*c |= MCI_CSPM_DATCMD;
/* Check if AUTO CMD19/CMD21 is required or not? */
- if (host->tuning_needed &&
- (host->en_auto_cmd19 || host->en_auto_cmd21)) {
+ if (host->tuning_needed && (cmd->mrq->data &&
+ (cmd->mrq->data->flags & MMC_DATA_READ)) &&
+ (host->en_auto_cmd19 || host->en_auto_cmd21)) {
/*
* For open ended block read operation (without CMD23),
* AUTO_CMD19/AUTO_CMD21 bit should be set while sending
@@ -1216,7 +1218,8 @@
MMC_READ_MULTIPLE_BLOCK) ||
(!host->curr.mrq->sbc &&
(cmd->opcode == MMC_READ_SINGLE_BLOCK ||
- cmd->opcode == MMC_READ_MULTIPLE_BLOCK))) {
+ cmd->opcode == MMC_READ_MULTIPLE_BLOCK ||
+ cmd->opcode == SD_IO_RW_EXTENDED))) {
msmsdcc_enable_cdr_cm_sdc4_dll(host);
if (host->en_auto_cmd19 &&
host->mmc->ios.timing == MMC_TIMING_UHS_SDR104)
@@ -1416,6 +1419,10 @@
else
data->error = -ETIMEDOUT;
}
+ /* In case of DATA CRC/timeout error, execute tuning again */
+ if (host->tuning_needed && !host->tuning_in_progress)
+ host->tuning_done = false;
+
} else if (status & MCI_RXOVERRUN) {
pr_err("%s: RX overrun\n", mmc_hostname(host->mmc));
data->error = -EIO;
@@ -1768,6 +1775,8 @@
msmsdcc_dump_sdcc_state(host);
/* Execute full tuning in case of CRC errors */
host->saved_tuning_phase = INVALID_TUNING_PHASE;
+ if (host->tuning_needed)
+ host->tuning_done = false;
cmd->error = -EILSEQ;
}
@@ -2149,6 +2158,22 @@
}
}
+ /*
+ * Check if DLL retuning is required? If yes, perform it here before
+ * starting new request.
+ */
+ if (host->tuning_needed && !host->tuning_in_progress &&
+ !host->tuning_done) {
+ pr_debug("%s: %s: execute_tuning for timing mode = %d\n",
+ mmc_hostname(mmc), __func__, host->mmc->ios.timing);
+ if (host->mmc->ios.timing == MMC_TIMING_UHS_SDR104)
+ msmsdcc_execute_tuning(mmc,
+ MMC_SEND_TUNING_BLOCK);
+ else if (host->mmc->ios.timing == MMC_TIMING_MMC_HS200)
+ msmsdcc_execute_tuning(mmc,
+ MMC_SEND_TUNING_BLOCK_HS200);
+ }
+
spin_lock_irqsave(&host->lock, flags);
if (host->eject) {
@@ -3345,10 +3370,24 @@
/* Card clock frequency must be > 100MHz to enable tuning */
clk |= (4 << 14);
host->tuning_needed = 1;
- } else if (ios->timing == MMC_TIMING_UHS_DDR50) {
- clk |= (3 << 14);
} else {
- clk |= (2 << 14); /* feedback clock */
+ if (ios->timing == MMC_TIMING_UHS_DDR50)
+ clk |= (3 << 14);
+ else
+ clk |= (2 << 14); /* feedback clock */
+
+ host->tuning_done = false;
+ if (atomic_read(&host->clks_on)) {
+ /* Write 1 to DLL_RST bit of MCI_DLL_CONFIG register */
+ writel_relaxed((readl_relaxed(host->base +
+ MCI_DLL_CONFIG) | MCI_DLL_RST),
+ host->base + MCI_DLL_CONFIG);
+
+ /* Write 1 to DLL_PDN bit of MCI_DLL_CONFIG register */
+ writel_relaxed((readl_relaxed(host->base +
+ MCI_DLL_CONFIG) | MCI_DLL_PDN),
+ host->base + MCI_DLL_CONFIG);
+ }
}
/* Select free running MCLK as input clock of cm_dll_sdc4 */
@@ -4183,6 +4222,8 @@
out:
spin_lock_irqsave(&host->lock, flags);
host->tuning_in_progress = 0;
+ if (!rc)
+ host->tuning_done = true;
spin_unlock_irqrestore(&host->lock, flags);
exit:
pr_debug("%s: Exit %s\n", mmc_hostname(mmc), __func__);
diff --git a/drivers/mmc/host/msm_sdcc.h b/drivers/mmc/host/msm_sdcc.h
index bb1b211..500b5fb 100644
--- a/drivers/mmc/host/msm_sdcc.h
+++ b/drivers/mmc/host/msm_sdcc.h
@@ -401,6 +401,7 @@
bool io_pad_pwr_switch;
bool tuning_in_progress;
bool tuning_needed;
+ bool tuning_done;
bool en_auto_cmd19;
bool en_auto_cmd21;
bool sdio_gpio_lpm;
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 494ec49..55ff980 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -1357,8 +1357,14 @@
{
struct usb_device *udev = to_usb_device(dev);
- if (udev->bus->skip_resume && udev->state == USB_STATE_SUSPENDED)
- return 0;
+ if (udev->bus->skip_resume) {
+ if (udev->state == USB_STATE_SUSPENDED) {
+ return 0;
+ } else {
+ dev_err(dev, "abort suspend\n");
+ return -EBUSY;
+ }
+ }
unbind_no_pm_drivers_interfaces(udev);
diff --git a/drivers/usb/host/ehci-msm-hsic.c b/drivers/usb/host/ehci-msm-hsic.c
index 8c22f8e..7d12598 100644
--- a/drivers/usb/host/ehci-msm-hsic.c
+++ b/drivers/usb/host/ehci-msm-hsic.c
@@ -1886,7 +1886,8 @@
* when remote wakeup is received or interface driver
* start I/O.
*/
- if (!atomic_read(&mehci->pm_usage_cnt))
+ if (!atomic_read(&mehci->pm_usage_cnt) &&
+ pm_runtime_suspended(dev))
return 0;
ret = msm_hsic_resume(mehci);
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index c6fe765..a315587 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -485,6 +485,9 @@
ret = msm_otg_phy_clk_reset(motg);
if (ret)
return ret;
+ /* 10 usec delay is required according to spec */
+ if (IS_ERR(motg->phy_reset_clk))
+ usleep_range(10, 12);
ret = msm_otg_link_clk_reset(motg, 0);
if (ret)
return ret;
diff --git a/drivers/video/msm/mdp4_overlay.c b/drivers/video/msm/mdp4_overlay.c
index 05344fc..9813e39 100644
--- a/drivers/video/msm/mdp4_overlay.c
+++ b/drivers/video/msm/mdp4_overlay.c
@@ -253,7 +253,7 @@
pipe->pipe_ndx, plane);
if (ion_map_iommu(display_iclient, *srcp_ihdl,
DISPLAY_READ_DOMAIN, GEN_POOL, SZ_4K, 0, start,
- len, 0, ION_IOMMU_UNMAP_DELAYED)) {
+ len, 0, 0)) {
ion_free(display_iclient, *srcp_ihdl);
pr_err("ion_map_iommu() failed\n");
return -EINVAL;
diff --git a/drivers/video/msm/mdss/mdss_fb.h b/drivers/video/msm/mdss/mdss_fb.h
index b760388..5e57de6 100644
--- a/drivers/video/msm/mdss/mdss_fb.h
+++ b/drivers/video/msm/mdss/mdss_fb.h
@@ -64,6 +64,9 @@
u32 fb_imgType;
u32 dst_format;
int vsync_pending;
+ ktime_t vsync_time;
+ struct completion vsync_comp;
+ spinlock_t vsync_lock;
int hw_refresh;
diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_video.c b/drivers/video/msm/mdss/mdss_mdp_intf_video.c
index 9508846..052d78c 100644
--- a/drivers/video/msm/mdss/mdss_mdp_intf_video.c
+++ b/drivers/video/msm/mdss/mdss_mdp_intf_video.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -13,8 +13,6 @@
#define pr_fmt(fmt) "%s: " fmt, __func__
-#include <linux/workqueue.h>
-
#include "mdss_fb.h"
#include "mdss_mdp.h"
@@ -39,7 +37,6 @@
#define MAX_SESSIONS 3
struct mdss_mdp_video_ctx {
- u32 ctl_num;
u32 pp_num;
u8 ref_cnt;
@@ -47,11 +44,9 @@
struct completion pp_comp;
struct completion vsync_comp;
- struct mutex vsync_lock;
- struct work_struct vsync_work;
+ atomic_t vsync_ref;
+ spinlock_t vsync_lock;
mdp_vsync_handler_t vsync_handler;
- void *vsync_ptr;
- ktime_t vsync_time;
};
struct mdss_mdp_video_ctx mdss_mdp_video_ctx_list[MAX_SESSIONS];
@@ -157,43 +152,43 @@
return 0;
}
-static void send_vsync_work(struct work_struct *work)
-{
- struct mdss_mdp_video_ctx *ctx;
- ctx = container_of(work, typeof(*ctx), vsync_work);
- mutex_lock(&ctx->vsync_lock);
- if (ctx->vsync_handler)
- ctx->vsync_handler(ctx->vsync_ptr, ctx->vsync_time);
- mutex_unlock(&ctx->vsync_lock);
+static inline void video_vsync_irq_enable(struct mdss_mdp_ctl *ctl)
+{
+ struct mdss_mdp_video_ctx *ctx = ctl->priv_data;
+
+ if (atomic_inc_return(&ctx->vsync_ref) == 1)
+ mdss_mdp_irq_enable(MDSS_MDP_IRQ_INTF_VSYNC, ctl->intf_num);
+}
+
+static inline void video_vsync_irq_disable(struct mdss_mdp_ctl *ctl)
+{
+ struct mdss_mdp_video_ctx *ctx = ctl->priv_data;
+
+ if (atomic_dec_return(&ctx->vsync_ref) == 0)
+ mdss_mdp_irq_disable(MDSS_MDP_IRQ_INTF_VSYNC, ctl->intf_num);
}
static int mdss_mdp_video_set_vsync_handler(struct mdss_mdp_ctl *ctl,
mdp_vsync_handler_t vsync_handler)
{
struct mdss_mdp_video_ctx *ctx;
+ unsigned long flags;
ctx = (struct mdss_mdp_video_ctx *) ctl->priv_data;
if (!ctx) {
pr_err("invalid ctx for ctl=%d\n", ctl->num);
return -ENODEV;
}
- if (mutex_lock_interruptible(&ctx->vsync_lock))
- return -EINTR;
- if (vsync_handler && !ctx->timegen_en) {
- ctx->vsync_time = ktime_get();
- schedule_work(&ctx->vsync_work);
- }
-
+ spin_lock_irqsave(&ctx->vsync_lock, flags);
if (!ctx->vsync_handler && vsync_handler)
- mdss_mdp_irq_enable(MDSS_MDP_IRQ_INTF_VSYNC, ctl->intf_num);
+ video_vsync_irq_enable(ctl);
else if (ctx->vsync_handler && !vsync_handler)
- mdss_mdp_irq_disable(MDSS_MDP_IRQ_INTF_VSYNC, ctl->intf_num);
+ video_vsync_irq_disable(ctl);
ctx->vsync_handler = vsync_handler;
- ctx->vsync_ptr = ctl;
- mutex_unlock(&ctx->vsync_lock);
+ spin_unlock_irqrestore(&ctx->vsync_lock, flags);
return 0;
}
@@ -229,8 +224,7 @@
WARN(rc, "intf %d timegen off error (%d)\n", ctl->intf_num, rc);
}
- if (ctx->vsync_handler)
- mdss_mdp_video_set_vsync_handler(ctl, NULL);
+ mdss_mdp_video_set_vsync_handler(ctl, NULL);
mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_INTF_VSYNC, ctl->intf_num,
NULL, NULL);
@@ -244,9 +238,9 @@
static void mdss_mdp_video_pp_intr_done(void *arg)
{
- struct mdss_mdp_video_ctx *ctx;
+ struct mdss_mdp_ctl *ctl = arg;
+ struct mdss_mdp_video_ctx *ctx = ctl->priv_data;
- ctx = (struct mdss_mdp_video_ctx *) arg;
if (!ctx) {
pr_err("invalid ctx\n");
return;
@@ -259,20 +253,24 @@
static void mdss_mdp_video_vsync_intr_done(void *arg)
{
- struct mdss_mdp_video_ctx *ctx;
+ struct mdss_mdp_ctl *ctl = arg;
+ struct mdss_mdp_video_ctx *ctx = ctl->priv_data;
+ ktime_t vsync_time;
- ctx = (struct mdss_mdp_video_ctx *) arg;
if (!ctx) {
pr_err("invalid ctx\n");
return;
}
- ctx->vsync_time = ktime_get();
- pr_debug("intr ctl=%d\n", ctx->ctl_num);
+ vsync_time = ktime_get();
+
+ pr_debug("intr ctl=%d\n", ctl->num);
complete(&ctx->vsync_comp);
+ spin_lock(&ctx->vsync_lock);
if (ctx->vsync_handler)
- schedule_work(&ctx->vsync_work);
+ ctx->vsync_handler(ctl, vsync_time);
+ spin_unlock(&ctx->vsync_lock);
}
static int mdss_mdp_video_prepare(struct mdss_mdp_ctl *ctl, void *arg)
@@ -309,11 +307,7 @@
return -ENODEV;
}
INIT_COMPLETION(ctx->vsync_comp);
-
- if (mutex_lock_interruptible(&ctx->vsync_lock))
- return -EINTR;
- if (!ctx->vsync_handler)
- mdss_mdp_irq_enable(MDSS_MDP_IRQ_INTF_VSYNC, ctl->intf_num);
+ video_vsync_irq_enable(ctl);
if (!ctx->timegen_en) {
int off = MDSS_MDP_REG_INTF_OFFSET(ctl->intf_num);
@@ -335,9 +329,8 @@
rc = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_TIMEGEN_ON, NULL);
WARN(rc, "intf %d timegen on error (%d)\n", ctl->intf_num, rc);
}
- if (!ctx->vsync_handler)
- mdss_mdp_irq_disable(MDSS_MDP_IRQ_INTF_VSYNC, ctl->intf_num);
- mutex_unlock(&ctx->vsync_lock);
+
+ video_vsync_irq_disable(ctl);
return 0;
}
@@ -376,17 +369,16 @@
return -ENOMEM;
}
ctl->priv_data = ctx;
- ctx->ctl_num = ctl->num;
ctx->pp_num = mixer->num;
init_completion(&ctx->pp_comp);
init_completion(&ctx->vsync_comp);
+ spin_lock_init(&ctx->vsync_lock);
+ atomic_set(&ctx->vsync_ref, 0);
- INIT_WORK(&ctx->vsync_work, send_vsync_work);
- mutex_init(&ctx->vsync_lock);
mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_INTF_VSYNC, ctl->intf_num,
- mdss_mdp_video_vsync_intr_done, ctx);
+ mdss_mdp_video_vsync_intr_done, ctl);
mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_PING_PONG_COMP, ctx->pp_num,
- mdss_mdp_video_pp_intr_done, ctx);
+ mdss_mdp_video_pp_intr_done, ctl);
itp.width = pinfo->xres + pinfo->lcdc.xres_pad;
itp.height = pinfo->yres + pinfo->lcdc.yres_pad;
diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
index f537c39..9c62ea2 100644
--- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
+++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c
@@ -26,6 +26,7 @@
#include "mdss_mdp.h"
#include "mdss_mdp_rotator.h"
+#define VSYNC_PERIOD 16
#define CHECK_BOUNDS(offset, size, max_size) \
(((size) > (max_size)) || ((offset) > ((max_size) - (size))))
@@ -837,30 +838,27 @@
mdss_mdp_overlay_kickoff(mfd->ctl);
}
+/* function is called in irq context should have minimum processing */
static void mdss_mdp_overlay_handle_vsync(struct mdss_mdp_ctl *ctl, ktime_t t)
{
- struct device *dev;
- char buf[64];
- char *envp[2];
-
- if (!ctl || !ctl->mfd || !ctl->mfd->fbi) {
+ struct msm_fb_data_type *mfd = ctl->mfd;
+ if (!mfd) {
pr_warn("Invalid handle for vsync\n");
return;
}
- dev = ctl->mfd->fbi->dev;
+ pr_debug("vsync on fb%d play_cnt=%d\n", mfd->index, ctl->play_cnt);
- snprintf(buf, sizeof(buf), "VSYNC=%llu", ktime_to_ns(t));
- envp[0] = buf;
- envp[1] = NULL;
- kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
-
- pr_debug("sent vsync on ctl=%d ts=%llu\n", ctl->num, ktime_to_ns(t));
+ spin_lock(&mfd->vsync_lock);
+ mfd->vsync_time = t;
+ complete(&mfd->vsync_comp);
+ spin_unlock(&mfd->vsync_lock);
}
int mdss_mdp_overlay_vsync_ctrl(struct msm_fb_data_type *mfd, int en)
{
struct mdss_mdp_ctl *ctl = mfd->ctl;
+ unsigned long flags;
int rc;
if (!ctl)
@@ -868,13 +866,23 @@
if (!ctl->set_vsync_handler)
return -ENOTSUPP;
- pr_debug("vsync en=%d\n", en);
-
if (!ctl->power_on) {
+ pr_debug("fb%d vsync pending first update en=%d\n",
+ mfd->index, en);
mfd->vsync_pending = en;
return 0;
}
+ pr_debug("fb%d vsync en=%d\n", mfd->index, en);
+
+ spin_lock_irqsave(&mfd->vsync_lock, flags);
+ INIT_COMPLETION(mfd->vsync_comp);
+ if (en && ctl->play_cnt == 0) {
+ mfd->vsync_time = ktime_get();
+ complete(&mfd->vsync_comp);
+ }
+ spin_unlock_irqrestore(&mfd->vsync_lock, flags);
+
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
if (en)
rc = ctl->set_vsync_handler(ctl, mdss_mdp_overlay_handle_vsync);
@@ -885,6 +893,47 @@
return rc;
}
+static ssize_t mdss_mdp_vsync_show_event(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct fb_info *fbi = dev_get_drvdata(dev);
+ struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)fbi->par;
+ unsigned long flags;
+ u64 vsync_ticks;
+ int ret;
+
+ if (!mfd->ctl || !mfd->ctl->power_on)
+ return 0;
+
+ ret = wait_for_completion_interruptible_timeout(&mfd->vsync_comp,
+ msecs_to_jiffies(VSYNC_PERIOD * 5));
+ if (ret <= 0) {
+ pr_warn("vsync wait on fb%d interrupted (%d)\n",
+ mfd->index, ret);
+ return -EBUSY;
+ }
+
+ spin_lock_irqsave(&mfd->vsync_lock, flags);
+ vsync_ticks = ktime_to_ns(mfd->vsync_time);
+ spin_unlock_irqrestore(&mfd->vsync_lock, flags);
+
+ pr_debug("fb%d vsync=%llu", mfd->index, vsync_ticks);
+ ret = snprintf(buf, PAGE_SIZE, "VSYNC=%llu", vsync_ticks);
+
+ return ret;
+}
+
+static DEVICE_ATTR(vsync_event, S_IRUGO, mdss_mdp_vsync_show_event, NULL);
+
+static struct attribute *vsync_fs_attrs[] = {
+ &dev_attr_vsync_event.attr,
+ NULL,
+};
+
+static struct attribute_group vsync_fs_attr_group = {
+ .attrs = vsync_fs_attrs,
+};
+
static int mdss_mdp_hw_cursor_update(struct msm_fb_data_type *mfd,
struct fb_cursor *cursor)
{
@@ -1154,6 +1203,9 @@
int mdss_mdp_overlay_init(struct msm_fb_data_type *mfd)
{
+ struct device *dev = mfd->fbi->dev;
+ int rc;
+
mfd->on_fnc = mdss_mdp_overlay_on;
mfd->off_fnc = mdss_mdp_overlay_off;
mfd->hw_refresh = true;
@@ -1168,7 +1220,18 @@
INIT_LIST_HEAD(&mfd->pipes_used);
INIT_LIST_HEAD(&mfd->pipes_cleanup);
+ init_completion(&mfd->vsync_comp);
+ spin_lock_init(&mfd->vsync_lock);
mutex_init(&mfd->ov_lock);
- return 0;
+ rc = sysfs_create_group(&dev->kobj, &vsync_fs_attr_group);
+ if (rc) {
+ pr_err("vsync sysfs group creation failed, ret=%d\n", rc);
+ return rc;
+ }
+
+ kobject_uevent(&dev->kobj, KOBJ_ADD);
+ pr_debug("vsync kobject_uevent(KOBJ_ADD)\n");
+
+ return rc;
}
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h
index 2a850d8..7a1d521 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h
@@ -293,6 +293,7 @@
struct vcd_property_slice_delivery_info slice_delivery_info;
struct ddl_batch_frame_data batch_frame;
u32 avc_delimiter_enable;
+ u32 vui_timinginfo_enable;
};
struct ddl_decoder_data {
struct ddl_codec_data_hdr hdr;
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
index 2c41ab4..78f96c8 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
@@ -1259,7 +1259,8 @@
output_vcd_frm->flags |=
VCD_FRAME_FLAG_DATACORRUPT;
}
- if (decoder->codec.codec != VCD_CODEC_H264)
+ if (decoder->codec.codec != VCD_CODEC_H264 ||
+ decoder->codec.codec != VCD_CODEC_MPEG2)
output_vcd_frm->flags &= ~VCD_FRAME_FLAG_DATACORRUPT;
output_vcd_frm->ip_frm_tag = dec_disp_info->tag_top;
vidc_sm_get_picture_times(&ddl->shared_mem
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
index d6558c3..332497f 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
@@ -1061,6 +1061,20 @@
}
break;
}
+ case VCD_I_ENABLE_VUI_TIMING_INFO:
+ {
+ struct vcd_property_vui_timing_info_enable *vui_timing_enable =
+ (struct vcd_property_vui_timing_info_enable *)
+ property_value;
+ if (sizeof(struct vcd_property_vui_timing_info_enable) ==
+ property_hdr->sz &&
+ encoder->codec.codec == VCD_CODEC_H264) {
+ encoder->vui_timinginfo_enable =
+ vui_timing_enable->vui_timing_info;
+ vcd_status = VCD_S_SUCCESS;
+ }
+ break;
+ }
default:
DDL_MSG_ERROR("INVALID ID %d\n", (int)property_hdr->prop_id);
vcd_status = VCD_ERR_ILLEGAL_OP;
@@ -1553,6 +1567,15 @@
vcd_status = VCD_S_SUCCESS;
}
break;
+ case VCD_I_ENABLE_VUI_TIMING_INFO:
+ if (sizeof(struct vcd_property_vui_timing_info_enable) ==
+ property_hdr->sz) {
+ ((struct vcd_property_vui_timing_info_enable *)
+ property_value)->vui_timing_info =
+ encoder->vui_timinginfo_enable;
+ vcd_status = VCD_S_SUCCESS;
+ }
+ break;
default:
vcd_status = VCD_ERR_ILLEGAL_OP;
break;
@@ -1715,6 +1738,7 @@
encoder->slice_delivery_info.num_slices = 0;
encoder->slice_delivery_info.num_slices_enc = 0;
encoder->avc_delimiter_enable = 0;
+ encoder->vui_timinginfo_enable = 0;
}
static void ddl_set_default_enc_profile(struct ddl_encoder_data *encoder)
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c
index 40dc2aa..7bdb3b9 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c
@@ -83,6 +83,8 @@
#define VIDC_SM_ENC_EXT_CTRL_ADDR 0x0028
#define VIDC_SM_ENC_EXT_CTRL_VBV_BUFFER_SIZE_BMSK 0xffff0000
#define VIDC_SM_ENC_EXT_CTRL_VBV_BUFFER_SIZE_SHFT 16
+#define VIDC_SM_ENC_EXT_CTRL_TIMING_INFO_EN_BMSK 0x00004000
+#define VIDC_SM_ENC_EXT_CTRL_TIMING_INFO_EN_SHFT 14
#define VIDC_SM_ENC_EXT_CTRL_AU_DELIMITER_EN_BMSK 0x00000800
#define VIDC_SM_ENC_EXT_CTRL_AU_DELIMITER_EN_SHFT 11
#define VIDC_SM_ENC_EXT_CTRL_H263_CPCFC_ENABLE_BMSK 0x80
@@ -176,6 +178,13 @@
#define VIDC_SM_ENC_NUM_OF_SLICE_COMP_ADDR 0x01d0
#define VIDC_SM_ENC_NUM_OF_SLICE_COMP_VALUE_BMSK 0xffffffff
#define VIDC_SM_ENC_NUM_OF_SLICE_COMP_VALUE_SHFT 0
+#define VIDC_SM_ENC_NUM_UNITS_IN_TICK_ADDR 0x01dc
+#define VIDC_SM_ENC_NUM_UNITS_IN_TICK_VALUE_BMSK 0xffffffff
+#define VIDC_SM_ENC_NUM_UNITS_IN_TICK_VALUE_SHFT 0
+#define VIDC_SM_ENC_TIME_SCALE_ADDR 0x01e0
+#define VIDC_SM_ENC_TIME_SCALE_VALUE_BMSK 0xffffffff
+#define VIDC_SM_ENC_TIME_SCALE_VALUE_SHFT 0
+
#define VIDC_SM_ALLOCATED_LUMA_DPB_SIZE_ADDR 0x0064
#define VIDC_SM_ALLOCATED_CHROMA_DPB_SIZE_ADDR 0x0068
@@ -449,7 +458,8 @@
enum VIDC_SM_frame_skip frame_skip_mode,
u32 seq_hdr_in_band, u32 vbv_buffer_size, u32 cpcfc_enable,
u32 sps_pps_control, u32 closed_gop_enable,
- u32 au_delim_enable)
+ u32 au_delim_enable,
+ u32 vui_timing_info_enable)
{
u32 enc_ctrl;
enc_ctrl = VIDC_SETFIELD((hec_enable) ? 1 : 0,
@@ -475,7 +485,10 @@
VIDC_SM_ENC_EXT_CTRL_CLOSED_GOP_ENABLE_BMSK) |
VIDC_SETFIELD((au_delim_enable) ? 1 : 0,
VIDC_SM_ENC_EXT_CTRL_AU_DELIMITER_EN_SHFT,
- VIDC_SM_ENC_EXT_CTRL_AU_DELIMITER_EN_BMSK);
+ VIDC_SM_ENC_EXT_CTRL_AU_DELIMITER_EN_BMSK) |
+ VIDC_SETFIELD((vui_timing_info_enable) ? 1 : 0,
+ VIDC_SM_ENC_EXT_CTRL_TIMING_INFO_EN_SHFT,
+ VIDC_SM_ENC_EXT_CTRL_TIMING_INFO_EN_BMSK);
DDL_MEM_WRITE_32(shared_mem, VIDC_SM_ENC_EXT_CTRL_ADDR, enc_ctrl);
}
@@ -1139,3 +1152,15 @@
VIDC_SM_MP2_DATA_DUMP_BUFFER_SIZE_ADDR,
mp2datadumpsize);
}
+
+void vidc_sm_set_h264_encoder_timing_info(struct ddl_buf_addr *shared_mem,
+ u32 num_units_in_tick, u32 time_scale)
+{
+ DDL_MEM_WRITE_32(shared_mem,
+ VIDC_SM_ENC_NUM_UNITS_IN_TICK_ADDR,
+ num_units_in_tick);
+
+ DDL_MEM_WRITE_32(shared_mem,
+ VIDC_SM_ENC_TIME_SCALE_ADDR,
+ time_scale);
+}
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.h
index c4d577b..2eef99d 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.h
@@ -106,7 +106,7 @@
struct ddl_buf_addr *shared_mem, u32 hec_enable,
enum VIDC_SM_frame_skip frame_skip_mode, u32 seq_hdr_in_band,
u32 vbv_buffer_size, u32 cpcfc_enable, u32 sps_pps_control,
- u32 closed_gop_enable, u32 au_delim_enable);
+ u32 closed_gop_enable, u32 au_delim_enable, u32 vui_timing_info_enable);
void vidc_sm_set_encoder_param_change(struct ddl_buf_addr *shared_mem,
u32 bit_rate_chg, u32 frame_rate_chg, u32 i_period_chg);
void vidc_sm_set_encoder_vop_time(struct ddl_buf_addr *shared_mem,
@@ -198,6 +198,8 @@
void vidc_sm_set_mp2datadump_enable(struct ddl_buf_addr *shared_mem,
struct ddl_mp2_datadumpenabletype *ddl_mp2_datadump_enable);
void vidc_sm_set_mp2datadumpbuffer(struct ddl_buf_addr *shared_mem,
- u32 mp2datadumpaddr, u32 mp2datadumpsize);
+ u32 mp2datadumpaddr, u32 mp2datadumpsize);
+void vidc_sm_set_h264_encoder_timing_info(struct ddl_buf_addr *shared_mem,
+ u32 num_units_in_tick, u32 time_scale);
#endif
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.h
index bbde7ae..6817101 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.h
@@ -62,7 +62,8 @@
#define DDL_GET_ALIGNED_VITUAL(x) ((x).align_virtual_addr)
#define DDL_KILO_BYTE(x) ((x)*1024)
#define DDL_MEGA_BYTE(x) ((x)*1024*1024)
-#define DDL_FRAMERATE_SCALE(x) ((x) * 1000)
+#define DDL_FRAMERATE_SCALE_FACTOR (1000)
+#define DDL_FRAMERATE_SCALE(x) ((x) * DDL_FRAMERATE_SCALE_FACTOR)
#define DDL_MIN(x, y) ((x < y) ? x : y)
#define DDL_MAX(x, y) ((x > y) ? x : y)
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c
index 5eed305..76972ca 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c
@@ -370,6 +370,15 @@
(u32)(DDL_FRAMERATE_SCALE(encoder->\
frame_rate.fps_numerator) /
encoder->frame_rate.fps_denominator));
+ if (encoder->vui_timinginfo_enable &&
+ encoder->frame_rate.fps_denominator) {
+ vidc_sm_set_h264_encoder_timing_info(
+ &ddl->shared_mem[ddl->command_channel],
+ DDL_FRAMERATE_SCALE_FACTOR,
+ (u32)(DDL_FRAMERATE_SCALE(encoder->\
+ frame_rate.fps_numerator) / encoder->\
+ frame_rate.fps_denominator) << 1);
+ }
encoder->dynamic_prop_change &=
~(DDL_ENC_CHANGE_FRAMERATE);
}
@@ -596,7 +605,14 @@
[ddl->command_channel], hdr_ext_control,
r_cframe_skip, false, 0,
h263_cpfc_enable, encoder->sps_pps.sps_pps_for_idr_enable_flag,
- encoder->closed_gop, encoder->avc_delimiter_enable);
+ encoder->closed_gop, encoder->avc_delimiter_enable,
+ encoder->vui_timinginfo_enable);
+ if (encoder->vui_timinginfo_enable) {
+ vidc_sm_set_h264_encoder_timing_info(
+ &ddl->shared_mem[ddl->command_channel],
+ DDL_FRAMERATE_SCALE_FACTOR,
+ scaled_frame_rate << 1);
+ }
vidc_sm_set_encoder_init_rc_value(&ddl->shared_mem
[ddl->command_channel],
encoder->target_bit_rate.target_bitrate);
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index f435221..c798cf9 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -468,6 +468,14 @@
return !(host->caps2 & MMC_CAP2_BOOTPART_NOACC);
}
+static inline int mmc_host_uhs(struct mmc_host *host)
+{
+ return host->caps &
+ (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
+ MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 |
+ MMC_CAP_UHS_DDR50);
+}
+
#ifdef CONFIG_MMC_CLKGATE
void mmc_host_clk_hold(struct mmc_host *host);
void mmc_host_clk_release(struct mmc_host *host);
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index b1f534d..e5e0bb4 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -1833,6 +1833,12 @@
V4L2_MPEG_VIDC_INDEX_EXTRADATA_DIGITAL_ZOOM,
V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO,
};
+#define V4L2_CID_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO \
+ (V4L2_CID_MPEG_MSM_VIDC_BASE + 23)
+enum v4l2_mpeg_vidc_video_h264_vui_timing_info {
+ V4L2_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO_DISABLED = 0,
+ V4L2_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO_ENABLED = 1
+};
/* Camera class control IDs */
#define V4L2_CID_CAMERA_CLASS_BASE (V4L2_CTRL_CLASS_CAMERA | 0x900)
diff --git a/include/media/msm/vcd_property.h b/include/media/msm/vcd_property.h
index 180b38d..545dcd2 100644
--- a/include/media/msm/vcd_property.h
+++ b/include/media/msm/vcd_property.h
@@ -56,6 +56,8 @@
#define VCD_I_VOP_TIMING_CONSTANT_DELTA (VCD_START_BASE + 0x28)
#define VCD_I_SET_TURBO_CLK (VCD_START_BASE + 0x29)
#define VCD_I_ENABLE_DELIMITER_FLAG (VCD_START_BASE + 0x2A)
+#define VCD_I_ENABLE_VUI_TIMING_INFO (VCD_START_BASE + 0x2B)
+
#define VCD_START_REQ (VCD_START_BASE + 0x1000)
#define VCD_I_REQ_IFRAME (VCD_START_REQ + 0x1)
@@ -378,4 +380,8 @@
u32 avc_delimiter_enable_flag;
};
+struct vcd_property_vui_timing_info_enable {
+ u32 vui_timing_info;
+};
+
#endif