linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 01/11] media: vsp1: drm: Fix minor grammar error
       [not found] <cover.50cd35ac550b4477f13fb4f3fbd3ffb6bcccfc8a.1520632434.git-series.kieran.bingham+renesas@ideasonboard.com>
@ 2018-03-09 22:03 ` Kieran Bingham
  2018-03-09 22:04 ` [PATCH 02/11] media: vsp1: use kernel __packed for structures Kieran Bingham
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 19+ messages in thread
From: Kieran Bingham @ 2018-03-09 22:03 UTC (permalink / raw)
  To: Laurent Pinchart, linux-renesas-soc, linux-media
  Cc: Kieran Bingham, Mauro Carvalho Chehab, open list

The pixel format is 'unsupported'. Fix the small debug message which
incorrectly declares this.

Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
---
 drivers/media/platform/vsp1/vsp1_drm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c
index 3c8b1952799d..0459b970e9da 100644
--- a/drivers/media/platform/vsp1/vsp1_drm.c
+++ b/drivers/media/platform/vsp1/vsp1_drm.c
@@ -363,7 +363,7 @@ int vsp1_du_atomic_update(struct device *dev, unsigned int pipe_index,
 	 */
 	fmtinfo = vsp1_get_format_info(vsp1, cfg->pixelformat);
 	if (!fmtinfo) {
-		dev_dbg(vsp1->dev, "Unsupport pixel format %08x for RPF\n",
+		dev_dbg(vsp1->dev, "Unsupported pixel format %08x for RPF\n",
 			cfg->pixelformat);
 		return -EINVAL;
 	}
-- 
git-series 0.9.1

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

* [PATCH 02/11] media: vsp1: use kernel __packed for structures
       [not found] <cover.50cd35ac550b4477f13fb4f3fbd3ffb6bcccfc8a.1520632434.git-series.kieran.bingham+renesas@ideasonboard.com>
  2018-03-09 22:03 ` [PATCH 01/11] media: vsp1: drm: Fix minor grammar error Kieran Bingham
@ 2018-03-09 22:04 ` Kieran Bingham
  2018-03-13 11:20   ` David Laight
  2018-03-09 22:04 ` [PATCH 03/11] media: vsp1: Rename dl_child to dl_next Kieran Bingham
                   ` (8 subsequent siblings)
  10 siblings, 1 reply; 19+ messages in thread
From: Kieran Bingham @ 2018-03-09 22:04 UTC (permalink / raw)
  To: Laurent Pinchart, linux-renesas-soc, linux-media
  Cc: Kieran Bingham, Mauro Carvalho Chehab, open list

The kernel provides a __packed definition to abstract away from the
compiler specific attributes tag.

Convert all packed structures in VSP1 to use it.

Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
---
 drivers/media/platform/vsp1/vsp1_dl.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c
index 37e2c984fbf3..382e45c2054e 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -29,19 +29,19 @@
 struct vsp1_dl_header_list {
 	u32 num_bytes;
 	u32 addr;
-} __attribute__((__packed__));
+} __packed;
 
 struct vsp1_dl_header {
 	u32 num_lists;
 	struct vsp1_dl_header_list lists[8];
 	u32 next_header;
 	u32 flags;
-} __attribute__((__packed__));
+} __packed;
 
 struct vsp1_dl_entry {
 	u32 addr;
 	u32 data;
-} __attribute__((__packed__));
+} __packed;
 
 /**
  * struct vsp1_dl_body - Display list body
-- 
git-series 0.9.1

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

* [PATCH 03/11] media: vsp1: Rename dl_child to dl_next
       [not found] <cover.50cd35ac550b4477f13fb4f3fbd3ffb6bcccfc8a.1520632434.git-series.kieran.bingham+renesas@ideasonboard.com>
  2018-03-09 22:03 ` [PATCH 01/11] media: vsp1: drm: Fix minor grammar error Kieran Bingham
  2018-03-09 22:04 ` [PATCH 02/11] media: vsp1: use kernel __packed for structures Kieran Bingham
@ 2018-03-09 22:04 ` Kieran Bingham
  2018-03-09 22:04 ` [PATCH 04/11] media: vsp1: Remove unused display list structure field Kieran Bingham
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 19+ messages in thread
From: Kieran Bingham @ 2018-03-09 22:04 UTC (permalink / raw)
  To: Laurent Pinchart, linux-renesas-soc, linux-media
  Cc: Kieran Bingham, Mauro Carvalho Chehab, open list

Both vsp1_dl_list_commit() and __vsp1_dl_list_put() walk the display
list chain referencing the nodes as children, when in reality they are
siblings.

Update the terminology to 'dl_next' to be consistent with the
vsp1_video_pipeline_run() usage.

Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
---
 drivers/media/platform/vsp1/vsp1_dl.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c
index 382e45c2054e..057f0f093222 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -400,7 +400,7 @@ struct vsp1_dl_list *vsp1_dl_list_get(struct vsp1_dl_manager *dlm)
 /* This function must be called with the display list manager lock held.*/
 static void __vsp1_dl_list_put(struct vsp1_dl_list *dl)
 {
-	struct vsp1_dl_list *dl_child;
+	struct vsp1_dl_list *dl_next;
 
 	if (!dl)
 		return;
@@ -410,8 +410,8 @@ static void __vsp1_dl_list_put(struct vsp1_dl_list *dl)
 	 * hardware operation.
 	 */
 	if (dl->has_chain) {
-		list_for_each_entry(dl_child, &dl->chain, chain)
-			__vsp1_dl_list_put(dl_child);
+		list_for_each_entry(dl_next, &dl->chain, chain)
+			__vsp1_dl_list_put(dl_next);
 	}
 
 	dl->has_chain = false;
@@ -667,17 +667,17 @@ static void vsp1_dl_list_commit_singleshot(struct vsp1_dl_list *dl)
 void vsp1_dl_list_commit(struct vsp1_dl_list *dl)
 {
 	struct vsp1_dl_manager *dlm = dl->dlm;
-	struct vsp1_dl_list *dl_child;
+	struct vsp1_dl_list *dl_next;
 	unsigned long flags;
 
 	if (dlm->mode == VSP1_DL_MODE_HEADER) {
 		/* Fill the header for the head and chained display lists. */
 		vsp1_dl_list_fill_header(dl, list_empty(&dl->chain));
 
-		list_for_each_entry(dl_child, &dl->chain, chain) {
-			bool last = list_is_last(&dl_child->chain, &dl->chain);
+		list_for_each_entry(dl_next, &dl->chain, chain) {
+			bool last = list_is_last(&dl_next->chain, &dl->chain);
 
-			vsp1_dl_list_fill_header(dl_child, last);
+			vsp1_dl_list_fill_header(dl_next, last);
 		}
 	}
 
-- 
git-series 0.9.1

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

* [PATCH 04/11] media: vsp1: Remove unused display list structure field
       [not found] <cover.50cd35ac550b4477f13fb4f3fbd3ffb6bcccfc8a.1520632434.git-series.kieran.bingham+renesas@ideasonboard.com>
                   ` (2 preceding siblings ...)
  2018-03-09 22:04 ` [PATCH 03/11] media: vsp1: Rename dl_child to dl_next Kieran Bingham
@ 2018-03-09 22:04 ` Kieran Bingham
  2018-03-09 22:04 ` [PATCH 05/11] media: vsp1: Clean up DLM objects on error Kieran Bingham
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 19+ messages in thread
From: Kieran Bingham @ 2018-03-09 22:04 UTC (permalink / raw)
  To: Laurent Pinchart, linux-renesas-soc, linux-media
  Cc: Kieran Bingham, Mauro Carvalho Chehab, open list

The vsp1 reference in the vsp1_dl_body structure is not used.
Remove it.

Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
---
 drivers/media/platform/vsp1/vsp1_dl.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c
index 057f0f093222..16a2d3c93655 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -48,7 +48,6 @@ struct vsp1_dl_entry {
  * @list: entry in the display list list of bodies
  * @free: entry in the pool free body list
  * @pool: pool to which this body belongs
- * @vsp1: the VSP1 device
  * @entries: array of entries
  * @dma: DMA address of the entries
  * @size: size of the DMA memory in bytes
@@ -62,7 +61,6 @@ struct vsp1_dl_body {
 	refcount_t refcnt;
 
 	struct vsp1_dl_body_pool *pool;
-	struct vsp1_device *vsp1;
 
 	struct vsp1_dl_entry *entries;
 	dma_addr_t dma;
-- 
git-series 0.9.1

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

* [PATCH 05/11] media: vsp1: Clean up DLM objects on error
       [not found] <cover.50cd35ac550b4477f13fb4f3fbd3ffb6bcccfc8a.1520632434.git-series.kieran.bingham+renesas@ideasonboard.com>
                   ` (3 preceding siblings ...)
  2018-03-09 22:04 ` [PATCH 04/11] media: vsp1: Remove unused display list structure field Kieran Bingham
@ 2018-03-09 22:04 ` Kieran Bingham
  2018-03-09 22:04 ` [PATCH 06/11] media: vsp1: Provide VSP1 feature helper macro Kieran Bingham
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 19+ messages in thread
From: Kieran Bingham @ 2018-03-09 22:04 UTC (permalink / raw)
  To: Laurent Pinchart, linux-renesas-soc, linux-media
  Cc: Kieran Bingham, Mauro Carvalho Chehab, open list

If there is an error allocating a display list within a DLM object
the existing display lists are not free'd, and neither is the DL body
pool.

Use the existing vsp1_dlm_destroy() function to clean up on error.

Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
---
 drivers/media/platform/vsp1/vsp1_dl.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c
index 16a2d3c93655..6271bea5e831 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -831,8 +831,10 @@ struct vsp1_dl_manager *vsp1_dlm_create(struct vsp1_device *vsp1,
 		struct vsp1_dl_list *dl;
 
 		dl = vsp1_dl_list_alloc(dlm, dlm->pool);
-		if (!dl)
+		if (!dl) {
+			vsp1_dlm_destroy(dlm);
 			return NULL;
+		}
 
 		list_add_tail(&dl->list, &dlm->free);
 	}
-- 
git-series 0.9.1

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

* [PATCH 06/11] media: vsp1: Provide VSP1 feature helper macro
       [not found] <cover.50cd35ac550b4477f13fb4f3fbd3ffb6bcccfc8a.1520632434.git-series.kieran.bingham+renesas@ideasonboard.com>
                   ` (4 preceding siblings ...)
  2018-03-09 22:04 ` [PATCH 05/11] media: vsp1: Clean up DLM objects on error Kieran Bingham
@ 2018-03-09 22:04 ` Kieran Bingham
  2018-03-09 22:04 ` [PATCH 07/11] media: vsp1: Use header display lists for all WPF outputs linked to the DU Kieran Bingham
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 19+ messages in thread
From: Kieran Bingham @ 2018-03-09 22:04 UTC (permalink / raw)
  To: Laurent Pinchart, linux-renesas-soc, linux-media
  Cc: Kieran Bingham, Mauro Carvalho Chehab, open list

The VSP1 devices define their specific capabilities through features
marked in their device info structure. Various parts of the code read
this info structure to infer if the features are available.

Wrap this into a more readable vsp1_feature(vsp1, f) macro to ensure
that usage is consistent throughout the driver.

Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
---
 drivers/media/platform/vsp1/vsp1.h     |  2 ++
 drivers/media/platform/vsp1/vsp1_drv.c | 16 ++++++++--------
 drivers/media/platform/vsp1/vsp1_wpf.c |  6 +++---
 3 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1.h b/drivers/media/platform/vsp1/vsp1.h
index 78ef838416b3..1c080538c993 100644
--- a/drivers/media/platform/vsp1/vsp1.h
+++ b/drivers/media/platform/vsp1/vsp1.h
@@ -69,6 +69,8 @@ struct vsp1_device_info {
 	bool uapi;
 };
 
+#define vsp1_feature(vsp1, f) ((vsp1)->info->features & (f))
+
 struct vsp1_device {
 	struct device *dev;
 	const struct vsp1_device_info *info;
diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
index eed9516e25e1..6fa0019ffc6e 100644
--- a/drivers/media/platform/vsp1/vsp1_drv.c
+++ b/drivers/media/platform/vsp1/vsp1_drv.c
@@ -268,7 +268,7 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
 	}
 
 	/* Instantiate all the entities. */
-	if (vsp1->info->features & VSP1_HAS_BRS) {
+	if (vsp1_feature(vsp1, VSP1_HAS_BRS)) {
 		vsp1->brs = vsp1_bru_create(vsp1, VSP1_ENTITY_BRS);
 		if (IS_ERR(vsp1->brs)) {
 			ret = PTR_ERR(vsp1->brs);
@@ -278,7 +278,7 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
 		list_add_tail(&vsp1->brs->entity.list_dev, &vsp1->entities);
 	}
 
-	if (vsp1->info->features & VSP1_HAS_BRU) {
+	if (vsp1_feature(vsp1, VSP1_HAS_BRU)) {
 		vsp1->bru = vsp1_bru_create(vsp1, VSP1_ENTITY_BRU);
 		if (IS_ERR(vsp1->bru)) {
 			ret = PTR_ERR(vsp1->bru);
@@ -288,7 +288,7 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
 		list_add_tail(&vsp1->bru->entity.list_dev, &vsp1->entities);
 	}
 
-	if (vsp1->info->features & VSP1_HAS_CLU) {
+	if (vsp1_feature(vsp1, VSP1_HAS_CLU)) {
 		vsp1->clu = vsp1_clu_create(vsp1);
 		if (IS_ERR(vsp1->clu)) {
 			ret = PTR_ERR(vsp1->clu);
@@ -314,7 +314,7 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
 
 	list_add_tail(&vsp1->hst->entity.list_dev, &vsp1->entities);
 
-	if (vsp1->info->features & VSP1_HAS_HGO && vsp1->info->uapi) {
+	if (vsp1_feature(vsp1, VSP1_HAS_HGO) && vsp1->info->uapi) {
 		vsp1->hgo = vsp1_hgo_create(vsp1);
 		if (IS_ERR(vsp1->hgo)) {
 			ret = PTR_ERR(vsp1->hgo);
@@ -325,7 +325,7 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
 			      &vsp1->entities);
 	}
 
-	if (vsp1->info->features & VSP1_HAS_HGT && vsp1->info->uapi) {
+	if (vsp1_feature(vsp1, VSP1_HAS_HGT) && vsp1->info->uapi) {
 		vsp1->hgt = vsp1_hgt_create(vsp1);
 		if (IS_ERR(vsp1->hgt)) {
 			ret = PTR_ERR(vsp1->hgt);
@@ -356,7 +356,7 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
 		}
 	}
 
-	if (vsp1->info->features & VSP1_HAS_LUT) {
+	if (vsp1_feature(vsp1, VSP1_HAS_LUT)) {
 		vsp1->lut = vsp1_lut_create(vsp1);
 		if (IS_ERR(vsp1->lut)) {
 			ret = PTR_ERR(vsp1->lut);
@@ -390,7 +390,7 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
 		}
 	}
 
-	if (vsp1->info->features & VSP1_HAS_SRU) {
+	if (vsp1_feature(vsp1, VSP1_HAS_SRU)) {
 		vsp1->sru = vsp1_sru_create(vsp1);
 		if (IS_ERR(vsp1->sru)) {
 			ret = PTR_ERR(vsp1->sru);
@@ -524,7 +524,7 @@ static int vsp1_device_init(struct vsp1_device *vsp1)
 	vsp1_write(vsp1, VI6_DPR_HSI_ROUTE, VI6_DPR_NODE_UNUSED);
 	vsp1_write(vsp1, VI6_DPR_BRU_ROUTE, VI6_DPR_NODE_UNUSED);
 
-	if (vsp1->info->features & VSP1_HAS_BRS)
+	if (vsp1_feature(vsp1, VSP1_HAS_BRS))
 		vsp1_write(vsp1, VI6_DPR_ILV_BRS_ROUTE, VI6_DPR_NODE_UNUSED);
 
 	vsp1_write(vsp1, VI6_DPR_HGO_SMPPT, (7 << VI6_DPR_SMPPT_TGW_SHIFT) |
diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c
index 68218625549e..f90e474cf2cc 100644
--- a/drivers/media/platform/vsp1/vsp1_wpf.c
+++ b/drivers/media/platform/vsp1/vsp1_wpf.c
@@ -146,13 +146,13 @@ static int wpf_init_controls(struct vsp1_rwpf *wpf)
 	if (wpf->entity.index != 0) {
 		/* Only WPF0 supports flipping. */
 		num_flip_ctrls = 0;
-	} else if (vsp1->info->features & VSP1_HAS_WPF_HFLIP) {
+	} else if (vsp1_feature(vsp1, VSP1_HAS_WPF_HFLIP)) {
 		/*
 		 * When horizontal flip is supported the WPF implements three
 		 * controls (horizontal flip, vertical flip and rotation).
 		 */
 		num_flip_ctrls = 3;
-	} else if (vsp1->info->features & VSP1_HAS_WPF_VFLIP) {
+	} else if (vsp1_feature(vsp1, VSP1_HAS_WPF_VFLIP)) {
 		/*
 		 * When only vertical flip is supported the WPF implements a
 		 * single control (vertical flip).
@@ -281,7 +281,7 @@ static void wpf_configure_stream(struct vsp1_entity *entity,
 
 		vsp1_wpf_write(wpf, dlb, VI6_WPF_DSWAP, fmtinfo->swap);
 
-		if (vsp1->info->features & VSP1_HAS_WPF_HFLIP &&
+		if (vsp1_feature(vsp1, VSP1_HAS_WPF_HFLIP) &&
 		    wpf->entity.index == 0)
 			vsp1_wpf_write(wpf, dlb, VI6_WPF_ROT_CTRL,
 				       VI6_WPF_ROT_CTRL_LN16 |
-- 
git-series 0.9.1

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

* [PATCH 07/11] media: vsp1: Use header display lists for all WPF outputs linked to the DU
       [not found] <cover.50cd35ac550b4477f13fb4f3fbd3ffb6bcccfc8a.1520632434.git-series.kieran.bingham+renesas@ideasonboard.com>
                   ` (5 preceding siblings ...)
  2018-03-09 22:04 ` [PATCH 06/11] media: vsp1: Provide VSP1 feature helper macro Kieran Bingham
@ 2018-03-09 22:04 ` Kieran Bingham
  2018-03-09 22:04 ` [PATCH 08/11] media: vsp1: Add support for extended display list headers Kieran Bingham
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 19+ messages in thread
From: Kieran Bingham @ 2018-03-09 22:04 UTC (permalink / raw)
  To: Laurent Pinchart, linux-renesas-soc, linux-media
  Cc: Kieran Bingham, Mauro Carvalho Chehab, open list

Header mode display lists are now supported on all WPF outputs. To
support extended headers and auto-fld capabilities for interlaced mode
handling only header mode display lists can be used.

Disable the headerless display list configuration, and remove the dead
code.

Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
---
 drivers/media/platform/vsp1/vsp1_dl.c | 107 ++++++---------------------
 1 file changed, 27 insertions(+), 80 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c
index 6271bea5e831..dc273e3b4753 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -98,7 +98,7 @@ struct vsp1_dl_body_pool {
  * struct vsp1_dl_list - Display list
  * @list: entry in the display list manager lists
  * @dlm: the display list manager
- * @header: display list header, NULL for headerless lists
+ * @header: display list header
  * @dma: DMA address for the header
  * @body0: first display list body
  * @bodies: list of extra display list bodies
@@ -119,15 +119,9 @@ struct vsp1_dl_list {
 	struct list_head chain;
 };
 
-enum vsp1_dl_mode {
-	VSP1_DL_MODE_HEADER,
-	VSP1_DL_MODE_HEADERLESS,
-};
-
 /**
  * struct vsp1_dl_manager - Display List manager
  * @index: index of the related WPF
- * @mode: display list operation mode (header or headerless)
  * @singleshot: execute the display list in single-shot mode
  * @vsp1: the VSP1 device
  * @lock: protects the free, active, queued, pending and gc_bodies lists
@@ -139,7 +133,6 @@ enum vsp1_dl_mode {
  */
 struct vsp1_dl_manager {
 	unsigned int index;
-	enum vsp1_dl_mode mode;
 	bool singleshot;
 	struct vsp1_device *vsp1;
 
@@ -320,6 +313,7 @@ static struct vsp1_dl_list *vsp1_dl_list_alloc(struct vsp1_dl_manager *dlm,
 					       struct vsp1_dl_body_pool *pool)
 {
 	struct vsp1_dl_list *dl;
+	size_t header_offset;
 
 	dl = kzalloc(sizeof(*dl), GFP_KERNEL);
 	if (!dl)
@@ -332,16 +326,15 @@ static struct vsp1_dl_list *vsp1_dl_list_alloc(struct vsp1_dl_manager *dlm,
 	dl->body0 = vsp1_dl_body_get(pool);
 	if (!dl->body0)
 		return NULL;
-	if (dlm->mode == VSP1_DL_MODE_HEADER) {
-		size_t header_offset = dl->body0->max_entries
-				     * sizeof(*dl->body0->entries);
 
-		dl->header = ((void *)dl->body0->entries) + header_offset;
-		dl->dma = dl->body0->dma + header_offset;
+	header_offset = dl->body0->max_entries
+			     * sizeof(*dl->body0->entries);
 
-		memset(dl->header, 0, sizeof(*dl->header));
-		dl->header->lists[0].addr = dl->body0->dma;
-	}
+	dl->header = ((void *)dl->body0->entries) + header_offset;
+	dl->dma = dl->body0->dma + header_offset;
+
+	memset(dl->header, 0, sizeof(*dl->header));
+	dl->header->lists[0].addr = dl->body0->dma;
 
 	return dl;
 }
@@ -473,16 +466,9 @@ struct vsp1_dl_body *vsp1_dl_list_get_body0(struct vsp1_dl_list *dl)
  *
  * The reference must be explicitly released by a call to vsp1_dl_body_put()
  * when the body isn't needed anymore.
- *
- * Additional bodies are only usable for display lists in header mode.
- * Attempting to add a body to a header-less display list will return an error.
  */
 int vsp1_dl_list_add_body(struct vsp1_dl_list *dl, struct vsp1_dl_body *dlb)
 {
-	/* Multi-body lists are only available in header mode. */
-	if (dl->dlm->mode != VSP1_DL_MODE_HEADER)
-		return -EINVAL;
-
 	refcount_inc(&dlb->refcnt);
 
 	list_add_tail(&dlb->list, &dl->bodies);
@@ -503,17 +489,10 @@ int vsp1_dl_list_add_body(struct vsp1_dl_list *dl, struct vsp1_dl_body *dlb)
  * Adding a display list to a chain passes ownership of the display list to
  * the head display list item. The chain is released when the head dl item is
  * put back with __vsp1_dl_list_put().
- *
- * Chained display lists are only usable in header mode. Attempts to add a
- * display list to a chain in header-less mode will return an error.
  */
 int vsp1_dl_list_add_chain(struct vsp1_dl_list *head,
 			   struct vsp1_dl_list *dl)
 {
-	/* Chained lists are only available in header mode. */
-	if (head->dlm->mode != VSP1_DL_MODE_HEADER)
-		return -EINVAL;
-
 	head->has_chain = true;
 	list_add_tail(&dl->chain, &head->chain);
 	return 0;
@@ -581,17 +560,10 @@ static bool vsp1_dl_list_hw_update_pending(struct vsp1_dl_manager *dlm)
 		return false;
 
 	/*
-	 * Check whether the VSP1 has taken the update. In headerless mode the
-	 * hardware indicates this by clearing the UPD bit in the DL_BODY_SIZE
-	 * register, and in header mode by clearing the UPDHDR bit in the CMD
-	 * register.
+	 * Check whether the VSP1 has taken the update. In header mode by
+	 * clearing the UPDHDR bit in the CMD register.
 	 */
-	if (dlm->mode == VSP1_DL_MODE_HEADERLESS)
-		return !!(vsp1_read(vsp1, VI6_DL_BODY_SIZE)
-			  & VI6_DL_BODY_SIZE_UPD);
-	else
-		return !!(vsp1_read(vsp1, VI6_CMD(dlm->index))
-			  & VI6_CMD_UPDHDR);
+	return !!(vsp1_read(vsp1, VI6_CMD(dlm->index)) & VI6_CMD_UPDHDR);
 }
 
 static void vsp1_dl_list_hw_enqueue(struct vsp1_dl_list *dl)
@@ -599,26 +571,14 @@ static void vsp1_dl_list_hw_enqueue(struct vsp1_dl_list *dl)
 	struct vsp1_dl_manager *dlm = dl->dlm;
 	struct vsp1_device *vsp1 = dlm->vsp1;
 
-	if (dlm->mode == VSP1_DL_MODE_HEADERLESS) {
-		/*
-		 * In headerless mode, program the hardware directly with the
-		 * display list body address and size and set the UPD bit. The
-		 * bit will be cleared by the hardware when the display list
-		 * processing starts.
-		 */
-		vsp1_write(vsp1, VI6_DL_HDR_ADDR(0), dl->body0->dma);
-		vsp1_write(vsp1, VI6_DL_BODY_SIZE, VI6_DL_BODY_SIZE_UPD |
-			(dl->body0->num_entries * sizeof(*dl->header->lists)));
-	} else {
-		/*
-		 * In header mode, program the display list header address. If
-		 * the hardware is idle (single-shot mode or first frame in
-		 * continuous mode) it will then be started independently. If
-		 * the hardware is operating, the VI6_DL_HDR_REF_ADDR register
-		 * will be updated with the display list address.
-		 */
-		vsp1_write(vsp1, VI6_DL_HDR_ADDR(dlm->index), dl->dma);
-	}
+	/*
+	 * In header mode, program the display list header address. If
+	 * the hardware is idle (single-shot mode or first frame in
+	 * continuous mode) it will then be started independently. If
+	 * the hardware is operating, the VI6_DL_HDR_REF_ADDR register
+	 * will be updated with the display list address.
+	 */
+	vsp1_write(vsp1, VI6_DL_HDR_ADDR(dlm->index), dl->dma);
 }
 
 static void vsp1_dl_list_commit_continuous(struct vsp1_dl_list *dl)
@@ -668,15 +628,13 @@ void vsp1_dl_list_commit(struct vsp1_dl_list *dl)
 	struct vsp1_dl_list *dl_next;
 	unsigned long flags;
 
-	if (dlm->mode == VSP1_DL_MODE_HEADER) {
-		/* Fill the header for the head and chained display lists. */
-		vsp1_dl_list_fill_header(dl, list_empty(&dl->chain));
+	/* Fill the header for the head and chained display lists. */
+	vsp1_dl_list_fill_header(dl, list_empty(&dl->chain));
 
-		list_for_each_entry(dl_next, &dl->chain, chain) {
-			bool last = list_is_last(&dl_next->chain, &dl->chain);
+	list_for_each_entry(dl_next, &dl->chain, chain) {
+		bool last = list_is_last(&dl_next->chain, &dl->chain);
 
-			vsp1_dl_list_fill_header(dl_next, last);
-		}
+		vsp1_dl_list_fill_header(dl_next, last);
 	}
 
 	spin_lock_irqsave(&dlm->lock, flags);
@@ -763,13 +721,6 @@ void vsp1_dlm_setup(struct vsp1_device *vsp1)
 		 | VI6_DL_CTRL_DC2 | VI6_DL_CTRL_DC1 | VI6_DL_CTRL_DC0
 		 | VI6_DL_CTRL_DLE;
 
-	/*
-	 * The DRM pipeline operates with display lists in Continuous Frame
-	 * Mode, all other pipelines use manual start.
-	 */
-	if (vsp1->drm)
-		ctrl |= VI6_DL_CTRL_CFM0 | VI6_DL_CTRL_NH0;
-
 	vsp1_write(vsp1, VI6_DL_CTRL, ctrl);
 	vsp1_write(vsp1, VI6_DL_SWAP, VI6_DL_SWAP_LWS);
 }
@@ -804,8 +755,6 @@ struct vsp1_dl_manager *vsp1_dlm_create(struct vsp1_device *vsp1,
 		return NULL;
 
 	dlm->index = index;
-	dlm->mode = index == 0 && !vsp1->info->uapi
-		  ? VSP1_DL_MODE_HEADERLESS : VSP1_DL_MODE_HEADER;
 	dlm->singleshot = vsp1->info->uapi;
 	dlm->vsp1 = vsp1;
 
@@ -814,13 +763,11 @@ struct vsp1_dl_manager *vsp1_dlm_create(struct vsp1_device *vsp1,
 
 	/*
 	 * Initialize the display list body and allocate DMA memory for the body
-	 * and the optional header. Both are allocated together to avoid memory
+	 * and the header. Both are allocated together to avoid memory
 	 * fragmentation, with the header located right after the body in
 	 * memory.
 	 */
-	header_size = dlm->mode == VSP1_DL_MODE_HEADER
-		    ? ALIGN(sizeof(struct vsp1_dl_header), 8)
-		    : 0;
+	header_size = ALIGN(sizeof(struct vsp1_dl_header), 8);
 
 	dlm->pool = vsp1_dl_body_pool_create(vsp1, prealloc,
 					     VSP1_DL_NUM_ENTRIES, header_size);
-- 
git-series 0.9.1

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

* [PATCH 08/11] media: vsp1: Add support for extended display list headers
       [not found] <cover.50cd35ac550b4477f13fb4f3fbd3ffb6bcccfc8a.1520632434.git-series.kieran.bingham+renesas@ideasonboard.com>
                   ` (6 preceding siblings ...)
  2018-03-09 22:04 ` [PATCH 07/11] media: vsp1: Use header display lists for all WPF outputs linked to the DU Kieran Bingham
@ 2018-03-09 22:04 ` Kieran Bingham
  2018-03-09 22:04 ` [PATCH 09/11] media: vsp1: Provide support for extended command pools Kieran Bingham
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 19+ messages in thread
From: Kieran Bingham @ 2018-03-09 22:04 UTC (permalink / raw)
  To: Laurent Pinchart, linux-renesas-soc, linux-media
  Cc: Kieran Bingham, Mauro Carvalho Chehab, open list

Extended display list headers allow pre and post command lists to be
executed by the VSP pipeline. This provides the base support for
features such as AUTO_FLD (for interlaced support) and AUTO_DISP (for
supporting continuous camera preview pipelines.

Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
---
 drivers/media/platform/vsp1/vsp1.h      |  1 +-
 drivers/media/platform/vsp1/vsp1_dl.c   | 83 +++++++++++++++++++++++++-
 drivers/media/platform/vsp1/vsp1_dl.h   | 29 ++++++++-
 drivers/media/platform/vsp1/vsp1_drv.c  |  7 +-
 drivers/media/platform/vsp1/vsp1_regs.h |  5 +-
 5 files changed, 116 insertions(+), 9 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1.h b/drivers/media/platform/vsp1/vsp1.h
index 1c080538c993..bb3b32795206 100644
--- a/drivers/media/platform/vsp1/vsp1.h
+++ b/drivers/media/platform/vsp1/vsp1.h
@@ -55,6 +55,7 @@ struct vsp1_uds;
 #define VSP1_HAS_HGO		(1 << 7)
 #define VSP1_HAS_HGT		(1 << 8)
 #define VSP1_HAS_BRS		(1 << 9)
+#define VSP1_HAS_EXT_DL		(1 << 10)
 
 struct vsp1_device_info {
 	u32 version;
diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c
index dc273e3b4753..36440a2a2c8b 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -26,6 +26,9 @@
 #define VSP1_DLH_INT_ENABLE		(1 << 1)
 #define VSP1_DLH_AUTO_START		(1 << 0)
 
+#define VSP1_DLH_EXT_PRE_CMD_EXEC	(1 << 9)
+#define VSP1_DLH_EXT_POST_CMD_EXEC	(1 << 8)
+
 struct vsp1_dl_header_list {
 	u32 num_bytes;
 	u32 addr;
@@ -38,11 +41,34 @@ struct vsp1_dl_header {
 	u32 flags;
 } __packed;
 
+struct vsp1_dl_ext_header {
+	u32 reserved0;		/* alignment padding */
+
+	u16 pre_ext_cmd_qty;
+	u16 flags;
+	u32 pre_ext_cmd_plist;
+
+	u32 post_ext_cmd_qty;
+	u32 post_ext_cmd_plist;
+} __packed;
+
+struct vsp1_dl_header_extended {
+	struct vsp1_dl_header header;
+	struct vsp1_dl_ext_header ext;
+} __packed;
+
 struct vsp1_dl_entry {
 	u32 addr;
 	u32 data;
 } __packed;
 
+struct vsp1_dl_ext_cmd_header {
+	u32 cmd;
+	u32 flags;
+	u32 data;
+	u32 reserved;
+} __packed;
+
 /**
  * struct vsp1_dl_body - Display list body
  * @list: entry in the display list list of bodies
@@ -99,9 +125,12 @@ struct vsp1_dl_body_pool {
  * @list: entry in the display list manager lists
  * @dlm: the display list manager
  * @header: display list header
+ * @extended: extended display list header. NULL for normal lists
  * @dma: DMA address for the header
  * @body0: first display list body
  * @bodies: list of extra display list bodies
+ * @pre_cmd: pre cmd to be issued through extended dl header
+ * @post_cmd: post cmd to be issued through extended dl header
  * @has_chain: if true, indicates that there's a partition chain
  * @chain: entry in the display list partition chain
  */
@@ -110,11 +139,15 @@ struct vsp1_dl_list {
 	struct vsp1_dl_manager *dlm;
 
 	struct vsp1_dl_header *header;
+	struct vsp1_dl_ext_header *extended;
 	dma_addr_t dma;
 
 	struct vsp1_dl_body *body0;
 	struct list_head bodies;
 
+	struct vsp1_dl_ext_cmd *pre_cmd;
+	struct vsp1_dl_ext_cmd *post_cmd;
+
 	bool has_chain;
 	struct list_head chain;
 };
@@ -498,6 +531,14 @@ int vsp1_dl_list_add_chain(struct vsp1_dl_list *head,
 	return 0;
 }
 
+static void vsp1_dl_ext_cmd_fill_header(struct vsp1_dl_ext_cmd *cmd)
+{
+	cmd->cmds[0].cmd = cmd->cmd_opcode;
+	cmd->cmds[0].flags = cmd->flags;
+	cmd->cmds[0].data = cmd->data_dma;
+	cmd->cmds[0].reserved = 0;
+}
+
 static void vsp1_dl_list_fill_header(struct vsp1_dl_list *dl, bool is_last)
 {
 	struct vsp1_dl_manager *dlm = dl->dlm;
@@ -550,6 +591,27 @@ static void vsp1_dl_list_fill_header(struct vsp1_dl_list *dl, bool is_last)
 		 */
 		dl->header->flags = VSP1_DLH_INT_ENABLE;
 	}
+
+	if (!dl->extended)
+		return;
+
+	dl->extended->flags = 0;
+
+	if (dl->pre_cmd) {
+		dl->extended->pre_ext_cmd_plist = dl->pre_cmd->cmd_dma;
+		dl->extended->pre_ext_cmd_qty = dl->pre_cmd->num_cmds;
+		dl->extended->flags |= VSP1_DLH_EXT_PRE_CMD_EXEC;
+
+		vsp1_dl_ext_cmd_fill_header(dl->pre_cmd);
+	}
+
+	if (dl->post_cmd) {
+		dl->extended->pre_ext_cmd_plist = dl->post_cmd->cmd_dma;
+		dl->extended->pre_ext_cmd_qty = dl->post_cmd->num_cmds;
+		dl->extended->flags |= VSP1_DLH_EXT_POST_CMD_EXEC;
+
+		vsp1_dl_ext_cmd_fill_header(dl->pre_cmd);
+	}
 }
 
 static bool vsp1_dl_list_hw_update_pending(struct vsp1_dl_manager *dlm)
@@ -715,14 +777,20 @@ bool vsp1_dlm_irq_frame_end(struct vsp1_dl_manager *dlm)
 }
 
 /* Hardware Setup */
-void vsp1_dlm_setup(struct vsp1_device *vsp1)
+void vsp1_dlm_setup(struct vsp1_device *vsp1, unsigned int index)
 {
 	u32 ctrl = (256 << VI6_DL_CTRL_AR_WAIT_SHIFT)
 		 | VI6_DL_CTRL_DC2 | VI6_DL_CTRL_DC1 | VI6_DL_CTRL_DC0
 		 | VI6_DL_CTRL_DLE;
 
+	if (vsp1_feature(vsp1, VSP1_HAS_EXT_DL))
+		vsp1_write(vsp1, VI6_DL_EXT_CTRL(index),
+			   (0x02 << VI6_DL_EXT_CTRL_POLINT_SHIFT) |
+			   VI6_DL_EXT_CTRL_DLPRI | VI6_DL_EXT_CTRL_EXT);
+
 	vsp1_write(vsp1, VI6_DL_CTRL, ctrl);
-	vsp1_write(vsp1, VI6_DL_SWAP, VI6_DL_SWAP_LWS);
+	vsp1_write(vsp1, VI6_DL_SWAP(index), VI6_DL_SWAP_LWS |
+			 ((index == 1) ? VI6_DL_SWAP_IND : 0));
 }
 
 void vsp1_dlm_reset(struct vsp1_dl_manager *dlm)
@@ -767,7 +835,11 @@ struct vsp1_dl_manager *vsp1_dlm_create(struct vsp1_device *vsp1,
 	 * fragmentation, with the header located right after the body in
 	 * memory.
 	 */
-	header_size = ALIGN(sizeof(struct vsp1_dl_header), 8);
+	header_size = vsp1_feature(vsp1, VSP1_HAS_EXT_DL) ?
+			sizeof(struct vsp1_dl_header_extended) :
+			sizeof(struct vsp1_dl_header);
+
+	header_size = ALIGN(header_size, 8);
 
 	dlm->pool = vsp1_dl_body_pool_create(vsp1, prealloc,
 					     VSP1_DL_NUM_ENTRIES, header_size);
@@ -783,6 +855,11 @@ struct vsp1_dl_manager *vsp1_dlm_create(struct vsp1_device *vsp1,
 			return NULL;
 		}
 
+		/* The extended header immediately follows the header */
+		if (vsp1_feature(vsp1, VSP1_HAS_EXT_DL))
+			dl->extended = (void *)dl->header
+				     + sizeof(*dl->header);
+
 		list_add_tail(&dl->list, &dlm->free);
 	}
 
diff --git a/drivers/media/platform/vsp1/vsp1_dl.h b/drivers/media/platform/vsp1/vsp1_dl.h
index 5ad2cec5cad9..4898b21dc840 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.h
+++ b/drivers/media/platform/vsp1/vsp1_dl.h
@@ -21,7 +21,34 @@ struct vsp1_dl_body_pool;
 struct vsp1_dl_list;
 struct vsp1_dl_manager;
 
-void vsp1_dlm_setup(struct vsp1_device *vsp1);
+/**
+ * struct vsp1_dl_ext_cmd - Extended Display command
+ * @free: entry in the pool of free commands list
+ * @cmd_opcode: command type opcode
+ * @flags: flags used by the command
+ * @cmds: array of command bodies for this extended cmd
+ * @num_cmds: quantity of commands in @cmds array
+ * @cmd_dma: DMA address of the command bodies
+ * @data: memory allocation for command specific data
+ * @data_dma: DMA address for command specific data
+ * @data_size: size of the @data_dma memory in bytes
+ */
+struct vsp1_dl_ext_cmd {
+	struct list_head free;
+
+	u8 cmd_opcode;
+	u32 flags;
+
+	struct vsp1_dl_ext_cmd_header *cmds;
+	unsigned int num_cmds;
+	dma_addr_t cmd_dma;
+
+	void *data;
+	dma_addr_t data_dma;
+	size_t data_size;
+};
+
+void vsp1_dlm_setup(struct vsp1_device *vsp1, unsigned int index);
 
 struct vsp1_dl_manager *vsp1_dlm_create(struct vsp1_device *vsp1,
 					unsigned int index,
diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
index 6fa0019ffc6e..73d9b1a44bdb 100644
--- a/drivers/media/platform/vsp1/vsp1_drv.c
+++ b/drivers/media/platform/vsp1/vsp1_drv.c
@@ -532,7 +532,8 @@ static int vsp1_device_init(struct vsp1_device *vsp1)
 	vsp1_write(vsp1, VI6_DPR_HGT_SMPPT, (7 << VI6_DPR_SMPPT_TGW_SHIFT) |
 		   (VI6_DPR_NODE_UNUSED << VI6_DPR_SMPPT_PT_SHIFT));
 
-	vsp1_dlm_setup(vsp1);
+	for (i = 0; i < vsp1->info->wpf_count; ++i)
+		vsp1_dlm_setup(vsp1, i);
 
 	return 0;
 }
@@ -741,7 +742,7 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
 		.version = VI6_IP_VERSION_MODEL_VSPD_GEN3,
 		.model = "VSP2-D",
 		.gen = 3,
-		.features = VSP1_HAS_BRU | VSP1_HAS_WPF_VFLIP,
+		.features = VSP1_HAS_BRU | VSP1_HAS_WPF_VFLIP | VSP1_HAS_EXT_DL,
 		.lif_count = 1,
 		.rpf_count = 5,
 		.wpf_count = 2,
@@ -759,7 +760,7 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
 		.version = VI6_IP_VERSION_MODEL_VSPDL_GEN3,
 		.model = "VSP2-DL",
 		.gen = 3,
-		.features = VSP1_HAS_BRS | VSP1_HAS_BRU,
+		.features = VSP1_HAS_BRS | VSP1_HAS_BRU | VSP1_HAS_EXT_DL,
 		.lif_count = 2,
 		.rpf_count = 5,
 		.wpf_count = 2,
diff --git a/drivers/media/platform/vsp1/vsp1_regs.h b/drivers/media/platform/vsp1/vsp1_regs.h
index dae0c1901297..43ad68ff3167 100644
--- a/drivers/media/platform/vsp1/vsp1_regs.h
+++ b/drivers/media/platform/vsp1/vsp1_regs.h
@@ -70,12 +70,13 @@
 
 #define VI6_DL_HDR_ADDR(n)		(0x0104 + (n) * 4)
 
-#define VI6_DL_SWAP			0x0114
+#define VI6_DL_SWAP(n)			(0x0114 + (n) * 56)
+#define VI6_DL_SWAP_IND			(1 << 31)
 #define VI6_DL_SWAP_LWS			(1 << 2)
 #define VI6_DL_SWAP_WDS			(1 << 1)
 #define VI6_DL_SWAP_BTS			(1 << 0)
 
-#define VI6_DL_EXT_CTRL			0x011c
+#define VI6_DL_EXT_CTRL(n)		(0x011c + (n) * 36)
 #define VI6_DL_EXT_CTRL_NWE		(1 << 16)
 #define VI6_DL_EXT_CTRL_POLINT_MASK	(0x3f << 8)
 #define VI6_DL_EXT_CTRL_POLINT_SHIFT	8
-- 
git-series 0.9.1

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

* [PATCH 09/11] media: vsp1: Provide support for extended command pools
       [not found] <cover.50cd35ac550b4477f13fb4f3fbd3ffb6bcccfc8a.1520632434.git-series.kieran.bingham+renesas@ideasonboard.com>
                   ` (7 preceding siblings ...)
  2018-03-09 22:04 ` [PATCH 08/11] media: vsp1: Add support for extended display list headers Kieran Bingham
@ 2018-03-09 22:04 ` Kieran Bingham
  2018-03-10 11:26   ` Kieran Bingham
  2018-03-12 16:30   ` jacopo mondi
  2018-03-09 22:04 ` [PATCH 10/11] media: vsp1: Support Interlaced display pipelines Kieran Bingham
  2018-03-09 22:04 ` [PATCH 11/11] drm: rcar-du: Support interlaced video output through vsp1 Kieran Bingham
  10 siblings, 2 replies; 19+ messages in thread
From: Kieran Bingham @ 2018-03-09 22:04 UTC (permalink / raw)
  To: Laurent Pinchart, linux-renesas-soc, linux-media
  Cc: Kieran Bingham, Mauro Carvalho Chehab, open list

VSPD and VSP-DL devices can provide extended display lists supporting
extended command display list objects.

These extended commands require their own dma memory areas for a header
and body specific to the command type.

Implement a command pool to allocate all necessary memory in a single
DMA allocation to reduce pressure on the TLB, and provide convenvient
re-usable command objects for the entities to utilise.

Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
---
 drivers/media/platform/vsp1/vsp1_dl.c | 189 +++++++++++++++++++++++++++-
 drivers/media/platform/vsp1/vsp1_dl.h |   3 +-
 2 files changed, 192 insertions(+)

diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c
index 36440a2a2c8b..6d17b8bfa21c 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -121,6 +121,30 @@ struct vsp1_dl_body_pool {
 };
 
 /**
+ * struct vsp1_cmd_pool - display list body pool
+ * @dma: DMA address of the entries
+ * @size: size of the full DMA memory pool in bytes
+ * @mem: CPU memory pointer for the pool
+ * @bodies: Array of DLB structures for the pool
+ * @free: List of free DLB entries
+ * @lock: Protects the pool and free list
+ * @vsp1: the VSP1 device
+ */
+struct vsp1_dl_cmd_pool {
+	/* DMA allocation */
+	dma_addr_t dma;
+	size_t size;
+	void *mem;
+
+	struct vsp1_dl_ext_cmd *cmds;
+	struct list_head free;
+
+	spinlock_t lock;
+
+	struct vsp1_device *vsp1;
+};
+
+/**
  * struct vsp1_dl_list - Display list
  * @list: entry in the display list manager lists
  * @dlm: the display list manager
@@ -176,6 +200,7 @@ struct vsp1_dl_manager {
 	struct vsp1_dl_list *pending;
 
 	struct vsp1_dl_body_pool *pool;
+	struct vsp1_dl_cmd_pool *autfld_cmds;
 };
 
 /* -----------------------------------------------------------------------------
@@ -339,6 +364,139 @@ void vsp1_dl_body_write(struct vsp1_dl_body *dlb, u32 reg, u32 data)
 }
 
 /* -----------------------------------------------------------------------------
+ * Display List Extended Command Management
+ */
+
+enum vsp1_extcmd_type {
+	VSP1_EXTCMD_AUTODISP,
+	VSP1_EXTCMD_AUTOFLD,
+};
+
+struct vsp1_extended_command_info {
+	u16 opcode;
+	size_t body_size;
+} vsp1_extended_commands[] = {
+	[VSP1_EXTCMD_AUTODISP] = { 0x02, 96 },
+	[VSP1_EXTCMD_AUTOFLD]  = { 0x03, 160 },
+};
+
+/**
+ * vsp1_dl_cmd_pool_create - Create a pool of commands from a single allocation
+ * @vsp1: The VSP1 device
+ * @type: The command pool type
+ * @num_commands: The quantity of commands to allocate
+ *
+ * Allocate a pool of commands each with enough memory to contain the private
+ * data of each command. The allocation sizes are dependent upon the command
+ * type.
+ *
+ * Return a pointer to a pool on success or NULL if memory can't be allocated.
+ */
+struct vsp1_dl_cmd_pool *
+vsp1_dl_cmd_pool_create(struct vsp1_device *vsp1, enum vsp1_extcmd_type type,
+			unsigned int num_cmds)
+{
+	struct vsp1_dl_cmd_pool *pool;
+	unsigned int i;
+	size_t cmd_size;
+
+	pool = kzalloc(sizeof(*pool), GFP_KERNEL);
+	if (!pool)
+		return NULL;
+
+	pool->cmds = kcalloc(num_cmds, sizeof(*pool->cmds), GFP_KERNEL);
+	if (!pool->cmds) {
+		kfree(pool);
+		return NULL;
+	}
+
+	cmd_size = sizeof(struct vsp1_dl_ext_cmd_header) +
+		   vsp1_extended_commands[type].body_size;
+	cmd_size = ALIGN(cmd_size, 16);
+
+	pool->size = cmd_size * num_cmds;
+	pool->mem = dma_alloc_wc(vsp1->bus_master, pool->size, &pool->dma,
+				 GFP_KERNEL);
+	if (!pool->mem) {
+		kfree(pool->cmds);
+		kfree(pool);
+		return NULL;
+	}
+
+	spin_lock_init(&pool->lock);
+	INIT_LIST_HEAD(&pool->free);
+
+	for (i = 0; i < num_cmds; ++i) {
+		struct vsp1_dl_ext_cmd *cmd = &pool->cmds[i];
+		size_t cmd_offset = i * cmd_size;
+		size_t data_offset = sizeof(struct vsp1_dl_ext_cmd_header) +
+				     cmd_offset;
+
+		cmd->pool = pool;
+		cmd->cmd_opcode = vsp1_extended_commands[type].opcode;
+
+		/* TODO: Auto-disp can utilise more than one command per cmd */
+		cmd->num_cmds = 1;
+		cmd->cmds = pool->mem + cmd_offset;
+		cmd->cmd_dma = pool->dma + cmd_offset;
+
+		cmd->data = pool->mem + data_offset;
+		cmd->data_dma = pool->dma + data_offset;
+		cmd->data_size = vsp1_extended_commands[type].body_size;
+
+		list_add_tail(&cmd->free, &pool->free);
+	}
+
+	return pool;
+}
+
+struct vsp1_dl_ext_cmd *vsp1_dl_ext_cmd_get(struct vsp1_dl_cmd_pool *pool)
+{
+	struct vsp1_dl_ext_cmd *cmd = NULL;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pool->lock, flags);
+
+	if (!list_empty(&pool->free)) {
+		cmd = list_first_entry(&pool->free, struct vsp1_dl_ext_cmd,
+				       free);
+		list_del(&cmd->free);
+	}
+
+	spin_unlock_irqrestore(&pool->lock, flags);
+
+	return cmd;
+}
+
+void vsp1_dl_ext_cmd_put(struct vsp1_dl_ext_cmd *cmd)
+{
+	unsigned long flags;
+
+	if (!cmd)
+		return;
+
+	/* Reset flags, these mark data usage */
+	cmd->flags = 0;
+
+	spin_lock_irqsave(&cmd->pool->lock, flags);
+	list_add_tail(&cmd->free, &cmd->pool->free);
+	spin_unlock_irqrestore(&cmd->pool->lock, flags);
+}
+
+void vsp1_dl_ext_cmd_pool_destroy(struct vsp1_dl_cmd_pool *pool)
+{
+	if (!pool)
+		return;
+
+	if (pool->mem)
+		dma_free_wc(pool->vsp1->bus_master, pool->size, pool->mem,
+			    pool->dma);
+
+	kfree(pool->cmds);
+	kfree(pool);
+}
+
+/* ----------------------------------------------------------------------------
  * Display List Transaction Management
  */
 
@@ -442,6 +600,12 @@ static void __vsp1_dl_list_put(struct vsp1_dl_list *dl)
 
 	vsp1_dl_list_bodies_put(dl);
 
+	vsp1_dl_ext_cmd_put(dl->pre_cmd);
+	vsp1_dl_ext_cmd_put(dl->post_cmd);
+
+	dl->pre_cmd = NULL;
+	dl->post_cmd = NULL;
+
 	/*
 	 * body0 is reused as as an optimisation as presently every display list
 	 * has at least one body, thus we reinitialise the entries list
@@ -863,6 +1027,15 @@ struct vsp1_dl_manager *vsp1_dlm_create(struct vsp1_device *vsp1,
 		list_add_tail(&dl->list, &dlm->free);
 	}
 
+	if (vsp1_feature(vsp1, VSP1_HAS_EXT_DL)) {
+		dlm->autfld_cmds = vsp1_dl_cmd_pool_create(vsp1,
+					VSP1_EXTCMD_AUTOFLD, prealloc);
+		if (!dlm->autfld_cmds) {
+			vsp1_dlm_destroy(dlm);
+			return NULL;
+		}
+	}
+
 	return dlm;
 }
 
@@ -879,4 +1052,20 @@ void vsp1_dlm_destroy(struct vsp1_dl_manager *dlm)
 	}
 
 	vsp1_dl_body_pool_destroy(dlm->pool);
+	vsp1_dl_ext_cmd_pool_destroy(dlm->autfld_cmds);
+}
+
+struct vsp1_dl_ext_cmd *vsp1_dlm_get_autofld_cmd(struct vsp1_dl_list *dl)
+{
+	struct vsp1_dl_manager *dlm = dl->dlm;
+	struct vsp1_dl_ext_cmd *cmd;
+
+	if (dl->pre_cmd)
+		return dl->pre_cmd;
+
+	cmd = vsp1_dl_ext_cmd_get(dlm->autfld_cmds);
+	if (cmd)
+		dl->pre_cmd = cmd;
+
+	return cmd;
 }
diff --git a/drivers/media/platform/vsp1/vsp1_dl.h b/drivers/media/platform/vsp1/vsp1_dl.h
index 4898b21dc840..3009912ddefb 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.h
+++ b/drivers/media/platform/vsp1/vsp1_dl.h
@@ -23,6 +23,7 @@ struct vsp1_dl_manager;
 
 /**
  * struct vsp1_dl_ext_cmd - Extended Display command
+ * @pool: pool to which this command belongs
  * @free: entry in the pool of free commands list
  * @cmd_opcode: command type opcode
  * @flags: flags used by the command
@@ -34,6 +35,7 @@ struct vsp1_dl_manager;
  * @data_size: size of the @data_dma memory in bytes
  */
 struct vsp1_dl_ext_cmd {
+	struct vsp1_dl_cmd_pool *pool;
 	struct list_head free;
 
 	u8 cmd_opcode;
@@ -56,6 +58,7 @@ struct vsp1_dl_manager *vsp1_dlm_create(struct vsp1_device *vsp1,
 void vsp1_dlm_destroy(struct vsp1_dl_manager *dlm);
 void vsp1_dlm_reset(struct vsp1_dl_manager *dlm);
 bool vsp1_dlm_irq_frame_end(struct vsp1_dl_manager *dlm);
+struct vsp1_dl_ext_cmd *vsp1_dlm_get_autofld_cmd(struct vsp1_dl_list *dl);
 
 struct vsp1_dl_list *vsp1_dl_list_get(struct vsp1_dl_manager *dlm);
 void vsp1_dl_list_put(struct vsp1_dl_list *dl);
-- 
git-series 0.9.1

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

* [PATCH 10/11] media: vsp1: Support Interlaced display pipelines
       [not found] <cover.50cd35ac550b4477f13fb4f3fbd3ffb6bcccfc8a.1520632434.git-series.kieran.bingham+renesas@ideasonboard.com>
                   ` (8 preceding siblings ...)
  2018-03-09 22:04 ` [PATCH 09/11] media: vsp1: Provide support for extended command pools Kieran Bingham
@ 2018-03-09 22:04 ` Kieran Bingham
  2018-03-09 22:04 ` [PATCH 11/11] drm: rcar-du: Support interlaced video output through vsp1 Kieran Bingham
  10 siblings, 0 replies; 19+ messages in thread
From: Kieran Bingham @ 2018-03-09 22:04 UTC (permalink / raw)
  To: Laurent Pinchart, linux-renesas-soc, linux-media
  Cc: Kieran Bingham, Mauro Carvalho Chehab, open list

Calculate the top and bottom fields for the interlaced frames and
utilise the extended display list command feature to implement the
auto-field operations. This allows the DU to update the VSP2 registers
dynamically based upon the currently processing field.

Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
---
 drivers/media/platform/vsp1/vsp1_dl.c   | 10 +++-
 drivers/media/platform/vsp1/vsp1_dl.h   |  2 +-
 drivers/media/platform/vsp1/vsp1_drm.c  | 12 ++++-
 drivers/media/platform/vsp1/vsp1_pipe.c |  3 +-
 drivers/media/platform/vsp1/vsp1_regs.h |  1 +-
 drivers/media/platform/vsp1/vsp1_rpf.c  | 72 ++++++++++++++++++++++++--
 drivers/media/platform/vsp1/vsp1_rwpf.h |  1 +-
 include/media/vsp1.h                    |  1 +-
 8 files changed, 96 insertions(+), 6 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c
index 6d17b8bfa21c..4a079060864b 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -886,8 +886,9 @@ void vsp1_dl_list_commit(struct vsp1_dl_list *dl)
  * with the frame end interrupt. The function always returns true in header mode
  * as display list processing is then not continuous and races never occur.
  */
-bool vsp1_dlm_irq_frame_end(struct vsp1_dl_manager *dlm)
+bool vsp1_dlm_irq_frame_end(struct vsp1_dl_manager *dlm, bool interlaced)
 {
+	struct vsp1_device *vsp1 = dlm->vsp1;
 	bool completed = false;
 
 	spin_lock(&dlm->lock);
@@ -912,6 +913,13 @@ bool vsp1_dlm_irq_frame_end(struct vsp1_dl_manager *dlm)
 	if (vsp1_dl_list_hw_update_pending(dlm))
 		goto done;
 
+	if (interlaced) {
+		u32 status = vsp1_read(vsp1, VI6_STATUS);
+
+		if (!(status & VI6_STATUS_FLD_STD(dlm->index)))
+			goto done;
+	}
+
 	/*
 	 * The device starts processing the queued display list right after the
 	 * frame end interrupt. The display list thus becomes active.
diff --git a/drivers/media/platform/vsp1/vsp1_dl.h b/drivers/media/platform/vsp1/vsp1_dl.h
index 3009912ddefb..24a9fb53223a 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.h
+++ b/drivers/media/platform/vsp1/vsp1_dl.h
@@ -57,7 +57,7 @@ struct vsp1_dl_manager *vsp1_dlm_create(struct vsp1_device *vsp1,
 					unsigned int prealloc);
 void vsp1_dlm_destroy(struct vsp1_dl_manager *dlm);
 void vsp1_dlm_reset(struct vsp1_dl_manager *dlm);
-bool vsp1_dlm_irq_frame_end(struct vsp1_dl_manager *dlm);
+bool vsp1_dlm_irq_frame_end(struct vsp1_dl_manager *dlm, bool interlaced);
 struct vsp1_dl_ext_cmd *vsp1_dlm_get_autofld_cmd(struct vsp1_dl_list *dl);
 
 struct vsp1_dl_list *vsp1_dl_list_get(struct vsp1_dl_manager *dlm);
diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c
index 0459b970e9da..d7028de053ae 100644
--- a/drivers/media/platform/vsp1/vsp1_drm.c
+++ b/drivers/media/platform/vsp1/vsp1_drm.c
@@ -329,6 +329,7 @@ int vsp1_du_atomic_update(struct device *dev, unsigned int pipe_index,
 	struct vsp1_device *vsp1 = dev_get_drvdata(dev);
 	struct vsp1_drm_pipeline *drm_pipe = &vsp1->drm->pipe[pipe_index];
 	const struct vsp1_format_info *fmtinfo;
+	struct vsp1_rwpf *output = drm_pipe->pipe.output;
 	struct vsp1_rwpf *rpf;
 
 	if (rpf_index >= vsp1->info->rpf_count)
@@ -368,6 +369,17 @@ int vsp1_du_atomic_update(struct device *dev, unsigned int pipe_index,
 		return -EINVAL;
 	}
 
+	if (!(vsp1_feature(vsp1, VSP1_HAS_EXT_DL)) && cfg->interlaced) {
+		/*
+		 * Interlaced support requires extended display lists to
+		 * provide the auto-fld feature with the DU.
+		 */
+		dev_dbg(vsp1->dev, "Interlaced unsupported on this output\n");
+		return -EINVAL;
+	}
+
+	rpf->interlaced = output->interlaced = cfg->interlaced;
+
 	rpf->fmtinfo = fmtinfo;
 	rpf->format.num_planes = fmtinfo->planes;
 	rpf->format.plane_fmt[0].bytesperline = cfg->pitch;
diff --git a/drivers/media/platform/vsp1/vsp1_pipe.c b/drivers/media/platform/vsp1/vsp1_pipe.c
index fa445b1a2e38..df674b3bb9a0 100644
--- a/drivers/media/platform/vsp1/vsp1_pipe.c
+++ b/drivers/media/platform/vsp1/vsp1_pipe.c
@@ -341,7 +341,8 @@ void vsp1_pipeline_frame_end(struct vsp1_pipeline *pipe)
 	 * up being postponed by one frame. @completed represents whether the
 	 * active frame was finished or postponed.
 	 */
-	completed = vsp1_dlm_irq_frame_end(pipe->output->dlm);
+	completed = vsp1_dlm_irq_frame_end(pipe->output->dlm,
+					   pipe->output->interlaced);
 
 	if (pipe->hgo)
 		vsp1_hgo_frame_end(pipe->hgo);
diff --git a/drivers/media/platform/vsp1/vsp1_regs.h b/drivers/media/platform/vsp1/vsp1_regs.h
index 43ad68ff3167..e2dffbe82809 100644
--- a/drivers/media/platform/vsp1/vsp1_regs.h
+++ b/drivers/media/platform/vsp1/vsp1_regs.h
@@ -31,6 +31,7 @@
 #define VI6_SRESET_SRTS(n)		(1 << (n))
 
 #define VI6_STATUS			0x0038
+#define VI6_STATUS_FLD_STD(n)		(1 << ((n) + 28))
 #define VI6_STATUS_SYS_ACT(n)		(1 << ((n) + 8))
 
 #define VI6_WPF_IRQ_ENB(n)		(0x0048 + (n) * 12)
diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c
index 67f2fb3e0611..51c02a1d40e5 100644
--- a/drivers/media/platform/vsp1/vsp1_rpf.c
+++ b/drivers/media/platform/vsp1/vsp1_rpf.c
@@ -24,6 +24,20 @@
 #define RPF_MAX_WIDTH				8190
 #define RPF_MAX_HEIGHT				8190
 
+/* Pre extended display list command data structure */
+struct vsp1_extcmd_auto_fld_body {
+	u32 top_y0;
+	u32 bottom_y0;
+	u32 top_c0;
+	u32 bottom_c0;
+	u32 top_c1;
+	u32 bottom_c1;
+	u32 reserved0;
+	u32 reserved1;
+} __packed;
+
+#define VSP1_DL_EXT_AUTOFLD_INT		BIT(1)
+
 /* -----------------------------------------------------------------------------
  * Device Access
  */
@@ -68,6 +82,14 @@ static void rpf_configure_stream(struct vsp1_entity *entity,
 		pstride |= format->plane_fmt[1].bytesperline
 			<< VI6_RPF_SRCM_PSTRIDE_C_SHIFT;
 
+	/*
+	 * pstride has both STRIDE_Y and STRIDE_C, but multiplying the whole
+	 * of pstride by 2 is conveniently OK here as we are multiplying both
+	 * values.
+	 */
+	if (rpf->interlaced)
+		pstride *= 2;
+
 	vsp1_rpf_write(rpf, dlb, VI6_RPF_SRCM_PSTRIDE, pstride);
 
 	/* Format */
@@ -104,6 +126,9 @@ static void rpf_configure_stream(struct vsp1_entity *entity,
 		top = compose->top;
 	}
 
+	if (rpf->interlaced)
+		top /= 2;
+
 	vsp1_rpf_write(rpf, dlb, VI6_RPF_LOC,
 		       (left << VI6_RPF_LOC_HCOORD_SHIFT) |
 		       (top << VI6_RPF_LOC_VCOORD_SHIFT));
@@ -173,6 +198,31 @@ static void rpf_configure_stream(struct vsp1_entity *entity,
 
 }
 
+static void vsp1_rpf_configure_autofld(struct vsp1_rwpf *rpf,
+				       struct vsp1_dl_ext_cmd *cmd)
+{
+	const struct v4l2_pix_format_mplane *format = &rpf->format;
+	struct vsp1_extcmd_auto_fld_body *auto_fld = cmd->data;
+	u32 offset_y, offset_c;
+
+	/* Re-index our auto_fld to match the current RPF */
+	auto_fld = &auto_fld[rpf->entity.index];
+
+	auto_fld->top_y0 = rpf->mem.addr[0];
+	auto_fld->top_c0 = rpf->mem.addr[1];
+	auto_fld->top_c1 = rpf->mem.addr[2];
+
+	offset_y = format->plane_fmt[0].bytesperline;
+	offset_c = format->plane_fmt[1].bytesperline;
+
+	auto_fld->bottom_y0 = rpf->mem.addr[0] + offset_y;
+	auto_fld->bottom_c0 = rpf->mem.addr[1] + offset_c;
+	auto_fld->bottom_c1 = rpf->mem.addr[2] + offset_c;
+
+	cmd->flags |= VSP1_DL_EXT_AUTOFLD_INT;
+	cmd->flags |= BIT(16 + rpf->entity.index);
+}
+
 static void rpf_configure_frame(struct vsp1_entity *entity,
 				struct vsp1_pipeline *pipe,
 				struct vsp1_dl_list *dl,
@@ -182,6 +232,7 @@ static void rpf_configure_frame(struct vsp1_entity *entity,
 	struct vsp1_rwpf *rpf = to_rwpf(&entity->subdev);
 	struct vsp1_rwpf_memory mem = rpf->mem;
 	struct vsp1_device *vsp1 = rpf->entity.vsp1;
+	struct vsp1_dl_ext_cmd *cmd;
 	const struct vsp1_format_info *fmtinfo = rpf->fmtinfo;
 	const struct v4l2_pix_format_mplane *format = &rpf->format;
 	struct v4l2_rect crop;
@@ -220,6 +271,11 @@ static void rpf_configure_frame(struct vsp1_entity *entity,
 		crop.left += pipe->partition->rpf.left;
 	}
 
+	if (rpf->interlaced) {
+		crop.height = round_down(crop.height / 2, fmtinfo->vsub);
+		crop.top = round_down(crop.top / 2, fmtinfo->vsub);
+	}
+
 	vsp1_rpf_write(rpf, dlb, VI6_RPF_SRC_BSIZE,
 		       (crop.width << VI6_RPF_SRC_BSIZE_BHSIZE_SHIFT) |
 		       (crop.height << VI6_RPF_SRC_BSIZE_BVSIZE_SHIFT));
@@ -248,11 +304,21 @@ static void rpf_configure_frame(struct vsp1_entity *entity,
 	    fmtinfo->swap_uv)
 		swap(mem.addr[1], mem.addr[2]);
 
-	vsp1_rpf_write(rpf, dlb, VI6_RPF_SRCM_ADDR_Y, mem.addr[0]);
-	vsp1_rpf_write(rpf, dlb, VI6_RPF_SRCM_ADDR_C0, mem.addr[1]);
-	vsp1_rpf_write(rpf, dlb, VI6_RPF_SRCM_ADDR_C1, mem.addr[2]);
+	/*
+	 * Interlaced pipelines will use the extended pre-cmd to process
+	 * SRCM_ADDR_{Y,C0,C1}
+	 */
+	if (rpf->interlaced) {
+		cmd = vsp1_dlm_get_autofld_cmd(dl);
+		vsp1_rpf_configure_autofld(rpf, cmd);
+	} else {
+		vsp1_rpf_write(rpf, dlb, VI6_RPF_SRCM_ADDR_Y, mem.addr[0]);
+		vsp1_rpf_write(rpf, dlb, VI6_RPF_SRCM_ADDR_C0, mem.addr[1]);
+		vsp1_rpf_write(rpf, dlb, VI6_RPF_SRCM_ADDR_C1, mem.addr[2]);
+	}
 }
 
+
 static void rpf_partition(struct vsp1_entity *entity,
 			  struct vsp1_pipeline *pipe,
 			  struct vsp1_partition *partition,
diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.h b/drivers/media/platform/vsp1/vsp1_rwpf.h
index 58215a7ab631..27ada15e8f00 100644
--- a/drivers/media/platform/vsp1/vsp1_rwpf.h
+++ b/drivers/media/platform/vsp1/vsp1_rwpf.h
@@ -47,6 +47,7 @@ struct vsp1_rwpf {
 
 	struct v4l2_pix_format_mplane format;
 	const struct vsp1_format_info *fmtinfo;
+	bool interlaced;
 	unsigned int bru_input;
 
 	unsigned int alpha;
diff --git a/include/media/vsp1.h b/include/media/vsp1.h
index 68a8abe4fac5..1f7e1dfe0c12 100644
--- a/include/media/vsp1.h
+++ b/include/media/vsp1.h
@@ -49,6 +49,7 @@ struct vsp1_du_atomic_config {
 	struct v4l2_rect dst;
 	unsigned int alpha;
 	unsigned int zpos;
+	bool interlaced;
 };
 
 void vsp1_du_atomic_begin(struct device *dev, unsigned int pipe_index);
-- 
git-series 0.9.1

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

* [PATCH 11/11] drm: rcar-du: Support interlaced video output through vsp1
       [not found] <cover.50cd35ac550b4477f13fb4f3fbd3ffb6bcccfc8a.1520632434.git-series.kieran.bingham+renesas@ideasonboard.com>
                   ` (9 preceding siblings ...)
  2018-03-09 22:04 ` [PATCH 10/11] media: vsp1: Support Interlaced display pipelines Kieran Bingham
@ 2018-03-09 22:04 ` Kieran Bingham
  10 siblings, 0 replies; 19+ messages in thread
From: Kieran Bingham @ 2018-03-09 22:04 UTC (permalink / raw)
  To: Laurent Pinchart, linux-renesas-soc, linux-media
  Cc: Kieran Bingham, David Airlie, open list:DRM DRIVERS FOR RENESAS,
	open list

Use the newly exposed VSP1 interface to enable interlaced frame support
through the VSP1 lif pipelines.

Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
---
 drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 1 +
 drivers/gpu/drm/rcar-du/rcar_du_vsp.c  | 3 +++
 2 files changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index 5685d5af6998..9854d9deb944 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -248,6 +248,7 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
 	/* Signal polarities */
 	value = ((mode->flags & DRM_MODE_FLAG_PVSYNC) ? DSMR_VSL : 0)
 	      | ((mode->flags & DRM_MODE_FLAG_PHSYNC) ? DSMR_HSL : 0)
+	      | ((mode->flags & DRM_MODE_FLAG_INTERLACE) ? DSMR_ODEV : 0)
 	      | DSMR_DIPM_DISP | DSMR_CSPM;
 	rcar_du_crtc_write(rcrtc, DSMR, value);
 
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
index 2c260c33840b..5e47daef8bd2 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
@@ -178,6 +178,9 @@ static void rcar_du_vsp_plane_setup(struct rcar_du_vsp_plane *plane)
 	};
 	unsigned int i;
 
+	cfg.interlaced = !!(plane->plane.state->crtc->mode.flags
+			    & DRM_MODE_FLAG_INTERLACE);
+
 	cfg.src.left = state->state.src.x1 >> 16;
 	cfg.src.top = state->state.src.y1 >> 16;
 	cfg.src.width = drm_rect_width(&state->state.src) >> 16;
-- 
git-series 0.9.1

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

* Re: [PATCH 09/11] media: vsp1: Provide support for extended command pools
  2018-03-09 22:04 ` [PATCH 09/11] media: vsp1: Provide support for extended command pools Kieran Bingham
@ 2018-03-10 11:26   ` Kieran Bingham
  2018-03-12 16:30   ` jacopo mondi
  1 sibling, 0 replies; 19+ messages in thread
From: Kieran Bingham @ 2018-03-10 11:26 UTC (permalink / raw)
  To: Laurent Pinchart, linux-renesas-soc, linux-media
  Cc: Mauro Carvalho Chehab, open list

On 09/03/18 22:04, Kieran Bingham wrote:
> VSPD and VSP-DL devices can provide extended display lists supporting
> extended command display list objects.
> 
> These extended commands require their own dma memory areas for a header
> and body specific to the command type.
> 
> Implement a command pool to allocate all necessary memory in a single
> DMA allocation to reduce pressure on the TLB, and provide convenvient

s/convenvient/convenient/

> re-usable command objects for the entities to utilise.
> Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
> ---

I feel like this adds quite a bit of 'duplication' against the body pool
implementation - and there is scope for re-factoring somehow to make a lot more
of this common.

I think this is still fine to go in as is for now (as an approach that is) - but
I'd like to work out how to make this better as a later task.

Then with a reusable implementation then we can easily move the excess display
list headers (which are currently being allocated 1 for *every dlb* rather than
1 for every dl) to their own pool and allocate as appropriate.

Essentially we have the following 'object's which want to have minimal DMA
allocations (to reduce TLB pressure) - and are all sharing the same size.

 - Display list headers (72 or 96 bytes)
 - Display list bodys   (variable size - multiple per header)
if (VSPD) {
 - Extended display list header (16 bytes * number of bodies)
 - Extended display list body   (autodisp 96 bytes, autofld 160 bytes)
}

The dma_pool API's don't seem to be suitable here because as far as I can tell
it is still calling dma_alloc_coherent for each page.., rather than creating a
large pre-allocated slab and carving from it.

There certainly doesn't seem to be a way to say the number of elements to
pre-allocate... If I'm missing something obvious here - I'd love to hear it as I
don't want to re-invent any wheels!

Surely this similar pattern occurs elsewhere in the kernel ?

--
Kieran


>  drivers/media/platform/vsp1/vsp1_dl.c | 189 +++++++++++++++++++++++++++-
>  drivers/media/platform/vsp1/vsp1_dl.h |   3 +-
>  2 files changed, 192 insertions(+)
> 
> diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c
> index 36440a2a2c8b..6d17b8bfa21c 100644
> --- a/drivers/media/platform/vsp1/vsp1_dl.c
> +++ b/drivers/media/platform/vsp1/vsp1_dl.c
> @@ -121,6 +121,30 @@ struct vsp1_dl_body_pool {
>  };
>  
>  /**
> + * struct vsp1_cmd_pool - display list body pool
> + * @dma: DMA address of the entries
> + * @size: size of the full DMA memory pool in bytes
> + * @mem: CPU memory pointer for the pool
> + * @bodies: Array of DLB structures for the pool
> + * @free: List of free DLB entries
> + * @lock: Protects the pool and free list
> + * @vsp1: the VSP1 device
> + */
> +struct vsp1_dl_cmd_pool {
> +	/* DMA allocation */
> +	dma_addr_t dma;
> +	size_t size;
> +	void *mem;
> +
> +	struct vsp1_dl_ext_cmd *cmds;
> +	struct list_head free;
> +
> +	spinlock_t lock;
> +
> +	struct vsp1_device *vsp1;
> +};
> +
> +/**
>   * struct vsp1_dl_list - Display list
>   * @list: entry in the display list manager lists
>   * @dlm: the display list manager
> @@ -176,6 +200,7 @@ struct vsp1_dl_manager {
>  	struct vsp1_dl_list *pending;
>  
>  	struct vsp1_dl_body_pool *pool;
> +	struct vsp1_dl_cmd_pool *autfld_cmds;
>  };
>  
>  /* -----------------------------------------------------------------------------
> @@ -339,6 +364,139 @@ void vsp1_dl_body_write(struct vsp1_dl_body *dlb, u32 reg, u32 data)
>  }
>  
>  /* -----------------------------------------------------------------------------
> + * Display List Extended Command Management
> + */
> +
> +enum vsp1_extcmd_type {
> +	VSP1_EXTCMD_AUTODISP,
> +	VSP1_EXTCMD_AUTOFLD,
> +};
> +
> +struct vsp1_extended_command_info {
> +	u16 opcode;
> +	size_t body_size;
> +} vsp1_extended_commands[] = {
> +	[VSP1_EXTCMD_AUTODISP] = { 0x02, 96 },
> +	[VSP1_EXTCMD_AUTOFLD]  = { 0x03, 160 },
> +};
> +
> +/**
> + * vsp1_dl_cmd_pool_create - Create a pool of commands from a single allocation
> + * @vsp1: The VSP1 device
> + * @type: The command pool type
> + * @num_commands: The quantity of commands to allocate
> + *
> + * Allocate a pool of commands each with enough memory to contain the private
> + * data of each command. The allocation sizes are dependent upon the command
> + * type.
> + *
> + * Return a pointer to a pool on success or NULL if memory can't be allocated.
> + */
> +struct vsp1_dl_cmd_pool *
> +vsp1_dl_cmd_pool_create(struct vsp1_device *vsp1, enum vsp1_extcmd_type type,
> +			unsigned int num_cmds)
> +{
> +	struct vsp1_dl_cmd_pool *pool;
> +	unsigned int i;
> +	size_t cmd_size;
> +
> +	pool = kzalloc(sizeof(*pool), GFP_KERNEL);
> +	if (!pool)
> +		return NULL;
> +
> +	pool->cmds = kcalloc(num_cmds, sizeof(*pool->cmds), GFP_KERNEL);
> +	if (!pool->cmds) {
> +		kfree(pool);
> +		return NULL;
> +	}
> +
> +	cmd_size = sizeof(struct vsp1_dl_ext_cmd_header) +
> +		   vsp1_extended_commands[type].body_size;
> +	cmd_size = ALIGN(cmd_size, 16);
> +
> +	pool->size = cmd_size * num_cmds;
> +	pool->mem = dma_alloc_wc(vsp1->bus_master, pool->size, &pool->dma,
> +				 GFP_KERNEL);
> +	if (!pool->mem) {
> +		kfree(pool->cmds);
> +		kfree(pool);
> +		return NULL;
> +	}
> +
> +	spin_lock_init(&pool->lock);
> +	INIT_LIST_HEAD(&pool->free);
> +
> +	for (i = 0; i < num_cmds; ++i) {
> +		struct vsp1_dl_ext_cmd *cmd = &pool->cmds[i];
> +		size_t cmd_offset = i * cmd_size;
> +		size_t data_offset = sizeof(struct vsp1_dl_ext_cmd_header) +
> +				     cmd_offset;
> +
> +		cmd->pool = pool;
> +		cmd->cmd_opcode = vsp1_extended_commands[type].opcode;
> +
> +		/* TODO: Auto-disp can utilise more than one command per cmd */
> +		cmd->num_cmds = 1;
> +		cmd->cmds = pool->mem + cmd_offset;
> +		cmd->cmd_dma = pool->dma + cmd_offset;
> +
> +		cmd->data = pool->mem + data_offset;
> +		cmd->data_dma = pool->dma + data_offset;
> +		cmd->data_size = vsp1_extended_commands[type].body_size;
> +
> +		list_add_tail(&cmd->free, &pool->free);
> +	}
> +
> +	return pool;
> +}
> +
> +struct vsp1_dl_ext_cmd *vsp1_dl_ext_cmd_get(struct vsp1_dl_cmd_pool *pool)
> +{
> +	struct vsp1_dl_ext_cmd *cmd = NULL;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&pool->lock, flags);
> +
> +	if (!list_empty(&pool->free)) {
> +		cmd = list_first_entry(&pool->free, struct vsp1_dl_ext_cmd,
> +				       free);
> +		list_del(&cmd->free);
> +	}
> +
> +	spin_unlock_irqrestore(&pool->lock, flags);
> +
> +	return cmd;
> +}
> +
> +void vsp1_dl_ext_cmd_put(struct vsp1_dl_ext_cmd *cmd)
> +{
> +	unsigned long flags;
> +
> +	if (!cmd)
> +		return;
> +
> +	/* Reset flags, these mark data usage */
> +	cmd->flags = 0;
> +
> +	spin_lock_irqsave(&cmd->pool->lock, flags);
> +	list_add_tail(&cmd->free, &cmd->pool->free);
> +	spin_unlock_irqrestore(&cmd->pool->lock, flags);
> +}
> +
> +void vsp1_dl_ext_cmd_pool_destroy(struct vsp1_dl_cmd_pool *pool)
> +{
> +	if (!pool)
> +		return;
> +
> +	if (pool->mem)
> +		dma_free_wc(pool->vsp1->bus_master, pool->size, pool->mem,
> +			    pool->dma);
> +
> +	kfree(pool->cmds);
> +	kfree(pool);
> +}
> +
> +/* ----------------------------------------------------------------------------
>   * Display List Transaction Management
>   */
>  
> @@ -442,6 +600,12 @@ static void __vsp1_dl_list_put(struct vsp1_dl_list *dl)
>  
>  	vsp1_dl_list_bodies_put(dl);
>  
> +	vsp1_dl_ext_cmd_put(dl->pre_cmd);
> +	vsp1_dl_ext_cmd_put(dl->post_cmd);
> +
> +	dl->pre_cmd = NULL;
> +	dl->post_cmd = NULL;
> +
>  	/*
>  	 * body0 is reused as as an optimisation as presently every display list
>  	 * has at least one body, thus we reinitialise the entries list
> @@ -863,6 +1027,15 @@ struct vsp1_dl_manager *vsp1_dlm_create(struct vsp1_device *vsp1,
>  		list_add_tail(&dl->list, &dlm->free);
>  	}
>  
> +	if (vsp1_feature(vsp1, VSP1_HAS_EXT_DL)) {
> +		dlm->autfld_cmds = vsp1_dl_cmd_pool_create(vsp1,
> +					VSP1_EXTCMD_AUTOFLD, prealloc);
> +		if (!dlm->autfld_cmds) {
> +			vsp1_dlm_destroy(dlm);
> +			return NULL;
> +		}
> +	}
> +
>  	return dlm;
>  }
>  
> @@ -879,4 +1052,20 @@ void vsp1_dlm_destroy(struct vsp1_dl_manager *dlm)
>  	}
>  
>  	vsp1_dl_body_pool_destroy(dlm->pool);
> +	vsp1_dl_ext_cmd_pool_destroy(dlm->autfld_cmds);
> +}
> +
> +struct vsp1_dl_ext_cmd *vsp1_dlm_get_autofld_cmd(struct vsp1_dl_list *dl)
> +{
> +	struct vsp1_dl_manager *dlm = dl->dlm;
> +	struct vsp1_dl_ext_cmd *cmd;
> +
> +	if (dl->pre_cmd)
> +		return dl->pre_cmd;
> +
> +	cmd = vsp1_dl_ext_cmd_get(dlm->autfld_cmds);
> +	if (cmd)
> +		dl->pre_cmd = cmd;
> +
> +	return cmd;
>  }
> diff --git a/drivers/media/platform/vsp1/vsp1_dl.h b/drivers/media/platform/vsp1/vsp1_dl.h
> index 4898b21dc840..3009912ddefb 100644
> --- a/drivers/media/platform/vsp1/vsp1_dl.h
> +++ b/drivers/media/platform/vsp1/vsp1_dl.h
> @@ -23,6 +23,7 @@ struct vsp1_dl_manager;
>  
>  /**
>   * struct vsp1_dl_ext_cmd - Extended Display command
> + * @pool: pool to which this command belongs
>   * @free: entry in the pool of free commands list
>   * @cmd_opcode: command type opcode
>   * @flags: flags used by the command
> @@ -34,6 +35,7 @@ struct vsp1_dl_manager;
>   * @data_size: size of the @data_dma memory in bytes
>   */
>  struct vsp1_dl_ext_cmd {
> +	struct vsp1_dl_cmd_pool *pool;
>  	struct list_head free;
>  
>  	u8 cmd_opcode;
> @@ -56,6 +58,7 @@ struct vsp1_dl_manager *vsp1_dlm_create(struct vsp1_device *vsp1,
>  void vsp1_dlm_destroy(struct vsp1_dl_manager *dlm);
>  void vsp1_dlm_reset(struct vsp1_dl_manager *dlm);
>  bool vsp1_dlm_irq_frame_end(struct vsp1_dl_manager *dlm);
> +struct vsp1_dl_ext_cmd *vsp1_dlm_get_autofld_cmd(struct vsp1_dl_list *dl);
>  
>  struct vsp1_dl_list *vsp1_dl_list_get(struct vsp1_dl_manager *dlm);
>  void vsp1_dl_list_put(struct vsp1_dl_list *dl);
> 

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

* Re: [PATCH 09/11] media: vsp1: Provide support for extended command pools
  2018-03-09 22:04 ` [PATCH 09/11] media: vsp1: Provide support for extended command pools Kieran Bingham
  2018-03-10 11:26   ` Kieran Bingham
@ 2018-03-12 16:30   ` jacopo mondi
  2018-03-13 10:27     ` Kieran Bingham
  1 sibling, 1 reply; 19+ messages in thread
From: jacopo mondi @ 2018-03-12 16:30 UTC (permalink / raw)
  To: Kieran Bingham
  Cc: Laurent Pinchart, linux-renesas-soc, linux-media,
	Mauro Carvalho Chehab, open list

[-- Attachment #1: Type: text/plain, Size: 2709 bytes --]

Hi Kieran,
    just one small thing I noticed below...

On Fri, Mar 09, 2018 at 10:04:07PM +0000, Kieran Bingham wrote:
> VSPD and VSP-DL devices can provide extended display lists supporting
> extended command display list objects.
>
> These extended commands require their own dma memory areas for a header
> and body specific to the command type.
>
> Implement a command pool to allocate all necessary memory in a single
> DMA allocation to reduce pressure on the TLB, and provide convenvient
> re-usable command objects for the entities to utilise.
>
> Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
> ---
>  drivers/media/platform/vsp1/vsp1_dl.c | 189 +++++++++++++++++++++++++++-
>  drivers/media/platform/vsp1/vsp1_dl.h |   3 +-
>  2 files changed, 192 insertions(+)
>
> diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c
> index 36440a2a2c8b..6d17b8bfa21c 100644
> --- a/drivers/media/platform/vsp1/vsp1_dl.c
> +++ b/drivers/media/platform/vsp1/vsp1_dl.c
> @@ -121,6 +121,30 @@ struct vsp1_dl_body_pool {
>  };
>
>  /**
> + * struct vsp1_cmd_pool - display list body pool
> + * @dma: DMA address of the entries
> + * @size: size of the full DMA memory pool in bytes
> + * @mem: CPU memory pointer for the pool
> + * @bodies: Array of DLB structures for the pool
> + * @free: List of free DLB entries
> + * @lock: Protects the pool and free list
> + * @vsp1: the VSP1 device
> + */
> +struct vsp1_dl_cmd_pool {
> +	/* DMA allocation */
> +	dma_addr_t dma;
> +	size_t size;
> +	void *mem;
> +
> +	struct vsp1_dl_ext_cmd *cmds;
> +	struct list_head free;
> +
> +	spinlock_t lock;
> +
> +	struct vsp1_device *vsp1;
> +};
> +
> +/**
>   * struct vsp1_dl_list - Display list
>   * @list: entry in the display list manager lists
>   * @dlm: the display list manager
> @@ -176,6 +200,7 @@ struct vsp1_dl_manager {
>  	struct vsp1_dl_list *pending;
>
>  	struct vsp1_dl_body_pool *pool;
> +	struct vsp1_dl_cmd_pool *autfld_cmds;
>  };
>
>  /* -----------------------------------------------------------------------------
> @@ -339,6 +364,139 @@ void vsp1_dl_body_write(struct vsp1_dl_body *dlb, u32 reg, u32 data)
>  }
>
>  /* -----------------------------------------------------------------------------
> + * Display List Extended Command Management
> + */
> +
> +enum vsp1_extcmd_type {
> +	VSP1_EXTCMD_AUTODISP,
> +	VSP1_EXTCMD_AUTOFLD,
> +};
> +
> +struct vsp1_extended_command_info {
> +	u16 opcode;
> +	size_t body_size;
> +} vsp1_extended_commands[] = {
> +	[VSP1_EXTCMD_AUTODISP] = { 0x02, 96 },
> +	[VSP1_EXTCMD_AUTOFLD]  = { 0x03, 160 },
> +};

How about making this one static and const, since it does not get
modified?

Thanks
   j

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [PATCH 09/11] media: vsp1: Provide support for extended command pools
  2018-03-12 16:30   ` jacopo mondi
@ 2018-03-13 10:27     ` Kieran Bingham
  0 siblings, 0 replies; 19+ messages in thread
From: Kieran Bingham @ 2018-03-13 10:27 UTC (permalink / raw)
  To: jacopo mondi, Kieran Bingham
  Cc: Laurent Pinchart, linux-renesas-soc, linux-media,
	Mauro Carvalho Chehab, open list

Hi Jacopo,

On 12/03/18 16:30, jacopo mondi wrote:
> Hi Kieran,
>     just one small thing I noticed below...
> 
> On Fri, Mar 09, 2018 at 10:04:07PM +0000, Kieran Bingham wrote:
>> VSPD and VSP-DL devices can provide extended display lists supporting
>> extended command display list objects.
>>
>> These extended commands require their own dma memory areas for a header
>> and body specific to the command type.
>>
>> Implement a command pool to allocate all necessary memory in a single
>> DMA allocation to reduce pressure on the TLB, and provide convenvient
>> re-usable command objects for the entities to utilise.
>>
>> Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
>> ---
>>  drivers/media/platform/vsp1/vsp1_dl.c | 189 +++++++++++++++++++++++++++-
>>  drivers/media/platform/vsp1/vsp1_dl.h |   3 +-
>>  2 files changed, 192 insertions(+)
>>
>> diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c
>> index 36440a2a2c8b..6d17b8bfa21c 100644
>> --- a/drivers/media/platform/vsp1/vsp1_dl.c
>> +++ b/drivers/media/platform/vsp1/vsp1_dl.c
>> @@ -121,6 +121,30 @@ struct vsp1_dl_body_pool {
>>  };
>>
>>  /**
>> + * struct vsp1_cmd_pool - display list body pool
>> + * @dma: DMA address of the entries
>> + * @size: size of the full DMA memory pool in bytes
>> + * @mem: CPU memory pointer for the pool
>> + * @bodies: Array of DLB structures for the pool
>> + * @free: List of free DLB entries
>> + * @lock: Protects the pool and free list
>> + * @vsp1: the VSP1 device
>> + */
>> +struct vsp1_dl_cmd_pool {
>> +	/* DMA allocation */
>> +	dma_addr_t dma;
>> +	size_t size;
>> +	void *mem;
>> +
>> +	struct vsp1_dl_ext_cmd *cmds;
>> +	struct list_head free;
>> +
>> +	spinlock_t lock;
>> +
>> +	struct vsp1_device *vsp1;
>> +};
>> +
>> +/**
>>   * struct vsp1_dl_list - Display list
>>   * @list: entry in the display list manager lists
>>   * @dlm: the display list manager
>> @@ -176,6 +200,7 @@ struct vsp1_dl_manager {
>>  	struct vsp1_dl_list *pending;
>>
>>  	struct vsp1_dl_body_pool *pool;
>> +	struct vsp1_dl_cmd_pool *autfld_cmds;
>>  };
>>
>>  /* -----------------------------------------------------------------------------
>> @@ -339,6 +364,139 @@ void vsp1_dl_body_write(struct vsp1_dl_body *dlb, u32 reg, u32 data)
>>  }
>>
>>  /* -----------------------------------------------------------------------------
>> + * Display List Extended Command Management
>> + */
>> +
>> +enum vsp1_extcmd_type {
>> +	VSP1_EXTCMD_AUTODISP,
>> +	VSP1_EXTCMD_AUTOFLD,
>> +};
>> +
>> +struct vsp1_extended_command_info {
>> +	u16 opcode;
>> +	size_t body_size;
>> +} vsp1_extended_commands[] = {
>> +	[VSP1_EXTCMD_AUTODISP] = { 0x02, 96 },
>> +	[VSP1_EXTCMD_AUTOFLD]  = { 0x03, 160 },
>> +};
> 
> How about making this one static and const, since it does not get
> modified?

Good spot. Certainly. This is just a static descriptor table of the extended
command parameter sizes, so it should not change.  (but could be added to in
later hardware operations I presume).

Cheers

Kieran


> 
> Thanks
>    j
> 

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

* RE: [PATCH 02/11] media: vsp1: use kernel __packed for structures
  2018-03-09 22:04 ` [PATCH 02/11] media: vsp1: use kernel __packed for structures Kieran Bingham
@ 2018-03-13 11:20   ` David Laight
  2018-03-13 11:47     ` Kieran Bingham
  0 siblings, 1 reply; 19+ messages in thread
From: David Laight @ 2018-03-13 11:20 UTC (permalink / raw)
  To: 'Kieran Bingham',
	Laurent Pinchart, linux-renesas-soc, linux-media
  Cc: Mauro Carvalho Chehab, open list

From: Kieran Bingham
> Sent: 09 March 2018 22:04
> The kernel provides a __packed definition to abstract away from the
> compiler specific attributes tag.
> 
> Convert all packed structures in VSP1 to use it.
> 
> Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
> ---
>  drivers/media/platform/vsp1/vsp1_dl.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c
> index 37e2c984fbf3..382e45c2054e 100644
> --- a/drivers/media/platform/vsp1/vsp1_dl.c
> +++ b/drivers/media/platform/vsp1/vsp1_dl.c
> @@ -29,19 +29,19 @@
>  struct vsp1_dl_header_list {
>  	u32 num_bytes;
>  	u32 addr;
> -} __attribute__((__packed__));
> +} __packed;
> 
>  struct vsp1_dl_header {
>  	u32 num_lists;
>  	struct vsp1_dl_header_list lists[8];
>  	u32 next_header;
>  	u32 flags;
> -} __attribute__((__packed__));
> +} __packed;
> 
>  struct vsp1_dl_entry {
>  	u32 addr;
>  	u32 data;
> -} __attribute__((__packed__));
> +} __packed;

Do these structures ever actually appear in misaligned memory?
If they don't then they shouldn't be marked 'packed'.

	David

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

* Re: [PATCH 02/11] media: vsp1: use kernel __packed for structures
  2018-03-13 11:20   ` David Laight
@ 2018-03-13 11:47     ` Kieran Bingham
  2018-03-13 12:38       ` David Laight
  0 siblings, 1 reply; 19+ messages in thread
From: Kieran Bingham @ 2018-03-13 11:47 UTC (permalink / raw)
  To: David Laight, Laurent Pinchart, linux-renesas-soc, linux-media
  Cc: Mauro Carvalho Chehab, open list

Hi David,

On 13/03/18 11:20, David Laight wrote:
> From: Kieran Bingham
>> Sent: 09 March 2018 22:04
>> The kernel provides a __packed definition to abstract away from the
>> compiler specific attributes tag.
>>
>> Convert all packed structures in VSP1 to use it.
>>
>> Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
>> ---
>>  drivers/media/platform/vsp1/vsp1_dl.c | 6 +++---
>>  1 file changed, 3 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c
>> index 37e2c984fbf3..382e45c2054e 100644
>> --- a/drivers/media/platform/vsp1/vsp1_dl.c
>> +++ b/drivers/media/platform/vsp1/vsp1_dl.c
>> @@ -29,19 +29,19 @@
>>  struct vsp1_dl_header_list {
>>  	u32 num_bytes;
>>  	u32 addr;
>> -} __attribute__((__packed__));
>> +} __packed;
>>
>>  struct vsp1_dl_header {
>>  	u32 num_lists;
>>  	struct vsp1_dl_header_list lists[8];
>>  	u32 next_header;
>>  	u32 flags;
>> -} __attribute__((__packed__));
>> +} __packed;
>>
>>  struct vsp1_dl_entry {
>>  	u32 addr;
>>  	u32 data;
>> -} __attribute__((__packed__));
>> +} __packed;
> 
> Do these structures ever actually appear in misaligned memory?
> If they don't then they shouldn't be marked 'packed'.

I believe the declaration is to ensure that the struct definition is not altered
by the compiler as these structures specifically define the layout of how the
memory is read by the VSP1 hardware.

Certainly 2 u32's sequentially stored in a struct are unlikely to be moved or
rearranged by the compiler (though I believe it would be free to do so if it
chose without this attribute), but I think the declaration shows the intent of
the memory structure.

Isn't this a common approach throughout the kernel when dealing with hardware
defined memory structures ?

Regards
--
Kieran


> 
> 	David
> 

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

* RE: [PATCH 02/11] media: vsp1: use kernel __packed for structures
  2018-03-13 11:47     ` Kieran Bingham
@ 2018-03-13 12:38       ` David Laight
  2018-03-13 14:03         ` Kieran Bingham
  0 siblings, 1 reply; 19+ messages in thread
From: David Laight @ 2018-03-13 12:38 UTC (permalink / raw)
  To: 'kieran.bingham@ideasonboard.com',
	Laurent Pinchart, linux-renesas-soc, linux-media
  Cc: Mauro Carvalho Chehab, open list

From: Kieran Bingham [mailto:kieran.bingham+renesas@ideasonboard.com]
> On 13/03/18 11:20, David Laight wrote:
> > From: Kieran Bingham
> >> Sent: 09 March 2018 22:04
> >> The kernel provides a __packed definition to abstract away from the
> >> compiler specific attributes tag.
> >>
> >> Convert all packed structures in VSP1 to use it.
> >>
> >> Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
> >> ---
> >>  drivers/media/platform/vsp1/vsp1_dl.c | 6 +++---
> >>  1 file changed, 3 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c
> >> index 37e2c984fbf3..382e45c2054e 100644
> >> --- a/drivers/media/platform/vsp1/vsp1_dl.c
> >> +++ b/drivers/media/platform/vsp1/vsp1_dl.c
> >> @@ -29,19 +29,19 @@
> >>  struct vsp1_dl_header_list {
> >>  	u32 num_bytes;
> >>  	u32 addr;
> >> -} __attribute__((__packed__));
> >> +} __packed;
> >>
> >>  struct vsp1_dl_header {
> >>  	u32 num_lists;
> >>  	struct vsp1_dl_header_list lists[8];
> >>  	u32 next_header;
> >>  	u32 flags;
> >> -} __attribute__((__packed__));
> >> +} __packed;
> >>
> >>  struct vsp1_dl_entry {
> >>  	u32 addr;
> >>  	u32 data;
> >> -} __attribute__((__packed__));
> >> +} __packed;
> >
> > Do these structures ever actually appear in misaligned memory?
> > If they don't then they shouldn't be marked 'packed'.
> 
> I believe the declaration is to ensure that the struct definition is not altered
> by the compiler as these structures specifically define the layout of how the
> memory is read by the VSP1 hardware.

The C language and ABI define structure layouts.

> Certainly 2 u32's sequentially stored in a struct are unlikely to be moved or
> rearranged by the compiler (though I believe it would be free to do so if it
> chose without this attribute), but I think the declaration shows the intent of
> the memory structure.

The language requires the fields be in order and the ABI stops the compiler
adding 'random' padding.

> Isn't this a common approach throughout the kernel when dealing with hardware
> defined memory structures ?

Absolutely not.
__packed tells the compiler that the structure might be on any address boundary.
On many architectures this means the compiler must use byte accesses with shifts
and ors for every access.
The most a hardware defined structure will have is a compile-time assert
that it is the correct size (to avoid silly errors from changes).

	David

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

* Re: [PATCH 02/11] media: vsp1: use kernel __packed for structures
  2018-03-13 12:38       ` David Laight
@ 2018-03-13 14:03         ` Kieran Bingham
  2018-03-13 22:34           ` Kieran Bingham
  0 siblings, 1 reply; 19+ messages in thread
From: Kieran Bingham @ 2018-03-13 14:03 UTC (permalink / raw)
  To: David Laight, Laurent Pinchart, linux-renesas-soc, linux-media
  Cc: Mauro Carvalho Chehab, open list

Hi David,

On 13/03/18 13:38, David Laight wrote:
> From: Kieran Bingham [mailto:kieran.bingham+renesas@ideasonboard.com]
>> On 13/03/18 11:20, David Laight wrote:
>>> From: Kieran Bingham
>>>> Sent: 09 March 2018 22:04
>>>> The kernel provides a __packed definition to abstract away from the
>>>> compiler specific attributes tag.
>>>>
>>>> Convert all packed structures in VSP1 to use it.
>>>>
>>>> Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
>>>> ---
>>>>  drivers/media/platform/vsp1/vsp1_dl.c | 6 +++---
>>>>  1 file changed, 3 insertions(+), 3 deletions(-)
>>>>
>>>> diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c
>>>> index 37e2c984fbf3..382e45c2054e 100644
>>>> --- a/drivers/media/platform/vsp1/vsp1_dl.c
>>>> +++ b/drivers/media/platform/vsp1/vsp1_dl.c
>>>> @@ -29,19 +29,19 @@
>>>>  struct vsp1_dl_header_list {
>>>>  	u32 num_bytes;
>>>>  	u32 addr;
>>>> -} __attribute__((__packed__));
>>>> +} __packed;
>>>>
>>>>  struct vsp1_dl_header {
>>>>  	u32 num_lists;
>>>>  	struct vsp1_dl_header_list lists[8];
>>>>  	u32 next_header;
>>>>  	u32 flags;
>>>> -} __attribute__((__packed__));
>>>> +} __packed;
>>>>
>>>>  struct vsp1_dl_entry {
>>>>  	u32 addr;
>>>>  	u32 data;
>>>> -} __attribute__((__packed__));
>>>> +} __packed;
>>>
>>> Do these structures ever actually appear in misaligned memory?
>>> If they don't then they shouldn't be marked 'packed'.
>>
>> I believe the declaration is to ensure that the struct definition is not altered
>> by the compiler as these structures specifically define the layout of how the
>> memory is read by the VSP1 hardware.
> 
> The C language and ABI define structure layouts.
> 
>> Certainly 2 u32's sequentially stored in a struct are unlikely to be moved or
>> rearranged by the compiler (though I believe it would be free to do so if it
>> chose without this attribute), but I think the declaration shows the intent of
>> the memory structure.
> 
> The language requires the fields be in order and the ABI stops the compiler
> adding 'random' padding.
> 
>> Isn't this a common approach throughout the kernel when dealing with hardware
>> defined memory structures ?
> 
> Absolutely not.
> __packed tells the compiler that the structure might be on any address boundary.
> On many architectures this means the compiler must use byte accesses with shifts
> and ors for every access.
> The most a hardware defined structure will have is a compile-time assert
> that it is the correct size (to avoid silly errors from changes).



Ok - interesting, I see what you're saying - and certainly don't want the
compiler to be performing byte accesses on the structures unnecessarily.

I'm trying to distinguish the difference here. Is the single point that
 __packed

causes byte-access, where as

__attribute__((__packed__));

does not?

Looking at the GCC docs [0]: I see that  __attribute__((__packed__)) tells the
compiler that the "structure or union is placed to minimize the memory required".

However, the keil compiler docs[1] do certainly declare that __packed causes
byte alignment.

I was confused/thrown off here by the Kernel defining __packed as
__attribute__((packed)) at [2].

Do __attribute__((packed)) and __attribute__((__packed__)) differ ?

In which case, from what I've read so far I wish "__packed" was "__unaligned"...


[0]
https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-packed-type-attribute

[1] http://www.keil.com/support/man/docs/armcc/armcc_chr1359124230195.htm

[2]
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/linux/compiler-gcc.h?h=v4.16-rc5#n92


Regards

Kieran


> 	David
> 

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

* Re: [PATCH 02/11] media: vsp1: use kernel __packed for structures
  2018-03-13 14:03         ` Kieran Bingham
@ 2018-03-13 22:34           ` Kieran Bingham
  0 siblings, 0 replies; 19+ messages in thread
From: Kieran Bingham @ 2018-03-13 22:34 UTC (permalink / raw)
  To: Kieran Bingham, David Laight, Laurent Pinchart,
	linux-renesas-soc, linux-media
  Cc: Mauro Carvalho Chehab, open list

Hi David,

Just for reference here, I've posted a v2 of this patch now titled:
[PATCH v2 02/11] media: vsp1: Remove packed attributes from aligned structures

which removes the attributes instead of modifying them.

Thanks for the pointers!

Regards

Kieran

On 13/03/18 15:03, Kieran Bingham wrote:
> Hi David,
> 
> On 13/03/18 13:38, David Laight wrote:
>> From: Kieran Bingham [mailto:kieran.bingham+renesas@ideasonboard.com]
>>> On 13/03/18 11:20, David Laight wrote:
>>>> From: Kieran Bingham
>>>>> Sent: 09 March 2018 22:04
>>>>> The kernel provides a __packed definition to abstract away from the
>>>>> compiler specific attributes tag.
>>>>>
>>>>> Convert all packed structures in VSP1 to use it.
>>>>>
>>>>> Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
>>>>> ---
>>>>>  drivers/media/platform/vsp1/vsp1_dl.c | 6 +++---
>>>>>  1 file changed, 3 insertions(+), 3 deletions(-)
>>>>>
>>>>> diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c
>>>>> index 37e2c984fbf3..382e45c2054e 100644
>>>>> --- a/drivers/media/platform/vsp1/vsp1_dl.c
>>>>> +++ b/drivers/media/platform/vsp1/vsp1_dl.c
>>>>> @@ -29,19 +29,19 @@
>>>>>  struct vsp1_dl_header_list {
>>>>>  	u32 num_bytes;
>>>>>  	u32 addr;
>>>>> -} __attribute__((__packed__));
>>>>> +} __packed;
>>>>>
>>>>>  struct vsp1_dl_header {
>>>>>  	u32 num_lists;
>>>>>  	struct vsp1_dl_header_list lists[8];
>>>>>  	u32 next_header;
>>>>>  	u32 flags;
>>>>> -} __attribute__((__packed__));
>>>>> +} __packed;
>>>>>
>>>>>  struct vsp1_dl_entry {
>>>>>  	u32 addr;
>>>>>  	u32 data;
>>>>> -} __attribute__((__packed__));
>>>>> +} __packed;
>>>>
>>>> Do these structures ever actually appear in misaligned memory?
>>>> If they don't then they shouldn't be marked 'packed'.
>>>
>>> I believe the declaration is to ensure that the struct definition is not altered
>>> by the compiler as these structures specifically define the layout of how the
>>> memory is read by the VSP1 hardware.
>>
>> The C language and ABI define structure layouts.
>>
>>> Certainly 2 u32's sequentially stored in a struct are unlikely to be moved or
>>> rearranged by the compiler (though I believe it would be free to do so if it
>>> chose without this attribute), but I think the declaration shows the intent of
>>> the memory structure.
>>
>> The language requires the fields be in order and the ABI stops the compiler
>> adding 'random' padding.
>>
>>> Isn't this a common approach throughout the kernel when dealing with hardware
>>> defined memory structures ?
>>
>> Absolutely not.
>> __packed tells the compiler that the structure might be on any address boundary.
>> On many architectures this means the compiler must use byte accesses with shifts
>> and ors for every access.
>> The most a hardware defined structure will have is a compile-time assert
>> that it is the correct size (to avoid silly errors from changes).
> 
> 
> 
> Ok - interesting, I see what you're saying - and certainly don't want the
> compiler to be performing byte accesses on the structures unnecessarily.
> 
> I'm trying to distinguish the difference here. Is the single point that
>  __packed
> 
> causes byte-access, where as
> 
> __attribute__((__packed__));
> 
> does not?
> 
> Looking at the GCC docs [0]: I see that  __attribute__((__packed__)) tells the
> compiler that the "structure or union is placed to minimize the memory required".
> 
> However, the keil compiler docs[1] do certainly declare that __packed causes
> byte alignment.
> 
> I was confused/thrown off here by the Kernel defining __packed as
> __attribute__((packed)) at [2].
> 
> Do __attribute__((packed)) and __attribute__((__packed__)) differ ?
> 
> In which case, from what I've read so far I wish "__packed" was "__unaligned"...
> 
> 
> [0]
> https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-packed-type-attribute
> 
> [1] http://www.keil.com/support/man/docs/armcc/armcc_chr1359124230195.htm
> 
> [2]
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/linux/compiler-gcc.h?h=v4.16-rc5#n92
> 
> 
> Regards
> 
> Kieran
> 
> 
>> 	David
>>

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

end of thread, other threads:[~2018-03-13 22:34 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <cover.50cd35ac550b4477f13fb4f3fbd3ffb6bcccfc8a.1520632434.git-series.kieran.bingham+renesas@ideasonboard.com>
2018-03-09 22:03 ` [PATCH 01/11] media: vsp1: drm: Fix minor grammar error Kieran Bingham
2018-03-09 22:04 ` [PATCH 02/11] media: vsp1: use kernel __packed for structures Kieran Bingham
2018-03-13 11:20   ` David Laight
2018-03-13 11:47     ` Kieran Bingham
2018-03-13 12:38       ` David Laight
2018-03-13 14:03         ` Kieran Bingham
2018-03-13 22:34           ` Kieran Bingham
2018-03-09 22:04 ` [PATCH 03/11] media: vsp1: Rename dl_child to dl_next Kieran Bingham
2018-03-09 22:04 ` [PATCH 04/11] media: vsp1: Remove unused display list structure field Kieran Bingham
2018-03-09 22:04 ` [PATCH 05/11] media: vsp1: Clean up DLM objects on error Kieran Bingham
2018-03-09 22:04 ` [PATCH 06/11] media: vsp1: Provide VSP1 feature helper macro Kieran Bingham
2018-03-09 22:04 ` [PATCH 07/11] media: vsp1: Use header display lists for all WPF outputs linked to the DU Kieran Bingham
2018-03-09 22:04 ` [PATCH 08/11] media: vsp1: Add support for extended display list headers Kieran Bingham
2018-03-09 22:04 ` [PATCH 09/11] media: vsp1: Provide support for extended command pools Kieran Bingham
2018-03-10 11:26   ` Kieran Bingham
2018-03-12 16:30   ` jacopo mondi
2018-03-13 10:27     ` Kieran Bingham
2018-03-09 22:04 ` [PATCH 10/11] media: vsp1: Support Interlaced display pipelines Kieran Bingham
2018-03-09 22:04 ` [PATCH 11/11] drm: rcar-du: Support interlaced video output through vsp1 Kieran Bingham

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).