[PATCH v3] [media] v4l2: Add support for go2001 PCI codec driver

2017-07-25 Thread Thierry Escande
This patch adds support for the go2001 PCI codec driver. This hardware
is present on ChromeOS based devices like the Acer ChromeBox and Acer/LG
ChromeBase 24 devices. This chipset comes on a mini PCI-E card with
Google as PCI vendor ID (0x1ae0).

This driver comes from the ChromeOS v3.18 kernel tree and has been
modified to support vb2_buffer restructuring introduced in Linux v4.4.

The go2001 firmware files can be found in the build tree of the Google
Chromium OS open source project.

This driver is originally developed by:
 Pawel Osciak <posc...@chromium.org>
 Ville-Mikko Rautio <v...@chromium.org>
 henryhsu <henry...@chromium.org>
 Wu-Cheng Li <wuchen...@chromium.org>

Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
---
 drivers/media/pci/Kconfig|2 +
 drivers/media/pci/Makefile   |1 +
 drivers/media/pci/go2001/Kconfig |   11 +
 drivers/media/pci/go2001/Makefile|2 +
 drivers/media/pci/go2001/go2001.h|  331 
 drivers/media/pci/go2001/go2001_driver.c | 2525 ++
 drivers/media/pci/go2001/go2001_hw.c | 1362 
 drivers/media/pci/go2001/go2001_hw.h |   55 +
 drivers/media/pci/go2001/go2001_proto.h  |  359 +
 9 files changed, 4648 insertions(+)
 create mode 100644 drivers/media/pci/go2001/Kconfig
 create mode 100644 drivers/media/pci/go2001/Makefile
 create mode 100644 drivers/media/pci/go2001/go2001.h
 create mode 100644 drivers/media/pci/go2001/go2001_driver.c
 create mode 100644 drivers/media/pci/go2001/go2001_hw.c
 create mode 100644 drivers/media/pci/go2001/go2001_hw.h
 create mode 100644 drivers/media/pci/go2001/go2001_proto.h

diff --git a/drivers/media/pci/Kconfig b/drivers/media/pci/Kconfig
index da28e68..837681e 100644
--- a/drivers/media/pci/Kconfig
+++ b/drivers/media/pci/Kconfig
@@ -54,5 +54,7 @@ source "drivers/media/pci/smipcie/Kconfig"
 source "drivers/media/pci/netup_unidvb/Kconfig"
 endif
 
+source "drivers/media/pci/go2001/Kconfig"
+
 endif #MEDIA_PCI_SUPPORT
 endif #PCI
diff --git a/drivers/media/pci/Makefile b/drivers/media/pci/Makefile
index a7e8af0..58639b7 100644
--- a/drivers/media/pci/Makefile
+++ b/drivers/media/pci/Makefile
@@ -32,3 +32,4 @@ obj-$(CONFIG_STA2X11_VIP) += sta2x11/
 obj-$(CONFIG_VIDEO_SOLO6X10) += solo6x10/
 obj-$(CONFIG_VIDEO_COBALT) += cobalt/
 obj-$(CONFIG_VIDEO_TW5864) += tw5864/
+obj-$(CONFIG_VIDEO_GO2001) += go2001/
diff --git a/drivers/media/pci/go2001/Kconfig b/drivers/media/pci/go2001/Kconfig
new file mode 100644
index 000..c7b5149
--- /dev/null
+++ b/drivers/media/pci/go2001/Kconfig
@@ -0,0 +1,11 @@
+config VIDEO_GO2001
+   tristate "GO2001 codec driver"
+   depends on VIDEO_V4L2 && PCI
+   select VIDEOBUF2_DMA_SG
+   ---help---
+ This driver supports the GO2001 PCI hardware codec. This codec
+ is present on ChromeOS based devices like the Acer ChromeBox
+ and ChromeBase 24 and LG ChromeBase as well.
+
+ To compile this driver as a module, choose M here: the
+ module will be called go2001.
diff --git a/drivers/media/pci/go2001/Makefile 
b/drivers/media/pci/go2001/Makefile
new file mode 100644
index 000..20bad18
--- /dev/null
+++ b/drivers/media/pci/go2001/Makefile
@@ -0,0 +1,2 @@
+go2001-objs:= go2001_driver.o go2001_hw.o
+obj-$(CONFIG_VIDEO_GO2001) += go2001.o
diff --git a/drivers/media/pci/go2001/go2001.h 
b/drivers/media/pci/go2001/go2001.h
new file mode 100644
index 000..0e5ccfd
--- /dev/null
+++ b/drivers/media/pci/go2001/go2001.h
@@ -0,0 +1,331 @@
+/*
+ *  go2001 - GO2001 codec driver.
+ *
+ *  Author : Pawel Osciak <posc...@chromium.org>
+ *
+ *  Copyright (C) 2017 Google, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  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.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef _MEDIA_PCI_GO2001_GO2001_H_
+#define _MEDIA_PCI_GO2001_GO2001_H_
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+#include "go2001_proto.h"
+
+struct go2001_msg {
+   struct list_head list_entry;
+   struct go2001_msg_payload payload;
+};
+
+static inline struct go2001_msg_hdr *msg_to_hdr(struct go2001_msg *msg)
+{
+   return >payload.hdr;
+}
+
+static inline void *msg_to_param(struct go2001_msg *msg)
+{
+   return ms

[PATCH v3] go2001 hardware codec support

2017-07-25 Thread Thierry Escande
 Multiplanar
Streaming
Extended Pix Format

Compliance test for device /dev/video1 (not using libv4l2):

Required ioctls:
test VIDIOC_QUERYCAP: OK

Allow for multiple opens:
test second video open: OK
test VIDIOC_QUERYCAP: OK
test VIDIOC_G/S_PRIORITY: OK
test for unlimited opens: OK

Debug ioctls:
test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported)
test VIDIOC_LOG_STATUS: OK (Not Supported)

Input ioctls:
test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
test VIDIOC_ENUMAUDIO: OK (Not Supported)
test VIDIOC_G/S/ENUMINPUT: OK (Not Supported)
test VIDIOC_G/S_AUDIO: OK (Not Supported)
Inputs: 0 Audio Inputs: 0 Tuners: 0

Output ioctls:
test VIDIOC_G/S_MODULATOR: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
test VIDIOC_ENUMAUDOUT: OK (Not Supported)
test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
test VIDIOC_G/S_AUDOUT: OK (Not Supported)
Outputs: 0 Audio Outputs: 0 Modulators: 0

Input/Output configuration ioctls:
test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
test VIDIOC_G/S_EDID: OK (Not Supported)

Control ioctls:
test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK
test VIDIOC_QUERYCTRL: OK
test VIDIOC_G/S_CTRL: OK
test VIDIOC_G/S/TRY_EXT_CTRLS: OK
test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK
test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
Standard Controls: 4 Private Controls: 0

Format ioctls:
test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
fail: v4l2-test-formats.cpp(1213): got error 22 when setting 
parms for buftype 10
test VIDIOC_G/S_PARM: FAIL
test VIDIOC_G_FBUF: OK (Not Supported)
fail: v4l2-test-formats.cpp(446): !pix_mp.width || 
!pix_mp.height
test VIDIOC_G_FMT: FAIL
test VIDIOC_TRY_FMT: OK (Not Supported)
test VIDIOC_S_FMT: OK (Not Supported)
test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
test Cropping: OK (Not Supported)
test Composing: OK (Not Supported)
fail: v4l2-test-formats.cpp(1678): doioctl(node, VIDIOC_G_FMT, 
)
test Scaling: FAIL

Codec ioctls:
test VIDIOC_(TRY_)ENCODER_CMD: OK (Not Supported)
test VIDIOC_G_ENC_INDEX: OK (Not Supported)
test VIDIOC_(TRY_)DECODER_CMD: OK (Not Supported)

Buffer ioctls:
test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
fail: v4l2-test-buffers.cpp(574): VIDIOC_EXPBUF is supported, 
but the V4L2_MEMORY_MMAP support is missing, probably due to earlier failing 
format tests.
test VIDIOC_EXPBUF: OK (Not Supported)

Test input 0:


Total: 43, Succeeded: 40, Failed: 3, Warnings: 0


Thierry Escande (1):
  [media] v4l2: Add support for go2001 PCI codec driver

 drivers/media/pci/Kconfig|2 +
 drivers/media/pci/Makefile   |1 +
 drivers/media/pci/go2001/Kconfig |   11 +
 drivers/media/pci/go2001/Makefile|2 +
 drivers/media/pci/go2001/go2001.h|  331 
 drivers/media/pci/go2001/go2001_driver.c | 2525 ++
 drivers/media/pci/go2001/go2001_hw.c | 1362 
 drivers/media/pci/go2001/go2001_hw.h |   55 +
 drivers/media/pci/go2001/go2001_proto.h  |  359 +
 9 files changed, 4648 insertions(+)
 create mode 100644 drivers/media/pci/go2001/Kconfig
 create mode 100644 drivers/media/pci/go2001/Makefile
 create mode 100644 drivers/media/pci/go2001/go2001.h
 create mode 100644 drivers/media/pci/go2001/go2001_driver.c
 create mode 100644 drivers/media/pci/go2001/go2001_hw.c
 create mode 100644 drivers/media/pci/go2001/go2001_hw.h
 create mode 100644 drivers/media/pci/go2001/go2001_proto.h

-- 
2.7.4



[PATCH v4 3/8] [media] s5p-jpeg: Handle parsing error in s5p_jpeg_parse_hdr()

2017-06-30 Thread Thierry Escande
This patch modifies the s5p_jpeg_parse_hdr() function so it only
modifies the passed s5p_jpeg_q_data structure if the jpeg header parsing
is successful.

Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
Acked-by: Andrzej Pietrasiewicz <andrze...@samsung.com>
Acked-by: Jacek Anaszewski <jacek.anaszew...@gmail.com>
---
 drivers/media/platform/s5p-jpeg/jpeg-core.c | 38 -
 1 file changed, 21 insertions(+), 17 deletions(-)

diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c 
b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index 0d935f5..df3e5ee 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -1206,22 +1206,9 @@ static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data 
*result,
break;
}
}
-   result->w = width;
-   result->h = height;
-   result->sos = sos;
-   result->dht.n = n_dht;
-   while (n_dht--) {
-   result->dht.marker[n_dht] = dht[n_dht];
-   result->dht.len[n_dht] = dht_len[n_dht];
-   }
-   result->dqt.n = n_dqt;
-   while (n_dqt--) {
-   result->dqt.marker[n_dqt] = dqt[n_dqt];
-   result->dqt.len[n_dqt] = dqt_len[n_dqt];
-   }
-   result->sof = sof;
-   result->sof_len = sof_len;
-   result->size = result->components = components;
+
+   if (notfound || !sos)
+   return false;
 
switch (subsampling) {
case 0x11:
@@ -1240,7 +1227,24 @@ static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data 
*result,
return false;
}
 
-   return !notfound && sos;
+   result->w = width;
+   result->h = height;
+   result->sos = sos;
+   result->dht.n = n_dht;
+   while (n_dht--) {
+   result->dht.marker[n_dht] = dht[n_dht];
+   result->dht.len[n_dht] = dht_len[n_dht];
+   }
+   result->dqt.n = n_dqt;
+   while (n_dqt--) {
+   result->dqt.marker[n_dqt] = dqt[n_dqt];
+   result->dqt.len[n_dqt] = dqt_len[n_dqt];
+   }
+   result->sof = sof;
+   result->sof_len = sof_len;
+   result->size = result->components = components;
+
+   return true;
 }
 
 static int s5p_jpeg_querycap(struct file *file, void *priv,
-- 
2.7.4



[PATCH v4 4/8] [media] s5p-jpeg: Don't use temporary structure in s5p_jpeg_buf_queue

2017-06-30 Thread Thierry Escande
If s5p_jpeg_parse_hdr() fails to parse the JPEG header, the passed
s5p_jpeg_q_data structure is not modified so there is no need to use a
temporary structure and the field-by-field copy can be avoided.

Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
Acked-by: Andrzej Pietrasiewicz <andrze...@samsung.com>
Acked-by: Jacek Anaszewski <jacek.anaszew...@gmail.com>
---
 drivers/media/platform/s5p-jpeg/jpeg-core.c | 23 ---
 1 file changed, 4 insertions(+), 19 deletions(-)

diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c 
b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index df3e5ee..1769744 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -2500,9 +2500,9 @@ static void s5p_jpeg_buf_queue(struct vb2_buffer *vb)
 
if (ctx->mode == S5P_JPEG_DECODE &&
vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
-   struct s5p_jpeg_q_data tmp, *q_data;
+   struct s5p_jpeg_q_data *q_data;
 
-   ctx->hdr_parsed = s5p_jpeg_parse_hdr(,
+   ctx->hdr_parsed = s5p_jpeg_parse_hdr(>out_q,
 (unsigned long)vb2_plane_vaddr(vb, 0),
 min((unsigned long)ctx->out_q.size,
 vb2_get_plane_payload(vb, 0)), ctx);
@@ -2511,24 +2511,9 @@ static void s5p_jpeg_buf_queue(struct vb2_buffer *vb)
return;
}
 
-   q_data = >out_q;
-   q_data->w = tmp.w;
-   q_data->h = tmp.h;
-   q_data->sos = tmp.sos;
-   memcpy(q_data->dht.marker, tmp.dht.marker,
-  sizeof(tmp.dht.marker));
-   memcpy(q_data->dht.len, tmp.dht.len, sizeof(tmp.dht.len));
-   q_data->dht.n = tmp.dht.n;
-   memcpy(q_data->dqt.marker, tmp.dqt.marker,
-  sizeof(tmp.dqt.marker));
-   memcpy(q_data->dqt.len, tmp.dqt.len, sizeof(tmp.dqt.len));
-   q_data->dqt.n = tmp.dqt.n;
-   q_data->sof = tmp.sof;
-   q_data->sof_len = tmp.sof_len;
-
q_data = >cap_q;
-   q_data->w = tmp.w;
-   q_data->h = tmp.h;
+   q_data->w = ctx->out_q.w;
+   q_data->h = ctx->out_q.h;
 
/*
 * This call to jpeg_bound_align_image() takes care of width and
-- 
2.7.4



[PATCH v4 6/8] [media] s5p-jpeg: Decode 4:1:1 chroma subsampling format

2017-06-30 Thread Thierry Escande
From: Tony K Nadackal <tony...@samsung.com>

This patch adds support for decoding 4:1:1 chroma subsampling in the
jpeg header parsing function.

Signed-off-by: Tony K Nadackal <tony...@samsung.com>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
Acked-by: Andrzej Pietrasiewicz <andrze...@samsung.com>
Acked-by: Jacek Anaszewski <jacek.anaszew...@gmail.com>
---
 drivers/media/platform/s5p-jpeg/jpeg-core.c | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c 
b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index 0783809..cca0fb8 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -1099,6 +1099,8 @@ static void skip(struct s5p_jpeg_buffer *buf, long len)
 static bool s5p_jpeg_subsampling_decode(struct s5p_jpeg_ctx *ctx,
unsigned int subsampling)
 {
+   unsigned int version;
+
switch (subsampling) {
case 0x11:
ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444;
@@ -1112,6 +1114,19 @@ static bool s5p_jpeg_subsampling_decode(struct 
s5p_jpeg_ctx *ctx,
case 0x33:
ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
break;
+   case 0x41:
+   /*
+* 4:1:1 subsampling only supported by 3250, 5420, and 5433
+* variants
+*/
+   version = ctx->jpeg->variant->version;
+   if (version != SJPEG_EXYNOS3250 &&
+   version != SJPEG_EXYNOS5420 &&
+   version != SJPEG_EXYNOS5433)
+   return false;
+
+   ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_411;
+   break;
default:
return false;
}
-- 
2.7.4



[PATCH v4 1/8] [media] s5p-jpeg: Call jpeg_bound_align_image after qbuf

2017-06-30 Thread Thierry Escande
From: Tony K Nadackal <tony...@samsung.com>

When queuing an OUTPUT buffer for decoder, s5p_jpeg_parse_hdr()
function parses the input jpeg file and takes the width and height
parameters from its header. These new width/height values will be used
for the calculation of stride. HX_JPEG Hardware needs the width and
height values aligned on a 16 bits boundary. This width/height alignment
is handled in the s5p_jpeg_s_fmt_vid_cap() function during the S_FMT
ioctl call.

But if user space calls the QBUF of OUTPUT buffer after the S_FMT of
CAPTURE buffer, these aligned values will be replaced by the values in
jpeg header. If the width/height values of jpeg are not aligned, the
decoder output will be corrupted. So in this patch we call
jpeg_bound_align_image() to align the width/height values of Capture
buffer in s5p_jpeg_buf_queue().

Signed-off-by: Tony K Nadackal <tony...@samsung.com>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
Acked-by: Andrzej Pietrasiewicz <andrze...@samsung.com>
Acked-by: Jacek Anaszewski <jacek.anaszew...@gmail.com>
---
 drivers/media/platform/s5p-jpeg/jpeg-core.c | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c 
b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index 52dc794..623508d 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -2523,6 +2523,25 @@ static void s5p_jpeg_buf_queue(struct vb2_buffer *vb)
q_data = >cap_q;
q_data->w = tmp.w;
q_data->h = tmp.h;
+
+   /*
+* This call to jpeg_bound_align_image() takes care of width and
+* height values alignment when user space calls the QBUF of
+* OUTPUT buffer after the S_FMT of CAPTURE buffer.
+* Please note that on Exynos4x12 SoCs, resigning from executing
+* S_FMT on capture buffer for each JPEG image can result in a
+* hardware hangup if subsampling is lower than the one of input
+* JPEG.
+*/
+   jpeg_bound_align_image(ctx,
+  _data->w,
+  S5P_JPEG_MIN_WIDTH, S5P_JPEG_MAX_WIDTH,
+  q_data->fmt->h_align,
+  _data->h,
+  S5P_JPEG_MIN_HEIGHT, S5P_JPEG_MAX_HEIGHT,
+  q_data->fmt->v_align);
+
+   q_data->size = q_data->w * q_data->h * q_data->fmt->depth >> 3;
}
 
v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
-- 
2.7.4



[PATCH v4 5/8] [media] s5p-jpeg: Split s5p_jpeg_parse_hdr()

2017-06-30 Thread Thierry Escande
This patch moves the subsampling value decoding read from the jpeg
header into its own function. This new function is called
s5p_jpeg_subsampling_decode() and returns true if it successfully
decodes the subsampling value, false otherwise.

Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
Acked-by: Andrzej Pietrasiewicz <andrze...@samsung.com>
Acked-by: Jacek Anaszewski <jacek.anaszew...@gmail.com>
---
 drivers/media/platform/s5p-jpeg/jpeg-core.c | 42 -
 1 file changed, 24 insertions(+), 18 deletions(-)

diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c 
b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index 1769744..0783809 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -1096,6 +1096,29 @@ static void skip(struct s5p_jpeg_buffer *buf, long len)
get_byte(buf);
 }
 
+static bool s5p_jpeg_subsampling_decode(struct s5p_jpeg_ctx *ctx,
+   unsigned int subsampling)
+{
+   switch (subsampling) {
+   case 0x11:
+   ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444;
+   break;
+   case 0x21:
+   ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422;
+   break;
+   case 0x22:
+   ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420;
+   break;
+   case 0x33:
+   ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
+   break;
+   default:
+   return false;
+   }
+
+   return true;
+}
+
 static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result,
   unsigned long buffer, unsigned long size,
   struct s5p_jpeg_ctx *ctx)
@@ -1207,26 +1230,9 @@ static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data 
*result,
}
}
 
-   if (notfound || !sos)
+   if (notfound || !sos || !s5p_jpeg_subsampling_decode(ctx, subsampling))
return false;
 
-   switch (subsampling) {
-   case 0x11:
-   ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444;
-   break;
-   case 0x21:
-   ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422;
-   break;
-   case 0x22:
-   ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420;
-   break;
-   case 0x33:
-   ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
-   break;
-   default:
-   return false;
-   }
-
result->w = width;
result->h = height;
result->sos = sos;
-- 
2.7.4



[PATCH v4 8/8] [media] s5p-jpeg: Add stream error handling for Exynos5420

2017-06-30 Thread Thierry Escande
From: henryhsu <henry...@chromium.org>

On Exynos5420, the STREAM_STAT bit raised on the JPGINTST register means
there is a syntax error or an unrecoverable error on compressed file
when ERR_INT_EN is set to 1.

Fix this case and report BUF_STATE_ERROR to videobuf2.

Signed-off-by: Henry-Ruey Hsu <henry...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
Acked-by: Andrzej Pietrasiewicz <andrze...@samsung.com>
Acked-by: Jacek Anaszewski <jacek.anaszew...@gmail.com>
---
 drivers/media/platform/s5p-jpeg/jpeg-core.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c 
b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index 5ad3d43..c35d169 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -2812,6 +2812,7 @@ static irqreturn_t exynos3250_jpeg_irq(int irq, void 
*dev_id)
unsigned long payload_size = 0;
enum vb2_buffer_state state = VB2_BUF_STATE_DONE;
bool interrupt_timeout = false;
+   bool stream_error = false;
u32 irq_status;
 
spin_lock(>slock);
@@ -2828,6 +2829,12 @@ static irqreturn_t exynos3250_jpeg_irq(int irq, void 
*dev_id)
 
jpeg->irq_status |= irq_status;
 
+   if (jpeg->variant->version == SJPEG_EXYNOS5420 &&
+   irq_status & EXYNOS3250_STREAM_STAT) {
+   stream_error = true;
+   dev_err(jpeg->dev, "Syntax error or unrecoverable error 
occurred.\n");
+   }
+
curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
 
if (!curr_ctx)
@@ -2844,7 +2851,7 @@ static irqreturn_t exynos3250_jpeg_irq(int irq, void 
*dev_id)
EXYNOS3250_RDMA_DONE |
EXYNOS3250_RESULT_STAT))
payload_size = exynos3250_jpeg_compressed_size(jpeg->regs);
-   else if (interrupt_timeout)
+   else if (interrupt_timeout || stream_error)
state = VB2_BUF_STATE_ERROR;
else
goto exit_unlock;
-- 
2.7.4



[PATCH v4 7/8] [media] s5p-jpeg: Add support for resolution change event

2017-06-30 Thread Thierry Escande
From: henryhsu <henry...@chromium.org>

This patch adds support for resolution change event to notify clients so
they can prepare correct output buffer. When resolution change happened,
G_FMT for CAPTURE should return old resolution and format before CAPTURE
queues streamoff.

This event is used in the Chromium browser project by the V4L2 JPEG
Decode Accelerator (V4L2JDA) to allocate output buffer.

Signed-off-by: Henry-Ruey Hsu <henry...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
Acked-by: Andrzej Pietrasiewicz <andrze...@samsung.com>
Acked-by: Jacek Anaszewski <jacek.anaszew...@gmail.com>
---
 drivers/media/platform/s5p-jpeg/jpeg-core.c | 106 +---
 drivers/media/platform/s5p-jpeg/jpeg-core.h |   7 ++
 2 files changed, 89 insertions(+), 24 deletions(-)

diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c 
b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index cca0fb8..5ad3d43 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -24,6 +24,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -1633,8 +1634,6 @@ static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct 
v4l2_format *f)
FMT_TYPE_OUTPUT : FMT_TYPE_CAPTURE;
 
q_data->fmt = s5p_jpeg_find_format(ct, pix->pixelformat, f_type);
-   q_data->w = pix->width;
-   q_data->h = pix->height;
if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG) {
/*
 * During encoding Exynos4x12 SoCs access wider memory area
@@ -1642,6 +1641,8 @@ static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct 
v4l2_format *f)
 * the JPEG_IMAGE_SIZE register. In order to avoid sysmmu
 * page fault calculate proper buffer size in such a case.
 */
+   q_data->w = pix->width;
+   q_data->h = pix->height;
if (ct->jpeg->variant->hw_ex4_compat &&
f_type == FMT_TYPE_OUTPUT && ct->mode == S5P_JPEG_ENCODE)
q_data->size = exynos4_jpeg_get_output_buffer_size(ct,
@@ -1717,6 +1718,15 @@ static int s5p_jpeg_s_fmt_vid_out(struct file *file, 
void *priv,
return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
 }
 
+static int s5p_jpeg_subscribe_event(struct v4l2_fh *fh,
+   const struct v4l2_event_subscription *sub)
+{
+   if (sub->type == V4L2_EVENT_SOURCE_CHANGE)
+   return v4l2_src_change_event_subscribe(fh, sub);
+
+   return -EINVAL;
+}
+
 static int exynos3250_jpeg_try_downscale(struct s5p_jpeg_ctx *ctx,
   struct v4l2_rect *r)
 {
@@ -2042,6 +2052,9 @@ static const struct v4l2_ioctl_ops s5p_jpeg_ioctl_ops = {
 
.vidioc_g_selection = s5p_jpeg_g_selection,
.vidioc_s_selection = s5p_jpeg_s_selection,
+
+   .vidioc_subscribe_event = s5p_jpeg_subscribe_event,
+   .vidioc_unsubscribe_event   = v4l2_event_unsubscribe,
 };
 
 /*
@@ -2434,8 +2447,17 @@ static int s5p_jpeg_job_ready(void *priv)
 {
struct s5p_jpeg_ctx *ctx = priv;
 
-   if (ctx->mode == S5P_JPEG_DECODE)
+   if (ctx->mode == S5P_JPEG_DECODE) {
+   /*
+* We have only one input buffer and one output buffer. If there
+* is a resolution change event, no need to continue decoding.
+*/
+   if (ctx->state == JPEGCTX_RESOLUTION_CHANGE)
+   return 0;
+
return ctx->hdr_parsed;
+   }
+
return 1;
 }
 
@@ -2514,6 +2536,30 @@ static int s5p_jpeg_buf_prepare(struct vb2_buffer *vb)
return 0;
 }
 
+static void s5p_jpeg_set_capture_queue_data(struct s5p_jpeg_ctx *ctx)
+{
+   struct s5p_jpeg_q_data *q_data = >cap_q;
+
+   q_data->w = ctx->out_q.w;
+   q_data->h = ctx->out_q.h;
+
+   /*
+* This call to jpeg_bound_align_image() takes care of width and
+* height values alignment when user space calls the QBUF of
+* OUTPUT buffer after the S_FMT of CAPTURE buffer.
+* Please note that on Exynos4x12 SoCs, resigning from executing
+* S_FMT on capture buffer for each JPEG image can result in a
+* hardware hangup if subsampling is lower than the one of input
+* JPEG.
+*/
+   jpeg_bound_align_image(ctx, _data->w, S5P_JPEG_MIN_WIDTH,
+  S5P_JPEG_MAX_WIDTH, q_data->fmt->h_align,
+  _data->h, S5P_JPEG_MIN_HEIGHT,
+  S5P_JPEG_MAX_HEIGHT, q_data->fmt->v_align);
+
+   q_data->size = q_data->w * q_data->h * q_data->fmt->depth >> 3;
+}
+
 static void s5p_jpeg_buf_queue(struct vb2_buffer *vb)
 {
struct v

[PATCH v4 2/8] [media] s5p-jpeg: Correct WARN_ON statement for checking subsampling

2017-06-30 Thread Thierry Escande
From: Tony K Nadackal <tony...@samsung.com>

Corrects the WARN_ON statement for subsampling based on the
JPEG Hardware version.

Signed-off-by: Tony K Nadackal <tony...@samsung.com>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
Acked-by: Andrzej Pietrasiewicz <andrze...@samsung.com>
Acked-by: Jacek Anaszewski <jacek.anaszew...@gmail.com>
---
 drivers/media/platform/s5p-jpeg/jpeg-core.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c 
b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index 623508d..0d935f5 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -614,24 +614,26 @@ static inline struct s5p_jpeg_ctx *fh_to_ctx(struct 
v4l2_fh *fh)
 
 static int s5p_jpeg_to_user_subsampling(struct s5p_jpeg_ctx *ctx)
 {
-   WARN_ON(ctx->subsampling > 3);
-
switch (ctx->jpeg->variant->version) {
case SJPEG_S5P:
+   WARN_ON(ctx->subsampling > 3);
if (ctx->subsampling > 2)
return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
return ctx->subsampling;
case SJPEG_EXYNOS3250:
case SJPEG_EXYNOS5420:
+   WARN_ON(ctx->subsampling > 6);
if (ctx->subsampling > 3)
return V4L2_JPEG_CHROMA_SUBSAMPLING_411;
return exynos3250_decoded_subsampling[ctx->subsampling];
case SJPEG_EXYNOS4:
case SJPEG_EXYNOS5433:
+   WARN_ON(ctx->subsampling > 3);
if (ctx->subsampling > 2)
return V4L2_JPEG_CHROMA_SUBSAMPLING_420;
return exynos4x12_decoded_subsampling[ctx->subsampling];
default:
+   WARN_ON(ctx->subsampling > 3);
return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
}
 }
-- 
2.7.4



[PATCH v4 0/8] [media] s5p-jpeg: Various fixes and improvements

2017-06-30 Thread Thierry Escande
Hi,

This series contains various fixes and improvements for the Samsung
s5p-jpeg driver. Most of these patches come from the Chromium v3.8
kernel tree.

In this v4:
- Correct a typo in patch #04 commit message (Thanks Jacek)
- Add Acked-by from Andrzej and Jacek for the whole series  

v3:
- Remove codec reset patch (Not needed based on documentation and no
  use case described in original patch commit message).
- Check for Exynos5420 variant in stream error handling patch.
- Add use case for resolution change event support in commit message.
- Move subsampling value decoding in a separate function.
- Check Exynos variant for 4:1:1 subsampling support.

v2:
- Remove IOMMU support patch (mapping now created automatically for
  single JPEG CODEC device).
- Remove "Change sclk_jpeg to 166MHz" patch (can be set through DT
  properties).
- Remove support for multi-planar APIs (Not needed).
- Add comment regarding call to jpeg_bound_align_image() after qbuf.
- Remove unrelated code from resolution change event support patch.

Thierry Escande (3):
  [media] s5p-jpeg: Handle parsing error in s5p_jpeg_parse_hdr()
  [media] s5p-jpeg: Don't use temporary structure in s5p_jpeg_buf_queue
  [media] s5p-jpeg: Split s5p_jpeg_parse_hdr()

Tony K Nadackal (3):
  [media] s5p-jpeg: Call jpeg_bound_align_image after qbuf
  [media] s5p-jpeg: Correct WARN_ON statement for checking subsampling
  [media] s5p-jpeg: Decode 4:1:1 chroma subsampling format

henryhsu (2):
  [media] s5p-jpeg: Add support for resolution change event
  [media] s5p-jpeg: Add stream error handling for Exynos5420

 drivers/media/platform/s5p-jpeg/jpeg-core.c | 186 +---
 drivers/media/platform/s5p-jpeg/jpeg-core.h |   7 ++
 2 files changed, 148 insertions(+), 45 deletions(-)

-- 
2.7.4



[PATCH v3 0/8] [media] s5p-jpeg: Various fixes and improvements

2017-06-27 Thread Thierry Escande
Hi,

This series contains various fixes and improvements for the Samsung
s5p-jpeg driver. Most of these patches come from the Chromium v3.8
kernel tree.

In this v3:
- Remove codec reset patch (Not needed based on documentation and no
  use case described in original patch commit message).
- Check for Exynos5420 variant in stream error handling patch.
- Add use case for resolution change event support in commit message.
- Move subsampling value decoding in a separate function.
- Check Exynos variant for 4:1:1 subsampling support.

v2:
- Remove IOMMU support patch (mapping now created automatically for
  single JPEG CODEC device).
- Remove "Change sclk_jpeg to 166MHz" patch (can be set through DT
  properties).
- Remove support for multi-planar APIs (Not needed).
- Add comment regarding call to jpeg_bound_align_image() after qbuf.
- Remove unrelated code from resolution change event support patch.

Thierry Escande (3):
  [media] s5p-jpeg: Handle parsing error in s5p_jpeg_parse_hdr()
  [media] s5p-jpeg: Don't use temporary structure in s5p_jpeg_buf_queue
  [media] s5p-jpeg: Split s5p_jpeg_parse_hdr()

Tony K Nadackal (3):
  [media] s5p-jpeg: Call jpeg_bound_align_image after qbuf
  [media] s5p-jpeg: Correct WARN_ON statement for checking subsampling
  [media] s5p-jpeg: Decode 4:1:1 chroma subsampling format

henryhsu (2):
  [media] s5p-jpeg: Add support for resolution change event
  [media] s5p-jpeg: Add stream error handling for Exynos5420

 drivers/media/platform/s5p-jpeg/jpeg-core.c | 186 +---
 drivers/media/platform/s5p-jpeg/jpeg-core.h |   7 ++
 2 files changed, 148 insertions(+), 45 deletions(-)

-- 
2.7.4



[PATCH v3 4/8] [media] s5p-jpeg: Don't use temporary structure in s5p_jpeg_buf_queue

2017-06-27 Thread Thierry Escande
If s5p_jpeg_parse_hdr() fails to parse the JPEG header, the passed
s5p_jpeg_q_data structure is not modify so there is no need to use a
temporary structure and the field-by-field copy can be avoided.

Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
---
 drivers/media/platform/s5p-jpeg/jpeg-core.c | 23 ---
 1 file changed, 4 insertions(+), 19 deletions(-)

diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c 
b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index df3e5ee..1769744 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -2500,9 +2500,9 @@ static void s5p_jpeg_buf_queue(struct vb2_buffer *vb)
 
if (ctx->mode == S5P_JPEG_DECODE &&
vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
-   struct s5p_jpeg_q_data tmp, *q_data;
+   struct s5p_jpeg_q_data *q_data;
 
-   ctx->hdr_parsed = s5p_jpeg_parse_hdr(,
+   ctx->hdr_parsed = s5p_jpeg_parse_hdr(>out_q,
 (unsigned long)vb2_plane_vaddr(vb, 0),
 min((unsigned long)ctx->out_q.size,
 vb2_get_plane_payload(vb, 0)), ctx);
@@ -2511,24 +2511,9 @@ static void s5p_jpeg_buf_queue(struct vb2_buffer *vb)
return;
}
 
-   q_data = >out_q;
-   q_data->w = tmp.w;
-   q_data->h = tmp.h;
-   q_data->sos = tmp.sos;
-   memcpy(q_data->dht.marker, tmp.dht.marker,
-  sizeof(tmp.dht.marker));
-   memcpy(q_data->dht.len, tmp.dht.len, sizeof(tmp.dht.len));
-   q_data->dht.n = tmp.dht.n;
-   memcpy(q_data->dqt.marker, tmp.dqt.marker,
-  sizeof(tmp.dqt.marker));
-   memcpy(q_data->dqt.len, tmp.dqt.len, sizeof(tmp.dqt.len));
-   q_data->dqt.n = tmp.dqt.n;
-   q_data->sof = tmp.sof;
-   q_data->sof_len = tmp.sof_len;
-
q_data = >cap_q;
-   q_data->w = tmp.w;
-   q_data->h = tmp.h;
+   q_data->w = ctx->out_q.w;
+   q_data->h = ctx->out_q.h;
 
/*
 * This call to jpeg_bound_align_image() takes care of width and
-- 
2.7.4



[PATCH v3 7/8] [media] s5p-jpeg: Add support for resolution change event

2017-06-27 Thread Thierry Escande
From: henryhsu <henry...@chromium.org>

This patch adds support for resolution change event to notify clients so
they can prepare correct output buffer. When resolution change happened,
G_FMT for CAPTURE should return old resolution and format before CAPTURE
queues streamoff.

This event is used in the Chromium browser project by the V4L2 JPEG
Decode Accelerator (V4L2JDA) to allocate output buffer.

Signed-off-by: Henry-Ruey Hsu <henry...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
---
 drivers/media/platform/s5p-jpeg/jpeg-core.c | 106 +---
 drivers/media/platform/s5p-jpeg/jpeg-core.h |   7 ++
 2 files changed, 89 insertions(+), 24 deletions(-)

diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c 
b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index cca0fb8..5ad3d43 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -24,6 +24,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -1633,8 +1634,6 @@ static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct 
v4l2_format *f)
FMT_TYPE_OUTPUT : FMT_TYPE_CAPTURE;
 
q_data->fmt = s5p_jpeg_find_format(ct, pix->pixelformat, f_type);
-   q_data->w = pix->width;
-   q_data->h = pix->height;
if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG) {
/*
 * During encoding Exynos4x12 SoCs access wider memory area
@@ -1642,6 +1641,8 @@ static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct 
v4l2_format *f)
 * the JPEG_IMAGE_SIZE register. In order to avoid sysmmu
 * page fault calculate proper buffer size in such a case.
 */
+   q_data->w = pix->width;
+   q_data->h = pix->height;
if (ct->jpeg->variant->hw_ex4_compat &&
f_type == FMT_TYPE_OUTPUT && ct->mode == S5P_JPEG_ENCODE)
q_data->size = exynos4_jpeg_get_output_buffer_size(ct,
@@ -1717,6 +1718,15 @@ static int s5p_jpeg_s_fmt_vid_out(struct file *file, 
void *priv,
return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
 }
 
+static int s5p_jpeg_subscribe_event(struct v4l2_fh *fh,
+   const struct v4l2_event_subscription *sub)
+{
+   if (sub->type == V4L2_EVENT_SOURCE_CHANGE)
+   return v4l2_src_change_event_subscribe(fh, sub);
+
+   return -EINVAL;
+}
+
 static int exynos3250_jpeg_try_downscale(struct s5p_jpeg_ctx *ctx,
   struct v4l2_rect *r)
 {
@@ -2042,6 +2052,9 @@ static const struct v4l2_ioctl_ops s5p_jpeg_ioctl_ops = {
 
.vidioc_g_selection = s5p_jpeg_g_selection,
.vidioc_s_selection = s5p_jpeg_s_selection,
+
+   .vidioc_subscribe_event = s5p_jpeg_subscribe_event,
+   .vidioc_unsubscribe_event   = v4l2_event_unsubscribe,
 };
 
 /*
@@ -2434,8 +2447,17 @@ static int s5p_jpeg_job_ready(void *priv)
 {
struct s5p_jpeg_ctx *ctx = priv;
 
-   if (ctx->mode == S5P_JPEG_DECODE)
+   if (ctx->mode == S5P_JPEG_DECODE) {
+   /*
+* We have only one input buffer and one output buffer. If there
+* is a resolution change event, no need to continue decoding.
+*/
+   if (ctx->state == JPEGCTX_RESOLUTION_CHANGE)
+   return 0;
+
return ctx->hdr_parsed;
+   }
+
return 1;
 }
 
@@ -2514,6 +2536,30 @@ static int s5p_jpeg_buf_prepare(struct vb2_buffer *vb)
return 0;
 }
 
+static void s5p_jpeg_set_capture_queue_data(struct s5p_jpeg_ctx *ctx)
+{
+   struct s5p_jpeg_q_data *q_data = >cap_q;
+
+   q_data->w = ctx->out_q.w;
+   q_data->h = ctx->out_q.h;
+
+   /*
+* This call to jpeg_bound_align_image() takes care of width and
+* height values alignment when user space calls the QBUF of
+* OUTPUT buffer after the S_FMT of CAPTURE buffer.
+* Please note that on Exynos4x12 SoCs, resigning from executing
+* S_FMT on capture buffer for each JPEG image can result in a
+* hardware hangup if subsampling is lower than the one of input
+* JPEG.
+*/
+   jpeg_bound_align_image(ctx, _data->w, S5P_JPEG_MIN_WIDTH,
+  S5P_JPEG_MAX_WIDTH, q_data->fmt->h_align,
+  _data->h, S5P_JPEG_MIN_HEIGHT,
+  S5P_JPEG_MAX_HEIGHT, q_data->fmt->v_align);
+
+   q_data->size = q_data->w * q_data->h * q_data->fmt->depth >> 3;
+}
+
 static void s5p_jpeg_buf_queue(struct vb2_buffer *vb)
 {
struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
@@ -2521,7 +2567,18 @@ static void s5p_jpeg_buf_queue(struct vb2_buffer *vb)
 
 

[PATCH v3 6/8] [media] s5p-jpeg: Decode 4:1:1 chroma subsampling format

2017-06-27 Thread Thierry Escande
From: Tony K Nadackal <tony...@samsung.com>

This patch adds support for decoding 4:1:1 chroma subsampling in the
jpeg header parsing function.

Signed-off-by: Tony K Nadackal <tony...@samsung.com>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
---
 drivers/media/platform/s5p-jpeg/jpeg-core.c | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c 
b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index 0783809..cca0fb8 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -1099,6 +1099,8 @@ static void skip(struct s5p_jpeg_buffer *buf, long len)
 static bool s5p_jpeg_subsampling_decode(struct s5p_jpeg_ctx *ctx,
unsigned int subsampling)
 {
+   unsigned int version;
+
switch (subsampling) {
case 0x11:
ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444;
@@ -1112,6 +1114,19 @@ static bool s5p_jpeg_subsampling_decode(struct 
s5p_jpeg_ctx *ctx,
case 0x33:
ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
break;
+   case 0x41:
+   /*
+* 4:1:1 subsampling only supported by 3250, 5420, and 5433
+* variants
+*/
+   version = ctx->jpeg->variant->version;
+   if (version != SJPEG_EXYNOS3250 &&
+   version != SJPEG_EXYNOS5420 &&
+   version != SJPEG_EXYNOS5433)
+   return false;
+
+   ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_411;
+   break;
default:
return false;
}
-- 
2.7.4



[PATCH v3 3/8] [media] s5p-jpeg: Handle parsing error in s5p_jpeg_parse_hdr()

2017-06-27 Thread Thierry Escande
This patch modifies the s5p_jpeg_parse_hdr() function so it only
modifies the passed s5p_jpeg_q_data structure if the jpeg header parsing
is successful.

Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
---
 drivers/media/platform/s5p-jpeg/jpeg-core.c | 38 -
 1 file changed, 21 insertions(+), 17 deletions(-)

diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c 
b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index 0d935f5..df3e5ee 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -1206,22 +1206,9 @@ static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data 
*result,
break;
}
}
-   result->w = width;
-   result->h = height;
-   result->sos = sos;
-   result->dht.n = n_dht;
-   while (n_dht--) {
-   result->dht.marker[n_dht] = dht[n_dht];
-   result->dht.len[n_dht] = dht_len[n_dht];
-   }
-   result->dqt.n = n_dqt;
-   while (n_dqt--) {
-   result->dqt.marker[n_dqt] = dqt[n_dqt];
-   result->dqt.len[n_dqt] = dqt_len[n_dqt];
-   }
-   result->sof = sof;
-   result->sof_len = sof_len;
-   result->size = result->components = components;
+
+   if (notfound || !sos)
+   return false;
 
switch (subsampling) {
case 0x11:
@@ -1240,7 +1227,24 @@ static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data 
*result,
return false;
}
 
-   return !notfound && sos;
+   result->w = width;
+   result->h = height;
+   result->sos = sos;
+   result->dht.n = n_dht;
+   while (n_dht--) {
+   result->dht.marker[n_dht] = dht[n_dht];
+   result->dht.len[n_dht] = dht_len[n_dht];
+   }
+   result->dqt.n = n_dqt;
+   while (n_dqt--) {
+   result->dqt.marker[n_dqt] = dqt[n_dqt];
+   result->dqt.len[n_dqt] = dqt_len[n_dqt];
+   }
+   result->sof = sof;
+   result->sof_len = sof_len;
+   result->size = result->components = components;
+
+   return true;
 }
 
 static int s5p_jpeg_querycap(struct file *file, void *priv,
-- 
2.7.4



[PATCH v3 8/8] [media] s5p-jpeg: Add stream error handling for Exynos5420

2017-06-27 Thread Thierry Escande
From: henryhsu <henry...@chromium.org>

On Exynos5420, the STREAM_STAT bit raised on the JPGINTST register means
there is a syntax error or an unrecoverable error on compressed file
when ERR_INT_EN is set to 1.

Fix this case and report BUF_STATE_ERROR to videobuf2.

Signed-off-by: Henry-Ruey Hsu <henry...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
---
 drivers/media/platform/s5p-jpeg/jpeg-core.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c 
b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index 5ad3d43..c35d169 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -2812,6 +2812,7 @@ static irqreturn_t exynos3250_jpeg_irq(int irq, void 
*dev_id)
unsigned long payload_size = 0;
enum vb2_buffer_state state = VB2_BUF_STATE_DONE;
bool interrupt_timeout = false;
+   bool stream_error = false;
u32 irq_status;
 
spin_lock(>slock);
@@ -2828,6 +2829,12 @@ static irqreturn_t exynos3250_jpeg_irq(int irq, void 
*dev_id)
 
jpeg->irq_status |= irq_status;
 
+   if (jpeg->variant->version == SJPEG_EXYNOS5420 &&
+   irq_status & EXYNOS3250_STREAM_STAT) {
+   stream_error = true;
+   dev_err(jpeg->dev, "Syntax error or unrecoverable error 
occurred.\n");
+   }
+
curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
 
if (!curr_ctx)
@@ -2844,7 +2851,7 @@ static irqreturn_t exynos3250_jpeg_irq(int irq, void 
*dev_id)
EXYNOS3250_RDMA_DONE |
EXYNOS3250_RESULT_STAT))
payload_size = exynos3250_jpeg_compressed_size(jpeg->regs);
-   else if (interrupt_timeout)
+   else if (interrupt_timeout || stream_error)
state = VB2_BUF_STATE_ERROR;
else
goto exit_unlock;
-- 
2.7.4



[PATCH v3 5/8] [media] s5p-jpeg: Split s5p_jpeg_parse_hdr()

2017-06-27 Thread Thierry Escande
This patch moves the subsampling value decoding read from the jpeg
header into its own function. This new function is called
s5p_jpeg_subsampling_decode() and returns true if it successfully
decodes the subsampling value, false otherwise.

Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
---
 drivers/media/platform/s5p-jpeg/jpeg-core.c | 42 -
 1 file changed, 24 insertions(+), 18 deletions(-)

diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c 
b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index 1769744..0783809 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -1096,6 +1096,29 @@ static void skip(struct s5p_jpeg_buffer *buf, long len)
get_byte(buf);
 }
 
+static bool s5p_jpeg_subsampling_decode(struct s5p_jpeg_ctx *ctx,
+   unsigned int subsampling)
+{
+   switch (subsampling) {
+   case 0x11:
+   ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444;
+   break;
+   case 0x21:
+   ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422;
+   break;
+   case 0x22:
+   ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420;
+   break;
+   case 0x33:
+   ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
+   break;
+   default:
+   return false;
+   }
+
+   return true;
+}
+
 static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result,
   unsigned long buffer, unsigned long size,
   struct s5p_jpeg_ctx *ctx)
@@ -1207,26 +1230,9 @@ static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data 
*result,
}
}
 
-   if (notfound || !sos)
+   if (notfound || !sos || !s5p_jpeg_subsampling_decode(ctx, subsampling))
return false;
 
-   switch (subsampling) {
-   case 0x11:
-   ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444;
-   break;
-   case 0x21:
-   ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422;
-   break;
-   case 0x22:
-   ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420;
-   break;
-   case 0x33:
-   ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
-   break;
-   default:
-   return false;
-   }
-
result->w = width;
result->h = height;
result->sos = sos;
-- 
2.7.4



[PATCH v3 2/8] [media] s5p-jpeg: Correct WARN_ON statement for checking subsampling

2017-06-27 Thread Thierry Escande
From: Tony K Nadackal <tony...@samsung.com>

Corrects the WARN_ON statement for subsampling based on the
JPEG Hardware version.

Signed-off-by: Tony K Nadackal <tony...@samsung.com>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
---
 drivers/media/platform/s5p-jpeg/jpeg-core.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c 
b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index 623508d..0d935f5 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -614,24 +614,26 @@ static inline struct s5p_jpeg_ctx *fh_to_ctx(struct 
v4l2_fh *fh)
 
 static int s5p_jpeg_to_user_subsampling(struct s5p_jpeg_ctx *ctx)
 {
-   WARN_ON(ctx->subsampling > 3);
-
switch (ctx->jpeg->variant->version) {
case SJPEG_S5P:
+   WARN_ON(ctx->subsampling > 3);
if (ctx->subsampling > 2)
return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
return ctx->subsampling;
case SJPEG_EXYNOS3250:
case SJPEG_EXYNOS5420:
+   WARN_ON(ctx->subsampling > 6);
if (ctx->subsampling > 3)
return V4L2_JPEG_CHROMA_SUBSAMPLING_411;
return exynos3250_decoded_subsampling[ctx->subsampling];
case SJPEG_EXYNOS4:
case SJPEG_EXYNOS5433:
+   WARN_ON(ctx->subsampling > 3);
if (ctx->subsampling > 2)
return V4L2_JPEG_CHROMA_SUBSAMPLING_420;
return exynos4x12_decoded_subsampling[ctx->subsampling];
default:
+   WARN_ON(ctx->subsampling > 3);
return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
}
 }
-- 
2.7.4



[PATCH v3 1/8] [media] s5p-jpeg: Call jpeg_bound_align_image after qbuf

2017-06-27 Thread Thierry Escande
From: Tony K Nadackal <tony...@samsung.com>

When queuing an OUTPUT buffer for decoder, s5p_jpeg_parse_hdr()
function parses the input jpeg file and takes the width and height
parameters from its header. These new width/height values will be used
for the calculation of stride. HX_JPEG Hardware needs the width and
height values aligned on a 16 bits boundary. This width/height alignment
is handled in the s5p_jpeg_s_fmt_vid_cap() function during the S_FMT
ioctl call.

But if user space calls the QBUF of OUTPUT buffer after the S_FMT of
CAPTURE buffer, these aligned values will be replaced by the values in
jpeg header. If the width/height values of jpeg are not aligned, the
decoder output will be corrupted. So in this patch we call
jpeg_bound_align_image() to align the width/height values of Capture
buffer in s5p_jpeg_buf_queue().

Signed-off-by: Tony K Nadackal <tony...@samsung.com>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
---
 drivers/media/platform/s5p-jpeg/jpeg-core.c | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c 
b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index 52dc794..623508d 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -2523,6 +2523,25 @@ static void s5p_jpeg_buf_queue(struct vb2_buffer *vb)
q_data = >cap_q;
q_data->w = tmp.w;
q_data->h = tmp.h;
+
+   /*
+* This call to jpeg_bound_align_image() takes care of width and
+* height values alignment when user space calls the QBUF of
+* OUTPUT buffer after the S_FMT of CAPTURE buffer.
+* Please note that on Exynos4x12 SoCs, resigning from executing
+* S_FMT on capture buffer for each JPEG image can result in a
+* hardware hangup if subsampling is lower than the one of input
+* JPEG.
+*/
+   jpeg_bound_align_image(ctx,
+  _data->w,
+  S5P_JPEG_MIN_WIDTH, S5P_JPEG_MAX_WIDTH,
+  q_data->fmt->h_align,
+  _data->h,
+  S5P_JPEG_MIN_HEIGHT, S5P_JPEG_MAX_HEIGHT,
+  q_data->fmt->v_align);
+
+   q_data->size = q_data->w * q_data->h * q_data->fmt->depth >> 3;
}
 
v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
-- 
2.7.4



Re: [PATCH v2 5/6] [media] s5p-jpeg: Add support for resolution change event

2017-06-20 Thread Thierry Escande

Hi Andrzej,

On 20/06/2017 12:51, Andrzej Pietrasiewicz wrote:

Hi Thierry,

W dniu 19.06.2017 o 15:50, Thierry Escande pisze:

Hi Andrzej,

On 16/06/2017 17:38, Andrzej Pietrasiewicz wrote:

Hi Thierry,

Thank you for the patch.

Can you give a use case for resolution change event?

Unfortunately, the original commit does not mention any clear use case.
I've asked to the patch author for more information.


Can you please share what you learn about it if the author gets back to 
you?

Now that we don't know why to apply a patch I guess we should not do it.
This event is used in Chromium by the V4L2 jpeg decode accelerator to 
allocate output buffer. Please see:

https://cs.chromium.org/chromium/src/media/gpu/v4l2_jpeg_decode_accelerator.cc?rcl=91793c6ef94f05e93d258db8c7f3cad59819c6b8=585

I'll add a note in the commit message.






@@ -2510,43 +2567,18 @@ static void s5p_jpeg_buf_queue(struct
vb2_buffer *vb)
   return;
   }
-q_data = >out_q;
-q_data->w = tmp.w;
-q_data->h = tmp.h;
-q_data->sos = tmp.sos;
-memcpy(q_data->dht.marker, tmp.dht.marker,
-   sizeof(tmp.dht.marker));
-memcpy(q_data->dht.len, tmp.dht.len, sizeof(tmp.dht.len));
-q_data->dht.n = tmp.dht.n;
-memcpy(q_data->dqt.marker, tmp.dqt.marker,
-   sizeof(tmp.dqt.marker));
-memcpy(q_data->dqt.len, tmp.dqt.len, sizeof(tmp.dqt.len));
-q_data->dqt.n = tmp.dqt.n;
-q_data->sof = tmp.sof;
-q_data->sof_len = tmp.sof_len;
-
-q_data = >cap_q;
-q_data->w = tmp.w;
-q_data->h = tmp.h;



Why is this part removed?

This has not been removed.
The  s5p_jpeg_q_data struct was passed to s5p_jpeg_parse_hdr() and
then copied field-by-field into ctx->out_q (through q_data pointer).
With this change ctx->out_q is passed to s5p_jpeg_parse_hdr() and this
avoids the copy.


It seems that changing field-by-field copying to passing a pointer
directly to s5p_jpeg_parse_hdr() is an unrelated change and as such
should be in a separate patch.

Will do.

Regards,
 Thierry


Re: [PATCH v2 5/6] [media] s5p-jpeg: Add support for resolution change event

2017-06-19 Thread Thierry Escande

Hi Andrzej,

On 16/06/2017 17:38, Andrzej Pietrasiewicz wrote:

Hi Thierry,

Thank you for the patch.

Can you give a use case for resolution change event?
Unfortunately, the original commit does not mention any clear use case. 
I've asked to the patch author for more information.



Also plase see inline.

W dniu 12.06.2017 o 19:13, Thierry Escande pisze:

From: henryhsu <henry...@chromium.org>
@@ -1611,8 +1612,6 @@ static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx 
*ct, struct v4l2_format *f)

  FMT_TYPE_OUTPUT : FMT_TYPE_CAPTURE;
  q_data->fmt = s5p_jpeg_find_format(ct, pix->pixelformat, f_type);
-q_data->w = pix->width;
-q_data->h = pix->height;
  if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG) {
  /*
   * During encoding Exynos4x12 SoCs access wider memory area
@@ -1620,6 +1619,8 @@ static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx 
*ct, struct v4l2_format *f)

   * the JPEG_IMAGE_SIZE register. In order to avoid sysmmu
   * page fault calculate proper buffer size in such a case.
   */
+q_data->w = pix->width;
+q_data->h = pix->height;


Is this change related to what the patch is supposed to be doing?

Yes actually. From the author comments to the same question:
"We want to send a resolution change in the first frame. Without this, 
q_data->w and h will be updated by s_fmt. Then we won't know the 
resolution is changed from (0, 0) to (w, h) in qbuf function."



  static void s5p_jpeg_buf_queue(struct vb2_buffer *vb)
  {
  struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
@@ -2499,9 +2545,20 @@ static void s5p_jpeg_buf_queue(struct 
vb2_buffer *vb)

  if (ctx->mode == S5P_JPEG_DECODE &&
  vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
-struct s5p_jpeg_q_data tmp, *q_data;
-
-ctx->hdr_parsed = s5p_jpeg_parse_hdr(,
+static const struct v4l2_event ev_src_ch = {
+.type = V4L2_EVENT_SOURCE_CHANGE,
+.u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION,
+};
+struct vb2_queue *dst_vq;
+u32 ori_w;
+u32 ori_h;
+
+dst_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
+ V4L2_BUF_TYPE_VIDEO_CAPTURE);
+ori_w = ctx->out_q.w;
+ori_h = ctx->out_q.h;
+
+ctx->hdr_parsed = s5p_jpeg_parse_hdr(>out_q,
   (unsigned long)vb2_plane_vaddr(vb, 0),
   min((unsigned long)ctx->out_q.size,
   vb2_get_plane_payload(vb, 0)), ctx);
@@ -2510,43 +2567,18 @@ static void s5p_jpeg_buf_queue(struct 
vb2_buffer *vb)

  return;
  }
-q_data = >out_q;
-q_data->w = tmp.w;
-q_data->h = tmp.h;
-q_data->sos = tmp.sos;
-memcpy(q_data->dht.marker, tmp.dht.marker,
-   sizeof(tmp.dht.marker));
-memcpy(q_data->dht.len, tmp.dht.len, sizeof(tmp.dht.len));
-q_data->dht.n = tmp.dht.n;
-memcpy(q_data->dqt.marker, tmp.dqt.marker,
-   sizeof(tmp.dqt.marker));
-memcpy(q_data->dqt.len, tmp.dqt.len, sizeof(tmp.dqt.len));
-q_data->dqt.n = tmp.dqt.n;
-q_data->sof = tmp.sof;
-q_data->sof_len = tmp.sof_len;
-
-q_data = >cap_q;
-q_data->w = tmp.w;
-q_data->h = tmp.h;



Why is this part removed?

This has not been removed.
The  s5p_jpeg_q_data struct was passed to s5p_jpeg_parse_hdr() and 
then copied field-by-field into ctx->out_q (through q_data pointer).
With this change ctx->out_q is passed to s5p_jpeg_parse_hdr() and this 
avoids the copy.
Then ctx->cap_q width & height copy is done in 
s5p_jpeg_set_capture_queue_data().


Regards,
 Thierry


[PATCH v2 6/6] [media] s5p-jpeg: Add stream error handling for Exynos5420

2017-06-12 Thread Thierry Escande
From: henryhsu <henry...@chromium.org>

On Exynos5420, the STREAM_STAT bit raised on the JPGINTST register means
there is a syntax error or an unrecoverable error on compressed file
when ERR_INT_EN is set to 1.

Fix this case and report BUF_STATE_ERROR to videobuf2.

Signed-off-by: Henry-Ruey Hsu <henry...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
---
 drivers/media/platform/s5p-jpeg/jpeg-core.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c 
b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index 3d90a63..1a07a82 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -2790,6 +2790,7 @@ static irqreturn_t exynos3250_jpeg_irq(int irq, void 
*dev_id)
unsigned long payload_size = 0;
enum vb2_buffer_state state = VB2_BUF_STATE_DONE;
bool interrupt_timeout = false;
+   bool stream_error = false;
u32 irq_status;
 
spin_lock(>slock);
@@ -2806,6 +2807,11 @@ static irqreturn_t exynos3250_jpeg_irq(int irq, void 
*dev_id)
 
jpeg->irq_status |= irq_status;
 
+   if (irq_status & EXYNOS3250_STREAM_STAT) {
+   stream_error = true;
+   dev_err(jpeg->dev, "Syntax error or unrecoverable error 
occurred.\n");
+   }
+
curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
 
if (!curr_ctx)
@@ -2822,7 +2828,7 @@ static irqreturn_t exynos3250_jpeg_irq(int irq, void 
*dev_id)
EXYNOS3250_RDMA_DONE |
EXYNOS3250_RESULT_STAT))
payload_size = exynos3250_jpeg_compressed_size(jpeg->regs);
-   else if (interrupt_timeout)
+   else if (interrupt_timeout || stream_error)
state = VB2_BUF_STATE_ERROR;
else
goto exit_unlock;
-- 
2.7.4



[PATCH v2 3/6] [media] s5p-jpeg: Correct WARN_ON statement for checking subsampling

2017-06-12 Thread Thierry Escande
From: Tony K Nadackal <tony...@samsung.com>

Corrects the WARN_ON statement for subsampling based on the
JPEG Hardware version.

Signed-off-by: Tony K Nadackal <tony...@samsung.com>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
---
 drivers/media/platform/s5p-jpeg/jpeg-core.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c 
b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index 623508d..0d935f5 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -614,24 +614,26 @@ static inline struct s5p_jpeg_ctx *fh_to_ctx(struct 
v4l2_fh *fh)
 
 static int s5p_jpeg_to_user_subsampling(struct s5p_jpeg_ctx *ctx)
 {
-   WARN_ON(ctx->subsampling > 3);
-
switch (ctx->jpeg->variant->version) {
case SJPEG_S5P:
+   WARN_ON(ctx->subsampling > 3);
if (ctx->subsampling > 2)
return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
return ctx->subsampling;
case SJPEG_EXYNOS3250:
case SJPEG_EXYNOS5420:
+   WARN_ON(ctx->subsampling > 6);
if (ctx->subsampling > 3)
return V4L2_JPEG_CHROMA_SUBSAMPLING_411;
return exynos3250_decoded_subsampling[ctx->subsampling];
case SJPEG_EXYNOS4:
case SJPEG_EXYNOS5433:
+   WARN_ON(ctx->subsampling > 3);
if (ctx->subsampling > 2)
return V4L2_JPEG_CHROMA_SUBSAMPLING_420;
return exynos4x12_decoded_subsampling[ctx->subsampling];
default:
+   WARN_ON(ctx->subsampling > 3);
return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
}
 }
-- 
2.7.4



[PATCH v2 0/6] [media] s5p-jpeg: Various fixes and improvements

2017-06-12 Thread Thierry Escande
Hi,

This series contains various fixes and improvements for the Samsung
s5p-jpeg driver. All these patches come from the Chromium v3.8 kernel
tree.

In this v2:
- Remove IOMMU support patch (mapping now created automatically for
  single JPEG CODEC device).
- Remove "Change sclk_jpeg to 166MHz" patch (can be set through DT
  properties).
- Remove support for multi-planar APIs (Not needed).
- Add comment regarding call to jpeg_bound_align_image() after qbuf.
- Remove unrelated code from resolution change event support patch.

Regards,
 Thierry

Abhilash Kesavan (1):
  [media] s5p-jpeg: Reset the Codec before doing a soft reset

Tony K Nadackal (3):
  [media] s5p-jpeg: Call jpeg_bound_align_image after qbuf
  [media] s5p-jpeg: Correct WARN_ON statement for checking subsampling
  [media] s5p-jpeg: Decode 4:1:1 chroma subsampling format

henryhsu (2):
  [media] s5p-jpeg: Add support for resolution change event
  [media] s5p-jpeg: Add stream error handling for Exynos5420

 drivers/media/platform/s5p-jpeg/jpeg-core.c   | 140 +-
 drivers/media/platform/s5p-jpeg/jpeg-core.h   |   7 ++
 drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c |   4 +
 3 files changed, 122 insertions(+), 29 deletions(-)

-- 
2.7.4



[PATCH v2 5/6] [media] s5p-jpeg: Add support for resolution change event

2017-06-12 Thread Thierry Escande
From: henryhsu <henry...@chromium.org>

This patch adds support for resolution change event to notify clients so
they can prepare correct output buffer. When resolution change happened,
G_FMT for CAPTURE should return old resolution and format before CAPTURE
queues streamoff.

Signed-off-by: Henry-Ruey Hsu <henry...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
---
 drivers/media/platform/s5p-jpeg/jpeg-core.c | 125 +++-
 drivers/media/platform/s5p-jpeg/jpeg-core.h |   7 ++
 2 files changed, 91 insertions(+), 41 deletions(-)

diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c 
b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index 7ef7173..3d90a63 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -24,6 +24,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -1611,8 +1612,6 @@ static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct 
v4l2_format *f)
FMT_TYPE_OUTPUT : FMT_TYPE_CAPTURE;
 
q_data->fmt = s5p_jpeg_find_format(ct, pix->pixelformat, f_type);
-   q_data->w = pix->width;
-   q_data->h = pix->height;
if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG) {
/*
 * During encoding Exynos4x12 SoCs access wider memory area
@@ -1620,6 +1619,8 @@ static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct 
v4l2_format *f)
 * the JPEG_IMAGE_SIZE register. In order to avoid sysmmu
 * page fault calculate proper buffer size in such a case.
 */
+   q_data->w = pix->width;
+   q_data->h = pix->height;
if (ct->jpeg->variant->hw_ex4_compat &&
f_type == FMT_TYPE_OUTPUT && ct->mode == S5P_JPEG_ENCODE)
q_data->size = exynos4_jpeg_get_output_buffer_size(ct,
@@ -1695,6 +1696,15 @@ static int s5p_jpeg_s_fmt_vid_out(struct file *file, 
void *priv,
return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
 }
 
+static int s5p_jpeg_subscribe_event(struct v4l2_fh *fh,
+   const struct v4l2_event_subscription *sub)
+{
+   if (sub->type == V4L2_EVENT_SOURCE_CHANGE)
+   return v4l2_src_change_event_subscribe(fh, sub);
+
+   return -EINVAL;
+}
+
 static int exynos3250_jpeg_try_downscale(struct s5p_jpeg_ctx *ctx,
   struct v4l2_rect *r)
 {
@@ -2020,6 +2030,9 @@ static const struct v4l2_ioctl_ops s5p_jpeg_ioctl_ops = {
 
.vidioc_g_selection = s5p_jpeg_g_selection,
.vidioc_s_selection = s5p_jpeg_s_selection,
+
+   .vidioc_subscribe_event = s5p_jpeg_subscribe_event,
+   .vidioc_unsubscribe_event   = v4l2_event_unsubscribe,
 };
 
 /*
@@ -2412,8 +2425,17 @@ static int s5p_jpeg_job_ready(void *priv)
 {
struct s5p_jpeg_ctx *ctx = priv;
 
-   if (ctx->mode == S5P_JPEG_DECODE)
+   if (ctx->mode == S5P_JPEG_DECODE) {
+   /*
+* We have only one input buffer and one output buffer. If there
+* is a resolution change event, no need to continue decoding.
+*/
+   if (ctx->state == JPEGCTX_RESOLUTION_CHANGE)
+   return 0;
+
return ctx->hdr_parsed;
+   }
+
return 1;
 }
 
@@ -2492,6 +2514,30 @@ static int s5p_jpeg_buf_prepare(struct vb2_buffer *vb)
return 0;
 }
 
+static void s5p_jpeg_set_capture_queue_data(struct s5p_jpeg_ctx *ctx)
+{
+   struct s5p_jpeg_q_data *q_data = >cap_q;
+
+   q_data->w = ctx->out_q.w;
+   q_data->h = ctx->out_q.h;
+
+   /*
+* This call to jpeg_bound_align_image() takes care of width and
+* height values alignment when user space calls the QBUF of
+* OUTPUT buffer after the S_FMT of CAPTURE buffer.
+* Please note that on Exynos4x12 SoCs, resigning from executing
+* S_FMT on capture buffer for each JPEG image can result in a
+* hardware hangup if subsampling is lower than the one of input
+* JPEG.
+*/
+   jpeg_bound_align_image(ctx, _data->w, S5P_JPEG_MIN_WIDTH,
+  S5P_JPEG_MAX_WIDTH, q_data->fmt->h_align,
+  _data->h, S5P_JPEG_MIN_HEIGHT,
+  S5P_JPEG_MAX_HEIGHT, q_data->fmt->v_align);
+
+   q_data->size = q_data->w * q_data->h * q_data->fmt->depth >> 3;
+}
+
 static void s5p_jpeg_buf_queue(struct vb2_buffer *vb)
 {
struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
@@ -2499,9 +2545,20 @@ static void s5p_jpeg_buf_queue(struct vb2_buffer *vb)
 
if (ctx->mode == S5P_JPEG_DECODE &&
vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPU

[PATCH v2 4/6] [media] s5p-jpeg: Decode 4:1:1 chroma subsampling format

2017-06-12 Thread Thierry Escande
From: Tony K Nadackal <tony...@samsung.com>

This patch adds support for decoding 4:1:1 chroma subsampling in the
jpeg header parsing function.

Signed-off-by: Tony K Nadackal <tony...@samsung.com>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
---
 drivers/media/platform/s5p-jpeg/jpeg-core.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c 
b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index 0d935f5..7ef7173 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -1236,6 +1236,9 @@ static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data 
*result,
case 0x33:
ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
break;
+   case 0x41:
+   ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_411;
+   break;
default:
return false;
}
-- 
2.7.4



[PATCH v2 1/6] [media] s5p-jpeg: Reset the Codec before doing a soft reset

2017-06-12 Thread Thierry Escande
From: Abhilash Kesavan <a.kesa...@samsung.com>

This patch resets the encoding and decoding register bits before doing a
soft reset.

Signed-off-by: Tony K Nadackal <tony...@samsung.com>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
---
 drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c 
b/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c
index a1d823a..9ad8f6d 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c
@@ -21,6 +21,10 @@ void exynos4_jpeg_sw_reset(void __iomem *base)
unsigned int reg;
 
reg = readl(base + EXYNOS4_JPEG_CNTL_REG);
+   writel(reg & ~(EXYNOS4_DEC_MODE | EXYNOS4_ENC_MODE),
+  base + EXYNOS4_JPEG_CNTL_REG);
+
+   reg = readl(base + EXYNOS4_JPEG_CNTL_REG);
writel(reg & ~EXYNOS4_SOFT_RESET_HI, base + EXYNOS4_JPEG_CNTL_REG);
 
udelay(100);
-- 
2.7.4



[PATCH v2 2/6] [media] s5p-jpeg: Call jpeg_bound_align_image after qbuf

2017-06-12 Thread Thierry Escande
From: Tony K Nadackal <tony...@samsung.com>

When queuing an OUTPUT buffer for decoder, s5p_jpeg_parse_hdr()
function parses the input jpeg file and takes the width and height
parameters from its header. These new width/height values will be used
for the calculation of stride. HX_JPEG Hardware needs the width and
height values aligned on a 16 bits boundary. This width/height alignment
is handled in the s5p_jpeg_s_fmt_vid_cap() function during the S_FMT
ioctl call.

But if user space calls the QBUF of OUTPUT buffer after the S_FMT of
CAPTURE buffer, these aligned values will be replaced by the values in
jpeg header. If the width/height values of jpeg are not aligned, the
decoder output will be corrupted. So in this patch we call
jpeg_bound_align_image() to align the width/height values of Capture
buffer in s5p_jpeg_buf_queue().

Signed-off-by: Tony K Nadackal <tony...@samsung.com>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
---
 drivers/media/platform/s5p-jpeg/jpeg-core.c | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c 
b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index 52dc794..623508d 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -2523,6 +2523,25 @@ static void s5p_jpeg_buf_queue(struct vb2_buffer *vb)
q_data = >cap_q;
q_data->w = tmp.w;
q_data->h = tmp.h;
+
+   /*
+* This call to jpeg_bound_align_image() takes care of width and
+* height values alignment when user space calls the QBUF of
+* OUTPUT buffer after the S_FMT of CAPTURE buffer.
+* Please note that on Exynos4x12 SoCs, resigning from executing
+* S_FMT on capture buffer for each JPEG image can result in a
+* hardware hangup if subsampling is lower than the one of input
+* JPEG.
+*/
+   jpeg_bound_align_image(ctx,
+  _data->w,
+  S5P_JPEG_MIN_WIDTH, S5P_JPEG_MAX_WIDTH,
+  q_data->fmt->h_align,
+  _data->h,
+  S5P_JPEG_MIN_HEIGHT, S5P_JPEG_MAX_HEIGHT,
+  q_data->fmt->v_align);
+
+   q_data->size = q_data->w * q_data->h * q_data->fmt->depth >> 3;
}
 
v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
-- 
2.7.4



Re: [PATCH 6/9] [media] s5p-jpeg: Add support for resolution change event

2017-06-07 Thread Thierry Escande

Hi Jacek,

On 02/06/2017 23:53, Jacek Anaszewski wrote:

Hi Thierry,

On 06/02/2017 06:02 PM, Thierry Escande wrote:

From: henryhsu <henry...@chromium.org>

This patch adds support for resolution change event to notify clients so
they can prepare correct output buffer. When resolution change happened,
G_FMT for CAPTURE should return old resolution and format before CAPTURE
queues streamoff.


Do you have a use case for that?
Sorry but no. Again, the entry in the chromeos bug tracker does not 
mention any use case.



--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
-   pix->width = q_data->w;
-   pix->height = q_data->h;
+   if ((f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE &&
+ct->mode == S5P_JPEG_ENCODE) ||
+   (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
+ct->mode == S5P_JPEG_DECODE)) {
+   pix->width = 0;
+   pix->height = 0;
+   } else {
+   pix->width = q_data->w;
+   pix->height = q_data->h;
+   }
+


Is this change related to the patch subject?

Hum... Not sure indeed. I'll remove that from the v2.


+static void s5p_jpeg_set_capture_queue_data(struct s5p_jpeg_ctx *ctx)
+{
+   struct s5p_jpeg_q_data *q_data = >cap_q;
+
+   q_data->w = ctx->out_q.w;
+   q_data->h = ctx->out_q.h;
+
+   jpeg_bound_align_image(ctx, _data->w, S5P_JPEG_MIN_WIDTH,
+  S5P_JPEG_MAX_WIDTH, q_data->fmt->h_align,
+  _data->h, S5P_JPEG_MIN_HEIGHT,
+  S5P_JPEG_MAX_HEIGHT, q_data->fmt->v_align);
+
+   q_data->size = q_data->w * q_data->h * q_data->fmt->depth >> 3;
+}
+
  static void s5p_jpeg_buf_queue(struct vb2_buffer *vb)
  {
struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
@@ -2565,9 +2611,20 @@ static void s5p_jpeg_buf_queue(struct vb2_buffer *vb)
  
  	if (ctx->mode == S5P_JPEG_DECODE &&

vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
-   struct s5p_jpeg_q_data tmp, *q_data;
-
-   ctx->hdr_parsed = s5p_jpeg_parse_hdr(,
+   static const struct v4l2_event ev_src_ch = {
+   .type = V4L2_EVENT_SOURCE_CHANGE,
+   .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION,
+   };
+   struct vb2_queue *dst_vq;
+   u32 ori_w;
+   u32 ori_h;
+
+   dst_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
+V4L2_BUF_TYPE_VIDEO_CAPTURE);
+   ori_w = ctx->out_q.w;
+   ori_h = ctx->out_q.h;
+
+   ctx->hdr_parsed = s5p_jpeg_parse_hdr(>out_q,
 (unsigned long)vb2_plane_vaddr(vb, 0),
 min((unsigned long)ctx->out_q.size,
 vb2_get_plane_payload(vb, 0)), ctx);
@@ -2576,31 +2633,18 @@ static void s5p_jpeg_buf_queue(struct vb2_buffer *vb)
return;
}
  
-		q_data = >out_q;

-   q_data->w = tmp.w;
-   q_data->h = tmp.h;
-   q_data->sos = tmp.sos;
-   memcpy(q_data->dht.marker, tmp.dht.marker,
-  sizeof(tmp.dht.marker));
-   memcpy(q_data->dht.len, tmp.dht.len, sizeof(tmp.dht.len));
-   q_data->dht.n = tmp.dht.n;
-   memcpy(q_data->dqt.marker, tmp.dqt.marker,
-  sizeof(tmp.dqt.marker));
-   memcpy(q_data->dqt.len, tmp.dqt.len, sizeof(tmp.dqt.len));
-   q_data->dqt.n = tmp.dqt.n;
-   q_data->sof = tmp.sof;
-   q_data->sof_len = tmp.sof_len;


You're removing here quantization and Huffman table info, is it
intentional?
ctx->out_q is now passed directly to s5p_jpeg_parse_hdr(). This avoids 
this field-by-field copy already done in s5p_jpeg_parse_hdr().

This do not remove anything unless I'm missing something here...

Regards,
 Thierry



Re: [PATCH 1/9] [media] s5p-jpeg: Reset the Codec before doing a soft reset

2017-06-07 Thread Thierry Escande

Hi Jacek,

On 02/06/2017 21:50, Jacek Anaszewski wrote:

Hi Thierry,

On 06/02/2017 06:02 PM, Thierry Escande wrote:

From: Abhilash Kesavan <a.kesa...@samsung.com>

This patch resets the encoding and decoding register bits before doing a
soft reset.

Signed-off-by: Tony K Nadackal <tony...@samsung.com>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
---
  drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c | 4 
  1 file changed, 4 insertions(+)

diff --git a/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c 
b/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c
index a1d823a..9ad8f6d 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c
@@ -21,6 +21,10 @@ void exynos4_jpeg_sw_reset(void __iomem *base)
unsigned int reg;
  
  	reg = readl(base + EXYNOS4_JPEG_CNTL_REG);

+   writel(reg & ~(EXYNOS4_DEC_MODE | EXYNOS4_ENC_MODE),
+  base + EXYNOS4_JPEG_CNTL_REG);


Why is it required? It would be nice if commit message explained that.


Unfortunately the bug entry in the ChromeOS issue tracker does not 
mention more information about that and the patch author is no more 
reachable on that email address.


So unless someone else knows the answer I won't be able to give more 
explanation in the commit message...


Regards,
 Thierry


[PATCH 4/9] [media] s5p-jpeg: Decode 4:1:1 chroma subsampling format

2017-06-02 Thread Thierry Escande
From: Tony K Nadackal <tony...@samsung.com>

This patch adds support for decoding 4:1:1 chroma subsampling in the
jpeg header parsing function.

Signed-off-by: Tony K Nadackal <tony...@samsung.com>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
---
 drivers/media/platform/s5p-jpeg/jpeg-core.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c 
b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index 0d83948..770a709 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -1236,6 +1236,9 @@ static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data 
*result,
case 0x33:
ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
break;
+   case 0x41:
+   ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_411;
+   break;
default:
return false;
}
-- 
2.7.4



[PATCH 0/9] [media] s5p-jpeg: Various fixes and improvements

2017-06-02 Thread Thierry Escande
Hi,

This series contains various fixes and improvements for the Samsung
s5p-jpeg driver. All these patches come from the Chromium v3.8 kernel
tree.

Regards,
 Thierry

Abhilash Kesavan (1):
  [media] s5p-jpeg: Reset the Codec before doing a soft reset

Ricky Liang (1):
  [media] s5p-jpeg: Add support for multi-planar APIs

Tony K Nadackal (4):
  [media] s5p-jpeg: Call jpeg_bound_align_image after qbuf
  [media] s5p-jpeg: Correct WARN_ON statement for checking subsampling
  [media] s5p-jpeg: Decode 4:1:1 chroma subsampling format
  [media] s5p-jpeg: Add IOMMU support

henryhsu (3):
  [media] s5p-jpeg: Add support for resolution change event
  [media] s5p-jpeg: Change sclk_jpeg to 166MHz for Exynos5250
  [media] s5p-jpeg: Add stream error handling for Exynos5420

 drivers/media/platform/s5p-jpeg/jpeg-core.c   | 387 --
 drivers/media/platform/s5p-jpeg/jpeg-core.h   |   9 +
 drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c |   4 +
 3 files changed, 368 insertions(+), 32 deletions(-)

-- 
2.7.4



[PATCH 1/9] [media] s5p-jpeg: Reset the Codec before doing a soft reset

2017-06-02 Thread Thierry Escande
From: Abhilash Kesavan <a.kesa...@samsung.com>

This patch resets the encoding and decoding register bits before doing a
soft reset.

Signed-off-by: Tony K Nadackal <tony...@samsung.com>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
---
 drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c 
b/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c
index a1d823a..9ad8f6d 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c
@@ -21,6 +21,10 @@ void exynos4_jpeg_sw_reset(void __iomem *base)
unsigned int reg;
 
reg = readl(base + EXYNOS4_JPEG_CNTL_REG);
+   writel(reg & ~(EXYNOS4_DEC_MODE | EXYNOS4_ENC_MODE),
+  base + EXYNOS4_JPEG_CNTL_REG);
+
+   reg = readl(base + EXYNOS4_JPEG_CNTL_REG);
writel(reg & ~EXYNOS4_SOFT_RESET_HI, base + EXYNOS4_JPEG_CNTL_REG);
 
udelay(100);
-- 
2.7.4



[PATCH 2/9] [media] s5p-jpeg: Call jpeg_bound_align_image after qbuf

2017-06-02 Thread Thierry Escande
From: Tony K Nadackal <tony...@samsung.com>

When queuing an OUTPUT buffer for decoder, s5p_jpeg_parse_hdr()
function parses the input jpeg file and takes the width and height
parameters from its header. These new width/height values will be used
for the calculation of stride. HX_JPEG Hardware needs the width and
height values aligned on a 16 bits boundary. This width/height alignment
is handled in the s5p_jpeg_s_fmt_vid_cap() function during the S_FMT
ioctl call.

But if user space calls the QBUF of OUTPUT buffer after the S_FMT of
CAPTURE buffer, these aligned values will be replaced by the values in
jpeg header. If the width/height values of jpeg are not aligned, the
decoder output will be corrupted. So in this patch we call
jpeg_bound_align_image() to align the width/height values of Capture
buffer in s5p_jpeg_buf_queue().

Signed-off-by: Tony K Nadackal <tony...@samsung.com>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
---
 drivers/media/platform/s5p-jpeg/jpeg-core.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c 
b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index 52dc794..6fb1ab4 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -2523,6 +2523,13 @@ static void s5p_jpeg_buf_queue(struct vb2_buffer *vb)
q_data = >cap_q;
q_data->w = tmp.w;
q_data->h = tmp.h;
+
+   jpeg_bound_align_image(ctx, _data->w, S5P_JPEG_MIN_WIDTH,
+  S5P_JPEG_MAX_WIDTH, q_data->fmt->h_align,
+  _data->h, S5P_JPEG_MIN_HEIGHT,
+  S5P_JPEG_MAX_HEIGHT, q_data->fmt->v_align
+ );
+   q_data->size = q_data->w * q_data->h * q_data->fmt->depth >> 3;
}
 
v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
-- 
2.7.4



[PATCH 5/9] [media] s5p-jpeg: Add IOMMU support

2017-06-02 Thread Thierry Escande
From: Tony K Nadackal <tony...@samsung.com>

This patch adds support for IOMMU s5p-jpeg driver if the Exynos IOMMU
and ARM DMA IOMMU configurations are supported. The address space is
created with size limited to 256M and base address set to 0x2000.

Signed-off-by: Tony K Nadackal <tony...@samsung.com>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
---
 drivers/media/platform/s5p-jpeg/jpeg-core.c | 77 +
 1 file changed, 77 insertions(+)

diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c 
b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index 770a709..5569b99 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -28,6 +28,14 @@
 #include 
 #include 
 #include 
+#if defined(CONFIG_EXYNOS_IOMMU) && defined(CONFIG_ARM_DMA_USE_IOMMU)
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#endif
 
 #include "jpeg-core.h"
 #include "jpeg-hw-s5p.h"
@@ -35,6 +43,10 @@
 #include "jpeg-hw-exynos3250.h"
 #include "jpeg-regs.h"
 
+#if defined(CONFIG_EXYNOS_IOMMU) && defined(CONFIG_ARM_DMA_USE_IOMMU)
+static struct dma_iommu_mapping *mapping;
+#endif
+
 static struct s5p_jpeg_fmt sjpeg_formats[] = {
{
.name   = "JPEG JFIF",
@@ -956,6 +968,60 @@ static void exynos4_jpeg_parse_q_tbl(struct s5p_jpeg_ctx 
*ctx)
}
 }
 
+#if defined(CONFIG_EXYNOS_IOMMU) && defined(CONFIG_ARM_DMA_USE_IOMMU)
+static int jpeg_iommu_init(struct platform_device *pdev)
+{
+   struct device *dev = >dev;
+   int err;
+
+   mapping = arm_iommu_create_mapping(_bus_type, 0x2000,
+  SZ_512M);
+   if (IS_ERR(mapping)) {
+   dev_err(dev, "IOMMU mapping failed\n");
+   return PTR_ERR(mapping);
+   }
+
+   dev->dma_parms = devm_kzalloc(dev, sizeof(*dev->dma_parms), GFP_KERNEL);
+   if (!dev->dma_parms) {
+   err = -ENOMEM;
+   goto error_alloc;
+   }
+
+   err = dma_set_max_seg_size(dev, 0xu);
+   if (err)
+   goto error;
+
+   err = arm_iommu_attach_device(dev, mapping);
+   if (err)
+   goto error;
+
+   return 0;
+
+error:
+   devm_kfree(dev, dev->dma_parms);
+   dev->dma_parms = NULL;
+
+error_alloc:
+   arm_iommu_release_mapping(mapping);
+   mapping = NULL;
+
+   return err;
+}
+
+static void jpeg_iommu_deinit(struct platform_device *pdev)
+{
+   struct device *dev = >dev;
+
+   if (mapping) {
+   arm_iommu_detach_device(dev);
+   devm_kfree(dev, dev->dma_parms);
+   dev->dma_parms = NULL;
+   arm_iommu_release_mapping(mapping);
+   mapping = NULL;
+   }
+}
+#endif
+
 /*
  * 
  * Device file operations
@@ -2816,6 +2882,13 @@ static int s5p_jpeg_probe(struct platform_device *pdev)
spin_lock_init(>slock);
jpeg->dev = >dev;
 
+#if defined(CONFIG_EXYNOS_IOMMU) && defined(CONFIG_ARM_DMA_USE_IOMMU)
+   ret = jpeg_iommu_init(pdev);
+   if (ret) {
+   dev_err(>dev, "IOMMU Initialization failed\n");
+   return ret;
+   }
+#endif
/* memory-mapped registers */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 
@@ -2962,6 +3035,10 @@ static int s5p_jpeg_remove(struct platform_device *pdev)
clk_disable_unprepare(jpeg->clocks[i]);
}
 
+#if defined(CONFIG_EXYNOS_IOMMU) && defined(CONFIG_ARM_DMA_USE_IOMMU)
+   jpeg_iommu_deinit(pdev);
+#endif
+
return 0;
 }
 
-- 
2.7.4



[PATCH 6/9] [media] s5p-jpeg: Add support for resolution change event

2017-06-02 Thread Thierry Escande
From: henryhsu <henry...@chromium.org>

This patch adds support for resolution change event to notify clients so
they can prepare correct output buffer. When resolution change happened,
G_FMT for CAPTURE should return old resolution and format before CAPTURE
queues streamoff.

Signed-off-by: Henry-Ruey Hsu <henry...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
---
 drivers/media/platform/s5p-jpeg/jpeg-core.c | 121 
 drivers/media/platform/s5p-jpeg/jpeg-core.h |   7 ++
 2 files changed, 95 insertions(+), 33 deletions(-)

diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c 
b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index 5569b99..7a7acbc 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -24,6 +24,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -1416,8 +1417,17 @@ static int s5p_jpeg_g_fmt(struct file *file, void *priv, 
struct v4l2_format *f)
q_data = get_q_data(ct, f->type);
BUG_ON(q_data == NULL);
 
-   pix->width = q_data->w;
-   pix->height = q_data->h;
+   if ((f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE &&
+ct->mode == S5P_JPEG_ENCODE) ||
+   (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
+ct->mode == S5P_JPEG_DECODE)) {
+   pix->width = 0;
+   pix->height = 0;
+   } else {
+   pix->width = q_data->w;
+   pix->height = q_data->h;
+   }
+
pix->field = V4L2_FIELD_NONE;
pix->pixelformat = q_data->fmt->fourcc;
pix->bytesperline = 0;
@@ -1677,8 +1687,6 @@ static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct 
v4l2_format *f)
FMT_TYPE_OUTPUT : FMT_TYPE_CAPTURE;
 
q_data->fmt = s5p_jpeg_find_format(ct, pix->pixelformat, f_type);
-   q_data->w = pix->width;
-   q_data->h = pix->height;
if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG) {
/*
 * During encoding Exynos4x12 SoCs access wider memory area
@@ -1686,6 +1694,8 @@ static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct 
v4l2_format *f)
 * the JPEG_IMAGE_SIZE register. In order to avoid sysmmu
 * page fault calculate proper buffer size in such a case.
 */
+   q_data->w = pix->width;
+   q_data->h = pix->height;
if (ct->jpeg->variant->hw_ex4_compat &&
f_type == FMT_TYPE_OUTPUT && ct->mode == S5P_JPEG_ENCODE)
q_data->size = exynos4_jpeg_get_output_buffer_size(ct,
@@ -1761,6 +1771,15 @@ static int s5p_jpeg_s_fmt_vid_out(struct file *file, 
void *priv,
return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
 }
 
+static int s5p_jpeg_subscribe_event(struct v4l2_fh *fh,
+   const struct v4l2_event_subscription *sub)
+{
+   if (sub->type == V4L2_EVENT_SOURCE_CHANGE)
+   return v4l2_src_change_event_subscribe(fh, sub);
+
+   return -EINVAL;
+}
+
 static int exynos3250_jpeg_try_downscale(struct s5p_jpeg_ctx *ctx,
   struct v4l2_rect *r)
 {
@@ -2086,6 +2105,9 @@ static const struct v4l2_ioctl_ops s5p_jpeg_ioctl_ops = {
 
.vidioc_g_selection = s5p_jpeg_g_selection,
.vidioc_s_selection = s5p_jpeg_s_selection,
+
+   .vidioc_subscribe_event = s5p_jpeg_subscribe_event,
+   .vidioc_unsubscribe_event   = v4l2_event_unsubscribe,
 };
 
 /*
@@ -2478,8 +2500,17 @@ static int s5p_jpeg_job_ready(void *priv)
 {
struct s5p_jpeg_ctx *ctx = priv;
 
-   if (ctx->mode == S5P_JPEG_DECODE)
+   if (ctx->mode == S5P_JPEG_DECODE) {
+   /*
+* We have only one input buffer and one output buffer. If there
+* is a resolution change event, no need to continue decoding.
+*/
+   if (ctx->state == JPEGCTX_RESOLUTION_CHANGE)
+   return 0;
+
return ctx->hdr_parsed;
+   }
+
return 1;
 }
 
@@ -2558,6 +2589,21 @@ static int s5p_jpeg_buf_prepare(struct vb2_buffer *vb)
return 0;
 }
 
+static void s5p_jpeg_set_capture_queue_data(struct s5p_jpeg_ctx *ctx)
+{
+   struct s5p_jpeg_q_data *q_data = >cap_q;
+
+   q_data->w = ctx->out_q.w;
+   q_data->h = ctx->out_q.h;
+
+   jpeg_bound_align_image(ctx, _data->w, S5P_JPEG_MIN_WIDTH,
+  S5P_JPEG_MAX_WIDTH, q_data->fmt->h_align,
+  _data->h, S5P_JPEG_MIN_HEIGHT,
+  S5P_JPEG_MAX_HEIGHT, q_data->fmt->v_align);
+
+   q_data->size = q_data->w * q_data->h * q_data-&

[PATCH 8/9] [media] s5p-jpeg: Add stream error handling for Exynos5420

2017-06-02 Thread Thierry Escande
From: henryhsu <henry...@chromium.org>

On Exynos5420, the STREAM_STAT bit raised on the JPGINTST register means
there is a syntax error or an unrecoverable error on compressed file
when ERR_INT_EN is set to 1.

Fix this case and report BUF_STATE_ERROR to videobuf2.

Signed-off-by: Henry-Ruey Hsu <henry...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
---
 drivers/media/platform/s5p-jpeg/jpeg-core.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c 
b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index 430e925..db56135 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -2894,6 +2894,7 @@ static irqreturn_t exynos3250_jpeg_irq(int irq, void 
*dev_id)
unsigned long payload_size = 0;
enum vb2_buffer_state state = VB2_BUF_STATE_DONE;
bool interrupt_timeout = false;
+   bool stream_error = false;
u32 irq_status;
 
spin_lock(>slock);
@@ -2910,6 +2911,11 @@ static irqreturn_t exynos3250_jpeg_irq(int irq, void 
*dev_id)
 
jpeg->irq_status |= irq_status;
 
+   if (irq_status & EXYNOS3250_STREAM_STAT) {
+   stream_error = true;
+   dev_err(jpeg->dev, "Syntax error or unrecoverable error 
occurred.\n");
+   }
+
curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
 
if (!curr_ctx)
@@ -2926,7 +2932,7 @@ static irqreturn_t exynos3250_jpeg_irq(int irq, void 
*dev_id)
EXYNOS3250_RDMA_DONE |
EXYNOS3250_RESULT_STAT))
payload_size = exynos3250_jpeg_compressed_size(jpeg->regs);
-   else if (interrupt_timeout)
+   else if (interrupt_timeout || stream_error)
state = VB2_BUF_STATE_ERROR;
else
goto exit_unlock;
-- 
2.7.4



[PATCH 7/9] [media] s5p-jpeg: Change sclk_jpeg to 166MHz for Exynos5250

2017-06-02 Thread Thierry Escande
From: henryhsu <henry...@chromium.org>

The default clock parent of jpeg on Exynos5250 is fin_pll, which is
24MHz. We have to change the clock parent to CPLL, which is 333MHz,
and set sclk_jpeg to 166MHz.

Signed-off-by: Heng-Ruey Hsu <henry...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
---
 drivers/media/platform/s5p-jpeg/jpeg-core.c | 47 +
 1 file changed, 47 insertions(+)

diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c 
b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index 7a7acbc..430e925 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -969,6 +969,44 @@ static void exynos4_jpeg_parse_q_tbl(struct s5p_jpeg_ctx 
*ctx)
}
 }
 
+static int exynos4_jpeg_set_sclk_rate(struct s5p_jpeg *jpeg, struct clk *sclk)
+{
+   struct clk *mout_jpeg;
+   struct clk *sclk_cpll;
+   int ret;
+
+   mout_jpeg = clk_get(jpeg->dev, "mout_jpeg");
+   if (IS_ERR(mout_jpeg)) {
+   dev_err(jpeg->dev, "mout_jpeg clock not available: %ld\n",
+   PTR_ERR(mout_jpeg));
+   return PTR_ERR(mout_jpeg);
+   }
+
+   sclk_cpll = clk_get(jpeg->dev, "sclk_cpll");
+   if (IS_ERR(sclk_cpll)) {
+   dev_err(jpeg->dev, "sclk_cpll clock not available: %ld\n",
+   PTR_ERR(sclk_cpll));
+   clk_put(mout_jpeg);
+   return PTR_ERR(sclk_cpll);
+   }
+
+   ret = clk_set_parent(mout_jpeg, sclk_cpll);
+   clk_put(sclk_cpll);
+   clk_put(mout_jpeg);
+   if (ret) {
+   dev_err(jpeg->dev, "clk_set_parent failed: %d\n", ret);
+   return ret;
+   }
+
+   ret = clk_set_rate(sclk, 166500 * 1000);
+   if (ret) {
+   dev_err(jpeg->dev, "clk_set_rate failed: %d\n", ret);
+   return ret;
+   }
+
+   return 0;
+}
+
 #if defined(CONFIG_EXYNOS_IOMMU) && defined(CONFIG_ARM_DMA_USE_IOMMU)
 static int jpeg_iommu_init(struct platform_device *pdev)
 {
@@ -2974,6 +3012,15 @@ static int s5p_jpeg_probe(struct platform_device *pdev)
jpeg->variant->clk_names[i]);
return PTR_ERR(jpeg->clocks[i]);
}
+
+   if (jpeg->variant->version == SJPEG_EXYNOS4 &&
+   !strncmp(jpeg->variant->clk_names[i],
+"sclk", strlen("sclk"))) {
+   ret = exynos4_jpeg_set_sclk_rate(jpeg,
+jpeg->clocks[i]);
+   if (ret)
+   return ret;
+   }
}
 
/* v4l2 device */
-- 
2.7.4



[PATCH 9/9] [media] s5p-jpeg: Add support for multi-planar APIs

2017-06-02 Thread Thierry Escande
From: Ricky Liang <jcli...@chromium.org>

This patch adds multi-planar APIs to the s5p-jpeg driver. The multi-planar
APIs are identical to the exisiting single-planar APIs except the plane
format info is stored in the v4l2_pixel_format_mplan struct instead
of the v4l2_pixel_format struct.

Signed-off-by: Ricky Liang <jcli...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
---
 drivers/media/platform/s5p-jpeg/jpeg-core.c | 152 +---
 drivers/media/platform/s5p-jpeg/jpeg-core.h |   2 +
 2 files changed, 139 insertions(+), 15 deletions(-)

diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c 
b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index db56135..a8fd7ed 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -1371,6 +1371,15 @@ static int s5p_jpeg_querycap(struct file *file, void 
*priv,
 dev_name(ctx->jpeg->dev));
cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M;
cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
+   /*
+* Advertise multi-planar capabilities. The driver supports only
+* single-planar pixel format at this moment so all the buffers will
+* have only one plane.
+*/
+   cap->capabilities |= V4L2_CAP_VIDEO_M2M_MPLANE |
+V4L2_CAP_VIDEO_CAPTURE_MPLANE |
+V4L2_CAP_VIDEO_OUTPUT_MPLANE;
+
return 0;
 }
 
@@ -1430,12 +1439,10 @@ static int s5p_jpeg_enum_fmt_vid_out(struct file *file, 
void *priv,
 static struct s5p_jpeg_q_data *get_q_data(struct s5p_jpeg_ctx *ctx,
  enum v4l2_buf_type type)
 {
-   if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
+   if (V4L2_TYPE_IS_OUTPUT(type))
return >out_q;
-   if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
-   return >cap_q;
 
-   return NULL;
+   return >cap_q;
 }
 
 static int s5p_jpeg_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
@@ -1449,16 +1456,14 @@ static int s5p_jpeg_g_fmt(struct file *file, void 
*priv, struct v4l2_format *f)
if (!vq)
return -EINVAL;
 
-   if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE &&
+   if (!V4L2_TYPE_IS_OUTPUT(f->type) &&
ct->mode == S5P_JPEG_DECODE && !ct->hdr_parsed)
return -EINVAL;
q_data = get_q_data(ct, f->type);
BUG_ON(q_data == NULL);
 
-   if ((f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE &&
-ct->mode == S5P_JPEG_ENCODE) ||
-   (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
-ct->mode == S5P_JPEG_DECODE)) {
+   if ((!V4L2_TYPE_IS_OUTPUT(f->type) && ct->mode == S5P_JPEG_ENCODE) ||
+   (V4L2_TYPE_IS_OUTPUT(f->type) && ct->mode == S5P_JPEG_DECODE)) {
pix->width = 0;
pix->height = 0;
} else {
@@ -1715,6 +1720,8 @@ static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct 
v4l2_format *f)
 
q_data = get_q_data(ct, f->type);
BUG_ON(q_data == NULL);
+   vq->type = f->type;
+   q_data->type = f->type;
 
if (vb2_is_busy(vq)) {
v4l2_err(>jpeg->v4l2_dev, "%s queue busy\n", __func__);
@@ -1919,7 +1926,9 @@ static int s5p_jpeg_g_selection(struct file *file, void 
*priv,
struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
 
if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
-   s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+   s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
+   s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
+   s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
return -EINVAL;
 
/* For JPEG blob active == default == bounds */
@@ -1957,7 +1966,8 @@ static int s5p_jpeg_s_selection(struct file *file, void 
*fh,
struct v4l2_rect *rect = >r;
int ret = -EINVAL;
 
-   if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+   if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
+   s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
return -EINVAL;
 
if (s->target == V4L2_SEL_TGT_COMPOSE) {
@@ -2118,6 +2128,107 @@ static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx 
*ctx)
return ret;
 }
 
+static void v4l2_format_pixmp_to_pix(struct v4l2_format *fmt_pix_mp,
+struct v4l2_format *fmt_pix) {
+   struct v4l2_pix_format *pix = _pix->fmt.pix;
+   struct v4l2_pix_format_mplane *pix_mp = _pix_mp->fmt.pix_mp;
+
+   fmt_pix->type = fmt_pix_mp->type;
+   pix->width = pix_mp->width;
+   pix->height = pix_mp->height;
+   pix->pixelformat = pix_mp->pixelformat;
+   

[PATCH 3/9] [media] s5p-jpeg: Correct WARN_ON statement for checking subsampling

2017-06-02 Thread Thierry Escande
From: Tony K Nadackal <tony...@samsung.com>

Corrects the WARN_ON statement for subsampling based on the
JPEG Hardware version.

Signed-off-by: Tony K Nadackal <tony...@samsung.com>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
---
 drivers/media/platform/s5p-jpeg/jpeg-core.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c 
b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index 6fb1ab4..0d83948 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -614,24 +614,26 @@ static inline struct s5p_jpeg_ctx *fh_to_ctx(struct 
v4l2_fh *fh)
 
 static int s5p_jpeg_to_user_subsampling(struct s5p_jpeg_ctx *ctx)
 {
-   WARN_ON(ctx->subsampling > 3);
-
switch (ctx->jpeg->variant->version) {
case SJPEG_S5P:
+   WARN_ON(ctx->subsampling > 3);
if (ctx->subsampling > 2)
return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
return ctx->subsampling;
case SJPEG_EXYNOS3250:
case SJPEG_EXYNOS5420:
+   WARN_ON(ctx->subsampling > 6);
if (ctx->subsampling > 3)
return V4L2_JPEG_CHROMA_SUBSAMPLING_411;
return exynos3250_decoded_subsampling[ctx->subsampling];
case SJPEG_EXYNOS4:
case SJPEG_EXYNOS5433:
+   WARN_ON(ctx->subsampling > 3);
if (ctx->subsampling > 2)
return V4L2_JPEG_CHROMA_SUBSAMPLING_420;
return exynos4x12_decoded_subsampling[ctx->subsampling];
default:
+   WARN_ON(ctx->subsampling > 3);
return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
}
 }
-- 
2.7.4



[PATCH v2] [media] v4l2: Add support for go2001 PCI codec driver

2017-05-25 Thread Thierry Escande
This patch adds support for the go2001 PCI codec driver. This hardware
is present on ChromeOS based devices like the Acer ChromeBox and Acer/LG
ChromeBase 24 devices.

This driver comes from the ChromeOS v3.18 kernel tree and has been
modified to support vb2_buffer restructuring introduced in Linux v4.4.

This driver is originally developed by:
 Pawel Osciak <posc...@chromium.org>
 Ville-Mikko Rautio <v...@chromium.org>
 henryhsu <henry...@chromium.org>
 Wu-Cheng Li <wuchen...@chromium.org>

Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
---

Changes in v2:
- Removed unneeded call to dma_cache_sync() on coherent dma buffer.

 drivers/media/pci/Kconfig|2 +
 drivers/media/pci/Makefile   |1 +
 drivers/media/pci/go2001/Kconfig |   11 +
 drivers/media/pci/go2001/Makefile|2 +
 drivers/media/pci/go2001/go2001.h|  331 
 drivers/media/pci/go2001/go2001_driver.c | 2563 ++
 drivers/media/pci/go2001/go2001_hw.c | 1362 
 drivers/media/pci/go2001/go2001_hw.h |   55 +
 drivers/media/pci/go2001/go2001_proto.h  |  359 +
 9 files changed, 4686 insertions(+)
 create mode 100644 drivers/media/pci/go2001/Kconfig
 create mode 100644 drivers/media/pci/go2001/Makefile
 create mode 100644 drivers/media/pci/go2001/go2001.h
 create mode 100644 drivers/media/pci/go2001/go2001_driver.c
 create mode 100644 drivers/media/pci/go2001/go2001_hw.c
 create mode 100644 drivers/media/pci/go2001/go2001_hw.h
 create mode 100644 drivers/media/pci/go2001/go2001_proto.h

diff --git a/drivers/media/pci/Kconfig b/drivers/media/pci/Kconfig
index da28e68..837681e 100644
--- a/drivers/media/pci/Kconfig
+++ b/drivers/media/pci/Kconfig
@@ -54,5 +54,7 @@ source "drivers/media/pci/smipcie/Kconfig"
 source "drivers/media/pci/netup_unidvb/Kconfig"
 endif
 
+source "drivers/media/pci/go2001/Kconfig"
+
 endif #MEDIA_PCI_SUPPORT
 endif #PCI
diff --git a/drivers/media/pci/Makefile b/drivers/media/pci/Makefile
index a7e8af0..58639b7 100644
--- a/drivers/media/pci/Makefile
+++ b/drivers/media/pci/Makefile
@@ -32,3 +32,4 @@ obj-$(CONFIG_STA2X11_VIP) += sta2x11/
 obj-$(CONFIG_VIDEO_SOLO6X10) += solo6x10/
 obj-$(CONFIG_VIDEO_COBALT) += cobalt/
 obj-$(CONFIG_VIDEO_TW5864) += tw5864/
+obj-$(CONFIG_VIDEO_GO2001) += go2001/
diff --git a/drivers/media/pci/go2001/Kconfig b/drivers/media/pci/go2001/Kconfig
new file mode 100644
index 000..c7b5149
--- /dev/null
+++ b/drivers/media/pci/go2001/Kconfig
@@ -0,0 +1,11 @@
+config VIDEO_GO2001
+   tristate "GO2001 codec driver"
+   depends on VIDEO_V4L2 && PCI
+   select VIDEOBUF2_DMA_SG
+   ---help---
+ This driver supports the GO2001 PCI hardware codec. This codec
+ is present on ChromeOS based devices like the Acer ChromeBox
+ and ChromeBase 24 and LG ChromeBase as well.
+
+ To compile this driver as a module, choose M here: the
+ module will be called go2001.
diff --git a/drivers/media/pci/go2001/Makefile 
b/drivers/media/pci/go2001/Makefile
new file mode 100644
index 000..20bad18
--- /dev/null
+++ b/drivers/media/pci/go2001/Makefile
@@ -0,0 +1,2 @@
+go2001-objs:= go2001_driver.o go2001_hw.o
+obj-$(CONFIG_VIDEO_GO2001) += go2001.o
diff --git a/drivers/media/pci/go2001/go2001.h 
b/drivers/media/pci/go2001/go2001.h
new file mode 100644
index 000..0e5ccfd
--- /dev/null
+++ b/drivers/media/pci/go2001/go2001.h
@@ -0,0 +1,331 @@
+/*
+ *  go2001 - GO2001 codec driver.
+ *
+ *  Author : Pawel Osciak <posc...@chromium.org>
+ *
+ *  Copyright (C) 2017 Google, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  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.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef _MEDIA_PCI_GO2001_GO2001_H_
+#define _MEDIA_PCI_GO2001_GO2001_H_
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+#include "go2001_proto.h"
+
+struct go2001_msg {
+   struct list_head list_entry;
+   struct go2001_msg_payload payload;
+};
+
+static inline struct go2001_msg_hdr *msg_to_hdr(struct go2001_msg *msg)
+{
+   return >payload.hdr;
+}
+
+static inline void *msg_to_param(struct go2001_msg *msg)
+{
+   return msg->payload.param;
+}
+
+struct go2001_msg_ring {
+   struct go2001_msg_ring_desc desc;

[PATCH] [media] v4l2: Add support for go2001 PCI codec driver

2017-05-03 Thread Thierry Escande
This patch adds support for the go2001 PCI codec driver. This hardware
is present on ChromeOS based devices like the Acer ChromeBox and Acer/LG
ChromeBase 24 devices.

This driver comes from the ChromeOS v3.18 kernel tree and has been
modified to support vb2_buffer restructuring introduced in Linux v4.4.

This driver is originally developed by:
 Pawel Osciak <posc...@chromium.org>
 Ville-Mikko Rautio <v...@chromium.org>
 henryhsu <henry...@chromium.org>
 Wu-Cheng Li <wuchen...@chromium.org>

Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
---
 drivers/media/pci/Kconfig|2 +
 drivers/media/pci/Makefile   |1 +
 drivers/media/pci/go2001/Kconfig |   11 +
 drivers/media/pci/go2001/Makefile|2 +
 drivers/media/pci/go2001/go2001.h|  331 
 drivers/media/pci/go2001/go2001_driver.c | 2563 ++
 drivers/media/pci/go2001/go2001_hw.c | 1365 
 drivers/media/pci/go2001/go2001_hw.h |   55 +
 drivers/media/pci/go2001/go2001_proto.h  |  359 +
 9 files changed, 4689 insertions(+)
 create mode 100644 drivers/media/pci/go2001/Kconfig
 create mode 100644 drivers/media/pci/go2001/Makefile
 create mode 100644 drivers/media/pci/go2001/go2001.h
 create mode 100644 drivers/media/pci/go2001/go2001_driver.c
 create mode 100644 drivers/media/pci/go2001/go2001_hw.c
 create mode 100644 drivers/media/pci/go2001/go2001_hw.h
 create mode 100644 drivers/media/pci/go2001/go2001_proto.h

diff --git a/drivers/media/pci/Kconfig b/drivers/media/pci/Kconfig
index da28e68..837681e 100644
--- a/drivers/media/pci/Kconfig
+++ b/drivers/media/pci/Kconfig
@@ -54,5 +54,7 @@ source "drivers/media/pci/smipcie/Kconfig"
 source "drivers/media/pci/netup_unidvb/Kconfig"
 endif
 
+source "drivers/media/pci/go2001/Kconfig"
+
 endif #MEDIA_PCI_SUPPORT
 endif #PCI
diff --git a/drivers/media/pci/Makefile b/drivers/media/pci/Makefile
index a7e8af0..58639b7 100644
--- a/drivers/media/pci/Makefile
+++ b/drivers/media/pci/Makefile
@@ -32,3 +32,4 @@ obj-$(CONFIG_STA2X11_VIP) += sta2x11/
 obj-$(CONFIG_VIDEO_SOLO6X10) += solo6x10/
 obj-$(CONFIG_VIDEO_COBALT) += cobalt/
 obj-$(CONFIG_VIDEO_TW5864) += tw5864/
+obj-$(CONFIG_VIDEO_GO2001) += go2001/
diff --git a/drivers/media/pci/go2001/Kconfig b/drivers/media/pci/go2001/Kconfig
new file mode 100644
index 000..c7b5149
--- /dev/null
+++ b/drivers/media/pci/go2001/Kconfig
@@ -0,0 +1,11 @@
+config VIDEO_GO2001
+   tristate "GO2001 codec driver"
+   depends on VIDEO_V4L2 && PCI
+   select VIDEOBUF2_DMA_SG
+   ---help---
+ This driver supports the GO2001 PCI hardware codec. This codec
+ is present on ChromeOS based devices like the Acer ChromeBox
+ and ChromeBase 24 and LG ChromeBase as well.
+
+ To compile this driver as a module, choose M here: the
+ module will be called go2001.
diff --git a/drivers/media/pci/go2001/Makefile 
b/drivers/media/pci/go2001/Makefile
new file mode 100644
index 000..20bad18
--- /dev/null
+++ b/drivers/media/pci/go2001/Makefile
@@ -0,0 +1,2 @@
+go2001-objs:= go2001_driver.o go2001_hw.o
+obj-$(CONFIG_VIDEO_GO2001) += go2001.o
diff --git a/drivers/media/pci/go2001/go2001.h 
b/drivers/media/pci/go2001/go2001.h
new file mode 100644
index 000..0e5ccfd
--- /dev/null
+++ b/drivers/media/pci/go2001/go2001.h
@@ -0,0 +1,331 @@
+/*
+ *  go2001 - GO2001 codec driver.
+ *
+ *  Author : Pawel Osciak <posc...@chromium.org>
+ *
+ *  Copyright (C) 2017 Google, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  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.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef _MEDIA_PCI_GO2001_GO2001_H_
+#define _MEDIA_PCI_GO2001_GO2001_H_
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+#include "go2001_proto.h"
+
+struct go2001_msg {
+   struct list_head list_entry;
+   struct go2001_msg_payload payload;
+};
+
+static inline struct go2001_msg_hdr *msg_to_hdr(struct go2001_msg *msg)
+{
+   return >payload.hdr;
+}
+
+static inline void *msg_to_param(struct go2001_msg *msg)
+{
+   return msg->payload.param;
+}
+
+struct go2001_msg_ring {
+   struct go2001_msg_ring_desc desc;
+   void __iomem *desc_iomem;
+   void __iomem *data_iomem;
+   spi

Re: [PATCH v5] [media] vb2: Add support for capture_dma_bidirectional queue flag

2016-11-22 Thread Thierry Escande

Hi Mauro,

On 18/11/2016 19:59, Mauro Carvalho Chehab wrote:

Em Tue, 25 Oct 2016 10:22:29 +0200
Thierry Escande <thierry.esca...@collabora.com> escreveu:


From: Pawel Osciak <posc...@chromium.org>

When this flag is set for CAPTURE queues by the driver on calling
vb2_queue_init(), it forces the buffers on the queue to be
allocated/mapped with DMA_BIDIRECTIONAL direction flag instead of
DMA_FROM_DEVICE. This allows the device not only to write to the
buffers, but also read out from them. This may be useful e.g. for codec
hardware which may be using CAPTURE buffers as reference to decode
other buffers.

This flag is ignored for OUTPUT queues as we don't want to allow HW to
be able to write to OUTPUT buffers.

This patch introduces 2 macros:
VB2_DMA_DIR(q) returns the corresponding dma_dir for the passed queue
type, tanking care of the capture_dma_birectional flag.

VB2_DMA_DIR_CAPTURE(d) is a test macro returning true if the passed DMA
direction refers to a capture buffer. This test is used to map virtual
addresses for writing and to mark pages as dirty.


Why to add it? There's no other patch on this series with would
justify its needs...


It is used by a Rockchip vpu driver which is only in the chromeos public 
tree for now and will be upstreamed soon.


Regards,
 Thierry



Signed-off-by: Pawel Osciak <posc...@chromium.org>
Tested-by: Pawel Osciak <posc...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
---

Changes in v2:
- Renamed use_dma_bidirectional field as capture_dma_bidirectional
- Added a VB2_DMA_DIR() macro

Changes in v3:
- Get rid of dma_dir field and therefore squashed the previous patch

Changes in v4:
- Fixed typos in include/media/videobuf2-core.h
- Added VB2_DMA_DIR_CAPTURE() test macro

Changes in v5:
- Use is_output queue field in VB2_DMA_DIR() macro

 drivers/media/v4l2-core/videobuf2-core.c   |  9 +++--
 drivers/media/v4l2-core/videobuf2-dma-contig.c |  2 +-
 drivers/media/v4l2-core/videobuf2-dma-sg.c |  5 +++--
 drivers/media/v4l2-core/videobuf2-vmalloc.c|  4 ++--
 include/media/videobuf2-core.h | 23 +++
 5 files changed, 32 insertions(+), 11 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-core.c 
b/drivers/media/v4l2-core/videobuf2-core.c
index 21900202..22d6105 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -194,8 +194,7 @@ static void __enqueue_in_driver(struct vb2_buffer *vb);
 static int __vb2_buf_mem_alloc(struct vb2_buffer *vb)
 {
struct vb2_queue *q = vb->vb2_queue;
-   enum dma_data_direction dma_dir =
-   q->is_output ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
+   enum dma_data_direction dma_dir = VB2_DMA_DIR(q);
void *mem_priv;
int plane;
int ret = -ENOMEM;
@@ -978,8 +977,7 @@ static int __qbuf_userptr(struct vb2_buffer *vb, const void 
*pb)
void *mem_priv;
unsigned int plane;
int ret = 0;
-   enum dma_data_direction dma_dir =
-   q->is_output ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
+   enum dma_data_direction dma_dir = VB2_DMA_DIR(q);
bool reacquired = vb->planes[0].mem_priv == NULL;

memset(planes, 0, sizeof(planes[0]) * vb->num_planes);
@@ -1096,8 +1094,7 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const 
void *pb)
void *mem_priv;
unsigned int plane;
int ret = 0;
-   enum dma_data_direction dma_dir =
-   q->is_output ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
+   enum dma_data_direction dma_dir = VB2_DMA_DIR(q);
bool reacquired = vb->planes[0].mem_priv == NULL;

memset(planes, 0, sizeof(planes[0]) * vb->num_planes);
diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index fb6a177..a44e383 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -507,7 +507,7 @@ static void *vb2_dc_get_userptr(struct device *dev, 
unsigned long vaddr,
buf->dma_dir = dma_dir;

offset = vaddr & ~PAGE_MASK;
-   vec = vb2_create_framevec(vaddr, size, dma_dir == DMA_FROM_DEVICE);
+   vec = vb2_create_framevec(vaddr, size, VB2_DMA_DIR_CAPTURE(dma_dir));
if (IS_ERR(vec)) {
ret = PTR_ERR(vec);
goto fail_buf;
diff --git a/drivers/media/v4l2-core/videobuf2-dma-sg.c 
b/drivers/media/v4l2-core/videobuf2-dma-sg.c
index ecff8f49..51c98f6 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-sg.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-sg.c
@@ -238,7 +238,8 @@ static void *vb2_dma_sg_get_userptr(struct device *dev, 
unsigned long vaddr,
buf->offset = vaddr & ~PAGE_MASK;
buf->size = size;
buf->dma_sgt = >sg_table;
-   vec = vb2_create_framevec(vaddr, size, bu

[PATCH v3 1/2] [media] videobuf2-dc: Move vb2_dc_get_base_sgt() above mmap callbacks

2016-10-26 Thread Thierry Escande
This patch moves vb2_dc_get_base_sgt() function above mmap buffers
callbacks, particularly vb2_dc_alloc() and vb2_dc_mmap() from where it
will be called for cacheable MMAP support introduced in the next patch.

Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
---
 drivers/media/v4l2-core/videobuf2-dma-contig.c | 44 +-
 1 file changed, 22 insertions(+), 22 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index a44e383..0d9665d 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -61,6 +61,28 @@ static unsigned long vb2_dc_get_contiguous_size(struct 
sg_table *sgt)
return size;
 }
 
+static struct sg_table *vb2_dc_get_base_sgt(struct vb2_dc_buf *buf)
+{
+   int ret;
+   struct sg_table *sgt;
+
+   sgt = kmalloc(sizeof(*sgt), GFP_KERNEL);
+   if (!sgt) {
+   dev_err(buf->dev, "failed to alloc sg table\n");
+   return NULL;
+   }
+
+   ret = dma_get_sgtable_attrs(buf->dev, sgt, buf->cookie, buf->dma_addr,
+   buf->size, buf->attrs);
+   if (ret < 0) {
+   dev_err(buf->dev, "failed to get scatterlist from DMA API\n");
+   kfree(sgt);
+   return NULL;
+   }
+
+   return sgt;
+}
+
 /*/
 /* callbacks for all buffers */
 /*/
@@ -363,28 +385,6 @@ static struct dma_buf_ops vb2_dc_dmabuf_ops = {
.release = vb2_dc_dmabuf_ops_release,
 };
 
-static struct sg_table *vb2_dc_get_base_sgt(struct vb2_dc_buf *buf)
-{
-   int ret;
-   struct sg_table *sgt;
-
-   sgt = kmalloc(sizeof(*sgt), GFP_KERNEL);
-   if (!sgt) {
-   dev_err(buf->dev, "failed to alloc sg table\n");
-   return NULL;
-   }
-
-   ret = dma_get_sgtable_attrs(buf->dev, sgt, buf->cookie, buf->dma_addr,
-   buf->size, buf->attrs);
-   if (ret < 0) {
-   dev_err(buf->dev, "failed to get scatterlist from DMA API\n");
-   kfree(sgt);
-   return NULL;
-   }
-
-   return sgt;
-}
-
 static struct dma_buf *vb2_dc_get_dmabuf(void *buf_priv, unsigned long flags)
 {
struct vb2_dc_buf *buf = buf_priv;
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 0/2] [media] videobuf2-dc: Add support for cacheable MMAP

2016-10-26 Thread Thierry Escande
Hi,

This series adds support for cacheable MMAP in DMA coherent allocator.

The first patch moves the vb2_dc_get_base_sgt() function above mmap
callbacks for calls introduced by the second patch. This avoids a
forward declaration.

Changes in v2:
- Put function move in a separate patch
- Added comments

Changes in v3:
- Remove redundant test on NO_KERNEL_MAPPING DMA attribute in mmap()

Heng-Ruey Hsu (1):
  [media] videobuf2-dc: Support cacheable MMAP

Thierry Escande (1):
  [media] videobuf2-dc: Move vb2_dc_get_base_sgt() above mmap callbacks

 drivers/media/v4l2-core/videobuf2-dma-contig.c | 60 --
 1 file changed, 38 insertions(+), 22 deletions(-)

-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 2/2] [media] videobuf2-dc: Support cacheable MMAP

2016-10-26 Thread Thierry Escande
From: Heng-Ruey Hsu <henry...@chromium.org>

DMA allocations for MMAP type are uncached by default. But for
some cases, CPU has to access the buffers. ie: memcpy for format
converter. Supporting cacheable MMAP improves huge performance.

This patch enables cacheable memory for DMA coherent allocator in mmap
buffer allocation if non-consistent DMA attribute is set and kernel
mapping is present. Even if userspace doesn't mmap the buffer, sync
still should be happening if kernel mapping is present.
If not done in allocation, it is enabled when memory is mapped from
userspace (if non-consistent DMA attribute is set).

Signed-off-by: Heng-Ruey Hsu <henry...@chromium.org>
Tested-by: Heng-ruey Hsu <henry...@chromium.org>
Reviewed-by: Tomasz Figa <tf...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
---
 drivers/media/v4l2-core/videobuf2-dma-contig.c | 16 
 1 file changed, 16 insertions(+)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index 0d9665d..89b534a 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -151,6 +151,10 @@ static void vb2_dc_put(void *buf_priv)
sg_free_table(buf->sgt_base);
kfree(buf->sgt_base);
}
+   if (buf->dma_sgt) {
+   sg_free_table(buf->dma_sgt);
+   kfree(buf->dma_sgt);
+   }
dma_free_attrs(buf->dev, buf->size, buf->cookie, buf->dma_addr,
   buf->attrs);
put_device(buf->dev);
@@ -192,6 +196,14 @@ static void *vb2_dc_alloc(struct device *dev, unsigned 
long attrs,
buf->handler.put = vb2_dc_put;
buf->handler.arg = buf;
 
+   /*
+* Enable cache maintenance. Even if userspace doesn't mmap the buffer,
+* sync still should be happening if kernel mapping is present.
+*/
+   if (!(buf->attrs & DMA_ATTR_NO_KERNEL_MAPPING) &&
+   buf->attrs & DMA_ATTR_NON_CONSISTENT)
+   buf->dma_sgt = vb2_dc_get_base_sgt(buf);
+
atomic_inc(>refcount);
 
return buf;
@@ -227,6 +239,10 @@ static int vb2_dc_mmap(void *buf_priv, struct 
vm_area_struct *vma)
 
vma->vm_ops->open(vma);
 
+   /* Enable cache maintenance if not enabled in allocation. */
+   if (!buf->dma_sgt && buf->attrs & DMA_ATTR_NON_CONSISTENT)
+   buf->dma_sgt = vb2_dc_get_base_sgt(buf);
+
pr_debug("%s: mapped dma addr 0x%08lx at 0x%08lx, size %ld\n",
__func__, (unsigned long)buf->dma_addr, vma->vm_start,
buf->size);
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v5] [media] vb2: Add support for capture_dma_bidirectional queue flag

2016-10-25 Thread Thierry Escande
From: Pawel Osciak <posc...@chromium.org>

When this flag is set for CAPTURE queues by the driver on calling
vb2_queue_init(), it forces the buffers on the queue to be
allocated/mapped with DMA_BIDIRECTIONAL direction flag instead of
DMA_FROM_DEVICE. This allows the device not only to write to the
buffers, but also read out from them. This may be useful e.g. for codec
hardware which may be using CAPTURE buffers as reference to decode
other buffers.

This flag is ignored for OUTPUT queues as we don't want to allow HW to
be able to write to OUTPUT buffers.

This patch introduces 2 macros:
VB2_DMA_DIR(q) returns the corresponding dma_dir for the passed queue
type, tanking care of the capture_dma_birectional flag.

VB2_DMA_DIR_CAPTURE(d) is a test macro returning true if the passed DMA
direction refers to a capture buffer. This test is used to map virtual
addresses for writing and to mark pages as dirty.

Signed-off-by: Pawel Osciak <posc...@chromium.org>
Tested-by: Pawel Osciak <posc...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
---

Changes in v2:
- Renamed use_dma_bidirectional field as capture_dma_bidirectional
- Added a VB2_DMA_DIR() macro

Changes in v3:
- Get rid of dma_dir field and therefore squashed the previous patch

Changes in v4:
- Fixed typos in include/media/videobuf2-core.h
- Added VB2_DMA_DIR_CAPTURE() test macro

Changes in v5:
- Use is_output queue field in VB2_DMA_DIR() macro

 drivers/media/v4l2-core/videobuf2-core.c   |  9 +++--
 drivers/media/v4l2-core/videobuf2-dma-contig.c |  2 +-
 drivers/media/v4l2-core/videobuf2-dma-sg.c |  5 +++--
 drivers/media/v4l2-core/videobuf2-vmalloc.c|  4 ++--
 include/media/videobuf2-core.h | 23 +++
 5 files changed, 32 insertions(+), 11 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-core.c 
b/drivers/media/v4l2-core/videobuf2-core.c
index 21900202..22d6105 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -194,8 +194,7 @@ static void __enqueue_in_driver(struct vb2_buffer *vb);
 static int __vb2_buf_mem_alloc(struct vb2_buffer *vb)
 {
struct vb2_queue *q = vb->vb2_queue;
-   enum dma_data_direction dma_dir =
-   q->is_output ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
+   enum dma_data_direction dma_dir = VB2_DMA_DIR(q);
void *mem_priv;
int plane;
int ret = -ENOMEM;
@@ -978,8 +977,7 @@ static int __qbuf_userptr(struct vb2_buffer *vb, const void 
*pb)
void *mem_priv;
unsigned int plane;
int ret = 0;
-   enum dma_data_direction dma_dir =
-   q->is_output ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
+   enum dma_data_direction dma_dir = VB2_DMA_DIR(q);
bool reacquired = vb->planes[0].mem_priv == NULL;
 
memset(planes, 0, sizeof(planes[0]) * vb->num_planes);
@@ -1096,8 +1094,7 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const 
void *pb)
void *mem_priv;
unsigned int plane;
int ret = 0;
-   enum dma_data_direction dma_dir =
-   q->is_output ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
+   enum dma_data_direction dma_dir = VB2_DMA_DIR(q);
bool reacquired = vb->planes[0].mem_priv == NULL;
 
memset(planes, 0, sizeof(planes[0]) * vb->num_planes);
diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index fb6a177..a44e383 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -507,7 +507,7 @@ static void *vb2_dc_get_userptr(struct device *dev, 
unsigned long vaddr,
buf->dma_dir = dma_dir;
 
offset = vaddr & ~PAGE_MASK;
-   vec = vb2_create_framevec(vaddr, size, dma_dir == DMA_FROM_DEVICE);
+   vec = vb2_create_framevec(vaddr, size, VB2_DMA_DIR_CAPTURE(dma_dir));
if (IS_ERR(vec)) {
ret = PTR_ERR(vec);
goto fail_buf;
diff --git a/drivers/media/v4l2-core/videobuf2-dma-sg.c 
b/drivers/media/v4l2-core/videobuf2-dma-sg.c
index ecff8f49..51c98f6 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-sg.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-sg.c
@@ -238,7 +238,8 @@ static void *vb2_dma_sg_get_userptr(struct device *dev, 
unsigned long vaddr,
buf->offset = vaddr & ~PAGE_MASK;
buf->size = size;
buf->dma_sgt = >sg_table;
-   vec = vb2_create_framevec(vaddr, size, buf->dma_dir == DMA_FROM_DEVICE);
+   vec = vb2_create_framevec(vaddr, size,
+ VB2_DMA_DIR_CAPTURE(buf->dma_dir));
if (IS_ERR(vec))
goto userptr_fail_pfnvec;
buf->vec = vec;
@@ -291,7 +292,7 @@ static void vb2_dma_sg_put_userptr(void *buf_priv)
vm_unmap_ram(buf->vaddr, buf->num_pages);
sg_free_table(buf->

[PATCH v2 1/2] [media] videobuf2-dc: Move vb2_dc_get_base_sgt() above mmap callbacks

2016-10-24 Thread Thierry Escande
This patch moves vb2_dc_get_base_sgt() function above mmap buffers
callbacks, particularly vb2_dc_alloc() and vb2_dc_mmap() from where it
will be called for cacheable MMAP support introduced in the next patch.

Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
---
 drivers/media/v4l2-core/videobuf2-dma-contig.c | 44 +-
 1 file changed, 22 insertions(+), 22 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index a44e383..0d9665d 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -61,6 +61,28 @@ static unsigned long vb2_dc_get_contiguous_size(struct 
sg_table *sgt)
return size;
 }
 
+static struct sg_table *vb2_dc_get_base_sgt(struct vb2_dc_buf *buf)
+{
+   int ret;
+   struct sg_table *sgt;
+
+   sgt = kmalloc(sizeof(*sgt), GFP_KERNEL);
+   if (!sgt) {
+   dev_err(buf->dev, "failed to alloc sg table\n");
+   return NULL;
+   }
+
+   ret = dma_get_sgtable_attrs(buf->dev, sgt, buf->cookie, buf->dma_addr,
+   buf->size, buf->attrs);
+   if (ret < 0) {
+   dev_err(buf->dev, "failed to get scatterlist from DMA API\n");
+   kfree(sgt);
+   return NULL;
+   }
+
+   return sgt;
+}
+
 /*/
 /* callbacks for all buffers */
 /*/
@@ -363,28 +385,6 @@ static struct dma_buf_ops vb2_dc_dmabuf_ops = {
.release = vb2_dc_dmabuf_ops_release,
 };
 
-static struct sg_table *vb2_dc_get_base_sgt(struct vb2_dc_buf *buf)
-{
-   int ret;
-   struct sg_table *sgt;
-
-   sgt = kmalloc(sizeof(*sgt), GFP_KERNEL);
-   if (!sgt) {
-   dev_err(buf->dev, "failed to alloc sg table\n");
-   return NULL;
-   }
-
-   ret = dma_get_sgtable_attrs(buf->dev, sgt, buf->cookie, buf->dma_addr,
-   buf->size, buf->attrs);
-   if (ret < 0) {
-   dev_err(buf->dev, "failed to get scatterlist from DMA API\n");
-   kfree(sgt);
-   return NULL;
-   }
-
-   return sgt;
-}
-
 static struct dma_buf *vb2_dc_get_dmabuf(void *buf_priv, unsigned long flags)
 {
struct vb2_dc_buf *buf = buf_priv;
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 2/2] [media] videobuf2-dc: Support cacheable MMAP

2016-10-24 Thread Thierry Escande
From: Heng-Ruey Hsu <henry...@chromium.org>

DMA allocations for MMAP type are uncached by default. But for
some cases, CPU has to access the buffers. ie: memcpy for format
converter. Supporting cacheable MMAP improves huge performance.

This patch enables cacheable memory for DMA coherent allocator in mmap
buffer allocation if non-consistent DMA attribute is set and kernel
mapping is present. Even if userspace doesn't mmap the buffer, sync
still should be happening if kernel mapping is present.
If not done in allocation, it is enabled when memory is mapped from
userspace when no kernel mapping is present and non-consistent DMA
attribute set.

Signed-off-by: Heng-Ruey Hsu <henry...@chromium.org>
Tested-by: Heng-ruey Hsu <henry...@chromium.org>
Reviewed-by: Tomasz Figa <tf...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
---
 drivers/media/v4l2-core/videobuf2-dma-contig.c | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index 0d9665d..1f7649d 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -151,6 +151,10 @@ static void vb2_dc_put(void *buf_priv)
sg_free_table(buf->sgt_base);
kfree(buf->sgt_base);
}
+   if (buf->dma_sgt) {
+   sg_free_table(buf->dma_sgt);
+   kfree(buf->dma_sgt);
+   }
dma_free_attrs(buf->dev, buf->size, buf->cookie, buf->dma_addr,
   buf->attrs);
put_device(buf->dev);
@@ -192,6 +196,14 @@ static void *vb2_dc_alloc(struct device *dev, unsigned 
long attrs,
buf->handler.put = vb2_dc_put;
buf->handler.arg = buf;
 
+   /*
+* Enable cacheable memory. Even if userspace doesn't mmap the buffer,
+* sync still should be happening if kernel mapping is present.
+*/
+   if (!(buf->attrs & DMA_ATTR_NO_KERNEL_MAPPING) &&
+   buf->attrs & DMA_ATTR_NON_CONSISTENT)
+   buf->dma_sgt = vb2_dc_get_base_sgt(buf);
+
atomic_inc(>refcount);
 
return buf;
@@ -227,6 +239,12 @@ static int vb2_dc_mmap(void *buf_priv, struct 
vm_area_struct *vma)
 
vma->vm_ops->open(vma);
 
+   /* Enable cacheable memory if not enabled in allocation. */
+   if (!buf->dma_sgt &&
+   buf->attrs & DMA_ATTR_NO_KERNEL_MAPPING &&
+   buf->attrs & DMA_ATTR_NON_CONSISTENT)
+   buf->dma_sgt = vb2_dc_get_base_sgt(buf);
+
pr_debug("%s: mapped dma addr 0x%08lx at 0x%08lx, size %ld\n",
__func__, (unsigned long)buf->dma_addr, vma->vm_start,
buf->size);
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 0/2] [media] videobuf2-dc: Add support for cacheable MMAP

2016-10-24 Thread Thierry Escande
Hi,

This series adds support for cacheable MMAP in DMA coherent allocator.

The first patch moves the vb2_dc_get_base_sgt() function above mmap
callbacks for calls introduced by the second patch. This avoids a
forward declaration.

Changes in v2:
- Put function move in a separate patch
- Added comments

Heng-Ruey Hsu (1):
  [media] videobuf2-dc: Support cacheable MMAP

Thierry Escande (1):
  [media] videobuf2-dc: Move vb2_dc_get_base_sgt() above mmap callbacks

 drivers/media/v4l2-core/videobuf2-dma-contig.c | 62 +-
 1 file changed, 40 insertions(+), 22 deletions(-)

-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4] [media] vb2: Add support for capture_dma_bidirectional queue flag

2016-10-24 Thread Thierry Escande
From: Pawel Osciak <posc...@chromium.org>

When this flag is set for CAPTURE queues by the driver on calling
vb2_queue_init(), it forces the buffers on the queue to be
allocated/mapped with DMA_BIDIRECTIONAL direction flag instead of
DMA_FROM_DEVICE. This allows the device not only to write to the
buffers, but also read out from them. This may be useful e.g. for codec
hardware which may be using CAPTURE buffers as reference to decode
other buffers.

This flag is ignored for OUTPUT queues as we don't want to allow HW to
be able to write to OUTPUT buffers.

This patch introduces 2 macros:
VB2_DMA_DIR(q) returns the corresponding dma_dir for the passed queue
type, tanking care of the capture_dma_birectional flag.

VB2_DMA_DIR_CAPTURE(d) is a test macro returning true if the passed DMA
direction refers to a capture buffer. This test is used to map virtual
addresses for writing and to mark pages as dirty.

Signed-off-by: Pawel Osciak <posc...@chromium.org>
Tested-by: Pawel Osciak <posc...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
---

Changes since v1:
- Renamed use_dma_bidirectional field as capture_dma_bidirectional
- Added a VB2_DMA_DIR() macro

Changes since v2:
- Get rid of dma_dir field and therefore squashed the previous patch

Changes since v3:
- Fixed typos in include/media/videobuf2-core.h
- Added VB2_DMA_DIR_CAPTURE() test macro


 drivers/media/v4l2-core/videobuf2-core.c   |  9 +++--
 drivers/media/v4l2-core/videobuf2-dma-contig.c |  2 +-
 drivers/media/v4l2-core/videobuf2-dma-sg.c |  5 +++--
 drivers/media/v4l2-core/videobuf2-vmalloc.c|  4 ++--
 include/media/videobuf2-core.h | 24 
 5 files changed, 33 insertions(+), 11 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-core.c 
b/drivers/media/v4l2-core/videobuf2-core.c
index 21900202..22d6105 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -194,8 +194,7 @@ static void __enqueue_in_driver(struct vb2_buffer *vb);
 static int __vb2_buf_mem_alloc(struct vb2_buffer *vb)
 {
struct vb2_queue *q = vb->vb2_queue;
-   enum dma_data_direction dma_dir =
-   q->is_output ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
+   enum dma_data_direction dma_dir = VB2_DMA_DIR(q);
void *mem_priv;
int plane;
int ret = -ENOMEM;
@@ -978,8 +977,7 @@ static int __qbuf_userptr(struct vb2_buffer *vb, const void 
*pb)
void *mem_priv;
unsigned int plane;
int ret = 0;
-   enum dma_data_direction dma_dir =
-   q->is_output ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
+   enum dma_data_direction dma_dir = VB2_DMA_DIR(q);
bool reacquired = vb->planes[0].mem_priv == NULL;
 
memset(planes, 0, sizeof(planes[0]) * vb->num_planes);
@@ -1096,8 +1094,7 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const 
void *pb)
void *mem_priv;
unsigned int plane;
int ret = 0;
-   enum dma_data_direction dma_dir =
-   q->is_output ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
+   enum dma_data_direction dma_dir = VB2_DMA_DIR(q);
bool reacquired = vb->planes[0].mem_priv == NULL;
 
memset(planes, 0, sizeof(planes[0]) * vb->num_planes);
diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index fb6a177..a44e383 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -507,7 +507,7 @@ static void *vb2_dc_get_userptr(struct device *dev, 
unsigned long vaddr,
buf->dma_dir = dma_dir;
 
offset = vaddr & ~PAGE_MASK;
-   vec = vb2_create_framevec(vaddr, size, dma_dir == DMA_FROM_DEVICE);
+   vec = vb2_create_framevec(vaddr, size, VB2_DMA_DIR_CAPTURE(dma_dir));
if (IS_ERR(vec)) {
ret = PTR_ERR(vec);
goto fail_buf;
diff --git a/drivers/media/v4l2-core/videobuf2-dma-sg.c 
b/drivers/media/v4l2-core/videobuf2-dma-sg.c
index ecff8f49..51c98f6 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-sg.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-sg.c
@@ -238,7 +238,8 @@ static void *vb2_dma_sg_get_userptr(struct device *dev, 
unsigned long vaddr,
buf->offset = vaddr & ~PAGE_MASK;
buf->size = size;
buf->dma_sgt = >sg_table;
-   vec = vb2_create_framevec(vaddr, size, buf->dma_dir == DMA_FROM_DEVICE);
+   vec = vb2_create_framevec(vaddr, size,
+ VB2_DMA_DIR_CAPTURE(buf->dma_dir));
if (IS_ERR(vec))
goto userptr_fail_pfnvec;
buf->vec = vec;
@@ -291,7 +292,7 @@ static void vb2_dma_sg_put_userptr(void *buf_priv)
vm_unmap_ram(buf->vaddr, buf->num_pages);
sg_free_table(buf->dma_sgt);
while (--i >= 0) {
-

Re: [PATCH v3] [media] vb2: Add support for capture_dma_bidirectional queue flag

2016-10-21 Thread Thierry Escande

Hi Sakari,

On 21/10/2016 09:48, Sakari Ailus wrote:

Hi Thierry,

On Fri, Oct 21, 2016 at 09:25:05AM +0200, Thierry Escande wrote:

From: Pawel Osciak <posc...@chromium.org>

When this flag is set for CAPTURE queues by the driver on calling
vb2_queue_init(), it forces the buffers on the queue to be
allocated/mapped with DMA_BIDIRECTIONAL direction flag instead of
DMA_FROM_DEVICE. This allows the device not only to write to the
buffers, but also read out from them. This may be useful e.g. for codec
hardware which may be using CAPTURE buffers as reference to decode
other buffers.

This flag is ignored for OUTPUT queues as we don't want to allow HW to
be able to write to OUTPUT buffers.

Signed-off-by: Pawel Osciak <posc...@chromium.org>
Tested-by: Pawel Osciak <posc...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>



Please also check where dma_dir is being used especially in memory type
implementation. There are several comparisons to DMA_FROM_DEVICE which will
have a different result if DMA_BIDIRECTIONAL is used instead.

Nice catch, thanks.

How about a macro like this:

#define VB2_DMA_DIR_CAPTURE(d) \
((d) == DMA_FROM_DEVICE || (d) == DMA_BIDIRECTIONAL)

Regards,
 Thierry

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3] [media] vb2: Add support for capture_dma_bidirectional queue flag

2016-10-21 Thread Thierry Escande
From: Pawel Osciak <posc...@chromium.org>

When this flag is set for CAPTURE queues by the driver on calling
vb2_queue_init(), it forces the buffers on the queue to be
allocated/mapped with DMA_BIDIRECTIONAL direction flag instead of
DMA_FROM_DEVICE. This allows the device not only to write to the
buffers, but also read out from them. This may be useful e.g. for codec
hardware which may be using CAPTURE buffers as reference to decode
other buffers.

This flag is ignored for OUTPUT queues as we don't want to allow HW to
be able to write to OUTPUT buffers.

Signed-off-by: Pawel Osciak <posc...@chromium.org>
Tested-by: Pawel Osciak <posc...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
---

Changes since v1:
- Renamed use_dma_bidirectional field as capture_dma_bidirectional
- Added a VB2_DMA_DIR() macro

Changes since v2:
- Get rid of dma_dir field and therefore squashed the previous patch

Changes since v3:
- Fixed typos in include/media/videobuf2-core.h

 drivers/media/v4l2-core/videobuf2-core.c |  9 +++--
 include/media/videobuf2-core.h   | 15 +++
 2 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-core.c 
b/drivers/media/v4l2-core/videobuf2-core.c
index 21900202..22d6105 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -194,8 +194,7 @@ static void __enqueue_in_driver(struct vb2_buffer *vb);
 static int __vb2_buf_mem_alloc(struct vb2_buffer *vb)
 {
struct vb2_queue *q = vb->vb2_queue;
-   enum dma_data_direction dma_dir =
-   q->is_output ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
+   enum dma_data_direction dma_dir = VB2_DMA_DIR(q);
void *mem_priv;
int plane;
int ret = -ENOMEM;
@@ -978,8 +977,7 @@ static int __qbuf_userptr(struct vb2_buffer *vb, const void 
*pb)
void *mem_priv;
unsigned int plane;
int ret = 0;
-   enum dma_data_direction dma_dir =
-   q->is_output ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
+   enum dma_data_direction dma_dir = VB2_DMA_DIR(q);
bool reacquired = vb->planes[0].mem_priv == NULL;
 
memset(planes, 0, sizeof(planes[0]) * vb->num_planes);
@@ -1096,8 +1094,7 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const 
void *pb)
void *mem_priv;
unsigned int plane;
int ret = 0;
-   enum dma_data_direction dma_dir =
-   q->is_output ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
+   enum dma_data_direction dma_dir = VB2_DMA_DIR(q);
bool reacquired = vb->planes[0].mem_priv == NULL;
 
memset(planes, 0, sizeof(planes[0]) * vb->num_planes);
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index ac5898a..a6cfdfb 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -433,6 +433,9 @@ struct vb2_buf_ops {
  * @quirk_poll_must_check_waiting_for_buffers: Return POLLERR at poll when QBUF
  *  has not been called. This is a vb1 idiom that has been adopted
  *  also by vb2.
+ * @capture_dma_bidirectional: use DMA_BIDIRECTIONAL for CAPTURE buffers; this
+ * allows HW to read from the CAPTURE buffers in
+ * addition to writing; ignored for OUTPUT queues.
  * @lock:  pointer to a mutex that protects the vb2_queue struct. The
  * driver can set this to a mutex to let the v4l2 core serialize
  * the queuing ioctls. If the driver wants to handle locking
@@ -499,6 +502,7 @@ struct vb2_queue {
unsignedfileio_write_immediately:1;
unsignedallow_zero_bytesused:1;
unsigned   quirk_poll_must_check_waiting_for_buffers:1;
+   unsignedcapture_dma_bidirectional:1;
 
struct mutex*lock;
void*owner;
@@ -554,6 +558,17 @@ struct vb2_queue {
 #endif
 };
 
+/*
+ * Returns the corresponding DMA direction given the vb2_queue type (capture or
+ * output). Returns DMA_BIDIRECTIONAL for capture buffers if the vb2_queue 
field
+ * capture_dma_bidirectional is set by the driver.
+ */
+#define VB2_DMA_DIR(q) (V4L2_TYPE_IS_OUTPUT((q)->type)   \
+   ? DMA_TO_DEVICE  \
+   : (q)->capture_dma_bidirectional \
+ ? DMA_BIDIRECTIONAL\
+ : DMA_FROM_DEVICE)
+
 /**
  * vb2_plane_vaddr() - Return a kernel virtual address of a given plane
  * @vb:vb2_buffer to which the plane in question belongs to
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3] [media] vb2: Add support for capture_dma_bidirectional queue flag

2016-10-20 Thread Thierry Escande
From: Pawel Osciak <posc...@chromium.org>

When this flag is set for CAPTURE queues by the driver on calling
vb2_queue_init(), it forces the buffers on the queue to be
allocated/mapped with DMA_BIDIRECTIONAL direction flag instead of
DMA_FROM_DEVICE. This allows the device not only to write to the
buffers, but also read out from them. This may be useful e.g. for codec
hardware which may be using CAPTURE buffers as reference to decode
other buffers.

This flag is ignored for OUTPUT queues as we don't want to allow HW to
be able to write to OUTPUT buffers.

Signed-off-by: Pawel Osciak <posc...@chromium.org>
Tested-by: Pawel Osciak <posc...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
---

Changes since v1:
- Renamed use_dma_bidirectional field as capture_dma_bidirectional
- Added a VB2_DMA_DIR() macro

Changes since v2:
- Get rid of dma_dir field and therefore squashed the previous patch

 drivers/media/v4l2-core/videobuf2-core.c |  9 +++--
 include/media/videobuf2-core.h   | 15 +++
 2 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-core.c 
b/drivers/media/v4l2-core/videobuf2-core.c
index 21900202..22d6105 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -194,8 +194,7 @@ static void __enqueue_in_driver(struct vb2_buffer *vb);
 static int __vb2_buf_mem_alloc(struct vb2_buffer *vb)
 {
struct vb2_queue *q = vb->vb2_queue;
-   enum dma_data_direction dma_dir =
-   q->is_output ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
+   enum dma_data_direction dma_dir = VB2_DMA_DIR(q);
void *mem_priv;
int plane;
int ret = -ENOMEM;
@@ -978,8 +977,7 @@ static int __qbuf_userptr(struct vb2_buffer *vb, const void 
*pb)
void *mem_priv;
unsigned int plane;
int ret = 0;
-   enum dma_data_direction dma_dir =
-   q->is_output ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
+   enum dma_data_direction dma_dir = VB2_DMA_DIR(q);
bool reacquired = vb->planes[0].mem_priv == NULL;
 
memset(planes, 0, sizeof(planes[0]) * vb->num_planes);
@@ -1096,8 +1094,7 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const 
void *pb)
void *mem_priv;
unsigned int plane;
int ret = 0;
-   enum dma_data_direction dma_dir =
-   q->is_output ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
+   enum dma_data_direction dma_dir = VB2_DMA_DIR(q);
bool reacquired = vb->planes[0].mem_priv == NULL;
 
memset(planes, 0, sizeof(planes[0]) * vb->num_planes);
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index ac5898a..631f08b 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -433,6 +433,9 @@ struct vb2_buf_ops {
  * @quirk_poll_must_check_waiting_for_buffers: Return POLLERR at poll when QBUF
  *  has not been called. This is a vb1 idiom that has been adopted
  *  also by vb2.
+ * @capture_dma_bidirectional: use DMA_BIDIRECTIONAL for CAPTURE buffers; this
+ * allows HW to read from the CAPTURE buffers in
+ * addition to writing; ignored for OUTPUT queues.
  * @lock:  pointer to a mutex that protects the vb2_queue struct. The
  * driver can set this to a mutex to let the v4l2 core serialize
  * the queuing ioctls. If the driver wants to handle locking
@@ -499,6 +502,7 @@ struct vb2_queue {
unsignedfileio_write_immediately:1;
unsignedallow_zero_bytesused:1;
unsigned   quirk_poll_must_check_waiting_for_buffers:1;
+   unsignedcapture_dma_bidirectional:1;
 
struct mutex*lock;
void*owner;
@@ -554,6 +558,17 @@ struct vb2_queue {
 #endif
 };
 
+/*
+ * Return the corresponding DMA direction given the vb2_queue type (capture or
+ * output). returns DMA_BIRECTIONAL for capture buffers if the vb2_queue field
+ * capture_dma_bidirectional is set by the driver.
+ */
+#define VB2_DMA_DIR(q) (V4L2_TYPE_IS_OUTPUT((q)->type)   \
+   ? DMA_TO_DEVICE  \
+   : (q)->capture_dma_bidirectional \
+ ? DMA_BIDIRECTIONAL\
+ : DMA_FROM_DEVICE)
+
 /**
  * vb2_plane_vaddr() - Return a kernel virtual address of a given plane
  * @vb:vb2_buffer to which the plane in question belongs to
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/2] [media] vb2: Store dma_dir in vb2_queue

2016-10-20 Thread Thierry Escande

Hi Sakari,

On 19/10/2016 23:29, Sakari Ailus wrote:

Hi Thierry,

On Wed, Oct 19, 2016 at 10:24:16AM +0200, Thierry Escande wrote:

From: Pawel Osciak <posc...@chromium.org>

Store dma_dir in struct vb2_queue and reuse it, instead of recalculating
it each time.

Signed-off-by: Pawel Osciak <posc...@chromium.org>
Tested-by: Pawel Osciak <posc...@chromium.org>
Reviewed-by: Tomasz Figa <tf...@chromium.org>
Reviewed-by: Owen Lin <owen...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
---
 drivers/media/v4l2-core/videobuf2-core.c | 12 +++-
 drivers/media/v4l2-core/videobuf2-v4l2.c |  2 ++
 include/media/videobuf2-core.h   |  2 ++
 3 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-core.c 
b/drivers/media/v4l2-core/videobuf2-core.c
index 21900202..f12103c 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -194,8 +194,6 @@ static void __enqueue_in_driver(struct vb2_buffer *vb);
 static int __vb2_buf_mem_alloc(struct vb2_buffer *vb)
 {
struct vb2_queue *q = vb->vb2_queue;
-   enum dma_data_direction dma_dir =
-   q->is_output ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
void *mem_priv;
int plane;
int ret = -ENOMEM;
@@ -209,7 +207,7 @@ static int __vb2_buf_mem_alloc(struct vb2_buffer *vb)

mem_priv = call_ptr_memop(vb, alloc,
q->alloc_devs[plane] ? : q->dev,
-   q->dma_attrs, size, dma_dir, q->gfp_flags);
+   q->dma_attrs, size, q->dma_dir, q->gfp_flags);


My bad, I guess I expressed myself unclearly.

Could you introduce the macro in this patch? You can then remove q->dma_dir
altogether.

My bad. Sorry for the confusion...

The v3 is on its way.

Regards,
 Thierry

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/2] [media] vb2: Add support for capture_dma_bidirectional queue flag

2016-10-19 Thread Thierry Escande
From: Pawel Osciak <posc...@chromium.org>

When this flag is set for CAPTURE queues by the driver on calling
vb2_queue_init(), it forces the buffers on the queue to be
allocated/mapped with DMA_BIDIRECTIONAL direction flag, instead of
DMA_FROM_DEVICE. This allows the device not only to write to the
buffers, but also read out from them. This may be useful e.g. for codec
hardware, which may be using CAPTURE buffers as reference to decode
other buffers.

This flag is ignored for OUTPUT queues, as we don't want to allow HW to
be able to write to OUTPUT buffers.

Signed-off-by: Pawel Osciak <posc...@chromium.org>
Tested-by: Pawel Osciak <posc...@chromium.org>
Reviewed-by: Tomasz Figa <tf...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
---
 drivers/media/v4l2-core/videobuf2-v4l2.c |  3 +--
 include/media/videobuf2-core.h   | 14 ++
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-v4l2.c 
b/drivers/media/v4l2-core/videobuf2-v4l2.c
index fde1e2d..c92197c 100644
--- a/drivers/media/v4l2-core/videobuf2-v4l2.c
+++ b/drivers/media/v4l2-core/videobuf2-v4l2.c
@@ -659,8 +659,7 @@ int vb2_queue_init(struct vb2_queue *q)
 * queues will always initialize waiting_for_buffers to false.
 */
q->quirk_poll_must_check_waiting_for_buffers = true;
-   q->dma_dir = V4L2_TYPE_IS_OUTPUT(q->type)
-  ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
+   q->dma_dir = VB2_DMA_DIR(q);
 
return vb2_core_queue_init(q);
 }
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index 38410dd..cd55917 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -433,6 +433,9 @@ struct vb2_buf_ops {
  * @quirk_poll_must_check_waiting_for_buffers: Return POLLERR at poll when QBUF
  *  has not been called. This is a vb1 idiom that has been adopted
  *  also by vb2.
+ * @capture_dma_bidirectional: use DMA_BIDIRECTIONAL for CAPTURE buffers; this
+ * allows HW to read from the CAPTURE buffers in
+ * addition to writing; ignored for OUTPUT queues.
  * @lock:  pointer to a mutex that protects the vb2_queue struct. The
  * driver can set this to a mutex to let the v4l2 core serialize
  * the queuing ioctls. If the driver wants to handle locking
@@ -500,6 +503,7 @@ struct vb2_queue {
unsignedfileio_write_immediately:1;
unsignedallow_zero_bytesused:1;
unsigned   quirk_poll_must_check_waiting_for_buffers:1;
+   unsignedcapture_dma_bidirectional:1;
 
struct mutex*lock;
void*owner;
@@ -556,6 +560,16 @@ struct vb2_queue {
 #endif
 };
 
+/*
+ * Return the corresponding DMA direction given the vb2_queue type (capture or
+ * output). returns DMA_BIRECTIONAL for capture buffers if set by the driver.
+ */
+#define VB2_DMA_DIR(q) (V4L2_TYPE_IS_OUTPUT((q)->type)   \
+   ? DMA_TO_DEVICE  \
+   : (q)->capture_dma_bidirectional \
+ ? DMA_BIDIRECTIONAL\
+ : DMA_FROM_DEVICE)
+
 /**
  * vb2_plane_vaddr() - Return a kernel virtual address of a given plane
  * @vb:vb2_buffer to which the plane in question belongs to
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/2] [media] vb2: Store dma_dir in vb2_queue

2016-10-19 Thread Thierry Escande
From: Pawel Osciak <posc...@chromium.org>

Store dma_dir in struct vb2_queue and reuse it, instead of recalculating
it each time.

Signed-off-by: Pawel Osciak <posc...@chromium.org>
Tested-by: Pawel Osciak <posc...@chromium.org>
Reviewed-by: Tomasz Figa <tf...@chromium.org>
Reviewed-by: Owen Lin <owen...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
---
 drivers/media/v4l2-core/videobuf2-core.c | 12 +++-
 drivers/media/v4l2-core/videobuf2-v4l2.c |  2 ++
 include/media/videobuf2-core.h   |  2 ++
 3 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-core.c 
b/drivers/media/v4l2-core/videobuf2-core.c
index 21900202..f12103c 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -194,8 +194,6 @@ static void __enqueue_in_driver(struct vb2_buffer *vb);
 static int __vb2_buf_mem_alloc(struct vb2_buffer *vb)
 {
struct vb2_queue *q = vb->vb2_queue;
-   enum dma_data_direction dma_dir =
-   q->is_output ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
void *mem_priv;
int plane;
int ret = -ENOMEM;
@@ -209,7 +207,7 @@ static int __vb2_buf_mem_alloc(struct vb2_buffer *vb)
 
mem_priv = call_ptr_memop(vb, alloc,
q->alloc_devs[plane] ? : q->dev,
-   q->dma_attrs, size, dma_dir, q->gfp_flags);
+   q->dma_attrs, size, q->dma_dir, q->gfp_flags);
if (IS_ERR(mem_priv)) {
if (mem_priv)
ret = PTR_ERR(mem_priv);
@@ -978,8 +976,6 @@ static int __qbuf_userptr(struct vb2_buffer *vb, const void 
*pb)
void *mem_priv;
unsigned int plane;
int ret = 0;
-   enum dma_data_direction dma_dir =
-   q->is_output ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
bool reacquired = vb->planes[0].mem_priv == NULL;
 
memset(planes, 0, sizeof(planes[0]) * vb->num_planes);
@@ -1030,7 +1026,7 @@ static int __qbuf_userptr(struct vb2_buffer *vb, const 
void *pb)
mem_priv = call_ptr_memop(vb, get_userptr,
q->alloc_devs[plane] ? : q->dev,
planes[plane].m.userptr,
-   planes[plane].length, dma_dir);
+   planes[plane].length, q->dma_dir);
if (IS_ERR(mem_priv)) {
dprintk(1, "failed acquiring userspace "
"memory for plane %d\n", plane);
@@ -1096,8 +1092,6 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const 
void *pb)
void *mem_priv;
unsigned int plane;
int ret = 0;
-   enum dma_data_direction dma_dir =
-   q->is_output ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
bool reacquired = vb->planes[0].mem_priv == NULL;
 
memset(planes, 0, sizeof(planes[0]) * vb->num_planes);
@@ -1156,7 +1150,7 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const 
void *pb)
/* Acquire each plane's memory */
mem_priv = call_ptr_memop(vb, attach_dmabuf,
q->alloc_devs[plane] ? : q->dev,
-   dbuf, planes[plane].length, dma_dir);
+   dbuf, planes[plane].length, q->dma_dir);
if (IS_ERR(mem_priv)) {
dprintk(1, "failed to attach dmabuf\n");
ret = PTR_ERR(mem_priv);
diff --git a/drivers/media/v4l2-core/videobuf2-v4l2.c 
b/drivers/media/v4l2-core/videobuf2-v4l2.c
index 52ef883..fde1e2d 100644
--- a/drivers/media/v4l2-core/videobuf2-v4l2.c
+++ b/drivers/media/v4l2-core/videobuf2-v4l2.c
@@ -659,6 +659,8 @@ int vb2_queue_init(struct vb2_queue *q)
 * queues will always initialize waiting_for_buffers to false.
 */
q->quirk_poll_must_check_waiting_for_buffers = true;
+   q->dma_dir = V4L2_TYPE_IS_OUTPUT(q->type)
+  ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
 
return vb2_core_queue_init(q);
 }
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index ac5898a..38410dd 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -489,6 +489,7 @@ struct vb2_buf_ops {
  * when a buffer with the V4L2_BUF_FLAG_LAST is dequeued.
  * @fileio:file io emulator internal data, used only if emulator is active
  * @threadio:  thread io internal data, used only if thread is active
+ * @dma_dir:   DMA direction to use for buffers on this queue
  */
 struct vb2_queue {
unsigned inttype;
@@ -540,6 +541,7 @@ struct vb2_queue {
 
struct vb2_fileio_data  *fileio;
struct vb2_threadio_data  

[PATCH 0/2] [media] DMA direction support in vb2_queue

2016-10-19 Thread Thierry Escande
Hi,

This series adds a dma_dir field to the vb2_queue structure in order to
store the DMA direction once for all in vb2_queue_init();

It also adds a new capture_dma_bidirectional flag to the vb2_queue
structure allowing the hardware to read from the CAPTURE buffer. This
flag is ignored for OUTPUT queues. This is used on ChromeOS by the
rockchip-vpu driver.

Changes since v1:
- Renamed use_dma_bidirectional field as capture_dma_bidirectional
- Added a VB2_DMA_DIR() macro

Pawel Osciak (2):
  [media] vb2: Store dma_dir in vb2_queue
  [media] vb2: Add support for capture_dma_bidirectional queue flag

 drivers/media/v4l2-core/videobuf2-core.c | 12 +++-
 drivers/media/v4l2-core/videobuf2-v4l2.c |  6 ++
 include/media/videobuf2-core.h   |  6 ++
 3 files changed, 15 insertions(+), 9 deletions(-)

-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/2] [media] vb2: Add support for use_dma_bidirectional queue flag

2016-10-18 Thread Thierry Escande

Hi Sakari,

On 17/10/2016 12:06, Sakari Ailus wrote:

Hi Thierry,

Thanks for the set. A few comments below.

On Fri, Oct 14, 2016 at 02:08:14PM +0200, Thierry Escande wrote:

From: Pawel Osciak <posc...@chromium.org>

When this flag is set for CAPTURE queues by the driver on calling
vb2_queue_init(), it forces the buffers on the queue to be
allocated/mapped with DMA_BIDIRECTIONAL direction flag, instead of
DMA_FROM_DEVICE. This allows the device not only to write to the
buffers, but also read out from them. This may be useful e.g. for codec
hardware, which may be using CAPTURE buffers as reference to decode
other buffers.


Just out of curiosity --- when do you return these buffers back to the user?
Once they're no longer needed as reference frames?
Tbh, I don't now. This is used by a rockchip vpu driver not yet 
upstreamed in the chromeos v4.4 kernel tree. Pawel might answer this 
question I guess.






This flag is ignored for OUTPUT queues, as we don't want to allow HW to
be able to write to OUTPUT buffers.

Signed-off-by: Pawel Osciak <posc...@chromium.org>
Tested-by: Pawel Osciak <posc...@chromium.org>
Reviewed-by: Tomasz Figa <tf...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
---
 drivers/media/v4l2-core/videobuf2-v4l2.c | 8 ++--
 include/media/videobuf2-core.h   | 4 
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-v4l2.c 
b/drivers/media/v4l2-core/videobuf2-v4l2.c
index fde1e2d..9255291 100644
--- a/drivers/media/v4l2-core/videobuf2-v4l2.c
+++ b/drivers/media/v4l2-core/videobuf2-v4l2.c
@@ -659,8 +659,12 @@ int vb2_queue_init(struct vb2_queue *q)
 * queues will always initialize waiting_for_buffers to false.
 */
q->quirk_poll_must_check_waiting_for_buffers = true;
-   q->dma_dir = V4L2_TYPE_IS_OUTPUT(q->type)
-  ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
+
+   if (V4L2_TYPE_IS_OUTPUT(q->type))
+   q->dma_dir = DMA_TO_DEVICE;
+   else
+   q->dma_dir = q->use_dma_bidirectional
+  ? DMA_BIDIRECTIONAL : DMA_FROM_DEVICE;

return vb2_core_queue_init(q);
 }
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index 38410dd..e613c74 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -433,6 +433,9 @@ struct vb2_buf_ops {
  * @quirk_poll_must_check_waiting_for_buffers: Return POLLERR at poll when QBUF
  *  has not been called. This is a vb1 idiom that has been adopted
  *  also by vb2.
+ * @use_dma_bidirectional: use DMA_BIDIRECTIONAL for CAPTURE buffers; this
+ * allows HW to read from the CAPTURE buffers in
+ * addition to writing; ignored for OUTPUT queues
  * @lock:  pointer to a mutex that protects the vb2_queue struct. The
  * driver can set this to a mutex to let the v4l2 core serialize
  * the queuing ioctls. If the driver wants to handle locking
@@ -500,6 +503,7 @@ struct vb2_queue {
unsignedfileio_write_immediately:1;
unsignedallow_zero_bytesused:1;
unsigned   quirk_poll_must_check_waiting_for_buffers:1;
+   unsigneduse_dma_bidirectional:1;


This field is in the same struct as dma_dir which it directly affects.

How about adding a macro instead to give you the queue DMA direction
instead?

E.g.

#define vb2_dma_dir(q) \
(V4L2_TYPE_IS_OUTPUT((q)->type) ? DMA_TO_DEVICE : \
 (q)->use_dma_bidirectional ? DMA_BIDIRECTIONAL : DMA_FROM_DEVICE)

I would call this capture_dma_bidirectional as it only affects capture. Or
simply choose DMA_BIDIRECTIONAL whenever the flag is set.

Sure. Will do.

Regards,
 Thierry
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [media] videobuf2-dma-contig: Support cacheable MMAP

2016-10-14 Thread Thierry Escande
From: Heng-Ruey Hsu <henry...@chromium.org>

DMA allocations for MMAP type are uncached by default. But for
some cases, CPU has to access the buffers. ie: memcpy for format
converter. Supporting cacheable MMAP improves huge performance.

Signed-off-by: Heng-Ruey Hsu <henry...@chromium.org>
Tested-by: Heng-ruey Hsu <henry...@chromium.org>
Reviewed-by: Tomasz Figa <tf...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
---
 drivers/media/v4l2-core/videobuf2-dma-contig.c | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index fb6a177..c953c24 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -42,6 +42,12 @@ struct vb2_dc_buf {
 };
 
 /*/
+/*   Forward declarations*/
+/*/
+
+static struct sg_table *vb2_dc_get_base_sgt(struct vb2_dc_buf *buf);
+
+/*/
 /*scatterlist table functions*/
 /*/
 
@@ -129,6 +135,10 @@ static void vb2_dc_put(void *buf_priv)
sg_free_table(buf->sgt_base);
kfree(buf->sgt_base);
}
+   if (buf->dma_sgt) {
+   sg_free_table(buf->dma_sgt);
+   kfree(buf->dma_sgt);
+   }
dma_free_attrs(buf->dev, buf->size, buf->cookie, buf->dma_addr,
   buf->attrs);
put_device(buf->dev);
@@ -170,6 +180,10 @@ static void *vb2_dc_alloc(struct device *dev, unsigned 
long attrs,
buf->handler.put = vb2_dc_put;
buf->handler.arg = buf;
 
+   if (!(buf->attrs & DMA_ATTR_NO_KERNEL_MAPPING) &&
+(buf->attrs & DMA_ATTR_NON_CONSISTENT))
+   buf->dma_sgt = vb2_dc_get_base_sgt(buf);
+
atomic_inc(>refcount);
 
return buf;
@@ -205,6 +219,11 @@ static int vb2_dc_mmap(void *buf_priv, struct 
vm_area_struct *vma)
 
vma->vm_ops->open(vma);
 
+   if ((buf->attrs & DMA_ATTR_NO_KERNEL_MAPPING) &&
+   (buf->attrs & DMA_ATTR_NON_CONSISTENT) &&
+   !buf->dma_sgt)
+   buf->dma_sgt = vb2_dc_get_base_sgt(buf);
+
pr_debug("%s: mapped dma addr 0x%08lx at 0x%08lx, size %ld\n",
__func__, (unsigned long)buf->dma_addr, vma->vm_start,
buf->size);
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/2] [media] vb2: Add support for use_dma_bidirectional queue flag

2016-10-14 Thread Thierry Escande
From: Pawel Osciak <posc...@chromium.org>

When this flag is set for CAPTURE queues by the driver on calling
vb2_queue_init(), it forces the buffers on the queue to be
allocated/mapped with DMA_BIDIRECTIONAL direction flag, instead of
DMA_FROM_DEVICE. This allows the device not only to write to the
buffers, but also read out from them. This may be useful e.g. for codec
hardware, which may be using CAPTURE buffers as reference to decode
other buffers.

This flag is ignored for OUTPUT queues, as we don't want to allow HW to
be able to write to OUTPUT buffers.

Signed-off-by: Pawel Osciak <posc...@chromium.org>
Tested-by: Pawel Osciak <posc...@chromium.org>
Reviewed-by: Tomasz Figa <tf...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
---
 drivers/media/v4l2-core/videobuf2-v4l2.c | 8 ++--
 include/media/videobuf2-core.h   | 4 
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-v4l2.c 
b/drivers/media/v4l2-core/videobuf2-v4l2.c
index fde1e2d..9255291 100644
--- a/drivers/media/v4l2-core/videobuf2-v4l2.c
+++ b/drivers/media/v4l2-core/videobuf2-v4l2.c
@@ -659,8 +659,12 @@ int vb2_queue_init(struct vb2_queue *q)
 * queues will always initialize waiting_for_buffers to false.
 */
q->quirk_poll_must_check_waiting_for_buffers = true;
-   q->dma_dir = V4L2_TYPE_IS_OUTPUT(q->type)
-  ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
+
+   if (V4L2_TYPE_IS_OUTPUT(q->type))
+   q->dma_dir = DMA_TO_DEVICE;
+   else
+   q->dma_dir = q->use_dma_bidirectional
+  ? DMA_BIDIRECTIONAL : DMA_FROM_DEVICE;
 
return vb2_core_queue_init(q);
 }
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index 38410dd..e613c74 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -433,6 +433,9 @@ struct vb2_buf_ops {
  * @quirk_poll_must_check_waiting_for_buffers: Return POLLERR at poll when QBUF
  *  has not been called. This is a vb1 idiom that has been adopted
  *  also by vb2.
+ * @use_dma_bidirectional: use DMA_BIDIRECTIONAL for CAPTURE buffers; this
+ * allows HW to read from the CAPTURE buffers in
+ * addition to writing; ignored for OUTPUT queues
  * @lock:  pointer to a mutex that protects the vb2_queue struct. The
  * driver can set this to a mutex to let the v4l2 core serialize
  * the queuing ioctls. If the driver wants to handle locking
@@ -500,6 +503,7 @@ struct vb2_queue {
unsignedfileio_write_immediately:1;
unsignedallow_zero_bytesused:1;
unsigned   quirk_poll_must_check_waiting_for_buffers:1;
+   unsigneduse_dma_bidirectional:1;
 
struct mutex*lock;
void*owner;
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/2] [media] vb2: Store dma_dir in vb2_queue

2016-10-14 Thread Thierry Escande
From: Pawel Osciak <posc...@chromium.org>

Store dma_dir in struct vb2_queue and reuse it, instead of recalculating
it each time.

Signed-off-by: Pawel Osciak <posc...@chromium.org>
Tested-by: Pawel Osciak <posc...@chromium.org>
Reviewed-by: Tomasz Figa <tf...@chromium.org>
Reviewed-by: Owen Lin <owen...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
---
 drivers/media/v4l2-core/videobuf2-core.c | 12 +++-
 drivers/media/v4l2-core/videobuf2-v4l2.c |  2 ++
 include/media/videobuf2-core.h   |  2 ++
 3 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-core.c 
b/drivers/media/v4l2-core/videobuf2-core.c
index 21900202..f12103c 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -194,8 +194,6 @@ static void __enqueue_in_driver(struct vb2_buffer *vb);
 static int __vb2_buf_mem_alloc(struct vb2_buffer *vb)
 {
struct vb2_queue *q = vb->vb2_queue;
-   enum dma_data_direction dma_dir =
-   q->is_output ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
void *mem_priv;
int plane;
int ret = -ENOMEM;
@@ -209,7 +207,7 @@ static int __vb2_buf_mem_alloc(struct vb2_buffer *vb)
 
mem_priv = call_ptr_memop(vb, alloc,
q->alloc_devs[plane] ? : q->dev,
-   q->dma_attrs, size, dma_dir, q->gfp_flags);
+   q->dma_attrs, size, q->dma_dir, q->gfp_flags);
if (IS_ERR(mem_priv)) {
if (mem_priv)
ret = PTR_ERR(mem_priv);
@@ -978,8 +976,6 @@ static int __qbuf_userptr(struct vb2_buffer *vb, const void 
*pb)
void *mem_priv;
unsigned int plane;
int ret = 0;
-   enum dma_data_direction dma_dir =
-   q->is_output ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
bool reacquired = vb->planes[0].mem_priv == NULL;
 
memset(planes, 0, sizeof(planes[0]) * vb->num_planes);
@@ -1030,7 +1026,7 @@ static int __qbuf_userptr(struct vb2_buffer *vb, const 
void *pb)
mem_priv = call_ptr_memop(vb, get_userptr,
q->alloc_devs[plane] ? : q->dev,
planes[plane].m.userptr,
-   planes[plane].length, dma_dir);
+   planes[plane].length, q->dma_dir);
if (IS_ERR(mem_priv)) {
dprintk(1, "failed acquiring userspace "
"memory for plane %d\n", plane);
@@ -1096,8 +1092,6 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const 
void *pb)
void *mem_priv;
unsigned int plane;
int ret = 0;
-   enum dma_data_direction dma_dir =
-   q->is_output ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
bool reacquired = vb->planes[0].mem_priv == NULL;
 
memset(planes, 0, sizeof(planes[0]) * vb->num_planes);
@@ -1156,7 +1150,7 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const 
void *pb)
/* Acquire each plane's memory */
mem_priv = call_ptr_memop(vb, attach_dmabuf,
q->alloc_devs[plane] ? : q->dev,
-   dbuf, planes[plane].length, dma_dir);
+   dbuf, planes[plane].length, q->dma_dir);
if (IS_ERR(mem_priv)) {
dprintk(1, "failed to attach dmabuf\n");
ret = PTR_ERR(mem_priv);
diff --git a/drivers/media/v4l2-core/videobuf2-v4l2.c 
b/drivers/media/v4l2-core/videobuf2-v4l2.c
index 52ef883..fde1e2d 100644
--- a/drivers/media/v4l2-core/videobuf2-v4l2.c
+++ b/drivers/media/v4l2-core/videobuf2-v4l2.c
@@ -659,6 +659,8 @@ int vb2_queue_init(struct vb2_queue *q)
 * queues will always initialize waiting_for_buffers to false.
 */
q->quirk_poll_must_check_waiting_for_buffers = true;
+   q->dma_dir = V4L2_TYPE_IS_OUTPUT(q->type)
+  ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
 
return vb2_core_queue_init(q);
 }
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index ac5898a..38410dd 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -489,6 +489,7 @@ struct vb2_buf_ops {
  * when a buffer with the V4L2_BUF_FLAG_LAST is dequeued.
  * @fileio:file io emulator internal data, used only if emulator is active
  * @threadio:  thread io internal data, used only if thread is active
+ * @dma_dir:   DMA direction to use for buffers on this queue
  */
 struct vb2_queue {
unsigned inttype;
@@ -540,6 +541,7 @@ struct vb2_queue {
 
struct vb2_fileio_data  *fileio;
struct vb2_threadio_data  

[PATCH 0/2] [media] DMA direction support in vb2_queue

2016-10-14 Thread Thierry Escande
Hi,

This series adds a dma_dir field to the vb2_queue structure in order to
store the DMA direction once for all in vb2_queue_init();

It also adds a new use_dma_bidirectional flag to the vb2_queue structure
allowing the hardware to read from the CAPTURE buffer. This flag is
ignored for OUTPUT queues. This is used on ChromeOS by the rockchip-vpu
driver.

Pawel Osciak (2):
  [media] vb2: Store dma_dir in vb2_queue
  [media] vb2: Add support for use_dma_bidirectional queue flag

 drivers/media/v4l2-core/videobuf2-core.c | 12 +++-
 drivers/media/v4l2-core/videobuf2-v4l2.c |  6 ++
 include/media/videobuf2-core.h   |  6 ++
 3 files changed, 15 insertions(+), 9 deletions(-)

-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html