summaryrefslogtreecommitdiff
path: root/drivers/media/platform/imx8/mxc-jpeg.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/platform/imx8/mxc-jpeg.c')
-rw-r--r--drivers/media/platform/imx8/mxc-jpeg.c349
1 files changed, 230 insertions, 119 deletions
diff --git a/drivers/media/platform/imx8/mxc-jpeg.c b/drivers/media/platform/imx8/mxc-jpeg.c
index fc6cb0f504d9..efa4cee94e43 100644
--- a/drivers/media/platform/imx8/mxc-jpeg.c
+++ b/drivers/media/platform/imx8/mxc-jpeg.c
@@ -101,8 +101,8 @@ static const unsigned char hactbl[615] = {
0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
-0xFF, 0xC0, 0x00, 0x11, 0x08, 0x01, 0x00,
-0x01, 0x00, 0x03, 0x01, 0x11, 0x00, 0x02,
+0xFF, 0xC0, 0x00, 0x11, 0x08, 0x00, 0x40,
+0x00, 0x40, 0x03, 0x01, 0x21, 0x00, 0x02,
0x11, 0x01, 0x03, 0x11, 0x01, 0xFF, 0xC4,
0x01, 0xA2, 0x00, 0x00, 0x01, 0x05, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
@@ -169,16 +169,21 @@ static const unsigned char hactbl[615] = {
0x11, 0x00, 0x3F, 0x00, 0xFF, 0xD9
};
-struct mxc_jpeg_src_buf {
- struct vb2_v4l2_buffer b;
- struct list_head list;
- struct mxc_jpeg_desc *desc;
- void *tbl;
- int flags;
- dma_addr_t handle;
- dma_addr_t cfg_handle;
- dma_addr_t tbl_handle;
-};
+static void print_buf(struct device *dev, struct vb2_buffer *buf)
+{
+ void *testaddri;
+ char *data;
+ u32 dma_addr;
+
+ testaddri = vb2_plane_vaddr(buf, 0);
+ dma_addr = vb2_dma_contig_plane_dma_addr(buf, 0);
+ data = (char *)testaddri;
+
+ /* print just the first 4 bytes from the beginning of the buffer */
+ dev_dbg(dev, "vaddr=%p dma_addr=%x: %x %x %x %x ...\n",
+ testaddri, dma_addr,
+ data[0], data[1], data[2], data[3]);
+}
#define MXC_NUM_FORMATS ARRAY_SIZE(mxc_formats)
static inline u32 mxc_jpeg_align(u32 val, u32 align)
@@ -192,11 +197,6 @@ static inline struct mxc_jpeg_ctx *mxc_jpeg_fh_to_ctx(struct v4l2_fh *fh)
return container_of(fh, struct mxc_jpeg_ctx, fh);
}
-static inline struct mxc_jpeg_src_buf *mxc_jpeg_vb2_to_srcbuf(
- struct vb2_buffer *vb)
-{
- return container_of(to_vb2_v4l2_buffer(vb), struct mxc_jpeg_src_buf, b);
-}
static int enum_fmt(struct mxc_jpeg_fmt *mxc_formats, int n,
struct v4l2_fmtdesc *f, u32 type)
@@ -225,14 +225,14 @@ static int enum_fmt(struct mxc_jpeg_fmt *mxc_formats, int n,
return 0;
}
-void mxc_jpeg_addrs(struct mxc_jpeg_desc *desc, struct vb2_buffer *b_base0_buf,
-struct vb2_buffer *bufbase_buf, int offset)
+static void mxc_jpeg_addrs(struct mxc_jpeg_desc *desc,
+ struct vb2_buffer *b_base0_buf,
+ struct vb2_buffer *bufbase_buf, int offset)
{
- u32 buf_base0, bufbase;
-
- buf_base0 = vb2_dma_contig_plane_dma_addr(b_base0_buf, 0);
- bufbase = vb2_dma_contig_plane_dma_addr(bufbase_buf, 0);
- mxc_jpeg_set_addrs(desc, buf_base0, bufbase + offset);
+ desc->buf_base0 = vb2_dma_contig_plane_dma_addr(b_base0_buf, 0);
+ desc->buf_base1 = 0; /* TODO for YUV420*/
+ desc->stm_bufbase = vb2_dma_contig_plane_dma_addr(bufbase_buf, 0) +
+ offset;
}
static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv)
@@ -240,73 +240,110 @@ static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv)
struct mxc_jpeg_dev *jpeg = priv;
struct mxc_jpeg_ctx *ctx;
void __iomem *reg = jpeg->base_reg;
+ struct device *dev = jpeg->dev;
struct vb2_buffer *src_buf, *dst_buf;
- struct mxc_jpeg_src_buf *jpeg_src_buf;
- enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR;
struct mxc_jpeg_desc *desc;
dma_addr_t dma_handle;
- u32 dec_ret, offset, slot;
- struct mxc_jpeg_q_data *q_data;
- void *testaddri;
- void *testaddro;
+ u32 dec_ret;
+ int slot = 0; /* TODO remove hardcoded slot 0 */
-
- /* hardcoded slot 0 */
- dec_ret = readl(reg + MXC_SLOT_OFFSET(0, SLOT_STATUS));
- writel(dec_ret, reg + MXC_SLOT_OFFSET(0, SLOT_STATUS)); /* w1c */
- if (!(dec_ret & MXC_FRMDONE))
- return IRQ_HANDLED;
+ spin_lock(&jpeg->hw_lock);
ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
+ if (!ctx) {
+ dev_err(dev,
+ "Instance released before the end of transaction.\n");
+ goto job_unlock;
+ }
+ if (ctx->aborting) {
+ dev_dbg(dev, "Aborting current job\n");
+ mxc_jpeg_sw_reset(reg);
+ goto job_finish;
+ }
+
+ dec_ret = readl(reg + MXC_SLOT_OFFSET(slot, SLOT_STATUS));
+ writel(dec_ret, reg + MXC_SLOT_OFFSET(slot, SLOT_STATUS)); /* w1c */
+ if (!(dec_ret & SLOTa_STATUS_FRMDONE))
+ goto job_unlock;
+
dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
- jpeg_src_buf = mxc_jpeg_vb2_to_srcbuf(src_buf);
-
- if (ctx->mode == MXC_JPEG_ENCODE &&
- ctx->enc_state == MXC_JPEG_ENC_CONF) {
- q_data = &ctx->out_q;
- desc = jpeg_src_buf->desc;
- dma_handle = jpeg_src_buf->handle;
-
- testaddri = vb2_plane_vaddr(src_buf, 0);
- testaddro = vb2_plane_vaddr(dst_buf, 0);
-
- offset = mxc_jpeg_get_offset(jpeg->base_reg, 0);
- mxc_jpeg_addrs(desc, src_buf, dst_buf, offset);
- slot = mxc_jpeg_get_slot(jpeg->base_reg);
- mxc_jpeg_set_params(desc, mxc_jpeg_align(
- vb2_plane_size(src_buf, 0), 1024),
- q_data->bytesperline[0],
- q_data->fmt->fourcc);
- mxc_jpeg_set_res(desc, q_data->w, q_data->h);
+
+ if (ctx->mode == MXC_JPEG_ENCODE
+ && ctx->enc_state == MXC_JPEG_ENC_CONF) {
ctx->enc_state = MXC_JPEG_ENC_DONE;
+ if (dec_ret & SLOTa_STATUS_ENC_CONFIG_ERR) {
+ dev_err(dev, "Encoder config finished with errors.\n");
+ goto job_finish;
+ }
+
+ dev_dbg(dev, "Encoder config finished.\n");
+
+ /* get out of config mode*/
+ mxc_jpeg_set_config_mode(reg, 0);
+
+ slot = 0; /* TODO get slot*/
+
+ desc = jpeg->slot_data[slot].desc;
+ dma_handle = jpeg->slot_data[slot].desc_handle;
+
+ mxc_jpeg_addrs(desc, src_buf, dst_buf, 0);
+
+ /* TODO remove hardcodings*/
+ mxc_jpeg_set_bufsize(desc, 0x1000);
+ mxc_jpeg_set_res(desc, 64, 64);
+ mxc_jpeg_set_line_pitch(desc, 64 * 2);
+ desc->stm_ctrl = STM_CTRL_CONFIG_MOD(0) |
+ STM_CTRL_AUTO_START(1) |
+ STM_CTRL_IMAGE_FORMAT(MXC_JPEG_YUV422);
+
+ mxc_jpeg_enable_slot(jpeg->base_reg, slot);
+ mxc_jpeg_enable_irq(jpeg->base_reg, slot);
mxc_jpeg_set_desc(dma_handle, jpeg->base_reg, slot);
- return IRQ_HANDLED;
+
+ print_descriptor_info(dev, desc);
+ print_wrapper_info(dev, jpeg->base_reg);
+ print_cast_encoder_info(dev, jpeg->base_reg);
+
+ dev_dbg(dev, "Encoder starts encoding...\n");
+ mxc_jpeg_go_auto(jpeg->base_reg);
+ goto job_unlock;
}
- buf_state = VB2_BUF_STATE_DONE;
+ if (ctx->mode == MXC_JPEG_ENCODE)
+ dev_dbg(dev, "Encoding finished\n");
+ else
+ dev_dbg(dev, "Decoding finished\n");
+
+ /* short preview of the results */
+ dev_dbg(dev, "src_buf: ");
+ print_buf(dev, src_buf);
+ dev_dbg(dev, "dst_buf: ");
+ print_buf(dev, dst_buf);
+
v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
- v4l2_m2m_buf_done(to_vb2_v4l2_buffer(src_buf), buf_state);
- v4l2_m2m_buf_done(to_vb2_v4l2_buffer(dst_buf), buf_state);
+ v4l2_m2m_buf_done(to_vb2_v4l2_buffer(src_buf), VB2_BUF_STATE_DONE);
+ v4l2_m2m_buf_done(to_vb2_v4l2_buffer(dst_buf), VB2_BUF_STATE_DONE);
+job_finish:
v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
+job_unlock:
+ spin_unlock(&jpeg->hw_lock);
return IRQ_HANDLED;
}
-void mxc_jpeg_config_enc(struct vb2_buffer *out_buf,
- struct mxc_jpeg_src_buf *jpeg_src_buf,
+
+static void mxc_jpeg_config_enc(struct vb2_buffer *out_buf,
+ int slot,
struct mxc_jpeg_dev *jpeg)
{
dma_addr_t jpg_handle;
jpg_handle = vb2_dma_contig_plane_dma_addr(out_buf, 0);
- jpeg_src_buf->tbl = dma_zalloc_coherent(jpeg->dev,
- sizeof(unsigned char) * 615,
- &jpeg_src_buf->tbl_handle, 0);
- memcpy(jpeg_src_buf->tbl, &hactbl, sizeof(unsigned char) * 615);
-
- mxc_jpeg_enc_config(jpeg->base_reg, jpeg_src_buf->desc, jpeg_src_buf->handle,
- jpeg_src_buf->tbl_handle, jpg_handle);
-
+ mxc_jpeg_enc_config(jpeg->dev,
+ jpeg->base_reg,
+ jpeg->slot_data[slot].desc, jpeg->slot_data[slot].desc_handle,
+ jpeg->slot_data[slot].cfg_stream_handle, jpg_handle);
}
+
static void mxc_jpeg_device_run(void *priv)
{
struct mxc_jpeg_ctx *ctx = priv;
@@ -314,34 +351,31 @@ static void mxc_jpeg_device_run(void *priv)
struct device *dev = jpeg->dev;
struct vb2_buffer *src_buf, *dst_buf;
unsigned long flags;
- struct mxc_jpeg_src_buf *jpeg_src_buf;
- int slot;
- void *testaddri;
- void *testaddro;
+ int slot = 0;
dma_addr_t dma_handle;
struct mxc_jpeg_desc *desc;
-
+ spin_lock_irqsave(&ctx->mxc_jpeg->hw_lock, flags);
src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
- jpeg_src_buf = mxc_jpeg_vb2_to_srcbuf(src_buf);
- desc = jpeg_src_buf->desc;
- dma_handle = jpeg_src_buf->handle;
-
-
- testaddri = vb2_plane_vaddr(src_buf, 0);
- testaddro = vb2_plane_vaddr(dst_buf, 0);
- spin_lock_irqsave(&ctx->mxc_jpeg->hw_lock, flags);
+ if (!src_buf || !dst_buf) {
+ dev_err(dev, "Null src or dst buf\n");
+ goto end;
+ }
+ slot = 0; /* TODO get slot */
mxc_jpeg_enable(jpeg->base_reg);
if (ctx->mode == MXC_JPEG_ENCODE) {
+ dev_dbg(dev, "Encoding on slot %d\n", slot);
ctx->enc_state = MXC_JPEG_ENC_CONF;
- mxc_jpeg_config_enc(dst_buf, jpeg_src_buf, jpeg);
+ mxc_jpeg_config_enc(dst_buf, slot, jpeg);
} else {
+ dev_dbg(dev, "Decoding on slot %d\n", slot);
+ desc = jpeg->slot_data[slot].desc;
+ dma_handle = jpeg->slot_data[slot].desc_handle;
+
mxc_jpeg_addrs(desc, dst_buf, src_buf, 0);
- slot = mxc_jpeg_get_slot(jpeg->base_reg);
- if (slot == -EINVAL)
- dev_err(dev, "No more slots available!\n");
+
mxc_jpeg_enable_slot(jpeg->base_reg, slot);
mxc_jpeg_set_bufsize(desc,
mxc_jpeg_align(vb2_plane_size(src_buf, 0), 1024));
@@ -350,20 +384,34 @@ static void mxc_jpeg_device_run(void *priv)
mxc_jpeg_set_desc(dma_handle, jpeg->base_reg, slot);
mxc_jpeg_go(jpeg->base_reg);
}
+end:
spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags);
}
+
static int mxc_jpeg_job_ready(void *priv)
{
struct mxc_jpeg_ctx *ctx = priv;
+ unsigned int num_src_bufs_ready;
+ unsigned int num_dst_bufs_ready;
+ unsigned long flags;
- dev_warn(ctx->mxc_jpeg->dev, "mxc_jpeg_job_ready unimplemented\n");
- return 1;
+ spin_lock_irqsave(&ctx->mxc_jpeg->hw_lock, flags);
+
+ num_src_bufs_ready = v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx);
+ num_dst_bufs_ready = v4l2_m2m_num_dst_bufs_ready(ctx->fh.m2m_ctx);
+
+ spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags);
+
+ if (num_src_bufs_ready >= 1 && num_dst_bufs_ready >= 1)
+ return 1;
+ return 0;
}
static void mxc_jpeg_job_abort(void *priv)
{
struct mxc_jpeg_ctx *ctx = priv;
- dev_warn(ctx->mxc_jpeg->dev, "mxc_jpeg_job_abort unimplemented\n");
+ ctx->aborting = 1;
+ dev_dbg(ctx->mxc_jpeg->dev, "Abort requested\n");
}
static struct mxc_jpeg_q_data *mxc_jpeg_get_q_data(struct mxc_jpeg_ctx *ctx,
@@ -399,6 +447,7 @@ static int mxc_jpeg_start_streaming(struct vb2_queue *q, unsigned int count)
struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(q);
int ret;
+ dev_dbg(ctx->mxc_jpeg->dev, "Start streaming\n");
ret = pm_runtime_get_sync(ctx->mxc_jpeg->dev);
return ret > 0 ? 0 : ret;
}
@@ -407,7 +456,8 @@ static void mxc_jpeg_stop_streaming(struct vb2_queue *q)
{
struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(q);
- pm_runtime_put(&ctx->mxc_jpeg->pdev->dev);
+ dev_dbg(ctx->mxc_jpeg->dev, "Stop streaming\n");
+ pm_runtime_put_sync(&ctx->mxc_jpeg->pdev->dev);
}
struct mxc_jpeg_stream {
u8 *addr;
@@ -567,7 +617,7 @@ static int mxc_jpeg_parse(struct device *dev,
dev_info(dev, "JPEG imgsize = 0x%x (%dx%d)\n", desc->imgsize,
sof.width, sof.height);
img_fmt = mxc_jpeg_get_image_format(dev, &sof);
- desc->stm_ctrl |= MXC_IMAGE_FORMAT(img_fmt);
+ desc->stm_ctrl |= STM_CTRL_IMAGE_FORMAT(img_fmt);
desc->line_pitch = mxc_jpeg_get_line_pitch(dev, &sof, img_fmt);
return 0;
}
@@ -575,21 +625,19 @@ static int mxc_jpeg_parse(struct device *dev,
static void mxc_jpeg_buf_queue(struct vb2_buffer *vb)
{
int ret;
- struct mxc_jpeg_src_buf *jpeg_src_buf;
struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+ int slot = 0; /* TODO get slot*/
if (vb->vb2_queue->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
goto end;
- jpeg_src_buf = container_of(vbuf, struct mxc_jpeg_src_buf, b);
- jpeg_src_buf->desc = dma_zalloc_coherent(ctx->mxc_jpeg->dev,
- sizeof(struct mxc_jpeg_desc),
- &jpeg_src_buf->handle, 0);
+
if (ctx->mode != MXC_JPEG_DECODE)
goto end;
ret = mxc_jpeg_parse(ctx->mxc_jpeg->dev,
- jpeg_src_buf->desc, (u8 *)vb2_plane_vaddr(vb, 0),
- vb2_get_plane_payload(vb, 0));
+ ctx->mxc_jpeg->slot_data[slot].desc,
+ (u8 *)vb2_plane_vaddr(vb, 0),
+ vb2_get_plane_payload(vb, 0));
if (ret) {
v4l2_err(&ctx->mxc_jpeg->v4l2_dev,
"driver does not support this resolution\n");
@@ -629,31 +677,18 @@ static int mxc_jpeg_buf_prepare(struct vb2_buffer *vb)
static void mxc_jpeg_buf_clean(struct vb2_buffer *vb)
{
- struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
- struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
- struct mxc_jpeg_src_buf *jpeg_src_buf;
-
- jpeg_src_buf = container_of(vbuf, struct mxc_jpeg_src_buf, b);
-
- if (ctx->mode == MXC_JPEG_ENCODE &&
- ctx->enc_state == MXC_JPEG_ENC_CONF)
- dma_free_coherent(ctx->mxc_jpeg->dev, sizeof(hactbl),
- jpeg_src_buf->tbl, jpeg_src_buf->tbl_handle);
-
- dma_free_coherent(ctx->mxc_jpeg->dev, sizeof(struct mxc_jpeg_desc),
- jpeg_src_buf->desc, jpeg_src_buf->handle);
+ return;
}
static const struct vb2_ops mxc_jpeg_qops = {
.queue_setup = mxc_jpeg_queue_setup,
-
- .buf_prepare = mxc_jpeg_buf_prepare,
- .buf_queue = mxc_jpeg_buf_queue,
.wait_prepare = vb2_ops_wait_prepare,
.wait_finish = vb2_ops_wait_finish,
+ .buf_prepare = mxc_jpeg_buf_prepare,
+ .buf_cleanup = mxc_jpeg_buf_clean,
.start_streaming = mxc_jpeg_start_streaming,
.stop_streaming = mxc_jpeg_stop_streaming,
- .buf_cleanup = mxc_jpeg_buf_clean,
+ .buf_queue = mxc_jpeg_buf_queue,
};
static int mxc_jpeg_queue_init(void *priv, struct vb2_queue *src_vq,
struct vb2_queue *dst_vq)
@@ -711,6 +746,76 @@ static struct mxc_jpeg_fmt *mxc_jpeg_find_format(struct mxc_jpeg_ctx *ctx,
return NULL;
}
+static int mxc_jpeg_alloc_slot_data(struct mxc_jpeg_dev *jpeg)
+{
+ int slot;
+
+ for (slot = 0; slot < MXC_MAX_SLOTS; slot++) {
+ /* allocate descriptor for decoding/encoding phase */
+ jpeg->slot_data[slot].desc = dma_zalloc_coherent(jpeg->dev,
+ sizeof(struct mxc_jpeg_desc),
+ &(jpeg->slot_data[slot].desc_handle), 0);
+ if (!jpeg->slot_data[slot].desc)
+ goto err;
+ dev_dbg(jpeg->dev, "Descriptor for dec/enc: %p 0x%llx\n",
+ jpeg->slot_data[slot].desc,
+ jpeg->slot_data[slot].desc_handle);
+
+ /* allocate descriptor for configuration phase (encoder only) */
+ jpeg->slot_data[slot].cfg_desc = dma_zalloc_coherent(jpeg->dev,
+ sizeof(struct mxc_jpeg_desc),
+ &jpeg->slot_data[slot].cfg_desc_handle, 0);
+ if (!jpeg->slot_data[slot].cfg_desc)
+ goto err;
+ dev_dbg(jpeg->dev, "Descriptor for config phase: %p 0x%llx\n",
+ jpeg->slot_data[slot].cfg_desc,
+ jpeg->slot_data[slot].cfg_desc_handle);
+
+ /* allocate configuration stream */
+ jpeg->slot_data[slot].cfg_stream_vaddr = dma_zalloc_coherent(
+ jpeg->dev,
+ sizeof(hactbl),
+ &jpeg->slot_data[slot].cfg_stream_handle, 0);
+ if (!jpeg->slot_data[slot].cfg_stream_vaddr)
+ goto err;
+ dev_dbg(jpeg->dev, "Configuration stream: %p 0x%llx\n",
+ jpeg->slot_data[slot].cfg_stream_vaddr,
+ jpeg->slot_data[slot].cfg_stream_handle);
+
+ /* initial set-up for configuration stream
+ * TODO: fixup the sizes, currently harcoded to 64x64)
+ */
+ memcpy(jpeg->slot_data[slot].cfg_stream_vaddr,
+ &hactbl, sizeof(hactbl));
+ }
+ return 0;
+err:
+ dev_err(jpeg->dev, "Could not allocate descriptors\n");
+ return 1;
+}
+
+static int mxc_jpeg_free_slot_data(struct mxc_jpeg_dev *jpeg)
+{
+ int slot;
+
+ for (slot = 0; slot < MXC_MAX_SLOTS; slot++) {
+ /* free descriptor for decoding/encoding phase */
+ dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc),
+ jpeg->slot_data[slot].desc,
+ jpeg->slot_data[slot].desc_handle);
+
+ /* free descriptor for configuration phase (encoder only) */
+ dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc),
+ jpeg->slot_data[slot].cfg_desc,
+ jpeg->slot_data[slot].cfg_desc_handle);
+
+ /* free configuration stream */
+ dma_free_coherent(jpeg->dev, sizeof(hactbl),
+ jpeg->slot_data[slot].cfg_stream_vaddr,
+ jpeg->slot_data[slot].cfg_stream_handle);
+ }
+ return 0;
+}
static int mxc_jpeg_open(struct file *file)
{
@@ -758,7 +863,8 @@ static int mxc_jpeg_open(struct file *file)
goto error;
}
-
+ if (mxc_jpeg_alloc_slot_data(mxc_jpeg))
+ goto error;
mutex_unlock(&mxc_jpeg->lock);
return 0;
@@ -967,7 +1073,6 @@ static int mxc_jpeg_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(priv);
struct vb2_queue *vq;
struct vb2_buffer *vb;
- struct mxc_jpeg_src_buf *jpeg_src_buf;
if (buf->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
goto end;
@@ -979,7 +1084,6 @@ static int mxc_jpeg_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
}
vb = vq->bufs[buf->index];
- jpeg_src_buf = mxc_jpeg_vb2_to_srcbuf(vb);
end:
return v4l2_m2m_qbuf(file, fh->m2m_ctx, buf);
}
@@ -1016,6 +1120,7 @@ static int mxc_jpeg_release(struct file *file)
struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(file->private_data);
mutex_lock(&mxc_jpeg->lock);
+ mxc_jpeg_free_slot_data(mxc_jpeg);
v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
v4l2_fh_del(&ctx->fh);
v4l2_fh_exit(&ctx->fh);
@@ -1060,6 +1165,11 @@ static int mxc_jpeg_probe(struct platform_device *pdev)
mutex_init(&jpeg->lock);
spin_lock_init(&jpeg->hw_lock);
+ if (dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32))) {
+ dev_err(&pdev->dev, "No suitable DMA available.\n");
+ return -EINVAL;
+ }
+
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
dec_irq = platform_get_irq(pdev, 0);
if (!res || dec_irq < 0) {
@@ -1126,7 +1236,7 @@ static int mxc_jpeg_probe(struct platform_device *pdev)
jpeg->dec_vdev->ioctl_ops = &mxc_jpeg_ioctl_ops;
jpeg->dec_vdev->minor = -1;
jpeg->dec_vdev->release = video_device_release;
- jpeg->dec_vdev->lock = &jpeg->lock;
+ jpeg->dec_vdev->lock = &jpeg->lock; /* lock for ioctl serialization*/
jpeg->dec_vdev->v4l2_dev = &jpeg->v4l2_dev;
jpeg->dec_vdev->vfl_dir = VFL_DIR_M2M;
jpeg->dec_vdev->device_caps = V4L2_CAP_STREAMING |
@@ -1217,6 +1327,7 @@ static int mxc_jpeg_remove(struct platform_device *pdev)
video_device_release(jpeg->dec_vdev);
v4l2_m2m_release(jpeg->m2m_dev);
v4l2_device_unregister(&jpeg->v4l2_dev);
+
return 0;
}