All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 00/11] R-Car DU Interlaced support through VSP1
@ 2018-05-03 13:36 ` Kieran Bingham
  0 siblings, 0 replies; 78+ messages in thread
From: Kieran Bingham @ 2018-05-03 13:36 UTC (permalink / raw)
  To: Laurent Pinchart, linux-renesas-soc, linux-media
  Cc: dri-devel, Kieran Bingham

The Gen3 R-Car DU devices make use of the VSP to handle frame processing.

In this series we implement support for handling interlaced pipelines by using
the auto-fld feature of the VSP hardware.

The implementation is preceded by some cleanup work and refactoring, through
patches 1 to 6. These are trivial and could be collected earlier and
independently if this series requires further revisions.

Patch 7 makes a key distinctive change to remove all existing support for
headerless display lists throughout the VSP1 driver, and ensures that all
pipelines use the same code path. This simplifies the code and reduces
opportunity for untested code paths to exist.

Patches 8, 9 and 10 implement the relevant support in the VSP1 driver, before
patch 11 finally enables the feature through the drm R-Car DU driver.

This series is based upon my previous TLB optimise and body rework (v9), and is
available from the following URL:

  git://git.kernel.org/pub/scm/linux/kernel/git/kbingham/rcar.git
  tags/vsp1/du/interlaced/v4

ChangeLog:

v4:
 - Move configure_partition() call changes into tlb-optimise-v9

v3:
 - Rebased on top of TLB Optimise rework v8
 - Added the DL parameter back into the configure_partition() calls.
   - This change could be moved into the TLB-Optimise series.
 - Document interlaced field in struct vsp1_du_atomic_config

v2:
 - media: vsp1: use kernel __packed for structures
    became:
   media: vsp1: Remove packed attributes from aligned structures

 - media: vsp1: Add support for extended display list headers
   - No longer declares structs __packed

 - media: vsp1: Provide support for extended command pools
   - Fix spelling typo in commit message
   - constify, and staticify the instantiation of vsp1_extended_commands
   - s/autfld_cmds/autofld_cmds/
   - staticify cmd pool functions (Thanks kbuild-bot)

 - media: vsp1: Support Interlaced display pipelines
   - fix erroneous BIT value which enabled interlaced
   - fix field handling at frame_end interrupt

Kieran Bingham (11):
  media: vsp1: drm: Fix minor grammar error
  media: vsp1: Remove packed attributes from aligned structures
  media: vsp1: Rename dl_child to dl_next
  media: vsp1: Remove unused display list structure field
  media: vsp1: Clean up DLM objects on error
  media: vsp1: Provide VSP1 feature helper macro
  media: vsp1: Use header display lists for all WPF outputs linked to the DU
  media: vsp1: Add support for extended display list headers
  media: vsp1: Provide support for extended command pools
  media: vsp1: Support Interlaced display pipelines
  drm: rcar-du: Support interlaced video output through vsp1

 drivers/gpu/drm/rcar-du/rcar_du_crtc.c  |   1 +-
 drivers/gpu/drm/rcar-du/rcar_du_vsp.c   |   3 +-
 drivers/media/platform/vsp1/vsp1.h      |   3 +-
 drivers/media/platform/vsp1/vsp1_dl.c   | 407 +++++++++++++++++++------
 drivers/media/platform/vsp1/vsp1_dl.h   |  32 +-
 drivers/media/platform/vsp1/vsp1_drm.c  |  13 +-
 drivers/media/platform/vsp1/vsp1_drv.c  |  23 +-
 drivers/media/platform/vsp1/vsp1_regs.h |   6 +-
 drivers/media/platform/vsp1/vsp1_rpf.c  |  71 +++-
 drivers/media/platform/vsp1/vsp1_rwpf.h |   1 +-
 drivers/media/platform/vsp1/vsp1_wpf.c  |   6 +-
 include/media/vsp1.h                    |   2 +-
 12 files changed, 456 insertions(+), 112 deletions(-)

base-commit: de53826416ea9c22ee985d1f0291aab7d7ea94ce
-- 
git-series 0.9.1

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

* [PATCH v4 00/11] R-Car DU Interlaced support through VSP1
@ 2018-05-03 13:36 ` Kieran Bingham
  0 siblings, 0 replies; 78+ messages in thread
From: Kieran Bingham @ 2018-05-03 13:36 UTC (permalink / raw)
  To: Laurent Pinchart, linux-renesas-soc, linux-media
  Cc: Kieran Bingham, dri-devel

The Gen3 R-Car DU devices make use of the VSP to handle frame processing.

In this series we implement support for handling interlaced pipelines by using
the auto-fld feature of the VSP hardware.

The implementation is preceded by some cleanup work and refactoring, through
patches 1 to 6. These are trivial and could be collected earlier and
independently if this series requires further revisions.

Patch 7 makes a key distinctive change to remove all existing support for
headerless display lists throughout the VSP1 driver, and ensures that all
pipelines use the same code path. This simplifies the code and reduces
opportunity for untested code paths to exist.

Patches 8, 9 and 10 implement the relevant support in the VSP1 driver, before
patch 11 finally enables the feature through the drm R-Car DU driver.

This series is based upon my previous TLB optimise and body rework (v9), and is
available from the following URL:

  git://git.kernel.org/pub/scm/linux/kernel/git/kbingham/rcar.git
  tags/vsp1/du/interlaced/v4

ChangeLog:

v4:
 - Move configure_partition() call changes into tlb-optimise-v9

v3:
 - Rebased on top of TLB Optimise rework v8
 - Added the DL parameter back into the configure_partition() calls.
   - This change could be moved into the TLB-Optimise series.
 - Document interlaced field in struct vsp1_du_atomic_config

v2:
 - media: vsp1: use kernel __packed for structures
    became:
   media: vsp1: Remove packed attributes from aligned structures

 - media: vsp1: Add support for extended display list headers
   - No longer declares structs __packed

 - media: vsp1: Provide support for extended command pools
   - Fix spelling typo in commit message
   - constify, and staticify the instantiation of vsp1_extended_commands
   - s/autfld_cmds/autofld_cmds/
   - staticify cmd pool functions (Thanks kbuild-bot)

 - media: vsp1: Support Interlaced display pipelines
   - fix erroneous BIT value which enabled interlaced
   - fix field handling at frame_end interrupt

Kieran Bingham (11):
  media: vsp1: drm: Fix minor grammar error
  media: vsp1: Remove packed attributes from aligned structures
  media: vsp1: Rename dl_child to dl_next
  media: vsp1: Remove unused display list structure field
  media: vsp1: Clean up DLM objects on error
  media: vsp1: Provide VSP1 feature helper macro
  media: vsp1: Use header display lists for all WPF outputs linked to the DU
  media: vsp1: Add support for extended display list headers
  media: vsp1: Provide support for extended command pools
  media: vsp1: Support Interlaced display pipelines
  drm: rcar-du: Support interlaced video output through vsp1

 drivers/gpu/drm/rcar-du/rcar_du_crtc.c  |   1 +-
 drivers/gpu/drm/rcar-du/rcar_du_vsp.c   |   3 +-
 drivers/media/platform/vsp1/vsp1.h      |   3 +-
 drivers/media/platform/vsp1/vsp1_dl.c   | 407 +++++++++++++++++++------
 drivers/media/platform/vsp1/vsp1_dl.h   |  32 +-
 drivers/media/platform/vsp1/vsp1_drm.c  |  13 +-
 drivers/media/platform/vsp1/vsp1_drv.c  |  23 +-
 drivers/media/platform/vsp1/vsp1_regs.h |   6 +-
 drivers/media/platform/vsp1/vsp1_rpf.c  |  71 +++-
 drivers/media/platform/vsp1/vsp1_rwpf.h |   1 +-
 drivers/media/platform/vsp1/vsp1_wpf.c  |   6 +-
 include/media/vsp1.h                    |   2 +-
 12 files changed, 456 insertions(+), 112 deletions(-)

base-commit: de53826416ea9c22ee985d1f0291aab7d7ea94ce
-- 
git-series 0.9.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH v4 01/11] media: vsp1: drm: Fix minor grammar error
  2018-05-03 13:36 ` Kieran Bingham
@ 2018-05-03 13:36   ` Kieran Bingham
  -1 siblings, 0 replies; 78+ messages in thread
From: Kieran Bingham @ 2018-05-03 13:36 UTC (permalink / raw)
  To: Laurent Pinchart, linux-renesas-soc, linux-media
  Cc: dri-devel, Kieran Bingham

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 ef0148082bf7..2c3db8b8adce 100644
--- a/drivers/media/platform/vsp1/vsp1_drm.c
+++ b/drivers/media/platform/vsp1/vsp1_drm.c
@@ -806,7 +806,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] 78+ messages in thread

* [PATCH v4 01/11] media: vsp1: drm: Fix minor grammar error
@ 2018-05-03 13:36   ` Kieran Bingham
  0 siblings, 0 replies; 78+ messages in thread
From: Kieran Bingham @ 2018-05-03 13:36 UTC (permalink / raw)
  To: Laurent Pinchart, linux-renesas-soc, linux-media
  Cc: Kieran Bingham, dri-devel

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 ef0148082bf7..2c3db8b8adce 100644
--- a/drivers/media/platform/vsp1/vsp1_drm.c
+++ b/drivers/media/platform/vsp1/vsp1_drm.c
@@ -806,7 +806,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
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH v4 02/11] media: vsp1: Remove packed attributes from aligned structures
  2018-05-03 13:36 ` Kieran Bingham
@ 2018-05-03 13:36   ` Kieran Bingham
  -1 siblings, 0 replies; 78+ messages in thread
From: Kieran Bingham @ 2018-05-03 13:36 UTC (permalink / raw)
  To: Laurent Pinchart, linux-renesas-soc, linux-media
  Cc: dri-devel, Kieran Bingham

The use of the packed attribute can cause a performance penalty for
all accesses to the struct members, as the compiler will assume that the
structure has the potential to have an unaligned base.

These structures are all correctly aligned and contain no holes, thus
the attribute is redundant and negatively impacts performance, so we
remove the attributes entirely.

Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
---
v2
 - Remove attributes entirely
---
 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 c7fa1cb088cd..f4cede9b9b43 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -25,19 +25,19 @@
 struct vsp1_dl_header_list {
 	u32 num_bytes;
 	u32 addr;
-} __attribute__((__packed__));
+};
 
 struct vsp1_dl_header {
 	u32 num_lists;
 	struct vsp1_dl_header_list lists[8];
 	u32 next_header;
 	u32 flags;
-} __attribute__((__packed__));
+};
 
 struct vsp1_dl_entry {
 	u32 addr;
 	u32 data;
-} __attribute__((__packed__));
+};
 
 /**
  * struct vsp1_dl_body - Display list body
-- 
git-series 0.9.1

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

* [PATCH v4 02/11] media: vsp1: Remove packed attributes from aligned structures
@ 2018-05-03 13:36   ` Kieran Bingham
  0 siblings, 0 replies; 78+ messages in thread
From: Kieran Bingham @ 2018-05-03 13:36 UTC (permalink / raw)
  To: Laurent Pinchart, linux-renesas-soc, linux-media
  Cc: Kieran Bingham, dri-devel

The use of the packed attribute can cause a performance penalty for
all accesses to the struct members, as the compiler will assume that the
structure has the potential to have an unaligned base.

These structures are all correctly aligned and contain no holes, thus
the attribute is redundant and negatively impacts performance, so we
remove the attributes entirely.

Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
---
v2
 - Remove attributes entirely
---
 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 c7fa1cb088cd..f4cede9b9b43 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -25,19 +25,19 @@
 struct vsp1_dl_header_list {
 	u32 num_bytes;
 	u32 addr;
-} __attribute__((__packed__));
+};
 
 struct vsp1_dl_header {
 	u32 num_lists;
 	struct vsp1_dl_header_list lists[8];
 	u32 next_header;
 	u32 flags;
-} __attribute__((__packed__));
+};
 
 struct vsp1_dl_entry {
 	u32 addr;
 	u32 data;
-} __attribute__((__packed__));
+};
 
 /**
  * struct vsp1_dl_body - Display list body
-- 
git-series 0.9.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH v4 03/11] media: vsp1: Rename dl_child to dl_next
  2018-05-03 13:36 ` Kieran Bingham
@ 2018-05-03 13:36   ` Kieran Bingham
  -1 siblings, 0 replies; 78+ messages in thread
From: Kieran Bingham @ 2018-05-03 13:36 UTC (permalink / raw)
  To: Laurent Pinchart, linux-renesas-soc, linux-media
  Cc: dri-devel, Kieran Bingham

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 f4cede9b9b43..ec6fc21fabe0 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -398,7 +398,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;
@@ -408,8 +408,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;
@@ -673,17 +673,17 @@ static void vsp1_dl_list_commit_singleshot(struct vsp1_dl_list *dl)
 void vsp1_dl_list_commit(struct vsp1_dl_list *dl, bool internal)
 {
 	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] 78+ messages in thread

* [PATCH v4 03/11] media: vsp1: Rename dl_child to dl_next
@ 2018-05-03 13:36   ` Kieran Bingham
  0 siblings, 0 replies; 78+ messages in thread
From: Kieran Bingham @ 2018-05-03 13:36 UTC (permalink / raw)
  To: Laurent Pinchart, linux-renesas-soc, linux-media
  Cc: Kieran Bingham, dri-devel

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 f4cede9b9b43..ec6fc21fabe0 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -398,7 +398,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;
@@ -408,8 +408,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;
@@ -673,17 +673,17 @@ static void vsp1_dl_list_commit_singleshot(struct vsp1_dl_list *dl)
 void vsp1_dl_list_commit(struct vsp1_dl_list *dl, bool internal)
 {
 	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
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH v4 04/11] media: vsp1: Remove unused display list structure field
  2018-05-03 13:36 ` Kieran Bingham
@ 2018-05-03 13:36   ` Kieran Bingham
  -1 siblings, 0 replies; 78+ messages in thread
From: Kieran Bingham @ 2018-05-03 13:36 UTC (permalink / raw)
  To: Laurent Pinchart, linux-renesas-soc, linux-media
  Cc: dri-devel, Kieran Bingham

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 ec6fc21fabe0..b23e88cda49f 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -44,7 +44,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
@@ -58,7 +57,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] 78+ messages in thread

* [PATCH v4 04/11] media: vsp1: Remove unused display list structure field
@ 2018-05-03 13:36   ` Kieran Bingham
  0 siblings, 0 replies; 78+ messages in thread
From: Kieran Bingham @ 2018-05-03 13:36 UTC (permalink / raw)
  To: Laurent Pinchart, linux-renesas-soc, linux-media
  Cc: Kieran Bingham, dri-devel

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 ec6fc21fabe0..b23e88cda49f 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -44,7 +44,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
@@ -58,7 +57,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
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH v4 05/11] media: vsp1: Clean up DLM objects on error
  2018-05-03 13:36 ` Kieran Bingham
@ 2018-05-03 13:36   ` Kieran Bingham
  -1 siblings, 0 replies; 78+ messages in thread
From: Kieran Bingham @ 2018-05-03 13:36 UTC (permalink / raw)
  To: Laurent Pinchart, linux-renesas-soc, linux-media
  Cc: dri-devel, Kieran Bingham

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 b23e88cda49f..fbffbd407b29 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -851,8 +851,10 @@ struct vsp1_dl_manager *vsp1_dlm_create(struct vsp1_device *vsp1,
 		struct vsp1_dl_list *dl;
 
 		dl = vsp1_dl_list_alloc(dlm);
-		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] 78+ messages in thread

* [PATCH v4 05/11] media: vsp1: Clean up DLM objects on error
@ 2018-05-03 13:36   ` Kieran Bingham
  0 siblings, 0 replies; 78+ messages in thread
From: Kieran Bingham @ 2018-05-03 13:36 UTC (permalink / raw)
  To: Laurent Pinchart, linux-renesas-soc, linux-media
  Cc: Kieran Bingham, dri-devel

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 b23e88cda49f..fbffbd407b29 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -851,8 +851,10 @@ struct vsp1_dl_manager *vsp1_dlm_create(struct vsp1_device *vsp1,
 		struct vsp1_dl_list *dl;
 
 		dl = vsp1_dl_list_alloc(dlm);
-		if (!dl)
+		if (!dl) {
+			vsp1_dlm_destroy(dlm);
 			return NULL;
+		}
 
 		list_add_tail(&dl->list, &dlm->free);
 	}
-- 
git-series 0.9.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH v4 06/11] media: vsp1: Provide VSP1 feature helper macro
  2018-05-03 13:36 ` Kieran Bingham
@ 2018-05-03 13:36   ` Kieran Bingham
  -1 siblings, 0 replies; 78+ messages in thread
From: Kieran Bingham @ 2018-05-03 13:36 UTC (permalink / raw)
  To: Laurent Pinchart, linux-renesas-soc, linux-media
  Cc: dri-devel, Kieran Bingham

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 33f632331474..f0d21cc8e9ab 100644
--- a/drivers/media/platform/vsp1/vsp1.h
+++ b/drivers/media/platform/vsp1/vsp1.h
@@ -68,6 +68,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 d29f9c4baebe..0fc388bf5a33 100644
--- a/drivers/media/platform/vsp1/vsp1_drv.c
+++ b/drivers/media/platform/vsp1/vsp1_drv.c
@@ -265,7 +265,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_brx_create(vsp1, VSP1_ENTITY_BRS);
 		if (IS_ERR(vsp1->brs)) {
 			ret = PTR_ERR(vsp1->brs);
@@ -275,7 +275,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_brx_create(vsp1, VSP1_ENTITY_BRU);
 		if (IS_ERR(vsp1->bru)) {
 			ret = PTR_ERR(vsp1->bru);
@@ -285,7 +285,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);
@@ -311,7 +311,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);
@@ -322,7 +322,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);
@@ -353,7 +353,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);
@@ -387,7 +387,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);
@@ -537,7 +537,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 2edea361eee4..ea1d226371b2 100644
--- a/drivers/media/platform/vsp1/vsp1_wpf.c
+++ b/drivers/media/platform/vsp1/vsp1_wpf.c
@@ -141,13 +141,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).
@@ -276,7 +276,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] 78+ messages in thread

* [PATCH v4 06/11] media: vsp1: Provide VSP1 feature helper macro
@ 2018-05-03 13:36   ` Kieran Bingham
  0 siblings, 0 replies; 78+ messages in thread
From: Kieran Bingham @ 2018-05-03 13:36 UTC (permalink / raw)
  To: Laurent Pinchart, linux-renesas-soc, linux-media
  Cc: Kieran Bingham, dri-devel

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 33f632331474..f0d21cc8e9ab 100644
--- a/drivers/media/platform/vsp1/vsp1.h
+++ b/drivers/media/platform/vsp1/vsp1.h
@@ -68,6 +68,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 d29f9c4baebe..0fc388bf5a33 100644
--- a/drivers/media/platform/vsp1/vsp1_drv.c
+++ b/drivers/media/platform/vsp1/vsp1_drv.c
@@ -265,7 +265,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_brx_create(vsp1, VSP1_ENTITY_BRS);
 		if (IS_ERR(vsp1->brs)) {
 			ret = PTR_ERR(vsp1->brs);
@@ -275,7 +275,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_brx_create(vsp1, VSP1_ENTITY_BRU);
 		if (IS_ERR(vsp1->bru)) {
 			ret = PTR_ERR(vsp1->bru);
@@ -285,7 +285,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);
@@ -311,7 +311,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);
@@ -322,7 +322,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);
@@ -353,7 +353,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);
@@ -387,7 +387,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);
@@ -537,7 +537,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 2edea361eee4..ea1d226371b2 100644
--- a/drivers/media/platform/vsp1/vsp1_wpf.c
+++ b/drivers/media/platform/vsp1/vsp1_wpf.c
@@ -141,13 +141,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).
@@ -276,7 +276,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
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH v4 07/11] media: vsp1: Use header display lists for all WPF outputs linked to the DU
  2018-05-03 13:36 ` Kieran Bingham
@ 2018-05-03 13:36   ` Kieran Bingham
  -1 siblings, 0 replies; 78+ messages in thread
From: Kieran Bingham @ 2018-05-03 13:36 UTC (permalink / raw)
  To: Laurent Pinchart, linux-renesas-soc, linux-media
  Cc: dri-devel, Kieran Bingham

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 fbffbd407b29..56514cd51c51 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -94,7 +94,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
@@ -118,15 +118,9 @@ struct vsp1_dl_list {
 	bool internal;
 };
 
-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, and pending lists
@@ -138,7 +132,6 @@ enum vsp1_dl_mode {
  */
 struct vsp1_dl_manager {
 	unsigned int index;
-	enum vsp1_dl_mode mode;
 	bool singleshot;
 	struct vsp1_device *vsp1;
 
@@ -318,6 +311,7 @@ void vsp1_dl_body_write(struct vsp1_dl_body *dlb, u32 reg, u32 data)
 static struct vsp1_dl_list *vsp1_dl_list_alloc(struct vsp1_dl_manager *dlm)
 {
 	struct vsp1_dl_list *dl;
+	size_t header_offset;
 
 	dl = kzalloc(sizeof(*dl), GFP_KERNEL);
 	if (!dl)
@@ -330,16 +324,15 @@ static struct vsp1_dl_list *vsp1_dl_list_alloc(struct vsp1_dl_manager *dlm)
 	dl->body0 = vsp1_dl_body_get(dlm->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;
 }
@@ -471,16 +464,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);
@@ -501,17 +487,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;
@@ -579,17 +558,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)
@@ -597,26 +569,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)
@@ -674,15 +634,13 @@ void vsp1_dl_list_commit(struct vsp1_dl_list *dl, bool internal)
 	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);
 	}
 
 	dl->internal = internal;
@@ -783,13 +741,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);
 }
@@ -824,8 +775,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;
 
@@ -834,13 +783,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] 78+ messages in thread

* [PATCH v4 07/11] media: vsp1: Use header display lists for all WPF outputs linked to the DU
@ 2018-05-03 13:36   ` Kieran Bingham
  0 siblings, 0 replies; 78+ messages in thread
From: Kieran Bingham @ 2018-05-03 13:36 UTC (permalink / raw)
  To: Laurent Pinchart, linux-renesas-soc, linux-media
  Cc: Kieran Bingham, dri-devel

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 fbffbd407b29..56514cd51c51 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -94,7 +94,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
@@ -118,15 +118,9 @@ struct vsp1_dl_list {
 	bool internal;
 };
 
-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, and pending lists
@@ -138,7 +132,6 @@ enum vsp1_dl_mode {
  */
 struct vsp1_dl_manager {
 	unsigned int index;
-	enum vsp1_dl_mode mode;
 	bool singleshot;
 	struct vsp1_device *vsp1;
 
@@ -318,6 +311,7 @@ void vsp1_dl_body_write(struct vsp1_dl_body *dlb, u32 reg, u32 data)
 static struct vsp1_dl_list *vsp1_dl_list_alloc(struct vsp1_dl_manager *dlm)
 {
 	struct vsp1_dl_list *dl;
+	size_t header_offset;
 
 	dl = kzalloc(sizeof(*dl), GFP_KERNEL);
 	if (!dl)
@@ -330,16 +324,15 @@ static struct vsp1_dl_list *vsp1_dl_list_alloc(struct vsp1_dl_manager *dlm)
 	dl->body0 = vsp1_dl_body_get(dlm->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;
 }
@@ -471,16 +464,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);
@@ -501,17 +487,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;
@@ -579,17 +558,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)
@@ -597,26 +569,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)
@@ -674,15 +634,13 @@ void vsp1_dl_list_commit(struct vsp1_dl_list *dl, bool internal)
 	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);
 	}
 
 	dl->internal = internal;
@@ -783,13 +741,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);
 }
@@ -824,8 +775,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;
 
@@ -834,13 +783,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
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH v4 08/11] media: vsp1: Add support for extended display list headers
  2018-05-03 13:36 ` Kieran Bingham
@ 2018-05-03 13:36   ` Kieran Bingham
  -1 siblings, 0 replies; 78+ messages in thread
From: Kieran Bingham @ 2018-05-03 13:36 UTC (permalink / raw)
  To: Laurent Pinchart, linux-renesas-soc, linux-media
  Cc: dri-devel, Kieran Bingham

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>

---

v2:
 - remove __packed attributes
---
 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 f0d21cc8e9ab..56c62122a81a 100644
--- a/drivers/media/platform/vsp1/vsp1.h
+++ b/drivers/media/platform/vsp1/vsp1.h
@@ -53,6 +53,7 @@ struct vsp1_uif;
 #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 56514cd51c51..b64d32535edc 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -22,6 +22,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;
@@ -34,11 +37,34 @@ struct vsp1_dl_header {
 	u32 flags;
 };
 
+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;
+};
+
+struct vsp1_dl_header_extended {
+	struct vsp1_dl_header header;
+	struct vsp1_dl_ext_header ext;
+};
+
 struct vsp1_dl_entry {
 	u32 addr;
 	u32 data;
 };
 
+struct vsp1_dl_ext_cmd_header {
+	u32 cmd;
+	u32 flags;
+	u32 data;
+	u32 reserved;
+};
+
 /**
  * struct vsp1_dl_body - Display list body
  * @list: entry in the display list list of bodies
@@ -95,9 +121,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
  * @internal: whether the display list is used for internal purpose
@@ -107,11 +136,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;
 
@@ -496,6 +529,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;
@@ -548,6 +589,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)
@@ -735,14 +797,20 @@ unsigned int 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)
@@ -787,7 +855,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);
@@ -803,6 +875,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 216bd23029dd..aa5f4adc6617 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.h
+++ b/drivers/media/platform/vsp1/vsp1_dl.h
@@ -20,7 +20,34 @@ struct vsp1_dl_manager;
 #define VSP1_DL_FRAME_END_COMPLETED		BIT(0)
 #define VSP1_DL_FRAME_END_INTERNAL		BIT(1)
 
-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 0fc388bf5a33..26a7b4d32e6c 100644
--- a/drivers/media/platform/vsp1/vsp1_drv.c
+++ b/drivers/media/platform/vsp1/vsp1_drv.c
@@ -545,7 +545,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;
 }
@@ -754,7 +755,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,
 		.uif_count = 1,
@@ -774,7 +775,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,
 		.uif_count = 2,
diff --git a/drivers/media/platform/vsp1/vsp1_regs.h b/drivers/media/platform/vsp1/vsp1_regs.h
index 0d249ff9f564..d054767570c1 100644
--- a/drivers/media/platform/vsp1/vsp1_regs.h
+++ b/drivers/media/platform/vsp1/vsp1_regs.h
@@ -67,12 +67,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] 78+ messages in thread

* [PATCH v4 08/11] media: vsp1: Add support for extended display list headers
@ 2018-05-03 13:36   ` Kieran Bingham
  0 siblings, 0 replies; 78+ messages in thread
From: Kieran Bingham @ 2018-05-03 13:36 UTC (permalink / raw)
  To: Laurent Pinchart, linux-renesas-soc, linux-media
  Cc: Kieran Bingham, dri-devel

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>

---

v2:
 - remove __packed attributes
---
 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 f0d21cc8e9ab..56c62122a81a 100644
--- a/drivers/media/platform/vsp1/vsp1.h
+++ b/drivers/media/platform/vsp1/vsp1.h
@@ -53,6 +53,7 @@ struct vsp1_uif;
 #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 56514cd51c51..b64d32535edc 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -22,6 +22,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;
@@ -34,11 +37,34 @@ struct vsp1_dl_header {
 	u32 flags;
 };
 
+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;
+};
+
+struct vsp1_dl_header_extended {
+	struct vsp1_dl_header header;
+	struct vsp1_dl_ext_header ext;
+};
+
 struct vsp1_dl_entry {
 	u32 addr;
 	u32 data;
 };
 
+struct vsp1_dl_ext_cmd_header {
+	u32 cmd;
+	u32 flags;
+	u32 data;
+	u32 reserved;
+};
+
 /**
  * struct vsp1_dl_body - Display list body
  * @list: entry in the display list list of bodies
@@ -95,9 +121,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
  * @internal: whether the display list is used for internal purpose
@@ -107,11 +136,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;
 
@@ -496,6 +529,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;
@@ -548,6 +589,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)
@@ -735,14 +797,20 @@ unsigned int 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)
@@ -787,7 +855,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);
@@ -803,6 +875,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 216bd23029dd..aa5f4adc6617 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.h
+++ b/drivers/media/platform/vsp1/vsp1_dl.h
@@ -20,7 +20,34 @@ struct vsp1_dl_manager;
 #define VSP1_DL_FRAME_END_COMPLETED		BIT(0)
 #define VSP1_DL_FRAME_END_INTERNAL		BIT(1)
 
-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 0fc388bf5a33..26a7b4d32e6c 100644
--- a/drivers/media/platform/vsp1/vsp1_drv.c
+++ b/drivers/media/platform/vsp1/vsp1_drv.c
@@ -545,7 +545,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;
 }
@@ -754,7 +755,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,
 		.uif_count = 1,
@@ -774,7 +775,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,
 		.uif_count = 2,
diff --git a/drivers/media/platform/vsp1/vsp1_regs.h b/drivers/media/platform/vsp1/vsp1_regs.h
index 0d249ff9f564..d054767570c1 100644
--- a/drivers/media/platform/vsp1/vsp1_regs.h
+++ b/drivers/media/platform/vsp1/vsp1_regs.h
@@ -67,12 +67,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
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH v4 09/11] media: vsp1: Provide support for extended command pools
  2018-05-03 13:36 ` Kieran Bingham
@ 2018-05-03 13:36   ` Kieran Bingham
  -1 siblings, 0 replies; 78+ messages in thread
From: Kieran Bingham @ 2018-05-03 13:36 UTC (permalink / raw)
  To: Laurent Pinchart, linux-renesas-soc, linux-media
  Cc: dri-devel, Kieran Bingham

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 convenient
re-usable command objects for the entities to utilise.

Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>

---

v2:
 - Fix spelling typo in commit message
 - constify, and staticify the instantiation of vsp1_extended_commands
 - s/autfld_cmds/autofld_cmds/
 - staticify cmd pool functions (Thanks kbuild-bot)
---
 drivers/media/platform/vsp1/vsp1_dl.c | 191 +++++++++++++++++++++++++++-
 drivers/media/platform/vsp1/vsp1_dl.h |   3 +-
 2 files changed, 194 insertions(+)

diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c
index b64d32535edc..d33ae5f125bd 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -117,6 +117,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
@@ -162,6 +186,7 @@ struct vsp1_dl_list {
  * @queued: list queued to the hardware (written to the DL registers)
  * @pending: list waiting to be queued to the hardware
  * @pool: body pool for the display list bodies
+ * @autofld_cmds: command pool to support auto-fld interlaced mode
  */
 struct vsp1_dl_manager {
 	unsigned int index;
@@ -175,6 +200,7 @@ struct vsp1_dl_manager {
 	struct vsp1_dl_list *pending;
 
 	struct vsp1_dl_body_pool *pool;
+	struct vsp1_dl_cmd_pool *autofld_cmds;
 };
 
 /* -----------------------------------------------------------------------------
@@ -338,6 +364,140 @@ 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;
+} static const 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.
+ */
+static 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;
+}
+
+static
+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;
+}
+
+static 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);
+}
+
+static 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
  */
 
@@ -440,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.
@@ -883,6 +1049,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->autofld_cmds = vsp1_dl_cmd_pool_create(vsp1,
+					VSP1_EXTCMD_AUTOFLD, prealloc);
+		if (!dlm->autofld_cmds) {
+			vsp1_dlm_destroy(dlm);
+			return NULL;
+		}
+	}
+
 	return dlm;
 }
 
@@ -899,4 +1074,20 @@ void vsp1_dlm_destroy(struct vsp1_dl_manager *dlm)
 	}
 
 	vsp1_dl_body_pool_destroy(dlm->pool);
+	vsp1_dl_ext_cmd_pool_destroy(dlm->autofld_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->autofld_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 aa5f4adc6617..d9621207b093 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.h
+++ b/drivers/media/platform/vsp1/vsp1_dl.h
@@ -22,6 +22,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
@@ -33,6 +34,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;
@@ -55,6 +57,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);
 unsigned int 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] 78+ messages in thread

* [PATCH v4 09/11] media: vsp1: Provide support for extended command pools
@ 2018-05-03 13:36   ` Kieran Bingham
  0 siblings, 0 replies; 78+ messages in thread
From: Kieran Bingham @ 2018-05-03 13:36 UTC (permalink / raw)
  To: Laurent Pinchart, linux-renesas-soc, linux-media
  Cc: Kieran Bingham, dri-devel

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 convenient
re-usable command objects for the entities to utilise.

Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>

---

v2:
 - Fix spelling typo in commit message
 - constify, and staticify the instantiation of vsp1_extended_commands
 - s/autfld_cmds/autofld_cmds/
 - staticify cmd pool functions (Thanks kbuild-bot)
---
 drivers/media/platform/vsp1/vsp1_dl.c | 191 +++++++++++++++++++++++++++-
 drivers/media/platform/vsp1/vsp1_dl.h |   3 +-
 2 files changed, 194 insertions(+)

diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c
index b64d32535edc..d33ae5f125bd 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -117,6 +117,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
@@ -162,6 +186,7 @@ struct vsp1_dl_list {
  * @queued: list queued to the hardware (written to the DL registers)
  * @pending: list waiting to be queued to the hardware
  * @pool: body pool for the display list bodies
+ * @autofld_cmds: command pool to support auto-fld interlaced mode
  */
 struct vsp1_dl_manager {
 	unsigned int index;
@@ -175,6 +200,7 @@ struct vsp1_dl_manager {
 	struct vsp1_dl_list *pending;
 
 	struct vsp1_dl_body_pool *pool;
+	struct vsp1_dl_cmd_pool *autofld_cmds;
 };
 
 /* -----------------------------------------------------------------------------
@@ -338,6 +364,140 @@ 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;
+} static const 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.
+ */
+static 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;
+}
+
+static
+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;
+}
+
+static 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);
+}
+
+static 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
  */
 
@@ -440,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.
@@ -883,6 +1049,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->autofld_cmds = vsp1_dl_cmd_pool_create(vsp1,
+					VSP1_EXTCMD_AUTOFLD, prealloc);
+		if (!dlm->autofld_cmds) {
+			vsp1_dlm_destroy(dlm);
+			return NULL;
+		}
+	}
+
 	return dlm;
 }
 
@@ -899,4 +1074,20 @@ void vsp1_dlm_destroy(struct vsp1_dl_manager *dlm)
 	}
 
 	vsp1_dl_body_pool_destroy(dlm->pool);
+	vsp1_dl_ext_cmd_pool_destroy(dlm->autofld_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->autofld_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 aa5f4adc6617..d9621207b093 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.h
+++ b/drivers/media/platform/vsp1/vsp1_dl.h
@@ -22,6 +22,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
@@ -33,6 +34,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;
@@ -55,6 +57,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);
 unsigned int 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
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH v4 10/11] media: vsp1: Support Interlaced display pipelines
  2018-05-03 13:36 ` Kieran Bingham
@ 2018-05-03 13:36   ` Kieran Bingham
  -1 siblings, 0 replies; 78+ messages in thread
From: Kieran Bingham @ 2018-05-03 13:36 UTC (permalink / raw)
  To: Laurent Pinchart, linux-renesas-soc, linux-media
  Cc: dri-devel, Kieran Bingham

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>

---
v3:
 - Pass DL through partition calls to allow autocmd's to be retrieved
 - Document interlaced field in struct vsp1_du_atomic_config

v2:
 - fix erroneous BIT value which enabled interlaced
 - fix field handling at frame_end interrupt
---
 drivers/media/platform/vsp1/vsp1_dl.c   | 10 ++++-
 drivers/media/platform/vsp1/vsp1_drm.c  | 11 ++++-
 drivers/media/platform/vsp1/vsp1_regs.h |  1 +-
 drivers/media/platform/vsp1/vsp1_rpf.c  | 71 ++++++++++++++++++++++++--
 drivers/media/platform/vsp1/vsp1_rwpf.h |  1 +-
 include/media/vsp1.h                    |  2 +-
 6 files changed, 93 insertions(+), 3 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c
index d33ae5f125bd..bbe9f3006f71 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -906,6 +906,8 @@ void vsp1_dl_list_commit(struct vsp1_dl_list *dl, bool internal)
  */
 unsigned int vsp1_dlm_irq_frame_end(struct vsp1_dl_manager *dlm)
 {
+	struct vsp1_device *vsp1 = dlm->vsp1;
+	u32 status = vsp1_read(vsp1, VI6_STATUS);
 	unsigned int flags = 0;
 
 	spin_lock(&dlm->lock);
@@ -931,6 +933,14 @@ unsigned int vsp1_dlm_irq_frame_end(struct vsp1_dl_manager *dlm)
 		goto done;
 
 	/*
+	 * Progressive streams report only TOP fields. If we have a BOTTOM
+	 * field, we are interlaced, and expect the frame to complete on the
+	 * next frame end interrupt.
+	 */
+	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_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c
index 2c3db8b8adce..cc29c9d96bb7 100644
--- a/drivers/media/platform/vsp1/vsp1_drm.c
+++ b/drivers/media/platform/vsp1/vsp1_drm.c
@@ -811,6 +811,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 = 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_regs.h b/drivers/media/platform/vsp1/vsp1_regs.h
index d054767570c1..a2ac65cc5155 100644
--- a/drivers/media/platform/vsp1/vsp1_regs.h
+++ b/drivers/media/platform/vsp1/vsp1_regs.h
@@ -28,6 +28,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 8fae7c485642..511b2e127820 100644
--- a/drivers/media/platform/vsp1/vsp1_rpf.c
+++ b/drivers/media/platform/vsp1/vsp1_rpf.c
@@ -20,6 +20,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(0)
+
 /* -----------------------------------------------------------------------------
  * Device Access
  */
@@ -64,6 +78,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 */
@@ -100,6 +122,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));
@@ -169,6 +194,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,
@@ -192,6 +242,7 @@ static void rpf_configure_partition(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_partition(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,9 +304,18 @@ static void rpf_configure_partition(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,
diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.h b/drivers/media/platform/vsp1/vsp1_rwpf.h
index 70742ecf766f..8d6e42f27908 100644
--- a/drivers/media/platform/vsp1/vsp1_rwpf.h
+++ b/drivers/media/platform/vsp1/vsp1_rwpf.h
@@ -42,6 +42,7 @@ struct vsp1_rwpf {
 	struct v4l2_pix_format_mplane format;
 	const struct vsp1_format_info *fmtinfo;
 	unsigned int brx_input;
+	bool interlaced;
 
 	unsigned int alpha;
 
diff --git a/include/media/vsp1.h b/include/media/vsp1.h
index 678c24de1ac6..c10883f30980 100644
--- a/include/media/vsp1.h
+++ b/include/media/vsp1.h
@@ -50,6 +50,7 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int pipe_index,
  * @dst: destination rectangle on the display (integer coordinates)
  * @alpha: alpha value (0: fully transparent, 255: fully opaque)
  * @zpos: Z position of the plane (from 0 to number of planes minus 1)
+ * @interlaced: true for interlaced pipelines
  */
 struct vsp1_du_atomic_config {
 	u32 pixelformat;
@@ -59,6 +60,7 @@ struct vsp1_du_atomic_config {
 	struct v4l2_rect dst;
 	unsigned int alpha;
 	unsigned int zpos;
+	bool interlaced;
 };
 
 /**
-- 
git-series 0.9.1

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

* [PATCH v4 10/11] media: vsp1: Support Interlaced display pipelines
@ 2018-05-03 13:36   ` Kieran Bingham
  0 siblings, 0 replies; 78+ messages in thread
From: Kieran Bingham @ 2018-05-03 13:36 UTC (permalink / raw)
  To: Laurent Pinchart, linux-renesas-soc, linux-media
  Cc: Kieran Bingham, dri-devel

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>

---
v3:
 - Pass DL through partition calls to allow autocmd's to be retrieved
 - Document interlaced field in struct vsp1_du_atomic_config

v2:
 - fix erroneous BIT value which enabled interlaced
 - fix field handling at frame_end interrupt
---
 drivers/media/platform/vsp1/vsp1_dl.c   | 10 ++++-
 drivers/media/platform/vsp1/vsp1_drm.c  | 11 ++++-
 drivers/media/platform/vsp1/vsp1_regs.h |  1 +-
 drivers/media/platform/vsp1/vsp1_rpf.c  | 71 ++++++++++++++++++++++++--
 drivers/media/platform/vsp1/vsp1_rwpf.h |  1 +-
 include/media/vsp1.h                    |  2 +-
 6 files changed, 93 insertions(+), 3 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c
index d33ae5f125bd..bbe9f3006f71 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -906,6 +906,8 @@ void vsp1_dl_list_commit(struct vsp1_dl_list *dl, bool internal)
  */
 unsigned int vsp1_dlm_irq_frame_end(struct vsp1_dl_manager *dlm)
 {
+	struct vsp1_device *vsp1 = dlm->vsp1;
+	u32 status = vsp1_read(vsp1, VI6_STATUS);
 	unsigned int flags = 0;
 
 	spin_lock(&dlm->lock);
@@ -931,6 +933,14 @@ unsigned int vsp1_dlm_irq_frame_end(struct vsp1_dl_manager *dlm)
 		goto done;
 
 	/*
+	 * Progressive streams report only TOP fields. If we have a BOTTOM
+	 * field, we are interlaced, and expect the frame to complete on the
+	 * next frame end interrupt.
+	 */
+	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_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c
index 2c3db8b8adce..cc29c9d96bb7 100644
--- a/drivers/media/platform/vsp1/vsp1_drm.c
+++ b/drivers/media/platform/vsp1/vsp1_drm.c
@@ -811,6 +811,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 = 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_regs.h b/drivers/media/platform/vsp1/vsp1_regs.h
index d054767570c1..a2ac65cc5155 100644
--- a/drivers/media/platform/vsp1/vsp1_regs.h
+++ b/drivers/media/platform/vsp1/vsp1_regs.h
@@ -28,6 +28,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 8fae7c485642..511b2e127820 100644
--- a/drivers/media/platform/vsp1/vsp1_rpf.c
+++ b/drivers/media/platform/vsp1/vsp1_rpf.c
@@ -20,6 +20,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(0)
+
 /* -----------------------------------------------------------------------------
  * Device Access
  */
@@ -64,6 +78,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 */
@@ -100,6 +122,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));
@@ -169,6 +194,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,
@@ -192,6 +242,7 @@ static void rpf_configure_partition(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_partition(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,9 +304,18 @@ static void rpf_configure_partition(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,
diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.h b/drivers/media/platform/vsp1/vsp1_rwpf.h
index 70742ecf766f..8d6e42f27908 100644
--- a/drivers/media/platform/vsp1/vsp1_rwpf.h
+++ b/drivers/media/platform/vsp1/vsp1_rwpf.h
@@ -42,6 +42,7 @@ struct vsp1_rwpf {
 	struct v4l2_pix_format_mplane format;
 	const struct vsp1_format_info *fmtinfo;
 	unsigned int brx_input;
+	bool interlaced;
 
 	unsigned int alpha;
 
diff --git a/include/media/vsp1.h b/include/media/vsp1.h
index 678c24de1ac6..c10883f30980 100644
--- a/include/media/vsp1.h
+++ b/include/media/vsp1.h
@@ -50,6 +50,7 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int pipe_index,
  * @dst: destination rectangle on the display (integer coordinates)
  * @alpha: alpha value (0: fully transparent, 255: fully opaque)
  * @zpos: Z position of the plane (from 0 to number of planes minus 1)
+ * @interlaced: true for interlaced pipelines
  */
 struct vsp1_du_atomic_config {
 	u32 pixelformat;
@@ -59,6 +60,7 @@ struct vsp1_du_atomic_config {
 	struct v4l2_rect dst;
 	unsigned int alpha;
 	unsigned int zpos;
+	bool interlaced;
 };
 
 /**
-- 
git-series 0.9.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH v4 11/11] drm: rcar-du: Support interlaced video output through vsp1
  2018-05-03 13:36 ` Kieran Bingham
@ 2018-05-03 13:36   ` Kieran Bingham
  -1 siblings, 0 replies; 78+ messages in thread
From: Kieran Bingham @ 2018-05-03 13:36 UTC (permalink / raw)
  To: Laurent Pinchart, linux-renesas-soc, linux-media
  Cc: dri-devel, Kieran Bingham

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 d71d709fe3d9..206532959ec9 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -289,6 +289,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 af7822a66dee..c7b37232ee91 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
@@ -186,6 +186,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] 78+ messages in thread

* [PATCH v4 11/11] drm: rcar-du: Support interlaced video output through vsp1
@ 2018-05-03 13:36   ` Kieran Bingham
  0 siblings, 0 replies; 78+ messages in thread
From: Kieran Bingham @ 2018-05-03 13:36 UTC (permalink / raw)
  To: Laurent Pinchart, linux-renesas-soc, linux-media
  Cc: Kieran Bingham, dri-devel

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 d71d709fe3d9..206532959ec9 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -289,6 +289,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 af7822a66dee..c7b37232ee91 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
@@ -186,6 +186,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
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v4 01/11] media: vsp1: drm: Fix minor grammar error
  2018-05-03 13:36   ` Kieran Bingham
@ 2018-05-24 10:24     ` Laurent Pinchart
  -1 siblings, 0 replies; 78+ messages in thread
From: Laurent Pinchart @ 2018-05-24 10:24 UTC (permalink / raw)
  To: Kieran Bingham; +Cc: linux-renesas-soc, linux-media, dri-devel

Hi Kieran,

Thank you for the patch.

On Thursday, 3 May 2018 16:36:12 EEST Kieran Bingham wrote:
> The pixel format is 'unsupported'. Fix the small debug message which
> incorrectly declares this.
> 
> Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>

Reviewed-by: Laurent Pinchart <laurent.pinchart@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 ef0148082bf7..2c3db8b8adce
> 100644
> --- a/drivers/media/platform/vsp1/vsp1_drm.c
> +++ b/drivers/media/platform/vsp1/vsp1_drm.c
> @@ -806,7 +806,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;
>  	}


-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v4 01/11] media: vsp1: drm: Fix minor grammar error
@ 2018-05-24 10:24     ` Laurent Pinchart
  0 siblings, 0 replies; 78+ messages in thread
From: Laurent Pinchart @ 2018-05-24 10:24 UTC (permalink / raw)
  To: Kieran Bingham; +Cc: linux-renesas-soc, dri-devel, linux-media

Hi Kieran,

Thank you for the patch.

On Thursday, 3 May 2018 16:36:12 EEST Kieran Bingham wrote:
> The pixel format is 'unsupported'. Fix the small debug message which
> incorrectly declares this.
> 
> Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>

Reviewed-by: Laurent Pinchart <laurent.pinchart@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 ef0148082bf7..2c3db8b8adce
> 100644
> --- a/drivers/media/platform/vsp1/vsp1_drm.c
> +++ b/drivers/media/platform/vsp1/vsp1_drm.c
> @@ -806,7 +806,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;
>  	}


-- 
Regards,

Laurent Pinchart



_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v4 02/11] media: vsp1: Remove packed attributes from aligned structures
  2018-05-03 13:36   ` Kieran Bingham
@ 2018-05-24 10:47     ` Laurent Pinchart
  -1 siblings, 0 replies; 78+ messages in thread
From: Laurent Pinchart @ 2018-05-24 10:47 UTC (permalink / raw)
  To: Kieran Bingham; +Cc: linux-renesas-soc, linux-media, dri-devel

Hi Kieran,

Thank you for the patch.

On Thursday, 3 May 2018 16:36:13 EEST Kieran Bingham wrote:
> The use of the packed attribute can cause a performance penalty for
> all accesses to the struct members, as the compiler will assume that the
> structure has the potential to have an unaligned base.
> 
> These structures are all correctly aligned and contain no holes, thus
> the attribute is redundant and negatively impacts performance, so we
> remove the attributes entirely.

With gcc 6.4.0 this patch makes no difference on the generated object. Is it 
worth it ?

> Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>

You forget to pick Geert's review tag.

> ---
> v2
>  - Remove attributes entirely
> ---
>  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 c7fa1cb088cd..f4cede9b9b43
> 100644
> --- a/drivers/media/platform/vsp1/vsp1_dl.c
> +++ b/drivers/media/platform/vsp1/vsp1_dl.c
> @@ -25,19 +25,19 @@
>  struct vsp1_dl_header_list {
>  	u32 num_bytes;
>  	u32 addr;
> -} __attribute__((__packed__));
> +};
> 
>  struct vsp1_dl_header {
>  	u32 num_lists;
>  	struct vsp1_dl_header_list lists[8];
>  	u32 next_header;
>  	u32 flags;
> -} __attribute__((__packed__));
> +};
> 
>  struct vsp1_dl_entry {
>  	u32 addr;
>  	u32 data;
> -} __attribute__((__packed__));
> +};
> 
>  /**
>   * struct vsp1_dl_body - Display list body

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v4 02/11] media: vsp1: Remove packed attributes from aligned structures
@ 2018-05-24 10:47     ` Laurent Pinchart
  0 siblings, 0 replies; 78+ messages in thread
From: Laurent Pinchart @ 2018-05-24 10:47 UTC (permalink / raw)
  To: Kieran Bingham; +Cc: linux-renesas-soc, dri-devel, linux-media

Hi Kieran,

Thank you for the patch.

On Thursday, 3 May 2018 16:36:13 EEST Kieran Bingham wrote:
> The use of the packed attribute can cause a performance penalty for
> all accesses to the struct members, as the compiler will assume that the
> structure has the potential to have an unaligned base.
> 
> These structures are all correctly aligned and contain no holes, thus
> the attribute is redundant and negatively impacts performance, so we
> remove the attributes entirely.

With gcc 6.4.0 this patch makes no difference on the generated object. Is it 
worth it ?

> Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>

You forget to pick Geert's review tag.

> ---
> v2
>  - Remove attributes entirely
> ---
>  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 c7fa1cb088cd..f4cede9b9b43
> 100644
> --- a/drivers/media/platform/vsp1/vsp1_dl.c
> +++ b/drivers/media/platform/vsp1/vsp1_dl.c
> @@ -25,19 +25,19 @@
>  struct vsp1_dl_header_list {
>  	u32 num_bytes;
>  	u32 addr;
> -} __attribute__((__packed__));
> +};
> 
>  struct vsp1_dl_header {
>  	u32 num_lists;
>  	struct vsp1_dl_header_list lists[8];
>  	u32 next_header;
>  	u32 flags;
> -} __attribute__((__packed__));
> +};
> 
>  struct vsp1_dl_entry {
>  	u32 addr;
>  	u32 data;
> -} __attribute__((__packed__));
> +};
> 
>  /**
>   * struct vsp1_dl_body - Display list body

-- 
Regards,

Laurent Pinchart



_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v4 03/11] media: vsp1: Rename dl_child to dl_next
  2018-05-03 13:36   ` Kieran Bingham
@ 2018-05-24 10:51     ` Laurent Pinchart
  -1 siblings, 0 replies; 78+ messages in thread
From: Laurent Pinchart @ 2018-05-24 10:51 UTC (permalink / raw)
  To: Kieran Bingham; +Cc: linux-renesas-soc, linux-media, dri-devel

Hi Kieran,

Thank you for the patch.

On Thursday, 3 May 2018 16:36:14 EEST Kieran Bingham wrote:
> 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>

Reviewed-by: Laurent Pinchart <laurent.pinchart@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 f4cede9b9b43..ec6fc21fabe0
> 100644
> --- a/drivers/media/platform/vsp1/vsp1_dl.c
> +++ b/drivers/media/platform/vsp1/vsp1_dl.c
> @@ -398,7 +398,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;
> @@ -408,8 +408,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;
> @@ -673,17 +673,17 @@ static void vsp1_dl_list_commit_singleshot(struct
> vsp1_dl_list *dl) void vsp1_dl_list_commit(struct vsp1_dl_list *dl, bool
> internal)
>  {
>  	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);
>  		}
>  	}


-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v4 03/11] media: vsp1: Rename dl_child to dl_next
@ 2018-05-24 10:51     ` Laurent Pinchart
  0 siblings, 0 replies; 78+ messages in thread
From: Laurent Pinchart @ 2018-05-24 10:51 UTC (permalink / raw)
  To: Kieran Bingham; +Cc: linux-renesas-soc, dri-devel, linux-media

Hi Kieran,

Thank you for the patch.

On Thursday, 3 May 2018 16:36:14 EEST Kieran Bingham wrote:
> 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>

Reviewed-by: Laurent Pinchart <laurent.pinchart@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 f4cede9b9b43..ec6fc21fabe0
> 100644
> --- a/drivers/media/platform/vsp1/vsp1_dl.c
> +++ b/drivers/media/platform/vsp1/vsp1_dl.c
> @@ -398,7 +398,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;
> @@ -408,8 +408,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;
> @@ -673,17 +673,17 @@ static void vsp1_dl_list_commit_singleshot(struct
> vsp1_dl_list *dl) void vsp1_dl_list_commit(struct vsp1_dl_list *dl, bool
> internal)
>  {
>  	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);
>  		}
>  	}


-- 
Regards,

Laurent Pinchart



_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v4 04/11] media: vsp1: Remove unused display list structure field
  2018-05-03 13:36   ` Kieran Bingham
@ 2018-05-24 10:51     ` Laurent Pinchart
  -1 siblings, 0 replies; 78+ messages in thread
From: Laurent Pinchart @ 2018-05-24 10:51 UTC (permalink / raw)
  To: Kieran Bingham; +Cc: linux-renesas-soc, linux-media, dri-devel

Hi Kieran,

Thank you for the patch.

On Thursday, 3 May 2018 16:36:15 EEST Kieran Bingham wrote:
> The vsp1 reference in the vsp1_dl_body structure is not used.
> Remove it.
> 
> Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>

Reviewed-by: Laurent Pinchart <laurent.pinchart@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 ec6fc21fabe0..b23e88cda49f
> 100644
> --- a/drivers/media/platform/vsp1/vsp1_dl.c
> +++ b/drivers/media/platform/vsp1/vsp1_dl.c
> @@ -44,7 +44,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
> @@ -58,7 +57,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;

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v4 04/11] media: vsp1: Remove unused display list structure field
@ 2018-05-24 10:51     ` Laurent Pinchart
  0 siblings, 0 replies; 78+ messages in thread
From: Laurent Pinchart @ 2018-05-24 10:51 UTC (permalink / raw)
  To: Kieran Bingham; +Cc: linux-renesas-soc, dri-devel, linux-media

Hi Kieran,

Thank you for the patch.

On Thursday, 3 May 2018 16:36:15 EEST Kieran Bingham wrote:
> The vsp1 reference in the vsp1_dl_body structure is not used.
> Remove it.
> 
> Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>

Reviewed-by: Laurent Pinchart <laurent.pinchart@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 ec6fc21fabe0..b23e88cda49f
> 100644
> --- a/drivers/media/platform/vsp1/vsp1_dl.c
> +++ b/drivers/media/platform/vsp1/vsp1_dl.c
> @@ -44,7 +44,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
> @@ -58,7 +57,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;

-- 
Regards,

Laurent Pinchart



_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v4 05/11] media: vsp1: Clean up DLM objects on error
  2018-05-03 13:36   ` Kieran Bingham
@ 2018-05-24 10:58     ` Laurent Pinchart
  -1 siblings, 0 replies; 78+ messages in thread
From: Laurent Pinchart @ 2018-05-24 10:58 UTC (permalink / raw)
  To: Kieran Bingham; +Cc: linux-renesas-soc, linux-media, dri-devel

Hi Kieran,

Thank you for the patch.

On Thursday, 3 May 2018 16:36:16 EEST Kieran Bingham wrote:
> 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>

Reviewed-by: Laurent Pinchart <laurent.pinchart@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 b23e88cda49f..fbffbd407b29
> 100644
> --- a/drivers/media/platform/vsp1/vsp1_dl.c
> +++ b/drivers/media/platform/vsp1/vsp1_dl.c
> @@ -851,8 +851,10 @@ struct vsp1_dl_manager *vsp1_dlm_create(struct
> vsp1_device *vsp1, struct vsp1_dl_list *dl;
> 
>  		dl = vsp1_dl_list_alloc(dlm);
> -		if (!dl)
> +		if (!dl) {
> +			vsp1_dlm_destroy(dlm);
>  			return NULL;
> +		}
> 
>  		list_add_tail(&dl->list, &dlm->free);
>  	}


-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v4 05/11] media: vsp1: Clean up DLM objects on error
@ 2018-05-24 10:58     ` Laurent Pinchart
  0 siblings, 0 replies; 78+ messages in thread
From: Laurent Pinchart @ 2018-05-24 10:58 UTC (permalink / raw)
  To: Kieran Bingham; +Cc: linux-renesas-soc, dri-devel, linux-media

Hi Kieran,

Thank you for the patch.

On Thursday, 3 May 2018 16:36:16 EEST Kieran Bingham wrote:
> 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>

Reviewed-by: Laurent Pinchart <laurent.pinchart@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 b23e88cda49f..fbffbd407b29
> 100644
> --- a/drivers/media/platform/vsp1/vsp1_dl.c
> +++ b/drivers/media/platform/vsp1/vsp1_dl.c
> @@ -851,8 +851,10 @@ struct vsp1_dl_manager *vsp1_dlm_create(struct
> vsp1_device *vsp1, struct vsp1_dl_list *dl;
> 
>  		dl = vsp1_dl_list_alloc(dlm);
> -		if (!dl)
> +		if (!dl) {
> +			vsp1_dlm_destroy(dlm);
>  			return NULL;
> +		}
> 
>  		list_add_tail(&dl->list, &dlm->free);
>  	}


-- 
Regards,

Laurent Pinchart



_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v4 06/11] media: vsp1: Provide VSP1 feature helper macro
  2018-05-03 13:36   ` Kieran Bingham
@ 2018-05-24 11:00     ` Laurent Pinchart
  -1 siblings, 0 replies; 78+ messages in thread
From: Laurent Pinchart @ 2018-05-24 11:00 UTC (permalink / raw)
  To: Kieran Bingham; +Cc: linux-renesas-soc, linux-media, dri-devel

Hi Kieran,

Thank you for the patch.

On Thursday, 3 May 2018 16:36:17 EEST Kieran Bingham wrote:
> 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>

Reviewed-by: Laurent Pinchart <laurent.pinchart@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 33f632331474..f0d21cc8e9ab
> 100644
> --- a/drivers/media/platform/vsp1/vsp1.h
> +++ b/drivers/media/platform/vsp1/vsp1.h
> @@ -68,6 +68,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 d29f9c4baebe..0fc388bf5a33
> 100644
> --- a/drivers/media/platform/vsp1/vsp1_drv.c
> +++ b/drivers/media/platform/vsp1/vsp1_drv.c
> @@ -265,7 +265,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_brx_create(vsp1, VSP1_ENTITY_BRS);
>  		if (IS_ERR(vsp1->brs)) {
>  			ret = PTR_ERR(vsp1->brs);
> @@ -275,7 +275,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_brx_create(vsp1, VSP1_ENTITY_BRU);
>  		if (IS_ERR(vsp1->bru)) {
>  			ret = PTR_ERR(vsp1->bru);
> @@ -285,7 +285,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);
> @@ -311,7 +311,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);
> @@ -322,7 +322,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);
> @@ -353,7 +353,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);
> @@ -387,7 +387,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);
> @@ -537,7 +537,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 2edea361eee4..ea1d226371b2
> 100644
> --- a/drivers/media/platform/vsp1/vsp1_wpf.c
> +++ b/drivers/media/platform/vsp1/vsp1_wpf.c
> @@ -141,13 +141,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).
> @@ -276,7 +276,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 |


-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v4 06/11] media: vsp1: Provide VSP1 feature helper macro
@ 2018-05-24 11:00     ` Laurent Pinchart
  0 siblings, 0 replies; 78+ messages in thread
From: Laurent Pinchart @ 2018-05-24 11:00 UTC (permalink / raw)
  To: Kieran Bingham; +Cc: linux-renesas-soc, dri-devel, linux-media

Hi Kieran,

Thank you for the patch.

On Thursday, 3 May 2018 16:36:17 EEST Kieran Bingham wrote:
> 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>

Reviewed-by: Laurent Pinchart <laurent.pinchart@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 33f632331474..f0d21cc8e9ab
> 100644
> --- a/drivers/media/platform/vsp1/vsp1.h
> +++ b/drivers/media/platform/vsp1/vsp1.h
> @@ -68,6 +68,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 d29f9c4baebe..0fc388bf5a33
> 100644
> --- a/drivers/media/platform/vsp1/vsp1_drv.c
> +++ b/drivers/media/platform/vsp1/vsp1_drv.c
> @@ -265,7 +265,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_brx_create(vsp1, VSP1_ENTITY_BRS);
>  		if (IS_ERR(vsp1->brs)) {
>  			ret = PTR_ERR(vsp1->brs);
> @@ -275,7 +275,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_brx_create(vsp1, VSP1_ENTITY_BRU);
>  		if (IS_ERR(vsp1->bru)) {
>  			ret = PTR_ERR(vsp1->bru);
> @@ -285,7 +285,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);
> @@ -311,7 +311,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);
> @@ -322,7 +322,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);
> @@ -353,7 +353,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);
> @@ -387,7 +387,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);
> @@ -537,7 +537,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 2edea361eee4..ea1d226371b2
> 100644
> --- a/drivers/media/platform/vsp1/vsp1_wpf.c
> +++ b/drivers/media/platform/vsp1/vsp1_wpf.c
> @@ -141,13 +141,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).
> @@ -276,7 +276,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 |


-- 
Regards,

Laurent Pinchart



_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v4 07/11] media: vsp1: Use header display lists for all WPF outputs linked to the DU
  2018-05-03 13:36   ` Kieran Bingham
@ 2018-05-24 11:10     ` Laurent Pinchart
  -1 siblings, 0 replies; 78+ messages in thread
From: Laurent Pinchart @ 2018-05-24 11:10 UTC (permalink / raw)
  To: Kieran Bingham; +Cc: linux-renesas-soc, linux-media, dri-devel

Hi Kieran,

Thank you for the patch.

On Thursday, 3 May 2018 16:36:18 EEST Kieran Bingham wrote:
> 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(-)

I like the diffstat.

> diff --git a/drivers/media/platform/vsp1/vsp1_dl.c
> b/drivers/media/platform/vsp1/vsp1_dl.c index fbffbd407b29..56514cd51c51
> 100644
> --- a/drivers/media/platform/vsp1/vsp1_dl.c
> +++ b/drivers/media/platform/vsp1/vsp1_dl.c
> @@ -94,7 +94,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
> @@ -118,15 +118,9 @@ struct vsp1_dl_list {
>  	bool internal;
>  };
> 
> -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, and pending lists
> @@ -138,7 +132,6 @@ enum vsp1_dl_mode {
>   */
>  struct vsp1_dl_manager {
>  	unsigned int index;
> -	enum vsp1_dl_mode mode;
>  	bool singleshot;
>  	struct vsp1_device *vsp1;
> 
> @@ -318,6 +311,7 @@ void vsp1_dl_body_write(struct vsp1_dl_body *dlb, u32
> reg, u32 data) static struct vsp1_dl_list *vsp1_dl_list_alloc(struct
> vsp1_dl_manager *dlm) {
>  	struct vsp1_dl_list *dl;
> +	size_t header_offset;
> 
>  	dl = kzalloc(sizeof(*dl), GFP_KERNEL);
>  	if (!dl)
> @@ -330,16 +324,15 @@ static struct vsp1_dl_list *vsp1_dl_list_alloc(struct
> vsp1_dl_manager *dlm) dl->body0 = vsp1_dl_body_get(dlm->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);

Nitpicking, please align * under =.

> 
> -		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;
>  }
> @@ -471,16 +464,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);
> @@ -501,17 +487,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;
> @@ -579,17 +558,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.

I'd write this

	 * Check whether the VSP1 has taken the update. The hardware indicates
	 * this 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)
> @@ -597,26 +569,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

s/In header mode, program/Program/

You can also reformat the comment block to reach the 80th column.

> +	 * 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)
> @@ -674,15 +634,13 @@ void vsp1_dl_list_commit(struct vsp1_dl_list *dl, bool
> internal) 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);
>  	}
> 
>  	dl->internal = internal;
> @@ -783,13 +741,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);
>  }
> @@ -824,8 +775,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;
> 
> @@ -834,13 +783,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);

While at it, could you update the documentation of the 
vsp1_dlm_irq_frame_end() function to s/header mode/single-shot mode/ ?

With these small issues fixed,

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v4 07/11] media: vsp1: Use header display lists for all WPF outputs linked to the DU
@ 2018-05-24 11:10     ` Laurent Pinchart
  0 siblings, 0 replies; 78+ messages in thread
From: Laurent Pinchart @ 2018-05-24 11:10 UTC (permalink / raw)
  To: Kieran Bingham; +Cc: linux-renesas-soc, dri-devel, linux-media

Hi Kieran,

Thank you for the patch.

On Thursday, 3 May 2018 16:36:18 EEST Kieran Bingham wrote:
> 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(-)

I like the diffstat.

> diff --git a/drivers/media/platform/vsp1/vsp1_dl.c
> b/drivers/media/platform/vsp1/vsp1_dl.c index fbffbd407b29..56514cd51c51
> 100644
> --- a/drivers/media/platform/vsp1/vsp1_dl.c
> +++ b/drivers/media/platform/vsp1/vsp1_dl.c
> @@ -94,7 +94,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
> @@ -118,15 +118,9 @@ struct vsp1_dl_list {
>  	bool internal;
>  };
> 
> -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, and pending lists
> @@ -138,7 +132,6 @@ enum vsp1_dl_mode {
>   */
>  struct vsp1_dl_manager {
>  	unsigned int index;
> -	enum vsp1_dl_mode mode;
>  	bool singleshot;
>  	struct vsp1_device *vsp1;
> 
> @@ -318,6 +311,7 @@ void vsp1_dl_body_write(struct vsp1_dl_body *dlb, u32
> reg, u32 data) static struct vsp1_dl_list *vsp1_dl_list_alloc(struct
> vsp1_dl_manager *dlm) {
>  	struct vsp1_dl_list *dl;
> +	size_t header_offset;
> 
>  	dl = kzalloc(sizeof(*dl), GFP_KERNEL);
>  	if (!dl)
> @@ -330,16 +324,15 @@ static struct vsp1_dl_list *vsp1_dl_list_alloc(struct
> vsp1_dl_manager *dlm) dl->body0 = vsp1_dl_body_get(dlm->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);

Nitpicking, please align * under =.

> 
> -		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;
>  }
> @@ -471,16 +464,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);
> @@ -501,17 +487,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;
> @@ -579,17 +558,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.

I'd write this

	 * Check whether the VSP1 has taken the update. The hardware indicates
	 * this 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)
> @@ -597,26 +569,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

s/In header mode, program/Program/

You can also reformat the comment block to reach the 80th column.

> +	 * 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)
> @@ -674,15 +634,13 @@ void vsp1_dl_list_commit(struct vsp1_dl_list *dl, bool
> internal) 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);
>  	}
> 
>  	dl->internal = internal;
> @@ -783,13 +741,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);
>  }
> @@ -824,8 +775,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;
> 
> @@ -834,13 +783,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);

While at it, could you update the documentation of the 
vsp1_dlm_irq_frame_end() function to s/header mode/single-shot mode/ ?

With these small issues fixed,

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

-- 
Regards,

Laurent Pinchart



_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v4 08/11] media: vsp1: Add support for extended display list headers
  2018-05-03 13:36   ` Kieran Bingham
@ 2018-05-24 11:44     ` Laurent Pinchart
  -1 siblings, 0 replies; 78+ messages in thread
From: Laurent Pinchart @ 2018-05-24 11:44 UTC (permalink / raw)
  To: Kieran Bingham; +Cc: linux-renesas-soc, linux-media, dri-devel

Hi Kieran,

Thank you for the patch.

On Thursday, 3 May 2018 16:36:19 EEST Kieran Bingham wrote:
> 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>
> 
> ---
> 
> v2:
>  - remove __packed attributes
> ---
>  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 f0d21cc8e9ab..56c62122a81a
> 100644
> --- a/drivers/media/platform/vsp1/vsp1.h
> +++ b/drivers/media/platform/vsp1/vsp1.h
> @@ -53,6 +53,7 @@ struct vsp1_uif;
>  #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 56514cd51c51..b64d32535edc
> 100644
> --- a/drivers/media/platform/vsp1/vsp1_dl.c
> +++ b/drivers/media/platform/vsp1/vsp1_dl.c
> @@ -22,6 +22,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;
> @@ -34,11 +37,34 @@ struct vsp1_dl_header {
>  	u32 flags;
>  };
> 
> +struct vsp1_dl_ext_header {
> +	u32 reserved0;		/* alignment padding */
> +
> +	u16 pre_ext_cmd_qty;

Should this be called pre_ext_dl_num_cmd to match the datasheet ?

> +	u16 flags;

Aren't the flags supposed to come before the pre_ext_dl_num_cmd field ?

> +	u32 pre_ext_cmd_plist;

And pre_ext_dl_plist ?

> +
> +	u32 post_ext_cmd_qty;
> +	u32 post_ext_cmd_plist;

Similar comments for these variables.

> +};
> +
> +struct vsp1_dl_header_extended {
> +	struct vsp1_dl_header header;
> +	struct vsp1_dl_ext_header ext;
> +};
> +
>  struct vsp1_dl_entry {
>  	u32 addr;
>  	u32 data;
>  };
> 
> +struct vsp1_dl_ext_cmd_header {

Isn't this referred to in the datasheet as a body entry, not a header ? How 
about naming it vsp1_dl_ext_cmd_entry ? Or just vsp1_dl_ext_cmd (in which case 
the other structure that goes by the same name would need to be renamed) ?

> +	u32 cmd;
> +	u32 flags;
> +	u32 data;
> +	u32 reserved;

The datasheet documents this as two 64-bit fields, shouldn't we handle the 
structure the same way ?

> +};
> +
>  /**
>   * struct vsp1_dl_body - Display list body
>   * @list: entry in the display list list of bodies
> @@ -95,9 +121,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

Should we name this extension instead of extended ?

>   * @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

I think you can spell command in full.

>   * @has_chain: if true, indicates that there's a partition chain
>   * @chain: entry in the display list partition chain
>   * @internal: whether the display list is used for internal purpose
> @@ -107,11 +136,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;
> 
> @@ -496,6 +529,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;
> @@ -548,6 +589,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)
> @@ -735,14 +797,20 @@ unsigned int 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));

Is this change needed ? If VI6_DL_SWAP_IND is not set in VI6_DL_SWAP(1), 
display list swap for WPF1 is supposed to be controlled by VI6_DL_SWAP(0) 
according to the datasheet.

If that's not the case and this change is needed, I would split support for 
VI6_DL_SWAP(n) to a separate patch, and moved it before 07/11.

>  }
> 
>  void vsp1_dlm_reset(struct vsp1_dl_manager *dlm)
> @@ -787,7 +855,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);

We will have to improve header handling at some point. Not all headers require 
extensions.

>  	dlm->pool = vsp1_dl_body_pool_create(vsp1, prealloc,
>  					     VSP1_DL_NUM_ENTRIES, header_size);
> @@ -803,6 +875,11 @@ struct vsp1_dl_manager *vsp1_dlm_create(struct
> vsp1_device *vsp1, return NULL;
>  		}
> 
> +		/* The extended header immediately follows the header */

s/ \*/. */

> +		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 216bd23029dd..aa5f4adc6617
> 100644
> --- a/drivers/media/platform/vsp1/vsp1_dl.h
> +++ b/drivers/media/platform/vsp1/vsp1_dl.h
> @@ -20,7 +20,34 @@ struct vsp1_dl_manager;
>  #define VSP1_DL_FRAME_END_COMPLETED		BIT(0)
>  #define VSP1_DL_FRAME_END_INTERNAL		BIT(1)
> 
> -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

Maybe just 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

s/command bodies/commands body/ ?

> + * @data: memory allocation for command specific data
> + * @data_dma: DMA address for command specific data

s/command specific/command-specific/

> + * @data_size: size of the @data_dma memory in bytes

data_size is set but otherwise never used. Should we drop the field, or make 
use of it ?

> + */
> +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 0fc388bf5a33..26a7b4d32e6c
> 100644
> --- a/drivers/media/platform/vsp1/vsp1_drv.c
> +++ b/drivers/media/platform/vsp1/vsp1_drv.c
> @@ -545,7 +545,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;
>  }
> @@ -754,7 +755,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,
>  		.uif_count = 1,
> @@ -774,7 +775,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,
>  		.uif_count = 2,
> diff --git a/drivers/media/platform/vsp1/vsp1_regs.h
> b/drivers/media/platform/vsp1/vsp1_regs.h index 0d249ff9f564..d054767570c1
> 100644
> --- a/drivers/media/platform/vsp1/vsp1_regs.h
> +++ b/drivers/media/platform/vsp1/vsp1_regs.h
> @@ -67,12 +67,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

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v4 08/11] media: vsp1: Add support for extended display list headers
@ 2018-05-24 11:44     ` Laurent Pinchart
  0 siblings, 0 replies; 78+ messages in thread
From: Laurent Pinchart @ 2018-05-24 11:44 UTC (permalink / raw)
  To: Kieran Bingham; +Cc: linux-renesas-soc, dri-devel, linux-media

Hi Kieran,

Thank you for the patch.

On Thursday, 3 May 2018 16:36:19 EEST Kieran Bingham wrote:
> 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>
> 
> ---
> 
> v2:
>  - remove __packed attributes
> ---
>  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 f0d21cc8e9ab..56c62122a81a
> 100644
> --- a/drivers/media/platform/vsp1/vsp1.h
> +++ b/drivers/media/platform/vsp1/vsp1.h
> @@ -53,6 +53,7 @@ struct vsp1_uif;
>  #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 56514cd51c51..b64d32535edc
> 100644
> --- a/drivers/media/platform/vsp1/vsp1_dl.c
> +++ b/drivers/media/platform/vsp1/vsp1_dl.c
> @@ -22,6 +22,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;
> @@ -34,11 +37,34 @@ struct vsp1_dl_header {
>  	u32 flags;
>  };
> 
> +struct vsp1_dl_ext_header {
> +	u32 reserved0;		/* alignment padding */
> +
> +	u16 pre_ext_cmd_qty;

Should this be called pre_ext_dl_num_cmd to match the datasheet ?

> +	u16 flags;

Aren't the flags supposed to come before the pre_ext_dl_num_cmd field ?

> +	u32 pre_ext_cmd_plist;

And pre_ext_dl_plist ?

> +
> +	u32 post_ext_cmd_qty;
> +	u32 post_ext_cmd_plist;

Similar comments for these variables.

> +};
> +
> +struct vsp1_dl_header_extended {
> +	struct vsp1_dl_header header;
> +	struct vsp1_dl_ext_header ext;
> +};
> +
>  struct vsp1_dl_entry {
>  	u32 addr;
>  	u32 data;
>  };
> 
> +struct vsp1_dl_ext_cmd_header {

Isn't this referred to in the datasheet as a body entry, not a header ? How 
about naming it vsp1_dl_ext_cmd_entry ? Or just vsp1_dl_ext_cmd (in which case 
the other structure that goes by the same name would need to be renamed) ?

> +	u32 cmd;
> +	u32 flags;
> +	u32 data;
> +	u32 reserved;

The datasheet documents this as two 64-bit fields, shouldn't we handle the 
structure the same way ?

> +};
> +
>  /**
>   * struct vsp1_dl_body - Display list body
>   * @list: entry in the display list list of bodies
> @@ -95,9 +121,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

Should we name this extension instead of extended ?

>   * @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

I think you can spell command in full.

>   * @has_chain: if true, indicates that there's a partition chain
>   * @chain: entry in the display list partition chain
>   * @internal: whether the display list is used for internal purpose
> @@ -107,11 +136,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;
> 
> @@ -496,6 +529,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;
> @@ -548,6 +589,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)
> @@ -735,14 +797,20 @@ unsigned int 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));

Is this change needed ? If VI6_DL_SWAP_IND is not set in VI6_DL_SWAP(1), 
display list swap for WPF1 is supposed to be controlled by VI6_DL_SWAP(0) 
according to the datasheet.

If that's not the case and this change is needed, I would split support for 
VI6_DL_SWAP(n) to a separate patch, and moved it before 07/11.

>  }
> 
>  void vsp1_dlm_reset(struct vsp1_dl_manager *dlm)
> @@ -787,7 +855,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);

We will have to improve header handling at some point. Not all headers require 
extensions.

>  	dlm->pool = vsp1_dl_body_pool_create(vsp1, prealloc,
>  					     VSP1_DL_NUM_ENTRIES, header_size);
> @@ -803,6 +875,11 @@ struct vsp1_dl_manager *vsp1_dlm_create(struct
> vsp1_device *vsp1, return NULL;
>  		}
> 
> +		/* The extended header immediately follows the header */

s/ \*/. */

> +		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 216bd23029dd..aa5f4adc6617
> 100644
> --- a/drivers/media/platform/vsp1/vsp1_dl.h
> +++ b/drivers/media/platform/vsp1/vsp1_dl.h
> @@ -20,7 +20,34 @@ struct vsp1_dl_manager;
>  #define VSP1_DL_FRAME_END_COMPLETED		BIT(0)
>  #define VSP1_DL_FRAME_END_INTERNAL		BIT(1)
> 
> -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

Maybe just 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

s/command bodies/commands body/ ?

> + * @data: memory allocation for command specific data
> + * @data_dma: DMA address for command specific data

s/command specific/command-specific/

> + * @data_size: size of the @data_dma memory in bytes

data_size is set but otherwise never used. Should we drop the field, or make 
use of it ?

> + */
> +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 0fc388bf5a33..26a7b4d32e6c
> 100644
> --- a/drivers/media/platform/vsp1/vsp1_drv.c
> +++ b/drivers/media/platform/vsp1/vsp1_drv.c
> @@ -545,7 +545,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;
>  }
> @@ -754,7 +755,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,
>  		.uif_count = 1,
> @@ -774,7 +775,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,
>  		.uif_count = 2,
> diff --git a/drivers/media/platform/vsp1/vsp1_regs.h
> b/drivers/media/platform/vsp1/vsp1_regs.h index 0d249ff9f564..d054767570c1
> 100644
> --- a/drivers/media/platform/vsp1/vsp1_regs.h
> +++ b/drivers/media/platform/vsp1/vsp1_regs.h
> @@ -67,12 +67,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

-- 
Regards,

Laurent Pinchart



_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v4 11/11] drm: rcar-du: Support interlaced video output through vsp1
  2018-05-03 13:36   ` Kieran Bingham
@ 2018-05-24 11:50     ` Laurent Pinchart
  -1 siblings, 0 replies; 78+ messages in thread
From: Laurent Pinchart @ 2018-05-24 11:50 UTC (permalink / raw)
  To: Kieran Bingham; +Cc: linux-renesas-soc, linux-media, dri-devel

Hi Kieran,

Thank you for the patch.

On Thursday, 3 May 2018 16:36:22 EEST Kieran Bingham wrote:
> Use the newly exposed VSP1 interface to enable interlaced frame support
> through the VSP1 lif pipelines.

s/lif/LIF/

> 
> 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 d71d709fe3d9..206532959ec9
> 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> @@ -289,6 +289,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)

How will this affect Gen2 ? Could you document what this change does in the 
commit message ?

>  	      | 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 af7822a66dee..c7b37232ee91
> 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
> @@ -186,6 +186,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;

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v4 11/11] drm: rcar-du: Support interlaced video output through vsp1
@ 2018-05-24 11:50     ` Laurent Pinchart
  0 siblings, 0 replies; 78+ messages in thread
From: Laurent Pinchart @ 2018-05-24 11:50 UTC (permalink / raw)
  To: Kieran Bingham; +Cc: linux-renesas-soc, dri-devel, linux-media

Hi Kieran,

Thank you for the patch.

On Thursday, 3 May 2018 16:36:22 EEST Kieran Bingham wrote:
> Use the newly exposed VSP1 interface to enable interlaced frame support
> through the VSP1 lif pipelines.

s/lif/LIF/

> 
> 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 d71d709fe3d9..206532959ec9
> 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> @@ -289,6 +289,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)

How will this affect Gen2 ? Could you document what this change does in the 
commit message ?

>  	      | 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 af7822a66dee..c7b37232ee91
> 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
> @@ -186,6 +186,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;

-- 
Regards,

Laurent Pinchart



_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v4 09/11] media: vsp1: Provide support for extended command pools
  2018-05-03 13:36   ` Kieran Bingham
@ 2018-05-24 12:12     ` Laurent Pinchart
  -1 siblings, 0 replies; 78+ messages in thread
From: Laurent Pinchart @ 2018-05-24 12:12 UTC (permalink / raw)
  To: Kieran Bingham; +Cc: linux-renesas-soc, linux-media, dri-devel

Hi Kieran,

Thank you for the patch.

On Thursday, 3 May 2018 16:36:20 EEST 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 convenient
> re-usable command objects for the entities to utilise.
> 
> Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
> 
> ---
> 
> v2:
>  - Fix spelling typo in commit message
>  - constify, and staticify the instantiation of vsp1_extended_commands
>  - s/autfld_cmds/autofld_cmds/
>  - staticify cmd pool functions (Thanks kbuild-bot)
> ---
>  drivers/media/platform/vsp1/vsp1_dl.c | 191 +++++++++++++++++++++++++++-
>  drivers/media/platform/vsp1/vsp1_dl.h |   3 +-
>  2 files changed, 194 insertions(+)
> 
> diff --git a/drivers/media/platform/vsp1/vsp1_dl.c
> b/drivers/media/platform/vsp1/vsp1_dl.c index b64d32535edc..d33ae5f125bd
> 100644
> --- a/drivers/media/platform/vsp1/vsp1_dl.c
> +++ b/drivers/media/platform/vsp1/vsp1_dl.c
> @@ -117,6 +117,30 @@ struct vsp1_dl_body_pool {
>  };
> 
>  /**
> + * struct vsp1_cmd_pool - display list body pool

The structure is called vsp1_dl_cmd_pool. I would document it as "Display list 
commands pool", not "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

The field is called cmds.

> + * @free: List of free DLB entries

"free pool entries" or "free command entries" ?

> + * @lock: Protects the pool and free list

The pool is the whole structure, does the lock really protects all fields ?

> + * @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
> @@ -162,6 +186,7 @@ struct vsp1_dl_list {
>   * @queued: list queued to the hardware (written to the DL registers)
>   * @pending: list waiting to be queued to the hardware
>   * @pool: body pool for the display list bodies
> + * @autofld_cmds: command pool to support auto-fld interlaced mode

This could also be used for auto-disp. How about calling it cmdpool ?

>   */
>  struct vsp1_dl_manager {
>  	unsigned int index;
> @@ -175,6 +200,7 @@ struct vsp1_dl_manager {
>  	struct vsp1_dl_list *pending;
> 
>  	struct vsp1_dl_body_pool *pool;
> +	struct vsp1_dl_cmd_pool *autofld_cmds;
>  };
> 
>  /* ------------------------------------------------------------------------
> @@ -338,6 +364,140 @@ 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;
> +} static const vsp1_extended_commands[] = {

The location of the static const keywords is strange. I would move them before 
struct, or split the structure definition and variable declaration.

> +	[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

s/quantity/number/ ?

> + *
> + * 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

s/a pool/the pool/

> allocated.
> + */
> +static 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);

I would move these two lines right after allocation of pool, I find it more 
readable to perform small and simple initialization right away.

> +	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;

The data memory has to be 16-bytes aligned. This is guaranteed as the header 
is 16 bytes long, and cmd_size is aligned to 16 bytes, but it would be worth 
adding a comment to explain this.

> +		cmd->pool = pool;
> +		cmd->cmd_opcode = vsp1_extended_commands[type].opcode;
> +
> +		/* TODO: Auto-disp can utilise more than one command per cmd */

That will be annoying to handle :-/

> +		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;
> +}
> +
> +static
> +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;
> +}
> +
> +static void vsp1_dl_ext_cmd_put(struct vsp1_dl_ext_cmd *cmd)
> +{
> +	unsigned long flags;
> +
> +	if (!cmd)
> +		return;
> +
> +	/* Reset flags, these mark data usage */

s/usage/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);
> +}
> +
> +static 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
>   */
> 
> @@ -440,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.
> @@ -883,6 +1049,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->autofld_cmds = vsp1_dl_cmd_pool_create(vsp1,
> +					VSP1_EXTCMD_AUTOFLD, prealloc);
> +		if (!dlm->autofld_cmds) {
> +			vsp1_dlm_destroy(dlm);
> +			return NULL;
> +		}
> +	}
> +
>  	return dlm;
>  }
> 
> @@ -899,4 +1074,20 @@ void vsp1_dlm_destroy(struct vsp1_dl_manager *dlm)
>  	}
> 
>  	vsp1_dl_body_pool_destroy(dlm->pool);
> +	vsp1_dl_ext_cmd_pool_destroy(dlm->autofld_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->autofld_cmds);
> +	if (cmd)
> +		dl->pre_cmd = cmd;
> +
> +	return cmd;

You can write it in a simpler way.

	dl->pre_cmd = vsp1_dl_ext_cmd_get(dlm->autofld_cmds);
	return dl->pre_cmd;

>  }
> diff --git a/drivers/media/platform/vsp1/vsp1_dl.h
> b/drivers/media/platform/vsp1/vsp1_dl.h index aa5f4adc6617..d9621207b093
> 100644
> --- a/drivers/media/platform/vsp1/vsp1_dl.h
> +++ b/drivers/media/platform/vsp1/vsp1_dl.h
> @@ -22,6 +22,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
> @@ -33,6 +34,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;
> @@ -55,6 +57,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);
>  unsigned int 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);

Should this be named vsp1_dl_get_autofld_cmd() as it operates on a dl ? I also 
think that you should move it down to group it with the dl functions.

>  struct vsp1_dl_list *vsp1_dl_list_get(struct vsp1_dl_manager *dlm);
>  void vsp1_dl_list_put(struct vsp1_dl_list *dl);

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v4 09/11] media: vsp1: Provide support for extended command pools
@ 2018-05-24 12:12     ` Laurent Pinchart
  0 siblings, 0 replies; 78+ messages in thread
From: Laurent Pinchart @ 2018-05-24 12:12 UTC (permalink / raw)
  To: Kieran Bingham; +Cc: linux-renesas-soc, dri-devel, linux-media

Hi Kieran,

Thank you for the patch.

On Thursday, 3 May 2018 16:36:20 EEST 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 convenient
> re-usable command objects for the entities to utilise.
> 
> Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
> 
> ---
> 
> v2:
>  - Fix spelling typo in commit message
>  - constify, and staticify the instantiation of vsp1_extended_commands
>  - s/autfld_cmds/autofld_cmds/
>  - staticify cmd pool functions (Thanks kbuild-bot)
> ---
>  drivers/media/platform/vsp1/vsp1_dl.c | 191 +++++++++++++++++++++++++++-
>  drivers/media/platform/vsp1/vsp1_dl.h |   3 +-
>  2 files changed, 194 insertions(+)
> 
> diff --git a/drivers/media/platform/vsp1/vsp1_dl.c
> b/drivers/media/platform/vsp1/vsp1_dl.c index b64d32535edc..d33ae5f125bd
> 100644
> --- a/drivers/media/platform/vsp1/vsp1_dl.c
> +++ b/drivers/media/platform/vsp1/vsp1_dl.c
> @@ -117,6 +117,30 @@ struct vsp1_dl_body_pool {
>  };
> 
>  /**
> + * struct vsp1_cmd_pool - display list body pool

The structure is called vsp1_dl_cmd_pool. I would document it as "Display list 
commands pool", not "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

The field is called cmds.

> + * @free: List of free DLB entries

"free pool entries" or "free command entries" ?

> + * @lock: Protects the pool and free list

The pool is the whole structure, does the lock really protects all fields ?

> + * @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
> @@ -162,6 +186,7 @@ struct vsp1_dl_list {
>   * @queued: list queued to the hardware (written to the DL registers)
>   * @pending: list waiting to be queued to the hardware
>   * @pool: body pool for the display list bodies
> + * @autofld_cmds: command pool to support auto-fld interlaced mode

This could also be used for auto-disp. How about calling it cmdpool ?

>   */
>  struct vsp1_dl_manager {
>  	unsigned int index;
> @@ -175,6 +200,7 @@ struct vsp1_dl_manager {
>  	struct vsp1_dl_list *pending;
> 
>  	struct vsp1_dl_body_pool *pool;
> +	struct vsp1_dl_cmd_pool *autofld_cmds;
>  };
> 
>  /* ------------------------------------------------------------------------
> @@ -338,6 +364,140 @@ 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;
> +} static const vsp1_extended_commands[] = {

The location of the static const keywords is strange. I would move them before 
struct, or split the structure definition and variable declaration.

> +	[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

s/quantity/number/ ?

> + *
> + * 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

s/a pool/the pool/

> allocated.
> + */
> +static 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);

I would move these two lines right after allocation of pool, I find it more 
readable to perform small and simple initialization right away.

> +	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;

The data memory has to be 16-bytes aligned. This is guaranteed as the header 
is 16 bytes long, and cmd_size is aligned to 16 bytes, but it would be worth 
adding a comment to explain this.

> +		cmd->pool = pool;
> +		cmd->cmd_opcode = vsp1_extended_commands[type].opcode;
> +
> +		/* TODO: Auto-disp can utilise more than one command per cmd */

That will be annoying to handle :-/

> +		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;
> +}
> +
> +static
> +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;
> +}
> +
> +static void vsp1_dl_ext_cmd_put(struct vsp1_dl_ext_cmd *cmd)
> +{
> +	unsigned long flags;
> +
> +	if (!cmd)
> +		return;
> +
> +	/* Reset flags, these mark data usage */

s/usage/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);
> +}
> +
> +static 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
>   */
> 
> @@ -440,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.
> @@ -883,6 +1049,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->autofld_cmds = vsp1_dl_cmd_pool_create(vsp1,
> +					VSP1_EXTCMD_AUTOFLD, prealloc);
> +		if (!dlm->autofld_cmds) {
> +			vsp1_dlm_destroy(dlm);
> +			return NULL;
> +		}
> +	}
> +
>  	return dlm;
>  }
> 
> @@ -899,4 +1074,20 @@ void vsp1_dlm_destroy(struct vsp1_dl_manager *dlm)
>  	}
> 
>  	vsp1_dl_body_pool_destroy(dlm->pool);
> +	vsp1_dl_ext_cmd_pool_destroy(dlm->autofld_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->autofld_cmds);
> +	if (cmd)
> +		dl->pre_cmd = cmd;
> +
> +	return cmd;

You can write it in a simpler way.

	dl->pre_cmd = vsp1_dl_ext_cmd_get(dlm->autofld_cmds);
	return dl->pre_cmd;

>  }
> diff --git a/drivers/media/platform/vsp1/vsp1_dl.h
> b/drivers/media/platform/vsp1/vsp1_dl.h index aa5f4adc6617..d9621207b093
> 100644
> --- a/drivers/media/platform/vsp1/vsp1_dl.h
> +++ b/drivers/media/platform/vsp1/vsp1_dl.h
> @@ -22,6 +22,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
> @@ -33,6 +34,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;
> @@ -55,6 +57,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);
>  unsigned int 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);

Should this be named vsp1_dl_get_autofld_cmd() as it operates on a dl ? I also 
think that you should move it down to group it with the dl functions.

>  struct vsp1_dl_list *vsp1_dl_list_get(struct vsp1_dl_manager *dlm);
>  void vsp1_dl_list_put(struct vsp1_dl_list *dl);

-- 
Regards,

Laurent Pinchart



_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v4 10/11] media: vsp1: Support Interlaced display pipelines
  2018-05-03 13:36   ` Kieran Bingham
@ 2018-05-24 12:51     ` Laurent Pinchart
  -1 siblings, 0 replies; 78+ messages in thread
From: Laurent Pinchart @ 2018-05-24 12:51 UTC (permalink / raw)
  To: Kieran Bingham; +Cc: linux-renesas-soc, linux-media, dri-devel

Hi Kieran,

Thank you for the patch.

On Thursday, 3 May 2018 16:36:21 EEST Kieran Bingham wrote:
> 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>
> 
> ---
> v3:
>  - Pass DL through partition calls to allow autocmd's to be retrieved
>  - Document interlaced field in struct vsp1_du_atomic_config
> 
> v2:
>  - fix erroneous BIT value which enabled interlaced
>  - fix field handling at frame_end interrupt
> ---
>  drivers/media/platform/vsp1/vsp1_dl.c   | 10 ++++-
>  drivers/media/platform/vsp1/vsp1_drm.c  | 11 ++++-
>  drivers/media/platform/vsp1/vsp1_regs.h |  1 +-
>  drivers/media/platform/vsp1/vsp1_rpf.c  | 71 ++++++++++++++++++++++++--
>  drivers/media/platform/vsp1/vsp1_rwpf.h |  1 +-
>  include/media/vsp1.h                    |  2 +-
>  6 files changed, 93 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/media/platform/vsp1/vsp1_dl.c
> b/drivers/media/platform/vsp1/vsp1_dl.c index d33ae5f125bd..bbe9f3006f71
> 100644
> --- a/drivers/media/platform/vsp1/vsp1_dl.c
> +++ b/drivers/media/platform/vsp1/vsp1_dl.c
> @@ -906,6 +906,8 @@ void vsp1_dl_list_commit(struct vsp1_dl_list *dl, bool
> internal) */
>  unsigned int vsp1_dlm_irq_frame_end(struct vsp1_dl_manager *dlm)
>  {
> +	struct vsp1_device *vsp1 = dlm->vsp1;
> +	u32 status = vsp1_read(vsp1, VI6_STATUS);
>  	unsigned int flags = 0;
> 
>  	spin_lock(&dlm->lock);
> @@ -931,6 +933,14 @@ unsigned int vsp1_dlm_irq_frame_end(struct
> vsp1_dl_manager *dlm) goto done;
> 
>  	/*
> +	 * Progressive streams report only TOP fields. If we have a BOTTOM
> +	 * field, we are interlaced, and expect the frame to complete on the
> +	 * next frame end interrupt.
> +	 */
> +	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_drm.c
> b/drivers/media/platform/vsp1/vsp1_drm.c index 2c3db8b8adce..cc29c9d96bb7
> 100644
> --- a/drivers/media/platform/vsp1/vsp1_drm.c
> +++ b/drivers/media/platform/vsp1/vsp1_drm.c
> @@ -811,6 +811,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) {

Nitpicking, writing the condition as

	if (cfg->interlaced && !(vsp1_feature(vsp1, VSP1_HAS_EXT_DL)))

would match the comment better. You can also drop the parentheses around the 
vsp1_feature() call.

> +		/*
> +		 * 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");

Could we catch this in the DU driver to fail atomic test ?

> +		return -EINVAL;
> +	}
> +
> +	rpf->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_regs.h
> b/drivers/media/platform/vsp1/vsp1_regs.h index d054767570c1..a2ac65cc5155
> 100644
> --- a/drivers/media/platform/vsp1/vsp1_regs.h
> +++ b/drivers/media/platform/vsp1/vsp1_regs.h
> @@ -28,6 +28,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 8fae7c485642..511b2e127820
> 100644
> --- a/drivers/media/platform/vsp1/vsp1_rpf.c
> +++ b/drivers/media/platform/vsp1/vsp1_rpf.c
> @@ -20,6 +20,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(0)

Should the bit definition be moved to vsp1_regs.h ?

>  /* ------------------------------------------------------------------------
>   * Device Access
>   */
> @@ -64,6 +78,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 */
> @@ -100,6 +122,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));
> @@ -169,6 +194,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 */

s/RPF/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);

Do you expect some flags to already be set ? If not, couldn't we assign the 
value to the field instead of OR'ing it ?

> +}
> +
>  static void rpf_configure_frame(struct vsp1_entity *entity,
>  				struct vsp1_pipeline *pipe,
>  				struct vsp1_dl_list *dl,
> @@ -192,6 +242,7 @@ static void rpf_configure_partition(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_partition(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,9 +304,18 @@ static void rpf_configure_partition(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);

How about moving this call to vsp1_rpf_configure_autofld() ?

> +		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,
> diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.h
> b/drivers/media/platform/vsp1/vsp1_rwpf.h index 70742ecf766f..8d6e42f27908
> 100644
> --- a/drivers/media/platform/vsp1/vsp1_rwpf.h
> +++ b/drivers/media/platform/vsp1/vsp1_rwpf.h
> @@ -42,6 +42,7 @@ struct vsp1_rwpf {
>  	struct v4l2_pix_format_mplane format;
>  	const struct vsp1_format_info *fmtinfo;
>  	unsigned int brx_input;
> +	bool interlaced;

Shouldn't this be stored in the pipeline instead ? Interlacing is a property 
of the whole pipeline, not of each input individually.

>  	unsigned int alpha;
> 
> diff --git a/include/media/vsp1.h b/include/media/vsp1.h
> index 678c24de1ac6..c10883f30980 100644
> --- a/include/media/vsp1.h
> +++ b/include/media/vsp1.h
> @@ -50,6 +50,7 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int
> pipe_index,
>   * @dst: destination rectangle on the display (integer coordinates)
>   * @alpha: alpha value (0: fully transparent, 255: fully opaque)
>   * @zpos: Z position of the plane (from 0 to number of planes minus 1)
> + * @interlaced: true for interlaced pipelines
>   */
>  struct vsp1_du_atomic_config {
>  	u32 pixelformat;
> @@ -59,6 +60,7 @@ struct vsp1_du_atomic_config {
>  	struct v4l2_rect dst;
>  	unsigned int alpha;
>  	unsigned int zpos;
> +	bool interlaced;

For the same reason shouldn't the interlaced flag be moved to 
vsp1_du_lif_config ?

>  };
> 
>  /**

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v4 10/11] media: vsp1: Support Interlaced display pipelines
@ 2018-05-24 12:51     ` Laurent Pinchart
  0 siblings, 0 replies; 78+ messages in thread
From: Laurent Pinchart @ 2018-05-24 12:51 UTC (permalink / raw)
  To: Kieran Bingham; +Cc: linux-renesas-soc, dri-devel, linux-media

Hi Kieran,

Thank you for the patch.

On Thursday, 3 May 2018 16:36:21 EEST Kieran Bingham wrote:
> 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>
> 
> ---
> v3:
>  - Pass DL through partition calls to allow autocmd's to be retrieved
>  - Document interlaced field in struct vsp1_du_atomic_config
> 
> v2:
>  - fix erroneous BIT value which enabled interlaced
>  - fix field handling at frame_end interrupt
> ---
>  drivers/media/platform/vsp1/vsp1_dl.c   | 10 ++++-
>  drivers/media/platform/vsp1/vsp1_drm.c  | 11 ++++-
>  drivers/media/platform/vsp1/vsp1_regs.h |  1 +-
>  drivers/media/platform/vsp1/vsp1_rpf.c  | 71 ++++++++++++++++++++++++--
>  drivers/media/platform/vsp1/vsp1_rwpf.h |  1 +-
>  include/media/vsp1.h                    |  2 +-
>  6 files changed, 93 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/media/platform/vsp1/vsp1_dl.c
> b/drivers/media/platform/vsp1/vsp1_dl.c index d33ae5f125bd..bbe9f3006f71
> 100644
> --- a/drivers/media/platform/vsp1/vsp1_dl.c
> +++ b/drivers/media/platform/vsp1/vsp1_dl.c
> @@ -906,6 +906,8 @@ void vsp1_dl_list_commit(struct vsp1_dl_list *dl, bool
> internal) */
>  unsigned int vsp1_dlm_irq_frame_end(struct vsp1_dl_manager *dlm)
>  {
> +	struct vsp1_device *vsp1 = dlm->vsp1;
> +	u32 status = vsp1_read(vsp1, VI6_STATUS);
>  	unsigned int flags = 0;
> 
>  	spin_lock(&dlm->lock);
> @@ -931,6 +933,14 @@ unsigned int vsp1_dlm_irq_frame_end(struct
> vsp1_dl_manager *dlm) goto done;
> 
>  	/*
> +	 * Progressive streams report only TOP fields. If we have a BOTTOM
> +	 * field, we are interlaced, and expect the frame to complete on the
> +	 * next frame end interrupt.
> +	 */
> +	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_drm.c
> b/drivers/media/platform/vsp1/vsp1_drm.c index 2c3db8b8adce..cc29c9d96bb7
> 100644
> --- a/drivers/media/platform/vsp1/vsp1_drm.c
> +++ b/drivers/media/platform/vsp1/vsp1_drm.c
> @@ -811,6 +811,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) {

Nitpicking, writing the condition as

	if (cfg->interlaced && !(vsp1_feature(vsp1, VSP1_HAS_EXT_DL)))

would match the comment better. You can also drop the parentheses around the 
vsp1_feature() call.

> +		/*
> +		 * 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");

Could we catch this in the DU driver to fail atomic test ?

> +		return -EINVAL;
> +	}
> +
> +	rpf->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_regs.h
> b/drivers/media/platform/vsp1/vsp1_regs.h index d054767570c1..a2ac65cc5155
> 100644
> --- a/drivers/media/platform/vsp1/vsp1_regs.h
> +++ b/drivers/media/platform/vsp1/vsp1_regs.h
> @@ -28,6 +28,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 8fae7c485642..511b2e127820
> 100644
> --- a/drivers/media/platform/vsp1/vsp1_rpf.c
> +++ b/drivers/media/platform/vsp1/vsp1_rpf.c
> @@ -20,6 +20,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(0)

Should the bit definition be moved to vsp1_regs.h ?

>  /* ------------------------------------------------------------------------
>   * Device Access
>   */
> @@ -64,6 +78,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 */
> @@ -100,6 +122,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));
> @@ -169,6 +194,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 */

s/RPF/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);

Do you expect some flags to already be set ? If not, couldn't we assign the 
value to the field instead of OR'ing it ?

> +}
> +
>  static void rpf_configure_frame(struct vsp1_entity *entity,
>  				struct vsp1_pipeline *pipe,
>  				struct vsp1_dl_list *dl,
> @@ -192,6 +242,7 @@ static void rpf_configure_partition(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_partition(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,9 +304,18 @@ static void rpf_configure_partition(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);

How about moving this call to vsp1_rpf_configure_autofld() ?

> +		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,
> diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.h
> b/drivers/media/platform/vsp1/vsp1_rwpf.h index 70742ecf766f..8d6e42f27908
> 100644
> --- a/drivers/media/platform/vsp1/vsp1_rwpf.h
> +++ b/drivers/media/platform/vsp1/vsp1_rwpf.h
> @@ -42,6 +42,7 @@ struct vsp1_rwpf {
>  	struct v4l2_pix_format_mplane format;
>  	const struct vsp1_format_info *fmtinfo;
>  	unsigned int brx_input;
> +	bool interlaced;

Shouldn't this be stored in the pipeline instead ? Interlacing is a property 
of the whole pipeline, not of each input individually.

>  	unsigned int alpha;
> 
> diff --git a/include/media/vsp1.h b/include/media/vsp1.h
> index 678c24de1ac6..c10883f30980 100644
> --- a/include/media/vsp1.h
> +++ b/include/media/vsp1.h
> @@ -50,6 +50,7 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int
> pipe_index,
>   * @dst: destination rectangle on the display (integer coordinates)
>   * @alpha: alpha value (0: fully transparent, 255: fully opaque)
>   * @zpos: Z position of the plane (from 0 to number of planes minus 1)
> + * @interlaced: true for interlaced pipelines
>   */
>  struct vsp1_du_atomic_config {
>  	u32 pixelformat;
> @@ -59,6 +60,7 @@ struct vsp1_du_atomic_config {
>  	struct v4l2_rect dst;
>  	unsigned int alpha;
>  	unsigned int zpos;
> +	bool interlaced;

For the same reason shouldn't the interlaced flag be moved to 
vsp1_du_lif_config ?

>  };
> 
>  /**

-- 
Regards,

Laurent Pinchart



_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v4 02/11] media: vsp1: Remove packed attributes from aligned structures
  2018-05-24 10:47     ` Laurent Pinchart
@ 2018-07-13 10:17       ` Kieran Bingham
  -1 siblings, 0 replies; 78+ messages in thread
From: Kieran Bingham @ 2018-07-13 10:17 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: linux-renesas-soc, linux-media, dri-devel

Hi Laurent,

On 24/05/18 11:47, Laurent Pinchart wrote:
> Hi Kieran,
> 
> Thank you for the patch.
> 
> On Thursday, 3 May 2018 16:36:13 EEST Kieran Bingham wrote:
>> The use of the packed attribute can cause a performance penalty for
>> all accesses to the struct members, as the compiler will assume that the
>> structure has the potential to have an unaligned base.
>>
>> These structures are all correctly aligned and contain no holes, thus
>> the attribute is redundant and negatively impacts performance, so we
>> remove the attributes entirely.
> 
> With gcc 6.4.0 this patch makes no difference on the generated object. Is it 
> worth it ?

This patch has certainly either enlightened me, or confused me about
this topic - as I had in the past used the packed attribute as here to
define that we don't want holes. (just as this existing code does)

As the documentation seems to determine that this isn't the effect of
this attribute, and removing it has no effect - I suspect removing it is
the right thing to do, as otherwise we are simply mis-using the
construct for no purpose.

It's up to though. Drop or accept as you feel is right.

> 
>> Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
> 
> You forget to pick Geert's review tag.

Ah yes, Collected thanks

--
Regards

Kieran


> 
>> ---
>> v2
>>  - Remove attributes entirely
>> ---
>>  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 c7fa1cb088cd..f4cede9b9b43
>> 100644
>> --- a/drivers/media/platform/vsp1/vsp1_dl.c
>> +++ b/drivers/media/platform/vsp1/vsp1_dl.c
>> @@ -25,19 +25,19 @@
>>  struct vsp1_dl_header_list {
>>  	u32 num_bytes;
>>  	u32 addr;
>> -} __attribute__((__packed__));
>> +};
>>
>>  struct vsp1_dl_header {
>>  	u32 num_lists;
>>  	struct vsp1_dl_header_list lists[8];
>>  	u32 next_header;
>>  	u32 flags;
>> -} __attribute__((__packed__));
>> +};
>>
>>  struct vsp1_dl_entry {
>>  	u32 addr;
>>  	u32 data;
>> -} __attribute__((__packed__));
>> +};
>>
>>  /**
>>   * struct vsp1_dl_body - Display list body
> 

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

* Re: [PATCH v4 02/11] media: vsp1: Remove packed attributes from aligned structures
@ 2018-07-13 10:17       ` Kieran Bingham
  0 siblings, 0 replies; 78+ messages in thread
From: Kieran Bingham @ 2018-07-13 10:17 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: linux-renesas-soc, dri-devel, linux-media

Hi Laurent,

On 24/05/18 11:47, Laurent Pinchart wrote:
> Hi Kieran,
> 
> Thank you for the patch.
> 
> On Thursday, 3 May 2018 16:36:13 EEST Kieran Bingham wrote:
>> The use of the packed attribute can cause a performance penalty for
>> all accesses to the struct members, as the compiler will assume that the
>> structure has the potential to have an unaligned base.
>>
>> These structures are all correctly aligned and contain no holes, thus
>> the attribute is redundant and negatively impacts performance, so we
>> remove the attributes entirely.
> 
> With gcc 6.4.0 this patch makes no difference on the generated object. Is it 
> worth it ?

This patch has certainly either enlightened me, or confused me about
this topic - as I had in the past used the packed attribute as here to
define that we don't want holes. (just as this existing code does)

As the documentation seems to determine that this isn't the effect of
this attribute, and removing it has no effect - I suspect removing it is
the right thing to do, as otherwise we are simply mis-using the
construct for no purpose.

It's up to though. Drop or accept as you feel is right.

> 
>> Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
> 
> You forget to pick Geert's review tag.

Ah yes, Collected thanks

--
Regards

Kieran


> 
>> ---
>> v2
>>  - Remove attributes entirely
>> ---
>>  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 c7fa1cb088cd..f4cede9b9b43
>> 100644
>> --- a/drivers/media/platform/vsp1/vsp1_dl.c
>> +++ b/drivers/media/platform/vsp1/vsp1_dl.c
>> @@ -25,19 +25,19 @@
>>  struct vsp1_dl_header_list {
>>  	u32 num_bytes;
>>  	u32 addr;
>> -} __attribute__((__packed__));
>> +};
>>
>>  struct vsp1_dl_header {
>>  	u32 num_lists;
>>  	struct vsp1_dl_header_list lists[8];
>>  	u32 next_header;
>>  	u32 flags;
>> -} __attribute__((__packed__));
>> +};
>>
>>  struct vsp1_dl_entry {
>>  	u32 addr;
>>  	u32 data;
>> -} __attribute__((__packed__));
>> +};
>>
>>  /**
>>   * struct vsp1_dl_body - Display list body
> 

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v4 07/11] media: vsp1: Use header display lists for all WPF outputs linked to the DU
  2018-05-24 11:10     ` Laurent Pinchart
@ 2018-07-13 10:39       ` Kieran Bingham
  -1 siblings, 0 replies; 78+ messages in thread
From: Kieran Bingham @ 2018-07-13 10:39 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: linux-renesas-soc, linux-media, dri-devel

On 24/05/18 12:10, Laurent Pinchart wrote:
> Hi Kieran,
> 
> Thank you for the patch.
> 
> On Thursday, 3 May 2018 16:36:18 EEST Kieran Bingham wrote:
>> 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(-)
> 
> I like the diffstat.
> 
>> diff --git a/drivers/media/platform/vsp1/vsp1_dl.c
>> b/drivers/media/platform/vsp1/vsp1_dl.c index fbffbd407b29..56514cd51c51
>> 100644
>> --- a/drivers/media/platform/vsp1/vsp1_dl.c
>> +++ b/drivers/media/platform/vsp1/vsp1_dl.c
>> @@ -94,7 +94,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
>> @@ -118,15 +118,9 @@ struct vsp1_dl_list {
>>  	bool internal;
>>  };
>>
>> -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, and pending lists
>> @@ -138,7 +132,6 @@ enum vsp1_dl_mode {
>>   */
>>  struct vsp1_dl_manager {
>>  	unsigned int index;
>> -	enum vsp1_dl_mode mode;
>>  	bool singleshot;
>>  	struct vsp1_device *vsp1;
>>
>> @@ -318,6 +311,7 @@ void vsp1_dl_body_write(struct vsp1_dl_body *dlb, u32
>> reg, u32 data) static struct vsp1_dl_list *vsp1_dl_list_alloc(struct
>> vsp1_dl_manager *dlm) {
>>  	struct vsp1_dl_list *dl;
>> +	size_t header_offset;
>>
>>  	dl = kzalloc(sizeof(*dl), GFP_KERNEL);
>>  	if (!dl)
>> @@ -330,16 +324,15 @@ static struct vsp1_dl_list *vsp1_dl_list_alloc(struct
>> vsp1_dl_manager *dlm) dl->body0 = vsp1_dl_body_get(dlm->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);
> 
> Nitpicking, please align * under =.

This fits on one line. Moved to a single line instead.

> 
>>
>> -		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;
>>  }
>> @@ -471,16 +464,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);
>> @@ -501,17 +487,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;
>> @@ -579,17 +558,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.
> 
> I'd write this
> 
> 	 * Check whether the VSP1 has taken the update. The hardware indicates
> 	 * this by clearing the UPDHDR bit in the CMD register.
> 

Agreed, Done.



>>  	 */
>> -	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)
>> @@ -597,26 +569,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
> 
> s/In header mode, program/Program/
> 
> You can also reformat the comment block to reach the 80th column.

Done


> 
>> +	 * 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)
>> @@ -674,15 +634,13 @@ void vsp1_dl_list_commit(struct vsp1_dl_list *dl, bool
>> internal) 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);
>>  	}
>>
>>  	dl->internal = internal;
>> @@ -783,13 +741,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);
>>  }
>> @@ -824,8 +775,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;
>>
>> @@ -834,13 +783,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);
> 
> While at it, could you update the documentation of the 
> vsp1_dlm_irq_frame_end() function to s/header mode/single-shot mode/ ?
> 
> With these small issues fixed,
> 
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

Collected

Thanks

Kieran

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

* Re: [PATCH v4 07/11] media: vsp1: Use header display lists for all WPF outputs linked to the DU
@ 2018-07-13 10:39       ` Kieran Bingham
  0 siblings, 0 replies; 78+ messages in thread
From: Kieran Bingham @ 2018-07-13 10:39 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: linux-renesas-soc, dri-devel, linux-media

On 24/05/18 12:10, Laurent Pinchart wrote:
> Hi Kieran,
> 
> Thank you for the patch.
> 
> On Thursday, 3 May 2018 16:36:18 EEST Kieran Bingham wrote:
>> 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(-)
> 
> I like the diffstat.
> 
>> diff --git a/drivers/media/platform/vsp1/vsp1_dl.c
>> b/drivers/media/platform/vsp1/vsp1_dl.c index fbffbd407b29..56514cd51c51
>> 100644
>> --- a/drivers/media/platform/vsp1/vsp1_dl.c
>> +++ b/drivers/media/platform/vsp1/vsp1_dl.c
>> @@ -94,7 +94,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
>> @@ -118,15 +118,9 @@ struct vsp1_dl_list {
>>  	bool internal;
>>  };
>>
>> -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, and pending lists
>> @@ -138,7 +132,6 @@ enum vsp1_dl_mode {
>>   */
>>  struct vsp1_dl_manager {
>>  	unsigned int index;
>> -	enum vsp1_dl_mode mode;
>>  	bool singleshot;
>>  	struct vsp1_device *vsp1;
>>
>> @@ -318,6 +311,7 @@ void vsp1_dl_body_write(struct vsp1_dl_body *dlb, u32
>> reg, u32 data) static struct vsp1_dl_list *vsp1_dl_list_alloc(struct
>> vsp1_dl_manager *dlm) {
>>  	struct vsp1_dl_list *dl;
>> +	size_t header_offset;
>>
>>  	dl = kzalloc(sizeof(*dl), GFP_KERNEL);
>>  	if (!dl)
>> @@ -330,16 +324,15 @@ static struct vsp1_dl_list *vsp1_dl_list_alloc(struct
>> vsp1_dl_manager *dlm) dl->body0 = vsp1_dl_body_get(dlm->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);
> 
> Nitpicking, please align * under =.

This fits on one line. Moved to a single line instead.

> 
>>
>> -		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;
>>  }
>> @@ -471,16 +464,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);
>> @@ -501,17 +487,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;
>> @@ -579,17 +558,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.
> 
> I'd write this
> 
> 	 * Check whether the VSP1 has taken the update. The hardware indicates
> 	 * this by clearing the UPDHDR bit in the CMD register.
> 

Agreed, Done.



>>  	 */
>> -	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)
>> @@ -597,26 +569,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
> 
> s/In header mode, program/Program/
> 
> You can also reformat the comment block to reach the 80th column.

Done


> 
>> +	 * 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)
>> @@ -674,15 +634,13 @@ void vsp1_dl_list_commit(struct vsp1_dl_list *dl, bool
>> internal) 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);
>>  	}
>>
>>  	dl->internal = internal;
>> @@ -783,13 +741,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);
>>  }
>> @@ -824,8 +775,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;
>>
>> @@ -834,13 +783,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);
> 
> While at it, could you update the documentation of the 
> vsp1_dlm_irq_frame_end() function to s/header mode/single-shot mode/ ?
> 
> With these small issues fixed,
> 
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

Collected

Thanks

Kieran



_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v4 08/11] media: vsp1: Add support for extended display list headers
  2018-05-24 11:44     ` Laurent Pinchart
@ 2018-07-16 17:14       ` Kieran Bingham
  -1 siblings, 0 replies; 78+ messages in thread
From: Kieran Bingham @ 2018-07-16 17:14 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: linux-renesas-soc, linux-media, dri-devel

Hi Laurent,

On 24/05/18 12:44, Laurent Pinchart wrote:
> Hi Kieran,
> 
> Thank you for the patch.
> 
> On Thursday, 3 May 2018 16:36:19 EEST Kieran Bingham wrote:
>> 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>
>>
>> ---
>>
>> v2:
>>  - remove __packed attributes
>> ---
>>  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 f0d21cc8e9ab..56c62122a81a
>> 100644
>> --- a/drivers/media/platform/vsp1/vsp1.h
>> +++ b/drivers/media/platform/vsp1/vsp1.h
>> @@ -53,6 +53,7 @@ struct vsp1_uif;
>>  #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 56514cd51c51..b64d32535edc
>> 100644
>> --- a/drivers/media/platform/vsp1/vsp1_dl.c
>> +++ b/drivers/media/platform/vsp1/vsp1_dl.c
>> @@ -22,6 +22,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;
>> @@ -34,11 +37,34 @@ struct vsp1_dl_header {
>>  	u32 flags;
>>  };
>>
>> +struct vsp1_dl_ext_header {
>> +	u32 reserved0;		/* alignment padding */
>> +
>> +	u16 pre_ext_cmd_qty;
> 
> Should this be called pre_ext_dl_num_cmd to match the datasheet ?

Yes, renamed.

> 
>> +	u16 flags;
> 
> Aren't the flags supposed to come before the pre_ext_dl_num_cmd field ?

These are out-of-order to account for the fact that they are 16bit values.

I felt that keeping them described in the struct was cleaner than shifts
and masks - but clearly this stands out, due to the byte-ordering.

Would you prefer I re-write this as 32 bit accesses (or even 64bit),
with shifts? Or is a comment sufficient here ?


If we rewrite to be 32 bit accesses, would you be happy with the
following naming:

	u32 reserved0;
	u32 pre_ext_dl_num_cmd; /* Also stores command flags. */
	u32 pre_ext_dl_plist;
	u32 post_ext_dl_num_cmd;
	u32 post_ext_dl_plist;

(Technically the flags are for the whole header, not the just the
pre_ext, which is why I wanted it separated)


Actually - now I write that - the 'number of commands' is sort of a flag
or a parameter? so maybe the following is just as appropriate?:

	u32 reserved0;
	u32 pre_ext_dl_flags;
	u32 pre_ext_dl_plist;
	u32 post_ext_dl_flags;
	u32 post_ext_dl_plist;

Or they could be named 'options', or parameters?

Any comments before I hack that in?

The annoying part is that the 'flags' aren't part of the pre_ext cmds,
they declare whether the pre or post cmd should be executed (or both I
presume, we are yet to see post-cmd usage)


> 
>> +	u32 pre_ext_cmd_plist;
> 
> And pre_ext_dl_plist ?
> 
>> +
>> +	u32 post_ext_cmd_qty;
>> +	u32 post_ext_cmd_plist;
> 
> Similar comments for these variables.

Renamed.


>> +};
>> +
>> +struct vsp1_dl_header_extended {
>> +	struct vsp1_dl_header header;
>> +	struct vsp1_dl_ext_header ext;
>> +};
>> +
>>  struct vsp1_dl_entry {
>>  	u32 addr;
>>  	u32 data;
>>  };
>>
>> +struct vsp1_dl_ext_cmd_header {
> 
> Isn't this referred to in the datasheet as a body entry, not a header ? How 
> about naming it vsp1_dl_ext_cmd_entry ? Or just vsp1_dl_ext_cmd (in which case 
> the other structure that goes by the same name would need to be renamed) ?

I think I was getting too creative. The reality is this part is really a
'header' describing the data in the body, but yes - it should be named
to match a "Pre Extended Display List Body"

  s/vsp1_dl_ext_cmd_header/vsp1_pre_ext_dl_body/

This will then leave "struct vsp1_dl_ext_cmd" which represents the
object instance within the VSP1 driver only.


> 
>> +	u32 cmd;

This should really have been opcode then too :)

>> +	u32 flags;
>> +	u32 data;
>> +	u32 reserved;
> 
> The datasheet documents this as two 64-bit fields, shouldn't we handle the 
> structure the same way ?


I was trying to separate out the fields for clarity.

In this instance (unlike the 16bit handling above), the byte ordering of
a 64 bit value works in our favour, and the ordering of the 4 u32s,
follows the order of the datasheet.

If you'd prefer to handle them as 64bit with mask and shift, I'll
update, and rename this to contain two fields :
     u64 ext_dl_cmd;
     u64 ext_dl_data;

But this is working well with the 32 bit definitions.

>> +};
>> +
>>  /**
>>   * struct vsp1_dl_body - Display list body
>>   * @list: entry in the display list list of bodies
>> @@ -95,9 +121,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
> 
> Should we name this extension instead of extended ?
> 

Fixed.

>>   * @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
> 
> I think you can spell command in full.
> 

Fixed


>>   * @has_chain: if true, indicates that there's a partition chain
>>   * @chain: entry in the display list partition chain
>>   * @internal: whether the display list is used for internal purpose
>> @@ -107,11 +136,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;
>>
>> @@ -496,6 +529,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;
>> @@ -548,6 +589,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)
>> @@ -735,14 +797,20 @@ unsigned int 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);


With the DL_SWAP change removed below, this is the only register which
needs to be written for each VSP1 index. As such, the loop iterator is
moved to this point, so that the VI6_DL_CTRL and VI6_DL_SWAP are not
needlessly written multiple times.


>> +
>>  	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));
> 
> Is this change needed ? If VI6_DL_SWAP_IND is not set in VI6_DL_SWAP(1), 
> display list swap for WPF1 is supposed to be controlled by VI6_DL_SWAP(0) 
> according to the datasheet.
> 
> If that's not the case and this change is needed, I would split support for 
> VI6_DL_SWAP(n) to a separate patch, and moved it before 07/11.
> 


No - it's a no-op and not needed.
Removed.


>>  }
>>
>>  void vsp1_dlm_reset(struct vsp1_dl_manager *dlm)
>> @@ -787,7 +855,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);
> 
> We will have to improve header handling at some point. Not all headers require 
> extensions.
> 
>>  	dlm->pool = vsp1_dl_body_pool_create(vsp1, prealloc,
>>  					     VSP1_DL_NUM_ENTRIES, header_size);
>> @@ -803,6 +875,11 @@ struct vsp1_dl_manager *vsp1_dlm_create(struct
>> vsp1_device *vsp1, return NULL;
>>  		}
>>
>> +		/* The extended header immediately follows the header */
> 
> s/ \*/. */

Fixed.


> 
>> +		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 216bd23029dd..aa5f4adc6617
>> 100644
>> --- a/drivers/media/platform/vsp1/vsp1_dl.h
>> +++ b/drivers/media/platform/vsp1/vsp1_dl.h
>> @@ -20,7 +20,34 @@ struct vsp1_dl_manager;
>>  #define VSP1_DL_FRAME_END_COMPLETED		BIT(0)
>>  #define VSP1_DL_FRAME_END_INTERNAL		BIT(1)
>>
>> -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
> 
> Maybe just opcode ?
> 

Fixed.

>> + * @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
> 
> s/command bodies/commands body/ ?

Fixed.

> 
>> + * @data: memory allocation for command specific data
>> + * @data_dma: DMA address for command specific data
> 
> s/command specific/command-specific/
> 
>> + * @data_size: size of the @data_dma memory in bytes
> 
> data_size is set but otherwise never used. Should we drop the field, or make 
> use of it ?

Dropped

> 
>> + */
>> +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 0fc388bf5a33..26a7b4d32e6c
>> 100644
>> --- a/drivers/media/platform/vsp1/vsp1_drv.c
>> +++ b/drivers/media/platform/vsp1/vsp1_drv.c
>> @@ -545,7 +545,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);


With the associated changes, this loop doesn't really have any benefit
to being here. Moved to the vsp1_dlm_setup(), and the function prototype
is no longer adjusted.

>>
>>  	return 0;
>>  }
>> @@ -754,7 +755,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,
>>  		.uif_count = 1,
>> @@ -774,7 +775,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,
>>  		.uif_count = 2,
>> diff --git a/drivers/media/platform/vsp1/vsp1_regs.h
>> b/drivers/media/platform/vsp1/vsp1_regs.h index 0d249ff9f564..d054767570c1
>> 100644
>> --- a/drivers/media/platform/vsp1/vsp1_regs.h
>> +++ b/drivers/media/platform/vsp1/vsp1_regs.h
>> @@ -67,12 +67,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)

Removed.


>>  #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
> 

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

* Re: [PATCH v4 08/11] media: vsp1: Add support for extended display list headers
@ 2018-07-16 17:14       ` Kieran Bingham
  0 siblings, 0 replies; 78+ messages in thread
From: Kieran Bingham @ 2018-07-16 17:14 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: linux-renesas-soc, dri-devel, linux-media

Hi Laurent,

On 24/05/18 12:44, Laurent Pinchart wrote:
> Hi Kieran,
> 
> Thank you for the patch.
> 
> On Thursday, 3 May 2018 16:36:19 EEST Kieran Bingham wrote:
>> 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>
>>
>> ---
>>
>> v2:
>>  - remove __packed attributes
>> ---
>>  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 f0d21cc8e9ab..56c62122a81a
>> 100644
>> --- a/drivers/media/platform/vsp1/vsp1.h
>> +++ b/drivers/media/platform/vsp1/vsp1.h
>> @@ -53,6 +53,7 @@ struct vsp1_uif;
>>  #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 56514cd51c51..b64d32535edc
>> 100644
>> --- a/drivers/media/platform/vsp1/vsp1_dl.c
>> +++ b/drivers/media/platform/vsp1/vsp1_dl.c
>> @@ -22,6 +22,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;
>> @@ -34,11 +37,34 @@ struct vsp1_dl_header {
>>  	u32 flags;
>>  };
>>
>> +struct vsp1_dl_ext_header {
>> +	u32 reserved0;		/* alignment padding */
>> +
>> +	u16 pre_ext_cmd_qty;
> 
> Should this be called pre_ext_dl_num_cmd to match the datasheet ?

Yes, renamed.

> 
>> +	u16 flags;
> 
> Aren't the flags supposed to come before the pre_ext_dl_num_cmd field ?

These are out-of-order to account for the fact that they are 16bit values.

I felt that keeping them described in the struct was cleaner than shifts
and masks - but clearly this stands out, due to the byte-ordering.

Would you prefer I re-write this as 32 bit accesses (or even 64bit),
with shifts? Or is a comment sufficient here ?


If we rewrite to be 32 bit accesses, would you be happy with the
following naming:

	u32 reserved0;
	u32 pre_ext_dl_num_cmd; /* Also stores command flags. */
	u32 pre_ext_dl_plist;
	u32 post_ext_dl_num_cmd;
	u32 post_ext_dl_plist;

(Technically the flags are for the whole header, not the just the
pre_ext, which is why I wanted it separated)


Actually - now I write that - the 'number of commands' is sort of a flag
or a parameter? so maybe the following is just as appropriate?:

	u32 reserved0;
	u32 pre_ext_dl_flags;
	u32 pre_ext_dl_plist;
	u32 post_ext_dl_flags;
	u32 post_ext_dl_plist;

Or they could be named 'options', or parameters?

Any comments before I hack that in?

The annoying part is that the 'flags' aren't part of the pre_ext cmds,
they declare whether the pre or post cmd should be executed (or both I
presume, we are yet to see post-cmd usage)


> 
>> +	u32 pre_ext_cmd_plist;
> 
> And pre_ext_dl_plist ?
> 
>> +
>> +	u32 post_ext_cmd_qty;
>> +	u32 post_ext_cmd_plist;
> 
> Similar comments for these variables.

Renamed.


>> +};
>> +
>> +struct vsp1_dl_header_extended {
>> +	struct vsp1_dl_header header;
>> +	struct vsp1_dl_ext_header ext;
>> +};
>> +
>>  struct vsp1_dl_entry {
>>  	u32 addr;
>>  	u32 data;
>>  };
>>
>> +struct vsp1_dl_ext_cmd_header {
> 
> Isn't this referred to in the datasheet as a body entry, not a header ? How 
> about naming it vsp1_dl_ext_cmd_entry ? Or just vsp1_dl_ext_cmd (in which case 
> the other structure that goes by the same name would need to be renamed) ?

I think I was getting too creative. The reality is this part is really a
'header' describing the data in the body, but yes - it should be named
to match a "Pre Extended Display List Body"

  s/vsp1_dl_ext_cmd_header/vsp1_pre_ext_dl_body/

This will then leave "struct vsp1_dl_ext_cmd" which represents the
object instance within the VSP1 driver only.


> 
>> +	u32 cmd;

This should really have been opcode then too :)

>> +	u32 flags;
>> +	u32 data;
>> +	u32 reserved;
> 
> The datasheet documents this as two 64-bit fields, shouldn't we handle the 
> structure the same way ?


I was trying to separate out the fields for clarity.

In this instance (unlike the 16bit handling above), the byte ordering of
a 64 bit value works in our favour, and the ordering of the 4 u32s,
follows the order of the datasheet.

If you'd prefer to handle them as 64bit with mask and shift, I'll
update, and rename this to contain two fields :
     u64 ext_dl_cmd;
     u64 ext_dl_data;

But this is working well with the 32 bit definitions.

>> +};
>> +
>>  /**
>>   * struct vsp1_dl_body - Display list body
>>   * @list: entry in the display list list of bodies
>> @@ -95,9 +121,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
> 
> Should we name this extension instead of extended ?
> 

Fixed.

>>   * @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
> 
> I think you can spell command in full.
> 

Fixed


>>   * @has_chain: if true, indicates that there's a partition chain
>>   * @chain: entry in the display list partition chain
>>   * @internal: whether the display list is used for internal purpose
>> @@ -107,11 +136,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;
>>
>> @@ -496,6 +529,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;
>> @@ -548,6 +589,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)
>> @@ -735,14 +797,20 @@ unsigned int 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);


With the DL_SWAP change removed below, this is the only register which
needs to be written for each VSP1 index. As such, the loop iterator is
moved to this point, so that the VI6_DL_CTRL and VI6_DL_SWAP are not
needlessly written multiple times.


>> +
>>  	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));
> 
> Is this change needed ? If VI6_DL_SWAP_IND is not set in VI6_DL_SWAP(1), 
> display list swap for WPF1 is supposed to be controlled by VI6_DL_SWAP(0) 
> according to the datasheet.
> 
> If that's not the case and this change is needed, I would split support for 
> VI6_DL_SWAP(n) to a separate patch, and moved it before 07/11.
> 


No - it's a no-op and not needed.
Removed.


>>  }
>>
>>  void vsp1_dlm_reset(struct vsp1_dl_manager *dlm)
>> @@ -787,7 +855,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);
> 
> We will have to improve header handling at some point. Not all headers require 
> extensions.
> 
>>  	dlm->pool = vsp1_dl_body_pool_create(vsp1, prealloc,
>>  					     VSP1_DL_NUM_ENTRIES, header_size);
>> @@ -803,6 +875,11 @@ struct vsp1_dl_manager *vsp1_dlm_create(struct
>> vsp1_device *vsp1, return NULL;
>>  		}
>>
>> +		/* The extended header immediately follows the header */
> 
> s/ \*/. */

Fixed.


> 
>> +		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 216bd23029dd..aa5f4adc6617
>> 100644
>> --- a/drivers/media/platform/vsp1/vsp1_dl.h
>> +++ b/drivers/media/platform/vsp1/vsp1_dl.h
>> @@ -20,7 +20,34 @@ struct vsp1_dl_manager;
>>  #define VSP1_DL_FRAME_END_COMPLETED		BIT(0)
>>  #define VSP1_DL_FRAME_END_INTERNAL		BIT(1)
>>
>> -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
> 
> Maybe just opcode ?
> 

Fixed.

>> + * @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
> 
> s/command bodies/commands body/ ?

Fixed.

> 
>> + * @data: memory allocation for command specific data
>> + * @data_dma: DMA address for command specific data
> 
> s/command specific/command-specific/
> 
>> + * @data_size: size of the @data_dma memory in bytes
> 
> data_size is set but otherwise never used. Should we drop the field, or make 
> use of it ?

Dropped

> 
>> + */
>> +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 0fc388bf5a33..26a7b4d32e6c
>> 100644
>> --- a/drivers/media/platform/vsp1/vsp1_drv.c
>> +++ b/drivers/media/platform/vsp1/vsp1_drv.c
>> @@ -545,7 +545,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);


With the associated changes, this loop doesn't really have any benefit
to being here. Moved to the vsp1_dlm_setup(), and the function prototype
is no longer adjusted.

>>
>>  	return 0;
>>  }
>> @@ -754,7 +755,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,
>>  		.uif_count = 1,
>> @@ -774,7 +775,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,
>>  		.uif_count = 2,
>> diff --git a/drivers/media/platform/vsp1/vsp1_regs.h
>> b/drivers/media/platform/vsp1/vsp1_regs.h index 0d249ff9f564..d054767570c1
>> 100644
>> --- a/drivers/media/platform/vsp1/vsp1_regs.h
>> +++ b/drivers/media/platform/vsp1/vsp1_regs.h
>> @@ -67,12 +67,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)

Removed.


>>  #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
> 

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v4 11/11] drm: rcar-du: Support interlaced video output through vsp1
  2018-05-24 11:50     ` Laurent Pinchart
@ 2018-07-16 17:20       ` Kieran Bingham
  -1 siblings, 0 replies; 78+ messages in thread
From: Kieran Bingham @ 2018-07-16 17:20 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: linux-renesas-soc, linux-media, dri-devel

Hi Laurent,


On 24/05/18 12:50, Laurent Pinchart wrote:
> Hi Kieran,
> 
> Thank you for the patch.
> 
> On Thursday, 3 May 2018 16:36:22 EEST Kieran Bingham wrote:
>> Use the newly exposed VSP1 interface to enable interlaced frame support
>> through the VSP1 lif pipelines.
> 
> s/lif/LIF/

Fixed.


>> 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 d71d709fe3d9..206532959ec9
>> 100644
>> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
>> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
>> @@ -289,6 +289,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)
> 
> How will this affect Gen2 ?.

The bit is documented identically for Gen2. Potentially / Probably it
'might' reverse the fields... I'm not certain yet. I don't have access
to a Gen2 platform to test.

I'll see if this change can be dropped, but I think it is playing a role
in ensuring that the field detection occurs in VSP1 through the
VI6_STATUS_FLD_STD() field. (see vsp1_dlm_irq_frame_end())


> Could you document what this change does in the 
> commit message ?

This sets the position in the buffer of the ODDF. With this set, the ODD
field is located in the second half (BOTTOM) of the same frame of the
interlace display.

Otherwise, it's in the first half (TOP)

I faced some issues as to the ordering when testing, so I suspect this
might actually be related to that. (re VI6_STATUS_FLD_STD in
vsp1_dlm_irq_frame_end()).

As you mention - this may have a negative effect on the Gen2
implementation - so it needs considering with that.


/me to investigate further.



> 
>>  	      | 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 af7822a66dee..c7b37232ee91
>> 100644
>> --- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
>> +++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
>> @@ -186,6 +186,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;

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

* Re: [PATCH v4 11/11] drm: rcar-du: Support interlaced video output through vsp1
@ 2018-07-16 17:20       ` Kieran Bingham
  0 siblings, 0 replies; 78+ messages in thread
From: Kieran Bingham @ 2018-07-16 17:20 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: linux-renesas-soc, dri-devel, linux-media

Hi Laurent,


On 24/05/18 12:50, Laurent Pinchart wrote:
> Hi Kieran,
> 
> Thank you for the patch.
> 
> On Thursday, 3 May 2018 16:36:22 EEST Kieran Bingham wrote:
>> Use the newly exposed VSP1 interface to enable interlaced frame support
>> through the VSP1 lif pipelines.
> 
> s/lif/LIF/

Fixed.


>> 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 d71d709fe3d9..206532959ec9
>> 100644
>> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
>> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
>> @@ -289,6 +289,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)
> 
> How will this affect Gen2 ?.

The bit is documented identically for Gen2. Potentially / Probably it
'might' reverse the fields... I'm not certain yet. I don't have access
to a Gen2 platform to test.

I'll see if this change can be dropped, but I think it is playing a role
in ensuring that the field detection occurs in VSP1 through the
VI6_STATUS_FLD_STD() field. (see vsp1_dlm_irq_frame_end())


> Could you document what this change does in the 
> commit message ?

This sets the position in the buffer of the ODDF. With this set, the ODD
field is located in the second half (BOTTOM) of the same frame of the
interlace display.

Otherwise, it's in the first half (TOP)

I faced some issues as to the ordering when testing, so I suspect this
might actually be related to that. (re VI6_STATUS_FLD_STD in
vsp1_dlm_irq_frame_end()).

As you mention - this may have a negative effect on the Gen2
implementation - so it needs considering with that.


/me to investigate further.



> 
>>  	      | 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 af7822a66dee..c7b37232ee91
>> 100644
>> --- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
>> +++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
>> @@ -186,6 +186,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;

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v4 10/11] media: vsp1: Support Interlaced display pipelines
  2018-05-24 12:51     ` Laurent Pinchart
@ 2018-07-16 18:21       ` Kieran Bingham
  -1 siblings, 0 replies; 78+ messages in thread
From: Kieran Bingham @ 2018-07-16 18:21 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: linux-renesas-soc, linux-media, dri-devel

Hi Laurent,

Some questions here too :)

On 24/05/18 13:51, Laurent Pinchart wrote:
> Hi Kieran,
> 
> Thank you for the patch.
> 
> On Thursday, 3 May 2018 16:36:21 EEST Kieran Bingham wrote:
>> 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>
>>
>> ---
>> v3:
>>  - Pass DL through partition calls to allow autocmd's to be retrieved
>>  - Document interlaced field in struct vsp1_du_atomic_config
>>
>> v2:
>>  - fix erroneous BIT value which enabled interlaced
>>  - fix field handling at frame_end interrupt
>> ---
>>  drivers/media/platform/vsp1/vsp1_dl.c   | 10 ++++-
>>  drivers/media/platform/vsp1/vsp1_drm.c  | 11 ++++-
>>  drivers/media/platform/vsp1/vsp1_regs.h |  1 +-
>>  drivers/media/platform/vsp1/vsp1_rpf.c  | 71 ++++++++++++++++++++++++--
>>  drivers/media/platform/vsp1/vsp1_rwpf.h |  1 +-
>>  include/media/vsp1.h                    |  2 +-
>>  6 files changed, 93 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/media/platform/vsp1/vsp1_dl.c
>> b/drivers/media/platform/vsp1/vsp1_dl.c index d33ae5f125bd..bbe9f3006f71
>> 100644
>> --- a/drivers/media/platform/vsp1/vsp1_dl.c
>> +++ b/drivers/media/platform/vsp1/vsp1_dl.c
>> @@ -906,6 +906,8 @@ void vsp1_dl_list_commit(struct vsp1_dl_list *dl, bool
>> internal) */
>>  unsigned int vsp1_dlm_irq_frame_end(struct vsp1_dl_manager *dlm)
>>  {
>> +	struct vsp1_device *vsp1 = dlm->vsp1;
>> +	u32 status = vsp1_read(vsp1, VI6_STATUS);
>>  	unsigned int flags = 0;
>>
>>  	spin_lock(&dlm->lock);
>> @@ -931,6 +933,14 @@ unsigned int vsp1_dlm_irq_frame_end(struct
>> vsp1_dl_manager *dlm) goto done;
>>
>>  	/*
>> +	 * Progressive streams report only TOP fields. If we have a BOTTOM
>> +	 * field, we are interlaced, and expect the frame to complete on the
>> +	 * next frame end interrupt.
>> +	 */
>> +	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_drm.c
>> b/drivers/media/platform/vsp1/vsp1_drm.c index 2c3db8b8adce..cc29c9d96bb7
>> 100644
>> --- a/drivers/media/platform/vsp1/vsp1_drm.c
>> +++ b/drivers/media/platform/vsp1/vsp1_drm.c
>> @@ -811,6 +811,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) {
> 
> Nitpicking, writing the condition as
> 
> 	if (cfg->interlaced && !(vsp1_feature(vsp1, VSP1_HAS_EXT_DL)))

Done.

> 
> would match the comment better. You can also drop the parentheses around the 
> vsp1_feature() call.
> 
>> +		/*
>> +		 * 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");
> 
> Could we catch this in the DU driver to fail atomic test ?

Ugh - I thought moving the configuration to vsp1_du_setup_lif() would
give us this, but that return value is not checked in the DU.

How can we interogate the VSP1 to ask it if it supports interlaced from
rcar_du_vsp_plane_atomic_check()?


Some dummy call to vsp1_du_setup_lif() to check the return value ? Or
should we implement a hook to call through to perform checks in the VSP1
DRM API?




> 
>> +		return -EINVAL;
>> +	}
>> +
>> +	rpf->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_regs.h
>> b/drivers/media/platform/vsp1/vsp1_regs.h index d054767570c1..a2ac65cc5155
>> 100644
>> --- a/drivers/media/platform/vsp1/vsp1_regs.h
>> +++ b/drivers/media/platform/vsp1/vsp1_regs.h
>> @@ -28,6 +28,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 8fae7c485642..511b2e127820
>> 100644
>> --- a/drivers/media/platform/vsp1/vsp1_rpf.c
>> +++ b/drivers/media/platform/vsp1/vsp1_rpf.c
>> @@ -20,6 +20,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(0)
> 
> Should the bit definition be moved to vsp1_regs.h ?

Moved, (and renamed s/VSP1_/VI6_/)

> 
>>  /* ------------------------------------------------------------------------
>>   * Device Access
>>   */
>> @@ -64,6 +78,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 */
>> @@ -100,6 +122,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));
>> @@ -169,6 +194,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 */
> 
> s/RPF/RPF./

Fixed.

> 
>> +	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);
> 
> Do you expect some flags to already be set ? If not, couldn't we assign the 
> value to the field instead of OR'ing it ?
No, I think you are correct. Moved to a single expression setting the
cmd->flags in one line.


> 
>> +}
>> +
>>  static void rpf_configure_frame(struct vsp1_entity *entity,
>>  				struct vsp1_pipeline *pipe,
>>  				struct vsp1_dl_list *dl,
>> @@ -192,6 +242,7 @@ static void rpf_configure_partition(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_partition(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,9 +304,18 @@ static void rpf_configure_partition(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);
> 
> How about moving this call to vsp1_rpf_configure_autofld() ?

Done.

> 
>> +		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,
>> diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.h
>> b/drivers/media/platform/vsp1/vsp1_rwpf.h index 70742ecf766f..8d6e42f27908
>> 100644
>> --- a/drivers/media/platform/vsp1/vsp1_rwpf.h
>> +++ b/drivers/media/platform/vsp1/vsp1_rwpf.h
>> @@ -42,6 +42,7 @@ struct vsp1_rwpf {
>>  	struct v4l2_pix_format_mplane format;
>>  	const struct vsp1_format_info *fmtinfo;
>>  	unsigned int brx_input;
>> +	bool interlaced;
> 
> Shouldn't this be stored in the pipeline instead ? Interlacing is a property 
> of the whole pipeline, not of each input individually.
> 

Moved.

>>  	unsigned int alpha;
>>
>> diff --git a/include/media/vsp1.h b/include/media/vsp1.h
>> index 678c24de1ac6..c10883f30980 100644
>> --- a/include/media/vsp1.h
>> +++ b/include/media/vsp1.h
>> @@ -50,6 +50,7 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int
>> pipe_index,
>>   * @dst: destination rectangle on the display (integer coordinates)
>>   * @alpha: alpha value (0: fully transparent, 255: fully opaque)
>>   * @zpos: Z position of the plane (from 0 to number of planes minus 1)
>> + * @interlaced: true for interlaced pipelines
>>   */
>>  struct vsp1_du_atomic_config {
>>  	u32 pixelformat;
>> @@ -59,6 +60,7 @@ struct vsp1_du_atomic_config {
>>  	struct v4l2_rect dst;
>>  	unsigned int alpha;
>>  	unsigned int zpos;
>> +	bool interlaced;
> 
> For the same reason shouldn't the interlaced flag be moved to 
> vsp1_du_lif_config ?
> 

Moved.

>>  };
>>
>>  /**
> 

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

* Re: [PATCH v4 10/11] media: vsp1: Support Interlaced display pipelines
@ 2018-07-16 18:21       ` Kieran Bingham
  0 siblings, 0 replies; 78+ messages in thread
From: Kieran Bingham @ 2018-07-16 18:21 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: linux-renesas-soc, dri-devel, linux-media

Hi Laurent,

Some questions here too :)

On 24/05/18 13:51, Laurent Pinchart wrote:
> Hi Kieran,
> 
> Thank you for the patch.
> 
> On Thursday, 3 May 2018 16:36:21 EEST Kieran Bingham wrote:
>> 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>
>>
>> ---
>> v3:
>>  - Pass DL through partition calls to allow autocmd's to be retrieved
>>  - Document interlaced field in struct vsp1_du_atomic_config
>>
>> v2:
>>  - fix erroneous BIT value which enabled interlaced
>>  - fix field handling at frame_end interrupt
>> ---
>>  drivers/media/platform/vsp1/vsp1_dl.c   | 10 ++++-
>>  drivers/media/platform/vsp1/vsp1_drm.c  | 11 ++++-
>>  drivers/media/platform/vsp1/vsp1_regs.h |  1 +-
>>  drivers/media/platform/vsp1/vsp1_rpf.c  | 71 ++++++++++++++++++++++++--
>>  drivers/media/platform/vsp1/vsp1_rwpf.h |  1 +-
>>  include/media/vsp1.h                    |  2 +-
>>  6 files changed, 93 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/media/platform/vsp1/vsp1_dl.c
>> b/drivers/media/platform/vsp1/vsp1_dl.c index d33ae5f125bd..bbe9f3006f71
>> 100644
>> --- a/drivers/media/platform/vsp1/vsp1_dl.c
>> +++ b/drivers/media/platform/vsp1/vsp1_dl.c
>> @@ -906,6 +906,8 @@ void vsp1_dl_list_commit(struct vsp1_dl_list *dl, bool
>> internal) */
>>  unsigned int vsp1_dlm_irq_frame_end(struct vsp1_dl_manager *dlm)
>>  {
>> +	struct vsp1_device *vsp1 = dlm->vsp1;
>> +	u32 status = vsp1_read(vsp1, VI6_STATUS);
>>  	unsigned int flags = 0;
>>
>>  	spin_lock(&dlm->lock);
>> @@ -931,6 +933,14 @@ unsigned int vsp1_dlm_irq_frame_end(struct
>> vsp1_dl_manager *dlm) goto done;
>>
>>  	/*
>> +	 * Progressive streams report only TOP fields. If we have a BOTTOM
>> +	 * field, we are interlaced, and expect the frame to complete on the
>> +	 * next frame end interrupt.
>> +	 */
>> +	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_drm.c
>> b/drivers/media/platform/vsp1/vsp1_drm.c index 2c3db8b8adce..cc29c9d96bb7
>> 100644
>> --- a/drivers/media/platform/vsp1/vsp1_drm.c
>> +++ b/drivers/media/platform/vsp1/vsp1_drm.c
>> @@ -811,6 +811,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) {
> 
> Nitpicking, writing the condition as
> 
> 	if (cfg->interlaced && !(vsp1_feature(vsp1, VSP1_HAS_EXT_DL)))

Done.

> 
> would match the comment better. You can also drop the parentheses around the 
> vsp1_feature() call.
> 
>> +		/*
>> +		 * 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");
> 
> Could we catch this in the DU driver to fail atomic test ?

Ugh - I thought moving the configuration to vsp1_du_setup_lif() would
give us this, but that return value is not checked in the DU.

How can we interogate the VSP1 to ask it if it supports interlaced from
rcar_du_vsp_plane_atomic_check()?


Some dummy call to vsp1_du_setup_lif() to check the return value ? Or
should we implement a hook to call through to perform checks in the VSP1
DRM API?




> 
>> +		return -EINVAL;
>> +	}
>> +
>> +	rpf->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_regs.h
>> b/drivers/media/platform/vsp1/vsp1_regs.h index d054767570c1..a2ac65cc5155
>> 100644
>> --- a/drivers/media/platform/vsp1/vsp1_regs.h
>> +++ b/drivers/media/platform/vsp1/vsp1_regs.h
>> @@ -28,6 +28,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 8fae7c485642..511b2e127820
>> 100644
>> --- a/drivers/media/platform/vsp1/vsp1_rpf.c
>> +++ b/drivers/media/platform/vsp1/vsp1_rpf.c
>> @@ -20,6 +20,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(0)
> 
> Should the bit definition be moved to vsp1_regs.h ?

Moved, (and renamed s/VSP1_/VI6_/)

> 
>>  /* ------------------------------------------------------------------------
>>   * Device Access
>>   */
>> @@ -64,6 +78,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 */
>> @@ -100,6 +122,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));
>> @@ -169,6 +194,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 */
> 
> s/RPF/RPF./

Fixed.

> 
>> +	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);
> 
> Do you expect some flags to already be set ? If not, couldn't we assign the 
> value to the field instead of OR'ing it ?
No, I think you are correct. Moved to a single expression setting the
cmd->flags in one line.


> 
>> +}
>> +
>>  static void rpf_configure_frame(struct vsp1_entity *entity,
>>  				struct vsp1_pipeline *pipe,
>>  				struct vsp1_dl_list *dl,
>> @@ -192,6 +242,7 @@ static void rpf_configure_partition(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_partition(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,9 +304,18 @@ static void rpf_configure_partition(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);
> 
> How about moving this call to vsp1_rpf_configure_autofld() ?

Done.

> 
>> +		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,
>> diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.h
>> b/drivers/media/platform/vsp1/vsp1_rwpf.h index 70742ecf766f..8d6e42f27908
>> 100644
>> --- a/drivers/media/platform/vsp1/vsp1_rwpf.h
>> +++ b/drivers/media/platform/vsp1/vsp1_rwpf.h
>> @@ -42,6 +42,7 @@ struct vsp1_rwpf {
>>  	struct v4l2_pix_format_mplane format;
>>  	const struct vsp1_format_info *fmtinfo;
>>  	unsigned int brx_input;
>> +	bool interlaced;
> 
> Shouldn't this be stored in the pipeline instead ? Interlacing is a property 
> of the whole pipeline, not of each input individually.
> 

Moved.

>>  	unsigned int alpha;
>>
>> diff --git a/include/media/vsp1.h b/include/media/vsp1.h
>> index 678c24de1ac6..c10883f30980 100644
>> --- a/include/media/vsp1.h
>> +++ b/include/media/vsp1.h
>> @@ -50,6 +50,7 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int
>> pipe_index,
>>   * @dst: destination rectangle on the display (integer coordinates)
>>   * @alpha: alpha value (0: fully transparent, 255: fully opaque)
>>   * @zpos: Z position of the plane (from 0 to number of planes minus 1)
>> + * @interlaced: true for interlaced pipelines
>>   */
>>  struct vsp1_du_atomic_config {
>>  	u32 pixelformat;
>> @@ -59,6 +60,7 @@ struct vsp1_du_atomic_config {
>>  	struct v4l2_rect dst;
>>  	unsigned int alpha;
>>  	unsigned int zpos;
>> +	bool interlaced;
> 
> For the same reason shouldn't the interlaced flag be moved to 
> vsp1_du_lif_config ?
> 

Moved.

>>  };
>>
>>  /**
> 

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v4 08/11] media: vsp1: Add support for extended display list headers
  2018-07-16 17:14       ` Kieran Bingham
@ 2018-07-17 10:53         ` Laurent Pinchart
  -1 siblings, 0 replies; 78+ messages in thread
From: Laurent Pinchart @ 2018-07-17 10:53 UTC (permalink / raw)
  To: kieran.bingham+renesas; +Cc: linux-renesas-soc, linux-media, dri-devel

Hi Kieran,

On Monday, 16 July 2018 20:14:55 EEST Kieran Bingham wrote:
> On 24/05/18 12:44, Laurent Pinchart wrote:
> > On Thursday, 3 May 2018 16:36:19 EEST Kieran Bingham wrote:
> >> 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>
> >> 
> >> ---
> >> 
> >> v2:
> >>  - remove __packed attributes
> >> 
> >> ---
> >> 
> >>  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(-)

[snip]

> >> diff --git a/drivers/media/platform/vsp1/vsp1_dl.c
> >> b/drivers/media/platform/vsp1/vsp1_dl.c index 56514cd51c51..b64d32535edc
> >> 100644
> >> --- a/drivers/media/platform/vsp1/vsp1_dl.c
> >> +++ b/drivers/media/platform/vsp1/vsp1_dl.c

[snip]

> >> +struct vsp1_dl_ext_header {
> >> +	u32 reserved0;		/* alignment padding */
> >> +
> >> +	u16 pre_ext_cmd_qty;
> > 
> > Should this be called pre_ext_dl_num_cmd to match the datasheet ?
> 
> Yes, renamed.
> 
> >> +	u16 flags;
> > 
> > Aren't the flags supposed to come before the pre_ext_dl_num_cmd field ?
> 
> These are out-of-order to account for the fact that they are 16bit values.

Ah OK. It makes sense, but is a bit confusing when reading the datasheet.

> I felt that keeping them described in the struct was cleaner than shifts
> and masks - but clearly this stands out, due to the byte-ordering.
> 
> Would you prefer I re-write this as 32 bit accesses (or even 64bit),
> with shifts? Or is a comment sufficient here ?

If it doesn't make the code too ugly, using larger accesses would be better I 
think. Otherwise a comment would do I suppose.

> If we rewrite to be 32 bit accesses, would you be happy with the
> following naming:
> 
> 	u32 reserved0;
> 	u32 pre_ext_dl_num_cmd; /* Also stores command flags. */
> 	u32 pre_ext_dl_plist;
> 	u32 post_ext_dl_num_cmd;
> 	u32 post_ext_dl_plist;
> 
> (Technically the flags are for the whole header, not the just the
> pre_ext, which is why I wanted it separated)
> 
> 
> Actually - now I write that - the 'number of commands' is sort of a flag
> or a parameter? so maybe the following is just as appropriate?:
> 
> 	u32 reserved0;

Maybe "u32 zero;" or "u32 padding;" ? The datasheet states this is padding for 
alignment purpose.

> 	u32 pre_ext_dl_flags;
> 	u32 pre_ext_dl_plist;
> 	u32 post_ext_dl_flags;
> 	u32 post_ext_dl_plist;
> 
> Or they could be named 'options', or parameters?
> 
> Any comments before I hack that in?
> 
> The annoying part is that the 'flags' aren't part of the pre_ext cmds,
> they declare whether the pre or post cmd should be executed (or both I
> presume, we are yet to see post-cmd usage)

I agree with you, having a separate flag field would be nicer, as the flags 
are shared. I'll chose the easy option of letting you decide what you like 
best :-) All the above options are equally good to me, provided you add a 
comment explaining why the flag comes after the num_cmd field if you decide to 
keep it as a separate field.

> >> +	u32 pre_ext_cmd_plist;
> > 
> > And pre_ext_dl_plist ?
> > 
> >> +
> >> +	u32 post_ext_cmd_qty;
> >> +	u32 post_ext_cmd_plist;
> > 
> > Similar comments for these variables.
> 
> Renamed.
> 
> >> +};
> >> +
> >> +struct vsp1_dl_header_extended {
> >> +	struct vsp1_dl_header header;
> >> +	struct vsp1_dl_ext_header ext;
> >> +};
> >> +
> >>  struct vsp1_dl_entry {
> >>  	u32 addr;
> >>  	u32 data;
> >>  };
> >> 
> >> +struct vsp1_dl_ext_cmd_header {
> > 
> > Isn't this referred to in the datasheet as a body entry, not a header ?
> > How about naming it vsp1_dl_ext_cmd_entry ? Or just vsp1_dl_ext_cmd (in
> > which case the other structure that goes by the same name would need to be
> > renamed) ?
> 
> I think I was getting too creative. The reality is this part is really a
> 'header' describing the data in the body, but yes - it should be named
> to match a "Pre Extended Display List Body"
> 
>   s/vsp1_dl_ext_cmd_header/vsp1_pre_ext_dl_body/

Sounds good to me.

> This will then leave "struct vsp1_dl_ext_cmd" which represents the
> object instance within the VSP1 driver only.
> 
> >> +	u32 cmd;
> 
> This should really have been opcode then too :)

Good point.

> >> +	u32 flags;
> >> +	u32 data;
> >> +	u32 reserved;
> > 
> > The datasheet documents this as two 64-bit fields, shouldn't we handle the
> > structure the same way ?
> 
> I was trying to separate out the fields for clarity.
> 
> In this instance (unlike the 16bit handling above), the byte ordering of
> a 64 bit value works in our favour, and the ordering of the 4 u32s,
> follows the order of the datasheet.
> 
> If you'd prefer to handle them as 64bit with mask and shift, I'll
> update, and rename this to contain two fields :
>      u64 ext_dl_cmd;
>      u64 ext_dl_data;
> 
> But this is working well with the 32 bit definitions.

Up to you, I'm OK with both.

> >> +};

[snip]

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v4 08/11] media: vsp1: Add support for extended display list headers
@ 2018-07-17 10:53         ` Laurent Pinchart
  0 siblings, 0 replies; 78+ messages in thread
From: Laurent Pinchart @ 2018-07-17 10:53 UTC (permalink / raw)
  To: kieran.bingham+renesas; +Cc: linux-renesas-soc, dri-devel, linux-media

Hi Kieran,

On Monday, 16 July 2018 20:14:55 EEST Kieran Bingham wrote:
> On 24/05/18 12:44, Laurent Pinchart wrote:
> > On Thursday, 3 May 2018 16:36:19 EEST Kieran Bingham wrote:
> >> 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>
> >> 
> >> ---
> >> 
> >> v2:
> >>  - remove __packed attributes
> >> 
> >> ---
> >> 
> >>  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(-)

[snip]

> >> diff --git a/drivers/media/platform/vsp1/vsp1_dl.c
> >> b/drivers/media/platform/vsp1/vsp1_dl.c index 56514cd51c51..b64d32535edc
> >> 100644
> >> --- a/drivers/media/platform/vsp1/vsp1_dl.c
> >> +++ b/drivers/media/platform/vsp1/vsp1_dl.c

[snip]

> >> +struct vsp1_dl_ext_header {
> >> +	u32 reserved0;		/* alignment padding */
> >> +
> >> +	u16 pre_ext_cmd_qty;
> > 
> > Should this be called pre_ext_dl_num_cmd to match the datasheet ?
> 
> Yes, renamed.
> 
> >> +	u16 flags;
> > 
> > Aren't the flags supposed to come before the pre_ext_dl_num_cmd field ?
> 
> These are out-of-order to account for the fact that they are 16bit values.

Ah OK. It makes sense, but is a bit confusing when reading the datasheet.

> I felt that keeping them described in the struct was cleaner than shifts
> and masks - but clearly this stands out, due to the byte-ordering.
> 
> Would you prefer I re-write this as 32 bit accesses (or even 64bit),
> with shifts? Or is a comment sufficient here ?

If it doesn't make the code too ugly, using larger accesses would be better I 
think. Otherwise a comment would do I suppose.

> If we rewrite to be 32 bit accesses, would you be happy with the
> following naming:
> 
> 	u32 reserved0;
> 	u32 pre_ext_dl_num_cmd; /* Also stores command flags. */
> 	u32 pre_ext_dl_plist;
> 	u32 post_ext_dl_num_cmd;
> 	u32 post_ext_dl_plist;
> 
> (Technically the flags are for the whole header, not the just the
> pre_ext, which is why I wanted it separated)
> 
> 
> Actually - now I write that - the 'number of commands' is sort of a flag
> or a parameter? so maybe the following is just as appropriate?:
> 
> 	u32 reserved0;

Maybe "u32 zero;" or "u32 padding;" ? The datasheet states this is padding for 
alignment purpose.

> 	u32 pre_ext_dl_flags;
> 	u32 pre_ext_dl_plist;
> 	u32 post_ext_dl_flags;
> 	u32 post_ext_dl_plist;
> 
> Or they could be named 'options', or parameters?
> 
> Any comments before I hack that in?
> 
> The annoying part is that the 'flags' aren't part of the pre_ext cmds,
> they declare whether the pre or post cmd should be executed (or both I
> presume, we are yet to see post-cmd usage)

I agree with you, having a separate flag field would be nicer, as the flags 
are shared. I'll chose the easy option of letting you decide what you like 
best :-) All the above options are equally good to me, provided you add a 
comment explaining why the flag comes after the num_cmd field if you decide to 
keep it as a separate field.

> >> +	u32 pre_ext_cmd_plist;
> > 
> > And pre_ext_dl_plist ?
> > 
> >> +
> >> +	u32 post_ext_cmd_qty;
> >> +	u32 post_ext_cmd_plist;
> > 
> > Similar comments for these variables.
> 
> Renamed.
> 
> >> +};
> >> +
> >> +struct vsp1_dl_header_extended {
> >> +	struct vsp1_dl_header header;
> >> +	struct vsp1_dl_ext_header ext;
> >> +};
> >> +
> >>  struct vsp1_dl_entry {
> >>  	u32 addr;
> >>  	u32 data;
> >>  };
> >> 
> >> +struct vsp1_dl_ext_cmd_header {
> > 
> > Isn't this referred to in the datasheet as a body entry, not a header ?
> > How about naming it vsp1_dl_ext_cmd_entry ? Or just vsp1_dl_ext_cmd (in
> > which case the other structure that goes by the same name would need to be
> > renamed) ?
> 
> I think I was getting too creative. The reality is this part is really a
> 'header' describing the data in the body, but yes - it should be named
> to match a "Pre Extended Display List Body"
> 
>   s/vsp1_dl_ext_cmd_header/vsp1_pre_ext_dl_body/

Sounds good to me.

> This will then leave "struct vsp1_dl_ext_cmd" which represents the
> object instance within the VSP1 driver only.
> 
> >> +	u32 cmd;
> 
> This should really have been opcode then too :)

Good point.

> >> +	u32 flags;
> >> +	u32 data;
> >> +	u32 reserved;
> > 
> > The datasheet documents this as two 64-bit fields, shouldn't we handle the
> > structure the same way ?
> 
> I was trying to separate out the fields for clarity.
> 
> In this instance (unlike the 16bit handling above), the byte ordering of
> a 64 bit value works in our favour, and the ordering of the 4 u32s,
> follows the order of the datasheet.
> 
> If you'd prefer to handle them as 64bit with mask and shift, I'll
> update, and rename this to contain two fields :
>      u64 ext_dl_cmd;
>      u64 ext_dl_data;
> 
> But this is working well with the 32 bit definitions.

Up to you, I'm OK with both.

> >> +};

[snip]

-- 
Regards,

Laurent Pinchart



_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v4 10/11] media: vsp1: Support Interlaced display pipelines
  2018-07-16 18:21       ` Kieran Bingham
@ 2018-07-17 12:52         ` Laurent Pinchart
  -1 siblings, 0 replies; 78+ messages in thread
From: Laurent Pinchart @ 2018-07-17 12:52 UTC (permalink / raw)
  To: kieran.bingham+renesas; +Cc: linux-renesas-soc, linux-media, dri-devel

Hi Kieran,

On Monday, 16 July 2018 21:21:00 EEST Kieran Bingham wrote:
> On 24/05/18 13:51, Laurent Pinchart wrote:
> > On Thursday, 3 May 2018 16:36:21 EEST Kieran Bingham wrote:
> >> 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>
> >> 
> >> ---
> >> 
> >> v3:
> >>  - Pass DL through partition calls to allow autocmd's to be retrieved
> >>  - Document interlaced field in struct vsp1_du_atomic_config
> >> 
> >> v2:
> >>  - fix erroneous BIT value which enabled interlaced
> >>  - fix field handling at frame_end interrupt
> >> 
> >> ---
> >> 
> >>  drivers/media/platform/vsp1/vsp1_dl.c   | 10 ++++-
> >>  drivers/media/platform/vsp1/vsp1_drm.c  | 11 ++++-
> >>  drivers/media/platform/vsp1/vsp1_regs.h |  1 +-
> >>  drivers/media/platform/vsp1/vsp1_rpf.c  | 71 ++++++++++++++++++++++++--
> >>  drivers/media/platform/vsp1/vsp1_rwpf.h |  1 +-
> >>  include/media/vsp1.h                    |  2 +-
> >>  6 files changed, 93 insertions(+), 3 deletions(-)

[snip]

> >> diff --git a/drivers/media/platform/vsp1/vsp1_drm.c
> >> b/drivers/media/platform/vsp1/vsp1_drm.c index 2c3db8b8adce..cc29c9d96bb7
> >> 100644
> >> --- a/drivers/media/platform/vsp1/vsp1_drm.c
> >> +++ b/drivers/media/platform/vsp1/vsp1_drm.c
> >> @@ -811,6 +811,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) {
> > 
> > Nitpicking, writing the condition as
> > 
> > 	if (cfg->interlaced && !(vsp1_feature(vsp1, VSP1_HAS_EXT_DL)))
> 
> Done.
> 
> > would match the comment better. You can also drop the parentheses around
> > the vsp1_feature() call.
> > 
> >> +		/*
> >> +		 * 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");
> > 
> > Could we catch this in the DU driver to fail atomic test ?
> 
> Ugh - I thought moving the configuration to vsp1_du_setup_lif() would
> give us this, but that return value is not checked in the DU.
> 
> How can we interogate the VSP1 to ask it if it supports interlaced from
> rcar_du_vsp_plane_atomic_check()?
> 
> 
> Some dummy call to vsp1_du_setup_lif() to check the return value ? Or
> should we implement a hook to call through to perform checks in the VSP1
> DRM API?

Would it be possible to just infer that from the DU compatible string, without 
querying the VSP driver ? Of course that's a bit of a layering violation, but 
as we know what type of VSP instance is present in each SoC, such a small hack 
wouldn't hurt in my opinion. If the need arises later we can introduce an API 
to query the information from the VSP driver.

> >> +		return -EINVAL;
> >> +	}
> >> +
> >> +	rpf->interlaced = cfg->interlaced;
> >> +
> >>  	rpf->fmtinfo = fmtinfo;
> >>  	rpf->format.num_planes = fmtinfo->planes;
> >>  	rpf->format.plane_fmt[0].bytesperline = cfg->pitch;

[snip]

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v4 10/11] media: vsp1: Support Interlaced display pipelines
@ 2018-07-17 12:52         ` Laurent Pinchart
  0 siblings, 0 replies; 78+ messages in thread
From: Laurent Pinchart @ 2018-07-17 12:52 UTC (permalink / raw)
  To: kieran.bingham+renesas; +Cc: linux-renesas-soc, dri-devel, linux-media

Hi Kieran,

On Monday, 16 July 2018 21:21:00 EEST Kieran Bingham wrote:
> On 24/05/18 13:51, Laurent Pinchart wrote:
> > On Thursday, 3 May 2018 16:36:21 EEST Kieran Bingham wrote:
> >> 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>
> >> 
> >> ---
> >> 
> >> v3:
> >>  - Pass DL through partition calls to allow autocmd's to be retrieved
> >>  - Document interlaced field in struct vsp1_du_atomic_config
> >> 
> >> v2:
> >>  - fix erroneous BIT value which enabled interlaced
> >>  - fix field handling at frame_end interrupt
> >> 
> >> ---
> >> 
> >>  drivers/media/platform/vsp1/vsp1_dl.c   | 10 ++++-
> >>  drivers/media/platform/vsp1/vsp1_drm.c  | 11 ++++-
> >>  drivers/media/platform/vsp1/vsp1_regs.h |  1 +-
> >>  drivers/media/platform/vsp1/vsp1_rpf.c  | 71 ++++++++++++++++++++++++--
> >>  drivers/media/platform/vsp1/vsp1_rwpf.h |  1 +-
> >>  include/media/vsp1.h                    |  2 +-
> >>  6 files changed, 93 insertions(+), 3 deletions(-)

[snip]

> >> diff --git a/drivers/media/platform/vsp1/vsp1_drm.c
> >> b/drivers/media/platform/vsp1/vsp1_drm.c index 2c3db8b8adce..cc29c9d96bb7
> >> 100644
> >> --- a/drivers/media/platform/vsp1/vsp1_drm.c
> >> +++ b/drivers/media/platform/vsp1/vsp1_drm.c
> >> @@ -811,6 +811,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) {
> > 
> > Nitpicking, writing the condition as
> > 
> > 	if (cfg->interlaced && !(vsp1_feature(vsp1, VSP1_HAS_EXT_DL)))
> 
> Done.
> 
> > would match the comment better. You can also drop the parentheses around
> > the vsp1_feature() call.
> > 
> >> +		/*
> >> +		 * 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");
> > 
> > Could we catch this in the DU driver to fail atomic test ?
> 
> Ugh - I thought moving the configuration to vsp1_du_setup_lif() would
> give us this, but that return value is not checked in the DU.
> 
> How can we interogate the VSP1 to ask it if it supports interlaced from
> rcar_du_vsp_plane_atomic_check()?
> 
> 
> Some dummy call to vsp1_du_setup_lif() to check the return value ? Or
> should we implement a hook to call through to perform checks in the VSP1
> DRM API?

Would it be possible to just infer that from the DU compatible string, without 
querying the VSP driver ? Of course that's a bit of a layering violation, but 
as we know what type of VSP instance is present in each SoC, such a small hack 
wouldn't hurt in my opinion. If the need arises later we can introduce an API 
to query the information from the VSP driver.

> >> +		return -EINVAL;
> >> +	}
> >> +
> >> +	rpf->interlaced = cfg->interlaced;
> >> +
> >>  	rpf->fmtinfo = fmtinfo;
> >>  	rpf->format.num_planes = fmtinfo->planes;
> >>  	rpf->format.plane_fmt[0].bytesperline = cfg->pitch;

[snip]

-- 
Regards,

Laurent Pinchart



_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v4 11/11] drm: rcar-du: Support interlaced video output through vsp1
  2018-07-16 17:20       ` Kieran Bingham
@ 2018-07-17 13:51         ` Laurent Pinchart
  -1 siblings, 0 replies; 78+ messages in thread
From: Laurent Pinchart @ 2018-07-17 13:51 UTC (permalink / raw)
  To: kieran.bingham+renesas; +Cc: linux-renesas-soc, linux-media, dri-devel

Hi Kieran,

On Monday, 16 July 2018 20:20:30 EEST Kieran Bingham wrote:
> On 24/05/18 12:50, Laurent Pinchart wrote:
> > On Thursday, 3 May 2018 16:36:22 EEST Kieran Bingham wrote:
> >> Use the newly exposed VSP1 interface to enable interlaced frame support
> >> through the VSP1 lif pipelines.
> > 
> > s/lif/LIF/
> 
> Fixed.
> 
> >> 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 d71d709fe3d9..206532959ec9
> >> 100644
> >> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> >> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> >> @@ -289,6 +289,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)
> > 
> > How will this affect Gen2 ?.
> 
> The bit is documented identically for Gen2. Potentially / Probably it
> 'might' reverse the fields... I'm not certain yet. I don't have access
> to a Gen2 platform to test.
> 
> I'll see if this change can be dropped, but I think it is playing a role
> in ensuring that the field detection occurs in VSP1 through the
> VI6_STATUS_FLD_STD() field. (see vsp1_dlm_irq_frame_end())
> 
> > Could you document what this change does in the
> > commit message ?
> 
> This sets the position in the buffer of the ODDF. With this set, the ODD
> field is located in the second half (BOTTOM) of the same frame of the
> interlace display.
> 
> Otherwise, it's in the first half (TOP)
> 
> I faced some issues as to the ordering when testing, so I suspect this
> might actually be related to that. (re VI6_STATUS_FLD_STD in
> vsp1_dlm_irq_frame_end()).
> 
> As you mention - this may have a negative effect on the Gen2
> implementation - so it needs considering with that.
> 
> 
> /me to investigate further.

Thank you. I don't object to this change, but I'd like to know what its 
implications are on Gen2. It might even fix a bug :-) Let me know if you'd 
like me to run tests on a Lager board.

> >>  	      | 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 af7822a66dee..c7b37232ee91
> >> 100644
> >> --- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
> >> +++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
> >> @@ -186,6 +186,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;

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v4 11/11] drm: rcar-du: Support interlaced video output through vsp1
@ 2018-07-17 13:51         ` Laurent Pinchart
  0 siblings, 0 replies; 78+ messages in thread
From: Laurent Pinchart @ 2018-07-17 13:51 UTC (permalink / raw)
  To: kieran.bingham+renesas; +Cc: linux-renesas-soc, dri-devel, linux-media

Hi Kieran,

On Monday, 16 July 2018 20:20:30 EEST Kieran Bingham wrote:
> On 24/05/18 12:50, Laurent Pinchart wrote:
> > On Thursday, 3 May 2018 16:36:22 EEST Kieran Bingham wrote:
> >> Use the newly exposed VSP1 interface to enable interlaced frame support
> >> through the VSP1 lif pipelines.
> > 
> > s/lif/LIF/
> 
> Fixed.
> 
> >> 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 d71d709fe3d9..206532959ec9
> >> 100644
> >> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> >> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> >> @@ -289,6 +289,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)
> > 
> > How will this affect Gen2 ?.
> 
> The bit is documented identically for Gen2. Potentially / Probably it
> 'might' reverse the fields... I'm not certain yet. I don't have access
> to a Gen2 platform to test.
> 
> I'll see if this change can be dropped, but I think it is playing a role
> in ensuring that the field detection occurs in VSP1 through the
> VI6_STATUS_FLD_STD() field. (see vsp1_dlm_irq_frame_end())
> 
> > Could you document what this change does in the
> > commit message ?
> 
> This sets the position in the buffer of the ODDF. With this set, the ODD
> field is located in the second half (BOTTOM) of the same frame of the
> interlace display.
> 
> Otherwise, it's in the first half (TOP)
> 
> I faced some issues as to the ordering when testing, so I suspect this
> might actually be related to that. (re VI6_STATUS_FLD_STD in
> vsp1_dlm_irq_frame_end()).
> 
> As you mention - this may have a negative effect on the Gen2
> implementation - so it needs considering with that.
> 
> 
> /me to investigate further.

Thank you. I don't object to this change, but I'd like to know what its 
implications are on Gen2. It might even fix a bug :-) Let me know if you'd 
like me to run tests on a Lager board.

> >>  	      | 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 af7822a66dee..c7b37232ee91
> >> 100644
> >> --- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
> >> +++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
> >> @@ -186,6 +186,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;

-- 
Regards,

Laurent Pinchart



_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v4 10/11] media: vsp1: Support Interlaced display pipelines
  2018-07-16 18:21       ` Kieran Bingham
@ 2018-07-17 14:23         ` Kieran Bingham
  -1 siblings, 0 replies; 78+ messages in thread
From: Kieran Bingham @ 2018-07-17 14:23 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: linux-renesas-soc, linux-media, dri-devel

Hi Laurent,

<snip>

>>> +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 */
>>
>> s/RPF/RPF./
> 
> Fixed.
> 
>>
>>> +	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);
>>
>> Do you expect some flags to already be set ? If not, couldn't we assign the 
>> value to the field instead of OR'ing it ?

> No, I think you are correct. Moved to a single expression setting the
> cmd->flags in one line.

Ahem.... no - of course these flags have to be OR-ed in. Because it
potentially updates a single command object for multiple RPFs.

The flags get reset to 0 when the command object is discarded in
vsp1_dl_ext_cmd_put()


> 
>>
>>> +}

<snip>

--
Kieran

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

* Re: [PATCH v4 10/11] media: vsp1: Support Interlaced display pipelines
@ 2018-07-17 14:23         ` Kieran Bingham
  0 siblings, 0 replies; 78+ messages in thread
From: Kieran Bingham @ 2018-07-17 14:23 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: linux-renesas-soc, dri-devel, linux-media

Hi Laurent,

<snip>

>>> +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 */
>>
>> s/RPF/RPF./
> 
> Fixed.
> 
>>
>>> +	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);
>>
>> Do you expect some flags to already be set ? If not, couldn't we assign the 
>> value to the field instead of OR'ing it ?

> No, I think you are correct. Moved to a single expression setting the
> cmd->flags in one line.

Ahem.... no - of course these flags have to be OR-ed in. Because it
potentially updates a single command object for multiple RPFs.

The flags get reset to 0 when the command object is discarded in
vsp1_dl_ext_cmd_put()


> 
>>
>>> +}

<snip>

--
Kieran

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v4 08/11] media: vsp1: Add support for extended display list headers
  2018-07-17 10:53         ` Laurent Pinchart
@ 2018-07-17 15:01           ` Kieran Bingham
  -1 siblings, 0 replies; 78+ messages in thread
From: Kieran Bingham @ 2018-07-17 15:01 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: linux-renesas-soc, linux-media, dri-devel

Hi Laurent,

On 17/07/18 11:53, Laurent Pinchart wrote:
> Hi Kieran,
> 
> On Monday, 16 July 2018 20:14:55 EEST Kieran Bingham wrote:
>> On 24/05/18 12:44, Laurent Pinchart wrote:
>>> On Thursday, 3 May 2018 16:36:19 EEST Kieran Bingham wrote:
>>>> 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>
>>>>
>>>> ---
>>>>
>>>> v2:
>>>>  - remove __packed attributes
>>>>
>>>> ---
>>>>
>>>>  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(-)
> 
> [snip]
> 
>>>> diff --git a/drivers/media/platform/vsp1/vsp1_dl.c
>>>> b/drivers/media/platform/vsp1/vsp1_dl.c index 56514cd51c51..b64d32535edc
>>>> 100644
>>>> --- a/drivers/media/platform/vsp1/vsp1_dl.c
>>>> +++ b/drivers/media/platform/vsp1/vsp1_dl.c
> 
> [snip]
> 
>>>> +struct vsp1_dl_ext_header {
>>>> +	u32 reserved0;		/* alignment padding */
>>>> +
>>>> +	u16 pre_ext_cmd_qty;
>>>
>>> Should this be called pre_ext_dl_num_cmd to match the datasheet ?
>>
>> Yes, renamed.
>>
>>>> +	u16 flags;
>>>
>>> Aren't the flags supposed to come before the pre_ext_dl_num_cmd field ?
>>
>> These are out-of-order to account for the fact that they are 16bit values.
> 
> Ah OK. It makes sense, but is a bit confusing when reading the datasheet.

Yes, I agree. Realising the byte-ordering was off was a bit of a pain
point when I was testing too :D

> 
>> I felt that keeping them described in the struct was cleaner than shifts
>> and masks - but clearly this stands out, due to the byte-ordering.
>>
>> Would you prefer I re-write this as 32 bit accesses (or even 64bit),
>> with shifts? Or is a comment sufficient here ?
> 
> If it doesn't make the code too ugly, using larger accesses would be better I 
> think. Otherwise a comment would do I suppose.
> 
>> If we rewrite to be 32 bit accesses, would you be happy with the
>> following naming:
>>
>> 	u32 reserved0;
>> 	u32 pre_ext_dl_num_cmd; /* Also stores command flags. */
>> 	u32 pre_ext_dl_plist;
>> 	u32 post_ext_dl_num_cmd;
>> 	u32 post_ext_dl_plist;
>>
>> (Technically the flags are for the whole header, not the just the
>> pre_ext, which is why I wanted it separated)
>>
>>
>> Actually - now I write that - the 'number of commands' is sort of a flag
>> or a parameter? so maybe the following is just as appropriate?:
>>
>> 	u32 reserved0;
> 
> Maybe "u32 zero;" or "u32 padding;" ? The datasheet states this is padding for 
> alignment purpose.

I've used "padding".


> 
>> 	u32 pre_ext_dl_flags;
>> 	u32 pre_ext_dl_plist;
>> 	u32 post_ext_dl_flags;
>> 	u32 post_ext_dl_plist;
>>
>> Or they could be named 'options', or parameters?
>>
>> Any comments before I hack that in?
>>
>> The annoying part is that the 'flags' aren't part of the pre_ext cmds,
>> they declare whether the pre or post cmd should be executed (or both I
>> presume, we are yet to see post-cmd usage)
> 
> I agree with you, having a separate flag field would be nicer, as the flags 
> are shared. I'll chose the easy option of letting you decide what you like 
> best :-) All the above options are equally good to me, provided you add a 
> comment explaining why the flag comes after the num_cmd field if you decide to 
> keep it as a separate field.

I've added a comment to explain why the flags must be after num_cmd. I
feel it's better to keep the flags separated as they are not specific to
the pre_cmd.


> 
>>>> +	u32 pre_ext_cmd_plist;
>>>
>>> And pre_ext_dl_plist ?
>>>
>>>> +
>>>> +	u32 post_ext_cmd_qty;
>>>> +	u32 post_ext_cmd_plist;
>>>
>>> Similar comments for these variables.
>>
>> Renamed.
>>
>>>> +};
>>>> +
>>>> +struct vsp1_dl_header_extended {
>>>> +	struct vsp1_dl_header header;
>>>> +	struct vsp1_dl_ext_header ext;
>>>> +};
>>>> +
>>>>  struct vsp1_dl_entry {
>>>>  	u32 addr;
>>>>  	u32 data;
>>>>  };
>>>>
>>>> +struct vsp1_dl_ext_cmd_header {
>>>
>>> Isn't this referred to in the datasheet as a body entry, not a header ?
>>> How about naming it vsp1_dl_ext_cmd_entry ? Or just vsp1_dl_ext_cmd (in
>>> which case the other structure that goes by the same name would need to be
>>> renamed) ?
>>
>> I think I was getting too creative. The reality is this part is really a
>> 'header' describing the data in the body, but yes - it should be named
>> to match a "Pre Extended Display List Body"
>>
>>   s/vsp1_dl_ext_cmd_header/vsp1_pre_ext_dl_body/
> 
> Sounds good to me.
> 
>> This will then leave "struct vsp1_dl_ext_cmd" which represents the
>> object instance within the VSP1 driver only.
>>
>>>> +	u32 cmd;
>>
>> This should really have been opcode then too :)
> 
> Good point.

Renamed


> 
>>>> +	u32 flags;
>>>> +	u32 data;
>>>> +	u32 reserved;
>>>
>>> The datasheet documents this as two 64-bit fields, shouldn't we handle the
>>> structure the same way ?
>>
>> I was trying to separate out the fields for clarity.
>>
>> In this instance (unlike the 16bit handling above), the byte ordering of
>> a 64 bit value works in our favour, and the ordering of the 4 u32s,
>> follows the order of the datasheet.
>>
>> If you'd prefer to handle them as 64bit with mask and shift, I'll
>> update, and rename this to contain two fields :
>>      u64 ext_dl_cmd;
>>      u64 ext_dl_data;
>>
>> But this is working well with the 32 bit definitions.
> 
> Up to you, I'm OK with both.

Great, in this instance - and because it works cleanly - I prefer the
split, with named field accesses.

I'll add a documenting comment along side it that it is listed as a
64-bit access, but the storage order is the same.

> 
>>>> +};
> 
> [snip]
> 

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

* Re: [PATCH v4 08/11] media: vsp1: Add support for extended display list headers
@ 2018-07-17 15:01           ` Kieran Bingham
  0 siblings, 0 replies; 78+ messages in thread
From: Kieran Bingham @ 2018-07-17 15:01 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: linux-renesas-soc, dri-devel, linux-media

Hi Laurent,

On 17/07/18 11:53, Laurent Pinchart wrote:
> Hi Kieran,
> 
> On Monday, 16 July 2018 20:14:55 EEST Kieran Bingham wrote:
>> On 24/05/18 12:44, Laurent Pinchart wrote:
>>> On Thursday, 3 May 2018 16:36:19 EEST Kieran Bingham wrote:
>>>> 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>
>>>>
>>>> ---
>>>>
>>>> v2:
>>>>  - remove __packed attributes
>>>>
>>>> ---
>>>>
>>>>  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(-)
> 
> [snip]
> 
>>>> diff --git a/drivers/media/platform/vsp1/vsp1_dl.c
>>>> b/drivers/media/platform/vsp1/vsp1_dl.c index 56514cd51c51..b64d32535edc
>>>> 100644
>>>> --- a/drivers/media/platform/vsp1/vsp1_dl.c
>>>> +++ b/drivers/media/platform/vsp1/vsp1_dl.c
> 
> [snip]
> 
>>>> +struct vsp1_dl_ext_header {
>>>> +	u32 reserved0;		/* alignment padding */
>>>> +
>>>> +	u16 pre_ext_cmd_qty;
>>>
>>> Should this be called pre_ext_dl_num_cmd to match the datasheet ?
>>
>> Yes, renamed.
>>
>>>> +	u16 flags;
>>>
>>> Aren't the flags supposed to come before the pre_ext_dl_num_cmd field ?
>>
>> These are out-of-order to account for the fact that they are 16bit values.
> 
> Ah OK. It makes sense, but is a bit confusing when reading the datasheet.

Yes, I agree. Realising the byte-ordering was off was a bit of a pain
point when I was testing too :D

> 
>> I felt that keeping them described in the struct was cleaner than shifts
>> and masks - but clearly this stands out, due to the byte-ordering.
>>
>> Would you prefer I re-write this as 32 bit accesses (or even 64bit),
>> with shifts? Or is a comment sufficient here ?
> 
> If it doesn't make the code too ugly, using larger accesses would be better I 
> think. Otherwise a comment would do I suppose.
> 
>> If we rewrite to be 32 bit accesses, would you be happy with the
>> following naming:
>>
>> 	u32 reserved0;
>> 	u32 pre_ext_dl_num_cmd; /* Also stores command flags. */
>> 	u32 pre_ext_dl_plist;
>> 	u32 post_ext_dl_num_cmd;
>> 	u32 post_ext_dl_plist;
>>
>> (Technically the flags are for the whole header, not the just the
>> pre_ext, which is why I wanted it separated)
>>
>>
>> Actually - now I write that - the 'number of commands' is sort of a flag
>> or a parameter? so maybe the following is just as appropriate?:
>>
>> 	u32 reserved0;
> 
> Maybe "u32 zero;" or "u32 padding;" ? The datasheet states this is padding for 
> alignment purpose.

I've used "padding".


> 
>> 	u32 pre_ext_dl_flags;
>> 	u32 pre_ext_dl_plist;
>> 	u32 post_ext_dl_flags;
>> 	u32 post_ext_dl_plist;
>>
>> Or they could be named 'options', or parameters?
>>
>> Any comments before I hack that in?
>>
>> The annoying part is that the 'flags' aren't part of the pre_ext cmds,
>> they declare whether the pre or post cmd should be executed (or both I
>> presume, we are yet to see post-cmd usage)
> 
> I agree with you, having a separate flag field would be nicer, as the flags 
> are shared. I'll chose the easy option of letting you decide what you like 
> best :-) All the above options are equally good to me, provided you add a 
> comment explaining why the flag comes after the num_cmd field if you decide to 
> keep it as a separate field.

I've added a comment to explain why the flags must be after num_cmd. I
feel it's better to keep the flags separated as they are not specific to
the pre_cmd.


> 
>>>> +	u32 pre_ext_cmd_plist;
>>>
>>> And pre_ext_dl_plist ?
>>>
>>>> +
>>>> +	u32 post_ext_cmd_qty;
>>>> +	u32 post_ext_cmd_plist;
>>>
>>> Similar comments for these variables.
>>
>> Renamed.
>>
>>>> +};
>>>> +
>>>> +struct vsp1_dl_header_extended {
>>>> +	struct vsp1_dl_header header;
>>>> +	struct vsp1_dl_ext_header ext;
>>>> +};
>>>> +
>>>>  struct vsp1_dl_entry {
>>>>  	u32 addr;
>>>>  	u32 data;
>>>>  };
>>>>
>>>> +struct vsp1_dl_ext_cmd_header {
>>>
>>> Isn't this referred to in the datasheet as a body entry, not a header ?
>>> How about naming it vsp1_dl_ext_cmd_entry ? Or just vsp1_dl_ext_cmd (in
>>> which case the other structure that goes by the same name would need to be
>>> renamed) ?
>>
>> I think I was getting too creative. The reality is this part is really a
>> 'header' describing the data in the body, but yes - it should be named
>> to match a "Pre Extended Display List Body"
>>
>>   s/vsp1_dl_ext_cmd_header/vsp1_pre_ext_dl_body/
> 
> Sounds good to me.
> 
>> This will then leave "struct vsp1_dl_ext_cmd" which represents the
>> object instance within the VSP1 driver only.
>>
>>>> +	u32 cmd;
>>
>> This should really have been opcode then too :)
> 
> Good point.

Renamed


> 
>>>> +	u32 flags;
>>>> +	u32 data;
>>>> +	u32 reserved;
>>>
>>> The datasheet documents this as two 64-bit fields, shouldn't we handle the
>>> structure the same way ?
>>
>> I was trying to separate out the fields for clarity.
>>
>> In this instance (unlike the 16bit handling above), the byte ordering of
>> a 64 bit value works in our favour, and the ordering of the 4 u32s,
>> follows the order of the datasheet.
>>
>> If you'd prefer to handle them as 64bit with mask and shift, I'll
>> update, and rename this to contain two fields :
>>      u64 ext_dl_cmd;
>>      u64 ext_dl_data;
>>
>> But this is working well with the 32 bit definitions.
> 
> Up to you, I'm OK with both.

Great, in this instance - and because it works cleanly - I prefer the
split, with named field accesses.

I'll add a documenting comment along side it that it is listed as a
64-bit access, but the storage order is the same.

> 
>>>> +};
> 
> [snip]
> 

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v4 09/11] media: vsp1: Provide support for extended command pools
  2018-05-24 12:12     ` Laurent Pinchart
@ 2018-07-17 15:59       ` Kieran Bingham
  -1 siblings, 0 replies; 78+ messages in thread
From: Kieran Bingham @ 2018-07-17 15:59 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: linux-renesas-soc, linux-media, dri-devel

Hi Laurent,

Thanks for your review comments.

These were easier to go through than patch 8 :D

On 24/05/18 13:12, Laurent Pinchart wrote:
> Hi Kieran,
> 
> Thank you for the patch.
> 
> On Thursday, 3 May 2018 16:36:20 EEST 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 convenient
>> re-usable command objects for the entities to utilise.
>>
>> Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
>>
>> ---
>>
>> v2:
>>  - Fix spelling typo in commit message
>>  - constify, and staticify the instantiation of vsp1_extended_commands
>>  - s/autfld_cmds/autofld_cmds/
>>  - staticify cmd pool functions (Thanks kbuild-bot)
>> ---
>>  drivers/media/platform/vsp1/vsp1_dl.c | 191 +++++++++++++++++++++++++++-
>>  drivers/media/platform/vsp1/vsp1_dl.h |   3 +-
>>  2 files changed, 194 insertions(+)
>>
>> diff --git a/drivers/media/platform/vsp1/vsp1_dl.c
>> b/drivers/media/platform/vsp1/vsp1_dl.c index b64d32535edc..d33ae5f125bd
>> 100644
>> --- a/drivers/media/platform/vsp1/vsp1_dl.c
>> +++ b/drivers/media/platform/vsp1/vsp1_dl.c
>> @@ -117,6 +117,30 @@ struct vsp1_dl_body_pool {
>>  };
>>
>>  /**
>> + * struct vsp1_cmd_pool - display list body pool
> 
> The structure is called vsp1_dl_cmd_pool. I would document it as "Display list 
> commands pool", not "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
> 
> The field is called cmds.
> 

Fixed

>> + * @free: List of free DLB entries
> 
> "free pool entries" or "free command entries" ?
> 

Fixed

>> + * @lock: Protects the pool and free list
> 
> The pool is the whole structure, does the lock really protects all fields ?

Perhaps in theory, but not in practice. Only the free-list is protected
by this lock. Adjusting the comment.


> 
>> + * @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
>> @@ -162,6 +186,7 @@ struct vsp1_dl_list {
>>   * @queued: list queued to the hardware (written to the DL registers)
>>   * @pending: list waiting to be queued to the hardware
>>   * @pool: body pool for the display list bodies
>> + * @autofld_cmds: command pool to support auto-fld interlaced mode
> 
> This could also be used for auto-disp. How about calling it cmdpool ?

Hrm ... I think originally I wanted to keep this specific to auto-fld,
as that is the 'type' which gets instatiated. But we can not have both
auto-fld and auto-disp at the same time, so cmdpool is fine. If we ever
find we need a pre_cmdpool, and a post_cmdpool, we can rename as
appropriate.

> 
>>   */
>>  struct vsp1_dl_manager {
>>  	unsigned int index;
>> @@ -175,6 +200,7 @@ struct vsp1_dl_manager {
>>  	struct vsp1_dl_list *pending;
>>
>>  	struct vsp1_dl_body_pool *pool;
>> +	struct vsp1_dl_cmd_pool *autofld_cmds;
>>  };
>>
>>  /* ------------------------------------------------------------------------
>> @@ -338,6 +364,140 @@ 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;
>> +} static const vsp1_extended_commands[] = {
> 
> The location of the static const keywords is strange. I would move them before 
> struct, or split the structure definition and variable declaration.

I'll split them.


> 
>> +	[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
> 
> s/quantity/number/ ?

Sure ... also s/num_commands/num_cmds/

>> + *
>> + * 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
> 
> s/a pool/the pool/
> 

Fixed.

>> allocated.
>> + */
>> +static 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);
> 
> I would move these two lines right after allocation of pool, I find it more 
> readable to perform small and simple initialization right away.

Done

> 
>> +	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;
> 
> The data memory has to be 16-bytes aligned. This is guaranteed as the header 
> is 16 bytes long, and cmd_size is aligned to 16 bytes, but it would be worth 
> adding a comment to explain this.

Yes, I've actually already added a comment to the struct definition
where this applies. But I think it warrants a line here too.


> 
>> +		cmd->pool = pool;
>> +		cmd->cmd_opcode = vsp1_extended_commands[type].opcode;
>> +
>> +		/* TODO: Auto-disp can utilise more than one command per cmd */
> 
> That will be annoying to handle :-/

Yes, I believe it's one command per VIN ? Perhaps limited by the number
of planes ... so a max 5?


>> +		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;
>> +}
>> +
>> +static
>> +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;
>> +}
>> +
>> +static void vsp1_dl_ext_cmd_put(struct vsp1_dl_ext_cmd *cmd)
>> +{
>> +	unsigned long flags;
>> +
>> +	if (!cmd)
>> +		return;
>> +
>> +	/* Reset flags, these mark data usage */
> 
> s/usage/usage./

Fixed.

> 
>> +	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);
>> +}
>> +
>> +static 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
>>   */
>>
>> @@ -440,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.
>> @@ -883,6 +1049,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->autofld_cmds = vsp1_dl_cmd_pool_create(vsp1,
>> +					VSP1_EXTCMD_AUTOFLD, prealloc);
>> +		if (!dlm->autofld_cmds) {
>> +			vsp1_dlm_destroy(dlm);
>> +			return NULL;
>> +		}
>> +	}
>> +
>>  	return dlm;
>>  }
>>
>> @@ -899,4 +1074,20 @@ void vsp1_dlm_destroy(struct vsp1_dl_manager *dlm)
>>  	}
>>
>>  	vsp1_dl_body_pool_destroy(dlm->pool);
>> +	vsp1_dl_ext_cmd_pool_destroy(dlm->autofld_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->autofld_cmds);
>> +	if (cmd)
>> +		dl->pre_cmd = cmd;
>> +
>> +	return cmd;
> 
> You can write it in a simpler way.
> 
> 	dl->pre_cmd = vsp1_dl_ext_cmd_get(dlm->autofld_cmds);
> 	return dl->pre_cmd;

Fixed.


> 
>>  }
>> diff --git a/drivers/media/platform/vsp1/vsp1_dl.h
>> b/drivers/media/platform/vsp1/vsp1_dl.h index aa5f4adc6617..d9621207b093
>> 100644
>> --- a/drivers/media/platform/vsp1/vsp1_dl.h
>> +++ b/drivers/media/platform/vsp1/vsp1_dl.h
>> @@ -22,6 +22,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
>> @@ -33,6 +34,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;
>> @@ -55,6 +57,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);
>>  unsigned int 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);
> 
> Should this be named vsp1_dl_get_autofld_cmd() as it operates on a dl ? I also 
> think that you should move it down to group it with the dl functions.

Perhaps. I named it as such as I felt like it was the display list
managers responsibility, and the pool belongs to the DLM. It's just the
reference to the DLM is obtained through the DL (and the object
retrieved is cached per DL)

Of course, now that the pool is not autofld_cmds, but cmdpool, it could
be said that the function name itself is wrong, and could be
vsp1_dl{,m}_get_pre_cmd() - but this feels like the link between the
instantiated type (VSP1_EXTCMD_AUTOFLD) and the point of usage will be
very tenuous.

However, this isn't much of an issue until we add support for other
command types.

Renaming to vsp1_dl_get_pre_cmd().


> 
>>  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] 78+ messages in thread

* Re: [PATCH v4 09/11] media: vsp1: Provide support for extended command pools
@ 2018-07-17 15:59       ` Kieran Bingham
  0 siblings, 0 replies; 78+ messages in thread
From: Kieran Bingham @ 2018-07-17 15:59 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: linux-renesas-soc, dri-devel, linux-media

Hi Laurent,

Thanks for your review comments.

These were easier to go through than patch 8 :D

On 24/05/18 13:12, Laurent Pinchart wrote:
> Hi Kieran,
> 
> Thank you for the patch.
> 
> On Thursday, 3 May 2018 16:36:20 EEST 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 convenient
>> re-usable command objects for the entities to utilise.
>>
>> Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
>>
>> ---
>>
>> v2:
>>  - Fix spelling typo in commit message
>>  - constify, and staticify the instantiation of vsp1_extended_commands
>>  - s/autfld_cmds/autofld_cmds/
>>  - staticify cmd pool functions (Thanks kbuild-bot)
>> ---
>>  drivers/media/platform/vsp1/vsp1_dl.c | 191 +++++++++++++++++++++++++++-
>>  drivers/media/platform/vsp1/vsp1_dl.h |   3 +-
>>  2 files changed, 194 insertions(+)
>>
>> diff --git a/drivers/media/platform/vsp1/vsp1_dl.c
>> b/drivers/media/platform/vsp1/vsp1_dl.c index b64d32535edc..d33ae5f125bd
>> 100644
>> --- a/drivers/media/platform/vsp1/vsp1_dl.c
>> +++ b/drivers/media/platform/vsp1/vsp1_dl.c
>> @@ -117,6 +117,30 @@ struct vsp1_dl_body_pool {
>>  };
>>
>>  /**
>> + * struct vsp1_cmd_pool - display list body pool
> 
> The structure is called vsp1_dl_cmd_pool. I would document it as "Display list 
> commands pool", not "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
> 
> The field is called cmds.
> 

Fixed

>> + * @free: List of free DLB entries
> 
> "free pool entries" or "free command entries" ?
> 

Fixed

>> + * @lock: Protects the pool and free list
> 
> The pool is the whole structure, does the lock really protects all fields ?

Perhaps in theory, but not in practice. Only the free-list is protected
by this lock. Adjusting the comment.


> 
>> + * @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
>> @@ -162,6 +186,7 @@ struct vsp1_dl_list {
>>   * @queued: list queued to the hardware (written to the DL registers)
>>   * @pending: list waiting to be queued to the hardware
>>   * @pool: body pool for the display list bodies
>> + * @autofld_cmds: command pool to support auto-fld interlaced mode
> 
> This could also be used for auto-disp. How about calling it cmdpool ?

Hrm ... I think originally I wanted to keep this specific to auto-fld,
as that is the 'type' which gets instatiated. But we can not have both
auto-fld and auto-disp at the same time, so cmdpool is fine. If we ever
find we need a pre_cmdpool, and a post_cmdpool, we can rename as
appropriate.

> 
>>   */
>>  struct vsp1_dl_manager {
>>  	unsigned int index;
>> @@ -175,6 +200,7 @@ struct vsp1_dl_manager {
>>  	struct vsp1_dl_list *pending;
>>
>>  	struct vsp1_dl_body_pool *pool;
>> +	struct vsp1_dl_cmd_pool *autofld_cmds;
>>  };
>>
>>  /* ------------------------------------------------------------------------
>> @@ -338,6 +364,140 @@ 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;
>> +} static const vsp1_extended_commands[] = {
> 
> The location of the static const keywords is strange. I would move them before 
> struct, or split the structure definition and variable declaration.

I'll split them.


> 
>> +	[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
> 
> s/quantity/number/ ?

Sure ... also s/num_commands/num_cmds/

>> + *
>> + * 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
> 
> s/a pool/the pool/
> 

Fixed.

>> allocated.
>> + */
>> +static 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);
> 
> I would move these two lines right after allocation of pool, I find it more 
> readable to perform small and simple initialization right away.

Done

> 
>> +	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;
> 
> The data memory has to be 16-bytes aligned. This is guaranteed as the header 
> is 16 bytes long, and cmd_size is aligned to 16 bytes, but it would be worth 
> adding a comment to explain this.

Yes, I've actually already added a comment to the struct definition
where this applies. But I think it warrants a line here too.


> 
>> +		cmd->pool = pool;
>> +		cmd->cmd_opcode = vsp1_extended_commands[type].opcode;
>> +
>> +		/* TODO: Auto-disp can utilise more than one command per cmd */
> 
> That will be annoying to handle :-/

Yes, I believe it's one command per VIN ? Perhaps limited by the number
of planes ... so a max 5?


>> +		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;
>> +}
>> +
>> +static
>> +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;
>> +}
>> +
>> +static void vsp1_dl_ext_cmd_put(struct vsp1_dl_ext_cmd *cmd)
>> +{
>> +	unsigned long flags;
>> +
>> +	if (!cmd)
>> +		return;
>> +
>> +	/* Reset flags, these mark data usage */
> 
> s/usage/usage./

Fixed.

> 
>> +	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);
>> +}
>> +
>> +static 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
>>   */
>>
>> @@ -440,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.
>> @@ -883,6 +1049,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->autofld_cmds = vsp1_dl_cmd_pool_create(vsp1,
>> +					VSP1_EXTCMD_AUTOFLD, prealloc);
>> +		if (!dlm->autofld_cmds) {
>> +			vsp1_dlm_destroy(dlm);
>> +			return NULL;
>> +		}
>> +	}
>> +
>>  	return dlm;
>>  }
>>
>> @@ -899,4 +1074,20 @@ void vsp1_dlm_destroy(struct vsp1_dl_manager *dlm)
>>  	}
>>
>>  	vsp1_dl_body_pool_destroy(dlm->pool);
>> +	vsp1_dl_ext_cmd_pool_destroy(dlm->autofld_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->autofld_cmds);
>> +	if (cmd)
>> +		dl->pre_cmd = cmd;
>> +
>> +	return cmd;
> 
> You can write it in a simpler way.
> 
> 	dl->pre_cmd = vsp1_dl_ext_cmd_get(dlm->autofld_cmds);
> 	return dl->pre_cmd;

Fixed.


> 
>>  }
>> diff --git a/drivers/media/platform/vsp1/vsp1_dl.h
>> b/drivers/media/platform/vsp1/vsp1_dl.h index aa5f4adc6617..d9621207b093
>> 100644
>> --- a/drivers/media/platform/vsp1/vsp1_dl.h
>> +++ b/drivers/media/platform/vsp1/vsp1_dl.h
>> @@ -22,6 +22,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
>> @@ -33,6 +34,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;
>> @@ -55,6 +57,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);
>>  unsigned int 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);
> 
> Should this be named vsp1_dl_get_autofld_cmd() as it operates on a dl ? I also 
> think that you should move it down to group it with the dl functions.

Perhaps. I named it as such as I felt like it was the display list
managers responsibility, and the pool belongs to the DLM. It's just the
reference to the DLM is obtained through the DL (and the object
retrieved is cached per DL)

Of course, now that the pool is not autofld_cmds, but cmdpool, it could
be said that the function name itself is wrong, and could be
vsp1_dl{,m}_get_pre_cmd() - but this feels like the link between the
instantiated type (VSP1_EXTCMD_AUTOFLD) and the point of usage will be
very tenuous.

However, this isn't much of an issue until we add support for other
command types.

Renaming to vsp1_dl_get_pre_cmd().


> 
>>  struct vsp1_dl_list *vsp1_dl_list_get(struct vsp1_dl_manager *dlm);
>>  void vsp1_dl_list_put(struct vsp1_dl_list *dl);
> 

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v4 10/11] media: vsp1: Support Interlaced display pipelines
  2018-07-17 12:52         ` Laurent Pinchart
@ 2018-07-17 16:08           ` Kieran Bingham
  -1 siblings, 0 replies; 78+ messages in thread
From: Kieran Bingham @ 2018-07-17 16:08 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: linux-renesas-soc, linux-media, dri-devel

Hi Laurent,

On 17/07/18 13:52, Laurent Pinchart wrote:
> Hi Kieran,
> 
> On Monday, 16 July 2018 21:21:00 EEST Kieran Bingham wrote:
>> On 24/05/18 13:51, Laurent Pinchart wrote:
>>> On Thursday, 3 May 2018 16:36:21 EEST Kieran Bingham wrote:
>>>> 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>
>>>>
>>>> ---
>>>>
>>>> v3:
>>>>  - Pass DL through partition calls to allow autocmd's to be retrieved
>>>>  - Document interlaced field in struct vsp1_du_atomic_config
>>>>
>>>> v2:
>>>>  - fix erroneous BIT value which enabled interlaced
>>>>  - fix field handling at frame_end interrupt
>>>>
>>>> ---
>>>>
>>>>  drivers/media/platform/vsp1/vsp1_dl.c   | 10 ++++-
>>>>  drivers/media/platform/vsp1/vsp1_drm.c  | 11 ++++-
>>>>  drivers/media/platform/vsp1/vsp1_regs.h |  1 +-
>>>>  drivers/media/platform/vsp1/vsp1_rpf.c  | 71 ++++++++++++++++++++++++--
>>>>  drivers/media/platform/vsp1/vsp1_rwpf.h |  1 +-
>>>>  include/media/vsp1.h                    |  2 +-
>>>>  6 files changed, 93 insertions(+), 3 deletions(-)
> 
> [snip]
> 
>>>> diff --git a/drivers/media/platform/vsp1/vsp1_drm.c
>>>> b/drivers/media/platform/vsp1/vsp1_drm.c index 2c3db8b8adce..cc29c9d96bb7
>>>> 100644
>>>> --- a/drivers/media/platform/vsp1/vsp1_drm.c
>>>> +++ b/drivers/media/platform/vsp1/vsp1_drm.c
>>>> @@ -811,6 +811,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) {
>>>
>>> Nitpicking, writing the condition as
>>>
>>> 	if (cfg->interlaced && !(vsp1_feature(vsp1, VSP1_HAS_EXT_DL)))
>>
>> Done.
>>
>>> would match the comment better. You can also drop the parentheses around
>>> the vsp1_feature() call.
>>>
>>>> +		/*
>>>> +		 * 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");
>>>
>>> Could we catch this in the DU driver to fail atomic test ?
>>
>> Ugh - I thought moving the configuration to vsp1_du_setup_lif() would
>> give us this, but that return value is not checked in the DU.
>>
>> How can we interogate the VSP1 to ask it if it supports interlaced from
>> rcar_du_vsp_plane_atomic_check()?
>>
>>
>> Some dummy call to vsp1_du_setup_lif() to check the return value ? Or
>> should we implement a hook to call through to perform checks in the VSP1
>> DRM API?
> 
> Would it be possible to just infer that from the DU compatible string, without 
> querying the VSP driver ? Of course that's a bit of a layering violation, but 
> as we know what type of VSP instance is present in each SoC, such a small hack 
> wouldn't hurt in my opinion. If the need arises later we can introduce an API 
> to query the information from the VSP driver.

I'm not sure what there is to match on currently.

I thought that we had restrictions on which display pipelines supported
interlaced. (i.e. D3/E3 might not) - but they seem to support extended
display lists ...

So isn't it the case that any pipeline which we connect to DRM supports
interlaced? (currently) - we can't / don't physically connect other VSP
entities to the DRM pipes...


> 
>>>> +		return -EINVAL;
>>>> +	}
>>>> +
>>>> +	rpf->interlaced = cfg->interlaced;
>>>> +
>>>>  	rpf->fmtinfo = fmtinfo;
>>>>  	rpf->format.num_planes = fmtinfo->planes;
>>>>  	rpf->format.plane_fmt[0].bytesperline = cfg->pitch;
> 
> [snip]

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

* Re: [PATCH v4 10/11] media: vsp1: Support Interlaced display pipelines
@ 2018-07-17 16:08           ` Kieran Bingham
  0 siblings, 0 replies; 78+ messages in thread
From: Kieran Bingham @ 2018-07-17 16:08 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: linux-renesas-soc, dri-devel, linux-media

Hi Laurent,

On 17/07/18 13:52, Laurent Pinchart wrote:
> Hi Kieran,
> 
> On Monday, 16 July 2018 21:21:00 EEST Kieran Bingham wrote:
>> On 24/05/18 13:51, Laurent Pinchart wrote:
>>> On Thursday, 3 May 2018 16:36:21 EEST Kieran Bingham wrote:
>>>> 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>
>>>>
>>>> ---
>>>>
>>>> v3:
>>>>  - Pass DL through partition calls to allow autocmd's to be retrieved
>>>>  - Document interlaced field in struct vsp1_du_atomic_config
>>>>
>>>> v2:
>>>>  - fix erroneous BIT value which enabled interlaced
>>>>  - fix field handling at frame_end interrupt
>>>>
>>>> ---
>>>>
>>>>  drivers/media/platform/vsp1/vsp1_dl.c   | 10 ++++-
>>>>  drivers/media/platform/vsp1/vsp1_drm.c  | 11 ++++-
>>>>  drivers/media/platform/vsp1/vsp1_regs.h |  1 +-
>>>>  drivers/media/platform/vsp1/vsp1_rpf.c  | 71 ++++++++++++++++++++++++--
>>>>  drivers/media/platform/vsp1/vsp1_rwpf.h |  1 +-
>>>>  include/media/vsp1.h                    |  2 +-
>>>>  6 files changed, 93 insertions(+), 3 deletions(-)
> 
> [snip]
> 
>>>> diff --git a/drivers/media/platform/vsp1/vsp1_drm.c
>>>> b/drivers/media/platform/vsp1/vsp1_drm.c index 2c3db8b8adce..cc29c9d96bb7
>>>> 100644
>>>> --- a/drivers/media/platform/vsp1/vsp1_drm.c
>>>> +++ b/drivers/media/platform/vsp1/vsp1_drm.c
>>>> @@ -811,6 +811,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) {
>>>
>>> Nitpicking, writing the condition as
>>>
>>> 	if (cfg->interlaced && !(vsp1_feature(vsp1, VSP1_HAS_EXT_DL)))
>>
>> Done.
>>
>>> would match the comment better. You can also drop the parentheses around
>>> the vsp1_feature() call.
>>>
>>>> +		/*
>>>> +		 * 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");
>>>
>>> Could we catch this in the DU driver to fail atomic test ?
>>
>> Ugh - I thought moving the configuration to vsp1_du_setup_lif() would
>> give us this, but that return value is not checked in the DU.
>>
>> How can we interogate the VSP1 to ask it if it supports interlaced from
>> rcar_du_vsp_plane_atomic_check()?
>>
>>
>> Some dummy call to vsp1_du_setup_lif() to check the return value ? Or
>> should we implement a hook to call through to perform checks in the VSP1
>> DRM API?
> 
> Would it be possible to just infer that from the DU compatible string, without 
> querying the VSP driver ? Of course that's a bit of a layering violation, but 
> as we know what type of VSP instance is present in each SoC, such a small hack 
> wouldn't hurt in my opinion. If the need arises later we can introduce an API 
> to query the information from the VSP driver.

I'm not sure what there is to match on currently.

I thought that we had restrictions on which display pipelines supported
interlaced. (i.e. D3/E3 might not) - but they seem to support extended
display lists ...

So isn't it the case that any pipeline which we connect to DRM supports
interlaced? (currently) - we can't / don't physically connect other VSP
entities to the DRM pipes...


> 
>>>> +		return -EINVAL;
>>>> +	}
>>>> +
>>>> +	rpf->interlaced = cfg->interlaced;
>>>> +
>>>>  	rpf->fmtinfo = fmtinfo;
>>>>  	rpf->format.num_planes = fmtinfo->planes;
>>>>  	rpf->format.plane_fmt[0].bytesperline = cfg->pitch;
> 
> [snip]


_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v4 10/11] media: vsp1: Support Interlaced display pipelines
  2018-07-17 16:08           ` Kieran Bingham
@ 2018-07-17 17:42             ` Laurent Pinchart
  -1 siblings, 0 replies; 78+ messages in thread
From: Laurent Pinchart @ 2018-07-17 17:42 UTC (permalink / raw)
  To: kieran.bingham+renesas; +Cc: linux-renesas-soc, linux-media, dri-devel

Hi Kieran,

On Tuesday, 17 July 2018 19:08:44 EEST Kieran Bingham wrote:
> On 17/07/18 13:52, Laurent Pinchart wrote:
> > On Monday, 16 July 2018 21:21:00 EEST Kieran Bingham wrote:
> >> On 24/05/18 13:51, Laurent Pinchart wrote:
> >>> On Thursday, 3 May 2018 16:36:21 EEST Kieran Bingham wrote:
> >>>> 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>
> >>>> 
> >>>> ---
> >>>> 
> >>>> v3:
> >>>>  - Pass DL through partition calls to allow autocmd's to be retrieved
> >>>>  - Document interlaced field in struct vsp1_du_atomic_config
> >>>> 
> >>>> v2:
> >>>>  - fix erroneous BIT value which enabled interlaced
> >>>>  - fix field handling at frame_end interrupt
> >>>> 
> >>>> ---
> >>>> 
> >>>>  drivers/media/platform/vsp1/vsp1_dl.c   | 10 ++++-
> >>>>  drivers/media/platform/vsp1/vsp1_drm.c  | 11 ++++-
> >>>>  drivers/media/platform/vsp1/vsp1_regs.h |  1 +-
> >>>>  drivers/media/platform/vsp1/vsp1_rpf.c  | 71 ++++++++++++++++++++++--
> >>>>  drivers/media/platform/vsp1/vsp1_rwpf.h |  1 +-
> >>>>  include/media/vsp1.h                    |  2 +-
> >>>>  6 files changed, 93 insertions(+), 3 deletions(-)
> > 
> > [snip]
> > 
> >>>> diff --git a/drivers/media/platform/vsp1/vsp1_drm.c
> >>>> b/drivers/media/platform/vsp1/vsp1_drm.c index
> >>>> 2c3db8b8adce..cc29c9d96bb7
> >>>> 100644
> >>>> --- a/drivers/media/platform/vsp1/vsp1_drm.c
> >>>> +++ b/drivers/media/platform/vsp1/vsp1_drm.c
> >>>> @@ -811,6 +811,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) {
> >>> 
> >>> Nitpicking, writing the condition as
> >>> 
> >>> 	if (cfg->interlaced && !(vsp1_feature(vsp1, VSP1_HAS_EXT_DL)))
> >> 
> >> Done.
> >> 
> >>> would match the comment better. You can also drop the parentheses around
> >>> the vsp1_feature() call.
> >>> 
> >>>> +		/*
> >>>> +		 * 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");
> >>> 
> >>> Could we catch this in the DU driver to fail atomic test ?
> >> 
> >> Ugh - I thought moving the configuration to vsp1_du_setup_lif() would
> >> give us this, but that return value is not checked in the DU.
> >> 
> >> How can we interogate the VSP1 to ask it if it supports interlaced from
> >> rcar_du_vsp_plane_atomic_check()?
> >> 
> >> Some dummy call to vsp1_du_setup_lif() to check the return value ? Or
> >> should we implement a hook to call through to perform checks in the VSP1
> >> DRM API?
> > 
> > Would it be possible to just infer that from the DU compatible string,
> > without querying the VSP driver ? Of course that's a bit of a layering
> > violation, but as we know what type of VSP instance is present in each
> > SoC, such a small hack wouldn't hurt in my opinion. If the need arises
> > later we can introduce an API to query the information from the VSP
> > driver.
> 
> I'm not sure what there is to match on currently.
> 
> I thought that we had restrictions on which display pipelines supported
> interlaced. (i.e. D3/E3 might not) - but they seem to support extended
> display lists ...
> 
> So isn't it the case that any pipeline which we connect to DRM supports
> interlaced? (currently) - we can't / don't physically connect other VSP
> entities to the DRM pipes...

I haven't checked, but if you think that's the case, I'll trust you :-)

> >>>> +		return -EINVAL;
> >>>> +	}
> >>>> +
> >>>> +	rpf->interlaced = cfg->interlaced;
> >>>> +
> >>>>  	rpf->fmtinfo = fmtinfo;
> >>>>  	rpf->format.num_planes = fmtinfo->planes;
> >>>>  	rpf->format.plane_fmt[0].bytesperline = cfg->pitch;
> > 
> > [snip]

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v4 10/11] media: vsp1: Support Interlaced display pipelines
@ 2018-07-17 17:42             ` Laurent Pinchart
  0 siblings, 0 replies; 78+ messages in thread
From: Laurent Pinchart @ 2018-07-17 17:42 UTC (permalink / raw)
  To: kieran.bingham+renesas; +Cc: linux-renesas-soc, dri-devel, linux-media

Hi Kieran,

On Tuesday, 17 July 2018 19:08:44 EEST Kieran Bingham wrote:
> On 17/07/18 13:52, Laurent Pinchart wrote:
> > On Monday, 16 July 2018 21:21:00 EEST Kieran Bingham wrote:
> >> On 24/05/18 13:51, Laurent Pinchart wrote:
> >>> On Thursday, 3 May 2018 16:36:21 EEST Kieran Bingham wrote:
> >>>> 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>
> >>>> 
> >>>> ---
> >>>> 
> >>>> v3:
> >>>>  - Pass DL through partition calls to allow autocmd's to be retrieved
> >>>>  - Document interlaced field in struct vsp1_du_atomic_config
> >>>> 
> >>>> v2:
> >>>>  - fix erroneous BIT value which enabled interlaced
> >>>>  - fix field handling at frame_end interrupt
> >>>> 
> >>>> ---
> >>>> 
> >>>>  drivers/media/platform/vsp1/vsp1_dl.c   | 10 ++++-
> >>>>  drivers/media/platform/vsp1/vsp1_drm.c  | 11 ++++-
> >>>>  drivers/media/platform/vsp1/vsp1_regs.h |  1 +-
> >>>>  drivers/media/platform/vsp1/vsp1_rpf.c  | 71 ++++++++++++++++++++++--
> >>>>  drivers/media/platform/vsp1/vsp1_rwpf.h |  1 +-
> >>>>  include/media/vsp1.h                    |  2 +-
> >>>>  6 files changed, 93 insertions(+), 3 deletions(-)
> > 
> > [snip]
> > 
> >>>> diff --git a/drivers/media/platform/vsp1/vsp1_drm.c
> >>>> b/drivers/media/platform/vsp1/vsp1_drm.c index
> >>>> 2c3db8b8adce..cc29c9d96bb7
> >>>> 100644
> >>>> --- a/drivers/media/platform/vsp1/vsp1_drm.c
> >>>> +++ b/drivers/media/platform/vsp1/vsp1_drm.c
> >>>> @@ -811,6 +811,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) {
> >>> 
> >>> Nitpicking, writing the condition as
> >>> 
> >>> 	if (cfg->interlaced && !(vsp1_feature(vsp1, VSP1_HAS_EXT_DL)))
> >> 
> >> Done.
> >> 
> >>> would match the comment better. You can also drop the parentheses around
> >>> the vsp1_feature() call.
> >>> 
> >>>> +		/*
> >>>> +		 * 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");
> >>> 
> >>> Could we catch this in the DU driver to fail atomic test ?
> >> 
> >> Ugh - I thought moving the configuration to vsp1_du_setup_lif() would
> >> give us this, but that return value is not checked in the DU.
> >> 
> >> How can we interogate the VSP1 to ask it if it supports interlaced from
> >> rcar_du_vsp_plane_atomic_check()?
> >> 
> >> Some dummy call to vsp1_du_setup_lif() to check the return value ? Or
> >> should we implement a hook to call through to perform checks in the VSP1
> >> DRM API?
> > 
> > Would it be possible to just infer that from the DU compatible string,
> > without querying the VSP driver ? Of course that's a bit of a layering
> > violation, but as we know what type of VSP instance is present in each
> > SoC, such a small hack wouldn't hurt in my opinion. If the need arises
> > later we can introduce an API to query the information from the VSP
> > driver.
> 
> I'm not sure what there is to match on currently.
> 
> I thought that we had restrictions on which display pipelines supported
> interlaced. (i.e. D3/E3 might not) - but they seem to support extended
> display lists ...
> 
> So isn't it the case that any pipeline which we connect to DRM supports
> interlaced? (currently) - we can't / don't physically connect other VSP
> entities to the DRM pipes...

I haven't checked, but if you think that's the case, I'll trust you :-)

> >>>> +		return -EINVAL;
> >>>> +	}
> >>>> +
> >>>> +	rpf->interlaced = cfg->interlaced;
> >>>> +
> >>>>  	rpf->fmtinfo = fmtinfo;
> >>>>  	rpf->format.num_planes = fmtinfo->planes;
> >>>>  	rpf->format.plane_fmt[0].bytesperline = cfg->pitch;
> > 
> > [snip]

-- 
Regards,

Laurent Pinchart



_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v4 11/11] drm: rcar-du: Support interlaced video output through vsp1
  2018-07-17 13:51         ` Laurent Pinchart
@ 2018-07-17 20:32           ` Kieran Bingham
  -1 siblings, 0 replies; 78+ messages in thread
From: Kieran Bingham @ 2018-07-17 20:32 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: linux-renesas-soc, linux-media, dri-devel

Hi Laurent,

On 17/07/18 14:51, Laurent Pinchart wrote:
> Hi Kieran,
> 
> On Monday, 16 July 2018 20:20:30 EEST Kieran Bingham wrote:
>> On 24/05/18 12:50, Laurent Pinchart wrote:
>>> On Thursday, 3 May 2018 16:36:22 EEST Kieran Bingham wrote:
>>>> Use the newly exposed VSP1 interface to enable interlaced frame support
>>>> through the VSP1 lif pipelines.
>>>
>>> s/lif/LIF/
>>
>> Fixed.
>>
>>>> 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 d71d709fe3d9..206532959ec9
>>>> 100644
>>>> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
>>>> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
>>>> @@ -289,6 +289,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)
>>>
>>> How will this affect Gen2 ?.
>>
>> The bit is documented identically for Gen2. Potentially / Probably it
>> 'might' reverse the fields... I'm not certain yet. I don't have access
>> to a Gen2 platform to test.
>>
>> I'll see if this change can be dropped, but I think it is playing a role
>> in ensuring that the field detection occurs in VSP1 through the
>> VI6_STATUS_FLD_STD() field. (see vsp1_dlm_irq_frame_end())
>>
>>> Could you document what this change does in the
>>> commit message ?
>>
>> This sets the position in the buffer of the ODDF. With this set, the ODD
>> field is located in the second half (BOTTOM) of the same frame of the
>> interlace display.
>>
>> Otherwise, it's in the first half (TOP)
>>
>> I faced some issues as to the ordering when testing, so I suspect this
>> might actually be related to that. (re VI6_STATUS_FLD_STD in
>> vsp1_dlm_irq_frame_end()).
>>
>> As you mention - this may have a negative effect on the Gen2
>> implementation - so it needs considering with that.
>>
>>
>> /me to investigate further.
> 
> Thank you. I don't object to this change, but I'd like to know what its 
> implications are on Gen2. It might even fix a bug :-) Let me know if you'd 
> like me to run tests on a Lager board.

I've done some testing with this (removing the DSMR change, and
inverting the VI6_STATUS_FLD_STD handling) and had some odd results.
Perhaps my testing needs refinement.

So, yes please - I think I'd really like to know what the effects are on
a Lager platform.

Would you (or anyone with a Gen2 and interest in vsp1/du) be able to
test my latest vsp1/du/interlaced branch/tag on your local Gen2 platform
please?

I'm testing interlaced with:

kmstest # sanity test.
kmstest -c 1 -r 1920x1080i --flip

Any (easy) other methods for testing interlaced pipelines are welcome.

Is it possible to set the mode for kmscube? (--help doesn't look promising)

I have various test streams of interlaced media content in my media
library, but not an easy way of decoding and presenting these on the
screen on the Gen3.

I believe GStreamer now has a drm/kms sink ... Perhaps I should get that
recompiled. (That would help me with other tasks too actually)


> 
>>>>  	      | 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 af7822a66dee..c7b37232ee91
>>>> 100644
>>>> --- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
>>>> +++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
>>>> @@ -186,6 +186,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;
> 

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

* Re: [PATCH v4 11/11] drm: rcar-du: Support interlaced video output through vsp1
@ 2018-07-17 20:32           ` Kieran Bingham
  0 siblings, 0 replies; 78+ messages in thread
From: Kieran Bingham @ 2018-07-17 20:32 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: linux-renesas-soc, dri-devel, linux-media

Hi Laurent,

On 17/07/18 14:51, Laurent Pinchart wrote:
> Hi Kieran,
> 
> On Monday, 16 July 2018 20:20:30 EEST Kieran Bingham wrote:
>> On 24/05/18 12:50, Laurent Pinchart wrote:
>>> On Thursday, 3 May 2018 16:36:22 EEST Kieran Bingham wrote:
>>>> Use the newly exposed VSP1 interface to enable interlaced frame support
>>>> through the VSP1 lif pipelines.
>>>
>>> s/lif/LIF/
>>
>> Fixed.
>>
>>>> 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 d71d709fe3d9..206532959ec9
>>>> 100644
>>>> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
>>>> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
>>>> @@ -289,6 +289,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)
>>>
>>> How will this affect Gen2 ?.
>>
>> The bit is documented identically for Gen2. Potentially / Probably it
>> 'might' reverse the fields... I'm not certain yet. I don't have access
>> to a Gen2 platform to test.
>>
>> I'll see if this change can be dropped, but I think it is playing a role
>> in ensuring that the field detection occurs in VSP1 through the
>> VI6_STATUS_FLD_STD() field. (see vsp1_dlm_irq_frame_end())
>>
>>> Could you document what this change does in the
>>> commit message ?
>>
>> This sets the position in the buffer of the ODDF. With this set, the ODD
>> field is located in the second half (BOTTOM) of the same frame of the
>> interlace display.
>>
>> Otherwise, it's in the first half (TOP)
>>
>> I faced some issues as to the ordering when testing, so I suspect this
>> might actually be related to that. (re VI6_STATUS_FLD_STD in
>> vsp1_dlm_irq_frame_end()).
>>
>> As you mention - this may have a negative effect on the Gen2
>> implementation - so it needs considering with that.
>>
>>
>> /me to investigate further.
> 
> Thank you. I don't object to this change, but I'd like to know what its 
> implications are on Gen2. It might even fix a bug :-) Let me know if you'd 
> like me to run tests on a Lager board.

I've done some testing with this (removing the DSMR change, and
inverting the VI6_STATUS_FLD_STD handling) and had some odd results.
Perhaps my testing needs refinement.

So, yes please - I think I'd really like to know what the effects are on
a Lager platform.

Would you (or anyone with a Gen2 and interest in vsp1/du) be able to
test my latest vsp1/du/interlaced branch/tag on your local Gen2 platform
please?

I'm testing interlaced with:

kmstest # sanity test.
kmstest -c 1 -r 1920x1080i --flip

Any (easy) other methods for testing interlaced pipelines are welcome.

Is it possible to set the mode for kmscube? (--help doesn't look promising)

I have various test streams of interlaced media content in my media
library, but not an easy way of decoding and presenting these on the
screen on the Gen3.

I believe GStreamer now has a drm/kms sink ... Perhaps I should get that
recompiled. (That would help me with other tasks too actually)


> 
>>>>  	      | 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 af7822a66dee..c7b37232ee91
>>>> 100644
>>>> --- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
>>>> +++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
>>>> @@ -186,6 +186,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;
> 

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v4 11/11] drm: rcar-du: Support interlaced video output through vsp1
  2018-07-17 20:32           ` Kieran Bingham
@ 2018-07-18  8:55             ` Laurent Pinchart
  -1 siblings, 0 replies; 78+ messages in thread
From: Laurent Pinchart @ 2018-07-18  8:55 UTC (permalink / raw)
  To: kieran.bingham+renesas; +Cc: linux-renesas-soc, linux-media, dri-devel

Hi Kieran,

On Tuesday, 17 July 2018 23:32:56 EEST Kieran Bingham wrote:
> On 17/07/18 14:51, Laurent Pinchart wrote:
> > On Monday, 16 July 2018 20:20:30 EEST Kieran Bingham wrote:
> >> On 24/05/18 12:50, Laurent Pinchart wrote:
> >>> On Thursday, 3 May 2018 16:36:22 EEST Kieran Bingham wrote:
> >>>> Use the newly exposed VSP1 interface to enable interlaced frame support
> >>>> through the VSP1 lif pipelines.
> >>> 
> >>> s/lif/LIF/
> >> 
> >> Fixed.
> >> 
> >>>> 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
> >>>> d71d709fe3d9..206532959ec9
> >>>> 100644
> >>>> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> >>>> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> >>>> @@ -289,6 +289,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)
> >>> 
> >>> How will this affect Gen2 ?.
> >> 
> >> The bit is documented identically for Gen2. Potentially / Probably it
> >> 'might' reverse the fields... I'm not certain yet. I don't have access
> >> to a Gen2 platform to test.
> >> 
> >> I'll see if this change can be dropped, but I think it is playing a role
> >> in ensuring that the field detection occurs in VSP1 through the
> >> VI6_STATUS_FLD_STD() field. (see vsp1_dlm_irq_frame_end())
> >> 
> >>> Could you document what this change does in the
> >>> commit message ?
> >> 
> >> This sets the position in the buffer of the ODDF. With this set, the ODD
> >> field is located in the second half (BOTTOM) of the same frame of the
> >> interlace display.
> >> 
> >> Otherwise, it's in the first half (TOP)
> >> 
> >> I faced some issues as to the ordering when testing, so I suspect this
> >> might actually be related to that. (re VI6_STATUS_FLD_STD in
> >> vsp1_dlm_irq_frame_end()).
> >> 
> >> As you mention - this may have a negative effect on the Gen2
> >> implementation - so it needs considering with that.
> >> 
> >> 
> >> /me to investigate further.
> > 
> > Thank you. I don't object to this change, but I'd like to know what its
> > implications are on Gen2. It might even fix a bug :-) Let me know if you'd
> > like me to run tests on a Lager board.
> 
> I've done some testing with this (removing the DSMR change, and
> inverting the VI6_STATUS_FLD_STD handling) and had some odd results.
> Perhaps my testing needs refinement.
> 
> So, yes please - I think I'd really like to know what the effects are on
> a Lager platform.
> 
> Would you (or anyone with a Gen2 and interest in vsp1/du) be able to
> test my latest vsp1/du/interlaced branch/tag on your local Gen2 platform
> please?

I can test it when I'll come back home on the 24th (or rather on the next day 
as I'll land in the evening). Could you please ping me on the 25th ?

> I'm testing interlaced with:
> 
> kmstest # sanity test.
> kmstest -c 1 -r 1920x1080i --flip

My monitors don't support interlaced modes, so this won't be easy :-/

Also, what's the expected outcome of the above command in the working and non-
working cases ?

> Any (easy) other methods for testing interlaced pipelines are welcome.
> 
> Is it possible to set the mode for kmscube? (--help doesn't look promising)

Not that I know of, but I think that shouldn't be too difficult to add.

> I have various test streams of interlaced media content in my media
> library, but not an easy way of decoding and presenting these on the
> screen on the Gen3.
> 
> I believe GStreamer now has a drm/kms sink ... Perhaps I should get that
> recompiled. (That would help me with other tasks too actually)
> 
> >>>>  	      | 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
> >>>> af7822a66dee..c7b37232ee91
> >>>> 100644
> >>>> --- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
> >>>> +++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
> >>>> @@ -186,6 +186,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;

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v4 11/11] drm: rcar-du: Support interlaced video output through vsp1
@ 2018-07-18  8:55             ` Laurent Pinchart
  0 siblings, 0 replies; 78+ messages in thread
From: Laurent Pinchart @ 2018-07-18  8:55 UTC (permalink / raw)
  To: kieran.bingham+renesas; +Cc: linux-renesas-soc, dri-devel, linux-media

Hi Kieran,

On Tuesday, 17 July 2018 23:32:56 EEST Kieran Bingham wrote:
> On 17/07/18 14:51, Laurent Pinchart wrote:
> > On Monday, 16 July 2018 20:20:30 EEST Kieran Bingham wrote:
> >> On 24/05/18 12:50, Laurent Pinchart wrote:
> >>> On Thursday, 3 May 2018 16:36:22 EEST Kieran Bingham wrote:
> >>>> Use the newly exposed VSP1 interface to enable interlaced frame support
> >>>> through the VSP1 lif pipelines.
> >>> 
> >>> s/lif/LIF/
> >> 
> >> Fixed.
> >> 
> >>>> 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
> >>>> d71d709fe3d9..206532959ec9
> >>>> 100644
> >>>> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> >>>> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> >>>> @@ -289,6 +289,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)
> >>> 
> >>> How will this affect Gen2 ?.
> >> 
> >> The bit is documented identically for Gen2. Potentially / Probably it
> >> 'might' reverse the fields... I'm not certain yet. I don't have access
> >> to a Gen2 platform to test.
> >> 
> >> I'll see if this change can be dropped, but I think it is playing a role
> >> in ensuring that the field detection occurs in VSP1 through the
> >> VI6_STATUS_FLD_STD() field. (see vsp1_dlm_irq_frame_end())
> >> 
> >>> Could you document what this change does in the
> >>> commit message ?
> >> 
> >> This sets the position in the buffer of the ODDF. With this set, the ODD
> >> field is located in the second half (BOTTOM) of the same frame of the
> >> interlace display.
> >> 
> >> Otherwise, it's in the first half (TOP)
> >> 
> >> I faced some issues as to the ordering when testing, so I suspect this
> >> might actually be related to that. (re VI6_STATUS_FLD_STD in
> >> vsp1_dlm_irq_frame_end()).
> >> 
> >> As you mention - this may have a negative effect on the Gen2
> >> implementation - so it needs considering with that.
> >> 
> >> 
> >> /me to investigate further.
> > 
> > Thank you. I don't object to this change, but I'd like to know what its
> > implications are on Gen2. It might even fix a bug :-) Let me know if you'd
> > like me to run tests on a Lager board.
> 
> I've done some testing with this (removing the DSMR change, and
> inverting the VI6_STATUS_FLD_STD handling) and had some odd results.
> Perhaps my testing needs refinement.
> 
> So, yes please - I think I'd really like to know what the effects are on
> a Lager platform.
> 
> Would you (or anyone with a Gen2 and interest in vsp1/du) be able to
> test my latest vsp1/du/interlaced branch/tag on your local Gen2 platform
> please?

I can test it when I'll come back home on the 24th (or rather on the next day 
as I'll land in the evening). Could you please ping me on the 25th ?

> I'm testing interlaced with:
> 
> kmstest # sanity test.
> kmstest -c 1 -r 1920x1080i --flip

My monitors don't support interlaced modes, so this won't be easy :-/

Also, what's the expected outcome of the above command in the working and non-
working cases ?

> Any (easy) other methods for testing interlaced pipelines are welcome.
> 
> Is it possible to set the mode for kmscube? (--help doesn't look promising)

Not that I know of, but I think that shouldn't be too difficult to add.

> I have various test streams of interlaced media content in my media
> library, but not an easy way of decoding and presenting these on the
> screen on the Gen3.
> 
> I believe GStreamer now has a drm/kms sink ... Perhaps I should get that
> recompiled. (That would help me with other tasks too actually)
> 
> >>>>  	      | 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
> >>>> af7822a66dee..c7b37232ee91
> >>>> 100644
> >>>> --- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
> >>>> +++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
> >>>> @@ -186,6 +186,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;

-- 
Regards,

Laurent Pinchart



_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v4 11/11] drm: rcar-du: Support interlaced video output through vsp1
  2018-07-18  8:55             ` Laurent Pinchart
@ 2018-07-18  9:55               ` Kieran Bingham
  -1 siblings, 0 replies; 78+ messages in thread
From: Kieran Bingham @ 2018-07-18  9:55 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: linux-renesas-soc, linux-media, dri-devel, Niklas Söderlund,
	Jacopo Mondi, Ulrich Hecht

+ MM Team.

On 18/07/18 09:55, Laurent Pinchart wrote:
> Hi Kieran,
> 
> On Tuesday, 17 July 2018 23:32:56 EEST Kieran Bingham wrote:
>> On 17/07/18 14:51, Laurent Pinchart wrote:
>>> On Monday, 16 July 2018 20:20:30 EEST Kieran Bingham wrote:
>>>> On 24/05/18 12:50, Laurent Pinchart wrote:
>>>>> On Thursday, 3 May 2018 16:36:22 EEST Kieran Bingham wrote:
>>>>>> Use the newly exposed VSP1 interface to enable interlaced frame support
>>>>>> through the VSP1 lif pipelines.
>>>>>
>>>>> s/lif/LIF/
>>>>
>>>> Fixed.
>>>>
>>>>>> 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
>>>>>> d71d709fe3d9..206532959ec9
>>>>>> 100644
>>>>>> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
>>>>>> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
>>>>>> @@ -289,6 +289,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)
>>>>>
>>>>> How will this affect Gen2 ?.
>>>>
>>>> The bit is documented identically for Gen2. Potentially / Probably it
>>>> 'might' reverse the fields... I'm not certain yet. I don't have access
>>>> to a Gen2 platform to test.
>>>>
>>>> I'll see if this change can be dropped, but I think it is playing a role
>>>> in ensuring that the field detection occurs in VSP1 through the
>>>> VI6_STATUS_FLD_STD() field. (see vsp1_dlm_irq_frame_end())
>>>>
>>>>> Could you document what this change does in the
>>>>> commit message ?
>>>>
>>>> This sets the position in the buffer of the ODDF. With this set, the ODD
>>>> field is located in the second half (BOTTOM) of the same frame of the
>>>> interlace display.
>>>>
>>>> Otherwise, it's in the first half (TOP)
>>>>
>>>> I faced some issues as to the ordering when testing, so I suspect this
>>>> might actually be related to that. (re VI6_STATUS_FLD_STD in
>>>> vsp1_dlm_irq_frame_end()).
>>>>
>>>> As you mention - this may have a negative effect on the Gen2
>>>> implementation - so it needs considering with that.
>>>>
>>>>
>>>> /me to investigate further.
>>>
>>> Thank you. I don't object to this change, but I'd like to know what its
>>> implications are on Gen2. It might even fix a bug :-) Let me know if you'd
>>> like me to run tests on a Lager board.
>>
>> I've done some testing with this (removing the DSMR change, and
>> inverting the VI6_STATUS_FLD_STD handling) and had some odd results.
>> Perhaps my testing needs refinement.
>>
>> So, yes please - I think I'd really like to know what the effects are on
>> a Lager platform.
>>
>> Would you (or anyone with a Gen2 and interest in vsp1/du) be able to
>> test my latest vsp1/du/interlaced branch/tag on your local Gen2 platform
>> please?
> 
> I can test it when I'll come back home on the 24th (or rather on the next day 
> as I'll land in the evening). Could you please ping me on the 25th ?
> 
>> I'm testing interlaced with:
>>
>> kmstest # sanity test.
>> kmstest -c 1 -r 1920x1080i --flip

 ## -c 1 may have to change to be the right CRTC number

> 
> My monitors don't support interlaced modes, so this won't be easy :-/

More than that - I suspect "won't be possible"?

Perhaps Niklas, Jacopo, or Uli could help ?

Do any of you have a Gen2 platform - and a monitor/TV capable of showing
interlaced display output?



> Also, what's the expected outcome of the above command in the working and non-
> working cases ?

Expected outcome ... a clean output of the standard kmstest pattern for
the sanity test.

For:
kmstest -c 1 -r 1920x1080i --flip


Good:
  A clean view of the usual 'flip' bar moving from left to right across
the screen.
 Must visually check the following for good result:
  - No 'tearing' on the vertical bar
  - A full height bar, showing the colours, red, green, and blue,
followed by 3 shades of grey; each separated by a white block.
  - cleanly drawn frame numbers



Bad symptoms
 - Half height frames
   (only RGB, or 3 Grey shades showing in the flip bar)

 - Tearing or image racing of any kind (check the frame numbers as they
overdraw on the moving bar. Any blurring of the numbers as the bar
travels past is a fail)


> 
>> Any (easy) other methods for testing interlaced pipelines are welcome.
>>
>> Is it possible to set the mode for kmscube? (--help doesn't look promising)
> 
> Not that I know of, but I think that shouldn't be too difficult to add.
> 
>> I have various test streams of interlaced media content in my media
>> library, but not an easy way of decoding and presenting these on the
>> screen on the Gen3.
>>
>> I believe GStreamer now has a drm/kms sink ... Perhaps I should get that
>> recompiled. (That would help me with other tasks too actually)
>>
>>>>>>  	      | 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
>>>>>> af7822a66dee..c7b37232ee91
>>>>>> 100644
>>>>>> --- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
>>>>>> +++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
>>>>>> @@ -186,6 +186,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;
> 

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

* Re: [PATCH v4 11/11] drm: rcar-du: Support interlaced video output through vsp1
@ 2018-07-18  9:55               ` Kieran Bingham
  0 siblings, 0 replies; 78+ messages in thread
From: Kieran Bingham @ 2018-07-18  9:55 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Jacopo Mondi, dri-devel, linux-renesas-soc, Ulrich Hecht,
	Niklas Söderlund, linux-media

+ MM Team.

On 18/07/18 09:55, Laurent Pinchart wrote:
> Hi Kieran,
> 
> On Tuesday, 17 July 2018 23:32:56 EEST Kieran Bingham wrote:
>> On 17/07/18 14:51, Laurent Pinchart wrote:
>>> On Monday, 16 July 2018 20:20:30 EEST Kieran Bingham wrote:
>>>> On 24/05/18 12:50, Laurent Pinchart wrote:
>>>>> On Thursday, 3 May 2018 16:36:22 EEST Kieran Bingham wrote:
>>>>>> Use the newly exposed VSP1 interface to enable interlaced frame support
>>>>>> through the VSP1 lif pipelines.
>>>>>
>>>>> s/lif/LIF/
>>>>
>>>> Fixed.
>>>>
>>>>>> 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
>>>>>> d71d709fe3d9..206532959ec9
>>>>>> 100644
>>>>>> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
>>>>>> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
>>>>>> @@ -289,6 +289,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)
>>>>>
>>>>> How will this affect Gen2 ?.
>>>>
>>>> The bit is documented identically for Gen2. Potentially / Probably it
>>>> 'might' reverse the fields... I'm not certain yet. I don't have access
>>>> to a Gen2 platform to test.
>>>>
>>>> I'll see if this change can be dropped, but I think it is playing a role
>>>> in ensuring that the field detection occurs in VSP1 through the
>>>> VI6_STATUS_FLD_STD() field. (see vsp1_dlm_irq_frame_end())
>>>>
>>>>> Could you document what this change does in the
>>>>> commit message ?
>>>>
>>>> This sets the position in the buffer of the ODDF. With this set, the ODD
>>>> field is located in the second half (BOTTOM) of the same frame of the
>>>> interlace display.
>>>>
>>>> Otherwise, it's in the first half (TOP)
>>>>
>>>> I faced some issues as to the ordering when testing, so I suspect this
>>>> might actually be related to that. (re VI6_STATUS_FLD_STD in
>>>> vsp1_dlm_irq_frame_end()).
>>>>
>>>> As you mention - this may have a negative effect on the Gen2
>>>> implementation - so it needs considering with that.
>>>>
>>>>
>>>> /me to investigate further.
>>>
>>> Thank you. I don't object to this change, but I'd like to know what its
>>> implications are on Gen2. It might even fix a bug :-) Let me know if you'd
>>> like me to run tests on a Lager board.
>>
>> I've done some testing with this (removing the DSMR change, and
>> inverting the VI6_STATUS_FLD_STD handling) and had some odd results.
>> Perhaps my testing needs refinement.
>>
>> So, yes please - I think I'd really like to know what the effects are on
>> a Lager platform.
>>
>> Would you (or anyone with a Gen2 and interest in vsp1/du) be able to
>> test my latest vsp1/du/interlaced branch/tag on your local Gen2 platform
>> please?
> 
> I can test it when I'll come back home on the 24th (or rather on the next day 
> as I'll land in the evening). Could you please ping me on the 25th ?
> 
>> I'm testing interlaced with:
>>
>> kmstest # sanity test.
>> kmstest -c 1 -r 1920x1080i --flip

 ## -c 1 may have to change to be the right CRTC number

> 
> My monitors don't support interlaced modes, so this won't be easy :-/

More than that - I suspect "won't be possible"?

Perhaps Niklas, Jacopo, or Uli could help ?

Do any of you have a Gen2 platform - and a monitor/TV capable of showing
interlaced display output?



> Also, what's the expected outcome of the above command in the working and non-
> working cases ?

Expected outcome ... a clean output of the standard kmstest pattern for
the sanity test.

For:
kmstest -c 1 -r 1920x1080i --flip


Good:
  A clean view of the usual 'flip' bar moving from left to right across
the screen.
 Must visually check the following for good result:
  - No 'tearing' on the vertical bar
  - A full height bar, showing the colours, red, green, and blue,
followed by 3 shades of grey; each separated by a white block.
  - cleanly drawn frame numbers



Bad symptoms
 - Half height frames
   (only RGB, or 3 Grey shades showing in the flip bar)

 - Tearing or image racing of any kind (check the frame numbers as they
overdraw on the moving bar. Any blurring of the numbers as the bar
travels past is a fail)


> 
>> Any (easy) other methods for testing interlaced pipelines are welcome.
>>
>> Is it possible to set the mode for kmscube? (--help doesn't look promising)
> 
> Not that I know of, but I think that shouldn't be too difficult to add.
> 
>> I have various test streams of interlaced media content in my media
>> library, but not an easy way of decoding and presenting these on the
>> screen on the Gen3.
>>
>> I believe GStreamer now has a drm/kms sink ... Perhaps I should get that
>> recompiled. (That would help me with other tasks too actually)
>>
>>>>>>  	      | 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
>>>>>> af7822a66dee..c7b37232ee91
>>>>>> 100644
>>>>>> --- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
>>>>>> +++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
>>>>>> @@ -186,6 +186,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;
> 

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

end of thread, other threads:[~2018-07-18 10:33 UTC | newest]

Thread overview: 78+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-05-03 13:36 [PATCH v4 00/11] R-Car DU Interlaced support through VSP1 Kieran Bingham
2018-05-03 13:36 ` Kieran Bingham
2018-05-03 13:36 ` [PATCH v4 01/11] media: vsp1: drm: Fix minor grammar error Kieran Bingham
2018-05-03 13:36   ` Kieran Bingham
2018-05-24 10:24   ` Laurent Pinchart
2018-05-24 10:24     ` Laurent Pinchart
2018-05-03 13:36 ` [PATCH v4 02/11] media: vsp1: Remove packed attributes from aligned structures Kieran Bingham
2018-05-03 13:36   ` Kieran Bingham
2018-05-24 10:47   ` Laurent Pinchart
2018-05-24 10:47     ` Laurent Pinchart
2018-07-13 10:17     ` Kieran Bingham
2018-07-13 10:17       ` Kieran Bingham
2018-05-03 13:36 ` [PATCH v4 03/11] media: vsp1: Rename dl_child to dl_next Kieran Bingham
2018-05-03 13:36   ` Kieran Bingham
2018-05-24 10:51   ` Laurent Pinchart
2018-05-24 10:51     ` Laurent Pinchart
2018-05-03 13:36 ` [PATCH v4 04/11] media: vsp1: Remove unused display list structure field Kieran Bingham
2018-05-03 13:36   ` Kieran Bingham
2018-05-24 10:51   ` Laurent Pinchart
2018-05-24 10:51     ` Laurent Pinchart
2018-05-03 13:36 ` [PATCH v4 05/11] media: vsp1: Clean up DLM objects on error Kieran Bingham
2018-05-03 13:36   ` Kieran Bingham
2018-05-24 10:58   ` Laurent Pinchart
2018-05-24 10:58     ` Laurent Pinchart
2018-05-03 13:36 ` [PATCH v4 06/11] media: vsp1: Provide VSP1 feature helper macro Kieran Bingham
2018-05-03 13:36   ` Kieran Bingham
2018-05-24 11:00   ` Laurent Pinchart
2018-05-24 11:00     ` Laurent Pinchart
2018-05-03 13:36 ` [PATCH v4 07/11] media: vsp1: Use header display lists for all WPF outputs linked to the DU Kieran Bingham
2018-05-03 13:36   ` Kieran Bingham
2018-05-24 11:10   ` Laurent Pinchart
2018-05-24 11:10     ` Laurent Pinchart
2018-07-13 10:39     ` Kieran Bingham
2018-07-13 10:39       ` Kieran Bingham
2018-05-03 13:36 ` [PATCH v4 08/11] media: vsp1: Add support for extended display list headers Kieran Bingham
2018-05-03 13:36   ` Kieran Bingham
2018-05-24 11:44   ` Laurent Pinchart
2018-05-24 11:44     ` Laurent Pinchart
2018-07-16 17:14     ` Kieran Bingham
2018-07-16 17:14       ` Kieran Bingham
2018-07-17 10:53       ` Laurent Pinchart
2018-07-17 10:53         ` Laurent Pinchart
2018-07-17 15:01         ` Kieran Bingham
2018-07-17 15:01           ` Kieran Bingham
2018-05-03 13:36 ` [PATCH v4 09/11] media: vsp1: Provide support for extended command pools Kieran Bingham
2018-05-03 13:36   ` Kieran Bingham
2018-05-24 12:12   ` Laurent Pinchart
2018-05-24 12:12     ` Laurent Pinchart
2018-07-17 15:59     ` Kieran Bingham
2018-07-17 15:59       ` Kieran Bingham
2018-05-03 13:36 ` [PATCH v4 10/11] media: vsp1: Support Interlaced display pipelines Kieran Bingham
2018-05-03 13:36   ` Kieran Bingham
2018-05-24 12:51   ` Laurent Pinchart
2018-05-24 12:51     ` Laurent Pinchart
2018-07-16 18:21     ` Kieran Bingham
2018-07-16 18:21       ` Kieran Bingham
2018-07-17 12:52       ` Laurent Pinchart
2018-07-17 12:52         ` Laurent Pinchart
2018-07-17 16:08         ` Kieran Bingham
2018-07-17 16:08           ` Kieran Bingham
2018-07-17 17:42           ` Laurent Pinchart
2018-07-17 17:42             ` Laurent Pinchart
2018-07-17 14:23       ` Kieran Bingham
2018-07-17 14:23         ` Kieran Bingham
2018-05-03 13:36 ` [PATCH v4 11/11] drm: rcar-du: Support interlaced video output through vsp1 Kieran Bingham
2018-05-03 13:36   ` Kieran Bingham
2018-05-24 11:50   ` Laurent Pinchart
2018-05-24 11:50     ` Laurent Pinchart
2018-07-16 17:20     ` Kieran Bingham
2018-07-16 17:20       ` Kieran Bingham
2018-07-17 13:51       ` Laurent Pinchart
2018-07-17 13:51         ` Laurent Pinchart
2018-07-17 20:32         ` Kieran Bingham
2018-07-17 20:32           ` Kieran Bingham
2018-07-18  8:55           ` Laurent Pinchart
2018-07-18  8:55             ` Laurent Pinchart
2018-07-18  9:55             ` Kieran Bingham
2018-07-18  9:55               ` Kieran Bingham

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.