linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [Patch v2 00/35] media: ti-vpe: fixes and enhancements
@ 2016-11-18 23:20 Benoit Parrot
  2016-11-18 23:20 ` [Patch v2 01/35] media: ti-vpe: vpdma: Make vpdma library into its own module Benoit Parrot
                   ` (34 more replies)
  0 siblings, 35 replies; 36+ messages in thread
From: Benoit Parrot @ 2016-11-18 23:20 UTC (permalink / raw)
  To: linux-media, Hans Verkuil
  Cc: linux-kernel, Tomi Valkeinen, Jyri Sarha, Peter Ujfalusi, Benoit Parrot

This patch series is to publish a number of enhancements
we have been carrying for a while.

A number of bug fixes and feature enhancements have been
included.

We also need to prepare the way for the introduction of
the VIP (Video Input Port) driver (coming soon) which
has internal IP module in common with VPE.

The relevant modules (vpdma, sc and csc) are therefore converted
into individual kernel modules.

Changes since v1:
- Fix typos from comments
- Clarified commit log based on comments
- Added Acked-by and Reviewed-by tags to relevant patches.

Archit Taneja (1):
  media: ti-vpe: Use line average de-interlacing for first 2 frames

Benoit Parrot (16):
  media: ti-vpe: vpdma: Make vpdma library into its own module
  media: ti-vpe: vpdma: Add multi-instance and multi-client support
  media: ti-vpe: vpdma: Add helper to set a background color
  media: ti-vpe: vpdma: Fix bus error when vpdma is writing a descriptor
  media: ti-vpe: vpe: Added MODULE_DEVICE_TABLE hint
  media: ti-vpe: vpdma: Corrected YUV422 data type label.
  media: ti-vpe: vpdma: RGB data type yield inverted data
  media: ti-vpe: vpe: Fix vb2 buffer cleanup
  media: ti-vpe: vpe: Enable DMABUF export
  media: ti-vpe: Make scaler library into its own module
  media: ti-vpe: scaler: Add debug support for multi-instance
  media: ti-vpe: vpe: Make sure frame size dont exceed scaler capacity
  media: ti-vpe: vpdma: Add RAW8 and RAW16 data types
  media: ti-vpe: Make colorspace converter library into its own module
  media: ti-vpe: csc: Add debug support for multi-instance
  media: ti-vpe: vpe: Add proper support single and multi-plane buffer

Harinarayan Bhatta (2):
  media: ti-vpe: Increasing max buffer height and width
  media: ti-vpe: Free vpdma buffers in vpe_release

Nikhil Devshatwar (16):
  media: ti-vpe: vpe: Do not perform job transaction atomically
  media: ti-vpe: Add support for SEQ_TB buffers
  media: ti-vpe: vpe: Return NULL for invalid buffer type
  media: ti-vpe: vpdma: Add support for setting max width height
  media: ti-vpe: vpdma: Add abort channel desc and cleanup APIs
  media: ti-vpe: vpdma: Make list post atomic operation
  media: ti-vpe: vpdma: Clear IRQs for individual lists
  media: ti-vpe: vpe: configure line mode separately
  media: ti-vpe: vpe: Setup srcdst parameters in start_streaming
  media: ti-vpe: vpe: Post next descriptor only for list complete IRQ
  media: ti-vpe: vpe: Add RGB565 and RGB5551 support
  media: ti-vpe: vpdma: allocate and maintain hwlist
  media: ti-vpe: sc: Fix incorrect optimization
  media: ti-vpe: vpdma: Fix race condition for firmware loading
  media: ti-vpe: vpdma: Use bidirectional cached buffers
  media: ti-vpe: vpe: Fix line stride for output motion vector

 drivers/media/platform/Kconfig             |  14 +
 drivers/media/platform/ti-vpe/Makefile     |  10 +-
 drivers/media/platform/ti-vpe/csc.c        |  18 +-
 drivers/media/platform/ti-vpe/csc.h        |   2 +-
 drivers/media/platform/ti-vpe/sc.c         |  28 +-
 drivers/media/platform/ti-vpe/sc.h         |  11 +-
 drivers/media/platform/ti-vpe/vpdma.c      | 349 +++++++++++++++++++---
 drivers/media/platform/ti-vpe/vpdma.h      |  85 +++++-
 drivers/media/platform/ti-vpe/vpdma_priv.h | 130 ++++-----
 drivers/media/platform/ti-vpe/vpe.c        | 450 ++++++++++++++++++++++++-----
 10 files changed, 891 insertions(+), 206 deletions(-)

-- 
2.9.0

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [Patch v2 01/35] media: ti-vpe: vpdma: Make vpdma library into its own module
  2016-11-18 23:20 [Patch v2 00/35] media: ti-vpe: fixes and enhancements Benoit Parrot
@ 2016-11-18 23:20 ` Benoit Parrot
  2016-11-18 23:20 ` [Patch v2 02/35] media: ti-vpe: vpdma: Add multi-instance and multi-client support Benoit Parrot
                   ` (33 subsequent siblings)
  34 siblings, 0 replies; 36+ messages in thread
From: Benoit Parrot @ 2016-11-18 23:20 UTC (permalink / raw)
  To: linux-media, Hans Verkuil
  Cc: linux-kernel, Tomi Valkeinen, Jyri Sarha, Peter Ujfalusi, Benoit Parrot

The VPDMA (Video Port DMA) as found in devices such as DRA7xx is
used for both the Video Processing Engine (VPE) and the Video Input
Port (VIP).

In preparation for this we need to turn vpdma into its own
kernel module.

Signed-off-by: Benoit Parrot <bparrot@ti.com>
---
 drivers/media/platform/Kconfig         |  6 ++++++
 drivers/media/platform/ti-vpe/Makefile |  4 +++-
 drivers/media/platform/ti-vpe/vpdma.c  | 28 +++++++++++++++++++++++++++-
 3 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index 3c5a0b6b23a9..b52b6771fc4d 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -364,6 +364,7 @@ config VIDEO_TI_VPE
 	depends on HAS_DMA
 	select VIDEOBUF2_DMA_CONTIG
 	select V4L2_MEM2MEM_DEV
+	select VIDEO_TI_VPDMA
 	default n
 	---help---
 	  Support for the TI VPE(Video Processing Engine) block
@@ -377,6 +378,11 @@ config VIDEO_TI_VPE_DEBUG
 
 endif # V4L_MEM2MEM_DRIVERS
 
+# TI VIDEO PORT Helper Modules
+# These will be selected by VPE and VIP
+config VIDEO_TI_VPDMA
+	tristate
+
 menuconfig V4L_TEST_DRIVERS
 	bool "Media test drivers"
 	depends on MEDIA_CAMERA_SUPPORT
diff --git a/drivers/media/platform/ti-vpe/Makefile b/drivers/media/platform/ti-vpe/Makefile
index e236059a60ad..faca5e115c1d 100644
--- a/drivers/media/platform/ti-vpe/Makefile
+++ b/drivers/media/platform/ti-vpe/Makefile
@@ -1,6 +1,8 @@
 obj-$(CONFIG_VIDEO_TI_VPE) += ti-vpe.o
+obj-$(CONFIG_VIDEO_TI_VPDMA) += ti-vpdma.o
 
-ti-vpe-y := vpe.o sc.o csc.o vpdma.o
+ti-vpe-y := vpe.o sc.o csc.o
+ti-vpdma-y := vpdma.o
 
 ccflags-$(CONFIG_VIDEO_TI_VPE_DEBUG) += -DDEBUG
 
diff --git a/drivers/media/platform/ti-vpe/vpdma.c b/drivers/media/platform/ti-vpe/vpdma.c
index 4aff05915051..7de0f3f55dcc 100644
--- a/drivers/media/platform/ti-vpe/vpdma.c
+++ b/drivers/media/platform/ti-vpe/vpdma.c
@@ -75,6 +75,7 @@ const struct vpdma_data_format vpdma_yuv_fmts[] = {
 		.depth		= 16,
 	},
 };
+EXPORT_SYMBOL(vpdma_yuv_fmts);
 
 const struct vpdma_data_format vpdma_rgb_fmts[] = {
 	[VPDMA_DATA_FMT_RGB565] = {
@@ -178,6 +179,7 @@ const struct vpdma_data_format vpdma_rgb_fmts[] = {
 		.depth		= 32,
 	},
 };
+EXPORT_SYMBOL(vpdma_rgb_fmts);
 
 const struct vpdma_data_format vpdma_misc_fmts[] = {
 	[VPDMA_DATA_FMT_MV] = {
@@ -186,6 +188,7 @@ const struct vpdma_data_format vpdma_misc_fmts[] = {
 		.depth		= 4,
 	},
 };
+EXPORT_SYMBOL(vpdma_misc_fmts);
 
 struct vpdma_channel_info {
 	int num;		/* VPDMA channel number */
@@ -317,6 +320,7 @@ void vpdma_dump_regs(struct vpdma_data *vpdma)
 	DUMPREG(VIP_UP_UV_CSTAT);
 	DUMPREG(VPI_CTL_CSTAT);
 }
+EXPORT_SYMBOL(vpdma_dump_regs);
 
 /*
  * Allocate a DMA buffer
@@ -333,6 +337,7 @@ int vpdma_alloc_desc_buf(struct vpdma_buf *buf, size_t size)
 
 	return 0;
 }
+EXPORT_SYMBOL(vpdma_alloc_desc_buf);
 
 void vpdma_free_desc_buf(struct vpdma_buf *buf)
 {
@@ -341,6 +346,7 @@ void vpdma_free_desc_buf(struct vpdma_buf *buf)
 	buf->addr = NULL;
 	buf->size = 0;
 }
+EXPORT_SYMBOL(vpdma_free_desc_buf);
 
 /*
  * map descriptor/payload DMA buffer, enabling DMA access
@@ -361,6 +367,7 @@ int vpdma_map_desc_buf(struct vpdma_data *vpdma, struct vpdma_buf *buf)
 
 	return 0;
 }
+EXPORT_SYMBOL(vpdma_map_desc_buf);
 
 /*
  * unmap descriptor/payload DMA buffer, disabling DMA access and
@@ -375,6 +382,7 @@ void vpdma_unmap_desc_buf(struct vpdma_data *vpdma, struct vpdma_buf *buf)
 
 	buf->mapped = false;
 }
+EXPORT_SYMBOL(vpdma_unmap_desc_buf);
 
 /*
  * create a descriptor list, the user of this list will append configuration,
@@ -396,6 +404,7 @@ int vpdma_create_desc_list(struct vpdma_desc_list *list, size_t size, int type)
 
 	return 0;
 }
+EXPORT_SYMBOL(vpdma_create_desc_list);
 
 /*
  * once a descriptor list is parsed by VPDMA, we reset the list by emptying it,
@@ -405,6 +414,7 @@ void vpdma_reset_desc_list(struct vpdma_desc_list *list)
 {
 	list->next = list->buf.addr;
 }
+EXPORT_SYMBOL(vpdma_reset_desc_list);
 
 /*
  * free the buffer allocated fot the VPDMA descriptor list, this should be
@@ -416,11 +426,13 @@ void vpdma_free_desc_list(struct vpdma_desc_list *list)
 
 	list->next = NULL;
 }
+EXPORT_SYMBOL(vpdma_free_desc_list);
 
-static bool vpdma_list_busy(struct vpdma_data *vpdma, int list_num)
+bool vpdma_list_busy(struct vpdma_data *vpdma, int list_num)
 {
 	return read_reg(vpdma, VPDMA_LIST_STAT_SYNC) & BIT(list_num + 16);
 }
+EXPORT_SYMBOL(vpdma_list_busy);
 
 /*
  * submit a list of DMA descriptors to the VPE VPDMA, do not wait for completion
@@ -446,6 +458,7 @@ int vpdma_submit_descs(struct vpdma_data *vpdma, struct vpdma_desc_list *list)
 
 	return 0;
 }
+EXPORT_SYMBOL(vpdma_submit_descs);
 
 static void dump_cfd(struct vpdma_cfd *cfd)
 {
@@ -498,6 +511,7 @@ void vpdma_add_cfd_block(struct vpdma_desc_list *list, int client,
 
 	dump_cfd(cfd);
 }
+EXPORT_SYMBOL(vpdma_add_cfd_block);
 
 /*
  * append a configuration descriptor to the given descriptor list, where the
@@ -526,6 +540,7 @@ void vpdma_add_cfd_adb(struct vpdma_desc_list *list, int client,
 
 	dump_cfd(cfd);
 };
+EXPORT_SYMBOL(vpdma_add_cfd_adb);
 
 /*
  * control descriptor format change based on what type of control descriptor it
@@ -563,6 +578,7 @@ void vpdma_add_sync_on_channel_ctd(struct vpdma_desc_list *list,
 
 	dump_ctd(ctd);
 }
+EXPORT_SYMBOL(vpdma_add_sync_on_channel_ctd);
 
 static void dump_dtd(struct vpdma_dtd *dtd)
 {
@@ -672,6 +688,7 @@ void vpdma_add_out_dtd(struct vpdma_desc_list *list, int width,
 
 	dump_dtd(dtd);
 }
+EXPORT_SYMBOL(vpdma_add_out_dtd);
 
 /*
  * append an inbound data transfer descriptor to the given descriptor list,
@@ -745,6 +762,7 @@ void vpdma_add_in_dtd(struct vpdma_desc_list *list, int width,
 
 	dump_dtd(dtd);
 }
+EXPORT_SYMBOL(vpdma_add_in_dtd);
 
 /* set or clear the mask for list complete interrupt */
 void vpdma_enable_list_complete_irq(struct vpdma_data *vpdma, int list_num,
@@ -759,6 +777,7 @@ void vpdma_enable_list_complete_irq(struct vpdma_data *vpdma, int list_num,
 		val &= ~(1 << (list_num * 2));
 	write_reg(vpdma, VPDMA_INT_LIST0_MASK, val);
 }
+EXPORT_SYMBOL(vpdma_enable_list_complete_irq);
 
 /* clear previosuly occured list intterupts in the LIST_STAT register */
 void vpdma_clear_list_stat(struct vpdma_data *vpdma)
@@ -766,6 +785,7 @@ void vpdma_clear_list_stat(struct vpdma_data *vpdma)
 	write_reg(vpdma, VPDMA_INT_LIST0_STAT,
 		read_reg(vpdma, VPDMA_INT_LIST0_STAT));
 }
+EXPORT_SYMBOL(vpdma_clear_list_stat);
 
 /*
  * configures the output mode of the line buffer for the given client, the
@@ -780,6 +800,7 @@ void vpdma_set_line_mode(struct vpdma_data *vpdma, int line_mode,
 	write_field_reg(vpdma, client_cstat, line_mode,
 		VPDMA_CSTAT_LINE_MODE_MASK, VPDMA_CSTAT_LINE_MODE_SHIFT);
 }
+EXPORT_SYMBOL(vpdma_set_line_mode);
 
 /*
  * configures the event which should trigger VPDMA transfer for the given
@@ -794,6 +815,7 @@ void vpdma_set_frame_start_event(struct vpdma_data *vpdma,
 	write_field_reg(vpdma, client_cstat, fs_event,
 		VPDMA_CSTAT_FRAME_START_MASK, VPDMA_CSTAT_FRAME_START_SHIFT);
 }
+EXPORT_SYMBOL(vpdma_set_frame_start_event);
 
 static void vpdma_firmware_cb(const struct firmware *f, void *context)
 {
@@ -907,4 +929,8 @@ struct vpdma_data *vpdma_create(struct platform_device *pdev,
 
 	return vpdma;
 }
+EXPORT_SYMBOL(vpdma_create);
+
+MODULE_AUTHOR("Texas Instruments Inc.");
 MODULE_FIRMWARE(VPDMA_FIRMWARE);
+MODULE_LICENSE("GPL v2");
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Patch v2 02/35] media: ti-vpe: vpdma: Add multi-instance and multi-client support
  2016-11-18 23:20 [Patch v2 00/35] media: ti-vpe: fixes and enhancements Benoit Parrot
  2016-11-18 23:20 ` [Patch v2 01/35] media: ti-vpe: vpdma: Make vpdma library into its own module Benoit Parrot
@ 2016-11-18 23:20 ` Benoit Parrot
  2016-11-18 23:20 ` [Patch v2 03/35] media: ti-vpe: vpdma: Add helper to set a background color Benoit Parrot
                   ` (32 subsequent siblings)
  34 siblings, 0 replies; 36+ messages in thread
From: Benoit Parrot @ 2016-11-18 23:20 UTC (permalink / raw)
  To: linux-media, Hans Verkuil
  Cc: linux-kernel, Tomi Valkeinen, Jyri Sarha, Peter Ujfalusi, Benoit Parrot

The VPDMA (Video Port DMA) as found in devices such as DRA7xx is
used for both the Video Processing Engine (VPE) and the Video Input
Port (VIP). Some devices may have multiple VIP instances each with
its own VPDMA engine. Within VIP two slices can use a single VPDMA
engine simultaneously. So support for multi instances and multiple
clients has been added to VPDMA. Needed modification to the existing
helper functions were then reflected to VPE.

Multi-clients registers offset have also been added in preparation.

Signed-off-by: Benoit Parrot <bparrot@ti.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/platform/ti-vpe/vpdma.c      | 104 +++++++++++++++++++++++++----
 drivers/media/platform/ti-vpe/vpdma.h      |  25 +++++--
 drivers/media/platform/ti-vpe/vpdma_priv.h |  15 ++++-
 drivers/media/platform/ti-vpe/vpe.c        |   8 +--
 4 files changed, 128 insertions(+), 24 deletions(-)

diff --git a/drivers/media/platform/ti-vpe/vpdma.c b/drivers/media/platform/ti-vpe/vpdma.c
index 7de0f3f55dcc..2b094016b470 100644
--- a/drivers/media/platform/ti-vpe/vpdma.c
+++ b/drivers/media/platform/ti-vpe/vpdma.c
@@ -437,10 +437,9 @@ EXPORT_SYMBOL(vpdma_list_busy);
 /*
  * submit a list of DMA descriptors to the VPE VPDMA, do not wait for completion
  */
-int vpdma_submit_descs(struct vpdma_data *vpdma, struct vpdma_desc_list *list)
+int vpdma_submit_descs(struct vpdma_data *vpdma,
+			struct vpdma_desc_list *list, int list_num)
 {
-	/* we always use the first list */
-	int list_num = 0;
 	int list_size;
 
 	if (vpdma_list_busy(vpdma, list_num))
@@ -460,6 +459,40 @@ int vpdma_submit_descs(struct vpdma_data *vpdma, struct vpdma_desc_list *list)
 }
 EXPORT_SYMBOL(vpdma_submit_descs);
 
+static void dump_dtd(struct vpdma_dtd *dtd);
+
+void vpdma_update_dma_addr(struct vpdma_data *vpdma,
+	struct vpdma_desc_list *list, dma_addr_t dma_addr,
+	void *write_dtd, int drop, int idx)
+{
+	struct vpdma_dtd *dtd = list->buf.addr;
+	dma_addr_t write_desc_addr;
+	int offset;
+
+	dtd += idx;
+	vpdma_unmap_desc_buf(vpdma, &list->buf);
+
+	dtd->start_addr = dma_addr;
+
+	/* Calculate write address from the offset of write_dtd from start
+	 * of the list->buf
+	 */
+	offset = (void *)write_dtd - list->buf.addr;
+	write_desc_addr = list->buf.dma_addr + offset;
+
+	if (drop)
+		dtd->desc_write_addr = dtd_desc_write_addr(write_desc_addr,
+							   1, 1, 0);
+	else
+		dtd->desc_write_addr = dtd_desc_write_addr(write_desc_addr,
+							   1, 0, 0);
+
+	vpdma_map_desc_buf(vpdma, &list->buf);
+
+	dump_dtd(dtd);
+}
+EXPORT_SYMBOL(vpdma_update_dma_addr);
+
 static void dump_cfd(struct vpdma_cfd *cfd)
 {
 	int class;
@@ -642,6 +675,16 @@ void vpdma_add_out_dtd(struct vpdma_desc_list *list, int width,
 		const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
 		enum vpdma_channel chan, u32 flags)
 {
+	vpdma_rawchan_add_out_dtd(list, width, c_rect, fmt, dma_addr,
+				  chan_info[chan].num, flags);
+}
+EXPORT_SYMBOL(vpdma_add_out_dtd);
+
+void vpdma_rawchan_add_out_dtd(struct vpdma_desc_list *list, int width,
+		const struct v4l2_rect *c_rect,
+		const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
+		int raw_vpdma_chan, u32 flags)
+{
 	int priority = 0;
 	int field = 0;
 	int notify = 1;
@@ -651,7 +694,7 @@ void vpdma_add_out_dtd(struct vpdma_desc_list *list, int width,
 	int stride;
 	struct vpdma_dtd *dtd;
 
-	channel = next_chan = chan_info[chan].num;
+	channel = next_chan = raw_vpdma_chan;
 
 	if (fmt->type == VPDMA_DATA_FMT_TYPE_YUV &&
 			fmt->data_type == DATA_TYPE_C420) {
@@ -688,7 +731,7 @@ void vpdma_add_out_dtd(struct vpdma_desc_list *list, int width,
 
 	dump_dtd(dtd);
 }
-EXPORT_SYMBOL(vpdma_add_out_dtd);
+EXPORT_SYMBOL(vpdma_rawchan_add_out_dtd);
 
 /*
  * append an inbound data transfer descriptor to the given descriptor list,
@@ -765,25 +808,62 @@ void vpdma_add_in_dtd(struct vpdma_desc_list *list, int width,
 EXPORT_SYMBOL(vpdma_add_in_dtd);
 
 /* set or clear the mask for list complete interrupt */
-void vpdma_enable_list_complete_irq(struct vpdma_data *vpdma, int list_num,
-		bool enable)
+void vpdma_enable_list_complete_irq(struct vpdma_data *vpdma, int irq_num,
+		int list_num, bool enable)
 {
+	u32 reg_addr = VPDMA_INT_LIST0_MASK + VPDMA_INTX_OFFSET * irq_num;
 	u32 val;
 
-	val = read_reg(vpdma, VPDMA_INT_LIST0_MASK);
+	val = read_reg(vpdma, reg_addr);
 	if (enable)
 		val |= (1 << (list_num * 2));
 	else
 		val &= ~(1 << (list_num * 2));
-	write_reg(vpdma, VPDMA_INT_LIST0_MASK, val);
+	write_reg(vpdma, reg_addr, val);
 }
 EXPORT_SYMBOL(vpdma_enable_list_complete_irq);
 
+/* set or clear the mask for list complete interrupt */
+void vpdma_enable_list_notify_irq(struct vpdma_data *vpdma, int irq_num,
+		int list_num, bool enable)
+{
+	u32 reg_addr = VPDMA_INT_LIST0_MASK + VPDMA_INTX_OFFSET * irq_num;
+	u32 val;
+
+	val = read_reg(vpdma, reg_addr);
+	if (enable)
+		val |= (1 << ((list_num * 2) + 1));
+	else
+		val &= ~(1 << ((list_num * 2) + 1));
+	write_reg(vpdma, reg_addr, val);
+}
+EXPORT_SYMBOL(vpdma_enable_list_notify_irq);
+
+/* get the LIST_STAT register */
+unsigned int vpdma_get_list_stat(struct vpdma_data *vpdma, int irq_num)
+{
+	u32 reg_addr = VPDMA_INT_LIST0_STAT + VPDMA_INTX_OFFSET * irq_num;
+
+	return read_reg(vpdma, reg_addr);
+}
+EXPORT_SYMBOL(vpdma_get_list_stat);
+
+/* get the LIST_MASK register */
+unsigned int vpdma_get_list_mask(struct vpdma_data *vpdma, int irq_num)
+{
+	u32 reg_addr = VPDMA_INT_LIST0_MASK + VPDMA_INTX_OFFSET * irq_num;
+
+	return read_reg(vpdma, reg_addr);
+}
+EXPORT_SYMBOL(vpdma_get_list_mask);
+
 /* clear previosuly occured list intterupts in the LIST_STAT register */
-void vpdma_clear_list_stat(struct vpdma_data *vpdma)
+void vpdma_clear_list_stat(struct vpdma_data *vpdma, int irq_num)
 {
-	write_reg(vpdma, VPDMA_INT_LIST0_STAT,
-		read_reg(vpdma, VPDMA_INT_LIST0_STAT));
+	u32 reg_addr = VPDMA_INT_LIST0_STAT + VPDMA_INTX_OFFSET * irq_num;
+
+	write_reg(vpdma, reg_addr,
+		read_reg(vpdma, reg_addr));
 }
 EXPORT_SYMBOL(vpdma_clear_list_stat);
 
diff --git a/drivers/media/platform/ti-vpe/vpdma.h b/drivers/media/platform/ti-vpe/vpdma.h
index 2bd8fb050381..83325d887546 100644
--- a/drivers/media/platform/ti-vpe/vpdma.h
+++ b/drivers/media/platform/ti-vpe/vpdma.h
@@ -134,6 +134,11 @@ enum vpdma_channel {
 	VPE_CHAN_RGB_OUT,
 };
 
+#define VIP_CHAN_VIP2_OFFSET		70
+#define VIP_CHAN_MULT_PORTB_OFFSET	16
+#define VIP_CHAN_YUV_PORTB_OFFSET	2
+#define VIP_CHAN_RGB_PORTB_OFFSET	1
+
 /* flags for VPDMA data descriptors */
 #define VPDMA_DATA_ODD_LINE_SKIP	(1 << 0)
 #define VPDMA_DATA_EVEN_LINE_SKIP	(1 << 1)
@@ -177,8 +182,12 @@ void vpdma_unmap_desc_buf(struct vpdma_data *vpdma, struct vpdma_buf *buf);
 int vpdma_create_desc_list(struct vpdma_desc_list *list, size_t size, int type);
 void vpdma_reset_desc_list(struct vpdma_desc_list *list);
 void vpdma_free_desc_list(struct vpdma_desc_list *list);
-int vpdma_submit_descs(struct vpdma_data *vpdma, struct vpdma_desc_list *list);
-
+int vpdma_submit_descs(struct vpdma_data *vpdma, struct vpdma_desc_list *list,
+		       int list_num);
+bool vpdma_list_busy(struct vpdma_data *vpdma, int list_num);
+void vpdma_update_dma_addr(struct vpdma_data *vpdma,
+	struct vpdma_desc_list *list, dma_addr_t dma_addr,
+	void *write_dtd, int drop, int idx);
 /* helpers for creating vpdma descriptors */
 void vpdma_add_cfd_block(struct vpdma_desc_list *list, int client,
 		struct vpdma_buf *blk, u32 dest_offset);
@@ -190,6 +199,10 @@ void vpdma_add_out_dtd(struct vpdma_desc_list *list, int width,
 		const struct v4l2_rect *c_rect,
 		const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
 		enum vpdma_channel chan, u32 flags);
+void vpdma_rawchan_add_out_dtd(struct vpdma_desc_list *list, int width,
+		const struct v4l2_rect *c_rect,
+		const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
+		int raw_vpdma_chan, u32 flags);
 void vpdma_add_in_dtd(struct vpdma_desc_list *list, int width,
 		const struct v4l2_rect *c_rect,
 		const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
@@ -197,9 +210,11 @@ void vpdma_add_in_dtd(struct vpdma_desc_list *list, int width,
 		int frame_height, int start_h, int start_v);
 
 /* vpdma list interrupt management */
-void vpdma_enable_list_complete_irq(struct vpdma_data *vpdma, int list_num,
-		bool enable);
-void vpdma_clear_list_stat(struct vpdma_data *vpdma);
+void vpdma_enable_list_complete_irq(struct vpdma_data *vpdma, int irq_num,
+		int list_num, bool enable);
+void vpdma_clear_list_stat(struct vpdma_data *vpdma, int irq_num);
+unsigned int vpdma_get_list_stat(struct vpdma_data *vpdma, int irq_num);
+unsigned int vpdma_get_list_mask(struct vpdma_data *vpdma, int irq_num);
 
 /* vpdma client configuration */
 void vpdma_set_line_mode(struct vpdma_data *vpdma, int line_mode,
diff --git a/drivers/media/platform/ti-vpe/vpdma_priv.h b/drivers/media/platform/ti-vpe/vpdma_priv.h
index c1a6ce1884f3..65f0c067bed1 100644
--- a/drivers/media/platform/ti-vpe/vpdma_priv.h
+++ b/drivers/media/platform/ti-vpe/vpdma_priv.h
@@ -39,9 +39,11 @@
 #define VPDMA_INT_LIST0_STAT		0x88
 #define VPDMA_INT_LIST0_MASK		0x8c
 
+#define VPDMA_INTX_OFFSET		0x50
+
 #define VPDMA_PERFMON(i)		(0x200 + i * 4)
 
-/* VPE specific client registers */
+/* VIP/VPE client registers */
 #define VPDMA_DEI_CHROMA1_CSTAT		0x0300
 #define VPDMA_DEI_LUMA1_CSTAT		0x0304
 #define VPDMA_DEI_LUMA2_CSTAT		0x0308
@@ -50,6 +52,8 @@
 #define VPDMA_DEI_CHROMA3_CSTAT		0x0314
 #define VPDMA_DEI_MV_IN_CSTAT		0x0330
 #define VPDMA_DEI_MV_OUT_CSTAT		0x033c
+#define VPDMA_VIP_LO_Y_CSTAT		0x0388
+#define VPDMA_VIP_LO_UV_CSTAT		0x038c
 #define VPDMA_VIP_UP_Y_CSTAT		0x0390
 #define VPDMA_VIP_UP_UV_CSTAT		0x0394
 #define VPDMA_VPI_CTL_CSTAT		0x03d0
@@ -103,7 +107,7 @@
 
 #define DATA_TYPE_MV				0x3
 
-/* VPDMA channel numbers(only VPE channels for now) */
+/* VPDMA channel numbers, some are common between VIP/VPE and appear twice */
 #define	VPE_CHAN_NUM_LUMA1_IN		0
 #define	VPE_CHAN_NUM_CHROMA1_IN		1
 #define	VPE_CHAN_NUM_LUMA2_IN		2
@@ -112,10 +116,15 @@
 #define	VPE_CHAN_NUM_CHROMA3_IN		5
 #define	VPE_CHAN_NUM_MV_IN		12
 #define	VPE_CHAN_NUM_MV_OUT		15
+#define VIP1_CHAN_NUM_MULT_PORT_A_SRC0	38
+#define VIP1_CHAN_NUM_MULT_ANC_A_SRC0	70
 #define	VPE_CHAN_NUM_LUMA_OUT		102
 #define	VPE_CHAN_NUM_CHROMA_OUT		103
+#define VIP1_CHAN_NUM_PORT_A_LUMA	102
+#define VIP1_CHAN_NUM_PORT_A_CHROMA	103
 #define	VPE_CHAN_NUM_RGB_OUT		106
-
+#define VIP1_CHAN_NUM_PORT_A_RGB	106
+#define VIP1_CHAN_NUM_PORT_B_RGB	107
 /*
  * a VPDMA address data block payload for a configuration descriptor needs to
  * have each sub block length as a multiple of 16 bytes. Therefore, the overall
diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c
index 1cf4a4c1b899..bd385c5bae2f 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -1077,7 +1077,7 @@ static void enable_irqs(struct vpe_ctx *ctx)
 	write_reg(ctx->dev, VPE_INT0_ENABLE1_SET, VPE_DEI_ERROR_INT |
 				VPE_DS1_UV_ERROR_INT);
 
-	vpdma_enable_list_complete_irq(ctx->dev->vpdma, 0, true);
+	vpdma_enable_list_complete_irq(ctx->dev->vpdma, 0, 0, true);
 }
 
 static void disable_irqs(struct vpe_ctx *ctx)
@@ -1085,7 +1085,7 @@ static void disable_irqs(struct vpe_ctx *ctx)
 	write_reg(ctx->dev, VPE_INT0_ENABLE0_CLR, 0xffffffff);
 	write_reg(ctx->dev, VPE_INT0_ENABLE1_CLR, 0xffffffff);
 
-	vpdma_enable_list_complete_irq(ctx->dev->vpdma, 0, false);
+	vpdma_enable_list_complete_irq(ctx->dev->vpdma, 0, 0, false);
 }
 
 /* device_run() - prepares and starts the device
@@ -1202,7 +1202,7 @@ static void device_run(void *priv)
 	enable_irqs(ctx);
 
 	vpdma_map_desc_buf(ctx->dev->vpdma, &ctx->desc_list.buf);
-	vpdma_submit_descs(ctx->dev->vpdma, &ctx->desc_list);
+	vpdma_submit_descs(ctx->dev->vpdma, &ctx->desc_list, 0);
 }
 
 static void dei_error(struct vpe_ctx *ctx)
@@ -1257,7 +1257,7 @@ static irqreturn_t vpe_irq(int irq_vpe, void *data)
 
 	if (irqst0) {
 		if (irqst0 & VPE_INT0_LIST0_COMPLETE)
-			vpdma_clear_list_stat(ctx->dev->vpdma);
+			vpdma_clear_list_stat(ctx->dev->vpdma, 0);
 
 		irqst0 &= ~(VPE_INT0_LIST0_COMPLETE);
 	}
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Patch v2 03/35] media: ti-vpe: vpdma: Add helper to set a background color
  2016-11-18 23:20 [Patch v2 00/35] media: ti-vpe: fixes and enhancements Benoit Parrot
  2016-11-18 23:20 ` [Patch v2 01/35] media: ti-vpe: vpdma: Make vpdma library into its own module Benoit Parrot
  2016-11-18 23:20 ` [Patch v2 02/35] media: ti-vpe: vpdma: Add multi-instance and multi-client support Benoit Parrot
@ 2016-11-18 23:20 ` Benoit Parrot
  2016-11-18 23:20 ` [Patch v2 04/35] media: ti-vpe: vpdma: Fix bus error when vpdma is writing a descriptor Benoit Parrot
                   ` (31 subsequent siblings)
  34 siblings, 0 replies; 36+ messages in thread
From: Benoit Parrot @ 2016-11-18 23:20 UTC (permalink / raw)
  To: linux-media, Hans Verkuil
  Cc: linux-kernel, Tomi Valkeinen, Jyri Sarha, Peter Ujfalusi, Benoit Parrot

Add a helper to set the background color during vpdma transfer.
This is needed when VPDMA is generating 32 bits RGB format
to have the Alpha channel set to an appropriate value.

Signed-off-by: Benoit Parrot <bparrot@ti.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/platform/ti-vpe/vpdma.c | 10 ++++++++++
 drivers/media/platform/ti-vpe/vpdma.h |  3 ++-
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/ti-vpe/vpdma.c b/drivers/media/platform/ti-vpe/vpdma.c
index 2b094016b470..133154628543 100644
--- a/drivers/media/platform/ti-vpe/vpdma.c
+++ b/drivers/media/platform/ti-vpe/vpdma.c
@@ -867,6 +867,16 @@ void vpdma_clear_list_stat(struct vpdma_data *vpdma, int irq_num)
 }
 EXPORT_SYMBOL(vpdma_clear_list_stat);
 
+void vpdma_set_bg_color(struct vpdma_data *vpdma,
+		struct vpdma_data_format *fmt, u32 color)
+{
+	if (fmt->type == VPDMA_DATA_FMT_TYPE_RGB)
+		write_reg(vpdma, VPDMA_BG_RGB, color);
+	else if (fmt->type == VPDMA_DATA_FMT_TYPE_YUV)
+		write_reg(vpdma, VPDMA_BG_YUV, color);
+}
+EXPORT_SYMBOL(vpdma_set_bg_color);
+
 /*
  * configures the output mode of the line buffer for the given client, the
  * line buffer content can either be mirrored(each line repeated twice) or
diff --git a/drivers/media/platform/ti-vpe/vpdma.h b/drivers/media/platform/ti-vpe/vpdma.h
index 83325d887546..220dc7e793f6 100644
--- a/drivers/media/platform/ti-vpe/vpdma.h
+++ b/drivers/media/platform/ti-vpe/vpdma.h
@@ -221,7 +221,8 @@ void vpdma_set_line_mode(struct vpdma_data *vpdma, int line_mode,
 		enum vpdma_channel chan);
 void vpdma_set_frame_start_event(struct vpdma_data *vpdma,
 		enum vpdma_frame_start_event fs_event, enum vpdma_channel chan);
-
+void vpdma_set_bg_color(struct vpdma_data *vpdma,
+			struct vpdma_data_format *fmt, u32 color);
 void vpdma_dump_regs(struct vpdma_data *vpdma);
 
 /* initialize vpdma, passed with VPE's platform device pointer */
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Patch v2 04/35] media: ti-vpe: vpdma: Fix bus error when vpdma is writing a descriptor
  2016-11-18 23:20 [Patch v2 00/35] media: ti-vpe: fixes and enhancements Benoit Parrot
                   ` (2 preceding siblings ...)
  2016-11-18 23:20 ` [Patch v2 03/35] media: ti-vpe: vpdma: Add helper to set a background color Benoit Parrot
@ 2016-11-18 23:20 ` Benoit Parrot
  2016-11-18 23:20 ` [Patch v2 05/35] media: ti-vpe: Use line average de-interlacing for first 2 frames Benoit Parrot
                   ` (30 subsequent siblings)
  34 siblings, 0 replies; 36+ messages in thread
From: Benoit Parrot @ 2016-11-18 23:20 UTC (permalink / raw)
  To: linux-media, Hans Verkuil
  Cc: linux-kernel, Tomi Valkeinen, Jyri Sarha, Peter Ujfalusi, Benoit Parrot

On DRA7 since l3_noc event are being reported it was found that
when the write descriptor was being written it was consistently
causing bus error events.

The write address was improperly programmed.

Signed-off-by: Benoit Parrot <bparrot@ti.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/platform/ti-vpe/vpdma_priv.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/ti-vpe/vpdma_priv.h b/drivers/media/platform/ti-vpe/vpdma_priv.h
index 65f0c067bed1..aeade5edc8ac 100644
--- a/drivers/media/platform/ti-vpe/vpdma_priv.h
+++ b/drivers/media/platform/ti-vpe/vpdma_priv.h
@@ -212,6 +212,7 @@ struct vpdma_dtd {
 #define DTD_V_START_MASK	0xffff
 #define DTD_V_START_SHFT	0
 
+#define DTD_DESC_START_MASK	0xffffffe0
 #define DTD_DESC_START_SHIFT	5
 #define DTD_WRITE_DESC_MASK	0x01
 #define DTD_WRITE_DESC_SHIFT	2
@@ -294,7 +295,7 @@ static inline u32 dtd_frame_width_height(int width, int height)
 static inline u32 dtd_desc_write_addr(unsigned int addr, bool write_desc,
 			bool drop_data, bool use_desc)
 {
-	return (addr << DTD_DESC_START_SHIFT) |
+	return (addr & DTD_DESC_START_MASK) |
 		(write_desc << DTD_WRITE_DESC_SHIFT) |
 		(drop_data << DTD_DROP_DATA_SHIFT) |
 		use_desc;
@@ -399,7 +400,7 @@ static inline int dtd_get_frame_height(struct vpdma_dtd *dtd)
 
 static inline int dtd_get_desc_write_addr(struct vpdma_dtd *dtd)
 {
-	return dtd->desc_write_addr >> DTD_DESC_START_SHIFT;
+	return dtd->desc_write_addr & DTD_DESC_START_MASK;
 }
 
 static inline bool dtd_get_write_desc(struct vpdma_dtd *dtd)
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Patch v2 05/35] media: ti-vpe: Use line average de-interlacing for first 2 frames
  2016-11-18 23:20 [Patch v2 00/35] media: ti-vpe: fixes and enhancements Benoit Parrot
                   ` (3 preceding siblings ...)
  2016-11-18 23:20 ` [Patch v2 04/35] media: ti-vpe: vpdma: Fix bus error when vpdma is writing a descriptor Benoit Parrot
@ 2016-11-18 23:20 ` Benoit Parrot
  2016-11-18 23:20 ` [Patch v2 06/35] media: ti-vpe: vpe: Do not perform job transaction atomically Benoit Parrot
                   ` (29 subsequent siblings)
  34 siblings, 0 replies; 36+ messages in thread
From: Benoit Parrot @ 2016-11-18 23:20 UTC (permalink / raw)
  To: linux-media, Hans Verkuil
  Cc: linux-kernel, Tomi Valkeinen, Jyri Sarha, Peter Ujfalusi, Benoit Parrot

From: Archit Taneja <archit@ti.com>

The motion detection block requires 3 fields to create the motion vector
data. This means that using the default method the first progressive
frame is only generated after 3rd field is consumed.
Hence by default for N input field we would generate N - 2 progressive
frames.

In order to generate N progressive frames from N fields we use the
line averaging mode of the de-interlacer for the first 2 fields and then
revert back to the preferred Edge Directed Interpolation method (using
the motion vector).
Thus creating 2 line averaged frames + N - 2 motion based frames for a
total of N frames.

Signed-off-by: Archit Taneja <archit@ti.com>
Signed-off-by: Nikhil Devshatwar <nikhil.nd@ti.com>
Signed-off-by: Benoit Parrot <bparrot@ti.com>
---
 drivers/media/platform/ti-vpe/vpe.c | 33 +++++++++++++++++++++++++++++++--
 1 file changed, 31 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c
index bd385c5bae2f..ad838b8a98c4 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -141,7 +141,7 @@ struct vpe_dei_regs {
  */
 static const struct vpe_dei_regs dei_regs = {
 	.mdt_spacial_freq_thr_reg = 0x020C0804u,
-	.edi_config_reg = 0x0118100Fu,
+	.edi_config_reg = 0x0118100Cu,
 	.edi_lut_reg0 = 0x08040200u,
 	.edi_lut_reg1 = 0x1010100Cu,
 	.edi_lut_reg2 = 0x10101010u,
@@ -798,6 +798,23 @@ static void set_dei_shadow_registers(struct vpe_ctx *ctx)
 	ctx->load_mmrs = true;
 }
 
+static void config_edi_input_mode(struct vpe_ctx *ctx, int mode)
+{
+	struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr;
+	u32 *edi_config_reg = &mmr_adb->dei_regs[3];
+
+	if (mode & 0x2)
+		write_field(edi_config_reg, 1, 1, 2);	/* EDI_ENABLE_3D */
+
+	if (mode & 0x3)
+		write_field(edi_config_reg, 1, 1, 3);	/* EDI_CHROMA_3D  */
+
+	write_field(edi_config_reg, mode, VPE_EDI_INP_MODE_MASK,
+		VPE_EDI_INP_MODE_SHIFT);
+
+	ctx->load_mmrs = true;
+}
+
 /*
  * Set the shadow registers whose values are modified when either the
  * source or destination format is changed.
@@ -1111,6 +1128,15 @@ static void device_run(void *priv)
 	ctx->dst_vb = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
 	WARN_ON(ctx->dst_vb == NULL);
 
+	if (ctx->deinterlacing) {
+		/*
+		 * we have output the first 2 frames through line average, we
+		 * now switch to EDI de-interlacer
+		 */
+		if (ctx->sequence == 2)
+			config_edi_input_mode(ctx, 0x3); /* EDI (Y + UV) */
+	}
+
 	/* config descriptors */
 	if (ctx->dev->loaded_mmrs != ctx->mmr_adb.dma_addr || ctx->load_mmrs) {
 		vpdma_map_desc_buf(ctx->dev->vpdma, &ctx->mmr_adb);
@@ -1864,7 +1890,10 @@ static void vpe_buf_queue(struct vb2_buffer *vb)
 
 static int vpe_start_streaming(struct vb2_queue *q, unsigned int count)
 {
-	/* currently we do nothing here */
+	struct vpe_ctx *ctx = vb2_get_drv_priv(q);
+
+	if (ctx->deinterlacing)
+		config_edi_input_mode(ctx, 0x0);
 
 	return 0;
 }
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Patch v2 06/35] media: ti-vpe: vpe: Do not perform job transaction atomically
  2016-11-18 23:20 [Patch v2 00/35] media: ti-vpe: fixes and enhancements Benoit Parrot
                   ` (4 preceding siblings ...)
  2016-11-18 23:20 ` [Patch v2 05/35] media: ti-vpe: Use line average de-interlacing for first 2 frames Benoit Parrot
@ 2016-11-18 23:20 ` Benoit Parrot
  2016-11-18 23:20 ` [Patch v2 07/35] media: ti-vpe: Add support for SEQ_TB buffers Benoit Parrot
                   ` (28 subsequent siblings)
  34 siblings, 0 replies; 36+ messages in thread
From: Benoit Parrot @ 2016-11-18 23:20 UTC (permalink / raw)
  To: linux-media, Hans Verkuil
  Cc: linux-kernel, Tomi Valkeinen, Jyri Sarha, Peter Ujfalusi, Benoit Parrot

From: Nikhil Devshatwar <nikhil.nd@ti.com>

Current VPE driver does not start the job until all the buffers for
a transaction are queued. When running in multiple context, this might
increase the processing latency.

Alternate solution would be to try to continue the same context as long as
buffers for the transaction are ready; else switch the context. This may
increase number of context switches but it reduces latency significantly.

In this approach, the job_ready always succeeds as long as there are
buffers on the CAPTURE and OUTPUT stream. Processing may start immediately
as the first 2 iterations don't need extra source buffers. Shift all the
source buffers after each iteration and remove the oldest buffer.

Also, with this removes the constraint of pre buffering 3 buffers before
call to STREAMON in case of de-interlacing.

Signed-off-by: Nikhil Devshatwar <nikhil.nd@ti.com>
Signed-off-by: Benoit Parrot <bparrot@ti.com>
---
 drivers/media/platform/ti-vpe/vpe.c | 32 ++++++++++++++++----------------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c
index ad838b8a98c4..9b7b9be5641d 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -898,15 +898,14 @@ static struct vpe_ctx *file2ctx(struct file *file)
 static int job_ready(void *priv)
 {
 	struct vpe_ctx *ctx = priv;
-	int needed = ctx->bufs_per_job;
 
-	if (ctx->deinterlacing && ctx->src_vbs[2] == NULL)
-		needed += 2;	/* need additional two most recent fields */
-
-	if (v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx) < needed)
-		return 0;
-
-	if (v4l2_m2m_num_dst_bufs_ready(ctx->fh.m2m_ctx) < needed)
+	/*
+	 * This check is needed as this might be called directly from driver
+	 * When called by m2m framework, this will always satisfy, but when
+	 * called from vpe_irq, this might fail. (src stream with zero buffers)
+	 */
+	if (v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx) <= 0 ||
+		v4l2_m2m_num_dst_bufs_ready(ctx->fh.m2m_ctx) <= 0)
 		return 0;
 
 	return 1;
@@ -1116,19 +1115,20 @@ static void device_run(void *priv)
 	struct sc_data *sc = ctx->dev->sc;
 	struct vpe_q_data *d_q_data = &ctx->q_data[Q_DATA_DST];
 
-	if (ctx->deinterlacing && ctx->src_vbs[2] == NULL) {
-		ctx->src_vbs[2] = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
-		WARN_ON(ctx->src_vbs[2] == NULL);
-		ctx->src_vbs[1] = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
-		WARN_ON(ctx->src_vbs[1] == NULL);
-	}
-
 	ctx->src_vbs[0] = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
 	WARN_ON(ctx->src_vbs[0] == NULL);
 	ctx->dst_vb = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
 	WARN_ON(ctx->dst_vb == NULL);
 
 	if (ctx->deinterlacing) {
+
+		if (ctx->src_vbs[2] == NULL) {
+			ctx->src_vbs[2] = ctx->src_vbs[0];
+			WARN_ON(ctx->src_vbs[2] == NULL);
+			ctx->src_vbs[1] = ctx->src_vbs[0];
+			WARN_ON(ctx->src_vbs[1] == NULL);
+		}
+
 		/*
 		 * we have output the first 2 frames through line average, we
 		 * now switch to EDI de-interlacer
@@ -1348,7 +1348,7 @@ static irqreturn_t vpe_irq(int irq_vpe, void *data)
 	}
 
 	ctx->bufs_completed++;
-	if (ctx->bufs_completed < ctx->bufs_per_job) {
+	if (ctx->bufs_completed < ctx->bufs_per_job && job_ready(ctx)) {
 		device_run(ctx);
 		goto handled;
 	}
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Patch v2 07/35] media: ti-vpe: Add support for SEQ_TB buffers
  2016-11-18 23:20 [Patch v2 00/35] media: ti-vpe: fixes and enhancements Benoit Parrot
                   ` (5 preceding siblings ...)
  2016-11-18 23:20 ` [Patch v2 06/35] media: ti-vpe: vpe: Do not perform job transaction atomically Benoit Parrot
@ 2016-11-18 23:20 ` Benoit Parrot
  2016-11-18 23:20 ` [Patch v2 08/35] media: ti-vpe: Increasing max buffer height and width Benoit Parrot
                   ` (27 subsequent siblings)
  34 siblings, 0 replies; 36+ messages in thread
From: Benoit Parrot @ 2016-11-18 23:20 UTC (permalink / raw)
  To: linux-media, Hans Verkuil
  Cc: linux-kernel, Tomi Valkeinen, Jyri Sarha, Peter Ujfalusi, Benoit Parrot

From: Nikhil Devshatwar <nikhil.nd@ti.com>

The video source can generate the data in the SEQ_TB buffer format.
In the case of TI SoC, the IVA_HD can generate the interlaced content in
the SEQ_TB buffer format. This is the format where the top and bottom field
data can be contained in a single buffer. For example, for NV12, interlaced
format, the data in Y buffer will be arranged as Y-top followed by
Y-bottom. And likewise for UV plane.

Also, queuing one buffer of SEQ_TB is equivalent to queuing two different
buffers for top and bottom fields. Driver needs to take care of this when
handling source buffer lists.

Signed-off-by: Nikhil Devshatwar <nikhil.nd@ti.com>
Signed-off-by: Benoit Parrot <bparrot@ti.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/platform/ti-vpe/vpe.c | 125 +++++++++++++++++++++++++++++-------
 1 file changed, 103 insertions(+), 22 deletions(-)

diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c
index 9b7b9be5641d..e5d55575350f 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -320,9 +320,13 @@ struct vpe_q_data {
 };
 
 /* vpe_q_data flag bits */
-#define	Q_DATA_FRAME_1D		(1 << 0)
-#define	Q_DATA_MODE_TILED	(1 << 1)
-#define	Q_DATA_INTERLACED	(1 << 2)
+#define	Q_DATA_FRAME_1D			BIT(0)
+#define	Q_DATA_MODE_TILED		BIT(1)
+#define	Q_DATA_INTERLACED_ALTERNATE	BIT(2)
+#define	Q_DATA_INTERLACED_SEQ_TB	BIT(3)
+
+#define Q_IS_INTERLACED		(Q_DATA_INTERLACED_ALTERNATE | \
+				Q_DATA_INTERLACED_SEQ_TB)
 
 enum {
 	Q_DATA_SRC = 0,
@@ -638,7 +642,7 @@ static void set_us_coefficients(struct vpe_ctx *ctx)
 
 	cp = &us_coeffs[0].anchor_fid0_c0;
 
-	if (s_q_data->flags & Q_DATA_INTERLACED)	/* interlaced */
+	if (s_q_data->flags & Q_IS_INTERLACED)		/* interlaced */
 		cp += sizeof(us_coeffs[0]) / sizeof(*cp);
 
 	end_cp = cp + sizeof(us_coeffs[0]) / sizeof(*cp);
@@ -765,8 +769,7 @@ static void set_dei_regs(struct vpe_ctx *ctx)
 	 * for both progressive and interlace content in interlace bypass mode.
 	 * It has been recommended not to use progressive bypass mode.
 	 */
-	if ((!ctx->deinterlacing && (s_q_data->flags & Q_DATA_INTERLACED)) ||
-			!(s_q_data->flags & Q_DATA_INTERLACED)) {
+	if (!(s_q_data->flags & Q_IS_INTERLACED) || !ctx->deinterlacing) {
 		deinterlace = false;
 		val = VPE_DEI_INTERLACE_BYPASS;
 	}
@@ -834,8 +837,8 @@ static int set_srcdst_params(struct vpe_ctx *ctx)
 	ctx->sequence = 0;
 	ctx->field = V4L2_FIELD_TOP;
 
-	if ((s_q_data->flags & Q_DATA_INTERLACED) &&
-			!(d_q_data->flags & Q_DATA_INTERLACED)) {
+	if ((s_q_data->flags & Q_IS_INTERLACED) &&
+			!(d_q_data->flags & Q_IS_INTERLACED)) {
 		int bytes_per_line;
 		const struct vpdma_data_format *mv =
 			&vpdma_misc_fmts[VPDMA_DATA_FMT_MV];
@@ -1066,6 +1069,28 @@ static void add_in_dtd(struct vpe_ctx *ctx, int port)
 				port);
 			return;
 		}
+
+		if (q_data->flags & Q_DATA_INTERLACED_SEQ_TB) {
+			/*
+			 * Use top or bottom field from same vb alternately
+			 * f,f-1,f-2 = TBT when seq is even
+			 * f,f-1,f-2 = BTB when seq is odd
+			 */
+			field = (p_data->vb_index + (ctx->sequence % 2)) % 2;
+
+			if (field) {
+				/*
+				 * bottom field of a SEQ_TB buffer
+				 * Skip the top field data by
+				 */
+				int height = q_data->height / 2;
+				int bpp = fmt->fourcc == V4L2_PIX_FMT_NV12 ?
+						1 : (vpdma_fmt->depth >> 3);
+				if (plane)
+					height /= 2;
+				dma_addr += q_data->width * height * bpp;
+			}
+		}
 	}
 
 	if (q_data->flags & Q_DATA_FRAME_1D)
@@ -1114,9 +1139,22 @@ static void device_run(void *priv)
 	struct vpe_ctx *ctx = priv;
 	struct sc_data *sc = ctx->dev->sc;
 	struct vpe_q_data *d_q_data = &ctx->q_data[Q_DATA_DST];
+	struct vpe_q_data *s_q_data = &ctx->q_data[Q_DATA_SRC];
+
+	if (ctx->deinterlacing && s_q_data->flags & Q_DATA_INTERLACED_SEQ_TB &&
+		ctx->sequence % 2 == 0) {
+		/* When using SEQ_TB buffers, When using it first time,
+		 * No need to remove the buffer as the next field is present
+		 * in the same buffer. (so that job_ready won't fail)
+		 * It will be removed when using bottom field
+		 */
+		ctx->src_vbs[0] = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
+		WARN_ON(ctx->src_vbs[0] == NULL);
+	} else {
+		ctx->src_vbs[0] = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
+		WARN_ON(ctx->src_vbs[0] == NULL);
+	}
 
-	ctx->src_vbs[0] = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
-	WARN_ON(ctx->src_vbs[0] == NULL);
 	ctx->dst_vb = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
 	WARN_ON(ctx->dst_vb == NULL);
 
@@ -1320,7 +1358,7 @@ static irqreturn_t vpe_irq(int irq_vpe, void *data)
 	d_vb->sequence = ctx->sequence;
 
 	d_q_data = &ctx->q_data[Q_DATA_DST];
-	if (d_q_data->flags & Q_DATA_INTERLACED) {
+	if (d_q_data->flags & Q_IS_INTERLACED) {
 		d_vb->field = ctx->field;
 		if (ctx->field == V4L2_FIELD_BOTTOM) {
 			ctx->sequence++;
@@ -1334,12 +1372,28 @@ static irqreturn_t vpe_irq(int irq_vpe, void *data)
 		ctx->sequence++;
 	}
 
-	if (ctx->deinterlacing)
-		s_vb = ctx->src_vbs[2];
+	if (ctx->deinterlacing) {
+		/*
+		 * Allow source buffer to be dequeued only if it won't be used
+		 * in the next iteration. All vbs are initialized to first
+		 * buffer and we are shifting buffers every iteration, for the
+		 * first two iterations, no buffer will be dequeued.
+		 * This ensures that driver will keep (n-2)th (n-1)th and (n)th
+		 * field when deinterlacing is enabled
+		 */
+		if (ctx->src_vbs[2] != ctx->src_vbs[1])
+			s_vb = ctx->src_vbs[2];
+		else
+			s_vb = NULL;
+	}
 
 	spin_lock_irqsave(&dev->lock, flags);
-	v4l2_m2m_buf_done(s_vb, VB2_BUF_STATE_DONE);
+
+	if (s_vb)
+		v4l2_m2m_buf_done(s_vb, VB2_BUF_STATE_DONE);
+
 	v4l2_m2m_buf_done(d_vb, VB2_BUF_STATE_DONE);
+
 	spin_unlock_irqrestore(&dev->lock, flags);
 
 	if (ctx->deinterlacing) {
@@ -1455,7 +1509,7 @@ static int __vpe_try_fmt(struct vpe_ctx *ctx, struct v4l2_format *f,
 	struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
 	struct v4l2_plane_pix_format *plane_fmt;
 	unsigned int w_align;
-	int i, depth, depth_bytes;
+	int i, depth, depth_bytes, height;
 
 	if (!fmt || !(fmt->types & type)) {
 		vpe_err(ctx->dev, "Fourcc format (0x%08x) invalid.\n",
@@ -1463,7 +1517,8 @@ static int __vpe_try_fmt(struct vpe_ctx *ctx, struct v4l2_format *f,
 		return -EINVAL;
 	}
 
-	if (pix->field != V4L2_FIELD_NONE && pix->field != V4L2_FIELD_ALTERNATE)
+	if (pix->field != V4L2_FIELD_NONE && pix->field != V4L2_FIELD_ALTERNATE
+			&& pix->field != V4L2_FIELD_SEQ_TB)
 		pix->field = V4L2_FIELD_NONE;
 
 	depth = fmt->vpdma_fmt[VPE_LUMA]->depth;
@@ -1497,6 +1552,15 @@ static int __vpe_try_fmt(struct vpe_ctx *ctx, struct v4l2_format *f,
 	pix->num_planes = fmt->coplanar ? 2 : 1;
 	pix->pixelformat = fmt->fourcc;
 
+	/*
+	 * For the actual image parameters, we need to consider the field
+	 * height of the image for SEQ_TB buffers.
+	 */
+	if (pix->field == V4L2_FIELD_SEQ_TB)
+		height = pix->height / 2;
+	else
+		height = pix->height;
+
 	if (!pix->colorspace) {
 		if (fmt->fourcc == V4L2_PIX_FMT_RGB24 ||
 				fmt->fourcc == V4L2_PIX_FMT_BGR24 ||
@@ -1504,7 +1568,7 @@ static int __vpe_try_fmt(struct vpe_ctx *ctx, struct v4l2_format *f,
 				fmt->fourcc == V4L2_PIX_FMT_BGR32) {
 			pix->colorspace = V4L2_COLORSPACE_SRGB;
 		} else {
-			if (pix->height > 1280)	/* HD */
+			if (height > 1280)	/* HD */
 				pix->colorspace = V4L2_COLORSPACE_REC709;
 			else			/* SD */
 				pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
@@ -1581,9 +1645,15 @@ static int __vpe_s_fmt(struct vpe_ctx *ctx, struct v4l2_format *f)
 	q_data->c_rect.height	= q_data->height;
 
 	if (q_data->field == V4L2_FIELD_ALTERNATE)
-		q_data->flags |= Q_DATA_INTERLACED;
+		q_data->flags |= Q_DATA_INTERLACED_ALTERNATE;
+	else if (q_data->field == V4L2_FIELD_SEQ_TB)
+		q_data->flags |= Q_DATA_INTERLACED_SEQ_TB;
 	else
-		q_data->flags &= ~Q_DATA_INTERLACED;
+		q_data->flags &= ~Q_IS_INTERLACED;
+
+	/* the crop height is halved for the case of SEQ_TB buffers */
+	if (q_data->flags & Q_DATA_INTERLACED_SEQ_TB)
+		q_data->c_rect.height /= 2;
 
 	vpe_dbg(ctx->dev, "Setting format for type %d, wxh: %dx%d, fmt: %d bpl_y %d",
 		f->type, q_data->width, q_data->height, q_data->fmt->fourcc,
@@ -1619,6 +1689,7 @@ static int vpe_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
 static int __vpe_try_selection(struct vpe_ctx *ctx, struct v4l2_selection *s)
 {
 	struct vpe_q_data *q_data;
+	int height;
 
 	if ((s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
 	    (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT))
@@ -1653,13 +1724,22 @@ static int __vpe_try_selection(struct vpe_ctx *ctx, struct v4l2_selection *s)
 		return -EINVAL;
 	}
 
+	/*
+	 * For SEQ_TB buffers, crop height should be less than the height of
+	 * the field height, not the buffer height
+	 */
+	if (q_data->flags & Q_DATA_INTERLACED_SEQ_TB)
+		height = q_data->height / 2;
+	else
+		height = q_data->height;
+
 	if (s->r.top < 0 || s->r.left < 0) {
 		vpe_err(ctx->dev, "negative values for top and left\n");
 		s->r.top = s->r.left = 0;
 	}
 
 	v4l_bound_align_image(&s->r.width, MIN_W, q_data->width, 1,
-		&s->r.height, MIN_H, q_data->height, H_ALIGN, S_ALIGN);
+		&s->r.height, MIN_H, height, H_ALIGN, S_ALIGN);
 
 	/* adjust left/top if cropping rectangle is out of bounds */
 	if (s->r.left + s->r.width > q_data->width)
@@ -1855,11 +1935,12 @@ static int vpe_buf_prepare(struct vb2_buffer *vb)
 	num_planes = q_data->fmt->coplanar ? 2 : 1;
 
 	if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
-		if (!(q_data->flags & Q_DATA_INTERLACED)) {
+		if (!(q_data->flags & Q_IS_INTERLACED)) {
 			vbuf->field = V4L2_FIELD_NONE;
 		} else {
 			if (vbuf->field != V4L2_FIELD_TOP &&
-					vbuf->field != V4L2_FIELD_BOTTOM)
+			    vbuf->field != V4L2_FIELD_BOTTOM &&
+			    vbuf->field != V4L2_FIELD_SEQ_TB)
 				return -EINVAL;
 		}
 	}
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Patch v2 08/35] media: ti-vpe: Increasing max buffer height and width
  2016-11-18 23:20 [Patch v2 00/35] media: ti-vpe: fixes and enhancements Benoit Parrot
                   ` (6 preceding siblings ...)
  2016-11-18 23:20 ` [Patch v2 07/35] media: ti-vpe: Add support for SEQ_TB buffers Benoit Parrot
@ 2016-11-18 23:20 ` Benoit Parrot
  2016-11-18 23:20 ` [Patch v2 09/35] media: ti-vpe: vpe: Return NULL for invalid buffer type Benoit Parrot
                   ` (26 subsequent siblings)
  34 siblings, 0 replies; 36+ messages in thread
From: Benoit Parrot @ 2016-11-18 23:20 UTC (permalink / raw)
  To: linux-media, Hans Verkuil
  Cc: linux-kernel, Tomi Valkeinen, Jyri Sarha, Peter Ujfalusi, Benoit Parrot

From: Harinarayan Bhatta <harinarayan@ti.com>

Increasing max buffer height and width to allow for padded buffers.

Signed-off-by: Harinarayan Bhatta <harinarayan@ti.com>
Signed-off-by: Nikhil Devshatwar <nikhil.nd@ti.com>
Signed-off-by: Benoit Parrot <bparrot@ti.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/platform/ti-vpe/vpe.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c
index e5d55575350f..c624f5db7f08 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -53,8 +53,8 @@
 /* minimum and maximum frame sizes */
 #define MIN_W		32
 #define MIN_H		32
-#define MAX_W		1920
-#define MAX_H		1080
+#define MAX_W		2048
+#define MAX_H		1184
 
 /* required alignments */
 #define S_ALIGN		0	/* multiple of 1 */
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Patch v2 09/35] media: ti-vpe: vpe: Return NULL for invalid buffer type
  2016-11-18 23:20 [Patch v2 00/35] media: ti-vpe: fixes and enhancements Benoit Parrot
                   ` (7 preceding siblings ...)
  2016-11-18 23:20 ` [Patch v2 08/35] media: ti-vpe: Increasing max buffer height and width Benoit Parrot
@ 2016-11-18 23:20 ` Benoit Parrot
  2016-11-18 23:20 ` [Patch v2 10/35] media: ti-vpe: Free vpdma buffers in vpe_release Benoit Parrot
                   ` (25 subsequent siblings)
  34 siblings, 0 replies; 36+ messages in thread
From: Benoit Parrot @ 2016-11-18 23:20 UTC (permalink / raw)
  To: linux-media, Hans Verkuil
  Cc: linux-kernel, Tomi Valkeinen, Jyri Sarha, Peter Ujfalusi, Benoit Parrot

From: Nikhil Devshatwar <nikhil.nd@ti.com>

get_q_data can be called with different values for type
e.g. vpe_try_crop calls it with the buffer type which gets passed
from user space

Framework doesn't check wheather its correct type or not
If user space passes wrong type, kernel should not crash.
Return NULL when the passed type is invalid.

Signed-off-by: Nikhil Devshatwar <nikhil.nd@ti.com>
Signed-off-by: Benoit Parrot <bparrot@ti.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/platform/ti-vpe/vpe.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c
index c624f5db7f08..4b6e8839dd83 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -420,7 +420,7 @@ static struct vpe_q_data *get_q_data(struct vpe_ctx *ctx,
 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
 		return &ctx->q_data[Q_DATA_DST];
 	default:
-		BUG();
+		return NULL;
 	}
 	return NULL;
 }
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Patch v2 10/35] media: ti-vpe: Free vpdma buffers in vpe_release
  2016-11-18 23:20 [Patch v2 00/35] media: ti-vpe: fixes and enhancements Benoit Parrot
                   ` (8 preceding siblings ...)
  2016-11-18 23:20 ` [Patch v2 09/35] media: ti-vpe: vpe: Return NULL for invalid buffer type Benoit Parrot
@ 2016-11-18 23:20 ` Benoit Parrot
  2016-11-18 23:20 ` [Patch v2 11/35] media: ti-vpe: vpdma: Add support for setting max width height Benoit Parrot
                   ` (24 subsequent siblings)
  34 siblings, 0 replies; 36+ messages in thread
From: Benoit Parrot @ 2016-11-18 23:20 UTC (permalink / raw)
  To: linux-media, Hans Verkuil
  Cc: linux-kernel, Tomi Valkeinen, Jyri Sarha, Peter Ujfalusi, Benoit Parrot

From: Harinarayan Bhatta <harinarayan@ti.com>

Free vpdma buffers in vpe_release. Otherwise it was generating random
backtrace.

Signed-off-by: Harinarayan Bhatta <harinarayan@ti.com>
Signed-off-by: Somnath Mukherjee <somnath@ti.com>
Signed-off-by: Nikhil Devshatwar <nikhil.nd@ti.com>
Signed-off-by: Benoit Parrot <bparrot@ti.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/platform/ti-vpe/vpe.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c
index 4b6e8839dd83..f2b90d42b408 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -2182,6 +2182,9 @@ static int vpe_release(struct file *file)
 	vpdma_free_desc_list(&ctx->desc_list);
 	vpdma_free_desc_buf(&ctx->mmr_adb);
 
+	vpdma_free_desc_buf(&ctx->sc_coeff_v);
+	vpdma_free_desc_buf(&ctx->sc_coeff_h);
+
 	v4l2_fh_del(&ctx->fh);
 	v4l2_fh_exit(&ctx->fh);
 	v4l2_ctrl_handler_free(&ctx->hdl);
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Patch v2 11/35] media: ti-vpe: vpdma: Add support for setting max width height
  2016-11-18 23:20 [Patch v2 00/35] media: ti-vpe: fixes and enhancements Benoit Parrot
                   ` (9 preceding siblings ...)
  2016-11-18 23:20 ` [Patch v2 10/35] media: ti-vpe: Free vpdma buffers in vpe_release Benoit Parrot
@ 2016-11-18 23:20 ` Benoit Parrot
  2016-11-18 23:20 ` [Patch v2 12/35] media: ti-vpe: vpdma: Add abort channel desc and cleanup APIs Benoit Parrot
                   ` (23 subsequent siblings)
  34 siblings, 0 replies; 36+ messages in thread
From: Benoit Parrot @ 2016-11-18 23:20 UTC (permalink / raw)
  To: linux-media, Hans Verkuil
  Cc: linux-kernel, Tomi Valkeinen, Jyri Sarha, Peter Ujfalusi, Benoit Parrot

From: Nikhil Devshatwar <nikhil.nd@ti.com>

Add a helper function to be able to set the maximum
VPDMA transfer size to limit potential buffer overrun.

Added enums for max_width and max_height fields of the
outbound data descriptor.

Changed vpdma_add_out_dtd to accept two more arguments
for max width and height.

Make use of different max width & height sets for different
of capture module (i.e. slices).

Signed-off-by: Nikhil Devshatwar <nikhil.nd@ti.com>
Signed-off-by: Benoit Parrot <bparrot@ti.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/platform/ti-vpe/vpdma.c      | 27 ++++++++++++++++----
 drivers/media/platform/ti-vpe/vpdma.h      | 32 ++++++++++++++++++++++--
 drivers/media/platform/ti-vpe/vpdma_priv.h | 40 +++---------------------------
 drivers/media/platform/ti-vpe/vpe.c        |  7 +++++-
 4 files changed, 62 insertions(+), 44 deletions(-)

diff --git a/drivers/media/platform/ti-vpe/vpdma.c b/drivers/media/platform/ti-vpe/vpdma.c
index 133154628543..1a0152842a17 100644
--- a/drivers/media/platform/ti-vpe/vpdma.c
+++ b/drivers/media/platform/ti-vpe/vpdma.c
@@ -493,6 +493,22 @@ void vpdma_update_dma_addr(struct vpdma_data *vpdma,
 }
 EXPORT_SYMBOL(vpdma_update_dma_addr);
 
+void vpdma_set_max_size(struct vpdma_data *vpdma, int reg_addr,
+			u32 width, u32 height)
+{
+	if (reg_addr != VPDMA_MAX_SIZE1 && reg_addr != VPDMA_MAX_SIZE2 &&
+	    reg_addr != VPDMA_MAX_SIZE3)
+		reg_addr = VPDMA_MAX_SIZE1;
+
+	write_field_reg(vpdma, reg_addr, width - 1,
+			VPDMA_MAX_SIZE_WIDTH_MASK, VPDMA_MAX_SIZE_WIDTH_SHFT);
+
+	write_field_reg(vpdma, reg_addr, height - 1,
+			VPDMA_MAX_SIZE_HEIGHT_MASK, VPDMA_MAX_SIZE_HEIGHT_SHFT);
+
+}
+EXPORT_SYMBOL(vpdma_set_max_size);
+
 static void dump_cfd(struct vpdma_cfd *cfd)
 {
 	int class;
@@ -667,23 +683,25 @@ static void dump_dtd(struct vpdma_dtd *dtd)
  * @c_rect: compose params of output image
  * @fmt: vpdma data format of the buffer
  * dma_addr: dma address as seen by VPDMA
+ * max_width: enum for maximum width of data transfer
+ * max_height: enum for maximum height of data transfer
  * chan: VPDMA channel
  * flags: VPDMA flags to configure some descriptor fileds
  */
 void vpdma_add_out_dtd(struct vpdma_desc_list *list, int width,
 		const struct v4l2_rect *c_rect,
 		const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
-		enum vpdma_channel chan, u32 flags)
+		int max_w, int max_h, enum vpdma_channel chan, u32 flags)
 {
 	vpdma_rawchan_add_out_dtd(list, width, c_rect, fmt, dma_addr,
-				  chan_info[chan].num, flags);
+				  max_w, max_h, chan_info[chan].num, flags);
 }
 EXPORT_SYMBOL(vpdma_add_out_dtd);
 
 void vpdma_rawchan_add_out_dtd(struct vpdma_desc_list *list, int width,
 		const struct v4l2_rect *c_rect,
 		const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
-		int raw_vpdma_chan, u32 flags)
+		int max_w, int max_h, int raw_vpdma_chan, u32 flags)
 {
 	int priority = 0;
 	int field = 0;
@@ -722,8 +740,7 @@ void vpdma_rawchan_add_out_dtd(struct vpdma_desc_list *list, int width,
 	dtd->pkt_ctl = dtd_pkt_ctl(!!(flags & VPDMA_DATA_MODE_TILED),
 				DTD_DIR_OUT, channel, priority, next_chan);
 	dtd->desc_write_addr = dtd_desc_write_addr(0, 0, 0, 0);
-	dtd->max_width_height = dtd_max_width_height(MAX_OUT_WIDTH_1920,
-					MAX_OUT_HEIGHT_1080);
+	dtd->max_width_height = dtd_max_width_height(max_w, max_h);
 	dtd->client_attr0 = 0;
 	dtd->client_attr1 = 0;
 
diff --git a/drivers/media/platform/ti-vpe/vpdma.h b/drivers/media/platform/ti-vpe/vpdma.h
index 220dc7e793f6..32b9ed5191c5 100644
--- a/drivers/media/platform/ti-vpe/vpdma.h
+++ b/drivers/media/platform/ti-vpe/vpdma.h
@@ -117,6 +117,30 @@ enum vpdma_frame_start_event {
 	VPDMA_FSEVENT_CHANNEL_ACTIVE,
 };
 
+/* max width configurations */
+enum vpdma_max_width {
+	MAX_OUT_WIDTH_UNLIMITED = 0,
+	MAX_OUT_WIDTH_REG1,
+	MAX_OUT_WIDTH_REG2,
+	MAX_OUT_WIDTH_REG3,
+	MAX_OUT_WIDTH_352,
+	MAX_OUT_WIDTH_768,
+	MAX_OUT_WIDTH_1280,
+	MAX_OUT_WIDTH_1920,
+};
+
+/* max height configurations */
+enum vpdma_max_height {
+	MAX_OUT_HEIGHT_UNLIMITED = 0,
+	MAX_OUT_HEIGHT_REG1,
+	MAX_OUT_HEIGHT_REG2,
+	MAX_OUT_HEIGHT_REG3,
+	MAX_OUT_HEIGHT_288,
+	MAX_OUT_HEIGHT_576,
+	MAX_OUT_HEIGHT_720,
+	MAX_OUT_HEIGHT_1080,
+};
+
 /*
  * VPDMA channel numbers
  */
@@ -198,11 +222,12 @@ void vpdma_add_sync_on_channel_ctd(struct vpdma_desc_list *list,
 void vpdma_add_out_dtd(struct vpdma_desc_list *list, int width,
 		const struct v4l2_rect *c_rect,
 		const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
-		enum vpdma_channel chan, u32 flags);
+		int max_w, int max_h, enum vpdma_channel chan, u32 flags);
 void vpdma_rawchan_add_out_dtd(struct vpdma_desc_list *list, int width,
 		const struct v4l2_rect *c_rect,
 		const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
-		int raw_vpdma_chan, u32 flags);
+		int max_w, int max_h, int raw_vpdma_chan, u32 flags);
+
 void vpdma_add_in_dtd(struct vpdma_desc_list *list, int width,
 		const struct v4l2_rect *c_rect,
 		const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
@@ -221,6 +246,9 @@ void vpdma_set_line_mode(struct vpdma_data *vpdma, int line_mode,
 		enum vpdma_channel chan);
 void vpdma_set_frame_start_event(struct vpdma_data *vpdma,
 		enum vpdma_frame_start_event fs_event, enum vpdma_channel chan);
+void vpdma_set_max_size(struct vpdma_data *vpdma, int reg_addr,
+			u32 width, u32 height);
+
 void vpdma_set_bg_color(struct vpdma_data *vpdma,
 			struct vpdma_data_format *fmt, u32 color);
 void vpdma_dump_regs(struct vpdma_data *vpdma);
diff --git a/drivers/media/platform/ti-vpe/vpdma_priv.h b/drivers/media/platform/ti-vpe/vpdma_priv.h
index aeade5edc8ac..54b6aa866c74 100644
--- a/drivers/media/platform/ti-vpe/vpdma_priv.h
+++ b/drivers/media/platform/ti-vpe/vpdma_priv.h
@@ -28,6 +28,10 @@
 #define VPDMA_MAX_SIZE1		0x34
 #define VPDMA_MAX_SIZE2		0x38
 #define VPDMA_MAX_SIZE3		0x3c
+#define VPDMA_MAX_SIZE_WIDTH_MASK	0xffff
+#define VPDMA_MAX_SIZE_WIDTH_SHFT	16
+#define VPDMA_MAX_SIZE_HEIGHT_MASK	0xffff
+#define VPDMA_MAX_SIZE_HEIGHT_SHFT	0
 
 /* Interrupts */
 #define VPDMA_INT_CHAN_STAT(grp)	(0x40 + grp * 8)
@@ -227,42 +231,6 @@ struct vpdma_dtd {
 #define DTD_MAX_HEIGHT_MASK	0x07
 #define DTD_MAX_HEIGHT_SHFT	0
 
-/* max width configurations */
- /* unlimited width */
-#define	MAX_OUT_WIDTH_UNLIMITED		0
-/* as specified in max_size1 reg */
-#define MAX_OUT_WIDTH_REG1		1
-/* as specified in max_size2 reg */
-#define MAX_OUT_WIDTH_REG2		2
-/* as specified in max_size3 reg */
-#define	MAX_OUT_WIDTH_REG3		3
-/* maximum of 352 pixels as width */
-#define MAX_OUT_WIDTH_352		4
-/* maximum of 768 pixels as width */
-#define	MAX_OUT_WIDTH_768		5
-/* maximum of 1280 pixels width */
-#define	MAX_OUT_WIDTH_1280		6
-/* maximum of 1920 pixels as width */
-#define	MAX_OUT_WIDTH_1920		7
-
-/* max height configurations */
- /* unlimited height */
-#define	MAX_OUT_HEIGHT_UNLIMITED	0
-/* as specified in max_size1 reg */
-#define MAX_OUT_HEIGHT_REG1		1
-/* as specified in max_size2 reg */
-#define MAX_OUT_HEIGHT_REG2		2
-/* as specified in max_size3 reg */
-#define	MAX_OUT_HEIGHT_REG3		3
-/* maximum of 288 lines as height */
-#define MAX_OUT_HEIGHT_288		4
-/* maximum of 576 lines as height */
-#define	MAX_OUT_HEIGHT_576		5
-/* maximum of 720 lines as height */
-#define	MAX_OUT_HEIGHT_720		6
-/* maximum of 1080 lines as height */
-#define	MAX_OUT_HEIGHT_1080		7
-
 static inline u32 dtd_type_ctl_stride(int type, bool notify, int field,
 			bool one_d, bool even_line_skip, bool odd_line_skip,
 			int line_stride)
diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c
index f2b90d42b408..151a9280bb85 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -44,6 +44,7 @@
 #include <media/videobuf2-dma-contig.h>
 
 #include "vpdma.h"
+#include "vpdma_priv.h"
 #include "vpe_regs.h"
 #include "sc.h"
 #include "csc.h"
@@ -1035,8 +1036,12 @@ static void add_out_dtd(struct vpe_ctx *ctx, int port)
 	if (q_data->flags & Q_DATA_MODE_TILED)
 		flags |= VPDMA_DATA_MODE_TILED;
 
+	vpdma_set_max_size(ctx->dev->vpdma, VPDMA_MAX_SIZE1,
+			   MAX_W, MAX_H);
+
 	vpdma_add_out_dtd(&ctx->desc_list, q_data->width, &q_data->c_rect,
-		vpdma_fmt, dma_addr, p_data->channel, flags);
+			  vpdma_fmt, dma_addr, MAX_OUT_WIDTH_REG1,
+			  MAX_OUT_HEIGHT_REG1, p_data->channel, flags);
 }
 
 static void add_in_dtd(struct vpe_ctx *ctx, int port)
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Patch v2 12/35] media: ti-vpe: vpdma: Add abort channel desc and cleanup APIs
  2016-11-18 23:20 [Patch v2 00/35] media: ti-vpe: fixes and enhancements Benoit Parrot
                   ` (10 preceding siblings ...)
  2016-11-18 23:20 ` [Patch v2 11/35] media: ti-vpe: vpdma: Add support for setting max width height Benoit Parrot
@ 2016-11-18 23:20 ` Benoit Parrot
  2016-11-18 23:20 ` [Patch v2 13/35] media: ti-vpe: vpdma: Make list post atomic operation Benoit Parrot
                   ` (22 subsequent siblings)
  34 siblings, 0 replies; 36+ messages in thread
From: Benoit Parrot @ 2016-11-18 23:20 UTC (permalink / raw)
  To: linux-media, Hans Verkuil
  Cc: linux-kernel, Tomi Valkeinen, Jyri Sarha, Peter Ujfalusi, Benoit Parrot

From: Nikhil Devshatwar <nikhil.nd@ti.com>

Whenever VPDMA processes a data descriptor of a list, it processes it
and sets up the channel for the DMA transaction. List manager holds the
descriptor in the list until the DMA is complete. If sync_on_channel
descriptor, or another descriptor for the same channel is present in
the FIFO, list manager keeps them until the current channel is free.

When the capture stream is closed suddenly while there are pending
descriptors in the FIFO (streamON failed, application killed), it would
keep the VPDMA in a busy state. Any further list post would fail with
EBUSY.

To avoid this, drivers need to stop the current processing list and
cleanup all the resources VPDMA has taken and also clear the internal FSM
of list manager. The state machine is cleared by issuing channel specific
abort descriptor.

Therefore, the vpdma_list_cleanup accepts an array of channels for which
abort_channel descriptors should be posted. It is driver's responsibility
to post for all the channels or the channels which were used in the last
context.

Signed-off-by: Nikhil Devshatwar <nikhil.nd@ti.com>
Signed-off-by: Benoit Parrot <bparrot@ti.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/platform/ti-vpe/vpdma.c | 75 +++++++++++++++++++++++++++++++++++
 drivers/media/platform/ti-vpe/vpdma.h |  6 +++
 2 files changed, 81 insertions(+)

diff --git a/drivers/media/platform/ti-vpe/vpdma.c b/drivers/media/platform/ti-vpe/vpdma.c
index 1a0152842a17..7808c9c1828b 100644
--- a/drivers/media/platform/ti-vpe/vpdma.c
+++ b/drivers/media/platform/ti-vpe/vpdma.c
@@ -385,6 +385,56 @@ void vpdma_unmap_desc_buf(struct vpdma_data *vpdma, struct vpdma_buf *buf)
 EXPORT_SYMBOL(vpdma_unmap_desc_buf);
 
 /*
+ * Cleanup all pending descriptors of a list
+ * First, stop the current list being processed.
+ * If the VPDMA was busy, this step makes vpdma to accept post lists.
+ * To cleanup the internal FSM, post abort list descriptor for all the
+ * channels from @channels array of size @size.
+ */
+int vpdma_list_cleanup(struct vpdma_data *vpdma, int list_num,
+		int *channels, int size)
+{
+	struct vpdma_desc_list abort_list;
+	int i, ret, timeout = 500;
+
+	write_reg(vpdma, VPDMA_LIST_ATTR,
+			(list_num << VPDMA_LIST_NUM_SHFT) |
+			(1 << VPDMA_LIST_STOP_SHFT));
+
+	if (size <= 0 || !channels)
+		return 0;
+
+	ret = vpdma_create_desc_list(&abort_list,
+		size * sizeof(struct vpdma_dtd), VPDMA_LIST_TYPE_NORMAL);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < size; i++)
+		vpdma_add_abort_channel_ctd(&abort_list, channels[i]);
+
+	ret = vpdma_map_desc_buf(vpdma, &abort_list.buf);
+	if (ret)
+		return ret;
+	ret = vpdma_submit_descs(vpdma, &abort_list, list_num);
+	if (ret)
+		return ret;
+
+	while (vpdma_list_busy(vpdma, list_num) && timeout--)
+		;
+
+	if (timeout == 0) {
+		dev_err(&vpdma->pdev->dev, "Timed out cleaning up VPDMA list\n");
+		return -EBUSY;
+	}
+
+	vpdma_unmap_desc_buf(vpdma, &abort_list.buf);
+	vpdma_free_desc_buf(&abort_list.buf);
+
+	return 0;
+}
+EXPORT_SYMBOL(vpdma_list_cleanup);
+
+/*
  * create a descriptor list, the user of this list will append configuration,
  * control and data descriptors to this list, this list will be submitted to
  * VPDMA. VPDMA's list parser will go through each descriptor and perform the
@@ -629,6 +679,31 @@ void vpdma_add_sync_on_channel_ctd(struct vpdma_desc_list *list,
 }
 EXPORT_SYMBOL(vpdma_add_sync_on_channel_ctd);
 
+/*
+ * append an 'abort_channel' type control descriptor to the given descriptor
+ * list, this descriptor aborts any DMA transaction happening using the
+ * specified channel
+ */
+void vpdma_add_abort_channel_ctd(struct vpdma_desc_list *list,
+		int chan_num)
+{
+	struct vpdma_ctd *ctd;
+
+	ctd = list->next;
+	WARN_ON((void *)(ctd + 1) > (list->buf.addr + list->buf.size));
+
+	ctd->w0 = 0;
+	ctd->w1 = 0;
+	ctd->w2 = 0;
+	ctd->type_source_ctl = ctd_type_source_ctl(chan_num,
+				CTD_TYPE_ABORT_CHANNEL);
+
+	list->next = ctd + 1;
+
+	dump_ctd(ctd);
+}
+EXPORT_SYMBOL(vpdma_add_abort_channel_ctd);
+
 static void dump_dtd(struct vpdma_dtd *dtd)
 {
 	int dir, chan;
diff --git a/drivers/media/platform/ti-vpe/vpdma.h b/drivers/media/platform/ti-vpe/vpdma.h
index 32b9ed5191c5..4dafc1bcf116 100644
--- a/drivers/media/platform/ti-vpe/vpdma.h
+++ b/drivers/media/platform/ti-vpe/vpdma.h
@@ -163,6 +163,8 @@ enum vpdma_channel {
 #define VIP_CHAN_YUV_PORTB_OFFSET	2
 #define VIP_CHAN_RGB_PORTB_OFFSET	1
 
+#define VPDMA_MAX_CHANNELS		256
+
 /* flags for VPDMA data descriptors */
 #define VPDMA_DATA_ODD_LINE_SKIP	(1 << 0)
 #define VPDMA_DATA_EVEN_LINE_SKIP	(1 << 1)
@@ -219,6 +221,8 @@ void vpdma_add_cfd_adb(struct vpdma_desc_list *list, int client,
 		struct vpdma_buf *adb);
 void vpdma_add_sync_on_channel_ctd(struct vpdma_desc_list *list,
 		enum vpdma_channel chan);
+void vpdma_add_abort_channel_ctd(struct vpdma_desc_list *list,
+		int chan_num);
 void vpdma_add_out_dtd(struct vpdma_desc_list *list, int width,
 		const struct v4l2_rect *c_rect,
 		const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
@@ -233,6 +237,8 @@ void vpdma_add_in_dtd(struct vpdma_desc_list *list, int width,
 		const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
 		enum vpdma_channel chan, int field, u32 flags, int frame_width,
 		int frame_height, int start_h, int start_v);
+int vpdma_list_cleanup(struct vpdma_data *vpdma, int list_num,
+		int *channels, int size);
 
 /* vpdma list interrupt management */
 void vpdma_enable_list_complete_irq(struct vpdma_data *vpdma, int irq_num,
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Patch v2 13/35] media: ti-vpe: vpdma: Make list post atomic operation
  2016-11-18 23:20 [Patch v2 00/35] media: ti-vpe: fixes and enhancements Benoit Parrot
                   ` (11 preceding siblings ...)
  2016-11-18 23:20 ` [Patch v2 12/35] media: ti-vpe: vpdma: Add abort channel desc and cleanup APIs Benoit Parrot
@ 2016-11-18 23:20 ` Benoit Parrot
  2016-11-18 23:20 ` [Patch v2 14/35] media: ti-vpe: vpdma: Clear IRQs for individual lists Benoit Parrot
                   ` (21 subsequent siblings)
  34 siblings, 0 replies; 36+ messages in thread
From: Benoit Parrot @ 2016-11-18 23:20 UTC (permalink / raw)
  To: linux-media, Hans Verkuil
  Cc: linux-kernel, Tomi Valkeinen, Jyri Sarha, Peter Ujfalusi, Benoit Parrot

From: Nikhil Devshatwar <nikhil.nd@ti.com>

Writing to the "VPDMA list attribute" register is considered as a list
post. This informs the VPDMA firmware to load the list from the address
which should be taken from the "VPDMA list address" register.

As these two register writes are dependent, it is important that the two
writes happen in atomic manner. This ensures multiple slices (which share
same VPDMA) can post lists asynchronously and all of them point to the
correct addresses.

Slightly modified to implementation for the original patch to use
spin_lock instead of mutex as the list post is also called from
interrupt context.

Signed-off-by: Nikhil Devshatwar <nikhil.nd@ti.com>
Signed-off-by: Benoit Parrot <bparrot@ti.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/platform/ti-vpe/vpdma.c | 4 ++++
 drivers/media/platform/ti-vpe/vpdma.h | 1 +
 2 files changed, 5 insertions(+)

diff --git a/drivers/media/platform/ti-vpe/vpdma.c b/drivers/media/platform/ti-vpe/vpdma.c
index 7808c9c1828b..ffc281d2b065 100644
--- a/drivers/media/platform/ti-vpe/vpdma.c
+++ b/drivers/media/platform/ti-vpe/vpdma.c
@@ -491,6 +491,7 @@ int vpdma_submit_descs(struct vpdma_data *vpdma,
 			struct vpdma_desc_list *list, int list_num)
 {
 	int list_size;
+	unsigned long flags;
 
 	if (vpdma_list_busy(vpdma, list_num))
 		return -EBUSY;
@@ -498,12 +499,14 @@ int vpdma_submit_descs(struct vpdma_data *vpdma,
 	/* 16-byte granularity */
 	list_size = (list->next - list->buf.addr) >> 4;
 
+	spin_lock_irqsave(&vpdma->lock, flags);
 	write_reg(vpdma, VPDMA_LIST_ADDR, (u32) list->buf.dma_addr);
 
 	write_reg(vpdma, VPDMA_LIST_ATTR,
 			(list_num << VPDMA_LIST_NUM_SHFT) |
 			(list->type << VPDMA_LIST_TYPE_SHFT) |
 			list_size);
+	spin_unlock_irqrestore(&vpdma->lock, flags);
 
 	return 0;
 }
@@ -1090,6 +1093,7 @@ struct vpdma_data *vpdma_create(struct platform_device *pdev,
 
 	vpdma->pdev = pdev;
 	vpdma->cb = cb;
+	spin_lock_init(&vpdma->lock);
 
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vpdma");
 	if (res == NULL) {
diff --git a/drivers/media/platform/ti-vpe/vpdma.h b/drivers/media/platform/ti-vpe/vpdma.h
index 4dafc1bcf116..f08f4370ce4a 100644
--- a/drivers/media/platform/ti-vpe/vpdma.h
+++ b/drivers/media/platform/ti-vpe/vpdma.h
@@ -35,6 +35,7 @@ struct vpdma_data {
 
 	struct platform_device	*pdev;
 
+	spinlock_t		lock;
 	/* callback to VPE driver when the firmware is loaded */
 	void (*cb)(struct platform_device *pdev);
 };
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Patch v2 14/35] media: ti-vpe: vpdma: Clear IRQs for individual lists
  2016-11-18 23:20 [Patch v2 00/35] media: ti-vpe: fixes and enhancements Benoit Parrot
                   ` (12 preceding siblings ...)
  2016-11-18 23:20 ` [Patch v2 13/35] media: ti-vpe: vpdma: Make list post atomic operation Benoit Parrot
@ 2016-11-18 23:20 ` Benoit Parrot
  2016-11-18 23:20 ` [Patch v2 15/35] media: ti-vpe: vpe: configure line mode separately Benoit Parrot
                   ` (20 subsequent siblings)
  34 siblings, 0 replies; 36+ messages in thread
From: Benoit Parrot @ 2016-11-18 23:20 UTC (permalink / raw)
  To: linux-media, Hans Verkuil
  Cc: linux-kernel, Tomi Valkeinen, Jyri Sarha, Peter Ujfalusi, Benoit Parrot

From: Nikhil Devshatwar <nikhil.nd@ti.com>

VPDMA IRQs are registered for multiple lists
When clearing an IRQ for a list interrupt, all the
IRQs for the individual lists are to be cleared separately.

Signed-off-by: Nikhil Devshatwar <nikhil.nd@ti.com>
Signed-off-by: Benoit Parrot <bparrot@ti.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/platform/ti-vpe/vpdma.c | 6 +++---
 drivers/media/platform/ti-vpe/vpdma.h | 3 ++-
 drivers/media/platform/ti-vpe/vpe.c   | 2 +-
 3 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/media/platform/ti-vpe/vpdma.c b/drivers/media/platform/ti-vpe/vpdma.c
index ffc281d2b065..c0a4e035bc2a 100644
--- a/drivers/media/platform/ti-vpe/vpdma.c
+++ b/drivers/media/platform/ti-vpe/vpdma.c
@@ -953,12 +953,12 @@ unsigned int vpdma_get_list_mask(struct vpdma_data *vpdma, int irq_num)
 EXPORT_SYMBOL(vpdma_get_list_mask);
 
 /* clear previosuly occured list intterupts in the LIST_STAT register */
-void vpdma_clear_list_stat(struct vpdma_data *vpdma, int irq_num)
+void vpdma_clear_list_stat(struct vpdma_data *vpdma, int irq_num,
+			   int list_num)
 {
 	u32 reg_addr = VPDMA_INT_LIST0_STAT + VPDMA_INTX_OFFSET * irq_num;
 
-	write_reg(vpdma, reg_addr,
-		read_reg(vpdma, reg_addr));
+	write_reg(vpdma, reg_addr, 3 << (list_num * 2));
 }
 EXPORT_SYMBOL(vpdma_clear_list_stat);
 
diff --git a/drivers/media/platform/ti-vpe/vpdma.h b/drivers/media/platform/ti-vpe/vpdma.h
index f08f4370ce4a..65961147e8f7 100644
--- a/drivers/media/platform/ti-vpe/vpdma.h
+++ b/drivers/media/platform/ti-vpe/vpdma.h
@@ -244,7 +244,8 @@ int vpdma_list_cleanup(struct vpdma_data *vpdma, int list_num,
 /* vpdma list interrupt management */
 void vpdma_enable_list_complete_irq(struct vpdma_data *vpdma, int irq_num,
 		int list_num, bool enable);
-void vpdma_clear_list_stat(struct vpdma_data *vpdma, int irq_num);
+void vpdma_clear_list_stat(struct vpdma_data *vpdma, int irq_num,
+			   int list_num);
 unsigned int vpdma_get_list_stat(struct vpdma_data *vpdma, int irq_num);
 unsigned int vpdma_get_list_mask(struct vpdma_data *vpdma, int irq_num);
 
diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c
index 151a9280bb85..6fcdd0ea50e4 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -1326,7 +1326,7 @@ static irqreturn_t vpe_irq(int irq_vpe, void *data)
 
 	if (irqst0) {
 		if (irqst0 & VPE_INT0_LIST0_COMPLETE)
-			vpdma_clear_list_stat(ctx->dev->vpdma, 0);
+			vpdma_clear_list_stat(ctx->dev->vpdma, 0, 0);
 
 		irqst0 &= ~(VPE_INT0_LIST0_COMPLETE);
 	}
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Patch v2 15/35] media: ti-vpe: vpe: configure line mode separately
  2016-11-18 23:20 [Patch v2 00/35] media: ti-vpe: fixes and enhancements Benoit Parrot
                   ` (13 preceding siblings ...)
  2016-11-18 23:20 ` [Patch v2 14/35] media: ti-vpe: vpdma: Clear IRQs for individual lists Benoit Parrot
@ 2016-11-18 23:20 ` Benoit Parrot
  2016-11-18 23:20 ` [Patch v2 16/35] media: ti-vpe: vpe: Setup srcdst parameters in start_streaming Benoit Parrot
                   ` (19 subsequent siblings)
  34 siblings, 0 replies; 36+ messages in thread
From: Benoit Parrot @ 2016-11-18 23:20 UTC (permalink / raw)
  To: linux-media, Hans Verkuil
  Cc: linux-kernel, Tomi Valkeinen, Jyri Sarha, Peter Ujfalusi, Benoit Parrot

From: Nikhil Devshatwar <nikhil.nd@ti.com>

Current driver configures the line mode of the DEI clients
from the open function directly. Even if the newly created context
is not yet scheduled, it updates some of the VPDMA registers.
This causes a problem in multi instance use case where just opening
the m2m device second time causes the running job to stall. This
happens especially if the source buffers used are NV12.

While all other configuration is being written to context specific
shadow registers, only line mode configuration is happening directly.

As there is no shadow register for line mode configuration, it's better
to separate the config_mode setting and line_mode setting. Call the
new "set_line_modes" functions only when actually loading the mmrs.
This makes sure that no non-running job will write to the registers
directly.

Signed-off-by: Nikhil Devshatwar <nikhil.nd@ti.com>
Signed-off-by: Benoit Parrot <bparrot@ti.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/platform/ti-vpe/vpe.c | 25 +++++++++++++++++--------
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c
index 6fcdd0ea50e4..c79137b404ea 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -660,14 +660,13 @@ static void set_us_coefficients(struct vpe_ctx *ctx)
 /*
  * Set the upsampler config mode and the VPDMA line mode in the shadow MMRs.
  */
-static void set_cfg_and_line_modes(struct vpe_ctx *ctx)
+static void set_cfg_modes(struct vpe_ctx *ctx)
 {
 	struct vpe_fmt *fmt = ctx->q_data[Q_DATA_SRC].fmt;
 	struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr;
 	u32 *us1_reg0 = &mmr_adb->us1_regs[0];
 	u32 *us2_reg0 = &mmr_adb->us2_regs[0];
 	u32 *us3_reg0 = &mmr_adb->us3_regs[0];
-	int line_mode = 1;
 	int cfg_mode = 1;
 
 	/*
@@ -675,15 +674,24 @@ static void set_cfg_and_line_modes(struct vpe_ctx *ctx)
 	 * Cfg Mode 1: YUV422 source, disable upsampler, DEI is de-interlacing.
 	 */
 
-	if (fmt->fourcc == V4L2_PIX_FMT_NV12) {
+	if (fmt->fourcc == V4L2_PIX_FMT_NV12)
 		cfg_mode = 0;
-		line_mode = 0;		/* double lines to line buffer */
-	}
 
 	write_field(us1_reg0, cfg_mode, VPE_US_MODE_MASK, VPE_US_MODE_SHIFT);
 	write_field(us2_reg0, cfg_mode, VPE_US_MODE_MASK, VPE_US_MODE_SHIFT);
 	write_field(us3_reg0, cfg_mode, VPE_US_MODE_MASK, VPE_US_MODE_SHIFT);
 
+	ctx->load_mmrs = true;
+}
+
+static void set_line_modes(struct vpe_ctx *ctx)
+{
+	struct vpe_fmt *fmt = ctx->q_data[Q_DATA_SRC].fmt;
+	int line_mode = 1;
+
+	if (fmt->fourcc == V4L2_PIX_FMT_NV12)
+		line_mode = 0;		/* double lines to line buffer */
+
 	/* regs for now */
 	vpdma_set_line_mode(ctx->dev->vpdma, line_mode, VPE_CHAN_CHROMA1_IN);
 	vpdma_set_line_mode(ctx->dev->vpdma, line_mode, VPE_CHAN_CHROMA2_IN);
@@ -708,8 +716,6 @@ static void set_cfg_and_line_modes(struct vpe_ctx *ctx)
 	/* frame start for MV in client */
 	vpdma_set_frame_start_event(ctx->dev->vpdma, VPDMA_FSEVENT_CHANNEL_ACTIVE,
 		VPE_CHAN_MV_IN);
-
-	ctx->load_mmrs = true;
 }
 
 /*
@@ -868,7 +874,7 @@ static int set_srcdst_params(struct vpe_ctx *ctx)
 	if (ret)
 		return ret;
 
-	set_cfg_and_line_modes(ctx);
+	set_cfg_modes(ctx);
 	set_dei_regs(ctx);
 
 	csc_set_coeff(ctx->dev->csc, &mmr_adb->csc_regs[0],
@@ -1184,6 +1190,9 @@ static void device_run(void *priv)
 	if (ctx->dev->loaded_mmrs != ctx->mmr_adb.dma_addr || ctx->load_mmrs) {
 		vpdma_map_desc_buf(ctx->dev->vpdma, &ctx->mmr_adb);
 		vpdma_add_cfd_adb(&ctx->desc_list, CFD_MMR_CLIENT, &ctx->mmr_adb);
+
+		set_line_modes(ctx);
+
 		ctx->dev->loaded_mmrs = ctx->mmr_adb.dma_addr;
 		ctx->load_mmrs = false;
 	}
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Patch v2 16/35] media: ti-vpe: vpe: Setup srcdst parameters in start_streaming
  2016-11-18 23:20 [Patch v2 00/35] media: ti-vpe: fixes and enhancements Benoit Parrot
                   ` (14 preceding siblings ...)
  2016-11-18 23:20 ` [Patch v2 15/35] media: ti-vpe: vpe: configure line mode separately Benoit Parrot
@ 2016-11-18 23:20 ` Benoit Parrot
  2016-11-18 23:20 ` [Patch v2 17/35] media: ti-vpe: vpe: Post next descriptor only for list complete IRQ Benoit Parrot
                   ` (18 subsequent siblings)
  34 siblings, 0 replies; 36+ messages in thread
From: Benoit Parrot @ 2016-11-18 23:20 UTC (permalink / raw)
  To: linux-media, Hans Verkuil
  Cc: linux-kernel, Tomi Valkeinen, Jyri Sarha, Peter Ujfalusi, Benoit Parrot

From: Nikhil Devshatwar <nikhil.nd@ti.com>

For deinterlacing operation, each operation needs 2 fields in the
history. This is achieved by holding three buffers in
ctx->src_vbs[0,1,2] (f,f-1,f-2)

This is achieved by using the ctx->sequence which gets reset via the
s_fmt ioctl.

These buffers are dequeued in stream OFF by calling free_vbs()
But the corresponding references aren't removed anywhere.

When application tries to stream ON and OFF continuously, s_fmt ioctl
won't be called and it won't setup the srcdst parameters.

Setting source/destination parameters in stream ON ioctl would make
sure that the context is re-initialized before it is being used by
the driver.

Signed-off-by: Nikhil Devshatwar <nikhil.nd@ti.com>
Signed-off-by: Benoit Parrot <bparrot@ti.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/platform/ti-vpe/vpe.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c
index c79137b404ea..1ee7e611e41b 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -869,6 +869,7 @@ static int set_srcdst_params(struct vpe_ctx *ctx)
 	}
 
 	free_vbs(ctx);
+	ctx->src_vbs[2] = ctx->src_vbs[1] = ctx->src_vbs[0] = NULL;
 
 	ret = realloc_mv_buffers(ctx, mv_buf_size);
 	if (ret)
@@ -1990,6 +1991,9 @@ static int vpe_start_streaming(struct vb2_queue *q, unsigned int count)
 	if (ctx->deinterlacing)
 		config_edi_input_mode(ctx, 0x0);
 
+	if (ctx->sequence != 0)
+		set_srcdst_params(ctx);
+
 	return 0;
 }
 
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Patch v2 17/35] media: ti-vpe: vpe: Post next descriptor only for list complete IRQ
  2016-11-18 23:20 [Patch v2 00/35] media: ti-vpe: fixes and enhancements Benoit Parrot
                   ` (15 preceding siblings ...)
  2016-11-18 23:20 ` [Patch v2 16/35] media: ti-vpe: vpe: Setup srcdst parameters in start_streaming Benoit Parrot
@ 2016-11-18 23:20 ` Benoit Parrot
  2016-11-18 23:20 ` [Patch v2 18/35] media: ti-vpe: vpe: Add RGB565 and RGB5551 support Benoit Parrot
                   ` (17 subsequent siblings)
  34 siblings, 0 replies; 36+ messages in thread
From: Benoit Parrot @ 2016-11-18 23:20 UTC (permalink / raw)
  To: linux-media, Hans Verkuil
  Cc: linux-kernel, Tomi Valkeinen, Jyri Sarha, Peter Ujfalusi, Benoit Parrot

From: Nikhil Devshatwar <nikhil.nd@ti.com>

vpe_irq checks for the possible interrupt sources and prints the
errors for the DEI_ERROR and DS_UV interrupts. But it also post the
next descriptor list irrespective of whichever interrupt has occurred.

Because of this, driver may release the buffers even before DMA is
complete and also schedule next descriptor list.

Fix this by _actually_ handling the IRQ only when ListComplete IRQ
occurs.

Signed-off-by: Nikhil Devshatwar <nikhil.nd@ti.com>
Signed-off-by: Benoit Parrot <bparrot@ti.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/platform/ti-vpe/vpe.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c
index 1ee7e611e41b..0f652a049ede 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -1304,6 +1304,7 @@ static irqreturn_t vpe_irq(int irq_vpe, void *data)
 	struct vb2_v4l2_buffer *s_vb, *d_vb;
 	unsigned long flags;
 	u32 irqst0, irqst1;
+	bool list_complete = false;
 
 	irqst0 = read_reg(dev, VPE_INT0_STATUS0);
 	if (irqst0) {
@@ -1339,6 +1340,7 @@ static irqreturn_t vpe_irq(int irq_vpe, void *data)
 			vpdma_clear_list_stat(ctx->dev->vpdma, 0, 0);
 
 		irqst0 &= ~(VPE_INT0_LIST0_COMPLETE);
+		list_complete = true;
 	}
 
 	if (irqst0 | irqst1) {
@@ -1346,6 +1348,13 @@ static irqreturn_t vpe_irq(int irq_vpe, void *data)
 			irqst0, irqst1);
 	}
 
+	/*
+	 * Setup next operation only when list complete IRQ occurs
+	 * otherwise, skip the following code
+	 */
+	if (!list_complete)
+		goto handled;
+
 	disable_irqs(ctx);
 
 	vpdma_unmap_desc_buf(dev->vpdma, &ctx->desc_list.buf);
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Patch v2 18/35] media: ti-vpe: vpe: Add RGB565 and RGB5551 support
  2016-11-18 23:20 [Patch v2 00/35] media: ti-vpe: fixes and enhancements Benoit Parrot
                   ` (16 preceding siblings ...)
  2016-11-18 23:20 ` [Patch v2 17/35] media: ti-vpe: vpe: Post next descriptor only for list complete IRQ Benoit Parrot
@ 2016-11-18 23:20 ` Benoit Parrot
  2016-11-18 23:20 ` [Patch v2 19/35] media: ti-vpe: vpdma: allocate and maintain hwlist Benoit Parrot
                   ` (16 subsequent siblings)
  34 siblings, 0 replies; 36+ messages in thread
From: Benoit Parrot @ 2016-11-18 23:20 UTC (permalink / raw)
  To: linux-media, Hans Verkuil
  Cc: linux-kernel, Tomi Valkeinen, Jyri Sarha, Peter Ujfalusi, Benoit Parrot

From: Nikhil Devshatwar <nikhil.nd@ti.com>

VPE hardware can generate output in RGB565 or in RGB5551 format.
Add these formats in the supported format list for CAPTURE stream.
Also, for RGB5551 format, the alpha component is not processed,
so the alpha value is taken from the default color.
Set the default color to make alpha component full when the dst
format is of RGB color space.

Signed-off-by: Nikhil Devshatwar <nikhil.nd@ti.com>
Signed-off-by: Benoit Parrot <bparrot@ti.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/platform/ti-vpe/vpe.c | 22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c
index 0f652a049ede..d3412accf564 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -302,6 +302,22 @@ static struct vpe_fmt vpe_formats[] = {
 		.vpdma_fmt	= { &vpdma_rgb_fmts[VPDMA_DATA_FMT_ABGR32],
 				  },
 	},
+	{
+		.name		= "RGB565",
+		.fourcc		= V4L2_PIX_FMT_RGB565,
+		.types		= VPE_FMT_TYPE_CAPTURE,
+		.coplanar	= 0,
+		.vpdma_fmt	= { &vpdma_rgb_fmts[VPDMA_DATA_FMT_RGB565],
+				  },
+	},
+	{
+		.name		= "RGB5551",
+		.fourcc		= V4L2_PIX_FMT_RGB555,
+		.types		= VPE_FMT_TYPE_CAPTURE,
+		.coplanar	= 0,
+		.vpdma_fmt	= { &vpdma_rgb_fmts[VPDMA_DATA_FMT_RGBA16_5551],
+				  },
+	},
 };
 
 /*
@@ -738,9 +754,11 @@ static void set_dst_registers(struct vpe_ctx *ctx)
 	struct vpe_fmt *fmt = ctx->q_data[Q_DATA_DST].fmt;
 	u32 val = 0;
 
-	if (clrspc == V4L2_COLORSPACE_SRGB)
+	if (clrspc == V4L2_COLORSPACE_SRGB) {
 		val |= VPE_RGB_OUT_SELECT;
-	else if (fmt->fourcc == V4L2_PIX_FMT_NV16)
+		vpdma_set_bg_color(ctx->dev->vpdma,
+			(struct vpdma_data_format *)fmt->vpdma_fmt[0], 0xff);
+	} else if (fmt->fourcc == V4L2_PIX_FMT_NV16)
 		val |= VPE_COLOR_SEPARATE_422;
 
 	/*
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Patch v2 19/35] media: ti-vpe: vpdma: allocate and maintain hwlist
  2016-11-18 23:20 [Patch v2 00/35] media: ti-vpe: fixes and enhancements Benoit Parrot
                   ` (17 preceding siblings ...)
  2016-11-18 23:20 ` [Patch v2 18/35] media: ti-vpe: vpe: Add RGB565 and RGB5551 support Benoit Parrot
@ 2016-11-18 23:20 ` Benoit Parrot
  2016-11-18 23:20 ` [Patch v2 20/35] media: ti-vpe: vpe: Added MODULE_DEVICE_TABLE hint Benoit Parrot
                   ` (15 subsequent siblings)
  34 siblings, 0 replies; 36+ messages in thread
From: Benoit Parrot @ 2016-11-18 23:20 UTC (permalink / raw)
  To: linux-media, Hans Verkuil
  Cc: linux-kernel, Tomi Valkeinen, Jyri Sarha, Peter Ujfalusi, Benoit Parrot

From: Nikhil Devshatwar <nikhil.nd@ti.com>

VPDMA block used in ti-vip and ti-vpe modules have support for
up to 8 hardware descriptor lists. A descriptor list can be
submitted to any of the 8 lists (as long as it's not busy).

When multiple clients want to transfer data in parallel, its easier
to allocate one list per client and let it use it. This way, the
list numbers need not be hard-coded into the driver.

Add support for allocating hwlist and maintain them with a priv data.

Signed-off-by: Nikhil Devshatwar <nikhil.nd@ti.com>
Signed-off-by: Benoit Parrot <bparrot@ti.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/platform/ti-vpe/vpdma.c | 44 +++++++++++++++++++++++++++++++++++
 drivers/media/platform/ti-vpe/vpdma.h |  9 +++++++
 2 files changed, 53 insertions(+)

diff --git a/drivers/media/platform/ti-vpe/vpdma.c b/drivers/media/platform/ti-vpe/vpdma.c
index c0a4e035bc2a..f85727a0ac44 100644
--- a/drivers/media/platform/ti-vpe/vpdma.c
+++ b/drivers/media/platform/ti-vpe/vpdma.c
@@ -902,6 +902,50 @@ void vpdma_add_in_dtd(struct vpdma_desc_list *list, int width,
 }
 EXPORT_SYMBOL(vpdma_add_in_dtd);
 
+int vpdma_hwlist_alloc(struct vpdma_data *vpdma, void *priv)
+{
+	int i, list_num = -1;
+	unsigned long flags;
+
+	spin_lock_irqsave(&vpdma->lock, flags);
+	for (i = 0; i < VPDMA_MAX_NUM_LIST &&
+	    vpdma->hwlist_used[i] == true; i++)
+		;
+
+	if (i < VPDMA_MAX_NUM_LIST) {
+		list_num = i;
+		vpdma->hwlist_used[i] = true;
+		vpdma->hwlist_priv[i] = priv;
+	}
+	spin_unlock_irqrestore(&vpdma->lock, flags);
+
+	return list_num;
+}
+EXPORT_SYMBOL(vpdma_hwlist_alloc);
+
+void *vpdma_hwlist_get_priv(struct vpdma_data *vpdma, int list_num)
+{
+	if (!vpdma || list_num >= VPDMA_MAX_NUM_LIST)
+		return NULL;
+
+	return vpdma->hwlist_priv[list_num];
+}
+EXPORT_SYMBOL(vpdma_hwlist_get_priv);
+
+void *vpdma_hwlist_release(struct vpdma_data *vpdma, int list_num)
+{
+	void *priv;
+	unsigned long flags;
+
+	spin_lock_irqsave(&vpdma->lock, flags);
+	vpdma->hwlist_used[list_num] = false;
+	priv = vpdma->hwlist_priv;
+	spin_unlock_irqrestore(&vpdma->lock, flags);
+
+	return priv;
+}
+EXPORT_SYMBOL(vpdma_hwlist_release);
+
 /* set or clear the mask for list complete interrupt */
 void vpdma_enable_list_complete_irq(struct vpdma_data *vpdma, int irq_num,
 		int list_num, bool enable)
diff --git a/drivers/media/platform/ti-vpe/vpdma.h b/drivers/media/platform/ti-vpe/vpdma.h
index 65961147e8f7..ccf871ad8800 100644
--- a/drivers/media/platform/ti-vpe/vpdma.h
+++ b/drivers/media/platform/ti-vpe/vpdma.h
@@ -13,6 +13,7 @@
 #ifndef __TI_VPDMA_H_
 #define __TI_VPDMA_H_
 
+#define VPDMA_MAX_NUM_LIST		8
 /*
  * A vpdma_buf tracks the size, DMA address and mapping status of each
  * driver DMA area.
@@ -36,6 +37,8 @@ struct vpdma_data {
 	struct platform_device	*pdev;
 
 	spinlock_t		lock;
+	bool			hwlist_used[VPDMA_MAX_NUM_LIST];
+	void			*hwlist_priv[VPDMA_MAX_NUM_LIST];
 	/* callback to VPE driver when the firmware is loaded */
 	void (*cb)(struct platform_device *pdev);
 };
@@ -215,6 +218,12 @@ bool vpdma_list_busy(struct vpdma_data *vpdma, int list_num);
 void vpdma_update_dma_addr(struct vpdma_data *vpdma,
 	struct vpdma_desc_list *list, dma_addr_t dma_addr,
 	void *write_dtd, int drop, int idx);
+
+/* VPDMA hardware list funcs */
+int vpdma_hwlist_alloc(struct vpdma_data *vpdma, void *priv);
+void *vpdma_hwlist_get_priv(struct vpdma_data *vpdma, int list_num);
+void *vpdma_hwlist_release(struct vpdma_data *vpdma, int list_num);
+
 /* helpers for creating vpdma descriptors */
 void vpdma_add_cfd_block(struct vpdma_desc_list *list, int client,
 		struct vpdma_buf *blk, u32 dest_offset);
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Patch v2 20/35] media: ti-vpe: vpe: Added MODULE_DEVICE_TABLE hint
  2016-11-18 23:20 [Patch v2 00/35] media: ti-vpe: fixes and enhancements Benoit Parrot
                   ` (18 preceding siblings ...)
  2016-11-18 23:20 ` [Patch v2 19/35] media: ti-vpe: vpdma: allocate and maintain hwlist Benoit Parrot
@ 2016-11-18 23:20 ` Benoit Parrot
  2016-11-18 23:20 ` [Patch v2 21/35] media: ti-vpe: vpdma: Corrected YUV422 data type label Benoit Parrot
                   ` (14 subsequent siblings)
  34 siblings, 0 replies; 36+ messages in thread
From: Benoit Parrot @ 2016-11-18 23:20 UTC (permalink / raw)
  To: linux-media, Hans Verkuil
  Cc: linux-kernel, Tomi Valkeinen, Jyri Sarha, Peter Ujfalusi, Benoit Parrot

ti_vpe module currently does not get loaded automatically.
Added MODULE_DEVICE_TABLE hint to the driver to assist.

Signed-off-by: Benoit Parrot <bparrot@ti.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
Reviewed-by: Javier Martinez Canillas <javier@osg.samsung.com>
---
 drivers/media/platform/ti-vpe/vpe.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c
index d3412accf564..05b793595ce9 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -2447,6 +2447,7 @@ static const struct of_device_id vpe_of_match[] = {
 	},
 	{},
 };
+MODULE_DEVICE_TABLE(of, vpe_of_match);
 #endif
 
 static struct platform_driver vpe_pdrv = {
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Patch v2 21/35] media: ti-vpe: vpdma: Corrected YUV422 data type label.
  2016-11-18 23:20 [Patch v2 00/35] media: ti-vpe: fixes and enhancements Benoit Parrot
                   ` (19 preceding siblings ...)
  2016-11-18 23:20 ` [Patch v2 20/35] media: ti-vpe: vpe: Added MODULE_DEVICE_TABLE hint Benoit Parrot
@ 2016-11-18 23:20 ` Benoit Parrot
  2016-11-18 23:20 ` [Patch v2 22/35] media: ti-vpe: vpdma: RGB data type yield inverted data Benoit Parrot
                   ` (13 subsequent siblings)
  34 siblings, 0 replies; 36+ messages in thread
From: Benoit Parrot @ 2016-11-18 23:20 UTC (permalink / raw)
  To: linux-media, Hans Verkuil
  Cc: linux-kernel, Tomi Valkeinen, Jyri Sarha, Peter Ujfalusi, Benoit Parrot

The YUV data type definition below are taken from
both the TRM and i839 Errata information.
Use the correct data type considering byte
reordering of components.

Added the 2 missing YUV422 variant.
Also since the single use of "C" in the 422 case
to mean "Cr" (i.e. V component). It was decided
to explicitly label them CR to remove any confusion.
Bear in mind that the type label refer to the memory
packed order (LSB - MSB).

Signed-off-by: Benoit Parrot <bparrot@ti.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/platform/ti-vpe/vpdma.c      | 18 ++++++++++++++----
 drivers/media/platform/ti-vpe/vpdma.h      |  6 ++++--
 drivers/media/platform/ti-vpe/vpdma_priv.h | 19 ++++++++++++++++---
 drivers/media/platform/ti-vpe/vpe.c        |  8 ++++----
 4 files changed, 38 insertions(+), 13 deletions(-)

diff --git a/drivers/media/platform/ti-vpe/vpdma.c b/drivers/media/platform/ti-vpe/vpdma.c
index f85727a0ac44..8f0d608c70f6 100644
--- a/drivers/media/platform/ti-vpe/vpdma.c
+++ b/drivers/media/platform/ti-vpe/vpdma.c
@@ -59,9 +59,9 @@ const struct vpdma_data_format vpdma_yuv_fmts[] = {
 		.data_type	= DATA_TYPE_C420,
 		.depth		= 4,
 	},
-	[VPDMA_DATA_FMT_YC422] = {
+	[VPDMA_DATA_FMT_YCR422] = {
 		.type		= VPDMA_DATA_FMT_TYPE_YUV,
-		.data_type	= DATA_TYPE_YC422,
+		.data_type	= DATA_TYPE_YCR422,
 		.depth		= 16,
 	},
 	[VPDMA_DATA_FMT_YC444] = {
@@ -69,9 +69,19 @@ const struct vpdma_data_format vpdma_yuv_fmts[] = {
 		.data_type	= DATA_TYPE_YC444,
 		.depth		= 24,
 	},
-	[VPDMA_DATA_FMT_CY422] = {
+	[VPDMA_DATA_FMT_CRY422] = {
 		.type		= VPDMA_DATA_FMT_TYPE_YUV,
-		.data_type	= DATA_TYPE_CY422,
+		.data_type	= DATA_TYPE_CRY422,
+		.depth		= 16,
+	},
+	[VPDMA_DATA_FMT_CBY422] = {
+		.type		= VPDMA_DATA_FMT_TYPE_YUV,
+		.data_type	= DATA_TYPE_CBY422,
+		.depth		= 16,
+	},
+	[VPDMA_DATA_FMT_YCB422] = {
+		.type		= VPDMA_DATA_FMT_TYPE_YUV,
+		.data_type	= DATA_TYPE_YCB422,
 		.depth		= 16,
 	},
 };
diff --git a/drivers/media/platform/ti-vpe/vpdma.h b/drivers/media/platform/ti-vpe/vpdma.h
index ccf871ad8800..405a6febc254 100644
--- a/drivers/media/platform/ti-vpe/vpdma.h
+++ b/drivers/media/platform/ti-vpe/vpdma.h
@@ -74,9 +74,11 @@ enum vpdma_yuv_formats {
 	VPDMA_DATA_FMT_C444,
 	VPDMA_DATA_FMT_C422,
 	VPDMA_DATA_FMT_C420,
-	VPDMA_DATA_FMT_YC422,
+	VPDMA_DATA_FMT_YCR422,
 	VPDMA_DATA_FMT_YC444,
-	VPDMA_DATA_FMT_CY422,
+	VPDMA_DATA_FMT_CRY422,
+	VPDMA_DATA_FMT_CBY422,
+	VPDMA_DATA_FMT_YCB422,
 };
 
 enum vpdma_rgb_formats {
diff --git a/drivers/media/platform/ti-vpe/vpdma_priv.h b/drivers/media/platform/ti-vpe/vpdma_priv.h
index 54b6aa866c74..f974a803fa27 100644
--- a/drivers/media/platform/ti-vpe/vpdma_priv.h
+++ b/drivers/media/platform/ti-vpe/vpdma_priv.h
@@ -77,16 +77,29 @@
 #define VPDMA_LIST_TYPE_SHFT		16
 #define VPDMA_LIST_SIZE_MASK		0xffff
 
-/* VPDMA data type values for data formats */
+/*
+ * The YUV data type definition below are taken from
+ * both the TRM and i839 Errata information.
+ * Use the correct data type considering byte
+ * reordering of components.
+ *
+ * Also since the single use of "C" in the 422 case
+ * to mean "Cr" (i.e. V component). It was decided
+ * to explicitly label them CR to remove any confusion.
+ * Bear in mind that the type label refer to the memory
+ * packed order (LSB - MSB).
+ */
 #define DATA_TYPE_Y444				0x0
 #define DATA_TYPE_Y422				0x1
 #define DATA_TYPE_Y420				0x2
 #define DATA_TYPE_C444				0x4
 #define DATA_TYPE_C422				0x5
 #define DATA_TYPE_C420				0x6
-#define DATA_TYPE_YC422				0x7
 #define DATA_TYPE_YC444				0x8
-#define DATA_TYPE_CY422				0x27
+#define DATA_TYPE_YCB422			0x7
+#define DATA_TYPE_YCR422			0x17
+#define DATA_TYPE_CBY422			0x27
+#define DATA_TYPE_CRY422			0x37
 
 #define DATA_TYPE_RGB16_565			0x0
 #define DATA_TYPE_ARGB_1555			0x1
diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c
index 05b793595ce9..ef55fb45d0be 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -237,7 +237,7 @@ struct vpe_fmt {
 
 static struct vpe_fmt vpe_formats[] = {
 	{
-		.name		= "YUV 422 co-planar",
+		.name		= "NV16 YUV 422 co-planar",
 		.fourcc		= V4L2_PIX_FMT_NV16,
 		.types		= VPE_FMT_TYPE_CAPTURE | VPE_FMT_TYPE_OUTPUT,
 		.coplanar	= 1,
@@ -246,7 +246,7 @@ static struct vpe_fmt vpe_formats[] = {
 				  },
 	},
 	{
-		.name		= "YUV 420 co-planar",
+		.name		= "NV12 YUV 420 co-planar",
 		.fourcc		= V4L2_PIX_FMT_NV12,
 		.types		= VPE_FMT_TYPE_CAPTURE | VPE_FMT_TYPE_OUTPUT,
 		.coplanar	= 1,
@@ -259,7 +259,7 @@ static struct vpe_fmt vpe_formats[] = {
 		.fourcc		= V4L2_PIX_FMT_YUYV,
 		.types		= VPE_FMT_TYPE_CAPTURE | VPE_FMT_TYPE_OUTPUT,
 		.coplanar	= 0,
-		.vpdma_fmt	= { &vpdma_yuv_fmts[VPDMA_DATA_FMT_YC422],
+		.vpdma_fmt	= { &vpdma_yuv_fmts[VPDMA_DATA_FMT_YCB422],
 				  },
 	},
 	{
@@ -267,7 +267,7 @@ static struct vpe_fmt vpe_formats[] = {
 		.fourcc		= V4L2_PIX_FMT_UYVY,
 		.types		= VPE_FMT_TYPE_CAPTURE | VPE_FMT_TYPE_OUTPUT,
 		.coplanar	= 0,
-		.vpdma_fmt	= { &vpdma_yuv_fmts[VPDMA_DATA_FMT_CY422],
+		.vpdma_fmt	= { &vpdma_yuv_fmts[VPDMA_DATA_FMT_CBY422],
 				  },
 	},
 	{
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Patch v2 22/35] media: ti-vpe: vpdma: RGB data type yield inverted data
  2016-11-18 23:20 [Patch v2 00/35] media: ti-vpe: fixes and enhancements Benoit Parrot
                   ` (20 preceding siblings ...)
  2016-11-18 23:20 ` [Patch v2 21/35] media: ti-vpe: vpdma: Corrected YUV422 data type label Benoit Parrot
@ 2016-11-18 23:20 ` Benoit Parrot
  2016-11-18 23:20 ` [Patch v2 23/35] media: ti-vpe: sc: Fix incorrect optimization Benoit Parrot
                   ` (12 subsequent siblings)
  34 siblings, 0 replies; 36+ messages in thread
From: Benoit Parrot @ 2016-11-18 23:20 UTC (permalink / raw)
  To: linux-media, Hans Verkuil
  Cc: linux-kernel, Tomi Valkeinen, Jyri Sarha, Peter Ujfalusi, Benoit Parrot

The VPDMA RGB data type definition have been updated
to match with Errata i839.

But some of the ARGB definition appeared to be wrong
in the document also. As they would yield RGBA instead.
They have been corrected based on experimentation.

Signed-off-by: Benoit Parrot <bparrot@ti.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/platform/ti-vpe/vpdma_priv.h | 49 ++++++++++++++++++------------
 1 file changed, 29 insertions(+), 20 deletions(-)

diff --git a/drivers/media/platform/ti-vpe/vpdma_priv.h b/drivers/media/platform/ti-vpe/vpdma_priv.h
index f974a803fa27..72c7f13b4a9d 100644
--- a/drivers/media/platform/ti-vpe/vpdma_priv.h
+++ b/drivers/media/platform/ti-vpe/vpdma_priv.h
@@ -101,26 +101,35 @@
 #define DATA_TYPE_CBY422			0x27
 #define DATA_TYPE_CRY422			0x37
 
-#define DATA_TYPE_RGB16_565			0x0
-#define DATA_TYPE_ARGB_1555			0x1
-#define DATA_TYPE_ARGB_4444			0x2
-#define DATA_TYPE_RGBA_5551			0x3
-#define DATA_TYPE_RGBA_4444			0x4
-#define DATA_TYPE_ARGB24_6666			0x5
-#define DATA_TYPE_RGB24_888			0x6
-#define DATA_TYPE_ARGB32_8888			0x7
-#define DATA_TYPE_RGBA24_6666			0x8
-#define DATA_TYPE_RGBA32_8888			0x9
-#define DATA_TYPE_BGR16_565			0x10
-#define DATA_TYPE_ABGR_1555			0x11
-#define DATA_TYPE_ABGR_4444			0x12
-#define DATA_TYPE_BGRA_5551			0x13
-#define DATA_TYPE_BGRA_4444			0x14
-#define DATA_TYPE_ABGR24_6666			0x15
-#define DATA_TYPE_BGR24_888			0x16
-#define DATA_TYPE_ABGR32_8888			0x17
-#define DATA_TYPE_BGRA24_6666			0x18
-#define DATA_TYPE_BGRA32_8888			0x19
+/*
+ * The RGB data type definition below are defined
+ * to follow Errata i819.
+ * The initial values were taken from:
+ * VPDMA_data_type_mapping_v0.2vayu_c.pdf
+ * But some of the ARGB definition appeared to be wrong
+ * in the document also. As they would yield RGBA instead.
+ * They have been corrected based on experimentation.
+ */
+#define DATA_TYPE_RGB16_565			0x10
+#define DATA_TYPE_ARGB_1555			0x13
+#define DATA_TYPE_ARGB_4444			0x14
+#define DATA_TYPE_RGBA_5551			0x11
+#define DATA_TYPE_RGBA_4444			0x12
+#define DATA_TYPE_ARGB24_6666			0x18
+#define DATA_TYPE_RGB24_888			0x16
+#define DATA_TYPE_ARGB32_8888			0x17
+#define DATA_TYPE_RGBA24_6666			0x15
+#define DATA_TYPE_RGBA32_8888			0x19
+#define DATA_TYPE_BGR16_565			0x0
+#define DATA_TYPE_ABGR_1555			0x3
+#define DATA_TYPE_ABGR_4444			0x4
+#define DATA_TYPE_BGRA_5551			0x1
+#define DATA_TYPE_BGRA_4444			0x2
+#define DATA_TYPE_ABGR24_6666			0x8
+#define DATA_TYPE_BGR24_888			0x6
+#define DATA_TYPE_ABGR32_8888			0x7
+#define DATA_TYPE_BGRA24_6666			0x5
+#define DATA_TYPE_BGRA32_8888			0x9
 
 #define DATA_TYPE_MV				0x3
 
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Patch v2 23/35] media: ti-vpe: sc: Fix incorrect optimization
  2016-11-18 23:20 [Patch v2 00/35] media: ti-vpe: fixes and enhancements Benoit Parrot
                   ` (21 preceding siblings ...)
  2016-11-18 23:20 ` [Patch v2 22/35] media: ti-vpe: vpdma: RGB data type yield inverted data Benoit Parrot
@ 2016-11-18 23:20 ` Benoit Parrot
  2016-11-18 23:20 ` [Patch v2 24/35] media: ti-vpe: vpe: Fix vb2 buffer cleanup Benoit Parrot
                   ` (11 subsequent siblings)
  34 siblings, 0 replies; 36+ messages in thread
From: Benoit Parrot @ 2016-11-18 23:20 UTC (permalink / raw)
  To: linux-media, Hans Verkuil
  Cc: linux-kernel, Tomi Valkeinen, Jyri Sarha, Peter Ujfalusi, Benoit Parrot

From: Nikhil Devshatwar <nikhil.nd@ti.com>

Current scaler library implementation of sc_set_hs_coeffs and
sc_set_vs_coeffs tries to return immediately if the calculated
coefficient index is already being used.

As the same scaler block is going to be used for all the VPE contexts,
even if the calculated index is same, the parameters have to be
reconfigured for each of the context.

Because of this, when multiple contexts use the same coefficients,
all other contexts would have zero scaling coefficients.
Fix this and also remove the unnecessary hs_index and vs_index fields.

Signed-off-by: Nikhil Devshatwar <nikhil.nd@ti.com>
Signed-off-by: Benoit Parrot <bparrot@ti.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/platform/ti-vpe/sc.c | 9 ---------
 drivers/media/platform/ti-vpe/sc.h | 3 ---
 2 files changed, 12 deletions(-)

diff --git a/drivers/media/platform/ti-vpe/sc.c b/drivers/media/platform/ti-vpe/sc.c
index f82d1c7f667f..02f3dae8ae42 100644
--- a/drivers/media/platform/ti-vpe/sc.c
+++ b/drivers/media/platform/ti-vpe/sc.c
@@ -84,9 +84,6 @@ void sc_set_hs_coeffs(struct sc_data *sc, void *addr, unsigned int src_w,
 		}
 	}
 
-	if (idx == sc->hs_index)
-		return;
-
 	cp = scaler_hs_coeffs[idx];
 
 	for (i = 0; i < SC_NUM_PHASES * 2; i++) {
@@ -101,8 +98,6 @@ void sc_set_hs_coeffs(struct sc_data *sc, void *addr, unsigned int src_w,
 		coeff_h += SC_NUM_TAPS_MEM_ALIGN - SC_H_NUM_TAPS;
 	}
 
-	sc->hs_index = idx;
-
 	sc->load_coeff_h = true;
 }
 
@@ -130,9 +125,6 @@ void sc_set_vs_coeffs(struct sc_data *sc, void *addr, unsigned int src_h,
 		idx = VS_LT_9_16_SCALE + sixteenths - 8;
 	}
 
-	if (idx == sc->vs_index)
-		return;
-
 	cp = scaler_vs_coeffs[idx];
 
 	for (i = 0; i < SC_NUM_PHASES * 2; i++) {
@@ -146,7 +138,6 @@ void sc_set_vs_coeffs(struct sc_data *sc, void *addr, unsigned int src_h,
 		coeff_v += SC_NUM_TAPS_MEM_ALIGN - SC_V_NUM_TAPS;
 	}
 
-	sc->vs_index = idx;
 	sc->load_coeff_v = true;
 }
 
diff --git a/drivers/media/platform/ti-vpe/sc.h b/drivers/media/platform/ti-vpe/sc.h
index 60e411e05c30..de947db98990 100644
--- a/drivers/media/platform/ti-vpe/sc.h
+++ b/drivers/media/platform/ti-vpe/sc.h
@@ -189,9 +189,6 @@ struct sc_data {
 	bool			load_coeff_h;	/* have new h SC coeffs */
 	bool			load_coeff_v;	/* have new v SC coeffs */
 
-	unsigned int		hs_index;	/* h SC coeffs selector */
-	unsigned int		vs_index;	/* v SC coeffs selector */
-
 	struct platform_device *pdev;
 };
 
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Patch v2 24/35] media: ti-vpe: vpe: Fix vb2 buffer cleanup
  2016-11-18 23:20 [Patch v2 00/35] media: ti-vpe: fixes and enhancements Benoit Parrot
                   ` (22 preceding siblings ...)
  2016-11-18 23:20 ` [Patch v2 23/35] media: ti-vpe: sc: Fix incorrect optimization Benoit Parrot
@ 2016-11-18 23:20 ` Benoit Parrot
  2016-11-18 23:20 ` [Patch v2 25/35] media: ti-vpe: vpdma: Fix race condition for firmware loading Benoit Parrot
                   ` (10 subsequent siblings)
  34 siblings, 0 replies; 36+ messages in thread
From: Benoit Parrot @ 2016-11-18 23:20 UTC (permalink / raw)
  To: linux-media, Hans Verkuil
  Cc: linux-kernel, Tomi Valkeinen, Jyri Sarha, Peter Ujfalusi, Benoit Parrot

When stop_streaming is called we need to cleanup the queued
vb2 buffers properly.
This was not previously being done which caused kernel
warning when the application using the resources was killed.
Kernel warnings were also generated on successful completion
of a de-interlacing case as well as upon aborting a
conversion.

Make sure every vb2 buffers is properly handled in all cases.

Signed-off-by: Benoit Parrot <bparrot@ti.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/platform/ti-vpe/vpe.c | 62 +++++++++++++++++++++++++++++++++++--
 1 file changed, 60 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c
index ef55fb45d0be..f92ad7a473c1 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -605,7 +605,10 @@ static void free_vbs(struct vpe_ctx *ctx)
 	spin_lock_irqsave(&dev->lock, flags);
 	if (ctx->src_vbs[2]) {
 		v4l2_m2m_buf_done(ctx->src_vbs[2], VB2_BUF_STATE_DONE);
-		v4l2_m2m_buf_done(ctx->src_vbs[1], VB2_BUF_STATE_DONE);
+		if (ctx->src_vbs[1] && (ctx->src_vbs[1] != ctx->src_vbs[2]))
+			v4l2_m2m_buf_done(ctx->src_vbs[1], VB2_BUF_STATE_DONE);
+		ctx->src_vbs[2] = NULL;
+		ctx->src_vbs[1] = NULL;
 	}
 	spin_unlock_irqrestore(&dev->lock, flags);
 }
@@ -1443,6 +1446,14 @@ static irqreturn_t vpe_irq(int irq_vpe, void *data)
 		ctx->src_vbs[1] = ctx->src_vbs[0];
 	}
 
+	/*
+	 * Since the vb2_buf_done has already been called fir therse
+	 * buffer we can now NULL them out so that we won't try
+	 * to clean out stray pointer later on.
+	*/
+	ctx->src_vbs[0] = NULL;
+	ctx->dst_vb = NULL;
+
 	ctx->bufs_completed++;
 	if (ctx->bufs_completed < ctx->bufs_per_job && job_ready(ctx)) {
 		device_run(ctx);
@@ -2027,9 +2038,57 @@ static int vpe_start_streaming(struct vb2_queue *q, unsigned int count)
 static void vpe_stop_streaming(struct vb2_queue *q)
 {
 	struct vpe_ctx *ctx = vb2_get_drv_priv(q);
+	struct vb2_v4l2_buffer *vb;
+	unsigned long flags;
 
 	vpe_dump_regs(ctx->dev);
 	vpdma_dump_regs(ctx->dev->vpdma);
+
+	for (;;) {
+		if (V4L2_TYPE_IS_OUTPUT(q->type))
+			vb = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
+		else
+			vb = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
+		if (!vb)
+			break;
+		spin_lock_irqsave(&ctx->dev->lock, flags);
+		v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR);
+		spin_unlock_irqrestore(&ctx->dev->lock, flags);
+	}
+
+	/*
+	 * Cleanup the in-transit vb2 buffers that have been
+	 * removed from their respective queue already but for
+	 * which procecessing has not been completed yet.
+	 */
+	if (V4L2_TYPE_IS_OUTPUT(q->type)) {
+		spin_lock_irqsave(&ctx->dev->lock, flags);
+
+		if (ctx->src_vbs[2])
+			v4l2_m2m_buf_done(ctx->src_vbs[2], VB2_BUF_STATE_ERROR);
+
+		if (ctx->src_vbs[1] && (ctx->src_vbs[1] != ctx->src_vbs[2]))
+			v4l2_m2m_buf_done(ctx->src_vbs[1], VB2_BUF_STATE_ERROR);
+
+		if (ctx->src_vbs[0] &&
+		    (ctx->src_vbs[0] != ctx->src_vbs[1]) &&
+		    (ctx->src_vbs[0] != ctx->src_vbs[2]))
+			v4l2_m2m_buf_done(ctx->src_vbs[0], VB2_BUF_STATE_ERROR);
+
+		ctx->src_vbs[2] = NULL;
+		ctx->src_vbs[1] = NULL;
+		ctx->src_vbs[0] = NULL;
+
+		spin_unlock_irqrestore(&ctx->dev->lock, flags);
+	} else {
+		if (ctx->dst_vb) {
+			spin_lock_irqsave(&ctx->dev->lock, flags);
+
+			v4l2_m2m_buf_done(ctx->dst_vb, VB2_BUF_STATE_ERROR);
+			ctx->dst_vb = NULL;
+			spin_unlock_irqrestore(&ctx->dev->lock, flags);
+		}
+	}
 }
 
 static const struct vb2_ops vpe_qops = {
@@ -2222,7 +2281,6 @@ static int vpe_release(struct file *file)
 	vpe_dbg(dev, "releasing instance %p\n", ctx);
 
 	mutex_lock(&dev->dev_mutex);
-	free_vbs(ctx);
 	free_mv_buffers(ctx);
 	vpdma_free_desc_list(&ctx->desc_list);
 	vpdma_free_desc_buf(&ctx->mmr_adb);
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Patch v2 25/35] media: ti-vpe: vpdma: Fix race condition for firmware loading
  2016-11-18 23:20 [Patch v2 00/35] media: ti-vpe: fixes and enhancements Benoit Parrot
                   ` (23 preceding siblings ...)
  2016-11-18 23:20 ` [Patch v2 24/35] media: ti-vpe: vpe: Fix vb2 buffer cleanup Benoit Parrot
@ 2016-11-18 23:20 ` Benoit Parrot
  2016-11-18 23:20 ` [Patch v2 26/35] media: ti-vpe: vpdma: Use bidirectional cached buffers Benoit Parrot
                   ` (9 subsequent siblings)
  34 siblings, 0 replies; 36+ messages in thread
From: Benoit Parrot @ 2016-11-18 23:20 UTC (permalink / raw)
  To: linux-media, Hans Verkuil
  Cc: linux-kernel, Tomi Valkeinen, Jyri Sarha, Peter Ujfalusi, Benoit Parrot

From: Nikhil Devshatwar <nikhil.nd@ti.com>

vpdma_create API is supposed to allocated the struct vpdma_data and
return it to the driver. Also, it would call the callback function
when the VPDMA firmware is loaded.

Typically, VPE driver have following function call:
    dev->vpdma = vpdma_create(pdev, firmware_load_callback);
And the callback implementation would continue the probe further.
Also, the dev->vpdma is accessed from the callback implementation.

This may lead to race condition between assignment of dev->vpdma
and the callback function being triggered.
This would lead to kernel crash because of NULL pointer access.

Fix this by passing a driver wrapped &vpdma_data instead of allocating
inside vpdma_create.
Change the vpdma_create prototype accordingly and fix return paths.

Also, update the VPE driver to use the updated API and
initialize the dev->vpdma before hand so that the race condition
is avoided.

Signed-off-by: Nikhil Devshatwar <nikhil.nd@ti.com>
Signed-off-by: Benoit Parrot <bparrot@ti.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/platform/ti-vpe/vpdma.c | 17 +++++------------
 drivers/media/platform/ti-vpe/vpdma.h |  2 +-
 drivers/media/platform/ti-vpe/vpe.c   |  8 ++++----
 3 files changed, 10 insertions(+), 17 deletions(-)

diff --git a/drivers/media/platform/ti-vpe/vpdma.c b/drivers/media/platform/ti-vpe/vpdma.c
index 8f0d608c70f6..070937fe1af6 100644
--- a/drivers/media/platform/ti-vpe/vpdma.c
+++ b/drivers/media/platform/ti-vpe/vpdma.c
@@ -1130,21 +1130,14 @@ static int vpdma_load_firmware(struct vpdma_data *vpdma)
 	return 0;
 }
 
-struct vpdma_data *vpdma_create(struct platform_device *pdev,
+int vpdma_create(struct platform_device *pdev, struct vpdma_data *vpdma,
 		void (*cb)(struct platform_device *pdev))
 {
 	struct resource *res;
-	struct vpdma_data *vpdma;
 	int r;
 
 	dev_dbg(&pdev->dev, "vpdma_create\n");
 
-	vpdma = devm_kzalloc(&pdev->dev, sizeof(*vpdma), GFP_KERNEL);
-	if (!vpdma) {
-		dev_err(&pdev->dev, "couldn't alloc vpdma_dev\n");
-		return ERR_PTR(-ENOMEM);
-	}
-
 	vpdma->pdev = pdev;
 	vpdma->cb = cb;
 	spin_lock_init(&vpdma->lock);
@@ -1152,22 +1145,22 @@ struct vpdma_data *vpdma_create(struct platform_device *pdev,
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vpdma");
 	if (res == NULL) {
 		dev_err(&pdev->dev, "missing platform resources data\n");
-		return ERR_PTR(-ENODEV);
+		return -ENODEV;
 	}
 
 	vpdma->base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
 	if (!vpdma->base) {
 		dev_err(&pdev->dev, "failed to ioremap\n");
-		return ERR_PTR(-ENOMEM);
+		return -ENOMEM;
 	}
 
 	r = vpdma_load_firmware(vpdma);
 	if (r) {
 		pr_err("failed to load firmware %s\n", VPDMA_FIRMWARE);
-		return ERR_PTR(r);
+		return r;
 	}
 
-	return vpdma;
+	return 0;
 }
 EXPORT_SYMBOL(vpdma_create);
 
diff --git a/drivers/media/platform/ti-vpe/vpdma.h b/drivers/media/platform/ti-vpe/vpdma.h
index 405a6febc254..0df156b7c1cf 100644
--- a/drivers/media/platform/ti-vpe/vpdma.h
+++ b/drivers/media/platform/ti-vpe/vpdma.h
@@ -273,7 +273,7 @@ void vpdma_set_bg_color(struct vpdma_data *vpdma,
 void vpdma_dump_regs(struct vpdma_data *vpdma);
 
 /* initialize vpdma, passed with VPE's platform device pointer */
-struct vpdma_data *vpdma_create(struct platform_device *pdev,
+int vpdma_create(struct platform_device *pdev, struct vpdma_data *vpdma,
 		void (*cb)(struct platform_device *pdev));
 
 #endif
diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c
index f92ad7a473c1..15e846b95719 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -383,6 +383,7 @@ struct vpe_dev {
 	void __iomem		*base;
 	struct resource		*res;
 
+	struct vpdma_data	vpdma_data;
 	struct vpdma_data	*vpdma;		/* vpdma data handle */
 	struct sc_data		*sc;		/* scaler data handle */
 	struct csc_data		*csc;		/* csc data handle */
@@ -2462,11 +2463,10 @@ static int vpe_probe(struct platform_device *pdev)
 		goto runtime_put;
 	}
 
-	dev->vpdma = vpdma_create(pdev, vpe_fw_cb);
-	if (IS_ERR(dev->vpdma)) {
-		ret = PTR_ERR(dev->vpdma);
+	dev->vpdma = &dev->vpdma_data;
+	ret = vpdma_create(pdev, dev->vpdma, vpe_fw_cb);
+	if (ret)
 		goto runtime_put;
-	}
 
 	return 0;
 
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Patch v2 26/35] media: ti-vpe: vpdma: Use bidirectional cached buffers
  2016-11-18 23:20 [Patch v2 00/35] media: ti-vpe: fixes and enhancements Benoit Parrot
                   ` (24 preceding siblings ...)
  2016-11-18 23:20 ` [Patch v2 25/35] media: ti-vpe: vpdma: Fix race condition for firmware loading Benoit Parrot
@ 2016-11-18 23:20 ` Benoit Parrot
  2016-11-18 23:20 ` [Patch v2 27/35] media: ti-vpe: vpe: Fix line stride for output motion vector Benoit Parrot
                   ` (8 subsequent siblings)
  34 siblings, 0 replies; 36+ messages in thread
From: Benoit Parrot @ 2016-11-18 23:20 UTC (permalink / raw)
  To: linux-media, Hans Verkuil
  Cc: linux-kernel, Tomi Valkeinen, Jyri Sarha, Peter Ujfalusi, Benoit Parrot

From: Nikhil Devshatwar <nikhil.nd@ti.com>

VPDMA buffer will be used by CPU as well as by the VPDMA.
CPU will write/update the VPDMA descriptors containing data
about the video buffer DMA addresses.
VPDMA will write the "write descriptor" containing the
data about the DMA operation.

When mapping/unmapping the buffer, driver has to take care of
WriteBack and invalidation of the cache so that all the
coherency is maintained from both directions.

Use DMA_BIDIRECTIONAL to maintain coherency between CPU and VPDMA.

Signed-off-by: Nikhil Devshatwar <nikhil.nd@ti.com>
Signed-off-by: Benoit Parrot <bparrot@ti.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/platform/ti-vpe/vpdma.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/ti-vpe/vpdma.c b/drivers/media/platform/ti-vpe/vpdma.c
index 070937fe1af6..2d13644a28a8 100644
--- a/drivers/media/platform/ti-vpe/vpdma.c
+++ b/drivers/media/platform/ti-vpe/vpdma.c
@@ -367,7 +367,7 @@ int vpdma_map_desc_buf(struct vpdma_data *vpdma, struct vpdma_buf *buf)
 
 	WARN_ON(buf->mapped);
 	buf->dma_addr = dma_map_single(dev, buf->addr, buf->size,
-				DMA_TO_DEVICE);
+				DMA_BIDIRECTIONAL);
 	if (dma_mapping_error(dev, buf->dma_addr)) {
 		dev_err(dev, "failed to map buffer\n");
 		return -EINVAL;
@@ -388,7 +388,8 @@ void vpdma_unmap_desc_buf(struct vpdma_data *vpdma, struct vpdma_buf *buf)
 	struct device *dev = &vpdma->pdev->dev;
 
 	if (buf->mapped)
-		dma_unmap_single(dev, buf->dma_addr, buf->size, DMA_TO_DEVICE);
+		dma_unmap_single(dev, buf->dma_addr, buf->size,
+				DMA_BIDIRECTIONAL);
 
 	buf->mapped = false;
 }
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Patch v2 27/35] media: ti-vpe: vpe: Fix line stride for output motion vector
  2016-11-18 23:20 [Patch v2 00/35] media: ti-vpe: fixes and enhancements Benoit Parrot
                   ` (25 preceding siblings ...)
  2016-11-18 23:20 ` [Patch v2 26/35] media: ti-vpe: vpdma: Use bidirectional cached buffers Benoit Parrot
@ 2016-11-18 23:20 ` Benoit Parrot
  2016-11-18 23:20 ` [Patch v2 28/35] media: ti-vpe: vpe: Enable DMABUF export Benoit Parrot
                   ` (7 subsequent siblings)
  34 siblings, 0 replies; 36+ messages in thread
From: Benoit Parrot @ 2016-11-18 23:20 UTC (permalink / raw)
  To: linux-media, Hans Verkuil
  Cc: linux-kernel, Tomi Valkeinen, Jyri Sarha, Peter Ujfalusi, Benoit Parrot

From: Nikhil Devshatwar <nikhil.nd@ti.com>

For deinterlacing operation, VPE hardware uses motion vectors.
MV calculated in the previous iteration are used for next interation.
Therefore driver allocates two motion vectors in ping-pong fashion.

For every transaction, one MV is DMAed in and one is DMAed out.
All the outbound DMAs (DMA to memory) use output parameters, but as
the motion vectors is generated purely out of input fields, it should
use the input parameters for DMA.

Fix the add_out_dtd to use source q_data for creating descriptor.
If the output size is greater than input stride, without this change,
MV DMA may overwrite the buffer causing memory corruption.

This CRITICAL fix ensures that the motion vector DMA descriptor is
created based on the attributes with which the buffer was allocated.

Signed-off-by: Nikhil Devshatwar <nikhil.nd@ti.com>
Signed-off-by: Ravikumar Kattekola <rk@ti.com>
Signed-off-by: Ravi Babu <ravibabu@ti.com>
Signed-off-by: Benoit Parrot <bparrot@ti.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/platform/ti-vpe/vpe.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c
index 15e846b95719..608d11344147 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -1046,6 +1046,7 @@ static void add_out_dtd(struct vpe_ctx *ctx, int port)
 	if (port == VPE_PORT_MV_OUT) {
 		vpdma_fmt = &vpdma_misc_fmts[VPDMA_DATA_FMT_MV];
 		dma_addr = ctx->mv_buf_dma[mv_buf_selector];
+		q_data = &ctx->q_data[Q_DATA_SRC];
 	} else {
 		/* to incorporate interleaved formats */
 		int plane = fmt->coplanar ? p_data->vb_part : 0;
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Patch v2 28/35] media: ti-vpe: vpe: Enable DMABUF export
  2016-11-18 23:20 [Patch v2 00/35] media: ti-vpe: fixes and enhancements Benoit Parrot
                   ` (26 preceding siblings ...)
  2016-11-18 23:20 ` [Patch v2 27/35] media: ti-vpe: vpe: Fix line stride for output motion vector Benoit Parrot
@ 2016-11-18 23:20 ` Benoit Parrot
  2016-11-18 23:20 ` [Patch v2 29/35] media: ti-vpe: Make scaler library into its own module Benoit Parrot
                   ` (6 subsequent siblings)
  34 siblings, 0 replies; 36+ messages in thread
From: Benoit Parrot @ 2016-11-18 23:20 UTC (permalink / raw)
  To: linux-media, Hans Verkuil
  Cc: linux-kernel, Tomi Valkeinen, Jyri Sarha, Peter Ujfalusi, Benoit Parrot

Allow VPE to be able to export DMA buffer.

Signed-off-by: Benoit Parrot <bparrot@ti.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/platform/ti-vpe/vpe.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c
index 608d11344147..1d780ac7ff82 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -1944,6 +1944,7 @@ static const struct v4l2_ioctl_ops vpe_ioctl_ops = {
 	.vidioc_querybuf		= v4l2_m2m_ioctl_querybuf,
 	.vidioc_qbuf			= v4l2_m2m_ioctl_qbuf,
 	.vidioc_dqbuf			= v4l2_m2m_ioctl_dqbuf,
+	.vidioc_expbuf			= v4l2_m2m_ioctl_expbuf,
 	.vidioc_streamon		= v4l2_m2m_ioctl_streamon,
 	.vidioc_streamoff		= v4l2_m2m_ioctl_streamoff,
 
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Patch v2 29/35] media: ti-vpe: Make scaler library into its own module
  2016-11-18 23:20 [Patch v2 00/35] media: ti-vpe: fixes and enhancements Benoit Parrot
                   ` (27 preceding siblings ...)
  2016-11-18 23:20 ` [Patch v2 28/35] media: ti-vpe: vpe: Enable DMABUF export Benoit Parrot
@ 2016-11-18 23:20 ` Benoit Parrot
  2016-11-18 23:20 ` [Patch v2 30/35] media: ti-vpe: scaler: Add debug support for multi-instance Benoit Parrot
                   ` (5 subsequent siblings)
  34 siblings, 0 replies; 36+ messages in thread
From: Benoit Parrot @ 2016-11-18 23:20 UTC (permalink / raw)
  To: linux-media, Hans Verkuil
  Cc: linux-kernel, Tomi Valkeinen, Jyri Sarha, Peter Ujfalusi, Benoit Parrot

In preparation to add scaler support into VIP we need to
turn sc.c into its own kernel module.

Add support for multiple SC memory block as VIP contains
2 scaler instances.
This is done by passing the resource name to sc_create() and
modify the vpe invocation accordingly.

Signed-off-by: Benoit Parrot <bparrot@ti.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/platform/Kconfig         |  4 ++++
 drivers/media/platform/ti-vpe/Makefile |  4 +++-
 drivers/media/platform/ti-vpe/sc.c     | 17 ++++++++++++++---
 drivers/media/platform/ti-vpe/sc.h     |  2 +-
 drivers/media/platform/ti-vpe/vpe.c    |  2 +-
 5 files changed, 23 insertions(+), 6 deletions(-)

diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index b52b6771fc4d..5d7befad90e0 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -365,6 +365,7 @@ config VIDEO_TI_VPE
 	select VIDEOBUF2_DMA_CONTIG
 	select V4L2_MEM2MEM_DEV
 	select VIDEO_TI_VPDMA
+	select VIDEO_TI_SC
 	default n
 	---help---
 	  Support for the TI VPE(Video Processing Engine) block
@@ -383,6 +384,9 @@ endif # V4L_MEM2MEM_DRIVERS
 config VIDEO_TI_VPDMA
 	tristate
 
+config VIDEO_TI_SC
+	tristate
+
 menuconfig V4L_TEST_DRIVERS
 	bool "Media test drivers"
 	depends on MEDIA_CAMERA_SUPPORT
diff --git a/drivers/media/platform/ti-vpe/Makefile b/drivers/media/platform/ti-vpe/Makefile
index faca5e115c1d..736558d309ad 100644
--- a/drivers/media/platform/ti-vpe/Makefile
+++ b/drivers/media/platform/ti-vpe/Makefile
@@ -1,8 +1,10 @@
 obj-$(CONFIG_VIDEO_TI_VPE) += ti-vpe.o
 obj-$(CONFIG_VIDEO_TI_VPDMA) += ti-vpdma.o
+obj-$(CONFIG_VIDEO_TI_SC) += ti-sc.o
 
-ti-vpe-y := vpe.o sc.o csc.o
+ti-vpe-y := vpe.o csc.o
 ti-vpdma-y := vpdma.o
+ti-sc-y := sc.o
 
 ccflags-$(CONFIG_VIDEO_TI_VPE_DEBUG) += -DDEBUG
 
diff --git a/drivers/media/platform/ti-vpe/sc.c b/drivers/media/platform/ti-vpe/sc.c
index 02f3dae8ae42..52ce1450362f 100644
--- a/drivers/media/platform/ti-vpe/sc.c
+++ b/drivers/media/platform/ti-vpe/sc.c
@@ -14,6 +14,7 @@
 
 #include <linux/err.h>
 #include <linux/io.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 
@@ -52,6 +53,7 @@ void sc_dump_regs(struct sc_data *sc)
 
 #undef DUMPREG
 }
+EXPORT_SYMBOL(sc_dump_regs);
 
 /*
  * set the horizontal scaler coefficients according to the ratio of output to
@@ -100,6 +102,7 @@ void sc_set_hs_coeffs(struct sc_data *sc, void *addr, unsigned int src_w,
 
 	sc->load_coeff_h = true;
 }
+EXPORT_SYMBOL(sc_set_hs_coeffs);
 
 /*
  * set the vertical scaler coefficients according to the ratio of output to
@@ -140,6 +143,7 @@ void sc_set_vs_coeffs(struct sc_data *sc, void *addr, unsigned int src_h,
 
 	sc->load_coeff_v = true;
 }
+EXPORT_SYMBOL(sc_set_vs_coeffs);
 
 void sc_config_scaler(struct sc_data *sc, u32 *sc_reg0, u32 *sc_reg8,
 		u32 *sc_reg17, unsigned int src_w, unsigned int src_h,
@@ -267,8 +271,9 @@ void sc_config_scaler(struct sc_data *sc, u32 *sc_reg0, u32 *sc_reg8,
 
 	*sc_reg24 = (src_w << CFG_ORG_W_SHIFT) | (src_h << CFG_ORG_H_SHIFT);
 }
+EXPORT_SYMBOL(sc_config_scaler);
 
-struct sc_data *sc_create(struct platform_device *pdev)
+struct sc_data *sc_create(struct platform_device *pdev, const char *res_name)
 {
 	struct sc_data *sc;
 
@@ -282,9 +287,10 @@ struct sc_data *sc_create(struct platform_device *pdev)
 
 	sc->pdev = pdev;
 
-	sc->res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sc");
+	sc->res = platform_get_resource_byname(pdev, IORESOURCE_MEM, res_name);
 	if (!sc->res) {
-		dev_err(&pdev->dev, "missing platform resources data\n");
+		dev_err(&pdev->dev, "missing '%s' platform resources data\n",
+			res_name);
 		return ERR_PTR(-ENODEV);
 	}
 
@@ -296,3 +302,8 @@ struct sc_data *sc_create(struct platform_device *pdev)
 
 	return sc;
 }
+EXPORT_SYMBOL(sc_create);
+
+MODULE_DESCRIPTION("TI VIP/VPE Scaler");
+MODULE_AUTHOR("Texas Instruments Inc.");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/ti-vpe/sc.h b/drivers/media/platform/ti-vpe/sc.h
index de947db98990..d0aab5ef0eca 100644
--- a/drivers/media/platform/ti-vpe/sc.h
+++ b/drivers/media/platform/ti-vpe/sc.h
@@ -200,6 +200,6 @@ void sc_set_vs_coeffs(struct sc_data *sc, void *addr, unsigned int src_h,
 void sc_config_scaler(struct sc_data *sc, u32 *sc_reg0, u32 *sc_reg8,
 		u32 *sc_reg17, unsigned int src_w, unsigned int src_h,
 		unsigned int dst_w, unsigned int dst_h);
-struct sc_data *sc_create(struct platform_device *pdev);
+struct sc_data *sc_create(struct platform_device *pdev, const char *res_name);
 
 #endif
diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c
index 1d780ac7ff82..ebde4f4586e6 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -2453,7 +2453,7 @@ static int vpe_probe(struct platform_device *pdev)
 
 	vpe_top_vpdma_reset(dev);
 
-	dev->sc = sc_create(pdev);
+	dev->sc = sc_create(pdev, "sc");
 	if (IS_ERR(dev->sc)) {
 		ret = PTR_ERR(dev->sc);
 		goto runtime_put;
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Patch v2 30/35] media: ti-vpe: scaler: Add debug support for multi-instance
  2016-11-18 23:20 [Patch v2 00/35] media: ti-vpe: fixes and enhancements Benoit Parrot
                   ` (28 preceding siblings ...)
  2016-11-18 23:20 ` [Patch v2 29/35] media: ti-vpe: Make scaler library into its own module Benoit Parrot
@ 2016-11-18 23:20 ` Benoit Parrot
  2016-11-18 23:20 ` [Patch v2 31/35] media: ti-vpe: vpe: Make sure frame size dont exceed scaler capacity Benoit Parrot
                   ` (4 subsequent siblings)
  34 siblings, 0 replies; 36+ messages in thread
From: Benoit Parrot @ 2016-11-18 23:20 UTC (permalink / raw)
  To: linux-media, Hans Verkuil
  Cc: linux-kernel, Tomi Valkeinen, Jyri Sarha, Peter Ujfalusi, Benoit Parrot

Since there might be more then one instance it is better to
show the base address when dumping registers to help
with debugging.

Signed-off-by: Benoit Parrot <bparrot@ti.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/platform/ti-vpe/sc.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/media/platform/ti-vpe/sc.c b/drivers/media/platform/ti-vpe/sc.c
index 52ce1450362f..e9273b713782 100644
--- a/drivers/media/platform/ti-vpe/sc.c
+++ b/drivers/media/platform/ti-vpe/sc.c
@@ -28,6 +28,8 @@ void sc_dump_regs(struct sc_data *sc)
 #define DUMPREG(r) dev_dbg(dev, "%-35s %08x\n", #r, \
 	ioread32(sc->base + CFG_##r))
 
+	dev_dbg(dev, "SC Registers @ %pa:\n", &sc->res->start);
+
 	DUMPREG(SC0);
 	DUMPREG(SC1);
 	DUMPREG(SC2);
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Patch v2 31/35] media: ti-vpe: vpe: Make sure frame size dont exceed scaler capacity
  2016-11-18 23:20 [Patch v2 00/35] media: ti-vpe: fixes and enhancements Benoit Parrot
                   ` (29 preceding siblings ...)
  2016-11-18 23:20 ` [Patch v2 30/35] media: ti-vpe: scaler: Add debug support for multi-instance Benoit Parrot
@ 2016-11-18 23:20 ` Benoit Parrot
  2016-11-18 23:20 ` [Patch v2 32/35] media: ti-vpe: vpdma: Add RAW8 and RAW16 data types Benoit Parrot
                   ` (3 subsequent siblings)
  34 siblings, 0 replies; 36+ messages in thread
From: Benoit Parrot @ 2016-11-18 23:20 UTC (permalink / raw)
  To: linux-media, Hans Verkuil
  Cc: linux-kernel, Tomi Valkeinen, Jyri Sarha, Peter Ujfalusi, Benoit Parrot

When scaler is to be used we need to make sure that the input and
output frame size do not exceed the maximum frame sizes that the
scaler h/w can handle otherwise streaming stall as the scaler
cannot proceed.

The scaler buffer is limited to 2047 pixels (i.e. 11 bits) when
attempting anything larger (2048 for example) the scaler stalls.

Realistically in an mem2mem device we can only check for this type
of issue when start_streaming is called. We can't do it during the
try_fmt/s_fmt because we do not have all of the info needed at that
point. So instead when start_streaming is called we need to check
that the input and output frames size do not exceed the scaler's
capability. The only time larger frame size are allowed is when
the input frame szie is the same as the output frame size.

Now in the case where we need to fail, start_streaming must return
all previously queued buffer back otherwise the vb2 framework
will issue kernel WARN messages.
In this case we also give an error message.

Signed-off-by: Benoit Parrot <bparrot@ti.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/platform/ti-vpe/sc.h  |  6 ++++
 drivers/media/platform/ti-vpe/vpe.c | 71 ++++++++++++++++++++++++++++---------
 2 files changed, 60 insertions(+), 17 deletions(-)

diff --git a/drivers/media/platform/ti-vpe/sc.h b/drivers/media/platform/ti-vpe/sc.h
index d0aab5ef0eca..f1fe80b38c9f 100644
--- a/drivers/media/platform/ti-vpe/sc.h
+++ b/drivers/media/platform/ti-vpe/sc.h
@@ -173,6 +173,12 @@
 /* number of taps expected by the scaler in it's coefficient memory */
 #define SC_NUM_TAPS_MEM_ALIGN		8
 
+/* Maximum frame width the scaler can handle (in pixels) */
+#define SC_MAX_PIXEL_WIDTH		2047
+
+/* Maximum frame height the scaler can handle (in lines) */
+#define SC_MAX_PIXEL_HEIGHT		2047
+
 /*
  * coefficient memory size in bytes:
  * num phases x num sets(luma and chroma) x num taps(aligned) x coeff size
diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c
index ebde4f4586e6..32489d6369ca 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -2025,28 +2025,33 @@ static void vpe_buf_queue(struct vb2_buffer *vb)
 	v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
 }
 
-static int vpe_start_streaming(struct vb2_queue *q, unsigned int count)
+static int check_srcdst_sizes(struct vpe_ctx *ctx)
 {
-	struct vpe_ctx *ctx = vb2_get_drv_priv(q);
+	struct vpe_q_data *s_q_data =  &ctx->q_data[Q_DATA_SRC];
+	struct vpe_q_data *d_q_data =  &ctx->q_data[Q_DATA_DST];
+	unsigned int src_w = s_q_data->c_rect.width;
+	unsigned int src_h = s_q_data->c_rect.height;
+	unsigned int dst_w = d_q_data->c_rect.width;
+	unsigned int dst_h = d_q_data->c_rect.height;
 
-	if (ctx->deinterlacing)
-		config_edi_input_mode(ctx, 0x0);
+	if (src_w == dst_w && src_h == dst_h)
+		return 0;
 
-	if (ctx->sequence != 0)
-		set_srcdst_params(ctx);
+	if (src_h <= SC_MAX_PIXEL_HEIGHT &&
+	    src_w <= SC_MAX_PIXEL_WIDTH &&
+	    dst_h <= SC_MAX_PIXEL_HEIGHT &&
+	    dst_w <= SC_MAX_PIXEL_WIDTH)
+		return 0;
 
-	return 0;
+	return -1;
 }
 
-static void vpe_stop_streaming(struct vb2_queue *q)
+static void vpe_return_all_buffers(struct vpe_ctx *ctx,  struct vb2_queue *q,
+				   enum vb2_buffer_state state)
 {
-	struct vpe_ctx *ctx = vb2_get_drv_priv(q);
 	struct vb2_v4l2_buffer *vb;
 	unsigned long flags;
 
-	vpe_dump_regs(ctx->dev);
-	vpdma_dump_regs(ctx->dev->vpdma);
-
 	for (;;) {
 		if (V4L2_TYPE_IS_OUTPUT(q->type))
 			vb = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
@@ -2055,7 +2060,7 @@ static void vpe_stop_streaming(struct vb2_queue *q)
 		if (!vb)
 			break;
 		spin_lock_irqsave(&ctx->dev->lock, flags);
-		v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR);
+		v4l2_m2m_buf_done(vb, state);
 		spin_unlock_irqrestore(&ctx->dev->lock, flags);
 	}
 
@@ -2068,15 +2073,15 @@ static void vpe_stop_streaming(struct vb2_queue *q)
 		spin_lock_irqsave(&ctx->dev->lock, flags);
 
 		if (ctx->src_vbs[2])
-			v4l2_m2m_buf_done(ctx->src_vbs[2], VB2_BUF_STATE_ERROR);
+			v4l2_m2m_buf_done(ctx->src_vbs[2], state);
 
 		if (ctx->src_vbs[1] && (ctx->src_vbs[1] != ctx->src_vbs[2]))
-			v4l2_m2m_buf_done(ctx->src_vbs[1], VB2_BUF_STATE_ERROR);
+			v4l2_m2m_buf_done(ctx->src_vbs[1], state);
 
 		if (ctx->src_vbs[0] &&
 		    (ctx->src_vbs[0] != ctx->src_vbs[1]) &&
 		    (ctx->src_vbs[0] != ctx->src_vbs[2]))
-			v4l2_m2m_buf_done(ctx->src_vbs[0], VB2_BUF_STATE_ERROR);
+			v4l2_m2m_buf_done(ctx->src_vbs[0], state);
 
 		ctx->src_vbs[2] = NULL;
 		ctx->src_vbs[1] = NULL;
@@ -2087,13 +2092,45 @@ static void vpe_stop_streaming(struct vb2_queue *q)
 		if (ctx->dst_vb) {
 			spin_lock_irqsave(&ctx->dev->lock, flags);
 
-			v4l2_m2m_buf_done(ctx->dst_vb, VB2_BUF_STATE_ERROR);
+			v4l2_m2m_buf_done(ctx->dst_vb, state);
 			ctx->dst_vb = NULL;
 			spin_unlock_irqrestore(&ctx->dev->lock, flags);
 		}
 	}
 }
 
+static int vpe_start_streaming(struct vb2_queue *q, unsigned int count)
+{
+	struct vpe_ctx *ctx = vb2_get_drv_priv(q);
+
+	/* Check any of the size exceed maximum scaling sizes */
+	if (check_srcdst_sizes(ctx)) {
+		vpe_err(ctx->dev,
+			"Conversion setup failed, check source and destination parameters\n"
+			);
+		vpe_return_all_buffers(ctx, q, VB2_BUF_STATE_QUEUED);
+		return -EINVAL;
+	}
+
+	if (ctx->deinterlacing)
+		config_edi_input_mode(ctx, 0x0);
+
+	if (ctx->sequence != 0)
+		set_srcdst_params(ctx);
+
+	return 0;
+}
+
+static void vpe_stop_streaming(struct vb2_queue *q)
+{
+	struct vpe_ctx *ctx = vb2_get_drv_priv(q);
+
+	vpe_dump_regs(ctx->dev);
+	vpdma_dump_regs(ctx->dev->vpdma);
+
+	vpe_return_all_buffers(ctx, q, VB2_BUF_STATE_ERROR);
+}
+
 static const struct vb2_ops vpe_qops = {
 	.queue_setup	 = vpe_queue_setup,
 	.buf_prepare	 = vpe_buf_prepare,
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Patch v2 32/35] media: ti-vpe: vpdma: Add RAW8 and RAW16 data types
  2016-11-18 23:20 [Patch v2 00/35] media: ti-vpe: fixes and enhancements Benoit Parrot
                   ` (30 preceding siblings ...)
  2016-11-18 23:20 ` [Patch v2 31/35] media: ti-vpe: vpe: Make sure frame size dont exceed scaler capacity Benoit Parrot
@ 2016-11-18 23:20 ` Benoit Parrot
  2016-11-18 23:20 ` [Patch v2 33/35] media: ti-vpe: Make colorspace converter library into its own module Benoit Parrot
                   ` (2 subsequent siblings)
  34 siblings, 0 replies; 36+ messages in thread
From: Benoit Parrot @ 2016-11-18 23:20 UTC (permalink / raw)
  To: linux-media, Hans Verkuil
  Cc: linux-kernel, Tomi Valkeinen, Jyri Sarha, Peter Ujfalusi, Benoit Parrot

Add RAW8 and RAW16 data type to VPDMA.
To handle RAW format we are re-using the YUV CBY422
vpdma data type so that we use the vpdma to re-order
the incoming bytes, as the VIP parser assumes that the
first byte presented on the bus is the MSB of a 2
bytes value.

RAW8 handles from 1 to 8 bits.
RAW16 handles from 9 to 16 bits.

Signed-off-by: Benoit Parrot <bparrot@ti.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/platform/ti-vpe/vpdma.c | 23 +++++++++++++++++++++++
 drivers/media/platform/ti-vpe/vpdma.h |  6 ++++++
 2 files changed, 29 insertions(+)

diff --git a/drivers/media/platform/ti-vpe/vpdma.c b/drivers/media/platform/ti-vpe/vpdma.c
index 2d13644a28a8..c8f842fd7f75 100644
--- a/drivers/media/platform/ti-vpe/vpdma.c
+++ b/drivers/media/platform/ti-vpe/vpdma.c
@@ -191,6 +191,29 @@ const struct vpdma_data_format vpdma_rgb_fmts[] = {
 };
 EXPORT_SYMBOL(vpdma_rgb_fmts);
 
+/*
+ * To handle RAW format we are re-using the CBY422
+ * vpdma data type so that we use the vpdma to re-order
+ * the incoming bytes, as the parser assumes that the
+ * first byte presented on the bus is the MSB of a 2
+ * bytes value.
+ * RAW8 handles from 1 to 8 bits
+ * RAW16 handles from 9 to 16 bits
+ */
+const struct vpdma_data_format vpdma_raw_fmts[] = {
+	[VPDMA_DATA_FMT_RAW8] = {
+		.type		= VPDMA_DATA_FMT_TYPE_YUV,
+		.data_type	= DATA_TYPE_CBY422,
+		.depth		= 8,
+	},
+	[VPDMA_DATA_FMT_RAW16] = {
+		.type		= VPDMA_DATA_FMT_TYPE_YUV,
+		.data_type	= DATA_TYPE_CBY422,
+		.depth		= 16,
+	},
+};
+EXPORT_SYMBOL(vpdma_raw_fmts);
+
 const struct vpdma_data_format vpdma_misc_fmts[] = {
 	[VPDMA_DATA_FMT_MV] = {
 		.type		= VPDMA_DATA_FMT_TYPE_MISC,
diff --git a/drivers/media/platform/ti-vpe/vpdma.h b/drivers/media/platform/ti-vpe/vpdma.h
index 0df156b7c1cf..131700c112b2 100644
--- a/drivers/media/platform/ti-vpe/vpdma.h
+++ b/drivers/media/platform/ti-vpe/vpdma.h
@@ -104,12 +104,18 @@ enum vpdma_rgb_formats {
 	VPDMA_DATA_FMT_BGRA32,
 };
 
+enum vpdma_raw_formats {
+	VPDMA_DATA_FMT_RAW8 = 0,
+	VPDMA_DATA_FMT_RAW16,
+};
+
 enum vpdma_misc_formats {
 	VPDMA_DATA_FMT_MV = 0,
 };
 
 extern const struct vpdma_data_format vpdma_yuv_fmts[];
 extern const struct vpdma_data_format vpdma_rgb_fmts[];
+extern const struct vpdma_data_format vpdma_raw_fmts[];
 extern const struct vpdma_data_format vpdma_misc_fmts[];
 
 enum vpdma_frame_start_event {
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Patch v2 33/35] media: ti-vpe: Make colorspace converter library into its own module
  2016-11-18 23:20 [Patch v2 00/35] media: ti-vpe: fixes and enhancements Benoit Parrot
                   ` (31 preceding siblings ...)
  2016-11-18 23:20 ` [Patch v2 32/35] media: ti-vpe: vpdma: Add RAW8 and RAW16 data types Benoit Parrot
@ 2016-11-18 23:20 ` Benoit Parrot
  2016-11-18 23:20 ` [Patch v2 34/35] media: ti-vpe: csc: Add debug support for multi-instance Benoit Parrot
  2016-11-18 23:20 ` [Patch v2 35/35] media: ti-vpe: vpe: Add proper support single and multi-plane buffer Benoit Parrot
  34 siblings, 0 replies; 36+ messages in thread
From: Benoit Parrot @ 2016-11-18 23:20 UTC (permalink / raw)
  To: linux-media, Hans Verkuil
  Cc: linux-kernel, Tomi Valkeinen, Jyri Sarha, Peter Ujfalusi, Benoit Parrot

In preparation to add colorspace conversion support to VIP,
we need to turn csc.c into its own kernel module.

Signed-off-by: Benoit Parrot <bparrot@ti.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/platform/Kconfig         |  4 ++++
 drivers/media/platform/ti-vpe/Makefile |  4 +++-
 drivers/media/platform/ti-vpe/csc.c    | 16 +++++++++++++---
 drivers/media/platform/ti-vpe/csc.h    |  2 +-
 drivers/media/platform/ti-vpe/vpe.c    |  2 +-
 5 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index 5d7befad90e0..60e20e5f4282 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -366,6 +366,7 @@ config VIDEO_TI_VPE
 	select V4L2_MEM2MEM_DEV
 	select VIDEO_TI_VPDMA
 	select VIDEO_TI_SC
+	select VIDEO_TI_CSC
 	default n
 	---help---
 	  Support for the TI VPE(Video Processing Engine) block
@@ -387,6 +388,9 @@ config VIDEO_TI_VPDMA
 config VIDEO_TI_SC
 	tristate
 
+config VIDEO_TI_CSC
+	tristate
+
 menuconfig V4L_TEST_DRIVERS
 	bool "Media test drivers"
 	depends on MEDIA_CAMERA_SUPPORT
diff --git a/drivers/media/platform/ti-vpe/Makefile b/drivers/media/platform/ti-vpe/Makefile
index 736558d309ad..32504b724b5d 100644
--- a/drivers/media/platform/ti-vpe/Makefile
+++ b/drivers/media/platform/ti-vpe/Makefile
@@ -1,10 +1,12 @@
 obj-$(CONFIG_VIDEO_TI_VPE) += ti-vpe.o
 obj-$(CONFIG_VIDEO_TI_VPDMA) += ti-vpdma.o
 obj-$(CONFIG_VIDEO_TI_SC) += ti-sc.o
+obj-$(CONFIG_VIDEO_TI_CSC) += ti-csc.o
 
-ti-vpe-y := vpe.o csc.o
+ti-vpe-y := vpe.o
 ti-vpdma-y := vpdma.o
 ti-sc-y := sc.o
+ti-csc-y := csc.o
 
 ccflags-$(CONFIG_VIDEO_TI_VPE_DEBUG) += -DDEBUG
 
diff --git a/drivers/media/platform/ti-vpe/csc.c b/drivers/media/platform/ti-vpe/csc.c
index bec674994752..9fc6f70adeeb 100644
--- a/drivers/media/platform/ti-vpe/csc.c
+++ b/drivers/media/platform/ti-vpe/csc.c
@@ -14,6 +14,7 @@
 
 #include <linux/err.h>
 #include <linux/io.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/videodev2.h>
@@ -105,11 +106,13 @@ void csc_dump_regs(struct csc_data *csc)
 
 #undef DUMPREG
 }
+EXPORT_SYMBOL(csc_dump_regs);
 
 void csc_set_coeff_bypass(struct csc_data *csc, u32 *csc_reg5)
 {
 	*csc_reg5 |= CSC_BYPASS;
 }
+EXPORT_SYMBOL(csc_set_coeff_bypass);
 
 /*
  * set the color space converter coefficient shadow register values
@@ -160,8 +163,9 @@ void csc_set_coeff(struct csc_data *csc, u32 *csc_reg0,
 	for (; coeff < end_coeff; coeff += 2)
 		*shadow_csc++ = (*(coeff + 1) << 16) | *coeff;
 }
+EXPORT_SYMBOL(csc_set_coeff);
 
-struct csc_data *csc_create(struct platform_device *pdev)
+struct csc_data *csc_create(struct platform_device *pdev, const char *res_name)
 {
 	struct csc_data *csc;
 
@@ -176,9 +180,10 @@ struct csc_data *csc_create(struct platform_device *pdev)
 	csc->pdev = pdev;
 
 	csc->res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
-			"csc");
+						res_name);
 	if (csc->res == NULL) {
-		dev_err(&pdev->dev, "missing platform resources data\n");
+		dev_err(&pdev->dev, "missing '%s' platform resources data\n",
+			res_name);
 		return ERR_PTR(-ENODEV);
 	}
 
@@ -190,3 +195,8 @@ struct csc_data *csc_create(struct platform_device *pdev)
 
 	return csc;
 }
+EXPORT_SYMBOL(csc_create);
+
+MODULE_DESCRIPTION("TI VIP/VPE Color Space Converter");
+MODULE_AUTHOR("Texas Instruments Inc.");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/ti-vpe/csc.h b/drivers/media/platform/ti-vpe/csc.h
index 1ad2b6dad561..024700b15152 100644
--- a/drivers/media/platform/ti-vpe/csc.h
+++ b/drivers/media/platform/ti-vpe/csc.h
@@ -63,6 +63,6 @@ void csc_set_coeff_bypass(struct csc_data *csc, u32 *csc_reg5);
 void csc_set_coeff(struct csc_data *csc, u32 *csc_reg0,
 		enum v4l2_colorspace src_colorspace,
 		enum v4l2_colorspace dst_colorspace);
-struct csc_data *csc_create(struct platform_device *pdev);
+struct csc_data *csc_create(struct platform_device *pdev, const char *res_name);
 
 #endif
diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c
index 32489d6369ca..1e4d614bd3b6 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -2496,7 +2496,7 @@ static int vpe_probe(struct platform_device *pdev)
 		goto runtime_put;
 	}
 
-	dev->csc = csc_create(pdev);
+	dev->csc = csc_create(pdev, "csc");
 	if (IS_ERR(dev->csc)) {
 		ret = PTR_ERR(dev->csc);
 		goto runtime_put;
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Patch v2 34/35] media: ti-vpe: csc: Add debug support for multi-instance
  2016-11-18 23:20 [Patch v2 00/35] media: ti-vpe: fixes and enhancements Benoit Parrot
                   ` (32 preceding siblings ...)
  2016-11-18 23:20 ` [Patch v2 33/35] media: ti-vpe: Make colorspace converter library into its own module Benoit Parrot
@ 2016-11-18 23:20 ` Benoit Parrot
  2016-11-18 23:20 ` [Patch v2 35/35] media: ti-vpe: vpe: Add proper support single and multi-plane buffer Benoit Parrot
  34 siblings, 0 replies; 36+ messages in thread
From: Benoit Parrot @ 2016-11-18 23:20 UTC (permalink / raw)
  To: linux-media, Hans Verkuil
  Cc: linux-kernel, Tomi Valkeinen, Jyri Sarha, Peter Ujfalusi, Benoit Parrot

Since there might be more then one instance it is better to
show the base address when dumping registers to help
with debugging.

Signed-off-by: Benoit Parrot <bparrot@ti.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/platform/ti-vpe/csc.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/media/platform/ti-vpe/csc.c b/drivers/media/platform/ti-vpe/csc.c
index 9fc6f70adeeb..44b8465cf101 100644
--- a/drivers/media/platform/ti-vpe/csc.c
+++ b/drivers/media/platform/ti-vpe/csc.c
@@ -97,6 +97,8 @@ void csc_dump_regs(struct csc_data *csc)
 #define DUMPREG(r) dev_dbg(dev, "%-35s %08x\n", #r, \
 	ioread32(csc->base + CSC_##r))
 
+	dev_dbg(dev, "CSC Registers @ %pa:\n", &csc->res->start);
+
 	DUMPREG(CSC00);
 	DUMPREG(CSC01);
 	DUMPREG(CSC02);
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Patch v2 35/35] media: ti-vpe: vpe: Add proper support single and multi-plane buffer
  2016-11-18 23:20 [Patch v2 00/35] media: ti-vpe: fixes and enhancements Benoit Parrot
                   ` (33 preceding siblings ...)
  2016-11-18 23:20 ` [Patch v2 34/35] media: ti-vpe: csc: Add debug support for multi-instance Benoit Parrot
@ 2016-11-18 23:20 ` Benoit Parrot
  34 siblings, 0 replies; 36+ messages in thread
From: Benoit Parrot @ 2016-11-18 23:20 UTC (permalink / raw)
  To: linux-media, Hans Verkuil
  Cc: linux-kernel, Tomi Valkeinen, Jyri Sarha, Peter Ujfalusi, Benoit Parrot

The VPE was restricting the number of plane per buffer based on
the fact that if a particular format had color separation it was
meant to need 2 planes.

However NV12/NV16 are color separate format which are meant to be
presented in a single contiguous buffer/plane.
It could also be presented in a multi-plane as well if need be.
So we must support both modes for more flexibility.

The number of plane requested by user space was previously ignored
and was therefore always overwritten.
The driver now use the requested num plane as hint to calculate needed
offset when required.

Signed-off-by: Benoit Parrot <bparrot@ti.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/platform/ti-vpe/vpe.c | 58 ++++++++++++++++++++++++++++++-------
 1 file changed, 48 insertions(+), 10 deletions(-)

diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c
index 1e4d614bd3b6..0626593a8b22 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -327,6 +327,7 @@ static struct vpe_fmt vpe_formats[] = {
 struct vpe_q_data {
 	unsigned int		width;				/* frame width */
 	unsigned int		height;				/* frame height */
+	unsigned int		nplanes;			/* Current number of planes */
 	unsigned int		bytesperline[VPE_MAX_PLANES];	/* bytes per line in memory */
 	enum v4l2_colorspace	colorspace;
 	enum v4l2_field		field;				/* supported field value */
@@ -1042,6 +1043,7 @@ static void add_out_dtd(struct vpe_ctx *ctx, int port)
 	int mv_buf_selector = !ctx->src_mv_buf_selector;
 	dma_addr_t dma_addr;
 	u32 flags = 0;
+	u32 offset = 0;
 
 	if (port == VPE_PORT_MV_OUT) {
 		vpdma_fmt = &vpdma_misc_fmts[VPDMA_DATA_FMT_MV];
@@ -1052,13 +1054,27 @@ static void add_out_dtd(struct vpe_ctx *ctx, int port)
 		int plane = fmt->coplanar ? p_data->vb_part : 0;
 
 		vpdma_fmt = fmt->vpdma_fmt[plane];
-		dma_addr = vb2_dma_contig_plane_dma_addr(vb, plane);
+		/*
+		 * If we are using a single plane buffer and
+		 * we need to set a separate vpdma chroma channel.
+		 */
+		if (q_data->nplanes == 1 && plane) {
+			dma_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
+			/* Compute required offset */
+			offset = q_data->bytesperline[0] * q_data->height;
+		} else {
+			dma_addr = vb2_dma_contig_plane_dma_addr(vb, plane);
+			/* Use address as is, no offset */
+			offset = 0;
+		}
 		if (!dma_addr) {
 			vpe_err(ctx->dev,
 				"acquiring output buffer(%d) dma_addr failed\n",
 				port);
 			return;
 		}
+		/* Apply the offset */
+		dma_addr += offset;
 	}
 
 	if (q_data->flags & Q_DATA_FRAME_1D)
@@ -1087,6 +1103,7 @@ static void add_in_dtd(struct vpe_ctx *ctx, int port)
 	int frame_width, frame_height;
 	dma_addr_t dma_addr;
 	u32 flags = 0;
+	u32 offset = 0;
 
 	if (port == VPE_PORT_MV_IN) {
 		vpdma_fmt = &vpdma_misc_fmts[VPDMA_DATA_FMT_MV];
@@ -1096,14 +1113,27 @@ static void add_in_dtd(struct vpe_ctx *ctx, int port)
 		int plane = fmt->coplanar ? p_data->vb_part : 0;
 
 		vpdma_fmt = fmt->vpdma_fmt[plane];
-
-		dma_addr = vb2_dma_contig_plane_dma_addr(vb, plane);
+		/*
+		 * If we are using a single plane buffer and
+		 * we need to set a separate vpdma chroma channel.
+		 */
+		if (q_data->nplanes == 1 && plane) {
+			dma_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
+			/* Compute required offset */
+			offset = q_data->bytesperline[0] * q_data->height;
+		} else {
+			dma_addr = vb2_dma_contig_plane_dma_addr(vb, plane);
+			/* Use address as is, no offset */
+			offset = 0;
+		}
 		if (!dma_addr) {
 			vpe_err(ctx->dev,
-				"acquiring input buffer(%d) dma_addr failed\n",
+				"acquiring output buffer(%d) dma_addr failed\n",
 				port);
 			return;
 		}
+		/* Apply the offset */
+		dma_addr += offset;
 
 		if (q_data->flags & Q_DATA_INTERLACED_SEQ_TB) {
 			/*
@@ -1548,7 +1578,7 @@ static int vpe_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
 		pix->colorspace = s_q_data->colorspace;
 	}
 
-	pix->num_planes = q_data->fmt->coplanar ? 2 : 1;
+	pix->num_planes = q_data->nplanes;
 
 	for (i = 0; i < pix->num_planes; i++) {
 		pix->plane_fmt[i].bytesperline = q_data->bytesperline[i];
@@ -1604,7 +1634,11 @@ static int __vpe_try_fmt(struct vpe_ctx *ctx, struct v4l2_format *f,
 			      &pix->height, MIN_H, MAX_H, H_ALIGN,
 			      S_ALIGN);
 
-	pix->num_planes = fmt->coplanar ? 2 : 1;
+	if (!pix->num_planes)
+		pix->num_planes = fmt->coplanar ? 2 : 1;
+	else if (pix->num_planes > 1 && !fmt->coplanar)
+		pix->num_planes = 1;
+
 	pix->pixelformat = fmt->fourcc;
 
 	/*
@@ -1640,6 +1674,8 @@ static int __vpe_try_fmt(struct vpe_ctx *ctx, struct v4l2_format *f,
 		else
 			plane_fmt->bytesperline = pix->width;
 
+		if (pix->num_planes == 1 && fmt->coplanar)
+			depth += fmt->vpdma_fmt[VPE_CHROMA]->depth;
 		plane_fmt->sizeimage =
 				(pix->height * pix->width * depth) >> 3;
 
@@ -1686,6 +1722,7 @@ static int __vpe_s_fmt(struct vpe_ctx *ctx, struct v4l2_format *f)
 	q_data->height		= pix->height;
 	q_data->colorspace	= pix->colorspace;
 	q_data->field		= pix->field;
+	q_data->nplanes		= pix->num_planes;
 
 	for (i = 0; i < pix->num_planes; i++) {
 		plane_fmt = &pix->plane_fmt[i];
@@ -1713,7 +1750,7 @@ static int __vpe_s_fmt(struct vpe_ctx *ctx, struct v4l2_format *f)
 	vpe_dbg(ctx->dev, "Setting format for type %d, wxh: %dx%d, fmt: %d bpl_y %d",
 		f->type, q_data->width, q_data->height, q_data->fmt->fourcc,
 		q_data->bytesperline[VPE_LUMA]);
-	if (q_data->fmt->coplanar)
+	if (q_data->nplanes == 2)
 		vpe_dbg(ctx->dev, " bpl_uv %d\n",
 			q_data->bytesperline[VPE_CHROMA]);
 
@@ -1965,14 +2002,14 @@ static int vpe_queue_setup(struct vb2_queue *vq,
 
 	q_data = get_q_data(ctx, vq->type);
 
-	*nplanes = q_data->fmt->coplanar ? 2 : 1;
+	*nplanes = q_data->nplanes;
 
 	for (i = 0; i < *nplanes; i++)
 		sizes[i] = q_data->sizeimage[i];
 
 	vpe_dbg(ctx->dev, "get %d buffer(s) of size %d", *nbuffers,
 		sizes[VPE_LUMA]);
-	if (q_data->fmt->coplanar)
+	if (q_data->nplanes == 2)
 		vpe_dbg(ctx->dev, " and %d\n", sizes[VPE_CHROMA]);
 
 	return 0;
@@ -1988,7 +2025,7 @@ static int vpe_buf_prepare(struct vb2_buffer *vb)
 	vpe_dbg(ctx->dev, "type: %d\n", vb->vb2_queue->type);
 
 	q_data = get_q_data(ctx, vb->vb2_queue->type);
-	num_planes = q_data->fmt->coplanar ? 2 : 1;
+	num_planes = q_data->nplanes;
 
 	if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
 		if (!(q_data->flags & Q_IS_INTERLACED)) {
@@ -2248,6 +2285,7 @@ static int vpe_open(struct file *file)
 	s_q_data->fmt = &vpe_formats[2];
 	s_q_data->width = 1920;
 	s_q_data->height = 1080;
+	s_q_data->nplanes = 1;
 	s_q_data->bytesperline[VPE_LUMA] = (s_q_data->width *
 			s_q_data->fmt->vpdma_fmt[VPE_LUMA]->depth) >> 3;
 	s_q_data->sizeimage[VPE_LUMA] = (s_q_data->bytesperline[VPE_LUMA] *
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 36+ messages in thread

end of thread, other threads:[~2016-11-18 23:30 UTC | newest]

Thread overview: 36+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-11-18 23:20 [Patch v2 00/35] media: ti-vpe: fixes and enhancements Benoit Parrot
2016-11-18 23:20 ` [Patch v2 01/35] media: ti-vpe: vpdma: Make vpdma library into its own module Benoit Parrot
2016-11-18 23:20 ` [Patch v2 02/35] media: ti-vpe: vpdma: Add multi-instance and multi-client support Benoit Parrot
2016-11-18 23:20 ` [Patch v2 03/35] media: ti-vpe: vpdma: Add helper to set a background color Benoit Parrot
2016-11-18 23:20 ` [Patch v2 04/35] media: ti-vpe: vpdma: Fix bus error when vpdma is writing a descriptor Benoit Parrot
2016-11-18 23:20 ` [Patch v2 05/35] media: ti-vpe: Use line average de-interlacing for first 2 frames Benoit Parrot
2016-11-18 23:20 ` [Patch v2 06/35] media: ti-vpe: vpe: Do not perform job transaction atomically Benoit Parrot
2016-11-18 23:20 ` [Patch v2 07/35] media: ti-vpe: Add support for SEQ_TB buffers Benoit Parrot
2016-11-18 23:20 ` [Patch v2 08/35] media: ti-vpe: Increasing max buffer height and width Benoit Parrot
2016-11-18 23:20 ` [Patch v2 09/35] media: ti-vpe: vpe: Return NULL for invalid buffer type Benoit Parrot
2016-11-18 23:20 ` [Patch v2 10/35] media: ti-vpe: Free vpdma buffers in vpe_release Benoit Parrot
2016-11-18 23:20 ` [Patch v2 11/35] media: ti-vpe: vpdma: Add support for setting max width height Benoit Parrot
2016-11-18 23:20 ` [Patch v2 12/35] media: ti-vpe: vpdma: Add abort channel desc and cleanup APIs Benoit Parrot
2016-11-18 23:20 ` [Patch v2 13/35] media: ti-vpe: vpdma: Make list post atomic operation Benoit Parrot
2016-11-18 23:20 ` [Patch v2 14/35] media: ti-vpe: vpdma: Clear IRQs for individual lists Benoit Parrot
2016-11-18 23:20 ` [Patch v2 15/35] media: ti-vpe: vpe: configure line mode separately Benoit Parrot
2016-11-18 23:20 ` [Patch v2 16/35] media: ti-vpe: vpe: Setup srcdst parameters in start_streaming Benoit Parrot
2016-11-18 23:20 ` [Patch v2 17/35] media: ti-vpe: vpe: Post next descriptor only for list complete IRQ Benoit Parrot
2016-11-18 23:20 ` [Patch v2 18/35] media: ti-vpe: vpe: Add RGB565 and RGB5551 support Benoit Parrot
2016-11-18 23:20 ` [Patch v2 19/35] media: ti-vpe: vpdma: allocate and maintain hwlist Benoit Parrot
2016-11-18 23:20 ` [Patch v2 20/35] media: ti-vpe: vpe: Added MODULE_DEVICE_TABLE hint Benoit Parrot
2016-11-18 23:20 ` [Patch v2 21/35] media: ti-vpe: vpdma: Corrected YUV422 data type label Benoit Parrot
2016-11-18 23:20 ` [Patch v2 22/35] media: ti-vpe: vpdma: RGB data type yield inverted data Benoit Parrot
2016-11-18 23:20 ` [Patch v2 23/35] media: ti-vpe: sc: Fix incorrect optimization Benoit Parrot
2016-11-18 23:20 ` [Patch v2 24/35] media: ti-vpe: vpe: Fix vb2 buffer cleanup Benoit Parrot
2016-11-18 23:20 ` [Patch v2 25/35] media: ti-vpe: vpdma: Fix race condition for firmware loading Benoit Parrot
2016-11-18 23:20 ` [Patch v2 26/35] media: ti-vpe: vpdma: Use bidirectional cached buffers Benoit Parrot
2016-11-18 23:20 ` [Patch v2 27/35] media: ti-vpe: vpe: Fix line stride for output motion vector Benoit Parrot
2016-11-18 23:20 ` [Patch v2 28/35] media: ti-vpe: vpe: Enable DMABUF export Benoit Parrot
2016-11-18 23:20 ` [Patch v2 29/35] media: ti-vpe: Make scaler library into its own module Benoit Parrot
2016-11-18 23:20 ` [Patch v2 30/35] media: ti-vpe: scaler: Add debug support for multi-instance Benoit Parrot
2016-11-18 23:20 ` [Patch v2 31/35] media: ti-vpe: vpe: Make sure frame size dont exceed scaler capacity Benoit Parrot
2016-11-18 23:20 ` [Patch v2 32/35] media: ti-vpe: vpdma: Add RAW8 and RAW16 data types Benoit Parrot
2016-11-18 23:20 ` [Patch v2 33/35] media: ti-vpe: Make colorspace converter library into its own module Benoit Parrot
2016-11-18 23:20 ` [Patch v2 34/35] media: ti-vpe: csc: Add debug support for multi-instance Benoit Parrot
2016-11-18 23:20 ` [Patch v2 35/35] media: ti-vpe: vpe: Add proper support single and multi-plane buffer Benoit Parrot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).