Merge "msm: SSR: Make subsystem restart into a bus" into msm-3.4
diff --git a/arch/arm/boot/dts/msm8974-camera.dtsi b/arch/arm/boot/dts/msm8974-camera.dtsi
index cf4f098..fd35103 100644
--- a/arch/arm/boot/dts/msm8974-camera.dtsi
+++ b/arch/arm/boot/dts/msm8974-camera.dtsi
@@ -125,6 +125,7 @@
reg-names = "jpeg";
interrupts = <0 59 0>;
interrupt-names = "jpeg";
+ vdd-supply = <&gdsc_jpeg>;
};
qcom,jpeg@fda20000 {
@@ -134,6 +135,7 @@
reg-names = "jpeg";
interrupts = <0 60 0>;
interrupt-names = "jpeg";
+ vdd-supply = <&gdsc_jpeg>;
};
qcom,jpeg@fda24000 {
@@ -143,6 +145,7 @@
reg-names = "jpeg";
interrupts = <0 61 0>;
interrupt-names = "jpeg";
+ vdd-supply = <&gdsc_jpeg>;
};
qcom,irqrouter@fda00000 {
diff --git a/arch/arm/boot/dts/msm9625-cdp.dts b/arch/arm/boot/dts/msm9625-cdp.dts
new file mode 100644
index 0000000..6733f59
--- /dev/null
+++ b/arch/arm/boot/dts/msm9625-cdp.dts
@@ -0,0 +1,21 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+/include/ "msm9625.dtsi"
+
+/ {
+ model = "Qualcomm MSM 9625 CDP";
+ compatible = "qcom,msm9625-cdp", "qcom,msm9625";
+ qcom,msm-id = <134 1 0>;
+};
diff --git a/arch/arm/boot/dts/msm9625-mtp.dts b/arch/arm/boot/dts/msm9625-mtp.dts
new file mode 100644
index 0000000..32185dc
--- /dev/null
+++ b/arch/arm/boot/dts/msm9625-mtp.dts
@@ -0,0 +1,21 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+/include/ "msm9625.dtsi"
+
+/ {
+ model = "Qualcomm MSM 9625 MTP";
+ compatible = "qcom,msm9625-mtp", "qcom,msm9625";
+ qcom,msm-id = <134 8 0>;
+};
diff --git a/arch/arm/boot/dts/msm9625-rumi.dts b/arch/arm/boot/dts/msm9625-rumi.dts
new file mode 100644
index 0000000..e4fa000
--- /dev/null
+++ b/arch/arm/boot/dts/msm9625-rumi.dts
@@ -0,0 +1,21 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+/include/ "msm9625.dtsi"
+
+/ {
+ model = "Qualcomm MSM 9625 RUMI";
+ compatible = "qcom,msm9625-rumi", "qcom,msm9625";
+ qcom,msm-id = <134 15 0>;
+};
diff --git a/arch/arm/boot/dts/msm9625.dts b/arch/arm/boot/dts/msm9625.dtsi
similarity index 99%
rename from arch/arm/boot/dts/msm9625.dts
rename to arch/arm/boot/dts/msm9625.dtsi
index 041b4dd..07233bb 100644
--- a/arch/arm/boot/dts/msm9625.dts
+++ b/arch/arm/boot/dts/msm9625.dtsi
@@ -10,7 +10,6 @@
* GNU General Public License for more details.
*/
-/dts-v1/;
/include/ "skeleton.dtsi"
/ {
diff --git a/arch/arm/configs/msm8974_defconfig b/arch/arm/configs/msm8974_defconfig
index 0a99036..09c341f 100644
--- a/arch/arm/configs/msm8974_defconfig
+++ b/arch/arm/configs/msm8974_defconfig
@@ -194,6 +194,7 @@
# CONFIG_FB_MSM_BACKLIGHT is not set
CONFIG_FB_MSM_MDSS=y
CONFIG_FB_MSM_MDSS_WRITEBACK=y
+CONFIG_FB_MSM_MDSS_HDMI_PANEL=y
CONFIG_BACKLIGHT_LCD_SUPPORT=y
# CONFIG_LCD_CLASS_DEVICE is not set
CONFIG_BACKLIGHT_CLASS_DEVICE=y
diff --git a/arch/arm/mach-msm/adsp-8974.c b/arch/arm/mach-msm/adsp-8974.c
new file mode 100644
index 0000000..0ded432
--- /dev/null
+++ b/arch/arm/mach-msm/adsp-8974.c
@@ -0,0 +1,295 @@
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/reboot.h>
+#include <linux/workqueue.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/err.h>
+
+#include <mach/irqs.h>
+#include <mach/scm.h>
+#include <mach/peripheral-loader.h>
+#include <mach/subsystem_restart.h>
+#include <mach/subsystem_notif.h>
+
+#include "smd_private.h"
+#include "ramdump.h"
+#include "sysmon.h"
+
+#define SCM_Q6_NMI_CMD 0x1
+#define MODULE_NAME "adsp_8974"
+#define MAX_BUF_SIZE 0x51
+
+/* Subsystem restart: QDSP6 data, functions */
+static void lpass_fatal_fn(struct work_struct *);
+static DECLARE_WORK(lpass_fatal_work, lpass_fatal_fn);
+
+struct lpass_ssr {
+ void *lpass_ramdump_dev;
+} lpass_ssr;
+
+static struct lpass_ssr lpass_ssr_8974;
+static int q6_crash_shutdown;
+
+static int riva_notifier_cb(struct notifier_block *this, unsigned long code,
+ void *ss_handle)
+{
+ int ret;
+ switch (code) {
+ case SUBSYS_BEFORE_SHUTDOWN:
+ pr_debug("%s: R-Notify: Shutdown started\n", __func__);
+ ret = sysmon_send_event(SYSMON_SS_LPASS, "wcnss",
+ SUBSYS_BEFORE_SHUTDOWN);
+ if (ret < 0)
+ pr_err("%s: sysmon_send_event error %d", __func__,
+ ret);
+ break;
+ }
+ return NOTIFY_DONE;
+}
+
+static void *ssr_notif_hdle;
+static struct notifier_block rnb = {
+ .notifier_call = riva_notifier_cb,
+};
+
+static int modem_notifier_cb(struct notifier_block *this, unsigned long code,
+ void *ss_handle)
+{
+ int ret;
+ switch (code) {
+ case SUBSYS_BEFORE_SHUTDOWN:
+ pr_debug("%s: M-Notify: Shutdown started\n", __func__);
+ ret = sysmon_send_event(SYSMON_SS_LPASS, "modem",
+ SUBSYS_BEFORE_SHUTDOWN);
+ if (ret < 0)
+ pr_err("%s: sysmon_send_event error %d", __func__,
+ ret);
+ break;
+ }
+ return NOTIFY_DONE;
+}
+
+static void *ssr_modem_notif_hdle;
+static struct notifier_block mnb = {
+ .notifier_call = modem_notifier_cb,
+};
+
+static void lpass_log_failure_reason(void)
+{
+ char *reason;
+ char buffer[MAX_BUF_SIZE];
+ unsigned size;
+
+ reason = smem_get_entry(SMEM_SSR_REASON_LPASS0, &size);
+
+ if (!reason) {
+ pr_err("%s: subsystem failure reason: (unknown, smem_get_entry failed).",
+ MODULE_NAME);
+ return;
+ }
+
+ if (reason[0] == '\0') {
+ pr_err("%s: subsystem failure reason: (unknown, init value found)",
+ MODULE_NAME);
+ return;
+ }
+
+ size = size < MAX_BUF_SIZE ? size : (MAX_BUF_SIZE-1);
+ memcpy(buffer, reason, size);
+ buffer[size] = '\0';
+ pr_err("%s: subsystem failure reason: %s", MODULE_NAME, buffer);
+ memset((void *)reason, 0x0, size);
+ wmb();
+}
+
+static void lpass_fatal_fn(struct work_struct *work)
+{
+ pr_err("%s %s: Watchdog bite received from Q6!\n", MODULE_NAME,
+ __func__);
+ lpass_log_failure_reason();
+ panic(MODULE_NAME ": Resetting the SoC");
+}
+
+static void lpass_smsm_state_cb(void *data, uint32_t old_state,
+ uint32_t new_state)
+{
+ /* Ignore if we're the one that set SMSM_RESET */
+ if (q6_crash_shutdown)
+ return;
+
+ if (new_state & SMSM_RESET) {
+ pr_debug("%s: LPASS SMSM state changed to SMSM_RESET, new_state= 0x%x, old_state = 0x%x\n",
+ __func__, new_state, old_state);
+ lpass_log_failure_reason();
+ panic(MODULE_NAME ": Resetting the SoC");
+ }
+}
+
+static void send_q6_nmi(void)
+{
+ /* Send NMI to QDSP6 via an SCM call. */
+ scm_call_atomic1(SCM_SVC_UTIL, SCM_Q6_NMI_CMD, 0x1);
+ pr_debug("%s: Q6 NMI was sent.\n", __func__);
+}
+
+static int lpass_shutdown(const struct subsys_desc *subsys)
+{
+ send_q6_nmi();
+
+ /* The write needs to go through before the q6 is shutdown. */
+ mb();
+
+ pil_force_shutdown("q6");
+ disable_irq_nosync(LPASS_Q6SS_WDOG_EXPIRED);
+
+ return 0;
+}
+
+static int lpass_powerup(const struct subsys_desc *subsys)
+{
+ int ret;
+
+ if (get_restart_level() == RESET_SUBSYS_INDEPENDENT) {
+ pr_debug("%s: Wait for ADSP power up!", __func__);
+ msleep(10000);
+ }
+
+ ret = pil_force_boot("q6");
+ enable_irq(LPASS_Q6SS_WDOG_EXPIRED);
+ return ret;
+}
+/* RAM segments - address and size for 8974 */
+static struct ramdump_segment q6_segments[] = { {0x8da00000, 0x8f200000 -
+ 0x8da00000}, {0x28400000, 0x20000} };
+static int lpass_ramdump(int enable, const struct subsys_desc *subsys)
+{
+ pr_debug("%s: enable[%d]\n", __func__, enable);
+ if (enable)
+ return do_ramdump(lpass_ssr_8974.lpass_ramdump_dev,
+ q6_segments,
+ ARRAY_SIZE(q6_segments));
+ else
+ return 0;
+}
+
+static void lpass_crash_shutdown(const struct subsys_desc *subsys)
+{
+ q6_crash_shutdown = 1;
+ send_q6_nmi();
+}
+
+static irqreturn_t lpass_wdog_bite_irq(int irq, void *dev_id)
+{
+ int ret;
+
+ pr_debug("%s: rxed irq[0x%x]", __func__, irq);
+ disable_irq_nosync(LPASS_Q6SS_WDOG_EXPIRED);
+ ret = schedule_work(&lpass_fatal_work);
+
+ return IRQ_HANDLED;
+}
+
+static struct subsys_device *lpass_8974_dev;
+
+static struct subsys_desc lpass_8974 = {
+ .name = "lpass",
+ .shutdown = lpass_shutdown,
+ .powerup = lpass_powerup,
+ .ramdump = lpass_ramdump,
+ .crash_shutdown = lpass_crash_shutdown
+};
+
+static int __init lpass_restart_init(void)
+{
+ lpass_8974_dev = subsys_register(&lpass_8974);
+ if (IS_ERR(lpass_8974_dev))
+ return PTR_ERR(lpass_8974_dev);
+ return 0;
+}
+
+static int __init lpass_fatal_init(void)
+{
+ int ret;
+
+ ret = smsm_state_cb_register(SMSM_Q6_STATE, SMSM_RESET,
+ lpass_smsm_state_cb, 0);
+
+ if (ret < 0)
+ pr_err("%s: Unable to register SMSM callback! (%d)\n",
+ __func__, ret);
+
+ ret = request_irq(LPASS_Q6SS_WDOG_EXPIRED, lpass_wdog_bite_irq,
+ IRQF_TRIGGER_RISING, "q6_wdog", NULL);
+
+ if (ret < 0) {
+ pr_err("%s: Unable to request LPASS_Q6SS_WDOG_EXPIRED irq.",
+ __func__);
+ goto out;
+ }
+ ret = lpass_restart_init();
+ if (ret < 0) {
+ pr_err("%s: Unable to reg with lpass ssr. (%d)\n",
+ __func__, ret);
+ goto out;
+ }
+
+ lpass_ssr_8974.lpass_ramdump_dev = create_ramdump_device("lpass");
+
+ if (!lpass_ssr_8974.lpass_ramdump_dev) {
+ pr_err("%s: Unable to create ramdump device.\n",
+ __func__);
+ ret = -ENOMEM;
+ goto out;
+ }
+ ssr_notif_hdle = subsys_notif_register_notifier("riva",
+ &rnb);
+ if (IS_ERR(ssr_notif_hdle) < 0) {
+ ret = PTR_ERR(ssr_notif_hdle);
+ pr_err("%s: subsys_register_notifier for Riva: err = %d\n",
+ __func__, ret);
+ free_irq(LPASS_Q6SS_WDOG_EXPIRED, NULL);
+ goto out;
+ }
+
+ ssr_modem_notif_hdle = subsys_notif_register_notifier("modem",
+ &mnb);
+ if (IS_ERR(ssr_modem_notif_hdle) < 0) {
+ ret = PTR_ERR(ssr_modem_notif_hdle);
+ pr_err("%s: subsys_register_notifier for Modem: err = %d\n",
+ __func__, ret);
+ subsys_notif_unregister_notifier(ssr_notif_hdle, &rnb);
+ free_irq(LPASS_Q6SS_WDOG_EXPIRED, NULL);
+ goto out;
+ }
+
+ pr_info("%s: lpass SSR driver init'ed.\n", __func__);
+out:
+ return ret;
+}
+
+static void __exit lpass_fatal_exit(void)
+{
+ subsys_notif_unregister_notifier(ssr_notif_hdle, &rnb);
+ subsys_notif_unregister_notifier(ssr_modem_notif_hdle, &mnb);
+ subsys_unregister(lpass_8974_dev);
+ free_irq(LPASS_Q6SS_WDOG_EXPIRED, NULL);
+}
+
+module_init(lpass_fatal_init);
+module_exit(lpass_fatal_exit);
+
+MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 47a5a08..2a02450 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -887,7 +887,7 @@
};
static int phy_init_seq[] = {
- 0x38, 0x81, /* update DC voltage level */
+ 0x68, 0x81, /* update DC voltage level */
0x24, 0x82, /* set pre-emphasis and rise/fall time */
-1
};
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index 7760f07..61b9a73 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -1451,7 +1451,7 @@
static int hsusb_phy_init_seq[] = {
0x44, 0x80, /* set VBUS valid threshold
and disconnect valid threshold */
- 0x38, 0x81, /* update DC voltage level */
+ 0x68, 0x81, /* update DC voltage level */
0x24, 0x82, /* set preemphasis and rise/fall time */
0x13, 0x83, /* set source impedance adjusment */
-1};
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index a3de539..2cd654c 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -1434,7 +1434,7 @@
static int wr_phy_init_seq[] = {
0x44, 0x80, /* set VBUS valid threshold
and disconnect valid threshold */
- 0x38, 0x81, /* update DC voltage level */
+ 0x68, 0x81, /* update DC voltage level */
0x14, 0x82, /* set preemphasis and rise/fall time */
0x13, 0x83, /* set source impedance adjusment */
-1};
@@ -1442,7 +1442,7 @@
static int liquid_v1_phy_init_seq[] = {
0x44, 0x80,/* set VBUS valid threshold
and disconnect valid threshold */
- 0x3C, 0x81,/* update DC voltage level */
+ 0x6C, 0x81,/* update DC voltage level */
0x18, 0x82,/* set preemphasis and rise/fall time */
0x23, 0x83,/* set source impedance sdjusment */
-1};
@@ -1450,7 +1450,7 @@
static int sglte_phy_init_seq[] = {
0x44, 0x80, /* set VBUS valid threshold
and disconnect valid threshold */
- 0x3A, 0x81, /* update DC voltage level */
+ 0x6A, 0x81, /* update DC voltage level */
0x24, 0x82, /* set preemphasis and rise/fall time */
0x13, 0x83, /* set source impedance adjusment */
-1};
diff --git a/arch/arm/mach-msm/board-9615.c b/arch/arm/mach-msm/board-9615.c
index e599739..177577e 100644
--- a/arch/arm/mach-msm/board-9615.c
+++ b/arch/arm/mach-msm/board-9615.c
@@ -612,7 +612,7 @@
static int shelby_phy_init_seq[] = {
0x44, 0x80,/* set VBUS valid threshold and
disconnect valid threshold */
- 0x38, 0x81, /* update DC voltage level */
+ 0x68, 0x81, /* update DC voltage level */
0x24, 0x82,/* set preemphasis and rise/fall time */
0x13, 0x83,/* set source impedance adjustment */
-1};
diff --git a/arch/arm/mach-msm/clock-8974.c b/arch/arm/mach-msm/clock-8974.c
index 357f0b7..e7f5b53 100644
--- a/arch/arm/mach-msm/clock-8974.c
+++ b/arch/arm/mach-msm/clock-8974.c
@@ -5173,17 +5173,36 @@
CLK_LOOKUP("bus_clk", camss_vfe_vfe_axi_clk.c, "fda14000.qcom,vfe"),
CLK_LOOKUP("alt_bus_clk", camss_vfe_vfe_ocmemnoc_clk.c,
"fda14000.qcom,vfe"),
- CLK_LOOKUP("core_clk", camss_jpeg_jpeg0_clk.c, ""),
- CLK_LOOKUP("core_clk", camss_jpeg_jpeg1_clk.c, ""),
- CLK_LOOKUP("core_clk", camss_jpeg_jpeg2_clk.c, ""),
+ /*Jpeg Clocks*/
+ CLK_LOOKUP("core_clk", camss_jpeg_jpeg0_clk.c, "fda1c000.qcom,jpeg"),
+ CLK_LOOKUP("core_clk", camss_jpeg_jpeg1_clk.c, "fda20000.qcom,jpeg"),
+ CLK_LOOKUP("core_clk", camss_jpeg_jpeg2_clk.c, "fda24000.qcom,jpeg"),
+ CLK_LOOKUP("iface_clk", camss_jpeg_jpeg_ahb_clk.c,
+ "fda1c000.qcom,jpeg"),
+ CLK_LOOKUP("iface_clk", camss_jpeg_jpeg_ahb_clk.c,
+ "fda20000.qcom,jpeg"),
+ CLK_LOOKUP("iface_clk", camss_jpeg_jpeg_ahb_clk.c,
+ "fda24000.qcom,jpeg"),
CLK_LOOKUP("iface_clk", camss_jpeg_jpeg_ahb_clk.c,
"fda64000.qcom,iommu"),
CLK_LOOKUP("core_clk", camss_jpeg_jpeg_axi_clk.c,
"fda64000.qcom,iommu"),
- CLK_LOOKUP("bus_clk", camss_jpeg_jpeg_axi_clk.c, ""),
- CLK_LOOKUP("bus_clk", camss_jpeg_jpeg_ocmemnoc_clk.c, ""),
+ CLK_LOOKUP("bus_clk0", camss_jpeg_jpeg_axi_clk.c, "fda1c000.qcom,jpeg"),
+ CLK_LOOKUP("bus_clk0", camss_jpeg_jpeg_axi_clk.c, "fda20000.qcom,jpeg"),
+ CLK_LOOKUP("bus_clk0", camss_jpeg_jpeg_axi_clk.c, "fda24000.qcom,jpeg"),
+ CLK_LOOKUP("alt_bus_clk", camss_jpeg_jpeg_ocmemnoc_clk.c,
+ "fda1c000.qcom,jpeg"),
+ CLK_LOOKUP("alt_bus_clk", camss_jpeg_jpeg_ocmemnoc_clk.c,
+ "fda20000.qcom,jpeg"),
+ CLK_LOOKUP("alt_bus_clk", camss_jpeg_jpeg_ocmemnoc_clk.c,
+ "fda24000.qcom,jpeg"),
+ CLK_LOOKUP("camss_top_ahb_clk", camss_top_ahb_clk.c,
+ "fda1c000.qcom,jpeg"),
+ CLK_LOOKUP("camss_top_ahb_clk", camss_top_ahb_clk.c,
+ "fda20000.qcom,jpeg"),
+ CLK_LOOKUP("camss_top_ahb_clk", camss_top_ahb_clk.c,
+ "fda24000.qcom,jpeg"),
CLK_LOOKUP("iface_clk", camss_micro_ahb_clk.c, ""),
- CLK_LOOKUP("iface_clk", camss_top_ahb_clk.c, ""),
CLK_LOOKUP("iface_clk", camss_vfe_cpp_ahb_clk.c, "fda44000.qcom,iommu"),
CLK_LOOKUP("core_clk", camss_vfe_cpp_clk.c, "fda44000.qcom,iommu"),
CLK_LOOKUP("iface_clk", mdss_ahb_clk.c, "mdp.0"),
diff --git a/arch/arm/mach-msm/restart.c b/arch/arm/mach-msm/restart.c
index aac83e5..25723d5 100644
--- a/arch/arm/mach-msm/restart.c
+++ b/arch/arm/mach-msm/restart.c
@@ -129,7 +129,11 @@
pm8xxx_reset_pwr_off(0);
if (lower_pshold) {
- __raw_writel(0, PSHOLD_CTL_SU);
+ if (!use_restart_v2())
+ __raw_writel(0, PSHOLD_CTL_SU);
+ else
+ __raw_writel(0, MSM_MPM2_PSHOLD_BASE);
+
mdelay(10000);
printk(KERN_ERR "Powering off has failed\n");
}
diff --git a/drivers/gpu/msm/kgsl_pwrscale_trustzone.c b/drivers/gpu/msm/kgsl_pwrscale_trustzone.c
index 1b029b1..7c2514b 100644
--- a/drivers/gpu/msm/kgsl_pwrscale_trustzone.c
+++ b/drivers/gpu/msm/kgsl_pwrscale_trustzone.c
@@ -178,15 +178,11 @@
priv->no_switch_cnt = 0;
}
+#ifdef CONFIG_MSM_SCM
static int tz_init(struct kgsl_device *device, struct kgsl_pwrscale *pwrscale)
{
struct tz_priv *priv;
- /* Trustzone is only valid for some SOCs */
- if (!(cpu_is_msm8x60() || cpu_is_msm8960() || cpu_is_apq8064() ||
- cpu_is_msm8930() || cpu_is_msm8930aa() || cpu_is_msm8627()))
- return -EINVAL;
-
priv = pwrscale->priv = kzalloc(sizeof(struct tz_priv), GFP_KERNEL);
if (pwrscale->priv == NULL)
return -ENOMEM;
@@ -197,6 +193,12 @@
return 0;
}
+#else
+static int tz_init(struct kgsl_device *device, struct kgsl_pwrscale *pwrscale)
+{
+ return -EINVAL;
+}
+#endif /* CONFIG_MSM_SCM */
static void tz_close(struct kgsl_device *device, struct kgsl_pwrscale *pwrscale)
{
diff --git a/drivers/media/video/msm/vfe/msm_vfe40.c b/drivers/media/video/msm/vfe/msm_vfe40.c
index 1297379..e958241 100644
--- a/drivers/media/video/msm/vfe/msm_vfe40.c
+++ b/drivers/media/video/msm/vfe/msm_vfe40.c
@@ -806,7 +806,7 @@
vfe40_ctrl->share_ctrl->vfebase + VFE_DEMUX_GAIN_0);
msm_camera_io_w(0x800080,
vfe40_ctrl->share_ctrl->vfebase + VFE_DEMUX_GAIN_1);
- msm_camera_io_w(0xFFFFF,
+ msm_camera_io_w(0x198FFFFF,
vfe40_ctrl->share_ctrl->vfebase + VFE_CGC_OVERRIDE);
msm_camera_io_w(0,
@@ -1289,6 +1289,12 @@
vfe40_ctrl->share_ctrl->vfebase +
VFE_REG_UPDATE_CMD);
+ msm_camera_io_w_mb(0x00003fff,
+ vfe40_ctrl->share_ctrl->vfebase +
+ V40_AXI_BUS_CMD_OFF);
+ msm_camera_io_w_mb(1,
+ vfe40_ctrl->share_ctrl->vfebase +
+ V40_BUS_PM_CMD);
if (vfe_operation_mode) {
msm_camera_io_w_mb(1, vfe40_ctrl->share_ctrl->vfebase +
VFE_CAMIF_COMMAND);
@@ -1345,8 +1351,6 @@
vfe40_ctrl->share_ctrl->start_ack_pending = TRUE;
vfe40_start_common(vfe40_ctrl);
- msm_camera_io_w(1, vfe40_ctrl->share_ctrl->vfebase + 0x18C);
- msm_camera_io_w(1, vfe40_ctrl->share_ctrl->vfebase + 0x188);
return 0;
}
static int vfe40_capture_raw(
@@ -1381,12 +1385,9 @@
vfe40_ctrl->share_ctrl->vfe_capture_count = num_frames_capture;
- vfe40_ctrl->share_ctrl->vfe_capture_count = num_frames_capture;
vfe40_start_common(vfe40_ctrl);
/* for debug */
- msm_camera_io_w(1, vfe40_ctrl->share_ctrl->vfebase + 0x18C);
- msm_camera_io_w(1, vfe40_ctrl->share_ctrl->vfebase + 0x188);
return 0;
}
@@ -1639,7 +1640,7 @@
outch = vfe40_get_ch(path, axi_ctrl->share_ctrl);
if (outch->ping.ch_paddr[0] && outch->pong.ch_paddr[0]) {
/* Configure Preview Ping Pong */
- pr_info("%s Configure ping/pong address for %d",
+ pr_info("%s Configure ping/pong address for %d\n",
__func__, path);
vfe40_put_ch_ping_addr(
axi_ctrl->share_ctrl->vfebase, outch->ch0,
@@ -3153,7 +3154,6 @@
irq_mask &= ~(0x1 << (share_ctrl->outpath.out3.ch0 +
VFE_WM_OFFSET));
}
-
msm_camera_io_w_mb(reg_update,
share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
msm_camera_io_w(irq_mask, share_ctrl->vfebase +
@@ -3326,7 +3326,6 @@
msm_camera_io_w(0, share_ctrl->vfebase +
vfe40_AXI_WM_CFG[
share_ctrl->outpath.out0.ch1]);
-
share_ctrl->liveshot_state = VFE_STATE_STOPPED;
msm_camera_io_w_mb(1, share_ctrl->vfebase +
VFE_REG_UPDATE_CMD);
@@ -3387,11 +3386,10 @@
msm_camera_io_w_mb
(CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
share_ctrl->vfebase +
- VFE_CAMIF_COMMAND);
+ VFE_CAMIF_COMMAND);
vfe40_ctrl->snapshot_frame_cnt = -1;
vfe40_ctrl->frame_skip_cnt = 31;
- vfe40_ctrl->frame_skip_pattern =
- 0xffffffff;
+ vfe40_ctrl->frame_skip_pattern = 0xffffffff;
} /*if snapshot count is 0*/
} /*if frame is not being dropped*/
vfe40_ctrl->snapshot_frame_cnt++;
@@ -3607,6 +3605,8 @@
static void vfe40_process_common_error_irq(
struct axi_ctrl_t *axi_ctrl, uint32_t errStatus)
{
+ if (errStatus & VFE40_IMASK_BUS_BDG_HALT_ACK)
+ pr_err("vfe40_irq: BUS BDG HALT ACK\n");
if (errStatus & VFE40_IMASK_IMG_MAST_0_BUS_OVFL)
pr_err("vfe40_irq: image master 0 bus overflow\n");
@@ -5455,9 +5455,14 @@
if (axi_ctrl->share_ctrl->outpath.output_mode &
VFE40_OUTPUT_MODE_PRIMARY) {
- irq_comp_mask |= (
- 0x1 << axi_ctrl->share_ctrl->outpath.out0.ch0 |
- 0x1 << axi_ctrl->share_ctrl->outpath.out0.ch1);
+ if (vfe_params.cmd_type == AXI_CMD_RAW_CAPTURE) {
+ irq_comp_mask |=
+ 0x1 << axi_ctrl->share_ctrl->outpath.out0.ch0;
+ } else {
+ irq_comp_mask |= (
+ 0x1 << axi_ctrl->share_ctrl->outpath.out0.ch0 |
+ 0x1 << axi_ctrl->share_ctrl->outpath.out0.ch1);
+ }
irq_mask |= VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK;
} else if (axi_ctrl->share_ctrl->outpath.output_mode &
VFE40_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
@@ -5551,12 +5556,21 @@
default:
if (axi_ctrl->share_ctrl->outpath.output_mode &
VFE40_OUTPUT_MODE_PRIMARY) {
- msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
- vfe40_AXI_WM_CFG[axi_ctrl->
- share_ctrl->outpath.out0.ch0]);
- msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
- vfe40_AXI_WM_CFG[axi_ctrl->
- share_ctrl->outpath.out0.ch1]);
+ if (vfe_params.cmd_type == AXI_CMD_RAW_CAPTURE) {
+ msm_camera_io_w(1,
+ axi_ctrl->share_ctrl->vfebase +
+ vfe40_AXI_WM_CFG[axi_ctrl->
+ share_ctrl->outpath.out0.ch0]);
+ } else {
+ msm_camera_io_w(1,
+ axi_ctrl->share_ctrl->vfebase +
+ vfe40_AXI_WM_CFG[axi_ctrl
+ ->share_ctrl->outpath.out0.ch0]);
+ msm_camera_io_w(1,
+ axi_ctrl->share_ctrl->vfebase +
+ vfe40_AXI_WM_CFG[axi_ctrl->
+ share_ctrl->outpath.out0.ch1]);
+ }
} else if (axi_ctrl->share_ctrl->outpath.output_mode &
VFE40_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
@@ -5592,6 +5606,7 @@
}
break;
}
+
if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI0)
msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
vfe40_AXI_WM_CFG[axi_ctrl->share_ctrl->
diff --git a/drivers/media/video/msm/vfe/msm_vfe40.h b/drivers/media/video/msm/vfe/msm_vfe40.h
index 5b73751..8201d18 100644
--- a/drivers/media/video/msm/vfe/msm_vfe40.h
+++ b/drivers/media/video/msm/vfe/msm_vfe40.h
@@ -204,6 +204,7 @@
#define V40_AXI_OUT_LEN 344
#define V40_AXI_CFG_LEN 71
+#define V40_BUS_PM_CMD 0x00000270
#define V40_FOV_ENC_OFF 0x00000854
#define V40_FOV_ENC_LEN 16
#define V40_FOV_VIEW_OFF 0x00000864
@@ -719,7 +720,7 @@
#define VFE40_IMASK_ERROR_ONLY_0 0x0
/* when normal case, don't want to block error status. */
/* bit 0-21 are error irq bits */
-#define VFE40_IMASK_COMMON_ERROR_ONLY_1 0x0000FE00
+#define VFE40_IMASK_COMMON_ERROR_ONLY_1 0x0000FF00
#define VFE40_IMASK_VFE_ERROR_ONLY_1 0x00FF01FF
#define VFE40_IMASK_CAMIF_ERROR (0x00000001<<0)
#define VFE40_IMASK_BHIST_OVWR (0x00000001<<1)
@@ -729,6 +730,7 @@
#define VFE40_IMASK_REALIGN_BUF_CB_OVFL (0x00000001<<5)
#define VFE40_IMASK_REALIGN_BUF_CR_OVFL (0x00000001<<6)
#define VFE40_IMASK_VIOLATION (0x00000001<<7)
+#define VFE40_IMASK_BUS_BDG_HALT_ACK (0x00000001<<8)
#define VFE40_IMASK_IMG_MAST_0_BUS_OVFL (0x00000001<<9)
#define VFE40_IMASK_IMG_MAST_1_BUS_OVFL (0x00000001<<10)
#define VFE40_IMASK_IMG_MAST_2_BUS_OVFL (0x00000001<<11)
diff --git a/drivers/media/video/msm_vidc/msm_vdec.c b/drivers/media/video/msm_vidc/msm_vdec.c
index c0f8014..4939b64 100644
--- a/drivers/media/video/msm_vidc/msm_vdec.c
+++ b/drivers/media/video/msm_vidc/msm_vdec.c
@@ -674,6 +674,7 @@
unsigned long flags;
struct vb2_buf_entry *temp;
struct list_head *ptr, *next;
+ inst->in_reconfig = false;
rc = msm_comm_set_scratch_buffers(inst);
if (rc) {
pr_err("Failed to set scratch buffers: %d\n", rc);
@@ -786,62 +787,18 @@
int msm_vdec_cmd(struct msm_vidc_inst *inst, struct v4l2_decoder_cmd *dec)
{
int rc = 0;
- bool ip_flush = false,
- op_flush = false;
-
switch (dec->cmd) {
case V4L2_DEC_QCOM_CMD_FLUSH:
- mutex_lock(&inst->sync_lock);
- ip_flush = dec->flags & V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT;
- op_flush = dec->flags & V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
- /* Only support flush on decoder (for now)*/
- if (inst->session_type == MSM_VIDC_ENCODER) {
- pr_err("Buffer flushing not supported for encoder\n");
- rc = -ENOTSUPP;
- mutex_unlock(&inst->sync_lock);
- break;
- }
-
- /* Certain types of flushes aren't supported such as: */
- /* 1) Input only flush */
- if (ip_flush && !op_flush) {
- pr_err("Input only flush not supported\n");
- rc = -ENOTSUPP;
- mutex_unlock(&inst->sync_lock);
- break;
- }
-
- /* 2) Output only flush when in reconfig */
- if (!ip_flush && op_flush && !inst->in_reconfig) {
- pr_err("Output only flush only supported when reconfiguring\n");
- rc = -ENOTSUPP;
- mutex_unlock(&inst->sync_lock);
- break;
- }
-
- /* Finally flush */
- if (op_flush && ip_flush)
- rc = vidc_hal_session_flush(inst->session,
- HAL_FLUSH_ALL);
- else if (ip_flush)
- rc = vidc_hal_session_flush(inst->session,
- HAL_FLUSH_INPUT);
- else if (op_flush)
- rc = vidc_hal_session_flush(inst->session,
- HAL_FLUSH_OUTPUT);
- mutex_unlock(&inst->sync_lock);
+ rc = msm_comm_flush(inst, dec->flags);
break;
case V4L2_DEC_CMD_STOP:
rc = msm_comm_try_state(inst, MSM_VIDC_CLOSE_DONE);
- if (rc)
- pr_err("Failed to close instance\n");
break;
default:
pr_err("Unknown Decoder Command\n");
rc = -ENOTSUPP;
goto exit;
}
-
if (rc) {
pr_err("Failed to exec decoder cmd %d\n", dec->cmd);
goto exit;
diff --git a/drivers/media/video/msm_vidc/msm_venc.c b/drivers/media/video/msm_vidc/msm_venc.c
index 1b1a0c5..2564a55 100644
--- a/drivers/media/video/msm_vidc/msm_venc.c
+++ b/drivers/media/video/msm_vidc/msm_venc.c
@@ -1251,9 +1251,16 @@
int msm_venc_cmd(struct msm_vidc_inst *inst, struct v4l2_encoder_cmd *enc)
{
int rc = 0;
- rc = msm_comm_try_state(inst, MSM_VIDC_CLOSE_DONE);
+ switch (enc->cmd) {
+ case V4L2_ENC_QCOM_CMD_FLUSH:
+ rc = msm_comm_flush(inst, enc->flags);
+ break;
+ case V4L2_ENC_CMD_STOP:
+ rc = msm_comm_try_state(inst, MSM_VIDC_CLOSE_DONE);
+ break;
+ }
if (rc)
- pr_err("Failed to close instance\n");
+ pr_err("Command: %d failed with rc = %d\n", enc->cmd, rc);
return rc;
}
diff --git a/drivers/media/video/msm_vidc/msm_vidc_common.c b/drivers/media/video/msm_vidc/msm_vidc_common.c
index 3f7e333..d85273d 100644
--- a/drivers/media/video/msm_vidc/msm_vidc_common.c
+++ b/drivers/media/video/msm_vidc/msm_vidc_common.c
@@ -1584,3 +1584,27 @@
err_no_mem:
return rc;
}
+
+int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags)
+{
+ int rc = 0;
+ bool ip_flush = false;
+ bool op_flush = false;
+ ip_flush = flags & V4L2_QCOM_CMD_FLUSH_OUTPUT;
+ op_flush = flags & V4L2_QCOM_CMD_FLUSH_CAPTURE;
+
+ if (ip_flush && !op_flush) {
+ pr_warn("Input only flush not supported\n");
+ return 0;
+ }
+ mutex_lock(&inst->sync_lock);
+ if (inst->in_reconfig && !ip_flush && op_flush) {
+ rc = vidc_hal_session_flush(inst->session,
+ HAL_FLUSH_OUTPUT);
+ } else {
+ rc = vidc_hal_session_flush(inst->session,
+ HAL_FLUSH_ALL);
+ }
+ mutex_unlock(&inst->sync_lock);
+ return rc;
+}
diff --git a/drivers/media/video/msm_vidc/msm_vidc_common.h b/drivers/media/video/msm_vidc/msm_vidc_common.h
index 69e466e..69aa53a 100644
--- a/drivers/media/video/msm_vidc/msm_vidc_common.h
+++ b/drivers/media/video/msm_vidc/msm_vidc_common.h
@@ -31,6 +31,7 @@
int msm_comm_set_persist_buffers(struct msm_vidc_inst *inst);
int msm_comm_qbuf(struct vb2_buffer *vb);
int msm_comm_scale_clocks(struct msm_vidc_core *core, enum session_type type);
+int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags);
#define IS_PRIV_CTRL(idx) (\
(V4L2_CTRL_ID2CLASS(idx) == V4L2_CTRL_CLASS_MPEG) && \
V4L2_CTRL_DRIVER_PRIV(idx))
diff --git a/drivers/media/video/msm_vidc/vidc_hal.c b/drivers/media/video/msm_vidc/vidc_hal.c
index 2021ec6..8e9e57f 100644
--- a/drivers/media/video/msm_vidc/vidc_hal.c
+++ b/drivers/media/video/msm_vidc/vidc_hal.c
@@ -607,6 +607,28 @@
return rc;
}
+static void set_vbif_registers(struct hal_device *device)
+{
+ write_register(device->hal_data->register_base_addr,
+ VIDC_VENUS0_VENUS_WRAPPER_VBIF_REQ_PRIORITY, 0, 0);
+ write_register(device->hal_data->register_base_addr,
+ VIDC_VENUS0_VENUS_WRAPPER_VBIF_PRIORITY_LEVEL, 0, 0);
+ write_register(device->hal_data->register_base_addr,
+ VIDC_VBIF_ARB_CTL, 0x30, 0);
+ write_register(device->hal_data->register_base_addr,
+ VIDC_VBIF_ROUND_ROBIN_QOS_ARB, 0x1, 0);
+ write_register(device->hal_data->register_base_addr,
+ VIDC_VBIF_OUT_AXI_AOOO_EN, 0x00000FFF, 0);
+ write_register(device->hal_data->register_base_addr,
+ VIDC_VBIF_OUT_AXI_AOOO, 0x0FFF0FFF, 0);
+ write_register(device->hal_data->register_base_addr,
+ VIDC_VBIF_OUT_AXI_AMEMTYPE_CONF0, 0x22222222, 0);
+ write_register(device->hal_data->register_base_addr,
+ VIDC_VBIF_OUT_AXI_AMEMTYPE_CONF1, 0x00002222, 0);
+ write_register(device->hal_data->register_base_addr,
+ VIDC_VBIF_DDR_OUT_MAX_BURST, 0x00000707, 0);
+}
+
int vidc_hal_core_init(void *device, int domain)
{
struct hfi_cmd_sys_init_packet pkt;
@@ -627,7 +649,7 @@
/*Disable Dynamic clock gating for Venus VBIF*/
write_register(dev->hal_data->register_base_addr,
VIDC_VENUS_VBIF_CLK_ON, 1, 0);
-
+ set_vbif_registers(dev);
if (!dev->hal_client) {
dev->hal_client = msm_smem_new_client(SMEM_ION);
if (dev->hal_client == NULL) {
diff --git a/drivers/media/video/msm_vidc/vidc_hal_io.h b/drivers/media/video/msm_vidc/vidc_hal_io.h
index c1058e6..571a053 100644
--- a/drivers/media/video/msm_vidc/vidc_hal_io.h
+++ b/drivers/media/video/msm_vidc/vidc_hal_io.h
@@ -98,7 +98,28 @@
#define VIDC_WRAPPER_AXI_HALT (VIDC_WRAPPER_BASE_OFFS + 0x2008)
#define VIDC_WRAPPER_AXI_HALT_STATUS (VIDC_WRAPPER_BASE_OFFS + 0x200C)
#define VIDC_WRAPPER_CPU_CGC_DIS (VIDC_WRAPPER_BASE_OFFS + 0x2010)
-#define VIDC_VENUS_VBIF_CLK_ON 0x80004
-
+#define VIDC_VENUS_VBIF_CLK_ON (VIDC_VBIF_BASE_OFFS + 0x4)
+#define VIDC_VBIF_IN_RD_LIM_CONF0 (VIDC_VBIF_BASE_OFFS + 0xB0)
+#define VIDC_VBIF_IN_RD_LIM_CONF1 (VIDC_VBIF_BASE_OFFS + 0xB4)
+#define VIDC_VBIF_IN_RD_LIM_CONF2 (VIDC_VBIF_BASE_OFFS + 0xB8)
+#define VIDC_VBIF_IN_WR_LIM_CONF0 (VIDC_VBIF_BASE_OFFS + 0xC0)
+#define VIDC_VBIF_IN_WR_LIM_CONF1 (VIDC_VBIF_BASE_OFFS + 0xC4)
+#define VIDC_VBIF_IN_WR_LIM_CONF2 (VIDC_VBIF_BASE_OFFS + 0xC8)
+#define VIDC_VBIF_OUT_RD_LIM_CONF0 (VIDC_VBIF_BASE_OFFS + 0xD0)
+#define VIDC_VBIF_OUT_WR_LIM_CONF0 (VIDC_VBIF_BASE_OFFS + 0xD4)
+#define VIDC_VBIF_DDR_OUT_MAX_BURST (VIDC_VBIF_BASE_OFFS + 0xD8)
+#define VIDC_VBIF_ARB_CTL (VIDC_VBIF_BASE_OFFS + 0xF0)
+#define VIDC_VBIF_DDR_ARB_CONF0 (VIDC_VBIF_BASE_OFFS + 0xF4)
+#define VIDC_VBIF_DDR_ARB_CONF1 (VIDC_VBIF_BASE_OFFS + 0xF8)
+#define VIDC_VBIF_ROUND_ROBIN_QOS_ARB (VIDC_VBIF_BASE_OFFS + 0x124)
+#define VIDC_VBIF_OUT_AXI_AOOO_EN (VIDC_VBIF_BASE_OFFS + 0x178)
+#define VIDC_VBIF_OUT_AXI_AOOO (VIDC_VBIF_BASE_OFFS + 0x17C)
+#define VIDC_VBIF_OUT_AXI_AMEMTYPE_CONF0 \
+ (VIDC_VBIF_BASE_OFFS + 0x160)
+#define VIDC_VBIF_OUT_AXI_AMEMTYPE_CONF1 \
+ (VIDC_VBIF_BASE_OFFS + 0x164)
+#define VIDC_VENUS0_VENUS_WRAPPER_VBIF_REQ_PRIORITY \
+ (VIDC_WRAPPER_BASE_OFFS + 0x20)
+#define VIDC_VENUS0_VENUS_WRAPPER_VBIF_PRIORITY_LEVEL \
+ (VIDC_WRAPPER_BASE_OFFS + 0x24)
#endif
-
diff --git a/drivers/usb/misc/mdm_data_bridge.c b/drivers/usb/misc/mdm_data_bridge.c
index 59ae13b..c78fd0c 100644
--- a/drivers/usb/misc/mdm_data_bridge.c
+++ b/drivers/usb/misc/mdm_data_bridge.c
@@ -990,10 +990,10 @@
}
ch_id--;
- ctrl_bridge_disconnect(ch_id);
+ ctrl_bridge_disconnect(dev->id);
platform_device_unregister(dev->pdev);
usb_set_intfdata(intf, NULL);
- __dev[ch_id] = NULL;
+ __dev[dev->id] = NULL;
cancel_work_sync(&dev->process_rx_w);
cancel_work_sync(&dev->kevent);
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index 70685e7..4fc78cd 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -1537,6 +1537,7 @@
mdp_clk_disable_unprepare();
}
}
+ pr_debug("%s: on=%d cnt=%d\n", __func__, on, mdp_clk_cnt);
mutex_unlock(&mdp_suspend_mutex);
}
@@ -2060,8 +2061,10 @@
int ret = 0;
struct msm_fb_data_type *mfd = platform_get_drvdata(pdev);
+ pr_debug("%s:+\n", __func__);
mdp_histogram_ctrl_all(FALSE);
+ mdp_clk_ctrl(1);
if (mfd->panel.type == MIPI_CMD_PANEL)
mdp4_dsi_cmd_off(pdev);
else if (mfd->panel.type == MIPI_VIDEO_PANEL)
@@ -2074,9 +2077,11 @@
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
ret = panel_next_off(pdev);
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+ mdp_clk_ctrl(0);
if (mdp_rev >= MDP_REV_41 && mfd->panel.type == MIPI_CMD_PANEL)
mdp_dsi_cmd_overlay_suspend(mfd);
+ pr_debug("%s:-\n", __func__);
return ret;
}
@@ -2097,6 +2102,8 @@
struct msm_fb_data_type *mfd;
mfd = platform_get_drvdata(pdev);
+ pr_debug("%s:+\n", __func__);
+
if (mdp_rev >= MDP_REV_40) {
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
mdp_clk_ctrl(1);
@@ -2126,8 +2133,8 @@
ret = panel_next_on(pdev);
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
-
mdp_histogram_ctrl_all(TRUE);
+ pr_debug("%s:-\n", __func__);
return ret;
}
diff --git a/drivers/video/msm/mdp4.h b/drivers/video/msm/mdp4.h
index 054741f..c845053 100644
--- a/drivers/video/msm/mdp4.h
+++ b/drivers/video/msm/mdp4.h
@@ -480,7 +480,7 @@
struct mdp4_overlay_pipe *pipe);
void mdp4_dmae_done_dtv(void);
void mdp4_dtv_wait4vsync(int cndx, long long *vtime);
-void mdp4_dtv_vsync_ctrl(int cndx, int enable);
+void mdp4_dtv_vsync_ctrl(struct fb_info *info, int enable);
void mdp4_dtv_base_swap(int cndx, struct mdp4_overlay_pipe *pipe);
#else
static inline void mdp4_overlay_dtv_start(void)
@@ -516,7 +516,7 @@
{
/* empty */
}
-static inline void mdp4_dtv_vsync_ctrl(int cndx, long long *vtime)
+static inline void mdp4_dtv_vsync_ctrl(struct fb_info *info, int enable)
{
/* empty */
}
@@ -548,7 +548,7 @@
int mdp4_atv_off(struct platform_device *pdev);
void mdp4_dsi_video_fxn_register(cmd_fxn_t fxn);
void mdp4_dsi_video_overlay(struct msm_fb_data_type *mfd);
-void mdp4_lcdc_vsync_ctrl(int cndx, int enable);
+void mdp4_lcdc_vsync_ctrl(struct fb_info *info, int enable);
void mdp4_overlay0_done_dsi_video(int cndx);
void mdp4_overlay0_done_dsi_cmd(int cndx);
void mdp4_primary_rdptr(void);
@@ -773,8 +773,8 @@
void mdp4_dsi_video_wait4vsync(int cndx, long long *vtime);
void mdp4_dsi_cmd_pipe_queue(int cndx, struct mdp4_overlay_pipe *pipe);
void mdp4_dsi_video_pipe_queue(int cndx, struct mdp4_overlay_pipe *pipe);
-void mdp4_dsi_cmd_vsync_ctrl(int cndx, int enable);
-void mdp4_dsi_video_vsync_ctrl(int cndx, int enable);
+void mdp4_dsi_cmd_vsync_ctrl(struct fb_info *info, int enable);
+void mdp4_dsi_video_vsync_ctrl(struct fb_info *info, int enable);
#ifdef CONFIG_FB_MSM_MDP303
static inline void mdp4_dsi_cmd_del_timer(void)
{
@@ -822,10 +822,12 @@
struct mdp4_overlay_pipe *pipe)
{
}
-static inline void mdp4_dsi_cmd_vsync_ctrl(int cndx, int enable)
+static inline void mdp4_dsi_cmd_vsync_ctrl(struct fb_info *info,
+ int enable)
{
}
-static inline void mdp4_dsi_video_vsync_ctrl(int cndx, int enable)
+static inline void mdp4_dsi_video_vsync_ctrl(struct fb_info *info,
+ int enable)
{
}
diff --git a/drivers/video/msm/mdp4_overlay.c b/drivers/video/msm/mdp4_overlay.c
index c07b3a7..3a1531f 100644
--- a/drivers/video/msm/mdp4_overlay.c
+++ b/drivers/video/msm/mdp4_overlay.c
@@ -3174,13 +3174,13 @@
if (!hdmi_prim_display && info->node == 0) {
if (ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO)
- mdp4_dsi_video_vsync_ctrl(0, cmd);
+ mdp4_dsi_video_vsync_ctrl(info, cmd);
else if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD)
- mdp4_dsi_cmd_vsync_ctrl(0, cmd);
+ mdp4_dsi_cmd_vsync_ctrl(info, cmd);
else if (ctrl->panel_mode & MDP4_PANEL_LCDC)
- mdp4_lcdc_vsync_ctrl(0, cmd);
+ mdp4_lcdc_vsync_ctrl(info, cmd);
} else if (hdmi_prim_display || info->node == 1)
- mdp4_dtv_vsync_ctrl(0, cmd);
+ mdp4_dtv_vsync_ctrl(info, cmd);
return 0;
}
diff --git a/drivers/video/msm/mdp4_overlay_dsi_cmd.c b/drivers/video/msm/mdp4_overlay_dsi_cmd.c
index c788c33..6232de0 100644
--- a/drivers/video/msm/mdp4_overlay_dsi_cmd.c
+++ b/drivers/video/msm/mdp4_overlay_dsi_cmd.c
@@ -39,7 +39,7 @@
static int vsync_start_y_adjust = 4;
#define MAX_CONTROLLER 1
-#define VSYNC_EXPIRE_TICK 4
+#define VSYNC_EXPIRE_TICK 8
static struct vsycn_ctrl {
struct device *dev;
@@ -58,7 +58,7 @@
int blt_change;
int blt_free;
int blt_end;
- int fake_vsync;
+ int uevent;
struct mutex update_lock;
struct completion ov_comp;
struct completion dmap_comp;
@@ -70,6 +70,7 @@
int vsync_enabled;
int clk_enabled;
int clk_control;
+ int new_update;
ktime_t vsync_time;
struct work_struct vsync_work;
struct work_struct clk_work;
@@ -379,26 +380,59 @@
return cnt;
}
-void mdp4_dsi_cmd_vsync_ctrl(int cndx, int enable)
-{
- struct vsycn_ctrl *vctrl;
+static void mdp4_overlay_update_dsi_cmd(struct msm_fb_data_type *mfd);
- if (cndx >= MAX_CONTROLLER) {
- pr_err("%s: out or range: cndx=%d\n", __func__, cndx);
- return;
- }
+void mdp4_dsi_cmd_vsync_ctrl(struct fb_info *info, int enable)
+{
+ struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+ struct vsycn_ctrl *vctrl;
+ unsigned long flags;
+ int clk_set_on = 0;
+ int cndx = 0;
vctrl = &vsync_ctrl_db[cndx];
- if (enable && vctrl->fake_vsync) {
- vctrl->fake_vsync = 0;
- schedule_work(&vctrl->vsync_work);
+ pr_debug("%s: clk_enabled=%d vsycn_enabeld=%d req=%d\n", __func__,
+ vctrl->clk_enabled, vctrl->vsync_enabled, enable);
+
+ mutex_lock(&vctrl->update_lock);
+
+ if (vctrl->vsync_enabled == enable) {
+ mutex_unlock(&vctrl->update_lock);
+ return;
}
- if (vctrl->vsync_enabled == enable)
- return;
-
vctrl->vsync_enabled = enable;
+
+ if (enable) {
+ if (vctrl->clk_enabled == 0) {
+ pr_debug("%s: SET_CLK_ON\n", __func__);
+ mipi_dsi_clk_cfg(1);
+ mdp_clk_ctrl(1);
+ vctrl->clk_enabled = 1;
+ clk_set_on = 1;
+ }
+ spin_lock_irqsave(&vctrl->spin_lock, flags);
+ vctrl->clk_control = 0;
+ vctrl->expire_tick = 0;
+ vctrl->uevent = 1;
+ vctrl->new_update = 1;
+ if (clk_set_on) {
+ vsync_irq_enable(INTR_PRIMARY_RDPTR,
+ MDP_PRIM_RDPTR_TERM);
+ }
+ spin_unlock_irqrestore(&vctrl->spin_lock, flags);
+
+ mdp4_overlay_update_dsi_cmd(mfd);
+ } else {
+ spin_lock_irqsave(&vctrl->spin_lock, flags);
+ vctrl->clk_control = 1;
+ vctrl->uevent = 0;
+ if (vctrl->clk_enabled)
+ vctrl->expire_tick = VSYNC_EXPIRE_TICK;
+ spin_unlock_irqrestore(&vctrl->spin_lock, flags);
+ }
+ mutex_unlock(&vctrl->update_lock);
}
void mdp4_dsi_cmd_wait4vsync(int cndx, long long *vtime)
@@ -479,13 +513,21 @@
pr_debug("%s: ISR, cpu=%d\n", __func__, smp_processor_id());
vctrl->rdptr_intr_tot++;
vctrl->vsync_time = ktime_get();
- schedule_work(&vctrl->vsync_work);
spin_lock(&vctrl->spin_lock);
+ if (vctrl->uevent)
+ schedule_work(&vctrl->vsync_work);
+
if (vctrl->wait_vsync_cnt) {
complete(&vctrl->vsync_comp);
vctrl->wait_vsync_cnt = 0;
}
+
+ if (vctrl->expire_tick) {
+ vctrl->expire_tick--;
+ if (vctrl->expire_tick == 0)
+ schedule_work(&vctrl->clk_work);
+ }
spin_unlock(&vctrl->spin_lock);
}
@@ -578,16 +620,19 @@
{
struct vsycn_ctrl *vctrl =
container_of(work, typeof(*vctrl), clk_work);
+ unsigned long flags;
mutex_lock(&vctrl->update_lock);
- if (vctrl->clk_control) {
- if (vctrl->clk_enabled) {
- mdp_clk_ctrl(0);
- vctrl->clk_enabled = 0;
- vctrl->fake_vsync = 1;
- }
+ if (vctrl->clk_control && vctrl->clk_enabled) {
+ pr_debug("%s: SET_CLK_OFF\n", __func__);
+ mdp_clk_ctrl(0);
+ mipi_dsi_clk_cfg(0);
+ spin_lock_irqsave(&vctrl->spin_lock, flags);
+ vsync_irq_disable(INTR_PRIMARY_RDPTR, MDP_PRIM_RDPTR_TERM);
+ vctrl->clk_enabled = 0;
+ vctrl->clk_control = 0;
+ spin_unlock_irqrestore(&vctrl->spin_lock, flags);
}
-
mutex_unlock(&vctrl->update_lock);
}
@@ -746,7 +791,7 @@
pipe->srcp0_addr = (uint32)src;
}
-void mdp4_overlay_update_dsi_cmd(struct msm_fb_data_type *mfd)
+static void mdp4_overlay_update_dsi_cmd(struct msm_fb_data_type *mfd)
{
int ptype;
struct mdp4_overlay_pipe *pipe;
@@ -760,30 +805,31 @@
vctrl = &vsync_ctrl_db[cndx];
- /* MDP cmd block enable */
- mdp_clk_ctrl(1);
+ if (vctrl->base_pipe == NULL) {
+ ptype = mdp4_overlay_format2type(mfd->fb_imgType);
+ if (ptype < 0)
+ printk(KERN_INFO "%s: format2type failed\n", __func__);
+ pipe = mdp4_overlay_pipe_alloc(ptype, MDP4_MIXER0);
+ if (pipe == NULL) {
+ printk(KERN_INFO "%s: pipe_alloc failed\n", __func__);
+ return;
+ }
+ pipe->pipe_used++;
+ pipe->mixer_stage = MDP4_MIXER_STAGE_BASE;
+ pipe->mixer_num = MDP4_MIXER0;
+ pipe->src_format = mfd->fb_imgType;
+ mdp4_overlay_panel_mode(pipe->mixer_num, MDP4_PANEL_DSI_CMD);
+ ret = mdp4_overlay_format2pipe(pipe);
+ if (ret < 0)
+ printk(KERN_INFO "%s: format2type failed\n", __func__);
- ptype = mdp4_overlay_format2type(mfd->fb_imgType);
- if (ptype < 0)
- printk(KERN_INFO "%s: format2type failed\n", __func__);
- pipe = mdp4_overlay_pipe_alloc(ptype, MDP4_MIXER0);
- if (pipe == NULL) {
- printk(KERN_INFO "%s: pipe_alloc failed\n", __func__);
- return;
+ vctrl->base_pipe = pipe; /* keep it */
+ mdp4_init_writeback_buf(mfd, MDP4_MIXER0);
+ pipe->ov_blt_addr = 0;
+ pipe->dma_blt_addr = 0;
+ } else {
+ pipe = vctrl->base_pipe;
}
- pipe->pipe_used++;
- pipe->mixer_stage = MDP4_MIXER_STAGE_BASE;
- pipe->mixer_num = MDP4_MIXER0;
- pipe->src_format = mfd->fb_imgType;
- mdp4_overlay_panel_mode(pipe->mixer_num, MDP4_PANEL_DSI_CMD);
- ret = mdp4_overlay_format2pipe(pipe);
- if (ret < 0)
- printk(KERN_INFO "%s: format2type failed\n", __func__);
-
- vctrl->base_pipe = pipe; /* keep it */
- mdp4_init_writeback_buf(mfd, MDP4_MIXER0);
- pipe->ov_blt_addr = 0;
- pipe->dma_blt_addr = 0;
MDP_OUTP(MDP_BASE + 0x021c, 10); /* read pointer */
@@ -795,7 +841,6 @@
/* disable dsi trigger */
MDP_OUTP(MDP_BASE + 0x000a4, 0x00);
-
mdp4_overlay_setup_pipe_addr(mfd, pipe);
mdp4_overlay_rgb_setup(pipe);
@@ -810,9 +855,7 @@
mdp4_overlay_dmap_cfg(mfd, 0);
- mdp4_mixer_stage_commit(pipe->mixer_num);
- /* MDP cmd block disable */
- mdp_clk_ctrl(0);
+ wmb();
}
/* 3D side by side */
@@ -916,7 +959,7 @@
struct msm_fb_data_type *mfd;
struct vsycn_ctrl *vctrl;
- pr_info("%s+:\n", __func__);
+ pr_debug("%s+:\n", __func__);
mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
@@ -925,15 +968,13 @@
vctrl->dev = mfd->fbi->dev;
mdp_clk_ctrl(1);
- vsync_irq_enable(INTR_PRIMARY_RDPTR, MDP_PRIM_RDPTR_TERM);
-
- if (vctrl->base_pipe == NULL)
- mdp4_overlay_update_dsi_cmd(mfd);
+ mdp4_overlay_update_dsi_cmd(mfd);
+ mdp_clk_ctrl(0);
mdp4_iommu_attach();
atomic_set(&vctrl->suspend, 0);
- pr_info("%s-:\n", __func__);
+ pr_debug("%s-:\n", __func__);
return ret;
@@ -947,7 +988,7 @@
struct vsycn_ctrl *vctrl;
struct mdp4_overlay_pipe *pipe;
- pr_info("%s+:\n", __func__);
+ pr_debug("%s+:\n", __func__);
mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
@@ -966,11 +1007,25 @@
mdp4_overlay_pipe_free(pipe);
vctrl->base_pipe = NULL;
- vctrl->fake_vsync = 1;
+ if (vctrl->clk_enabled) {
+ /*
+ * in case of suspend, vsycn_ctrl off is not
+ * received from frame work which left clock on
+ * then, clock need to be turned off here
+ */
+ mdp_clk_ctrl(0);
+ }
+
+ vctrl->clk_enabled = 0;
+ vctrl->vsync_enabled = 0;
+ vctrl->clk_control = 0;
+ vctrl->expire_tick = 0;
+ vctrl->uevent = 0;
vsync_irq_disable(INTR_PRIMARY_RDPTR, MDP_PRIM_RDPTR_TERM);
- pr_info("%s-:\n", __func__);
+
+ pr_debug("%s-:\n", __func__);
/*
* footswitch off
@@ -1012,6 +1067,7 @@
int cndx = 0;
struct vsycn_ctrl *vctrl;
struct mdp4_overlay_pipe *pipe;
+ unsigned long flags;
long long xx;
vctrl = &vsync_ctrl_db[cndx];
@@ -1019,13 +1075,31 @@
if (!mfd->panel_power_on)
return;
- vctrl->clk_control = 0;
pipe = vctrl->base_pipe;
if (pipe == NULL) {
pr_err("%s: NO base pipe\n", __func__);
return;
}
+ mutex_lock(&vctrl->update_lock);
+ if (!vctrl->clk_enabled) {
+ pr_err("%s: mdp clocks disabled\n", __func__);
+ mutex_unlock(&vctrl->update_lock);
+ return;
+
+ }
+ mutex_unlock(&vctrl->update_lock);
+
+ spin_lock_irqsave(&vctrl->spin_lock, flags);
+ if (vctrl->expire_tick) {
+ /*
+ * in the middle of shutting clocks down
+ * delay to allow pan display to go through
+ */
+ vctrl->expire_tick = VSYNC_EXPIRE_TICK;
+ }
+ spin_unlock_irqrestore(&vctrl->spin_lock, flags);
+
if (pipe->mixer_stage == MDP4_MIXER_STAGE_BASE) {
mdp4_mipi_vsync_enable(mfd, pipe, 0);
mdp4_overlay_setup_pipe_addr(mfd, pipe);
@@ -1033,13 +1107,12 @@
}
mdp4_overlay_mdp_perf_upd(mfd, 1);
+
mutex_lock(&mfd->dma->ov_mutex);
mdp4_dsi_cmd_pipe_commit();
mutex_unlock(&mfd->dma->ov_mutex);
mdp4_dsi_cmd_wait4vsync(0, &xx);
- vctrl->expire_tick = VSYNC_EXPIRE_TICK;
- vctrl->clk_control = 1;
mdp4_overlay_mdp_perf_upd(mfd, 0);
}
diff --git a/drivers/video/msm/mdp4_overlay_dsi_video.c b/drivers/video/msm/mdp4_overlay_dsi_video.c
index a461c3b..04da0a3 100644
--- a/drivers/video/msm/mdp4_overlay_dsi_video.c
+++ b/drivers/video/msm/mdp4_overlay_dsi_video.c
@@ -256,14 +256,10 @@
return cnt;
}
-void mdp4_dsi_video_vsync_ctrl(int cndx, int enable)
+void mdp4_dsi_video_vsync_ctrl(struct fb_info *info, int enable)
{
struct vsycn_ctrl *vctrl;
-
- if (cndx >= MAX_CONTROLLER) {
- pr_err("%s: out or range: cndx=%d\n", __func__, cndx);
- return;
- }
+ int cndx = 0;
vctrl = &vsync_ctrl_db[cndx];
diff --git a/drivers/video/msm/mdp4_overlay_dtv.c b/drivers/video/msm/mdp4_overlay_dtv.c
index e131369..8a0b092 100644
--- a/drivers/video/msm/mdp4_overlay_dtv.c
+++ b/drivers/video/msm/mdp4_overlay_dtv.c
@@ -238,14 +238,10 @@
return cnt;
}
-void mdp4_dtv_vsync_ctrl(int cndx, int enable)
+void mdp4_dtv_vsync_ctrl(struct fb_info *info, int enable)
{
struct vsycn_ctrl *vctrl;
-
- if (cndx >= MAX_CONTROLLER) {
- pr_err("%s: out or range: cndx=%d\n", __func__, cndx);
- return;
- }
+ int cndx = 0;
vctrl = &vsync_ctrl_db[cndx];
diff --git a/drivers/video/msm/mdp4_overlay_lcdc.c b/drivers/video/msm/mdp4_overlay_lcdc.c
index a2fabca..aa2de32 100644
--- a/drivers/video/msm/mdp4_overlay_lcdc.c
+++ b/drivers/video/msm/mdp4_overlay_lcdc.c
@@ -260,14 +260,10 @@
return cnt;
}
-void mdp4_lcdc_vsync_ctrl(int cndx, int enable)
+void mdp4_lcdc_vsync_ctrl(struct fb_info *info, int enable)
{
struct vsycn_ctrl *vctrl;
-
- if (cndx >= MAX_CONTROLLER) {
- pr_err("%s: out or range: cndx=%d\n", __func__, cndx);
- return;
- }
+ int cndx = 0;
vctrl = &vsync_ctrl_db[cndx];
diff --git a/drivers/video/msm/mdss/mdss.h b/drivers/video/msm/mdss/mdss.h
index 886e8de..3017200 100644
--- a/drivers/video/msm/mdss/mdss.h
+++ b/drivers/video/msm/mdss/mdss.h
@@ -14,6 +14,7 @@
#ifndef MDSS_H
#define MDSS_H
+#include <linux/ion.h>
#include <linux/spinlock.h>
#include <linux/types.h>
#include <linux/workqueue.h>
@@ -52,24 +53,24 @@
u32 mdp_irq_mask;
- u32 clk_ena;
u32 suspend;
u32 timeout;
- u32 fs_ena;
- u32 vsync_ena;
+ u8 clk_ena;
+ u8 fs_ena;
+ u8 vsync_ena;
+ u8 eintf_ena;
- u32 intf;
- u32 eintf_ena;
u32 prim_ptype;
u32 res_init;
- u32 pdev_lcnt;
u32 bus_hdl;
u32 smp_mb_cnt;
u32 smp_mb_size;
u32 *pipe_type_map;
u32 *mixer_type_map;
+
+ struct ion_client *iclient;
};
extern struct mdss_data_type *mdss_res;
@@ -91,4 +92,10 @@
void mdss_enable_irq(struct mdss_hw *hw);
void mdss_disable_irq(struct mdss_hw *hw);
void mdss_disable_irq_nosync(struct mdss_hw *hw);
+static inline struct ion_client *mdss_get_ionclient(void)
+{
+ if (!mdss_res)
+ return NULL;
+ return mdss_res->iclient;
+}
#endif /* MDSS_H */
diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c
index 1f83b2b..5ea52e7 100644
--- a/drivers/video/msm/mdss/mdss_fb.c
+++ b/drivers/video/msm/mdss/mdss_fb.c
@@ -204,9 +204,6 @@
mfd->panel_info.frame_count = 0;
mfd->bl_level = 0;
mfd->fb_imgType = MDP_RGBA_8888;
- mfd->iclient = msm_ion_client_create(-1, pdev->name);
- if (IS_ERR(mfd->iclient))
- mfd->iclient = NULL;
mfd->pdev = pdev;
@@ -592,7 +589,7 @@
size *= mfd->fb_page;
if (mfd->index == 0) {
- struct ion_client *iclient = mfd->iclient;
+ struct ion_client *iclient = mdss_get_ionclient();
if (iclient) {
mfd->ihdl = ion_alloc(iclient, size, SZ_4K,
diff --git a/drivers/video/msm/mdss/mdss_fb.h b/drivers/video/msm/mdss/mdss_fb.h
index ab140fe..dd84ce5 100644
--- a/drivers/video/msm/mdss/mdss_fb.h
+++ b/drivers/video/msm/mdss/mdss_fb.h
@@ -89,10 +89,10 @@
u32 var_pixclock;
u32 mdp_fb_page_protection;
- struct ion_client *iclient;
struct mdss_mdp_ctl *ctl;
struct mdss_mdp_wb *wb;
+ struct list_head overlay_list;
};
int mdss_fb_get_phys_info(unsigned long *start, unsigned long *len, int fb_num);
diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c
index ce55e71..4604d4a 100644
--- a/drivers/video/msm/mdss/mdss_mdp.c
+++ b/drivers/video/msm/mdss/mdss_mdp.c
@@ -608,7 +608,7 @@
static u32 mdss_mdp_res_init(struct mdss_data_type *mdata)
{
- u32 rc;
+ u32 rc = 0;
rc = mdss_mdp_irq_clk_setup(mdata);
if (rc)
@@ -639,6 +639,13 @@
mdata->prim_ptype = NO_PANEL;
mdata->irq_ena = false;
+ mdata->iclient = msm_ion_client_create(-1, mdata->pdev->name);
+ if (IS_ERR_OR_NULL(mdata->iclient)) {
+ pr_err("msm_ion_client_create() return error (%p)\n",
+ mdata->iclient);
+ mdata->iclient = NULL;
+ }
+
rc = mdss_hw_init(mdata);
return rc;
diff --git a/drivers/video/msm/mdss/mdss_mdp.h b/drivers/video/msm/mdss/mdss_mdp.h
index a282c3a..a77c18e 100644
--- a/drivers/video/msm/mdss/mdss_mdp.h
+++ b/drivers/video/msm/mdss/mdss_mdp.h
@@ -200,7 +200,6 @@
int p_need;
struct file *srcp_file;
struct ion_handle *srcp_ihdl;
- struct ion_client *iclient;
};
struct mdss_mdp_data {
@@ -240,6 +239,9 @@
u32 params_changed;
unsigned long smp[MAX_PLANES];
+
+ struct mdss_mdp_data buffers[2];
+ struct list_head list;
};
struct mdss_mdp_writeback_arg {
@@ -276,6 +278,7 @@
void mdss_mdp_footswitch_ctrl(int on);
int mdss_mdp_overlay_init(struct msm_fb_data_type *mfd);
+int mdss_mdp_overlay_release_all(struct msm_fb_data_type *mfd);
int mdss_mdp_video_start(struct mdss_mdp_ctl *ctl);
int mdss_mdp_writeback_start(struct mdss_mdp_ctl *ctl);
@@ -301,7 +304,6 @@
void mdss_mdp_pipe_unlock(struct mdss_mdp_pipe *pipe);
int mdss_mdp_pipe_destroy(struct mdss_mdp_pipe *pipe);
-int mdss_mdp_pipe_release_all(struct msm_fb_data_type *mfd);
int mdss_mdp_pipe_queue_data(struct mdss_mdp_pipe *pipe,
struct mdss_mdp_data *src_data);
@@ -311,8 +313,7 @@
struct mdss_mdp_plane_sizes *ps);
struct mdss_mdp_format_params *mdss_mdp_get_format_params(u32 format);
int mdss_mdp_put_img(struct mdss_mdp_img_data *data);
-int mdss_mdp_get_img(struct ion_client *iclient, struct msmfb_data *img,
- struct mdss_mdp_img_data *data);
+int mdss_mdp_get_img(struct msmfb_data *img, struct mdss_mdp_img_data *data);
int mdss_mdp_wb_kickoff(struct mdss_mdp_ctl *ctl);
int mdss_mdp_wb_ioctl_handler(struct msm_fb_data_type *mfd, u32 cmd, void *arg);
diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c
index 21f4071..1486779 100644
--- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
+++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c
@@ -595,7 +595,7 @@
mutex_unlock(&ctl->lock);
- mdss_mdp_pipe_release_all(mfd);
+ mdss_mdp_overlay_release_all(mfd);
if (!mfd->ref_cnt)
mdss_mdp_ctl_destroy(mfd);
diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
index 1cb474d..6719d9e 100644
--- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
+++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c
@@ -279,6 +279,9 @@
return -ENOMEM;
}
+ mutex_lock(&mfd->lock);
+ list_add(&pipe->list, &mfd->overlay_list);
+ mutex_unlock(&mfd->lock);
pipe->mixer = mixer;
pipe->mfd = mfd;
} else {
@@ -343,6 +346,79 @@
return ret;
}
+static inline int mdss_mdp_overlay_get_buf(struct msm_fb_data_type *mfd,
+ struct mdss_mdp_data *data,
+ struct msmfb_data *planes,
+ int num_planes)
+{
+ int i;
+
+ memset(data, 0, sizeof(*data));
+ for (i = 0; i < num_planes; i++) {
+ mdss_mdp_get_img(&planes[i], &data->p[i]);
+ if (data->p[0].len == 0)
+ break;
+ }
+
+ if (i != num_planes) {
+ for (; i >= 0; i--)
+ mdss_mdp_put_img(&data->p[i]);
+ return -ENOMEM;
+ }
+
+ data->num_planes = num_planes;
+
+ return 0;
+}
+
+static inline int mdss_mdp_overlay_free_buf(struct mdss_mdp_data *data)
+{
+ int i;
+ for (i = 0; i < data->num_planes && data->p[i].len; i++)
+ mdss_mdp_put_img(&data->p[i]);
+
+ data->num_planes = 0;
+
+ return 0;
+}
+
+static int mdss_mdp_overlay_kickoff(struct mdss_mdp_ctl *ctl)
+{
+ int ret;
+
+ if (ctl->mfd->kickoff_fnc)
+ ret = ctl->mfd->kickoff_fnc(ctl);
+ else
+ ret = mdss_mdp_display_commit(ctl, NULL);
+ if (IS_ERR_VALUE(ret))
+ return ret;
+
+ pr_debug("freeing previous buffers\n");
+
+ mutex_lock(&ctl->mfd->lock);
+ if (!list_empty(&ctl->mfd->overlay_list)) {
+ struct mdss_mdp_pipe *pipe;
+ struct mdss_mdp_data *data;
+ int buf_ndx;
+
+ list_for_each_entry(pipe, &ctl->mfd->overlay_list, list) {
+ buf_ndx = (pipe->play_cnt - 1) & 1; /* prev buffer */
+ data = &pipe->buffers[buf_ndx];
+
+ if (data->num_planes) {
+ pr_debug("free buffer ndx=%d pnum=%d\n",
+ buf_ndx, pipe->num);
+ mdss_mdp_overlay_free_buf(data);
+ }
+ }
+ }
+ mutex_unlock(&ctl->mfd->lock);
+
+ pr_debug("done freeing previous buffers\n");
+
+ return ret;
+}
+
static int mdss_mdp_overlay_unset(struct msm_fb_data_type *mfd, int ndx)
{
struct mdss_mdp_pipe *pipe;
@@ -374,6 +450,9 @@
unset_ndx |= pipe_ndx;
pipe = mdss_mdp_pipe_get_locked(pipe_ndx);
if (pipe) {
+ mutex_lock(&mfd->lock);
+ list_del(&pipe->list);
+ mutex_unlock(&mfd->lock);
mdss_mdp_mixer_pipe_unstage(pipe);
cleanup_pipes[clean_cnt++] = pipe;
} else {
@@ -383,15 +462,51 @@
}
if (clean_cnt) {
- ret = mfd->kickoff_fnc(mfd->ctl);
+ int j;
+ ret = mdss_mdp_overlay_kickoff(mfd->ctl);
- for (i = 0; i < clean_cnt; i++)
- mdss_mdp_pipe_destroy(cleanup_pipes[i]);
+ for (i = 0; i < clean_cnt; i++) {
+ pipe = cleanup_pipes[i];
+ for (j = 0; j < ARRAY_SIZE(pipe->buffers); j++)
+ mdss_mdp_overlay_free_buf(&pipe->buffers[i]);
+
+ mdss_mdp_pipe_destroy(pipe);
+ }
}
return ret;
}
+int mdss_mdp_overlay_release_all(struct msm_fb_data_type *mfd)
+{
+ struct mdss_mdp_pipe *pipe;
+ u32 unset_ndx = 0;
+ int cnt = 0;
+
+ mutex_lock(&mfd->lock);
+ if (!list_empty(&mfd->overlay_list)) {
+ list_for_each_entry(pipe, &mfd->overlay_list, list) {
+ if (pipe->ndx & MDSS_MDP_ROT_SESSION_MASK) {
+ struct mdss_mdp_rotator_session *rot;
+ rot = mdss_mdp_rotator_session_get(pipe->ndx);
+ if (rot)
+ mdss_mdp_rotator_finish(rot);
+ } else {
+ unset_ndx |= pipe->ndx;
+ cnt++;
+ }
+ }
+ }
+ mutex_unlock(&mfd->lock);
+
+ if (unset_ndx) {
+ pr_debug("%d pipes need cleanup (%x)\n", cnt, unset_ndx);
+ mdss_mdp_overlay_unset(mfd, unset_ndx);
+ }
+
+ return 0;
+}
+
static int mdss_mdp_overlay_play_wait(struct msm_fb_data_type *mfd,
struct msmfb_overlay_data *req)
{
@@ -400,41 +515,59 @@
if (!mfd || !mfd->ctl)
return -ENODEV;
- ret = mfd->kickoff_fnc(mfd->ctl);
+ ret = mdss_mdp_overlay_kickoff(mfd->ctl);
if (!ret)
pr_err("error displaying\n");
return ret;
}
-static int mdss_mdp_overlay_rotate(struct msmfb_overlay_data *req,
- struct mdss_mdp_data *src_data,
- struct mdss_mdp_data *dst_data)
+static int mdss_mdp_overlay_rotate(struct msm_fb_data_type *mfd,
+ struct msmfb_overlay_data *req)
{
struct mdss_mdp_rotator_session *rot;
+ struct mdss_mdp_data src_data, dst_data;
int ret;
+ ret = mdss_mdp_overlay_get_buf(mfd, &src_data, &req->data, 1);
+ if (ret) {
+ pr_err("src_data pmem error\n");
+ goto rotate_done;
+ }
+
+ ret = mdss_mdp_overlay_get_buf(mfd, &dst_data, &req->dst_data, 1);
+ if (ret) {
+ pr_err("dst_data pmem error\n");
+ goto rotate_done;
+ }
+
rot = mdss_mdp_rotator_session_get(req->id);
if (!rot) {
pr_err("invalid session id=%x\n", req->id);
- return -ENODEV;
+ ret = -ENODEV;
+ goto rotate_done;
}
- ret = mdss_mdp_rotator_queue(rot, src_data, dst_data);
+ ret = mdss_mdp_rotator_queue(rot, &src_data, &dst_data);
if (ret) {
pr_err("rotator queue error session id=%x\n", req->id);
- return ret;
+ goto rotate_done;
}
+rotate_done:
+ mdss_mdp_overlay_free_buf(&dst_data);
+ mdss_mdp_overlay_free_buf(&src_data);
+
return 0;
}
-static int mdss_mdp_overlay_queue(struct msmfb_overlay_data *req,
- struct mdss_mdp_data *src_data)
+static int mdss_mdp_overlay_queue(struct msm_fb_data_type *mfd,
+ struct msmfb_overlay_data *req)
{
- struct mdss_mdp_pipe *pipe;
struct mdss_mdp_ctl *ctl;
- int ret;
+ struct mdss_mdp_pipe *pipe;
+ struct mdss_mdp_data *src_data;
+ int ret, buf_ndx;
pipe = mdss_mdp_pipe_get_locked(req->id);
if (pipe == NULL) {
@@ -444,13 +577,23 @@
pr_debug("ov queue pnum=%d\n", pipe->num);
- ret = mdss_mdp_pipe_queue_data(pipe, src_data);
+ buf_ndx = (pipe->play_cnt + 1) & 1; /* next buffer */
+ src_data = &pipe->buffers[buf_ndx];
+ mdss_mdp_overlay_free_buf(src_data);
+
+ ret = mdss_mdp_overlay_get_buf(mfd, src_data, &req->data, 1);
+ if (IS_ERR_VALUE(ret)) {
+ pr_err("src_data pmem error\n");
+ } else {
+ ret = mdss_mdp_pipe_queue_data(pipe, src_data);
+ if (IS_ERR_VALUE(ret))
+ mdss_mdp_overlay_free_buf(src_data);
+ }
ctl = pipe->mixer->ctl;
mdss_mdp_pipe_unlock(pipe);
if (ret == 0 && !(pipe->flags & MDP_OV_PLAY_NOWAIT))
- ret = ctl->mfd->kickoff_fnc(ctl);
-
+ ret = mdss_mdp_overlay_kickoff(ctl);
return ret;
}
@@ -458,41 +601,14 @@
static int mdss_mdp_overlay_play(struct msm_fb_data_type *mfd,
struct msmfb_overlay_data *req)
{
- struct mdss_mdp_data src_data;
int ret = 0;
- if (mfd == NULL)
- return -ENODEV;
-
pr_debug("play req id=%x\n", req->id);
- memset(&src_data, 0, sizeof(src_data));
- mdss_mdp_get_img(mfd->iclient, &req->data, &src_data.p[0]);
- if (src_data.p[0].len == 0) {
- pr_err("src data pmem error\n");
- return -ENOMEM;
- }
- src_data.num_planes = 1;
-
- if (req->id & MDSS_MDP_ROT_SESSION_MASK) {
- struct mdss_mdp_data dst_data;
- memset(&dst_data, 0, sizeof(dst_data));
-
- mdss_mdp_get_img(mfd->iclient, &req->dst_data, &dst_data.p[0]);
- if (dst_data.p[0].len == 0) {
- pr_err("dst data pmem error\n");
- return -ENOMEM;
- }
- dst_data.num_planes = 1;
-
- ret = mdss_mdp_overlay_rotate(req, &src_data, &dst_data);
-
- mdss_mdp_put_img(&dst_data.p[0]);
- } else {
- ret = mdss_mdp_overlay_queue(req, &src_data);
- }
-
- mdss_mdp_put_img(&src_data.p[0]);
+ if (req->id & MDSS_MDP_ROT_SESSION_MASK)
+ ret = mdss_mdp_overlay_rotate(mfd, req);
+ else
+ ret = mdss_mdp_overlay_queue(mfd, req);
return ret;
}
@@ -577,6 +693,12 @@
offset = fbi->var.xoffset * bpp +
fbi->var.yoffset * fbi->fix.line_length;
+ if (offset > fbi->fix.smem_len) {
+ pr_err("invalid fb offset=%u total length=%u\n",
+ offset, fbi->fix.smem_len);
+ return;
+ }
+
data.p[0].addr = fbi->fix.smem_start + offset;
data.p[0].len = fbi->fix.smem_len - offset;
data.num_planes = 1;
@@ -612,7 +734,7 @@
}
if (fbi->var.activate & FB_ACTIVATE_VBL)
- mfd->kickoff_fnc(mfd->ctl);
+ mdss_mdp_overlay_kickoff(mfd->ctl);
}
static void mdss_mdp_overlay_handle_vsync(struct mdss_mdp_ctl *ctl, ktime_t t)
@@ -772,11 +894,6 @@
return 0;
}
-static int mdss_mdp_overlay_kickoff(struct mdss_mdp_ctl *ctl)
-{
- return mdss_mdp_display_commit(ctl, NULL);
-}
-
static int mdss_mdp_overlay_ioctl_handler(struct msm_fb_data_type *mfd,
u32 cmd, void __user *argp)
{
@@ -897,8 +1014,8 @@
if (mfd->panel_info.type == WRITEBACK_PANEL)
mfd->kickoff_fnc = mdss_mdp_wb_kickoff;
- else
- mfd->kickoff_fnc = mdss_mdp_overlay_kickoff;
+
+ INIT_LIST_HEAD(&mfd->overlay_list);
return 0;
}
diff --git a/drivers/video/msm/mdss/mdss_mdp_pipe.c b/drivers/video/msm/mdss/mdss_mdp_pipe.c
index c94068a..c936b7d 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pipe.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pipe.c
@@ -272,35 +272,6 @@
return 0;
}
-int mdss_mdp_pipe_release_all(struct msm_fb_data_type *mfd)
-{
- struct mdss_mdp_pipe *pipe;
- int i;
-
- if (!mfd)
- return -ENODEV;
-
- mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
- mutex_lock(&mdss_mdp_sspp_lock);
- for (i = 0; i < MDSS_MDP_MAX_SSPP; i++) {
- pipe = &mdss_mdp_pipe_list[i];
- if (atomic_read(&pipe->ref_cnt) && pipe->mfd == mfd) {
- pr_debug("release pnum=%d\n", pipe->num);
- if (mdss_mdp_pipe_lock(pipe) == 0) {
- mdss_mdp_mixer_pipe_unstage(pipe);
- mdss_mdp_pipe_free(pipe);
- } else {
- pr_err("unable to lock pipe=%d for release",
- pipe->num);
- }
- }
- }
- mutex_unlock(&mdss_mdp_sspp_lock);
- mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
-
- return 0;
-}
-
static inline void mdss_mdp_pipe_write(struct mdss_mdp_pipe *pipe,
u32 reg, u32 val)
{
diff --git a/drivers/video/msm/mdss/mdss_mdp_util.c b/drivers/video/msm/mdss/mdss_mdp_util.c
index 53cd378..6fd8463 100644
--- a/drivers/video/msm/mdss/mdss_mdp_util.c
+++ b/drivers/video/msm/mdss/mdss_mdp_util.c
@@ -284,33 +284,33 @@
int mdss_mdp_put_img(struct mdss_mdp_img_data *data)
{
- /* only source may use frame buffer */
+ struct ion_client *iclient = mdss_get_ionclient();
if (data->flags & MDP_MEMORY_ID_TYPE_FB) {
+ pr_debug("fb mem buf=0x%x\n", data->addr);
fput_light(data->srcp_file, data->p_need);
- return 0;
- }
- if (data->srcp_file) {
+ data->srcp_file = NULL;
+ } else if (data->srcp_file) {
+ pr_debug("pmem buf=0x%x\n", data->addr);
put_pmem_file(data->srcp_file);
data->srcp_file = NULL;
- return 0;
- }
- if (!IS_ERR_OR_NULL(data->srcp_ihdl)) {
- ion_free(data->iclient, data->srcp_ihdl);
- data->iclient = NULL;
+ } else if (!IS_ERR_OR_NULL(data->srcp_ihdl)) {
+ pr_debug("ion hdl=%p buf=0x%x\n", data->srcp_ihdl, data->addr);
+ ion_free(iclient, data->srcp_ihdl);
data->srcp_ihdl = NULL;
- return 0;
+ } else {
+ return -ENOMEM;
}
- return -ENOMEM;
+ return 0;
}
-int mdss_mdp_get_img(struct ion_client *iclient, struct msmfb_data *img,
- struct mdss_mdp_img_data *data)
+int mdss_mdp_get_img(struct msmfb_data *img, struct mdss_mdp_img_data *data)
{
struct file *file;
int ret = -EINVAL;
int fb_num;
unsigned long *start, *len;
+ struct ion_client *iclient = mdss_get_ionclient();
start = (unsigned long *) &data->addr;
len = (unsigned long *) &data->len;
@@ -323,19 +323,36 @@
start, len);
} else if (img->flags & MDP_MEMORY_ID_TYPE_FB) {
file = fget_light(img->memory_id, &data->p_need);
- if (file && FB_MAJOR ==
- MAJOR(file->f_dentry->d_inode->i_rdev)) {
- data->srcp_file = file;
+ if (file == NULL) {
+ pr_err("invalid framebuffer file (%d)\n",
+ img->memory_id);
+ return -EINVAL;
+ }
+ data->srcp_file = file;
+
+ if (MAJOR(file->f_dentry->d_inode->i_rdev) == FB_MAJOR) {
fb_num = MINOR(file->f_dentry->d_inode->i_rdev);
ret = mdss_fb_get_phys_info(start, len, fb_num);
+ if (ret)
+ pr_err("mdss_fb_get_phys_info() failed\n");
+ } else {
+ pr_err("invalid FB_MAJOR\n");
+ ret = -1;
}
} else if (iclient) {
- data->iclient = iclient;
data->srcp_ihdl = ion_import_dma_buf(iclient, img->memory_id);
- if (IS_ERR_OR_NULL(data->srcp_ihdl))
- return PTR_ERR(data->srcp_ihdl);
- ret = ion_phys(iclient, data->srcp_ihdl,
- start, (size_t *) len);
+ if (IS_ERR_OR_NULL(data->srcp_ihdl)) {
+ pr_err("error on ion_import_fd\n");
+ ret = PTR_ERR(data->srcp_ihdl);
+ data->srcp_ihdl = NULL;
+ return ret;
+ }
+ ret = ion_phys(iclient, data->srcp_ihdl, start, (size_t *) len);
+ if (IS_ERR_VALUE(ret)) {
+ ion_free(iclient, data->srcp_ihdl);
+ pr_err("failed to map ion handle (%d)\n", ret);
+ return ret;
+ }
} else {
unsigned long vstart;
ret = get_pmem_file(img->memory_id, start, &vstart, len,
@@ -345,9 +362,11 @@
if (!ret && (img->offset < data->len)) {
data->addr += img->offset;
data->len -= img->offset;
+
+ pr_debug("mem=%d ihdl=%p buf=0x%x len=0x%x\n", img->memory_id,
+ data->srcp_ihdl, data->addr, data->len);
} else {
- mdss_mdp_put_img(data);
- ret = -EINVAL;
+ return -EINVAL;
}
return ret;
diff --git a/drivers/video/msm/mdss/mdss_mdp_wb.c b/drivers/video/msm/mdss/mdss_mdp_wb.c
index 26e459f..8c4b1b9 100644
--- a/drivers/video/msm/mdss/mdss_mdp_wb.c
+++ b/drivers/video/msm/mdss/mdss_mdp_wb.c
@@ -67,33 +67,34 @@
static struct ion_handle *ihdl;
static void *videomemory;
static ion_phys_addr_t mdss_wb_mem;
- static struct mdss_mdp_data buffer = { .num_planes = 1, };
- struct fb_info *fbi;
- size_t img_size;
+ static struct mdss_mdp_data mdss_wb_buffer = { .num_planes = 1, };
- fbi = mfd->fbi;
- img_size = fbi->var.xres * fbi->var.yres * fbi->var.bits_per_pixel / 8;
+ if (IS_ERR_OR_NULL(ihdl)) {
+ struct fb_info *fbi;
+ size_t img_size;
+ struct ion_client *iclient = mdss_get_ionclient();
+ struct mdss_mdp_img_data *img = mdss_wb_buffer.p;
- if (ihdl == NULL) {
- ihdl = ion_alloc(mfd->iclient, img_size, SZ_4K,
+ fbi = mfd->fbi;
+ img_size = fbi->var.xres * fbi->var.yres *
+ fbi->var.bits_per_pixel / 8;
+
+ ihdl = ion_alloc(iclient, img_size, SZ_4K,
ION_HEAP(ION_SF_HEAP_ID));
- if (!IS_ERR_OR_NULL(ihdl)) {
- videomemory = ion_map_kernel(mfd->iclient, ihdl, 0);
- ion_phys(mfd->iclient, ihdl, &mdss_wb_mem, &img_size);
- } else {
+ if (IS_ERR_OR_NULL(ihdl)) {
pr_err("unable to alloc fbmem from ion (%p)\n", ihdl);
- ihdl = NULL;
+ return NULL;
}
+
+ videomemory = ion_map_kernel(iclient, ihdl, 0);
+ ion_phys(iclient, ihdl, &mdss_wb_mem, &img_size);
+
+ img->addr = mdss_wb_mem;
+ img->len = img_size;
+ pr_debug("ihdl=%p virt=%p phys=0x%lx iova=0x%x size=%u\n",
+ ihdl, videomemory, mdss_wb_mem, img->addr, img_size);
}
-
- if (mdss_wb_mem) {
- buffer.p[0].addr = (u32) mdss_wb_mem;
- buffer.p[0].len = img_size;
-
- return &buffer;
- }
-
- return NULL;
+ return &mdss_wb_buffer;
}
#else
static inline
@@ -266,7 +267,7 @@
node->buf_data.num_planes = 1;
buf = &node->buf_data.p[0];
- ret = mdss_mdp_get_img(mfd->iclient, data, buf);
+ ret = mdss_mdp_get_img(data, buf);
if (IS_ERR_VALUE(ret)) {
pr_err("error getting buffer info\n");
goto register_fail;
@@ -394,6 +395,9 @@
if (!ctl || !ctl->mfd)
return -ENODEV;
+ if (!ctl->power_on)
+ return 0;
+
mutex_lock(&mdss_mdp_wb_buf_lock);
wb = ctl->mfd->wb;
if (wb) {
diff --git a/drivers/video/msm/mhl/mhl_8334.c b/drivers/video/msm/mhl/mhl_8334.c
index be160c4..f3b8cd1 100644
--- a/drivers/video/msm/mhl/mhl_8334.c
+++ b/drivers/video/msm/mhl/mhl_8334.c
@@ -531,40 +531,62 @@
static int mhl_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
- int ret = -ENODEV;
+ int ret;
+ struct msm_mhl_platform_data *tmp = client->dev.platform_data;
+ if (!tmp->mhl_enabled) {
+ ret = -ENODEV;
+ pr_warn("MHL feautre left disabled\n");
+ goto probe_early_exit;
+ }
mhl_msm_state->mhl_data = kzalloc(sizeof(struct msm_mhl_platform_data),
GFP_KERNEL);
if (!(mhl_msm_state->mhl_data)) {
ret = -ENOMEM;
pr_err("MHL I2C Probe failed - no mem\n");
- goto probe_exit;
+ goto probe_early_exit;
}
mhl_msm_state->i2c_client = client;
-
spin_lock_init(&mhl_state_lock);
-
i2c_set_clientdata(client, mhl_msm_state);
mhl_msm_state->mhl_data = client->dev.platform_data;
pr_debug("MHL: mhl_msm_state->mhl_data->irq=[%d]\n",
mhl_msm_state->mhl_data->irq);
msc_send_workqueue = create_workqueue("mhl_msc_cmd_queue");
- if (!mhl_msm_state->mhl_data->mhl_enabled) {
- pr_info("MHL Display not enabled\n");
- return -ENODEV;
- }
-
+ mhl_msm_state->cur_state = POWER_STATE_D0_MHL;
/* Init GPIO stuff here */
ret = mhl_sii_gpio_setup(1);
- if (ret == -1) {
+ if (ret) {
pr_err("MHL: mhl_gpio_init has failed\n");
ret = -ENODEV;
+ goto probe_early_exit;
+ }
+ mhl_sii_power_on();
+ /* MHL SII 8334 chip specific init */
+ mhl_chip_init();
+ init_completion(&mhl_msm_state->rgnd_done);
+ /* Request IRQ stuff here */
+ pr_debug("MHL: mhl_msm_state->mhl_data->irq=[%d]\n",
+ mhl_msm_state->mhl_data->irq);
+ ret = request_threaded_irq(mhl_msm_state->mhl_data->irq, NULL,
+ &mhl_tx_isr,
+ IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+ "mhl_tx_isr", mhl_msm_state);
+ if (ret) {
+ pr_err("request_threaded_irq failed, status: %d\n",
+ ret);
goto probe_exit;
+ } else {
+ pr_debug("request_threaded_irq succeeded\n");
}
- mhl_sii_power_on();
+ INIT_WORK(&mhl_msm_state->mhl_msc_send_work, mhl_msc_send_work);
+ INIT_LIST_HEAD(&mhl_msm_state->list_cmd);
+ mhl_msm_state->msc_command_put_work = list_cmd_put;
+ mhl_msm_state->msc_command_get_work = list_cmd_get;
+ init_completion(&mhl_msm_state->msc_cmd_done);
- pr_debug("I2C PROBE successful\n");
+ pr_debug("i2c probe successful\n");
return 0;
probe_exit:
@@ -574,6 +596,7 @@
kfree(mhl_msm_state->mhl_data);
mhl_msm_state->mhl_data = NULL;
}
+probe_early_exit:
return ret;
}
@@ -636,7 +659,6 @@
ret = -ENOMEM;
goto init_exit;
}
-
mhl_msm_state->i2c_client = NULL;
ret = i2c_add_driver(&mhl_sii_i2c_driver);
if (ret) {
@@ -645,6 +667,7 @@
goto init_exit;
} else {
if (mhl_msm_state->i2c_client == NULL) {
+ i2c_del_driver(&mhl_sii_i2c_driver);
pr_err("MHL: I2C driver add failed\n");
ret = -ENODEV;
goto init_exit;
@@ -652,36 +675,9 @@
pr_info("MHL: I2C driver added\n");
}
- /* Request IRQ stuff here */
- pr_debug("MHL: mhl_msm_state->mhl_data->irq=[%d]\n",
- mhl_msm_state->mhl_data->irq);
- ret = request_threaded_irq(mhl_msm_state->mhl_data->irq, NULL,
- &mhl_tx_isr,
- IRQF_TRIGGER_LOW | IRQF_ONESHOT,
- "mhl_tx_isr", mhl_msm_state);
- if (ret != 0) {
- pr_err("request_threaded_irq failed, status: %d\n",
- ret);
- ret = -EACCES; /* Error code???? */
- goto init_exit;
- } else
- pr_debug("request_threaded_irq succeeded\n");
-
- INIT_WORK(&mhl_msm_state->mhl_msc_send_work, mhl_msc_send_work);
- mhl_msm_state->cur_state = POWER_STATE_D0_MHL;
- INIT_LIST_HEAD(&mhl_msm_state->list_cmd);
- mhl_msm_state->msc_command_put_work = list_cmd_put;
- mhl_msm_state->msc_command_get_work = list_cmd_get;
- init_completion(&mhl_msm_state->msc_cmd_done);
-
- /* MHL SII 8334 chip specific init */
- mhl_chip_init();
- init_completion(&mhl_msm_state->rgnd_done);
return 0;
-
init_exit:
pr_err("Exiting from the init with err\n");
- i2c_del_driver(&mhl_sii_i2c_driver);
if (!mhl_msm_state) {
kfree(mhl_msm_state);
mhl_msm_state = NULL;
@@ -846,9 +842,6 @@
if (0x02 == rgnd_imp) {
pr_debug("MHL: MHL DEVICE!!!\n");
mhl_i2c_reg_modify(TX_PAGE_3, 0x0018, BIT0, BIT0);
- /*
- * Handling the MHL event in driver
- */
mhl_msm_state->mhl_mode = TRUE;
if (notify_usb_online)
notify_usb_online(1);
@@ -985,8 +978,7 @@
uint8_t intr_5_stat;
/*
- * Clear INT 5 ??
- * Probably need to revisit this later
+ * Clear INT 5
* INTR5 is related to FIFO underflow/overflow reset
* which is handled in 8334 by auto FIFO reset
*/
@@ -1464,6 +1456,7 @@
}
+/* MSC, RCP, RAP messages - mandatory for compliance */
static void mhl_cbus_isr(void)
{
uint8_t regval;
@@ -1477,7 +1470,10 @@
if (regval == 0xff)
return;
- /* clear all interrupts that were raised even if we did not process */
+ /*
+ * clear all interrupts that were raised
+ * even if we did not process
+ */
if (regval)
mhl_i2c_reg_write(TX_PAGE_CBUS, 0x08, regval);
diff --git a/drivers/video/msm/mipi_dsi.c b/drivers/video/msm/mipi_dsi.c
index e6e8aca..7d534ed 100644
--- a/drivers/video/msm/mipi_dsi.c
+++ b/drivers/video/msm/mipi_dsi.c
@@ -79,6 +79,14 @@
mdp4_overlay_dsi_state_set(ST_DSI_SUSPEND);
+ /* make sure dsi clk is on so that
+ * dcs commands can be sent
+ */
+ mipi_dsi_clk_cfg(1);
+
+ /* make sure dsi_cmd_mdp is idle */
+ mipi_dsi_cmd_mdp_busy();
+
/*
* Desctiption: change to DSI_CMD_MODE since it needed to
* tx DCS dsiplay off comamnd to panel
diff --git a/drivers/video/msm/mipi_dsi.h b/drivers/video/msm/mipi_dsi.h
index 2f691cf..a7832ed 100644
--- a/drivers/video/msm/mipi_dsi.h
+++ b/drivers/video/msm/mipi_dsi.h
@@ -344,6 +344,7 @@
int mipi_dsi_cmdlist_put(struct dcs_cmd_req *cmdreq);
struct dcs_cmd_req *mipi_dsi_cmdlist_get(void);
void mipi_dsi_cmdlist_commit(int from_mdp);
+void mipi_dsi_cmd_mdp_busy(void);
#ifdef CONFIG_FB_MSM_MDP303
void update_lane_config(struct msm_panel_info *pinfo);
diff --git a/drivers/video/msm/mipi_dsi_host.c b/drivers/video/msm/mipi_dsi_host.c
index 39a071b..d7992a7 100644
--- a/drivers/video/msm/mipi_dsi_host.c
+++ b/drivers/video/msm/mipi_dsi_host.c
@@ -1604,10 +1604,12 @@
mipi_dsi_cmd_mdp_busy();
}
- if (req->flags && CMD_REQ_RX)
+ mipi_dsi_clk_cfg(1);
+ if (req->flags & CMD_REQ_RX)
mipi_dsi_cmdlist_rx(req);
else
mipi_dsi_cmdlist_tx(req);
+ mipi_dsi_clk_cfg(0);
mutex_unlock(&cmd_mutex);
}
diff --git a/drivers/video/msm/vidc/common/dec/vdec.c b/drivers/video/msm/vidc/common/dec/vdec.c
index f68265a..68bcd5c 100644
--- a/drivers/video/msm/vidc/common/dec/vdec.c
+++ b/drivers/video/msm/vidc/common/dec/vdec.c
@@ -2079,10 +2079,6 @@
mutex_unlock(&client_ctx->msg_queue_lock);
vcd_status = vcd_close(client_ctx->vcd_handle);
- if (vcd_status) {
- mutex_unlock(&vid_dec_device_p->lock);
- return false;
- }
client_ctx->user_ion_client = NULL;
memset((void *)client_ctx, 0, sizeof(struct video_client_ctx));
vid_dec_device_p->num_clients--;
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_device_sm.c b/drivers/video/msm/vidc/common/vcd/vcd_device_sm.c
index 53495e0..1281127 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_device_sm.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_device_sm.c
@@ -858,7 +858,7 @@
} else {
VCD_MSG_ERROR("Unsupported API in client state %d",
cctxt->clnt_state.state);
-
+ vcd_destroy_client_context(cctxt);
rc = VCD_ERR_BAD_STATE;
}
diff --git a/include/linux/msm_mdp.h b/include/linux/msm_mdp.h
index e7cbb79..f6229b5 100644
--- a/include/linux/msm_mdp.h
+++ b/include/linux/msm_mdp.h
@@ -354,12 +354,15 @@
/*
- mdp_block_type defines the identifiers for each of pipes in MDP 4.3
+ mdp_block_type defines the identifiers for pipes in MDP 4.3 and up
MDP_BLOCK_RESERVED is provided for backward compatibility and is
deprecated. It corresponds to DMA_P. So MDP_BLOCK_DMA_P should be used
instead.
+ MDP_LOGICAL_BLOCK_DISP_0 identifies the display pipe which fb0 uses,
+ same for others.
+
*/
enum {
@@ -374,6 +377,9 @@
MDP_BLOCK_DMA_S,
MDP_BLOCK_DMA_E,
MDP_BLOCK_OVERLAY_2,
+ MDP_LOGICAL_BLOCK_DISP_0 = 0x1000,
+ MDP_LOGICAL_BLOCK_DISP_1,
+ MDP_LOGICAL_BLOCK_DISP_2,
MDP_BLOCK_MAX,
};
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 78b5b84..7b5aa0b 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -2074,6 +2074,7 @@
#define V4L2_ENC_CMD_STOP (1)
#define V4L2_ENC_CMD_PAUSE (2)
#define V4L2_ENC_CMD_RESUME (3)
+#define V4L2_ENC_QCOM_CMD_FLUSH (4)
/* Flags for V4L2_ENC_CMD_STOP */
#define V4L2_ENC_CMD_STOP_AT_GOP_END (1 << 0)
@@ -2111,6 +2112,9 @@
#define V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT (1 << 0)
#define V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE (1 << 1)
+#define V4L2_QCOM_CMD_FLUSH_OUTPUT (1 << 0)
+#define V4L2_QCOM_CMD_FLUSH_CAPTURE (1 << 1)
+
/* Play format requirements (returned by the driver): */
/* The decoder has no special format requirements */
diff --git a/sound/soc/msm/mdm9615.c b/sound/soc/msm/mdm9615.c
index b80a0a9..05786a7 100644
--- a/sound/soc/msm/mdm9615.c
+++ b/sound/soc/msm/mdm9615.c
@@ -17,6 +17,7 @@
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/io.h>
+#include <linux/mfd/wcd9xxx/core.h>
#include <sound/core.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
@@ -42,10 +43,8 @@
#define SAMPLE_RATE_8KHZ 8000
#define SAMPLE_RATE_16KHZ 16000
-#define BOTTOM_SPK_AMP_POS 0x1
-#define BOTTOM_SPK_AMP_NEG 0x2
-#define TOP_SPK_AMP_POS 0x4
-#define TOP_SPK_AMP_NEG 0x8
+#define TOP_AND_BOTTOM_SPK_AMP_POS 0x1
+#define TOP_AND_BOTTOM_SPK_AMP_NEG 0x2
#define GPIO_AUX_PCM_DOUT 23
#define GPIO_AUX_PCM_DIN 22
@@ -62,6 +61,10 @@
#define TABLA_MBHC_DEF_BUTTONS 8
#define TABLA_MBHC_DEF_RLOADS 5
+#define PM8018_IRQ_BASE (NR_MSM_IRQS + NR_GPIO_IRQS)
+#define JACK_DETECT_GPIO 3
+#define JACK_DETECT_INT PM8018_GPIO_IRQ(PM8018_IRQ_BASE, JACK_DETECT_GPIO)
+
/*
* Added for I2S
*/
@@ -245,16 +248,13 @@
/*
* Added for I2S
*/
-
-static u32 top_spk_pamp_gpio = PM8018_GPIO_PM_TO_SYS(3);
-static u32 bottom_spk_pamp_gpio = PM8018_GPIO_PM_TO_SYS(5);
+static u32 top_and_bottom_spk_pamp_gpio = PM8018_GPIO_PM_TO_SYS(5);
void *sif_virt_addr;
void *secpcm_portslc_virt_addr;
static int mdm9615_spk_control;
-static int mdm9615_ext_bottom_spk_pamp;
-static int mdm9615_ext_top_spk_pamp;
+static int mdm9615_ext_top_and_bottom_spk_pamp;
static int mdm9615_slim_0_rx_ch = 1;
static int mdm9615_slim_0_tx_ch = 1;
@@ -271,6 +271,14 @@
static struct snd_soc_jack hs_jack;
static struct snd_soc_jack button_jack;
+static bool hs_detect_use_gpio;
+module_param(hs_detect_use_gpio, bool, 0444);
+MODULE_PARM_DESC(hs_detect_use_gpio, "Use GPIO for headset detection");
+
+static bool hs_detect_use_firmware;
+module_param(hs_detect_use_firmware, bool, 0444);
+MODULE_PARM_DESC(hs_detect_use_firmware, "Use firmware for headset detection");
+
static int mdm9615_enable_codec_ext_clk(struct snd_soc_codec *codec, int enable,
bool dapm);
static struct tabla_mbhc_config mbhc_cfg = {
@@ -300,39 +308,26 @@
.function = PM_GPIO_FUNC_NORMAL,
};
- if (spk_amp_gpio == bottom_spk_pamp_gpio) {
+ if (spk_amp_gpio == top_and_bottom_spk_pamp_gpio) {
- ret = gpio_request(bottom_spk_pamp_gpio, "BOTTOM_SPK_AMP");
+ ret = gpio_request(top_and_bottom_spk_pamp_gpio,
+ "TOP_AND_BOTTOM_SPK_AMP");
if (ret) {
- pr_err("%s: Error requesting BOTTOM SPK AMP GPIO %u\n",
- __func__, bottom_spk_pamp_gpio);
+ pr_err("%s: Error requesting TOP AND BOTTOM SPK AMP GPIO %u\n",
+ __func__, top_and_bottom_spk_pamp_gpio);
return;
}
- ret = pm8xxx_gpio_config(bottom_spk_pamp_gpio, ¶m);
+ ret = pm8xxx_gpio_config(top_and_bottom_spk_pamp_gpio, ¶m);
if (ret)
- pr_err("%s: Failed to configure Bottom Spk Ampl"
- " gpio %u\n", __func__, bottom_spk_pamp_gpio);
+ pr_err("%s: Failed to configure Top & Bottom Spk Ampl\n"
+ "gpio %u\n", __func__,
+ top_and_bottom_spk_pamp_gpio);
else {
- pr_debug("%s: enable Bottom spkr amp gpio\n", __func__);
- gpio_direction_output(bottom_spk_pamp_gpio, 1);
+ pr_debug("%s: enable Top & Bottom spkr amp gpio\n",
+ __func__);
+ gpio_direction_output(top_and_bottom_spk_pamp_gpio, 1);
}
- } else if (spk_amp_gpio == top_spk_pamp_gpio) {
-
- ret = gpio_request(top_spk_pamp_gpio, "TOP_SPK_AMP");
- if (ret) {
- pr_err("%s: Error requesting GPIO %d\n", __func__,
- top_spk_pamp_gpio);
- return;
- }
- ret = pm8xxx_gpio_config(top_spk_pamp_gpio, ¶m);
- if (ret)
- pr_err("%s: Failed to configure Top Spk Ampl"
- " gpio %u\n", __func__, top_spk_pamp_gpio);
- else {
- pr_debug("%s: enable Top spkr amp gpio\n", __func__);
- gpio_direction_output(top_spk_pamp_gpio, 1);
- }
} else {
pr_err("%s: ERROR : Invalid External Speaker Ampl GPIO."
" gpio = %u\n", __func__, spk_amp_gpio);
@@ -342,49 +337,30 @@
static void mdm9615_ext_spk_power_amp_on(u32 spk)
{
- if (spk & (BOTTOM_SPK_AMP_POS | BOTTOM_SPK_AMP_NEG)) {
-
- if ((mdm9615_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_POS) &&
- (mdm9615_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_NEG)) {
-
- pr_debug("%s() External Bottom Speaker Ampl already "
+ if (spk & (TOP_AND_BOTTOM_SPK_AMP_POS | TOP_AND_BOTTOM_SPK_AMP_NEG)) {
+ if ((mdm9615_ext_top_and_bottom_spk_pamp &
+ TOP_AND_BOTTOM_SPK_AMP_POS) &&
+ (mdm9615_ext_top_and_bottom_spk_pamp &
+ TOP_AND_BOTTOM_SPK_AMP_NEG)) {
+ pr_debug("%s() External Speaker Ampl already "
"turned on. spk = 0x%08x\n", __func__, spk);
return;
}
- mdm9615_ext_bottom_spk_pamp |= spk;
+ mdm9615_ext_top_and_bottom_spk_pamp |= spk;
- if ((mdm9615_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_POS) &&
- (mdm9615_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_NEG)) {
-
- mdm9615_enable_ext_spk_amp_gpio(bottom_spk_pamp_gpio);
- pr_debug("%s: slepping 4 ms after turning on external "
- " Bottom Speaker Ampl\n", __func__);
+ if ((mdm9615_ext_top_and_bottom_spk_pamp &
+ TOP_AND_BOTTOM_SPK_AMP_POS) &&
+ (mdm9615_ext_top_and_bottom_spk_pamp &
+ TOP_AND_BOTTOM_SPK_AMP_NEG)) {
+ mdm9615_enable_ext_spk_amp_gpio(
+ top_and_bottom_spk_pamp_gpio);
+ pr_debug("%s: slepping 4 ms after turning on external\n"
+ "Speaker Ampl\n", __func__);
usleep_range(4000, 4000);
}
- } else if (spk & (TOP_SPK_AMP_POS | TOP_SPK_AMP_NEG)) {
-
- if ((mdm9615_ext_top_spk_pamp & TOP_SPK_AMP_POS) &&
- (mdm9615_ext_top_spk_pamp & TOP_SPK_AMP_NEG)) {
-
- pr_debug("%s() External Top Speaker Ampl already"
- "turned on. spk = 0x%08x\n", __func__, spk);
- return;
- }
-
- mdm9615_ext_top_spk_pamp |= spk;
-
- if ((mdm9615_ext_top_spk_pamp & TOP_SPK_AMP_POS) &&
- (mdm9615_ext_top_spk_pamp & TOP_SPK_AMP_NEG)) {
-
- mdm9615_enable_ext_spk_amp_gpio(top_spk_pamp_gpio);
- pr_debug("%s: sleeping 4 ms after turning on "
- " external Top Speaker Ampl\n", __func__);
- usleep_range(4000, 4000);
- }
- } else {
-
+ } else {
pr_err("%s: ERROR : Invalid External Speaker Ampl. spk = 0x%08x\n",
__func__, spk);
return;
@@ -393,33 +369,20 @@
static void mdm9615_ext_spk_power_amp_off(u32 spk)
{
- if (spk & (BOTTOM_SPK_AMP_POS | BOTTOM_SPK_AMP_NEG)) {
+ if (spk & (TOP_AND_BOTTOM_SPK_AMP_POS | TOP_AND_BOTTOM_SPK_AMP_NEG)) {
- if (!mdm9615_ext_bottom_spk_pamp)
+ if (!mdm9615_ext_top_and_bottom_spk_pamp)
return;
- gpio_direction_output(bottom_spk_pamp_gpio, 0);
- gpio_free(bottom_spk_pamp_gpio);
- mdm9615_ext_bottom_spk_pamp = 0;
+ gpio_direction_output(top_and_bottom_spk_pamp_gpio, 0);
+ gpio_free(top_and_bottom_spk_pamp_gpio);
+ mdm9615_ext_top_and_bottom_spk_pamp = 0;
pr_debug("%s: sleeping 4 ms after turning off external Bottom"
" Speaker Ampl\n", __func__);
usleep_range(4000, 4000);
- } else if (spk & (TOP_SPK_AMP_POS | TOP_SPK_AMP_NEG)) {
-
- if (!mdm9615_ext_top_spk_pamp)
- return;
-
- gpio_direction_output(top_spk_pamp_gpio, 0);
- gpio_free(top_spk_pamp_gpio);
- mdm9615_ext_top_spk_pamp = 0;
-
- pr_debug("%s: sleeping 4 ms after turning off external Top"
- " Spkaker Ampl\n", __func__);
-
- usleep_range(4000, 4000);
} else {
pr_err("%s: ERROR : Invalid Ext Spk Ampl. spk = 0x%08x\n",
@@ -434,15 +397,11 @@
pr_debug("%s: mdm9615_spk_control = %d", __func__, mdm9615_spk_control);
if (mdm9615_spk_control == MDM9615_SPK_ON) {
- snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Pos");
- snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Neg");
- snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Pos");
- snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Neg");
+ snd_soc_dapm_enable_pin(dapm, "Ext Spk Pos");
+ snd_soc_dapm_enable_pin(dapm, "Ext Spk Neg");
} else {
- snd_soc_dapm_disable_pin(dapm, "Ext Spk Bottom Pos");
- snd_soc_dapm_disable_pin(dapm, "Ext Spk Bottom Neg");
- snd_soc_dapm_disable_pin(dapm, "Ext Spk Top Pos");
- snd_soc_dapm_disable_pin(dapm, "Ext Spk Top Neg");
+ snd_soc_dapm_disable_pin(dapm, "Ext Spk Pos");
+ snd_soc_dapm_disable_pin(dapm, "Ext Spk Neg");
}
snd_soc_dapm_sync(dapm);
@@ -474,14 +433,12 @@
pr_debug("%s() %x\n", __func__, SND_SOC_DAPM_EVENT_ON(event));
if (SND_SOC_DAPM_EVENT_ON(event)) {
- if (!strncmp(w->name, "Ext Spk Bottom Pos", 18))
- mdm9615_ext_spk_power_amp_on(BOTTOM_SPK_AMP_POS);
- else if (!strncmp(w->name, "Ext Spk Bottom Neg", 18))
- mdm9615_ext_spk_power_amp_on(BOTTOM_SPK_AMP_NEG);
- else if (!strncmp(w->name, "Ext Spk Top Pos", 15))
- mdm9615_ext_spk_power_amp_on(TOP_SPK_AMP_POS);
- else if (!strncmp(w->name, "Ext Spk Top Neg", 15))
- mdm9615_ext_spk_power_amp_on(TOP_SPK_AMP_NEG);
+ if (!strncmp(w->name, "Ext Spk Pos", 11))
+ mdm9615_ext_spk_power_amp_on(
+ TOP_AND_BOTTOM_SPK_AMP_POS);
+ else if (!strncmp(w->name, "Ext Spk Neg", 11))
+ mdm9615_ext_spk_power_amp_on(
+ TOP_AND_BOTTOM_SPK_AMP_NEG);
else {
pr_err("%s() Invalid Speaker Widget = %s\n",
__func__, w->name);
@@ -489,14 +446,12 @@
}
} else {
- if (!strncmp(w->name, "Ext Spk Bottom Pos", 18))
- mdm9615_ext_spk_power_amp_off(BOTTOM_SPK_AMP_POS);
- else if (!strncmp(w->name, "Ext Spk Bottom Neg", 18))
- mdm9615_ext_spk_power_amp_off(BOTTOM_SPK_AMP_NEG);
- else if (!strncmp(w->name, "Ext Spk Top Pos", 15))
- mdm9615_ext_spk_power_amp_off(TOP_SPK_AMP_POS);
- else if (!strncmp(w->name, "Ext Spk Top Neg", 15))
- mdm9615_ext_spk_power_amp_off(TOP_SPK_AMP_NEG);
+ if (!strncmp(w->name, "Ext Spk Pos", 11))
+ mdm9615_ext_spk_power_amp_off(
+ TOP_AND_BOTTOM_SPK_AMP_POS);
+ else if (!strncmp(w->name, "Ext Spk Neg", 11))
+ mdm9615_ext_spk_power_amp_off(
+ TOP_AND_BOTTOM_SPK_AMP_NEG);
else {
pr_err("%s() Invalid Speaker Widget = %s\n",
__func__, w->name);
@@ -557,11 +512,8 @@
SND_SOC_DAPM_SUPPLY("MCLK", SND_SOC_NOPM, 0, 0,
mdm9615_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_SPK("Ext Spk Bottom Pos", mdm9615_spkramp_event),
- SND_SOC_DAPM_SPK("Ext Spk Bottom Neg", mdm9615_spkramp_event),
-
- SND_SOC_DAPM_SPK("Ext Spk Top Pos", mdm9615_spkramp_event),
- SND_SOC_DAPM_SPK("Ext Spk Top Neg", mdm9615_spkramp_event),
+ SND_SOC_DAPM_SPK("Ext Spk Pos", mdm9615_spkramp_event),
+ SND_SOC_DAPM_SPK("Ext Spk Neg", mdm9615_spkramp_event),
SND_SOC_DAPM_MIC("Handset Mic", NULL),
SND_SOC_DAPM_MIC("Headset Mic", NULL),
@@ -584,11 +536,11 @@
{"LDO_H", NULL, "MCLK"},
/* Speaker path */
- {"Ext Spk Bottom Pos", NULL, "LINEOUT1"},
- {"Ext Spk Bottom Neg", NULL, "LINEOUT3"},
+ {"Ext Spk Pos", NULL, "LINEOUT1"},
+ {"Ext Spk Neg", NULL, "LINEOUT3"},
- {"Ext Spk Top Pos", NULL, "LINEOUT2"},
- {"Ext Spk Top Neg", NULL, "LINEOUT4"},
+ {"Ext Spk Pos", NULL, "LINEOUT2"},
+ {"Ext Spk Neg", NULL, "LINEOUT4"},
/* Microphone path */
{"AMIC1", NULL, "MIC BIAS1 External"},
@@ -1006,10 +958,8 @@
snd_soc_dapm_add_routes(dapm, common_audio_map,
ARRAY_SIZE(common_audio_map));
- snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Pos");
- snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Neg");
- snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Pos");
- snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Neg");
+ snd_soc_dapm_enable_pin(dapm, "Ext Spk Pos");
+ snd_soc_dapm_enable_pin(dapm, "Ext Spk Neg");
snd_soc_dapm_sync(dapm);
@@ -1510,6 +1460,13 @@
struct snd_soc_codec *codec = rtd->codec;
struct snd_soc_dapm_context *dapm = &codec->dapm;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct pm_gpio jack_gpio_cfg = {
+ .direction = PM_GPIO_DIR_IN,
+ .pull = PM_GPIO_PULL_NO,
+ .function = PM_GPIO_FUNC_NORMAL,
+ .vin_sel = 2,
+ .inv_int_pol = 0,
+ };
pr_debug("%s(), dev_name%s\n", __func__, dev_name(cpu_dai->dev));
@@ -1521,10 +1478,8 @@
snd_soc_dapm_add_routes(dapm, common_audio_map,
ARRAY_SIZE(common_audio_map));
- snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Pos");
- snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Neg");
- snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Pos");
- snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Neg");
+ snd_soc_dapm_enable_pin(dapm, "Ext Spk Pos");
+ snd_soc_dapm_enable_pin(dapm, "Ext Spk Neg");
snd_soc_dapm_sync(dapm);
@@ -1545,6 +1500,22 @@
}
codec_clk = clk_get(cpu_dai->dev, "osr_clk");
+ if (hs_detect_use_gpio) {
+ mbhc_cfg.gpio = PM8018_GPIO_PM_TO_SYS(JACK_DETECT_GPIO);
+ mbhc_cfg.gpio_irq = JACK_DETECT_INT;
+ }
+
+ if (mbhc_cfg.gpio) {
+ err = pm8xxx_gpio_config(mbhc_cfg.gpio, &jack_gpio_cfg);
+ if (err) {
+ pr_err("%s: pm8xxx_gpio_config JACK_DETECT failed %d\n",
+ __func__, err);
+ return err;
+ }
+ }
+
+ mbhc_cfg.read_fw_bin = hs_detect_use_firmware;
+
err = tabla_hs_detect(codec, &mbhc_cfg);
return err;
diff --git a/sound/soc/msm/msm-dai-fe.c b/sound/soc/msm/msm-dai-fe.c
index 011912e..16a4aaa 100644
--- a/sound/soc/msm/msm-dai-fe.c
+++ b/sound/soc/msm/msm-dai-fe.c
@@ -199,7 +199,7 @@
SNDRV_PCM_RATE_KNOT),
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.channels_min = 1,
- .channels_max = 6,
+ .channels_max = 8,
.rate_min = 8000,
.rate_max = 48000,
},
@@ -225,7 +225,7 @@
SNDRV_PCM_RATE_KNOT),
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.channels_min = 1,
- .channels_max = 6,
+ .channels_max = 8,
.rate_min = 8000,
.rate_max = 48000,
},
@@ -240,7 +240,7 @@
SNDRV_PCM_RATE_KNOT),
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.channels_min = 1,
- .channels_max = 6,
+ .channels_max = 8,
.rate_min = 8000,
.rate_max = 48000,
},
@@ -255,7 +255,7 @@
SNDRV_PCM_RATE_KNOT),
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.channels_min = 1,
- .channels_max = 6,
+ .channels_max = 8,
.rate_min = 8000,
.rate_max = 48000,
},
diff --git a/sound/soc/msm/msm-multi-ch-pcm-q6.c b/sound/soc/msm/msm-multi-ch-pcm-q6.c
index a33a01f..5b0759c 100644
--- a/sound/soc/msm/msm-multi-ch-pcm-q6.c
+++ b/sound/soc/msm/msm-multi-ch-pcm-q6.c
@@ -47,11 +47,11 @@
static struct snd_msm_volume multi_ch_pcm_audio = {NULL, 0x2000};
#define PLAYBACK_NUM_PERIODS 8
-#define PLAYBACK_MAX_PERIOD_SIZE 4032
+#define PLAYBACK_MAX_PERIOD_SIZE 12288
#define PLAYBACK_MIN_PERIOD_SIZE 256
#define CAPTURE_NUM_PERIODS 16
#define CAPTURE_MIN_PERIOD_SIZE 320
-#define CAPTURE_MAX_PERIOD_SIZE 5376
+#define CAPTURE_MAX_PERIOD_SIZE 12288
static struct snd_pcm_hardware msm_pcm_hardware_capture = {
.info = (SNDRV_PCM_INFO_MMAP |
@@ -303,8 +303,8 @@
pr_debug("Samp_rate = %d\n", prtd->samp_rate);
pr_debug("Channel = %d\n", prtd->channel_mode);
- ret = q6asm_enc_cfg_blk_pcm(prtd->audio_client, prtd->samp_rate,
- prtd->channel_mode);
+ ret = q6asm_enc_cfg_blk_multi_ch_pcm(prtd->audio_client,
+ prtd->samp_rate, prtd->channel_mode);
if (ret < 0)
pr_debug("%s: cmd cfg pcm was block failed", __func__);
@@ -399,7 +399,8 @@
/* Capture path */
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
runtime->hw = msm_pcm_hardware_capture;
- ret = q6asm_open_read(prtd->audio_client, FORMAT_LINEAR_PCM);
+ ret = q6asm_open_read(prtd->audio_client,
+ FORMAT_MULTI_CHANNEL_LINEAR_PCM);
if (ret < 0) {
pr_err("%s: pcm in open failed\n", __func__);
q6asm_audio_client_free(prtd->audio_client);
diff --git a/sound/soc/msm/qdsp6/q6asm.c b/sound/soc/msm/qdsp6/q6asm.c
index 1aac158..3a226b4 100644
--- a/sound/soc/msm/qdsp6/q6asm.c
+++ b/sound/soc/msm/qdsp6/q6asm.c
@@ -1885,7 +1885,16 @@
enc_cfg.enc_blk.cfg.mpcm.sample_rate = rate;
enc_cfg.enc_blk.cfg.mpcm.is_signed = 1;
enc_cfg.enc_blk.cfg.mpcm.is_interleaved = 1;
- if (channels == 2) {
+ if (channels == 1) {
+ enc_cfg.enc_blk.cfg.mpcm.channel_mapping[0] = PCM_CHANNEL_FL;
+ enc_cfg.enc_blk.cfg.mpcm.channel_mapping[1] = 0;
+ enc_cfg.enc_blk.cfg.mpcm.channel_mapping[2] = 0;
+ enc_cfg.enc_blk.cfg.mpcm.channel_mapping[3] = 0;
+ enc_cfg.enc_blk.cfg.mpcm.channel_mapping[4] = 0;
+ enc_cfg.enc_blk.cfg.mpcm.channel_mapping[5] = 0;
+ enc_cfg.enc_blk.cfg.mpcm.channel_mapping[6] = 0;
+ enc_cfg.enc_blk.cfg.mpcm.channel_mapping[7] = 0;
+ } else if (channels == 2) {
enc_cfg.enc_blk.cfg.mpcm.channel_mapping[0] = PCM_CHANNEL_FL;
enc_cfg.enc_blk.cfg.mpcm.channel_mapping[1] = PCM_CHANNEL_FR;
enc_cfg.enc_blk.cfg.mpcm.channel_mapping[2] = 0;
@@ -2040,6 +2049,11 @@
} else if (num_channels == 2) {
channel_mapping[0] = PCM_CHANNEL_FL;
channel_mapping[1] = PCM_CHANNEL_FR;
+ } else if (num_channels == 4) {
+ channel_mapping[0] = PCM_CHANNEL_FL;
+ channel_mapping[1] = PCM_CHANNEL_FR;
+ channel_mapping[1] = PCM_CHANNEL_LB;
+ channel_mapping[1] = PCM_CHANNEL_RB;
} else if (num_channels == 6) {
channel_mapping[0] = PCM_CHANNEL_FC;
channel_mapping[1] = PCM_CHANNEL_FL;
@@ -2047,6 +2061,15 @@
channel_mapping[3] = PCM_CHANNEL_LB;
channel_mapping[4] = PCM_CHANNEL_RB;
channel_mapping[5] = PCM_CHANNEL_LFE;
+ } else if (num_channels == 8) {
+ channel_mapping[0] = PCM_CHANNEL_FC;
+ channel_mapping[1] = PCM_CHANNEL_FL;
+ channel_mapping[2] = PCM_CHANNEL_FR;
+ channel_mapping[3] = PCM_CHANNEL_LB;
+ channel_mapping[4] = PCM_CHANNEL_RB;
+ channel_mapping[5] = PCM_CHANNEL_LFE;
+ channel_mapping[6] = PCM_CHANNEL_FLC;
+ channel_mapping[7] = PCM_CHANNEL_FRC;
} else {
pr_err("%s: ERROR.unsupported num_ch = %u\n", __func__,
num_channels);
@@ -2303,6 +2326,11 @@
} else if (channels == 2) {
channel_mapping[0] = PCM_CHANNEL_FL;
channel_mapping[1] = PCM_CHANNEL_FR;
+ } else if (channels == 4) {
+ channel_mapping[0] = PCM_CHANNEL_FL;
+ channel_mapping[1] = PCM_CHANNEL_FR;
+ channel_mapping[1] = PCM_CHANNEL_LB;
+ channel_mapping[1] = PCM_CHANNEL_RB;
} else if (channels == 6) {
channel_mapping[0] = PCM_CHANNEL_FC;
channel_mapping[1] = PCM_CHANNEL_FL;
@@ -2310,6 +2338,15 @@
channel_mapping[3] = PCM_CHANNEL_LB;
channel_mapping[4] = PCM_CHANNEL_RB;
channel_mapping[5] = PCM_CHANNEL_LFE;
+ } else if (channels == 8) {
+ channel_mapping[0] = PCM_CHANNEL_FC;
+ channel_mapping[1] = PCM_CHANNEL_FL;
+ channel_mapping[2] = PCM_CHANNEL_FR;
+ channel_mapping[3] = PCM_CHANNEL_LB;
+ channel_mapping[4] = PCM_CHANNEL_RB;
+ channel_mapping[5] = PCM_CHANNEL_LFE;
+ channel_mapping[6] = PCM_CHANNEL_FLC;
+ channel_mapping[7] = PCM_CHANNEL_FRC;
} else {
pr_err("%s: ERROR.unsupported num_ch = %u\n", __func__,
channels);
diff --git a/tools/perf/util/scripting-engines/trace-event-json-export.c b/tools/perf/util/scripting-engines/trace-event-json-export.c
index 3fb6da7..2aec459 100644
--- a/tools/perf/util/scripting-engines/trace-event-json-export.c
+++ b/tools/perf/util/scripting-engines/trace-event-json-export.c
@@ -53,8 +53,8 @@
value = eval_flag(field_value);
- fprintf(ofp , ",\n[\"%s\",%d,{\"field\":\"%s\",\"value\":%llu,
- \"name\":\"%s\"}]",
+ fprintf(ofp,
+ ",\n[\"%s\",%d,{\"field\":\"%s\",\"value\":%llu,\"name\":\"%s\"}]",
handler_name, id, field_name, value, field_str);
}
@@ -77,12 +77,12 @@
{
if (field_type == PRINT_FLAGS) {
const char *handler_name = "define_flag_field";
- fprintf(ofp , ",\n[\"%s\",%d,{\"field\":\"%s\",
- \"delim\":\"%s\"}]",
- handler_name, id, field_name, delim);
+ fprintf(ofp,
+ ",\n[\"%s\",%d,{\"field\":\"%s\",\"delim\":\"%s\"}]",
+ handler_name, id, field_name, delim);
} else {
const char *handler_name = "define_symbol_field";
- fprintf(ofp , ",\n[\"%s\",%d,{\"field\":\"%s\"}]",
+ fprintf(ofp, ",\n[\"%s\",%d,{\"field\":\"%s\"}]",
handler_name, id, field_name);
}
}
@@ -140,27 +140,27 @@
const char *handler_name = "define_event";
struct format_field *field = 0;
- fprintf(ofp , ",\n[\"%s\",%d,{\"system\":\"%s\",
- \"name\":\"%s\",\"args\":{",
+ fprintf(ofp,
+ ",\n[\"%s\",%d,{\"system\":\"%s\",\"name\":\"%s\",\"args\":{",
handler_name, event->id, ev_system, ev_name);
- fprintf(ofp , "%s\"%s\":%d", prefix(indx), "common_s", indx);
+ fprintf(ofp, "%s\"%s\":%d", prefix(indx), "common_s", indx);
indx++;
- fprintf(ofp , "%s\"%s\":%d", prefix(indx), "common_ns", indx);
+ fprintf(ofp, "%s\"%s\":%d", prefix(indx), "common_ns", indx);
indx++;
- fprintf(ofp , "%s\"%s\":%d", prefix(indx), "common_cpu", indx);
+ fprintf(ofp, "%s\"%s\":%d", prefix(indx), "common_cpu", indx);
indx++;
- fprintf(ofp , "%s\"%s\":%d", prefix(indx), "common_comm", indx);
+ fprintf(ofp, "%s\"%s\":%d", prefix(indx), "common_comm", indx);
indx++;
for (field = event->format.common_fields; field; field = field->next) {
- fprintf(ofp , "%s\"%s\":%d", prefix(indx), field->name, indx);
+ fprintf(ofp, "%s\"%s\":%d", prefix(indx), field->name, indx);
indx++;
}
for (field = event->format.fields; field; field = field->next) {
- fprintf(ofp , "%s\"%s\":%d", prefix(indx), field->name, indx);
+ fprintf(ofp, "%s\"%s\":%d", prefix(indx), field->name, indx);
indx++;
}
- fprintf(ofp , "}}]");
+ fprintf(ofp, "}}]");
}
static inline struct event *find_cache_event(int type)
@@ -191,14 +191,14 @@
offset &= 0xffff;
} else
offset = field->offset;
- fprintf(ofp , "%s\"%s\"", prefix(indx), (char *)data + offset);
+ fprintf(ofp, "%s\"%s\"", prefix(indx), (char *)data + offset);
} else { /* FIELD_IS_NUMERIC */
val = read_size(data + field->offset, field->size);
if (field->flags & FIELD_IS_SIGNED)
- fprintf(ofp , "%s%lld", prefix(indx),
+ fprintf(ofp, "%s%lld", prefix(indx),
(long long int) val);
else
- fprintf(ofp , "%s%llu", prefix(indx), val);
+ fprintf(ofp, "%s%llu", prefix(indx), val);
}
}
@@ -227,7 +227,7 @@
s = nsecs / NSECS_PER_SEC;
ns = nsecs - s * NSECS_PER_SEC;
- fprintf(ofp , ",\n[\"event\",%d,[%lu,%lu,%d,\"%s\"",
+ fprintf(ofp, ",\n[\"event\",%d,[%lu,%lu,%d,\"%s\"",
type, s, ns, cpu, comm);
indx += 4;
@@ -258,7 +258,7 @@
} else
ofp = stdout;
- fprintf(ofp , "[[\"trace_start\"]");
+ fprintf(ofp, "[[\"trace_start\"]");
return err;
}
@@ -270,7 +270,7 @@
{
int err = 0;
- fprintf(ofp , ",\n[\"trace_end\"]]");
+ fprintf(ofp, ",\n[\"trace_end\"]]");
return err;
}
@@ -288,14 +288,14 @@
fprintf(stderr, "couldn't open %s\n", fname);
return -EBADF;
}
- fprintf(ofp , "[[\"generate_start\"]");
+ fprintf(ofp, "[[\"generate_start\"]");
while ((event = trace_find_next_event(event))) {
define_event(event);
define_event_symbols(event, event->print_fmt.args);
}
- fprintf(ofp , ",\n[\"generate_end\"]]");
+ fprintf(ofp, ",\n[\"generate_end\"]]");
fclose(ofp);