Merge "arm/dt: msm8974: Add charger devices"
diff --git a/arch/arm/boot/dts/dsi-panel-toshiba-720p-video.dtsi b/arch/arm/boot/dts/dsi-panel-toshiba-720p-video.dtsi
index 1f7e488..7731b33 100644
--- a/arch/arm/boot/dts/dsi-panel-toshiba-720p-video.dtsi
+++ b/arch/arm/boot/dts/dsi-panel-toshiba-720p-video.dtsi
@@ -39,17 +39,17 @@
qcom,mdss-pan-dsi-dma-tr = <0x04>;
qcom,mdss-pan-frame-rate = <60>;
qcom,panel-phy-regulatorSettings = [03 01 01 00 /* Regualotor settings */
- 20 00 01 00];
+ 20 00 01];
qcom,panel-phy-timingSettings = [69 29 1f 00 55 55
19 2a 2a 03 04 00];
qcom,panel-phy-strengthCtrl = [77 06];
- qcom,panel-phy-bistCtrl = [00 00 01 ff /* BIST Ctrl settings */
+ qcom,panel-phy-bistCtrl = [00 00 b1 ff /* BIST Ctrl settings */
00 00];
- qcom,panel-phy-laneConfig = [05 c2 00 00 00 00 00 01 75 /* lane0 config */
- 05 c2 00 00 00 00 00 01 75 /* lane1 config */
- 05 c2 00 00 00 00 00 01 75 /* lane2 config */
- 05 c2 00 00 00 00 00 01 75 /* lane3 config */
- 00 c2 00 00 00 00 00 01 97]; /* Clk ln config */
+ qcom,panel-phy-laneConfig = [00 c2 45 00 00 00 00 01 75 /* lane0 config */
+ 00 c2 45 00 00 00 00 01 75 /* lane1 config */
+ 00 c2 45 00 00 00 00 01 75 /* lane2 config */
+ 00 c2 45 00 00 00 00 01 75 /* lane3 config */
+ 00 02 45 00 00 00 00 01 97]; /* Clk ln config */
qcom,panel-on-cmds = [23 01 00 00 0a 02 b0 00
23 01 00 00 0a 02 b2 00
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index ffd4518..da0e1e5 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -60,6 +60,10 @@
<244800 133330000>;
};
+ qcom,wfd {
+ compatible = "qcom,msm-wfd";
+ };
+
serial@f991f000 {
compatible = "qcom,msm-lsuart-v14";
reg = <0xf991f000 0x1000>;
diff --git a/arch/arm/boot/dts/msm9625.dtsi b/arch/arm/boot/dts/msm9625.dtsi
index 7b7adca..8ad3b66 100644
--- a/arch/arm/boot/dts/msm9625.dtsi
+++ b/arch/arm/boot/dts/msm9625.dtsi
@@ -55,7 +55,7 @@
compatible = "qcom,msm_sps";
reg = <0xf9984000 0x15000>,
<0xf9999000 0xb000>,
- <0xfe800000 0x4800>;
+ <0xfe803000 0x4800>;
interrupts = <0 94 0>;
qcom,device-type = <2>;
};
diff --git a/arch/arm/mach-msm/bam_dmux.c b/arch/arm/mach-msm/bam_dmux.c
index 1a02fce..d5e4638 100644
--- a/arch/arm/mach-msm/bam_dmux.c
+++ b/arch/arm/mach-msm/bam_dmux.c
@@ -1809,6 +1809,10 @@
in_global_reset = 0;
vote_dfab();
if (!power_management_only_mode) {
+ sps_disconnect(bam_tx_pipe);
+ sps_disconnect(bam_rx_pipe);
+ __memzero(rx_desc_mem_buf.base, rx_desc_mem_buf.size);
+ __memzero(tx_desc_mem_buf.base, tx_desc_mem_buf.size);
i = sps_device_reset(a2_device_handle);
if (i)
pr_err("%s: device reset failed rc = %d\n", __func__,
@@ -1861,12 +1865,6 @@
/* tear down BAM connection */
INIT_COMPLETION(bam_connection_completion);
- if (!power_management_only_mode) {
- sps_disconnect(bam_tx_pipe);
- sps_disconnect(bam_rx_pipe);
- __memzero(rx_desc_mem_buf.base, rx_desc_mem_buf.size);
- __memzero(tx_desc_mem_buf.base, tx_desc_mem_buf.size);
- }
unvote_dfab();
mutex_lock(&bam_rx_pool_mutexlock);
diff --git a/arch/arm/mach-msm/clock-mdss-8974.c b/arch/arm/mach-msm/clock-mdss-8974.c
index 4d147c3..14e1185 100644
--- a/arch/arm/mach-msm/clock-mdss-8974.c
+++ b/arch/arm/mach-msm/clock-mdss-8974.c
@@ -67,7 +67,9 @@
static int pll_byte_clk_rate;
static int pll_pclk_rate;
static int pll_initialized;
+static int pll_enabled;
static struct clk *mdss_dsi_ahb_clk;
+static unsigned long dsi_pll_rate;
static void __iomem *hdmi_phy_base;
static void __iomem *hdmi_phy_pll_base;
@@ -135,6 +137,7 @@
int pll_divcfg1, pll_divcfg2;
int half_bitclk_rate;
+ pr_debug("%s:\n", __func__);
if (pll_initialized)
return 0;
@@ -193,10 +196,13 @@
REG_W(0x00, mdss_dsi_base + 0x0290); /* CAL CFG9 */
REG_W(0x20, mdss_dsi_base + 0x029c); /* EFUSE CFG */
+ dsi_pll_rate = rate;
+
pll_byte_clk_rate = 53000000;
pll_pclk_rate = 105000000;
clk_disable(mdss_dsi_ahb_clk);
+ pr_debug("%s: **** PLL initialized success\n", __func__);
pll_initialized = 1;
return 0;
@@ -206,11 +212,19 @@
{
u32 status;
u32 max_reads, timeout_us;
- static int pll_enabled;
+ int i;
if (pll_enabled)
return 0;
+ if (!pll_initialized) {
+ if (dsi_pll_rate)
+ mdss_dsi_pll_byte_set_rate(c, dsi_pll_rate);
+ else
+ pr_err("%s: Calling clk_en before set_rate\n",
+ __func__);
+ }
+
if (!mdss_dsi_ahb_clk) {
pr_err("%s: mdss_dsi_ahb_clk not initialized\n",
__func__);
@@ -218,26 +232,39 @@
}
clk_enable(mdss_dsi_ahb_clk);
- /* PLL power up */
- REG_W(0x01, mdss_dsi_base + 0x0220); /* GLB CFG */
- REG_W(0x05, mdss_dsi_base + 0x0220); /* GLB CFG */
- udelay(20);
- REG_W(0x07, mdss_dsi_base + 0x0220); /* GLB CFG */
- udelay(20);
- REG_W(0x0f, mdss_dsi_base + 0x0220); /* GLB CFG */
- /* poll for PLL ready status */
- max_reads = 20;
- timeout_us = 100;
- if (readl_poll_timeout_noirq((mdss_dsi_base + 0x02c0),
- status,
- ((status & 0x01) == 1),
- max_reads, timeout_us)) {
+ /* PLL power up */
+ for (i = 0; i < 3; i++) {
+ REG_W(0x01, mdss_dsi_base + 0x0220); /* GLB CFG */
+ REG_W(0x05, mdss_dsi_base + 0x0220); /* GLB CFG */
+ udelay(20);
+ REG_W(0x07, mdss_dsi_base + 0x0220); /* GLB CFG */
+ udelay(20);
+ REG_W(0x0f, mdss_dsi_base + 0x0220); /* GLB CFG */
+
+ /* poll for PLL ready status */
+ max_reads = 20;
+ timeout_us = 100;
+ if (readl_poll_timeout_noirq((mdss_dsi_base + 0x02c0),
+ status,
+ ((status & 0x01) == 1),
+ max_reads, timeout_us)) {
+ pr_debug("%s: DSI PLL status=%x failed to Lock\n",
+ __func__, status);
+ pr_debug("%s:Trying to power UP PLL again\n",
+ __func__);
+ } else
+ break;
+ }
+
+ if ((status & 0x01) != 1) {
pr_err("%s: DSI PLL status=%x failed to Lock\n",
__func__, status);
clk_disable(mdss_dsi_ahb_clk);
return -EINVAL;
}
+
+ pr_debug("%s: **** PLL Lock success\n", __func__);
clk_disable(mdss_dsi_ahb_clk);
pll_enabled = 1;
@@ -253,6 +280,9 @@
clk_enable(mdss_dsi_ahb_clk);
writel_relaxed(0x00, mdss_dsi_base + 0x0220); /* GLB CFG */
clk_disable(mdss_dsi_ahb_clk);
+ pr_debug("%s: **** disable pll Initialize\n", __func__);
+ pll_initialized = 0;
+ pll_enabled = 0;
}
void hdmi_pll_disable(void)
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c b/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
index a7e34d9..2e4b756 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
@@ -471,13 +471,20 @@
pr_debug("%s[%p]:\n", __func__, audio);
- mutex_lock(&audio->write_lock);
audio->eos_rsp = 0;
+ pr_debug("%s[%p]Wait for write done from DSP\n", __func__, audio);
rc = wait_event_interruptible(audio->write_wait,
(list_empty(&audio->out_queue)) ||
audio->wflush || audio->stopped);
+ if (audio->stopped || audio->wflush) {
+ pr_debug("%s[%p]: Audio Flushed or Stopped,this is not EOS\n"
+ , __func__, audio);
+ audio->wflush = 0;
+ rc = -EBUSY;
+ }
+
if (rc < 0) {
pr_err("%s[%p]: wait event for list_empty failed, rc = %d\n",
__func__, audio, rc);
@@ -485,11 +492,14 @@
}
rc = q6asm_cmd(audio->ac, CMD_EOS);
+ pr_debug("%s[%p]: EOS cmd sent to DSP\n", __func__, audio);
if (rc < 0)
pr_err("%s[%p]: q6asm_cmd failed, rc = %d",
__func__, audio, rc);
+ pr_debug("%s[%p]: wait for RENDERED_EOS from DSP\n"
+ , __func__, audio);
rc = wait_event_interruptible(audio->write_wait,
(audio->eos_rsp || audio->wflush ||
audio->stopped));
@@ -500,22 +510,18 @@
goto done;
}
- if (audio->eos_rsp == 1) {
- rc = audio_aio_enable(audio);
- if (rc)
- pr_err("%s[%p]: audio enable failed\n",
- __func__, audio);
- else {
- audio->drv_status &= ~ADRV_STATUS_PAUSE;
- audio->enabled = 1;
- }
+ if (audio->stopped || audio->wflush) {
+ audio->wflush = 0;
+ pr_debug("%s[%p]: Audio Flushed or Stopped,this is not EOS\n"
+ , __func__, audio);
+ rc = -EBUSY;
}
- if (audio->stopped || audio->wflush)
- rc = -EBUSY;
+ if (audio->eos_rsp == 1)
+ pr_debug("%s[%p]: EOS\n", __func__, audio);
+
done:
- mutex_unlock(&audio->write_lock);
mutex_lock(&audio->lock);
audio->drv_status &= ~ADRV_STATUS_FSYNC;
mutex_unlock(&audio->lock);
@@ -963,7 +969,8 @@
audio->drv_ops.out_flush(audio);
} else
audio->drv_ops.out_flush(audio);
- audio->drv_ops.in_flush(audio);
+ if (audio->feedback == NON_TUNNEL_MODE)
+ audio->drv_ops.in_flush(audio);
}
}
@@ -1167,7 +1174,11 @@
rc = -EINTR;
} else {
audio->rflush = 0;
- audio->wflush = 0;
+ if (audio->drv_status & ADRV_STATUS_FSYNC)
+ wake_up(&audio->write_wait);
+ else
+ audio->wflush = 0;
+
}
audio->eos_flag = 0;
audio->eos_rsp = 0;
diff --git a/drivers/gpu/msm/Makefile b/drivers/gpu/msm/Makefile
index c7ed329..aacd355 100644
--- a/drivers/gpu/msm/Makefile
+++ b/drivers/gpu/msm/Makefile
@@ -17,6 +17,7 @@
msm_kgsl_core-$(CONFIG_MSM_SCM) += kgsl_pwrscale_trustzone.o
msm_kgsl_core-$(CONFIG_MSM_SLEEP_STATS_DEVICE) += kgsl_pwrscale_idlestats.o
msm_kgsl_core-$(CONFIG_MSM_DCVS) += kgsl_pwrscale_msm.o
+msm_kgsl_core-$(CONFIG_SYNC) += kgsl_sync.o
msm_adreno-y += \
adreno_ringbuffer.o \
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 21227a0..5904abb 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -36,6 +36,7 @@
#include "kgsl_sharedmem.h"
#include "kgsl_device.h"
#include "kgsl_trace.h"
+#include "kgsl_sync.h"
#undef MODULE_PARAM_PREFIX
#define MODULE_PARAM_PREFIX "kgsl."
@@ -368,6 +369,12 @@
context->id = id;
context->dev_priv = dev_priv;
+ if (kgsl_sync_timeline_create(context)) {
+ idr_remove(&dev_priv->device->context_idr, id);
+ kfree(context);
+ return NULL;
+ }
+
return context;
}
@@ -412,6 +419,7 @@
{
struct kgsl_context *context = container_of(kref, struct kgsl_context,
refcount);
+ kgsl_sync_timeline_destroy(context);
kfree(context);
}
@@ -1435,42 +1443,43 @@
if (ret)
return ret;
- if (phys == 0) {
- ret = -EINVAL;
+ ret = -ERANGE;
+
+ if (phys == 0)
+ goto err;
+
+ /* Make sure the length of the region, the offset and the desired
+ * size are all page aligned or bail
+ */
+ if ((len & ~PAGE_MASK) ||
+ (offset & ~PAGE_MASK) ||
+ (size & ~PAGE_MASK)) {
+ KGSL_CORE_ERR("length offset or size is not page aligned\n");
goto err;
}
- if (offset >= len) {
- ret = -EINVAL;
+ /* The size or offset can never be greater than the PMEM length */
+ if (offset >= len || size > len)
goto err;
- }
+ /* If size is 0, then adjust it to default to the size of the region
+ * minus the offset. If size isn't zero, then make sure that it will
+ * fit inside of the region.
+ */
if (size == 0)
- size = len;
+ size = len - offset;
- /* Adjust the size of the region to account for the offset */
- size += offset & ~PAGE_MASK;
-
- size = ALIGN(size, PAGE_SIZE);
-
- if (_check_region(offset & PAGE_MASK, size, len)) {
- KGSL_CORE_ERR("Offset (%ld) + size (%d) is larger"
- "than pmem region length %ld\n",
- offset & PAGE_MASK, size, len);
- ret = -EINVAL;
+ else if (_check_region(offset, size, len))
goto err;
- }
-
entry->priv_data = filep;
entry->memdesc.pagetable = pagetable;
entry->memdesc.size = size;
- entry->memdesc.physaddr = phys + (offset & PAGE_MASK);
- entry->memdesc.hostptr = (void *) (virt + (offset & PAGE_MASK));
+ entry->memdesc.physaddr = phys + offset;
+ entry->memdesc.hostptr = (void *) (virt + offset);
- ret = memdesc_sg_phys(&entry->memdesc,
- phys + (offset & PAGE_MASK), size);
+ ret = memdesc_sg_phys(&entry->memdesc, phys + offset, size);
if (ret)
goto err;
@@ -2016,6 +2025,11 @@
param->context_id, param->timestamp, param->priv,
param->len, dev_priv);
break;
+ case KGSL_TIMESTAMP_EVENT_FENCE:
+ ret = kgsl_add_fence_event(dev_priv->device,
+ param->context_id, param->timestamp, param->priv,
+ param->len, dev_priv);
+ break;
default:
ret = -EINVAL;
}
@@ -2092,6 +2106,8 @@
cmd = IOCTL_KGSL_CMDSTREAM_FREEMEMONTIMESTAMP;
else if (cmd == IOCTL_KGSL_CMDSTREAM_READTIMESTAMP_OLD)
cmd = IOCTL_KGSL_CMDSTREAM_READTIMESTAMP;
+ else if (cmd == IOCTL_KGSL_TIMESTAMP_EVENT_OLD)
+ cmd = IOCTL_KGSL_TIMESTAMP_EVENT;
nr = _IOC_NR(cmd);
diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h
index 2a2e916..2ca3a4f 100644
--- a/drivers/gpu/msm/kgsl_device.h
+++ b/drivers/gpu/msm/kgsl_device.h
@@ -22,6 +22,7 @@
#include "kgsl_pwrctrl.h"
#include "kgsl_log.h"
#include "kgsl_pwrscale.h"
+#include <linux/sync.h>
#define KGSL_TIMEOUT_NONE 0
#define KGSL_TIMEOUT_DEFAULT 0xFFFFFFFF
@@ -236,6 +237,12 @@
* context was responsible for causing it
*/
unsigned int reset_status;
+
+ /*
+ * Timeline used to create fences that can be signaled when a
+ * sync_pt timestamp expires.
+ */
+ struct sync_timeline *timeline;
};
struct kgsl_process_private {
diff --git a/drivers/gpu/msm/kgsl_sync.c b/drivers/gpu/msm/kgsl_sync.c
new file mode 100644
index 0000000..a2dfe3b
--- /dev/null
+++ b/drivers/gpu/msm/kgsl_sync.c
@@ -0,0 +1,214 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * 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/file.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+
+#include "kgsl_sync.h"
+
+struct sync_pt *kgsl_sync_pt_create(struct sync_timeline *timeline,
+ unsigned int timestamp)
+{
+ struct sync_pt *pt;
+ pt = sync_pt_create(timeline, (int) sizeof(struct kgsl_sync_pt));
+ if (pt) {
+ struct kgsl_sync_pt *kpt = (struct kgsl_sync_pt *) pt;
+ kpt->timestamp = timestamp;
+ }
+ return pt;
+}
+
+/*
+ * This should only be called on sync_pts which have been created but
+ * not added to a fence.
+ */
+void kgsl_sync_pt_destroy(struct sync_pt *pt)
+{
+ sync_pt_free(pt);
+}
+
+static struct sync_pt *kgsl_sync_pt_dup(struct sync_pt *pt)
+{
+ struct kgsl_sync_pt *kpt = (struct kgsl_sync_pt *) pt;
+ return kgsl_sync_pt_create(pt->parent, kpt->timestamp);
+}
+
+static int kgsl_sync_pt_has_signaled(struct sync_pt *pt)
+{
+ struct kgsl_sync_pt *kpt = (struct kgsl_sync_pt *) pt;
+ struct kgsl_sync_timeline *ktimeline =
+ (struct kgsl_sync_timeline *) pt->parent;
+ unsigned int ts = kpt->timestamp;
+ unsigned int last_ts = ktimeline->last_timestamp;
+ if (timestamp_cmp(last_ts, ts) >= 0) {
+ /* signaled */
+ return 1;
+ }
+ return 0;
+}
+
+static int kgsl_sync_pt_compare(struct sync_pt *a, struct sync_pt *b)
+{
+ struct kgsl_sync_pt *kpt_a = (struct kgsl_sync_pt *) a;
+ struct kgsl_sync_pt *kpt_b = (struct kgsl_sync_pt *) b;
+ unsigned int ts_a = kpt_a->timestamp;
+ unsigned int ts_b = kpt_b->timestamp;
+ return timestamp_cmp(ts_a, ts_b);
+}
+
+struct kgsl_fence_event_priv {
+ struct kgsl_context *context;
+};
+
+/**
+ * kgsl_fence_event_cb - Event callback for a fence timestamp event
+ * @device - The KGSL device that expired the timestamp
+ * @priv - private data for the event
+ * @context_id - the context id that goes with the timestamp
+ * @timestamp - the timestamp that triggered the event
+ *
+ * Signal a fence following the expiration of a timestamp
+ */
+
+static inline void kgsl_fence_event_cb(struct kgsl_device *device,
+ void *priv, u32 context_id, u32 timestamp)
+{
+ struct kgsl_fence_event_priv *ev = priv;
+ kgsl_sync_timeline_signal(ev->context->timeline, timestamp);
+ kgsl_context_put(ev->context);
+ kfree(ev);
+}
+
+/**
+ * kgsl_add_fence_event - Create a new fence event
+ * @device - KGSL device to create the event on
+ * @timestamp - Timestamp to trigger the event
+ * @data - Return fence fd stored in struct kgsl_timestamp_event_fence
+ * @len - length of the fence event
+ * @owner - driver instance that owns this event
+ * @returns 0 on success or error code on error
+ *
+ * Create a fence and register an event to signal the fence when
+ * the timestamp expires
+ */
+
+int kgsl_add_fence_event(struct kgsl_device *device,
+ u32 context_id, u32 timestamp, void __user *data, int len,
+ struct kgsl_device_private *owner)
+{
+ struct kgsl_fence_event_priv *event;
+ struct kgsl_timestamp_event_fence priv;
+ struct kgsl_context *context;
+ struct sync_pt *pt;
+ struct sync_fence *fence = NULL;
+ int ret = -EINVAL;
+
+ if (len != sizeof(priv))
+ return -EINVAL;
+
+ context = kgsl_find_context(owner, context_id);
+ if (context == NULL)
+ return -EINVAL;
+
+ event = kzalloc(sizeof(*event), GFP_KERNEL);
+ if (event == NULL)
+ return -ENOMEM;
+ event->context = context;
+ kgsl_context_get(context);
+
+ pt = kgsl_sync_pt_create(context->timeline, timestamp);
+ if (pt == NULL) {
+ KGSL_DRV_ERR(device, "kgsl_sync_pt_create failed\n");
+ ret = -ENOMEM;
+ goto fail_pt;
+ }
+
+ fence = sync_fence_create("kgsl-fence", pt);
+ if (fence == NULL) {
+ /* only destroy pt when not added to fence */
+ kgsl_sync_pt_destroy(pt);
+ KGSL_DRV_ERR(device, "sync_fence_create failed\n");
+ ret = -ENOMEM;
+ goto fail_fence;
+ }
+
+ priv.fence_fd = get_unused_fd_flags(0);
+ if (priv.fence_fd < 0) {
+ KGSL_DRV_ERR(device, "invalid fence fd\n");
+ ret = -EINVAL;
+ goto fail_fd;
+ }
+ sync_fence_install(fence, priv.fence_fd);
+
+ if (copy_to_user(data, &priv, sizeof(priv))) {
+ ret = -EFAULT;
+ goto fail_copy_fd;
+ }
+
+ ret = kgsl_add_event(device, context_id, timestamp,
+ kgsl_fence_event_cb, event, owner);
+ if (ret)
+ goto fail_event;
+
+ return 0;
+
+fail_event:
+fail_copy_fd:
+ /* clean up sync_fence_install */
+ sync_fence_put(fence);
+ put_unused_fd(priv.fence_fd);
+fail_fd:
+ /* clean up sync_fence_create */
+ sync_fence_put(fence);
+fail_fence:
+fail_pt:
+ kgsl_context_put(context);
+ kfree(event);
+ return ret;
+}
+
+static const struct sync_timeline_ops kgsl_sync_timeline_ops = {
+ .dup = kgsl_sync_pt_dup,
+ .has_signaled = kgsl_sync_pt_has_signaled,
+ .compare = kgsl_sync_pt_compare,
+};
+
+int kgsl_sync_timeline_create(struct kgsl_context *context)
+{
+ struct kgsl_sync_timeline *ktimeline;
+
+ context->timeline = sync_timeline_create(&kgsl_sync_timeline_ops,
+ (int) sizeof(struct kgsl_sync_timeline), "kgsl-timeline");
+ if (context->timeline == NULL)
+ return -EINVAL;
+
+ ktimeline = (struct kgsl_sync_timeline *) context->timeline;
+ ktimeline->last_timestamp = 0;
+
+ return 0;
+}
+
+void kgsl_sync_timeline_signal(struct sync_timeline *timeline,
+ unsigned int timestamp)
+{
+ struct kgsl_sync_timeline *ktimeline =
+ (struct kgsl_sync_timeline *) timeline;
+ ktimeline->last_timestamp = timestamp;
+ sync_timeline_signal(timeline);
+}
+
+void kgsl_sync_timeline_destroy(struct kgsl_context *context)
+{
+ sync_timeline_destroy(context->timeline);
+}
diff --git a/drivers/gpu/msm/kgsl_sync.h b/drivers/gpu/msm/kgsl_sync.h
new file mode 100644
index 0000000..06b3ad0
--- /dev/null
+++ b/drivers/gpu/msm/kgsl_sync.h
@@ -0,0 +1,75 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * 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.
+ *
+ */
+#ifndef __KGSL_SYNC_H
+#define __KGSL_SYNC_H
+
+#include <linux/sync.h>
+#include "kgsl_device.h"
+
+struct kgsl_sync_timeline {
+ struct sync_timeline timeline;
+ unsigned int last_timestamp;
+};
+
+struct kgsl_sync_pt {
+ struct sync_pt pt;
+ unsigned int timestamp;
+};
+
+#if defined(CONFIG_SYNC)
+struct sync_pt *kgsl_sync_pt_create(struct sync_timeline *timeline,
+ unsigned int timestamp);
+void kgsl_sync_pt_destroy(struct sync_pt *pt);
+int kgsl_add_fence_event(struct kgsl_device *device,
+ u32 context_id, u32 timestamp, void __user *data, int len,
+ struct kgsl_device_private *owner);
+int kgsl_sync_timeline_create(struct kgsl_context *context);
+void kgsl_sync_timeline_signal(struct sync_timeline *timeline,
+ unsigned int timestamp);
+void kgsl_sync_timeline_destroy(struct kgsl_context *context);
+#else
+static inline struct sync_pt
+*kgsl_sync_pt_create(struct sync_timeline *timeline, unsigned int timestamp)
+{
+ return NULL;
+}
+
+static inline void kgsl_sync_pt_destroy(struct sync_pt *pt)
+{
+}
+
+static inline int kgsl_add_fence_event(struct kgsl_device *device,
+ u32 context_id, u32 timestamp, void __user *data, int len,
+ struct kgsl_device_private *owner)
+{
+ return -EINVAL;
+}
+
+static int kgsl_sync_timeline_create(struct kgsl_context *context)
+{
+ context->timeline = NULL;
+ return 0;
+}
+
+static inline void
+kgsl_sync_timeline_signal(struct sync_timeline *timeline,
+ unsigned int timestamp)
+{
+}
+
+static inline void kgsl_sync_timeline_destroy(struct kgsl_context *context)
+{
+}
+#endif
+
+#endif /* __KGSL_SYNC_H */
diff --git a/drivers/media/dvb/mpq/video/mpq_dvb_video.c b/drivers/media/dvb/mpq/video/mpq_dvb_video.c
index 3dc31bb..4b3fb0c 100644
--- a/drivers/media/dvb/mpq/video/mpq_dvb_video.c
+++ b/drivers/media/dvb/mpq/video/mpq_dvb_video.c
@@ -868,7 +868,7 @@
if (rc)
DBG("Failed in mpq_int_vid_dec_get_buffer_req : %d\n", rc);
- vdec_buf_req.num_output_buffers = 15;
+ vdec_buf_req.num_output_buffers = 12;
rc = mpq_int_set_out_buffer_req(client_ctx, &vdec_buf_req);
if (rc)
DBG("Failed in mpq_int_set_out_buffer_req (15) : %d\n", rc);
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_common.h b/drivers/media/video/msm/jpeg_10/msm_jpeg_common.h
index 88ec1ad..04af6b6 100644
--- a/drivers/media/video/msm/jpeg_10/msm_jpeg_common.h
+++ b/drivers/media/video/msm/jpeg_10/msm_jpeg_common.h
@@ -14,12 +14,13 @@
#define MSM_JPEG_COMMON_H
#ifdef MSM_JPEG_DEBUG
-#define JPEG_DBG(fmt, args...) printk(fmt, ##args)
+#define JPEG_DBG(fmt, args...) pr_info(fmt, ##args)
#else
#define JPEG_DBG(fmt, args...) do { } while (0)
#endif
#define JPEG_PR_ERR pr_err
+#define JPEG_DBG_HIGH pr_err
enum JPEG_MODE {
JPEG_MODE_DISABLE,
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_core.c b/drivers/media/video/msm/jpeg_10/msm_jpeg_core.c
index 7905ff3..b67245c 100644
--- a/drivers/media/video/msm/jpeg_10/msm_jpeg_core.c
+++ b/drivers/media/video/msm/jpeg_10/msm_jpeg_core.c
@@ -17,122 +17,130 @@
#include "msm_jpeg_platform.h"
#include "msm_jpeg_common.h"
-static struct msm_jpeg_hw_pingpong fe_pingpong_buf;
-static struct msm_jpeg_hw_pingpong we_pingpong_buf;
-static int we_pingpong_index;
-static int reset_done_ack;
-static spinlock_t reset_lock;
-static wait_queue_head_t reset_wait;
-
-int msm_jpeg_core_reset(uint8_t op_mode, void *base, int size)
-{
+int msm_jpeg_core_reset(struct msm_jpeg_device *pgmn_dev, uint8_t op_mode,
+ void *base, int size) {
unsigned long flags;
int rc = 0;
int tm = 500; /*500ms*/
- memset(&fe_pingpong_buf, 0, sizeof(fe_pingpong_buf));
- fe_pingpong_buf.is_fe = 1;
- we_pingpong_index = 0;
- memset(&we_pingpong_buf, 0, sizeof(we_pingpong_buf));
- spin_lock_irqsave(&reset_lock, flags);
- reset_done_ack = 0;
+ JPEG_DBG("%s:%d] reset", __func__, __LINE__);
+ memset(&pgmn_dev->fe_pingpong_buf, 0,
+ sizeof(pgmn_dev->fe_pingpong_buf));
+ pgmn_dev->fe_pingpong_buf.is_fe = 1;
+ memset(&pgmn_dev->we_pingpong_buf, 0,
+ sizeof(pgmn_dev->we_pingpong_buf));
+ spin_lock_irqsave(&pgmn_dev->reset_lock, flags);
+ pgmn_dev->reset_done_ack = 0;
msm_jpeg_hw_reset(base, size);
- spin_unlock_irqrestore(&reset_lock, flags);
+ spin_unlock_irqrestore(&pgmn_dev->reset_lock, flags);
rc = wait_event_interruptible_timeout(
- reset_wait,
- reset_done_ack,
+ pgmn_dev->reset_wait,
+ pgmn_dev->reset_done_ack,
msecs_to_jiffies(tm));
- if (!reset_done_ack) {
+ if (!pgmn_dev->reset_done_ack) {
JPEG_DBG("%s: reset ACK failed %d", __func__, rc);
return -EBUSY;
}
JPEG_DBG("%s: reset_done_ack rc %d", __func__, rc);
- spin_lock_irqsave(&reset_lock, flags);
- reset_done_ack = 0;
- spin_unlock_irqrestore(&reset_lock, flags);
+ spin_lock_irqsave(&pgmn_dev->reset_lock, flags);
+ pgmn_dev->reset_done_ack = 0;
+ spin_unlock_irqrestore(&pgmn_dev->reset_lock, flags);
return 0;
}
-void msm_jpeg_core_release(int release_buf, int domain_num)
-{
+void msm_jpeg_core_release(struct msm_jpeg_device *pgmn_dev,
+ int domain_num) {
int i = 0;
for (i = 0; i < 2; i++) {
- if (we_pingpong_buf.buf_status[i] && release_buf)
- msm_jpeg_platform_p2v(we_pingpong_buf.buf[i].file,
- &we_pingpong_buf.buf[i].handle, domain_num);
- we_pingpong_buf.buf_status[i] = 0;
+ if (pgmn_dev->we_pingpong_buf.buf_status[i] &&
+ pgmn_dev->release_buf)
+ msm_jpeg_platform_p2v(pgmn_dev,
+ pgmn_dev->we_pingpong_buf.buf[i].file,
+ &pgmn_dev->we_pingpong_buf.buf[i].handle,
+ domain_num);
+ pgmn_dev->we_pingpong_buf.buf_status[i] = 0;
}
}
-void msm_jpeg_core_init(void)
+void msm_jpeg_core_init(struct msm_jpeg_device *pgmn_dev)
{
- init_waitqueue_head(&reset_wait);
- spin_lock_init(&reset_lock);
+ init_waitqueue_head(&pgmn_dev->reset_wait);
+ spin_lock_init(&pgmn_dev->reset_lock);
}
-int msm_jpeg_core_fe_start(void)
+int msm_jpeg_core_fe_start(struct msm_jpeg_device *pgmn_dev)
{
- msm_jpeg_hw_fe_start();
+ msm_jpeg_hw_fe_start(pgmn_dev->base);
return 0;
}
/* fetch engine */
-int msm_jpeg_core_fe_buf_update(struct msm_jpeg_core_buf *buf)
+int msm_jpeg_core_fe_buf_update(struct msm_jpeg_device *pgmn_dev,
+ struct msm_jpeg_core_buf *buf)
{
+ if (0 == buf->cbcr_len)
+ buf->cbcr_buffer_addr = 0x0;
JPEG_DBG("%s:%d] 0x%08x %d 0x%08x %d\n", __func__, __LINE__,
(int) buf->y_buffer_addr, buf->y_len,
(int) buf->cbcr_buffer_addr, buf->cbcr_len);
- return msm_jpeg_hw_pingpong_update(&fe_pingpong_buf, buf);
+ return msm_jpeg_hw_pingpong_update(&pgmn_dev->fe_pingpong_buf, buf,
+ pgmn_dev->base);
}
-void *msm_jpeg_core_fe_pingpong_irq(int jpeg_irq_status, void *context)
+void *msm_jpeg_core_fe_pingpong_irq(int jpeg_irq_status,
+ struct msm_jpeg_device *pgmn_dev)
{
- return msm_jpeg_hw_pingpong_irq(&fe_pingpong_buf);
+ return msm_jpeg_hw_pingpong_irq(&pgmn_dev->fe_pingpong_buf);
}
/* write engine */
-int msm_jpeg_core_we_buf_update(struct msm_jpeg_core_buf *buf)
-{
+int msm_jpeg_core_we_buf_update(struct msm_jpeg_device *pgmn_dev,
+ struct msm_jpeg_core_buf *buf) {
JPEG_DBG("%s:%d] 0x%08x 0x%08x %d\n", __func__, __LINE__,
(int) buf->y_buffer_addr, (int) buf->cbcr_buffer_addr,
buf->y_len);
- we_pingpong_buf.buf[0] = *buf;
- we_pingpong_buf.buf_status[0] = 1;
+ pgmn_dev->we_pingpong_buf.buf[0] = *buf;
+ pgmn_dev->we_pingpong_buf.buf_status[0] = 1;
msm_jpeg_hw_we_buffer_update(
- &we_pingpong_buf.buf[0], 0);
+ &pgmn_dev->we_pingpong_buf.buf[0], 0, pgmn_dev->base);
return 0;
}
-int msm_jpeg_core_we_buf_reset(struct msm_jpeg_hw_buf *buf)
+int msm_jpeg_core_we_buf_reset(struct msm_jpeg_device *pgmn_dev,
+ struct msm_jpeg_hw_buf *buf)
{
int i = 0;
for (i = 0; i < 2; i++) {
- if (we_pingpong_buf.buf[i].y_buffer_addr
- == buf->y_buffer_addr)
- we_pingpong_buf.buf_status[i] = 0;
+ if (pgmn_dev->we_pingpong_buf.buf[i].y_buffer_addr
+ == buf->y_buffer_addr)
+ pgmn_dev->we_pingpong_buf.buf_status[i] = 0;
}
return 0;
}
-void *msm_jpeg_core_we_pingpong_irq(int jpeg_irq_status, void *context)
+void *msm_jpeg_core_we_pingpong_irq(int jpeg_irq_status,
+ struct msm_jpeg_device *pgmn_dev)
{
JPEG_DBG("%s:%d]\n", __func__, __LINE__);
- return msm_jpeg_hw_pingpong_irq(&we_pingpong_buf);
+ return msm_jpeg_hw_pingpong_irq(&pgmn_dev->we_pingpong_buf);
}
-void *msm_jpeg_core_framedone_irq(int jpeg_irq_status, void *context)
+void *msm_jpeg_core_framedone_irq(int jpeg_irq_status,
+ struct msm_jpeg_device *pgmn_dev)
{
struct msm_jpeg_hw_buf *buf_p;
JPEG_DBG("%s:%d]\n", __func__, __LINE__);
- buf_p = msm_jpeg_hw_pingpong_active_buffer(&we_pingpong_buf);
- if (buf_p) {
- buf_p->framedone_len = msm_jpeg_hw_encode_output_size();
+ buf_p = msm_jpeg_hw_pingpong_active_buffer(
+ &pgmn_dev->we_pingpong_buf);
+ if (buf_p && !pgmn_dev->decode_flag) {
+ buf_p->framedone_len =
+ msm_jpeg_hw_encode_output_size(pgmn_dev->base);
JPEG_DBG("%s:%d] framedone_len %d\n", __func__, __LINE__,
buf_p->framedone_len);
}
@@ -140,14 +148,16 @@
return buf_p;
}
-void *msm_jpeg_core_reset_ack_irq(int jpeg_irq_status, void *context)
+void *msm_jpeg_core_reset_ack_irq(int jpeg_irq_status,
+ struct msm_jpeg_device *pgmn_dev)
{
/* @todo return the status back to msm_jpeg_core_reset */
JPEG_DBG("%s:%d]\n", __func__, __LINE__);
return NULL;
}
-void *msm_jpeg_core_err_irq(int jpeg_irq_status, void *context)
+void *msm_jpeg_core_err_irq(int jpeg_irq_status,
+ struct msm_jpeg_device *pgmn_dev)
{
JPEG_PR_ERR("%s:%d]\n", __func__, jpeg_irq_status);
return NULL;
@@ -155,15 +165,32 @@
static int (*msm_jpeg_irq_handler) (int, void *, void *);
+void msm_jpeg_core_return_buffers(struct msm_jpeg_device *pgmn_dev,
+ int jpeg_irq_status)
+{
+ void *data = NULL;
+ data = msm_jpeg_core_fe_pingpong_irq(jpeg_irq_status,
+ pgmn_dev);
+ if (msm_jpeg_irq_handler)
+ msm_jpeg_irq_handler(MSM_JPEG_HW_MASK_COMP_FE,
+ pgmn_dev, data);
+ data = msm_jpeg_core_we_pingpong_irq(jpeg_irq_status,
+ pgmn_dev);
+ if (msm_jpeg_irq_handler)
+ msm_jpeg_irq_handler(MSM_JPEG_HW_MASK_COMP_WE,
+ pgmn_dev, data);
+}
+
irqreturn_t msm_jpeg_core_irq(int irq_num, void *context)
{
void *data = NULL;
unsigned long flags;
int jpeg_irq_status;
+ struct msm_jpeg_device *pgmn_dev = (struct msm_jpeg_device *)context;
JPEG_DBG("%s:%d] irq_num = %d\n", __func__, __LINE__, irq_num);
- jpeg_irq_status = msm_jpeg_hw_irq_get_status();
+ jpeg_irq_status = msm_jpeg_hw_irq_get_status(pgmn_dev->base);
JPEG_DBG("%s:%d] jpeg_irq_status = %0x\n", __func__, __LINE__,
jpeg_irq_status);
@@ -171,18 +198,26 @@
/*For reset and framedone IRQs, clear all bits*/
if (jpeg_irq_status & 0x10000000) {
msm_jpeg_hw_irq_clear(JPEG_IRQ_CLEAR_BMSK,
- JPEG_IRQ_CLEAR_ALL);
+ JPEG_IRQ_CLEAR_ALL, pgmn_dev->base);
} else if (jpeg_irq_status & 0x1) {
msm_jpeg_hw_irq_clear(JPEG_IRQ_CLEAR_BMSK,
- JPEG_IRQ_CLEAR_ALL);
+ JPEG_IRQ_CLEAR_ALL, pgmn_dev->base);
+ if (pgmn_dev->decode_flag)
+ msm_jpeg_decode_status(pgmn_dev->base);
} else {
msm_jpeg_hw_irq_clear(JPEG_IRQ_CLEAR_BMSK,
- jpeg_irq_status);
+ jpeg_irq_status, pgmn_dev->base);
}
if (msm_jpeg_hw_irq_is_frame_done(jpeg_irq_status)) {
+ /* send fe ping pong irq */
+ data = msm_jpeg_core_fe_pingpong_irq(jpeg_irq_status,
+ pgmn_dev);
+ if (msm_jpeg_irq_handler)
+ msm_jpeg_irq_handler(MSM_JPEG_HW_MASK_COMP_FE,
+ context, data);
data = msm_jpeg_core_framedone_irq(jpeg_irq_status,
- context);
+ pgmn_dev);
if (msm_jpeg_irq_handler)
msm_jpeg_irq_handler(
MSM_JPEG_HW_MASK_COMP_FRAMEDONE,
@@ -190,11 +225,11 @@
}
if (msm_jpeg_hw_irq_is_reset_ack(jpeg_irq_status)) {
data = msm_jpeg_core_reset_ack_irq(jpeg_irq_status,
- context);
- spin_lock_irqsave(&reset_lock, flags);
- reset_done_ack = 1;
- spin_unlock_irqrestore(&reset_lock, flags);
- wake_up(&reset_wait);
+ pgmn_dev);
+ spin_lock_irqsave(&pgmn_dev->reset_lock, flags);
+ pgmn_dev->reset_done_ack = 1;
+ spin_unlock_irqrestore(&pgmn_dev->reset_lock, flags);
+ wake_up(&pgmn_dev->reset_wait);
if (msm_jpeg_irq_handler)
msm_jpeg_irq_handler(
MSM_JPEG_HW_MASK_COMP_RESET_ACK,
@@ -203,7 +238,10 @@
/* Unexpected/unintended HW interrupt */
if (msm_jpeg_hw_irq_is_err(jpeg_irq_status)) {
- data = msm_jpeg_core_err_irq(jpeg_irq_status, context);
+ if (pgmn_dev->decode_flag)
+ msm_jpeg_decode_status(pgmn_dev->base);
+ msm_jpeg_core_return_buffers(pgmn_dev, jpeg_irq_status);
+ data = msm_jpeg_core_err_irq(jpeg_irq_status, pgmn_dev);
if (msm_jpeg_irq_handler)
msm_jpeg_irq_handler(MSM_JPEG_HW_MASK_COMP_ERR,
context, data);
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_core.h b/drivers/media/video/msm/jpeg_10/msm_jpeg_core.h
index b5c725c..212eaff 100644
--- a/drivers/media/video/msm/jpeg_10/msm_jpeg_core.h
+++ b/drivers/media/video/msm/jpeg_10/msm_jpeg_core.h
@@ -15,6 +15,7 @@
#include <linux/interrupt.h>
#include "msm_jpeg_hw.h"
+#include "msm_jpeg_sync.h"
#define msm_jpeg_core_buf msm_jpeg_hw_buf
@@ -23,13 +24,17 @@
void msm_jpeg_core_irq_install(int (*irq_handler) (int, void *, void *));
void msm_jpeg_core_irq_remove(void);
-int msm_jpeg_core_fe_buf_update(struct msm_jpeg_core_buf *buf);
-int msm_jpeg_core_we_buf_update(struct msm_jpeg_core_buf *buf);
-int msm_jpeg_core_we_buf_reset(struct msm_jpeg_hw_buf *buf);
+int msm_jpeg_core_fe_buf_update(struct msm_jpeg_device *pgmn_dev,
+ struct msm_jpeg_core_buf *buf);
+int msm_jpeg_core_we_buf_update(struct msm_jpeg_device *pgmn_dev,
+ struct msm_jpeg_core_buf *buf);
+int msm_jpeg_core_we_buf_reset(struct msm_jpeg_device *pgmn_dev,
+ struct msm_jpeg_hw_buf *buf);
-int msm_jpeg_core_reset(uint8_t op_mode, void *base, int size);
-int msm_jpeg_core_fe_start(void);
+int msm_jpeg_core_reset(struct msm_jpeg_device *pgmn_dev, uint8_t op_mode,
+ void *base, int size);
+int msm_jpeg_core_fe_start(struct msm_jpeg_device *);
-void msm_jpeg_core_release(int, int);
-void msm_jpeg_core_init(void);
+void msm_jpeg_core_release(struct msm_jpeg_device *, int);
+void msm_jpeg_core_init(struct msm_jpeg_device *);
#endif /* MSM_JPEG_CORE_H */
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_dev.c b/drivers/media/video/msm/jpeg_10/msm_jpeg_dev.c
index 45a9a38..0662f54 100644
--- a/drivers/media/video/msm/jpeg_10/msm_jpeg_dev.c
+++ b/drivers/media/video/msm/jpeg_10/msm_jpeg_dev.c
@@ -31,9 +31,7 @@
#include "msm_jpeg_common.h"
#define MSM_JPEG_NAME "jpeg"
-#define MSM_JPEGE1_NAME "jpege1"
-#define MSM_JPEGD_NAME "jpegd"
-
+#define DEV_NAME_LEN 10
static int msm_jpeg_open(struct inode *inode, struct file *filp)
{
@@ -146,7 +144,7 @@
int rc = -1;
struct device *dev;
struct msm_jpeg_device *msm_jpeg_device_p;
- char devname[10];
+ char devname[DEV_NAME_LEN];
msm_jpeg_device_p = kzalloc(sizeof(struct msm_jpeg_device), GFP_ATOMIC);
if (!msm_jpeg_device_p) {
@@ -158,7 +156,7 @@
if (pdev->dev.of_node)
of_property_read_u32((&pdev->dev)->of_node, "cell-index",
- &pdev->id);
+ &pdev->id);
snprintf(devname, sizeof(devname), "%s%d", MSM_JPEG_NAME, pdev->id);
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_hw.c b/drivers/media/video/msm/jpeg_10/msm_jpeg_hw.c
index 0bfb6a8..e311e4c 100644
--- a/drivers/media/video/msm/jpeg_10/msm_jpeg_hw.c
+++ b/drivers/media/video/msm/jpeg_10/msm_jpeg_hw.c
@@ -17,11 +17,8 @@
#include <linux/io.h>
-static void *jpeg_region_base;
-static uint32_t jpeg_region_size;
-
int msm_jpeg_hw_pingpong_update(struct msm_jpeg_hw_pingpong *pingpong_hw,
- struct msm_jpeg_hw_buf *buf)
+ struct msm_jpeg_hw_buf *buf, void *base)
{
int buf_free_index = -1;
@@ -41,11 +38,13 @@
if (pingpong_hw->is_fe) {
/* it is fe */
msm_jpeg_hw_fe_buffer_update(
- &pingpong_hw->buf[buf_free_index], buf_free_index);
+ &pingpong_hw->buf[buf_free_index], buf_free_index,
+ base);
} else {
/* it is we */
msm_jpeg_hw_we_buffer_update(
- &pingpong_hw->buf[buf_free_index], buf_free_index);
+ &pingpong_hw->buf[buf_free_index], buf_free_index,
+ base);
}
return 0;
}
@@ -81,12 +80,10 @@
JPEG_IRQ_STATUS_BMSK, {0} },
};
-int msm_jpeg_hw_irq_get_status(void)
+int msm_jpeg_hw_irq_get_status(void *base)
{
uint32_t n_irq_status = 0;
- rmb();
- n_irq_status = msm_jpeg_hw_read(&hw_cmd_irq_get_status[0]);
- rmb();
+ n_irq_status = msm_jpeg_hw_read(&hw_cmd_irq_get_status[0], base);
return n_irq_status;
}
@@ -97,11 +94,12 @@
JPEG_ENCODE_OUTPUT_SIZE_STATUS_BMSK, {0} } ,
};
-long msm_jpeg_hw_encode_output_size(void)
+long msm_jpeg_hw_encode_output_size(void *base)
{
uint32_t encode_output_size = 0;
- encode_output_size = msm_jpeg_hw_read(&hw_cmd_encode_output_size[0]);
+ encode_output_size = msm_jpeg_hw_read(&hw_cmd_encode_output_size[0],
+ base);
return encode_output_size;
}
@@ -112,12 +110,12 @@
JPEG_IRQ_CLEAR_BMSK, {JPEG_IRQ_CLEAR_ALL} },
};
-void msm_jpeg_hw_irq_clear(uint32_t mask, uint32_t data)
+void msm_jpeg_hw_irq_clear(uint32_t mask, uint32_t data, void *base)
{
JPEG_DBG("%s:%d] mask %0x data %0x", __func__, __LINE__, mask, data);
hw_cmd_irq_clear[0].mask = mask;
hw_cmd_irq_clear[0].data = data;
- msm_jpeg_hw_write(&hw_cmd_irq_clear[0]);
+ msm_jpeg_hw_write(&hw_cmd_irq_clear[0], base);
}
struct msm_jpeg_hw_cmd hw_cmd_fe_ping_update[] = {
@@ -137,26 +135,26 @@
};
void msm_jpeg_hw_fe_buffer_update(struct msm_jpeg_hw_buf *p_input,
- uint8_t pingpong_index)
+ uint8_t pingpong_index, void *base)
{
struct msm_jpeg_hw_cmd *hw_cmd_p;
if (pingpong_index == 0) {
hw_cmd_p = &hw_cmd_fe_ping_update[0];
wmb();
- msm_jpeg_hw_write(hw_cmd_p++);
+ msm_jpeg_hw_write(hw_cmd_p++, base);
wmb();
- msm_jpeg_hw_write(hw_cmd_p++);
+ msm_jpeg_hw_write(hw_cmd_p++, base);
wmb();
- msm_jpeg_hw_write(hw_cmd_p++);
+ msm_jpeg_hw_write(hw_cmd_p++, base);
wmb();
hw_cmd_p->data = p_input->y_buffer_addr;
- msm_jpeg_hw_write(hw_cmd_p++);
+ msm_jpeg_hw_write(hw_cmd_p++, base);
wmb();
- msm_jpeg_hw_write(hw_cmd_p++);
+ msm_jpeg_hw_write(hw_cmd_p++, base);
wmb();
hw_cmd_p->data = p_input->cbcr_buffer_addr;
- msm_jpeg_hw_write(hw_cmd_p++);
+ msm_jpeg_hw_write(hw_cmd_p++, base);
wmb();
}
@@ -169,9 +167,9 @@
JPEG_CMD_BMSK, {JPEG_OFFLINE_CMD_START} },
};
-void msm_jpeg_hw_fe_start(void)
+void msm_jpeg_hw_fe_start(void *base)
{
- msm_jpeg_hw_write(&hw_cmd_fe_start[0]);
+ msm_jpeg_hw_write(&hw_cmd_fe_start[0], base);
return;
}
@@ -180,20 +178,46 @@
/* type, repeat n times, offset, mask, data or pdata */
{MSM_JPEG_HW_CMD_TYPE_WRITE, 1, JPEG_PLN0_WR_PNTR_ADDR,
JPEG_PLN0_WR_PNTR_BMSK, {0} },
+ {MSM_JPEG_HW_CMD_TYPE_WRITE, 1, JPEG_PLN1_WR_PNTR_ADDR,
+ JPEG_PLN0_WR_PNTR_BMSK, {0} },
+ {MSM_JPEG_HW_CMD_TYPE_WRITE, 1, JPEG_PLN2_WR_PNTR_ADDR,
+ JPEG_PLN0_WR_PNTR_BMSK, {0} },
};
+void msm_jpeg_decode_status(void *base)
+{
+ uint32_t data;
+ data = readl_relaxed(base + JPEG_DECODE_MCUS_DECODED_STATUS);
+ JPEG_DBG_HIGH("Decode MCUs decode status %u", data);
+ data = readl_relaxed(base + JPEG_DECODE_BITS_CONSUMED_STATUS);
+ JPEG_DBG_HIGH("Decode bits consumed status %u", data);
+ data = readl_relaxed(base + JPEG_DECODE_PRED_Y_STATE);
+ JPEG_DBG_HIGH("Decode prediction Y state %u", data);
+ data = readl_relaxed(base + JPEG_DECODE_PRED_C_STATE);
+ JPEG_DBG_HIGH("Decode prediction C state %u", data);
+ data = readl_relaxed(base + JPEG_DECODE_RSM_STATE);
+ JPEG_DBG_HIGH("Decode prediction RSM state %u", data);
+}
+
+
void msm_jpeg_hw_we_buffer_update(struct msm_jpeg_hw_buf *p_input,
- uint8_t pingpong_index)
+ uint8_t pingpong_index, void *base)
{
struct msm_jpeg_hw_cmd *hw_cmd_p;
if (pingpong_index == 0) {
hw_cmd_p = &hw_cmd_we_ping_update[0];
hw_cmd_p->data = p_input->y_buffer_addr;
- JPEG_PR_ERR("%s Output buffer address is %x\n", __func__,
- p_input->y_buffer_addr);
- msm_jpeg_hw_write(hw_cmd_p++);
-
+ JPEG_PR_ERR("%s Output pln0 buffer address is %x\n", __func__,
+ p_input->y_buffer_addr);
+ msm_jpeg_hw_write(hw_cmd_p++, base);
+ hw_cmd_p->data = p_input->cbcr_buffer_addr;
+ JPEG_PR_ERR("%s Output pln1 buffer address is %x\n", __func__,
+ p_input->cbcr_buffer_addr);
+ msm_jpeg_hw_write(hw_cmd_p++, base);
+ JPEG_PR_ERR("%s Output pln2 buffer address is %x\n", __func__,
+ p_input->pln2_addr);
+ msm_jpeg_hw_write(hw_cmd_p++, base);
}
return;
}
@@ -210,31 +234,26 @@
JPEG_RESET_CMD_RMSK, {JPEG_RESET_DEFAULT} },
};
-void msm_jpeg_hw_init(void *base, int size)
-{
- jpeg_region_base = base;
- jpeg_region_size = size;
-}
-
void msm_jpeg_hw_reset(void *base, int size)
{
struct msm_jpeg_hw_cmd *hw_cmd_p;
hw_cmd_p = &hw_cmd_reset[0];
wmb();
- msm_jpeg_hw_write(hw_cmd_p++);
+ msm_jpeg_hw_write(hw_cmd_p++, base);
wmb();
- msm_jpeg_hw_write(hw_cmd_p++);
+ msm_jpeg_hw_write(hw_cmd_p++, base);
wmb();
- msm_jpeg_hw_write(hw_cmd_p++);
+ msm_jpeg_hw_write(hw_cmd_p++, base);
wmb();
- msm_jpeg_hw_write(hw_cmd_p);
+ msm_jpeg_hw_write(hw_cmd_p, base);
wmb();
return;
}
-uint32_t msm_jpeg_hw_read(struct msm_jpeg_hw_cmd *hw_cmd_p)
+uint32_t msm_jpeg_hw_read(struct msm_jpeg_hw_cmd *hw_cmd_p,
+ void *jpeg_region_base)
{
uint32_t *paddr;
uint32_t data;
@@ -247,7 +266,8 @@
return data;
}
-void msm_jpeg_hw_write(struct msm_jpeg_hw_cmd *hw_cmd_p)
+void msm_jpeg_hw_write(struct msm_jpeg_hw_cmd *hw_cmd_p,
+ void *jpeg_region_base)
{
uint32_t *paddr;
uint32_t old_data, new_data;
@@ -266,17 +286,18 @@
writel_relaxed(new_data, paddr);
}
-int msm_jpeg_hw_wait(struct msm_jpeg_hw_cmd *hw_cmd_p, int m_us)
+int msm_jpeg_hw_wait(struct msm_jpeg_hw_cmd *hw_cmd_p, int m_us,
+ void *base)
{
int tm = hw_cmd_p->n;
uint32_t data;
uint32_t wait_data = hw_cmd_p->data & hw_cmd_p->mask;
- data = msm_jpeg_hw_read(hw_cmd_p);
+ data = msm_jpeg_hw_read(hw_cmd_p, base);
if (data != wait_data) {
while (tm) {
udelay(m_us);
- data = msm_jpeg_hw_read(hw_cmd_p);
+ data = msm_jpeg_hw_read(hw_cmd_p, base);
if (data == wait_data)
break;
tm--;
@@ -295,41 +316,42 @@
}
}
-int msm_jpeg_hw_exec_cmds(struct msm_jpeg_hw_cmd *hw_cmd_p, int m_cmds)
+int msm_jpeg_hw_exec_cmds(struct msm_jpeg_hw_cmd *hw_cmd_p, int m_cmds,
+ uint32_t max_size, void *base)
{
int is_copy_to_user = -1;
uint32_t data;
while (m_cmds--) {
- if (hw_cmd_p->offset > jpeg_region_size) {
+ if (hw_cmd_p->offset > max_size) {
JPEG_PR_ERR("%s:%d] %d exceed hw region %d\n", __func__,
- __LINE__, hw_cmd_p->offset, jpeg_region_size);
+ __LINE__, hw_cmd_p->offset, max_size);
return -EFAULT;
}
switch (hw_cmd_p->type) {
case MSM_JPEG_HW_CMD_TYPE_READ:
- hw_cmd_p->data = msm_jpeg_hw_read(hw_cmd_p);
+ hw_cmd_p->data = msm_jpeg_hw_read(hw_cmd_p, base);
is_copy_to_user = 1;
break;
case MSM_JPEG_HW_CMD_TYPE_WRITE:
- msm_jpeg_hw_write(hw_cmd_p);
+ msm_jpeg_hw_write(hw_cmd_p, base);
break;
case MSM_JPEG_HW_CMD_TYPE_WRITE_OR:
- data = msm_jpeg_hw_read(hw_cmd_p);
+ data = msm_jpeg_hw_read(hw_cmd_p, base);
hw_cmd_p->data = (hw_cmd_p->data & hw_cmd_p->mask) |
data;
- msm_jpeg_hw_write(hw_cmd_p);
+ msm_jpeg_hw_write(hw_cmd_p, base);
break;
case MSM_JPEG_HW_CMD_TYPE_UWAIT:
- msm_jpeg_hw_wait(hw_cmd_p, 1);
+ msm_jpeg_hw_wait(hw_cmd_p, 1, base);
break;
case MSM_JPEG_HW_CMD_TYPE_MWAIT:
- msm_jpeg_hw_wait(hw_cmd_p, 1000);
+ msm_jpeg_hw_wait(hw_cmd_p, 1000, base);
break;
case MSM_JPEG_HW_CMD_TYPE_UDELAY:
@@ -350,15 +372,14 @@
return is_copy_to_user;
}
-void msm_jpeg_io_dump(int size)
+void msm_jpeg_io_dump(void *base, int size)
{
char line_str[128], *p_str;
- void __iomem *addr = jpeg_region_base;
+ void __iomem *addr = (void __iomem *)base;
int i;
u32 *p = (u32 *) addr;
u32 data;
- JPEG_PR_ERR("%s: %p %d reg_size %d\n", __func__, addr, size,
- jpeg_region_size);
+ JPEG_DBG_HIGH("%s:%d] %p %d", __func__, __LINE__, addr, size);
line_str[0] = '\0';
p_str = line_str;
for (i = 0; i < size/4; i++) {
@@ -370,11 +391,12 @@
snprintf(p_str, 12, "%08x ", data);
p_str += 9;
if ((i + 1) % 4 == 0) {
- JPEG_PR_ERR("%s\n", line_str);
+ JPEG_DBG_HIGH("%s\n", line_str);
line_str[0] = '\0';
p_str = line_str;
}
}
if (line_str[0] != '\0')
- JPEG_PR_ERR("%s\n", line_str);
+ JPEG_DBG_HIGH("%s\n", line_str);
}
+
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_hw.h b/drivers/media/video/msm/jpeg_10/msm_jpeg_hw.h
index 73a0e27..e90b941 100644
--- a/drivers/media/video/msm/jpeg_10/msm_jpeg_hw.h
+++ b/drivers/media/video/msm/jpeg_10/msm_jpeg_hw.h
@@ -28,6 +28,8 @@
uint32_t cbcr_len;
uint32_t num_of_mcu_rows;
struct ion_handle *handle;
+ uint32_t pln2_addr;
+ uint32_t pln2_offset;
};
struct msm_jpeg_hw_pingpong {
@@ -38,14 +40,14 @@
};
int msm_jpeg_hw_pingpong_update(struct msm_jpeg_hw_pingpong *pingpong_hw,
- struct msm_jpeg_hw_buf *buf);
+ struct msm_jpeg_hw_buf *buf, void *);
void *msm_jpeg_hw_pingpong_irq(struct msm_jpeg_hw_pingpong *pingpong_hw);
void *msm_jpeg_hw_pingpong_active_buffer(struct msm_jpeg_hw_pingpong
*pingpong_hw);
-void msm_jpeg_hw_irq_clear(uint32_t, uint32_t);
-int msm_jpeg_hw_irq_get_status(void);
-long msm_jpeg_hw_encode_output_size(void);
+void msm_jpeg_hw_irq_clear(uint32_t, uint32_t, void *);
+int msm_jpeg_hw_irq_get_status(void *);
+long msm_jpeg_hw_encode_output_size(void *);
#define MSM_JPEG_HW_MASK_COMP_FRAMEDONE \
MSM_JPEG_HW_IRQ_STATUS_FRAMEDONE_MASK
#define MSM_JPEG_HW_MASK_COMP_FE \
@@ -56,13 +58,14 @@
#define MSM_JPEG_HW_MASK_COMP_RESET_ACK \
MSM_JPEG_HW_IRQ_STATUS_RESET_ACK_MASK
#define MSM_JPEG_HW_MASK_COMP_ERR \
- (MSM_JPEG_HW_IRQ_STATUS_FE_RTOVF_MASK | \
- MSM_JPEG_HW_IRQ_STATUS_FE_VFE_OVERFLOW_MASK | \
- MSM_JPEG_HW_IRQ_STATUS_WE_Y_BUFFER_OVERFLOW_MASK | \
- MSM_JPEG_HW_IRQ_STATUS_WE_CBCR_BUFFER_OVERFLOW_MASK | \
- MSM_JPEG_HW_IRQ_STATUS_WE_CH0_DATAFIFO_OVERFLOW_MASK | \
- MSM_JPEG_HW_IRQ_STATUS_WE_CH1_DATAFIFO_OVERFLOW_MASK | \
- MSM_JPEG_HW_IRQ_STATUS_BUS_ERROR_MASK | \
+ (MSM_JPEG_HW_IRQ_STATUS_DCD_UNESCAPED_FF | \
+ MSM_JPEG_HW_IRQ_STATUS_DCD_HUFFMAN_ERROR | \
+ MSM_JPEG_HW_IRQ_STATUS_DCD_COEFFICIENT_ERR | \
+ MSM_JPEG_HW_IRQ_STATUS_DCD_MISSING_BIT_STUFF | \
+ MSM_JPEG_HW_IRQ_STATUS_DCD_SCAN_UNDERFLOW | \
+ MSM_JPEG_HW_IRQ_STATUS_DCD_INVALID_RSM | \
+ MSM_JPEG_HW_IRQ_STATUS_DCD_INVALID_RSM_SEQ | \
+ MSM_JPEG_HW_IRQ_STATUS_DCD_MISSING_RSM | \
MSM_JPEG_HW_IRQ_STATUS_VIOLATION_MASK)
#define msm_jpeg_hw_irq_is_frame_done(jpeg_irq_status) \
@@ -77,25 +80,26 @@
(jpeg_irq_status & MSM_JPEG_HW_MASK_COMP_ERR)
void msm_jpeg_hw_fe_buffer_update(struct msm_jpeg_hw_buf *p_input,
- uint8_t pingpong_index);
+ uint8_t pingpong_index, void *);
void msm_jpeg_hw_we_buffer_update(struct msm_jpeg_hw_buf *p_input,
- uint8_t pingpong_index);
+ uint8_t pingpong_index, void *);
void msm_jpeg_hw_we_buffer_cfg(uint8_t is_realtime);
-void msm_jpeg_hw_fe_start(void);
+void msm_jpeg_hw_fe_start(void *);
void msm_jpeg_hw_clk_cfg(void);
void msm_jpeg_hw_reset(void *base, int size);
void msm_jpeg_hw_irq_cfg(void);
-void msm_jpeg_hw_init(void *base, int size);
-uint32_t msm_jpeg_hw_read(struct msm_jpeg_hw_cmd *hw_cmd_p);
-void msm_jpeg_hw_write(struct msm_jpeg_hw_cmd *hw_cmd_p);
-int msm_jpeg_hw_wait(struct msm_jpeg_hw_cmd *hw_cmd_p, int m_us);
-void msm_jpeg_hw_delay(struct msm_jpeg_hw_cmd *hw_cmd_p, int m_us);
-int msm_jpeg_hw_exec_cmds(struct msm_jpeg_hw_cmd *hw_cmd_p, int m_cmds);
+uint32_t msm_jpeg_hw_read(struct msm_jpeg_hw_cmd *, void *);
+void msm_jpeg_hw_write(struct msm_jpeg_hw_cmd *, void *);
+int msm_jpeg_hw_wait(struct msm_jpeg_hw_cmd *, int, void *);
+void msm_jpeg_hw_delay(struct msm_jpeg_hw_cmd *, int);
+int msm_jpeg_hw_exec_cmds(struct msm_jpeg_hw_cmd *, int ,
+ uint32_t , void *);
void msm_jpeg_hw_region_dump(int size);
-void msm_jpeg_io_dump(int size);
+void msm_jpeg_io_dump(void *base, int size);
+void msm_jpeg_decode_status(void *base);
#endif /* MSM_JPEG_HW_H */
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_hw_reg.h b/drivers/media/video/msm/jpeg_10/msm_jpeg_hw_reg.h
index ae64c32..928d59e 100644
--- a/drivers/media/video/msm/jpeg_10/msm_jpeg_hw_reg.h
+++ b/drivers/media/video/msm/jpeg_10/msm_jpeg_hw_reg.h
@@ -37,30 +37,25 @@
#define MSM_JPEG_HW_IRQ_STATUS_WE_CBCR_PINGPONG_MASK 0x00000020
#define MSM_JPEG_HW_IRQ_STATUS_WE_CBCR_PINGPONG_SHIFT 0x00000005
-#define MSM_JPEG_HW_IRQ_STATUS_WE_Y_BUFFER_OVERFLOW_MASK 0x00000040
-#define MSM_JPEG_HW_IRQ_STATUS_WE_Y_BUFFER_OVERFLOW_SHIFT 0x00000006
-
-#define MSM_JPEG_HW_IRQ_STATUS_WE_CBCR_BUFFER_OVERFLOW_MASK 0x00000080
-#define MSM_JPEG_HW_IRQ_STATUS_WE_CBCR_BUFFER_OVERFLOW_SHIFT 0x00000007
-
-#define MSM_JPEG_HW_IRQ_STATUS_WE_CH0_DATAFIFO_OVERFLOW_MASK 0x00000100
-#define MSM_JPEG_HW_IRQ_STATUS_WE_CH0_DATAFIFO_OVERFLOW_SHIFT 0x00000008
-
-#define MSM_JPEG_HW_IRQ_STATUS_WE_CH1_DATAFIFO_OVERFLOW_MASK 0x00000200
-#define MSM_JPEG_HW_IRQ_STATUS_WE_CH1_DATAFIFO_OVERFLOW_SHIFT 0x00000009
-
#define MSM_JPEG_HW_IRQ_STATUS_RESET_ACK_MASK 0x10000000
#define MSM_JPEG_HW_IRQ_STATUS_RESET_ACK_SHIFT 0x0000000a
#define MSM_JPEG_HW_IRQ_STATUS_BUS_ERROR_MASK 0x00000800
#define MSM_JPEG_HW_IRQ_STATUS_BUS_ERROR_SHIFT 0x0000000b
-#define MSM_JPEG_HW_IRQ_STATUS_VIOLATION_MASK 0x00001000
-#define MSM_JPEG_HW_IRQ_STATUS_VIOLATION_SHIFT 0x0000000c
+#define MSM_JPEG_HW_IRQ_STATUS_DCD_UNESCAPED_FF (0x1<<19)
+#define MSM_JPEG_HW_IRQ_STATUS_DCD_HUFFMAN_ERROR (0x1<<20)
+#define MSM_JPEG_HW_IRQ_STATUS_DCD_COEFFICIENT_ERR (0x1<<21)
+#define MSM_JPEG_HW_IRQ_STATUS_DCD_MISSING_BIT_STUFF (0x1<<22)
+#define MSM_JPEG_HW_IRQ_STATUS_DCD_SCAN_UNDERFLOW (0x1<<23)
+#define MSM_JPEG_HW_IRQ_STATUS_DCD_INVALID_RSM (0x1<<24)
+#define MSM_JPEG_HW_IRQ_STATUS_DCD_INVALID_RSM_SEQ (0x1<<25)
+#define MSM_JPEG_HW_IRQ_STATUS_DCD_MISSING_RSM (0x1<<26)
+#define MSM_JPEG_HW_IRQ_STATUS_VIOLATION_MASK (0x1<<29)
#define JPEG_OFFLINE_CMD_START 0x00000001
-#define JPEG_RESET_DEFAULT 0x00000003 /* cfff? */
+#define JPEG_RESET_DEFAULT 0x00020000
#define JPEG_IRQ_DISABLE_ALL 0x00000000
#define JPEG_IRQ_CLEAR_ALL 0xFFFFFFFF
@@ -87,6 +82,9 @@
#define JPEG_PLN1_WR_PNTR_ADDR (JPEG_REG_BASE + 0x000000D0)
#define JPEG_PLN1_WR_PNTR_BMSK 0xFFFFFFFF
+#define JPEG_PLN2_WR_PNTR_ADDR (JPEG_REG_BASE + 0x000000D4)
+#define JPEG_PLN2_WR_PNTR_BMSK 0xFFFFFFFF
+
#define JPEG_IRQ_MASK_ADDR (JPEG_REG_BASE + 0x00000018)
#define JPEG_IRQ_MASK_BMSK 0xFFFFFFFF
#define JPEG_IRQ_ALLSOURCES_ENABLE 0xFFFFFFFF
@@ -103,6 +101,11 @@
#define JPEG_ENCODE_OUTPUT_SIZE_STATUS_ADDR (JPEG_REG_BASE + 0x00000180)
#define JPEG_ENCODE_OUTPUT_SIZE_STATUS_BMSK 0x1FFFFFFF
+#define JPEG_DECODE_MCUS_DECODED_STATUS (JPEG_REG_BASE + 0x00000258)
+#define JPEG_DECODE_BITS_CONSUMED_STATUS (JPEG_REG_BASE + 0x0000025C)
+#define JPEG_DECODE_PRED_Y_STATE (JPEG_REG_BASE + 0x00000260)
+#define JPEG_DECODE_PRED_C_STATE (JPEG_REG_BASE + 0x00000264)
+#define JPEG_DECODE_RSM_STATE (JPEG_REG_BASE + 0x00000268)
#define VBIF_BASE_ADDRESS 0xFDA60000
#define VBIF_REGION_SIZE 0xC30
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_platform.c b/drivers/media/video/msm/jpeg_10/msm_jpeg_platform.c
index 981c56c..0370f63 100644
--- a/drivers/media/video/msm/jpeg_10/msm_jpeg_platform.c
+++ b/drivers/media/video/msm/jpeg_10/msm_jpeg_platform.c
@@ -26,36 +26,32 @@
#include "msm_jpeg_common.h"
#include "msm_jpeg_hw.h"
-/* AXI rate in KHz */
-struct ion_client *jpeg_client;
-static void *jpeg_vbif;
-
-void msm_jpeg_platform_p2v(struct file *file,
- struct ion_handle **ionhandle, int domain_num)
+void msm_jpeg_platform_p2v(struct msm_jpeg_device *pgmn_dev, struct file *file,
+ struct ion_handle **ionhandle, int domain_num)
{
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
- ion_unmap_iommu(jpeg_client, *ionhandle, domain_num, 0);
- ion_free(jpeg_client, *ionhandle);
+ ion_unmap_iommu(pgmn_dev->jpeg_client, *ionhandle, domain_num, 0);
+ ion_free(pgmn_dev->jpeg_client, *ionhandle);
*ionhandle = NULL;
#elif CONFIG_ANDROID_PMEM
put_pmem_file(file);
#endif
}
-uint32_t msm_jpeg_platform_v2p(int fd, uint32_t len, struct file **file_p,
- struct ion_handle **ionhandle, int domain_num)
-{
+uint32_t msm_jpeg_platform_v2p(struct msm_jpeg_device *pgmn_dev, int fd,
+ uint32_t len, struct file **file_p, struct ion_handle **ionhandle,
+ int domain_num) {
unsigned long paddr;
unsigned long size;
int rc;
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
- *ionhandle = ion_import_dma_buf(jpeg_client, fd);
+ *ionhandle = ion_import_dma_buf(pgmn_dev->jpeg_client, fd);
if (IS_ERR_OR_NULL(*ionhandle))
return 0;
- rc = ion_map_iommu(jpeg_client, *ionhandle, domain_num, 0,
- SZ_4K, 0, &paddr, (unsigned long *)&size, UNCACHED, 0);
- JPEG_DBG("%s:%d] addr 0x%x size %ld", __func__, __LINE__,
+ rc = ion_map_iommu(pgmn_dev->jpeg_client, *ionhandle, domain_num, 0,
+ SZ_4K, 0, &paddr, (unsigned long *)&size, UNCACHED,
+0); JPEG_DBG("%s:%d] addr 0x%x size %ld", __func__, __LINE__,
(uint32_t)paddr, size);
#elif CONFIG_ANDROID_PMEM
@@ -81,7 +77,7 @@
return paddr;
error1:
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
- ion_free(jpeg_client, *ionhandle);
+ ion_free(pgmn_dev->jpeg_client, *ionhandle);
#endif
return 0;
}
@@ -149,10 +145,10 @@
}
jpeg_irq = jpeg_irq_res->start;
JPEG_DBG("%s base address: 0x%x, jpeg irq number: %d\n", __func__,
- jpeg_mem->start, jpeg_irq);
+ jpeg_mem->start, jpeg_irq);
jpeg_io = request_mem_region(jpeg_mem->start,
- resource_size(jpeg_mem), pdev->name);
+ resource_size(jpeg_mem), pdev->name);
if (!jpeg_io) {
JPEG_PR_ERR("%s: region already claimed\n", __func__);
return -EBUSY;
@@ -165,14 +161,14 @@
goto fail1;
}
- jpeg_vbif = ioremap(VBIF_BASE_ADDRESS, VBIF_REGION_SIZE);
- if (!jpeg_vbif) {
+ pgmn_dev->jpeg_vbif = ioremap(VBIF_BASE_ADDRESS, VBIF_REGION_SIZE);
+ if (!pgmn_dev->jpeg_vbif) {
rc = -ENOMEM;
JPEG_PR_ERR("%s:%d] ioremap failed\n", __func__, __LINE__);
goto fail1;
}
JPEG_DBG("%s:%d] jpeg_vbif 0x%x", __func__, __LINE__,
- (uint32_t)jpeg_vbif);
+ (uint32_t)pgmn_dev->jpeg_vbif);
pgmn_dev->jpeg_fs = regulator_get(&pgmn_dev->pdev->dev, "vdd");
rc = regulator_enable(pgmn_dev->jpeg_fs);
@@ -202,9 +198,8 @@
(uint32_t)pgmn_dev->iommu_ctx_arr[i]);
}
#endif
- set_vbif_params(jpeg_vbif);
+ set_vbif_params(pgmn_dev->jpeg_vbif);
- msm_jpeg_hw_init(jpeg_base, resource_size(jpeg_mem));
rc = request_irq(jpeg_irq, handler, IRQF_TRIGGER_RISING, "jpeg",
context);
if (rc) {
@@ -218,7 +213,7 @@
*irq = jpeg_irq;
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
- jpeg_client = msm_ion_client_create(-1, "camera/jpeg");
+ pgmn_dev->jpeg_client = msm_ion_client_create(-1, "camera/jpeg");
#endif
JPEG_DBG("%s:%d] success\n", __func__, __LINE__);
@@ -276,11 +271,11 @@
regulator_disable(pgmn_dev->jpeg_fs);
pgmn_dev->jpeg_fs = NULL;
}
- iounmap(jpeg_vbif);
+ iounmap(pgmn_dev->jpeg_vbif);
iounmap(base);
release_mem_region(mem->start, resource_size(mem));
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
- ion_client_destroy(jpeg_client);
+ ion_client_destroy(pgmn_dev->jpeg_client);
#endif
JPEG_DBG("%s:%d] success\n", __func__, __LINE__);
return result;
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_platform.h b/drivers/media/video/msm/jpeg_10/msm_jpeg_platform.h
index 8a37cef..cd80d2e 100644
--- a/drivers/media/video/msm/jpeg_10/msm_jpeg_platform.h
+++ b/drivers/media/video/msm/jpeg_10/msm_jpeg_platform.h
@@ -18,12 +18,13 @@
#include <linux/ion.h>
#include <linux/iommu.h>
#include <mach/iommu.h>
+#include "msm_jpeg_sync.h"
-
-void msm_jpeg_platform_p2v(struct file *file,
- struct ion_handle **ionhandle, int domain_num);
-uint32_t msm_jpeg_platform_v2p(int fd, uint32_t len, struct file **file,
- struct ion_handle **ionhandle, int domain_num);
+void msm_jpeg_platform_p2v(struct msm_jpeg_device *pgmn_dev, struct file *file,
+ struct ion_handle **ionhandle, int domain_num);
+uint32_t msm_jpeg_platform_v2p(struct msm_jpeg_device *pgmn_dev, int fd,
+ uint32_t len, struct file **file, struct ion_handle **ionhandle,
+ int domain_num);
int msm_jpeg_platform_clk_enable(void);
int msm_jpeg_platform_clk_disable(void);
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_sync.c b/drivers/media/video/msm/jpeg_10/msm_jpeg_sync.c
index 6ac4a5e..a0aaf03 100644
--- a/drivers/media/video/msm/jpeg_10/msm_jpeg_sync.c
+++ b/drivers/media/video/msm/jpeg_10/msm_jpeg_sync.c
@@ -22,7 +22,9 @@
#include "msm_jpeg_platform.h"
#include "msm_jpeg_common.h"
-static int release_buf;
+#define JPEG_REG_SIZE 0x308
+#define JPEG_DEV_CNT 3
+#define JPEG_DEC_ID 2
inline void msm_jpeg_q_init(char const *name, struct msm_jpeg_q *q_p)
{
@@ -143,15 +145,15 @@
return 0;
}
-inline void msm_jpeg_outbuf_q_cleanup(struct msm_jpeg_q *q_p,
- int domain_num)
+inline void msm_jpeg_outbuf_q_cleanup(struct msm_jpeg_device *pgmn_dev,
+ struct msm_jpeg_q *q_p, int domain_num)
{
struct msm_jpeg_core_buf *buf_p;
JPEG_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
do {
buf_p = msm_jpeg_q_out(q_p);
if (buf_p) {
- msm_jpeg_platform_p2v(buf_p->file,
+ msm_jpeg_platform_p2v(pgmn_dev, buf_p->file,
&buf_p->handle, domain_num);
JPEG_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
kfree(buf_p);
@@ -289,10 +291,10 @@
if (buf_out) {
JPEG_DBG("%s:%d] 0x%08x %d\n", __func__, __LINE__,
(int) buf_out->y_buffer_addr, buf_out->y_len);
- rc = msm_jpeg_core_we_buf_update(buf_out);
+ rc = msm_jpeg_core_we_buf_update(pgmn_dev, buf_out);
kfree(buf_out);
} else {
- msm_jpeg_core_we_buf_reset(buf_in);
+ msm_jpeg_core_we_buf_reset(pgmn_dev, buf_in);
JPEG_DBG("%s:%d] no output buffer\n", __func__, __LINE__);
rc = -2;
}
@@ -320,7 +322,7 @@
}
buf_cmd = buf_p->vbuf;
- msm_jpeg_platform_p2v(buf_p->file, &buf_p->handle,
+ msm_jpeg_platform_p2v(pgmn_dev, buf_p->file, &buf_p->handle,
pgmn_dev->domain_num);
kfree(buf_p);
@@ -347,6 +349,7 @@
{
struct msm_jpeg_buf buf_cmd;
struct msm_jpeg_core_buf *buf_p;
+ memset(&buf_cmd, 0x0, sizeof(struct msm_jpeg_buf));
JPEG_DBG("%s:%d] Enter\n", __func__, __LINE__);
if (copy_from_user(&buf_cmd, arg, sizeof(struct msm_jpeg_buf))) {
@@ -364,7 +367,7 @@
__func__, __LINE__, (int) buf_cmd.vaddr, buf_cmd.y_len,
buf_cmd.fd);
- buf_p->y_buffer_addr = msm_jpeg_platform_v2p(buf_cmd.fd,
+ buf_p->y_buffer_addr = msm_jpeg_platform_v2p(pgmn_dev, buf_cmd.fd,
buf_cmd.y_len, &buf_p->file, &buf_p->handle,
pgmn_dev->domain_num);
if (!buf_p->y_buffer_addr) {
@@ -372,9 +375,18 @@
kfree(buf_p);
return -EFAULT;
}
- JPEG_DBG("%s:%d]After v2p y_address =0x%08x, handle = %p\n",
- __func__, __LINE__, buf_p->y_buffer_addr, buf_p->handle);
+
+ if (buf_cmd.cbcr_len)
+ buf_p->cbcr_buffer_addr = buf_p->y_buffer_addr +
+ buf_cmd.y_len;
+ else
+ buf_p->cbcr_buffer_addr = 0x0;
+
+ JPEG_DBG("%s:%d] After v2p pln0_addr =0x%x,pln0_len %d pl1_len %d",
+ __func__, __LINE__, buf_p->y_buffer_addr,
+ buf_cmd.y_len, buf_cmd.cbcr_len);
buf_p->y_len = buf_cmd.y_len;
+ buf_p->cbcr_len = buf_cmd.cbcr_len;
buf_p->vbuf = buf_cmd;
msm_jpeg_q_in(&pgmn_dev->output_buf_q, buf_p);
@@ -403,9 +415,9 @@
buf_out = msm_jpeg_q_out(&pgmn_dev->input_buf_q);
if (buf_out) {
- rc = msm_jpeg_core_fe_buf_update(buf_out);
+ rc = msm_jpeg_core_fe_buf_update(pgmn_dev, buf_out);
kfree(buf_out);
- msm_jpeg_core_fe_start();
+ msm_jpeg_core_fe_start(pgmn_dev);
} else {
JPEG_DBG("%s:%d] no input buffer\n", __func__, __LINE__);
rc = -EFAULT;
@@ -433,8 +445,8 @@
}
buf_cmd = buf_p->vbuf;
- msm_jpeg_platform_p2v(buf_p->file, &buf_p->handle,
- pgmn_dev->domain_num);
+ msm_jpeg_platform_p2v(pgmn_dev, buf_p->file, &buf_p->handle,
+ pgmn_dev->domain_num);
kfree(buf_p);
JPEG_DBG("%s:%d] 0x%08x %d\n", __func__, __LINE__,
@@ -460,6 +472,7 @@
{
struct msm_jpeg_core_buf *buf_p;
struct msm_jpeg_buf buf_cmd;
+ memset(&buf_cmd, 0x0, sizeof(struct msm_jpeg_buf));
if (copy_from_user(&buf_cmd, arg, sizeof(struct msm_jpeg_buf))) {
JPEG_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
@@ -475,20 +488,26 @@
JPEG_DBG("%s:%d] 0x%08x %d\n", __func__, __LINE__,
(int) buf_cmd.vaddr, buf_cmd.y_len);
- buf_p->y_buffer_addr = msm_jpeg_platform_v2p(buf_cmd.fd,
+ buf_p->y_buffer_addr = msm_jpeg_platform_v2p(pgmn_dev, buf_cmd.fd,
buf_cmd.y_len + buf_cmd.cbcr_len, &buf_p->file,
&buf_p->handle, pgmn_dev->domain_num) + buf_cmd.offset
+ buf_cmd.y_off;
buf_p->y_len = buf_cmd.y_len;
- buf_p->cbcr_buffer_addr = buf_p->y_buffer_addr + buf_cmd.y_len
- + buf_cmd.cbcr_off;
buf_p->cbcr_len = buf_cmd.cbcr_len;
buf_p->num_of_mcu_rows = buf_cmd.num_of_mcu_rows;
+ buf_p->y_len = buf_cmd.y_len;
+ buf_p->cbcr_len = buf_cmd.cbcr_len;
+ if (buf_cmd.cbcr_len)
+ buf_p->cbcr_buffer_addr = buf_p->y_buffer_addr + buf_cmd.y_len
+ + buf_cmd.cbcr_off;
+ else
+ buf_p->cbcr_buffer_addr = 0x0;
+
JPEG_DBG("%s: y_addr=%x, y_len=%x, cbcr_addr=%x, cbcr_len=%x, fd =%d\n",
__func__, buf_p->y_buffer_addr, buf_p->y_len,
buf_p->cbcr_buffer_addr, buf_p->cbcr_len, buf_cmd.fd);
- if (!buf_p->y_buffer_addr || !buf_p->cbcr_buffer_addr) {
+ if (!buf_p->y_buffer_addr) {
JPEG_PR_ERR("%s:%d] v2p wrong\n", __func__, __LINE__);
kfree(buf_p);
return -EFAULT;
@@ -559,13 +578,15 @@
JPEG_DBG("%s:%d] platform resources - mem %p, base %p, irq %d\n",
__func__, __LINE__,
pgmn_dev->mem, pgmn_dev->base, pgmn_dev->irq);
+ pgmn_dev->res_size = resource_size(pgmn_dev->mem);
msm_jpeg_q_cleanup(&pgmn_dev->evt_q);
msm_jpeg_q_cleanup(&pgmn_dev->output_rtn_q);
- msm_jpeg_outbuf_q_cleanup(&pgmn_dev->output_buf_q,
- pgmn_dev->domain_num); msm_jpeg_q_cleanup(&pgmn_dev->input_rtn_q);
+ msm_jpeg_outbuf_q_cleanup(pgmn_dev, &pgmn_dev->output_buf_q,
+ pgmn_dev->domain_num);
+ msm_jpeg_q_cleanup(&pgmn_dev->input_rtn_q);
msm_jpeg_q_cleanup(&pgmn_dev->input_buf_q);
- msm_jpeg_core_init();
+ msm_jpeg_core_init(pgmn_dev);
JPEG_DBG("%s:%d] success\n", __func__, __LINE__);
return rc;
@@ -583,13 +604,14 @@
pgmn_dev->open_count--;
mutex_unlock(&pgmn_dev->lock);
- msm_jpeg_core_release(release_buf, pgmn_dev->domain_num);
+ msm_jpeg_core_release(pgmn_dev, pgmn_dev->domain_num);
msm_jpeg_q_cleanup(&pgmn_dev->evt_q);
msm_jpeg_q_cleanup(&pgmn_dev->output_rtn_q);
- msm_jpeg_outbuf_q_cleanup(&pgmn_dev->output_buf_q,
- pgmn_dev->domain_num);
+ msm_jpeg_outbuf_q_cleanup(pgmn_dev, &pgmn_dev->output_buf_q,
+ pgmn_dev->domain_num);
msm_jpeg_q_cleanup(&pgmn_dev->input_rtn_q);
- msm_jpeg_outbuf_q_cleanup(&pgmn_dev->input_buf_q, pgmn_dev->domain_num);
+ msm_jpeg_outbuf_q_cleanup(pgmn_dev, &pgmn_dev->input_buf_q,
+ pgmn_dev->domain_num);
JPEG_DBG("%s:%d]\n", __func__, __LINE__);
if (pgmn_dev->open_count)
@@ -598,6 +620,7 @@
msm_jpeg_platform_release(pgmn_dev->mem, pgmn_dev->base,
pgmn_dev->irq, pgmn_dev);
+ JPEG_DBG("%s:%d]\n", __func__, __LINE__);
return 0;
}
@@ -612,7 +635,8 @@
return -EFAULT;
}
- is_copy_to_user = msm_jpeg_hw_exec_cmds(&hw_cmd, 1);
+ is_copy_to_user = msm_jpeg_hw_exec_cmds(&hw_cmd, 1,
+ pgmn_dev->res_size, pgmn_dev->base);
JPEG_DBG("%s:%d] type %d, n %d, offset %d, mask %x, data %x,pdata %x\n",
__func__, __LINE__, hw_cmd.type, hw_cmd.n, hw_cmd.offset,
hw_cmd.mask, hw_cmd.data, (int) hw_cmd.pdata);
@@ -657,7 +681,8 @@
hw_cmd_p = (struct msm_jpeg_hw_cmd *) &(hw_cmds_p->hw_cmd);
- is_copy_to_user = msm_jpeg_hw_exec_cmds(hw_cmd_p, m);
+ is_copy_to_user = msm_jpeg_hw_exec_cmds(hw_cmd_p, m,
+ pgmn_dev->res_size, pgmn_dev->base);
if (is_copy_to_user >= 0) {
if (copy_to_user(arg, hw_cmds_p, len)) {
@@ -678,12 +703,12 @@
JPEG_DBG("%s:%d] Enter\n", __func__, __LINE__);
- release_buf = 1;
+ pgmn_dev->release_buf = 1;
for (i = 0; i < 2; i++) {
buf_out = msm_jpeg_q_out(&pgmn_dev->input_buf_q);
if (buf_out) {
- msm_jpeg_core_fe_buf_update(buf_out);
+ msm_jpeg_core_fe_buf_update(pgmn_dev, buf_out);
kfree(buf_out);
} else {
JPEG_DBG("%s:%d] no input buffer\n", __func__,
@@ -696,8 +721,8 @@
buf_out_free[i] = msm_jpeg_q_out(&pgmn_dev->output_buf_q);
if (buf_out_free[i]) {
- msm_jpeg_core_we_buf_update(buf_out_free[i]);
- release_buf = 0;
+ msm_jpeg_core_we_buf_update(pgmn_dev, buf_out_free[i]);
+ pgmn_dev->release_buf = 0;
} else {
JPEG_DBG("%s:%d] no output buffer\n",
__func__, __LINE__);
@@ -708,6 +733,7 @@
for (i = 0; i < 2; i++)
kfree(buf_out_free[i]);
+ msm_jpeg_io_dump(pgmn_dev->base, JPEG_REG_SIZE);
rc = msm_jpeg_ioctl_hw_cmds(pgmn_dev, arg);
JPEG_DBG("%s:%d]\n", __func__, __LINE__);
return rc;
@@ -727,7 +753,7 @@
pgmn_dev->op_mode = ctrl_cmd.type;
- rc = msm_jpeg_core_reset(pgmn_dev->op_mode, pgmn_dev->base,
+ rc = msm_jpeg_core_reset(pgmn_dev, pgmn_dev->op_mode, pgmn_dev->base,
resource_size(pgmn_dev->mem));
return rc;
}
@@ -736,7 +762,7 @@
unsigned long arg)
{
JPEG_DBG("%s:%d] Enter\n", __func__, __LINE__);
- msm_jpeg_io_dump(arg);
+ msm_jpeg_io_dump(pgmn_dev->base, JPEG_REG_SIZE);
return 0;
}
@@ -836,9 +862,10 @@
int __msm_jpeg_init(struct msm_jpeg_device *pgmn_dev)
{
- int rc = 0, i = 0;
+ int rc = 0, i = 0, j = 0;
int idx = 0;
- char *iommu_name[3] = {"jpeg_enc0", "jpeg_enc1", "jpeg_dec"};
+ char *iommu_name[JPEG_DEV_CNT] = {"jpeg_enc0", "jpeg_enc1",
+ "jpeg_dec"};
mutex_init(&pgmn_dev->lock);
@@ -847,6 +874,7 @@
idx = pgmn_dev->pdev->id;
pgmn_dev->idx = idx;
pgmn_dev->iommu_cnt = 1;
+ pgmn_dev->decode_flag = (idx == JPEG_DEC_ID);
msm_jpeg_q_init("evt_q", &pgmn_dev->evt_q);
msm_jpeg_q_init("output_rtn_q", &pgmn_dev->output_rtn_q);
@@ -855,21 +883,23 @@
msm_jpeg_q_init("input_buf_q", &pgmn_dev->input_buf_q);
#ifdef CONFIG_MSM_IOMMU
-/*get device context for IOMMU*/
+ j = (pgmn_dev->iommu_cnt <= 1) ? idx : 0;
+ /*get device context for IOMMU*/
for (i = 0; i < pgmn_dev->iommu_cnt; i++) {
- pgmn_dev->iommu_ctx_arr[i] = msm_iommu_get_ctx(iommu_name[i]);
- JPEG_DBG("%s:%d] name %s", __func__, __LINE__, iommu_name[i]);
+ pgmn_dev->iommu_ctx_arr[i] = msm_iommu_get_ctx(iommu_name[j]);
+ JPEG_DBG("%s:%d] name %s", __func__, __LINE__, iommu_name[j]);
JPEG_DBG("%s:%d] ctx 0x%x", __func__, __LINE__,
- (uint32_t)pgmn_dev->iommu_ctx_arr[i]);
+ (uint32_t)pgmn_dev->iommu_ctx_arr[i]);
if (!pgmn_dev->iommu_ctx_arr[i]) {
JPEG_PR_ERR("%s: No iommu fw context found\n",
__func__);
goto error;
}
+ j++;
}
pgmn_dev->domain_num = camera_register_domain();
JPEG_DBG("%s:%d] dom_num 0x%x", __func__, __LINE__,
- pgmn_dev->domain_num);
+ pgmn_dev->domain_num);
if (pgmn_dev->domain_num < 0) {
JPEG_PR_ERR("%s: could not register domain\n", __func__);
goto error;
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_sync.h b/drivers/media/video/msm/jpeg_10/msm_jpeg_sync.h
index 1d82060..1ac4838 100644
--- a/drivers/media/video/msm/jpeg_10/msm_jpeg_sync.h
+++ b/drivers/media/video/msm/jpeg_10/msm_jpeg_sync.h
@@ -21,7 +21,7 @@
#include <linux/platform_device.h>
#include <media/v4l2-device.h>
#include <media/v4l2-subdev.h>
-#include "msm_jpeg_core.h"
+#include "msm_jpeg_hw.h"
#define JPEG_7X 0x1
#define JPEG_8X60 (0x1 << 1)
@@ -88,6 +88,17 @@
struct iommu_domain *domain;
struct device *iommu_ctx_arr[3];
int iommu_cnt;
+ int decode_flag;
+ struct ion_client *jpeg_client;
+ void *jpeg_vbif;
+ int release_buf;
+ struct msm_jpeg_hw_pingpong fe_pingpong_buf;
+ struct msm_jpeg_hw_pingpong we_pingpong_buf;
+ int we_pingpong_index;
+ int reset_done_ack;
+ spinlock_t reset_lock;
+ wait_queue_head_t reset_wait;
+ uint32_t res_size;
};
int __msm_jpeg_open(struct msm_jpeg_device *pgmn_dev);
diff --git a/drivers/media/video/msm_vidc/msm_venc.c b/drivers/media/video/msm_vidc/msm_venc.c
index 6c0f224..c137c08 100644
--- a/drivers/media/video/msm_vidc/msm_venc.c
+++ b/drivers/media/video/msm_vidc/msm_venc.c
@@ -95,7 +95,7 @@
.type = V4L2_CTRL_TYPE_INTEGER,
.minimum = MIN_FRAME_RATE,
.maximum = MAX_FRAME_RATE,
- .default_value = DEFAULT_FRAME_RATE,
+ .default_value = MIN_FRAME_RATE,
.step = 1,
.menu_skip_mask = 0,
.qmenu = NULL,
diff --git a/drivers/net/usb/rmnet_usb_ctrl.c b/drivers/net/usb/rmnet_usb_ctrl.c
index ba16ed9..7ed8ffa 100644
--- a/drivers/net/usb/rmnet_usb_ctrl.c
+++ b/drivers/net/usb/rmnet_usb_ctrl.c
@@ -122,6 +122,55 @@
return 0;
}
+static void get_encap_work(struct work_struct *w)
+{
+ struct usb_device *udev;
+ struct rmnet_ctrl_dev *dev =
+ container_of(w, struct rmnet_ctrl_dev, get_encap_work);
+ int status;
+
+ udev = interface_to_usbdev(dev->intf);
+
+ status = usb_autopm_get_interface(dev->intf);
+ if (status < 0 && status != -EAGAIN && status != -EACCES) {
+ dev->get_encap_failure_cnt++;
+ return;
+ }
+
+ usb_fill_control_urb(dev->rcvurb, udev,
+ usb_rcvctrlpipe(udev, 0),
+ (unsigned char *)dev->in_ctlreq,
+ dev->rcvbuf,
+ DEFAULT_READ_URB_LENGTH,
+ resp_avail_cb, dev);
+
+
+ usb_anchor_urb(dev->rcvurb, &dev->rx_submitted);
+ status = usb_submit_urb(dev->rcvurb, GFP_KERNEL);
+ if (status) {
+ dev->get_encap_failure_cnt++;
+ usb_unanchor_urb(dev->rcvurb);
+ usb_autopm_put_interface(dev->intf);
+ dev_err(dev->devicep,
+ "%s: Error submitting Read URB %d\n", __func__, status);
+ goto resubmit_int_urb;
+ }
+
+ return;
+
+resubmit_int_urb:
+ /*check if it is already submitted in resume*/
+ if (!dev->inturb->anchor) {
+ usb_anchor_urb(dev->inturb, &dev->rx_submitted);
+ status = usb_submit_urb(dev->inturb, GFP_KERNEL);
+ if (status) {
+ usb_unanchor_urb(dev->inturb);
+ dev_err(dev->devicep, "%s: Error re-submitting Int URB %d\n",
+ __func__, status);
+ }
+ }
+}
+
static void notification_available_cb(struct urb *urb)
{
int status;
@@ -133,12 +182,13 @@
switch (urb->status) {
case 0:
+ /*if non zero lenght of data received while unlink*/
+ case -ENOENT:
/*success*/
break;
/*do not resubmit*/
case -ESHUTDOWN:
- case -ENOENT:
case -ECONNRESET:
case -EPROTO:
return;
@@ -156,26 +206,17 @@
goto resubmit_int_urb;
}
+ if (!urb->actual_length)
+ return;
+
ctrl = urb->transfer_buffer;
switch (ctrl->bNotificationType) {
case USB_CDC_NOTIFY_RESPONSE_AVAILABLE:
dev->resp_avail_cnt++;
- usb_fill_control_urb(dev->rcvurb, udev,
- usb_rcvctrlpipe(udev, 0),
- (unsigned char *)dev->in_ctlreq,
- dev->rcvbuf,
- DEFAULT_READ_URB_LENGTH,
- resp_avail_cb, dev);
-
- status = usb_submit_urb(dev->rcvurb, GFP_ATOMIC);
- if (status) {
- dev_err(dev->devicep,
- "%s: Error submitting Read URB %d\n", __func__, status);
- goto resubmit_int_urb;
- }
usb_mark_last_busy(udev);
+ queue_work(dev->wq, &dev->get_encap_work);
if (!dev->resp_available) {
dev->resp_available = true;
@@ -189,10 +230,13 @@
}
resubmit_int_urb:
+ usb_anchor_urb(urb, &dev->rx_submitted);
status = usb_submit_urb(urb, GFP_ATOMIC);
- if (status)
+ if (status) {
+ usb_unanchor_urb(urb);
dev_err(dev->devicep, "%s: Error re-submitting Int URB %d\n",
__func__, status);
+ }
return;
}
@@ -208,6 +252,8 @@
udev = interface_to_usbdev(dev->intf);
+ usb_autopm_put_interface_async(dev->intf);
+
switch (urb->status) {
case 0:
/*success*/
@@ -263,41 +309,41 @@
wake_up(&dev->read_wait_queue);
resubmit_int_urb:
- /*re-submit int urb to check response available*/
- usb_mark_last_busy(udev);
- status = usb_submit_urb(dev->inturb, GFP_ATOMIC);
- if (status)
- dev_err(dev->devicep, "%s: Error re-submitting Int URB %d\n",
- __func__, status);
+ /*check if it is already submitted in resume*/
+ if (!dev->inturb->anchor) {
+ usb_mark_last_busy(udev);
+ usb_anchor_urb(dev->inturb, &dev->rx_submitted);
+ status = usb_submit_urb(dev->inturb, GFP_ATOMIC);
+ if (status) {
+ usb_unanchor_urb(dev->inturb);
+ dev_err(dev->devicep, "%s: Error re-submitting Int URB %d\n",
+ __func__, status);
+ }
+ }
}
int rmnet_usb_ctrl_start_rx(struct rmnet_ctrl_dev *dev)
{
int retval = 0;
+ usb_anchor_urb(dev->inturb, &dev->rx_submitted);
retval = usb_submit_urb(dev->inturb, GFP_KERNEL);
- if (retval < 0)
- dev_err(dev->devicep, "%s Intr submit %d\n", __func__, retval);
+ if (retval < 0) {
+ usb_unanchor_urb(dev->inturb);
+ dev_err(dev->devicep, "%s Intr submit %d\n", __func__,
+ retval);
+ }
return retval;
}
-int rmnet_usb_ctrl_stop_rx(struct rmnet_ctrl_dev *dev)
+int rmnet_usb_ctrl_suspend(struct rmnet_ctrl_dev *dev)
{
- if (!is_dev_connected(dev)) {
- dev_dbg(dev->devicep, "%s: Ctrl device disconnected\n",
- __func__);
- return -ENODEV;
- }
-
- dev_dbg(dev->devicep, "%s\n", __func__);
-
- usb_kill_urb(dev->rcvurb);
- usb_kill_urb(dev->inturb);
+ if (!flush_work_sync(&dev->get_encap_work))
+ usb_kill_anchored_urbs(&dev->rx_submitted);
return 0;
}
-
static int rmnet_usb_ctrl_alloc_rx(struct rmnet_ctrl_dev *dev)
{
int retval = -ENOMEM;
@@ -826,7 +872,6 @@
void rmnet_usb_ctrl_disconnect(struct rmnet_ctrl_dev *dev)
{
- rmnet_usb_ctrl_stop_rx(dev);
mutex_lock(&dev->dev_lock);
@@ -839,13 +884,16 @@
wake_up(&dev->read_wait_queue);
+ cancel_work_sync(&dev->get_encap_work);
+
+ usb_kill_anchored_urbs(&dev->tx_submitted);
+ usb_kill_anchored_urbs(&dev->rx_submitted);
+
usb_free_urb(dev->inturb);
dev->inturb = NULL;
kfree(dev->intbuf);
dev->intbuf = NULL;
-
- usb_kill_anchored_urbs(&dev->tx_submitted);
}
#if defined(CONFIG_DEBUG_FS)
@@ -879,6 +927,7 @@
"cbits_tomdm: %d\n"
"mdm_wait_timeout: %u\n"
"zlp_cnt: %u\n"
+ "get_encap_failure_cnt %u\n"
"dev opened: %s\n",
dev, dev->name,
dev->snd_encap_cmd_cnt,
@@ -890,6 +939,7 @@
dev->cbits_tomdm,
dev->mdm_wait_timeout,
dev->zlp_cnt,
+ dev->get_encap_failure_cnt,
dev->is_opened ? "OPEN" : "CLOSE");
}
@@ -968,12 +1018,21 @@
/*for debug purpose*/
snprintf(dev->name, CTRL_DEV_MAX_LEN, "hsicctl%d", n);
+ dev->wq = create_singlethread_workqueue(dev->name);
+ if (!dev->wq) {
+ pr_err("unable to allocate workqueue");
+ kfree(dev);
+ goto error0;
+ }
+
mutex_init(&dev->dev_lock);
spin_lock_init(&dev->rx_lock);
init_waitqueue_head(&dev->read_wait_queue);
init_waitqueue_head(&dev->open_wait_queue);
INIT_LIST_HEAD(&dev->rx_list);
init_usb_anchor(&dev->tx_submitted);
+ init_usb_anchor(&dev->rx_submitted);
+ INIT_WORK(&dev->get_encap_work, get_encap_work);
status = rmnet_usb_ctrl_alloc_rx(dev);
if (status < 0) {
@@ -1074,6 +1133,7 @@
device_remove_file(ctrl_dev[i]->devicep, &dev_attr_modem_wait);
#endif
cdev_del(&ctrl_dev[i]->cdev);
+ destroy_workqueue(ctrl_dev[i]->wq);
kfree(ctrl_dev[i]);
ctrl_dev[i] = NULL;
device_destroy(ctrldev_classp, MKDEV(MAJOR(ctrldev_num), i));
diff --git a/drivers/net/usb/rmnet_usb_ctrl.h b/drivers/net/usb/rmnet_usb_ctrl.h
index 7a84817..a8f8079 100644
--- a/drivers/net/usb/rmnet_usb_ctrl.h
+++ b/drivers/net/usb/rmnet_usb_ctrl.h
@@ -34,6 +34,7 @@
struct urb *rcvurb;
struct urb *inturb;
struct usb_anchor tx_submitted;
+ struct usb_anchor rx_submitted;
void *rcvbuf;
void *intbuf;
struct usb_ctrlrequest *in_ctlreq;
@@ -44,6 +45,9 @@
wait_queue_head_t read_wait_queue;
wait_queue_head_t open_wait_queue;
+ struct workqueue_struct *wq;
+ struct work_struct get_encap_work;
+
unsigned is_opened;
bool is_connected;
@@ -66,6 +70,7 @@
unsigned int snd_encap_cmd_cnt;
unsigned int get_encap_resp_cnt;
unsigned int resp_avail_cnt;
+ unsigned int get_encap_failure_cnt;
unsigned int set_ctrl_line_state_cnt;
unsigned int tx_ctrl_err_cnt;
unsigned int zlp_cnt;
@@ -74,7 +79,7 @@
extern struct rmnet_ctrl_dev *ctrl_dev[];
extern int rmnet_usb_ctrl_start_rx(struct rmnet_ctrl_dev *);
-extern int rmnet_usb_ctrl_stop_rx(struct rmnet_ctrl_dev *);
+extern int rmnet_usb_ctrl_suspend(struct rmnet_ctrl_dev *dev);
extern int rmnet_usb_ctrl_init(void);
extern void rmnet_usb_ctrl_exit(void);
extern int rmnet_usb_ctrl_probe(struct usb_interface *intf,
diff --git a/drivers/net/usb/rmnet_usb_data.c b/drivers/net/usb/rmnet_usb_data.c
index b8c6140..17ff067 100644
--- a/drivers/net/usb/rmnet_usb_data.c
+++ b/drivers/net/usb/rmnet_usb_data.c
@@ -87,7 +87,6 @@
{
struct usbnet *unet;
struct rmnet_ctrl_dev *dev;
- int time = 0;
int retval = 0;
unet = usb_get_intfdata(iface);
@@ -107,19 +106,12 @@
retval = usbnet_suspend(iface, message);
if (!retval) {
- if (message.event & PM_EVENT_SUSPEND) {
- time = usb_wait_anchor_empty_timeout(&dev->tx_submitted,
- 1000);
- if (!time)
- usb_kill_anchored_urbs(&dev->tx_submitted);
-
- retval = rmnet_usb_ctrl_stop_rx(dev);
- iface->dev.power.power_state.event = message.event;
- }
- /* TBD : do we need to set/clear usbnet->udev->reset_resume*/
- } else
+ retval = rmnet_usb_ctrl_suspend(dev);
+ iface->dev.power.power_state.event = message.event;
+ } else {
dev_dbg(&iface->dev,
"%s: device is busy can not suspend\n", __func__);
+ }
fail:
return retval;
diff --git a/drivers/tty/smux_ctl.c b/drivers/tty/smux_ctl.c
index 7e0e6f8..c17495b 100644
--- a/drivers/tty/smux_ctl.c
+++ b/drivers/tty/smux_ctl.c
@@ -770,12 +770,13 @@
poll_wait(file, &devp->read_wait_queue, wait);
readable = smux_ctl_readable(devp->id);
- if (readable < 0) {
+ if (readable > 0) {
+ mask = POLLIN | POLLRDNORM;
+ } else if ((readable < 0) && (readable != -ERESTARTSYS)) {
+ /* error case (non-signal) received */
pr_err(SMUX_CTL_MODULE_NAME ": %s err%d during poll for smuxctl%d\n",
__func__, readable, devp->id);
mask = POLLERR;
- } else if (readable) {
- mask = POLLIN | POLLRDNORM;
}
return mask;
diff --git a/drivers/usb/gadget/u_data_hsic.c b/drivers/usb/gadget/u_data_hsic.c
index 89d2887..746c041 100644
--- a/drivers/usb/gadget/u_data_hsic.c
+++ b/drivers/usb/gadget/u_data_hsic.c
@@ -220,6 +220,7 @@
req->context = skb;
req->buf = skb->data;
req->length = skb->len;
+ req->zero = 1;
port->n_tx_req_queued++;
if (port->n_tx_req_queued == ghsic_data_tx_intr_thld) {
diff --git a/drivers/usb/host/ehci-msm-hsic.c b/drivers/usb/host/ehci-msm-hsic.c
index fee7a09..b7f1878 100644
--- a/drivers/usb/host/ehci-msm-hsic.c
+++ b/drivers/usb/host/ehci-msm-hsic.c
@@ -659,12 +659,6 @@
return 0;
}
- if (!(readl_relaxed(USB_PORTSC) & PORT_PE)) {
- dev_dbg(mehci->dev, "%s:port is not enabled skip suspend\n",
- __func__);
- return -EAGAIN;
- }
-
disable_irq(hcd->irq);
/* make sure we don't race against a remote wakeup */
@@ -934,6 +928,15 @@
static int ehci_hsic_bus_suspend(struct usb_hcd *hcd)
{
+ struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
+
+ if (!(readl_relaxed(USB_PORTSC) & PORT_PE)) {
+ dbg_log_event(NULL, "RH suspend attempt failed", 0);
+ dev_dbg(mehci->dev, "%s:port is not enabled skip suspend\n",
+ __func__);
+ return -EAGAIN;
+ }
+
dbg_log_event(NULL, "Suspend RH", 0);
return ehci_bus_suspend(hcd);
}
diff --git a/drivers/video/msm/mipi_NT35510.c b/drivers/video/msm/mipi_NT35510.c
index 0c6ff79..d75198a 100644
--- a/drivers/video/msm/mipi_NT35510.c
+++ b/drivers/video/msm/mipi_NT35510.c
@@ -32,8 +32,8 @@
static char write_ram[2] = {0x2c, 0x00}; /* write ram */
static struct dsi_cmd_desc nt35510_display_off_cmds[] = {
- {DTYPE_DCS_WRITE, 1, 0, 0, 150, sizeof(display_off), display_off},
- {DTYPE_DCS_WRITE, 1, 0, 0, 150, sizeof(enter_sleep), enter_sleep}
+ {DTYPE_DCS_WRITE, 1, 0, 0, 50, sizeof(display_off), display_off},
+ {DTYPE_DCS_WRITE, 1, 0, 0, 50, sizeof(enter_sleep), enter_sleep}
};
static char cmd0[6] = {
@@ -213,46 +213,46 @@
};
static char config_MADCTL[2] = {0x36, 0x00};
static struct dsi_cmd_desc nt35510_cmd_display_on_cmds[] = {
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd0), cmd0},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd1), cmd1},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd2), cmd2},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd3), cmd3},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd4), cmd4},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd5), cmd5},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd6), cmd6},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd7), cmd7},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd8), cmd8},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd9), cmd9},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd10), cmd10},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd11), cmd11},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd12), cmd12},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd13), cmd13},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd14), cmd14},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd15), cmd15},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd16), cmd16},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd17), cmd17},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd18), cmd18},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd19), cmd19},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd20), cmd20},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd21), cmd21},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd22), cmd22},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd23), cmd23},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd24), cmd24},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd25), cmd25},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd26), cmd26},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd27), cmd27},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd0), cmd0},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd1), cmd1},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd2), cmd2},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd3), cmd3},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd4), cmd4},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd5), cmd5},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd6), cmd6},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd7), cmd7},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd8), cmd8},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd9), cmd9},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd10), cmd10},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd11), cmd11},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd12), cmd12},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd13), cmd13},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd14), cmd14},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd15), cmd15},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd16), cmd16},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd17), cmd17},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd18), cmd18},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd19), cmd19},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd20), cmd20},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd21), cmd21},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd22), cmd22},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd23), cmd23},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd24), cmd24},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd25), cmd25},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd26), cmd26},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(cmd27), cmd27},
- {DTYPE_DCS_WRITE, 1, 0, 0, 150, sizeof(exit_sleep), exit_sleep},
- {DTYPE_DCS_WRITE, 1, 0, 0, 10, sizeof(display_on), display_on},
+ {DTYPE_DCS_WRITE, 1, 0, 0, 0, sizeof(exit_sleep), exit_sleep},
+ {DTYPE_DCS_WRITE, 1, 0, 0, 0, sizeof(display_on), display_on},
- {DTYPE_DCS_WRITE1, 1, 0, 0, 150,
+ {DTYPE_DCS_WRITE1, 1, 0, 0, 0,
sizeof(config_MADCTL), config_MADCTL},
- {DTYPE_DCS_WRITE, 1, 0, 0, 10, sizeof(write_ram), write_ram},
+ {DTYPE_DCS_WRITE, 1, 0, 0, 0, sizeof(write_ram), write_ram},
};
static struct dsi_cmd_desc nt35510_cmd_display_on_cmds_rotate[] = {
- {DTYPE_DCS_LWRITE, 1, 0, 0, 50,
+ {DTYPE_DCS_LWRITE, 1, 0, 0, 0,
sizeof(cmd19_rotate), cmd19_rotate},
};
@@ -430,34 +430,34 @@
};
static char config_video_MADCTL[2] = {0x36, 0xC0};
static struct dsi_cmd_desc nt35510_video_display_on_cmds[] = {
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video0), video0},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video1), video1},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video2), video2},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video3), video3},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video4), video4},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video5), video5},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video6), video6},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video7), video7},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video8), video8},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video9), video9},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video10), video10},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video11), video11},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video12), video12},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video13), video13},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video14), video14},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video15), video15},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video16), video16},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video17), video17},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video18), video18},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video19), video19},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video20), video20},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video21), video21},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video22), video22},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video23), video23},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video24), video24},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video25), video25},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video26), video26},
- {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video27), video27},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video0), video0},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video1), video1},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video2), video2},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video3), video3},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video4), video4},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video5), video5},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video6), video6},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video7), video7},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video8), video8},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video9), video9},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video10), video10},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video11), video11},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video12), video12},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video13), video13},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video14), video14},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video15), video15},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video16), video16},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video17), video17},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video18), video18},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video19), video19},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video20), video20},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video21), video21},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video22), video22},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video23), video23},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video24), video24},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video25), video25},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video26), video26},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(video27), video27},
{DTYPE_DCS_WRITE, 1, 0, 0, NT35510_SLEEP_OFF_DELAY, sizeof(exit_sleep),
exit_sleep},
{DTYPE_DCS_WRITE, 1, 0, 0, NT35510_DISPLAY_ON_DELAY, sizeof(display_on),
@@ -465,7 +465,7 @@
};
static struct dsi_cmd_desc nt35510_video_display_on_cmds_rotate[] = {
- {DTYPE_DCS_WRITE1, 1, 0, 0, 150,
+ {DTYPE_DCS_WRITE1, 1, 0, 0, 0,
sizeof(config_video_MADCTL), config_video_MADCTL},
};
static int mipi_nt35510_lcd_on(struct platform_device *pdev)
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
index 4f19de9..d94bc5b 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
@@ -1258,6 +1258,8 @@
output_vcd_frm->flags |=
VCD_FRAME_FLAG_DATACORRUPT;
}
+ if (decoder->codec.codec != VCD_CODEC_H264)
+ output_vcd_frm->flags &= ~VCD_FRAME_FLAG_DATACORRUPT;
output_vcd_frm->ip_frm_tag = dec_disp_info->tag_top;
vidc_sm_get_picture_times(&ddl->shared_mem
[ddl->command_channel],
diff --git a/include/linux/msm_kgsl.h b/include/linux/msm_kgsl.h
index 2253655..71ff639 100644
--- a/include/linux/msm_kgsl.h
+++ b/include/linux/msm_kgsl.h
@@ -2,7 +2,7 @@
#define _MSM_KGSL_H
#define KGSL_VERSION_MAJOR 3
-#define KGSL_VERSION_MINOR 11
+#define KGSL_VERSION_MINOR 12
/*context flags */
#define KGSL_CONTEXT_SAVE_GMEM 0x00000001
@@ -432,7 +432,8 @@
/*
* A timestamp event allows the user space to register an action following an
- * expired timestamp.
+ * expired timestamp. Note IOCTL_KGSL_TIMESTAMP_EVENT has been redefined to
+ * _IOWR to support fences which need to return a fd for the priv parameter.
*/
struct kgsl_timestamp_event {
@@ -443,7 +444,7 @@
size_t len; /* Size of the event specific blob */
};
-#define IOCTL_KGSL_TIMESTAMP_EVENT \
+#define IOCTL_KGSL_TIMESTAMP_EVENT_OLD \
_IOW(KGSL_IOC_TYPE, 0x31, struct kgsl_timestamp_event)
/* A genlock timestamp event releases an existing lock on timestamp expire */
@@ -454,6 +455,14 @@
int handle; /* Handle of the genlock lock to release */
};
+/* A fence timestamp event releases an existing lock on timestamp expire */
+
+#define KGSL_TIMESTAMP_EVENT_FENCE 2
+
+struct kgsl_timestamp_event_fence {
+ int fence_fd; /* Fence to signal */
+};
+
/*
* Set a property within the kernel. Uses the same structure as
* IOCTL_KGSL_GETPROPERTY
@@ -462,6 +471,9 @@
#define IOCTL_KGSL_SETPROPERTY \
_IOW(KGSL_IOC_TYPE, 0x32, struct kgsl_device_getproperty)
+#define IOCTL_KGSL_TIMESTAMP_EVENT \
+ _IOWR(KGSL_IOC_TYPE, 0x33, struct kgsl_timestamp_event)
+
#ifdef __KERNEL__
#ifdef CONFIG_MSM_KGSL_DRM
int kgsl_gem_obj_addr(int drm_fd, int handle, unsigned long *start,
diff --git a/include/media/msm_jpeg.h b/include/media/msm_jpeg.h
index 11c3247..56829f1 100644
--- a/include/media/msm_jpeg.h
+++ b/include/media/msm_jpeg.h
@@ -85,6 +85,8 @@
uint32_t num_of_mcu_rows;
uint32_t offset;
+ uint32_t pln2_off;
+ uint32_t pln2_len;
};
#define MSM_JPEG_HW_CMD_TYPE_READ 0