All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/8] R-Car DU: Support CRC calculation
@ 2018-04-22 22:34 ` Laurent Pinchart
  0 siblings, 0 replies; 82+ messages in thread
From: Laurent Pinchart @ 2018-04-22 22:34 UTC (permalink / raw)
  To: linux-media, dri-devel; +Cc: linux-renesas-soc, Kieran Bingham

Hello,

This patch series adds support for CRC calculation to the rcar-du-drm driver.

CRC calculation is supported starting at the Renesas R-Car Gen3 SoCs, as
earlier versions don't have the necessary hardware. On Gen3 SoCs, the CRC is
computed by the DISCOM module part of the VSP-D and VSP-DL.

The DISCOM is interfaced to the VSP through the UIF glue and appears as a VSP
entity with a sink pad and a source pad.

The series starts with a switch to SPDX license headers in patch 1/8, prompted
by a checkpatch.pl warning for a later patch that complained about missing
SPDX license headers. It then continues with cleanup and refactoring. Patches
2/8 and 3/8 prepare for DISCOM and UIF support by extending generic code to
make it usable for the UIF. Patch 4/8 documents a structure that will receive
new fields.

Patch 5/8 then extends the API exposed by the VSP driver to the DU driver to
support CRC computation configuration and reporting. The patch unfortunately
needs to touch both the VSP and DU drivers, so the whole series will need to
be merged through a single tree.

Patch 5/8 adds support for the DISCOM and UIF in the VSP driver, patch 7/8
integrates it in the DRM pipeline, and patch 8/8 finally implements the CRC
API in the DU driver to expose CRC computation to userspace.

The hardware supports computing the CRC at any arbitrary point in the
pipeline on a configurable window of the frame. This patch series supports CRC
computation on input planes or pipeline output, but on the full frame only.
Support for CRC window configuration can be added later if needed but will
require extending the userspace API, as the DRM/KMS CRC API doesn't support
this feature.

Compared to v1, the CRC source names for plane inputs are now constructed from
plane IDs instead of plane indices. This allows userspace to match CRC sources
with planes.

Note that exposing the DISCOM and UIF though the V4L2 API isn't supported as
the module is only found in VSP-D and VSP-DL instances that are not exposed
through V4L2. It is possible to expose those instances through V4L2 with a
small modification to the driver for testing purpose. If the need arises to
test DISCOM and UIF with such an out-of-tree patch, support for CRC reporting
through a V4L2 control can be added later without affecting how CRC is exposed
through the DRM/KMS API.

The patches are based on top of the "[PATCH v2 00/15] R-Car VSP1: Dynamically
assign blend units to display pipelines" patch series, itself based on top of
the Linux media master branch and scheduled for merge in v4.18. The new base
caused heavy conflicts, requiring this series to be merged through the V4L2
tree. Once the patches receive the necessary review I will ask Dave to ack the
merge plan.

For convenience the patches are available at

        git://linuxtv.org/pinchartl/media.git vsp1-discom-v2-20180423

The code has been tested through the kms-test-crc.py script part of the DU
test suite available at

        git://git.ideasonboard.com/renesas/kms-tests.git discom

Laurent Pinchart (8):
  v4l: vsp1: Use SPDX license headers
  v4l: vsp1: Share the CLU, LIF and LUT set_fmt pad operation code
  v4l: vsp1: Reset the crop and compose rectangles in the set_fmt helper
  v4l: vsp1: Document the vsp1_du_atomic_config structure
  v4l: vsp1: Extend the DU API to support CRC computation
  v4l: vsp1: Add support for the DISCOM entity
  v4l: vsp1: Integrate DISCOM in display pipeline
  drm: rcar-du: Add support for CRC computation

 drivers/gpu/drm/rcar-du/rcar_du_crtc.c    | 156 ++++++++++++++++-
 drivers/gpu/drm/rcar-du/rcar_du_crtc.h    |  19 +++
 drivers/gpu/drm/rcar-du/rcar_du_vsp.c     |  13 +-
 drivers/media/platform/vsp1/Makefile      |   2 +-
 drivers/media/platform/vsp1/vsp1.h        |  10 +-
 drivers/media/platform/vsp1/vsp1_brx.c    |   6 +-
 drivers/media/platform/vsp1/vsp1_brx.h    |   6 +-
 drivers/media/platform/vsp1/vsp1_clu.c    |  71 ++------
 drivers/media/platform/vsp1/vsp1_clu.h    |   6 +-
 drivers/media/platform/vsp1/vsp1_dl.c     |   8 +-
 drivers/media/platform/vsp1/vsp1_dl.h     |   6 +-
 drivers/media/platform/vsp1/vsp1_drm.c    | 127 ++++++++++++--
 drivers/media/platform/vsp1/vsp1_drm.h    |  20 ++-
 drivers/media/platform/vsp1/vsp1_drv.c    |  26 ++-
 drivers/media/platform/vsp1/vsp1_entity.c | 103 +++++++++++-
 drivers/media/platform/vsp1/vsp1_entity.h |  13 +-
 drivers/media/platform/vsp1/vsp1_hgo.c    |   6 +-
 drivers/media/platform/vsp1/vsp1_hgo.h    |   6 +-
 drivers/media/platform/vsp1/vsp1_hgt.c    |   6 +-
 drivers/media/platform/vsp1/vsp1_hgt.h    |   6 +-
 drivers/media/platform/vsp1/vsp1_histo.c  |  65 +------
 drivers/media/platform/vsp1/vsp1_histo.h  |   6 +-
 drivers/media/platform/vsp1/vsp1_hsit.c   |   6 +-
 drivers/media/platform/vsp1/vsp1_hsit.h   |   6 +-
 drivers/media/platform/vsp1/vsp1_lif.c    |  71 ++------
 drivers/media/platform/vsp1/vsp1_lif.h    |   6 +-
 drivers/media/platform/vsp1/vsp1_lut.c    |  71 ++------
 drivers/media/platform/vsp1/vsp1_lut.h    |   6 +-
 drivers/media/platform/vsp1/vsp1_pipe.c   |   6 +-
 drivers/media/platform/vsp1/vsp1_pipe.h   |   6 +-
 drivers/media/platform/vsp1/vsp1_regs.h   |  46 ++++-
 drivers/media/platform/vsp1/vsp1_rpf.c    |   6 +-
 drivers/media/platform/vsp1/vsp1_rwpf.c   |   6 +-
 drivers/media/platform/vsp1/vsp1_rwpf.h   |   6 +-
 drivers/media/platform/vsp1/vsp1_sru.c    |   6 +-
 drivers/media/platform/vsp1/vsp1_sru.h    |   6 +-
 drivers/media/platform/vsp1/vsp1_uds.c    |   6 +-
 drivers/media/platform/vsp1/vsp1_uds.h    |   6 +-
 drivers/media/platform/vsp1/vsp1_uif.c    | 271 ++++++++++++++++++++++++++++++
 drivers/media/platform/vsp1/vsp1_uif.h    |  32 ++++
 drivers/media/platform/vsp1/vsp1_video.c  |   6 +-
 drivers/media/platform/vsp1/vsp1_video.h  |   6 +-
 drivers/media/platform/vsp1/vsp1_wpf.c    |   6 +-
 include/media/vsp1.h                      |  39 ++++-
 44 files changed, 896 insertions(+), 417 deletions(-)
 create mode 100644 drivers/media/platform/vsp1/vsp1_uif.c
 create mode 100644 drivers/media/platform/vsp1/vsp1_uif.h

-- 
Regards,

Laurent Pinchart

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

* [PATCH v2 0/8] R-Car DU: Support CRC calculation
@ 2018-04-22 22:34 ` Laurent Pinchart
  0 siblings, 0 replies; 82+ messages in thread
From: Laurent Pinchart @ 2018-04-22 22:34 UTC (permalink / raw)
  To: linux-media, dri-devel; +Cc: linux-renesas-soc, Kieran Bingham

Hello,

This patch series adds support for CRC calculation to the rcar-du-drm driver.

CRC calculation is supported starting at the Renesas R-Car Gen3 SoCs, as
earlier versions don't have the necessary hardware. On Gen3 SoCs, the CRC is
computed by the DISCOM module part of the VSP-D and VSP-DL.

The DISCOM is interfaced to the VSP through the UIF glue and appears as a VSP
entity with a sink pad and a source pad.

The series starts with a switch to SPDX license headers in patch 1/8, prompted
by a checkpatch.pl warning for a later patch that complained about missing
SPDX license headers. It then continues with cleanup and refactoring. Patches
2/8 and 3/8 prepare for DISCOM and UIF support by extending generic code to
make it usable for the UIF. Patch 4/8 documents a structure that will receive
new fields.

Patch 5/8 then extends the API exposed by the VSP driver to the DU driver to
support CRC computation configuration and reporting. The patch unfortunately
needs to touch both the VSP and DU drivers, so the whole series will need to
be merged through a single tree.

Patch 5/8 adds support for the DISCOM and UIF in the VSP driver, patch 7/8
integrates it in the DRM pipeline, and patch 8/8 finally implements the CRC
API in the DU driver to expose CRC computation to userspace.

The hardware supports computing the CRC at any arbitrary point in the
pipeline on a configurable window of the frame. This patch series supports CRC
computation on input planes or pipeline output, but on the full frame only.
Support for CRC window configuration can be added later if needed but will
require extending the userspace API, as the DRM/KMS CRC API doesn't support
this feature.

Compared to v1, the CRC source names for plane inputs are now constructed from
plane IDs instead of plane indices. This allows userspace to match CRC sources
with planes.

Note that exposing the DISCOM and UIF though the V4L2 API isn't supported as
the module is only found in VSP-D and VSP-DL instances that are not exposed
through V4L2. It is possible to expose those instances through V4L2 with a
small modification to the driver for testing purpose. If the need arises to
test DISCOM and UIF with such an out-of-tree patch, support for CRC reporting
through a V4L2 control can be added later without affecting how CRC is exposed
through the DRM/KMS API.

The patches are based on top of the "[PATCH v2 00/15] R-Car VSP1: Dynamically
assign blend units to display pipelines" patch series, itself based on top of
the Linux media master branch and scheduled for merge in v4.18. The new base
caused heavy conflicts, requiring this series to be merged through the V4L2
tree. Once the patches receive the necessary review I will ask Dave to ack the
merge plan.

For convenience the patches are available at

        git://linuxtv.org/pinchartl/media.git vsp1-discom-v2-20180423

The code has been tested through the kms-test-crc.py script part of the DU
test suite available at

        git://git.ideasonboard.com/renesas/kms-tests.git discom

Laurent Pinchart (8):
  v4l: vsp1: Use SPDX license headers
  v4l: vsp1: Share the CLU, LIF and LUT set_fmt pad operation code
  v4l: vsp1: Reset the crop and compose rectangles in the set_fmt helper
  v4l: vsp1: Document the vsp1_du_atomic_config structure
  v4l: vsp1: Extend the DU API to support CRC computation
  v4l: vsp1: Add support for the DISCOM entity
  v4l: vsp1: Integrate DISCOM in display pipeline
  drm: rcar-du: Add support for CRC computation

 drivers/gpu/drm/rcar-du/rcar_du_crtc.c    | 156 ++++++++++++++++-
 drivers/gpu/drm/rcar-du/rcar_du_crtc.h    |  19 +++
 drivers/gpu/drm/rcar-du/rcar_du_vsp.c     |  13 +-
 drivers/media/platform/vsp1/Makefile      |   2 +-
 drivers/media/platform/vsp1/vsp1.h        |  10 +-
 drivers/media/platform/vsp1/vsp1_brx.c    |   6 +-
 drivers/media/platform/vsp1/vsp1_brx.h    |   6 +-
 drivers/media/platform/vsp1/vsp1_clu.c    |  71 ++------
 drivers/media/platform/vsp1/vsp1_clu.h    |   6 +-
 drivers/media/platform/vsp1/vsp1_dl.c     |   8 +-
 drivers/media/platform/vsp1/vsp1_dl.h     |   6 +-
 drivers/media/platform/vsp1/vsp1_drm.c    | 127 ++++++++++++--
 drivers/media/platform/vsp1/vsp1_drm.h    |  20 ++-
 drivers/media/platform/vsp1/vsp1_drv.c    |  26 ++-
 drivers/media/platform/vsp1/vsp1_entity.c | 103 +++++++++++-
 drivers/media/platform/vsp1/vsp1_entity.h |  13 +-
 drivers/media/platform/vsp1/vsp1_hgo.c    |   6 +-
 drivers/media/platform/vsp1/vsp1_hgo.h    |   6 +-
 drivers/media/platform/vsp1/vsp1_hgt.c    |   6 +-
 drivers/media/platform/vsp1/vsp1_hgt.h    |   6 +-
 drivers/media/platform/vsp1/vsp1_histo.c  |  65 +------
 drivers/media/platform/vsp1/vsp1_histo.h  |   6 +-
 drivers/media/platform/vsp1/vsp1_hsit.c   |   6 +-
 drivers/media/platform/vsp1/vsp1_hsit.h   |   6 +-
 drivers/media/platform/vsp1/vsp1_lif.c    |  71 ++------
 drivers/media/platform/vsp1/vsp1_lif.h    |   6 +-
 drivers/media/platform/vsp1/vsp1_lut.c    |  71 ++------
 drivers/media/platform/vsp1/vsp1_lut.h    |   6 +-
 drivers/media/platform/vsp1/vsp1_pipe.c   |   6 +-
 drivers/media/platform/vsp1/vsp1_pipe.h   |   6 +-
 drivers/media/platform/vsp1/vsp1_regs.h   |  46 ++++-
 drivers/media/platform/vsp1/vsp1_rpf.c    |   6 +-
 drivers/media/platform/vsp1/vsp1_rwpf.c   |   6 +-
 drivers/media/platform/vsp1/vsp1_rwpf.h   |   6 +-
 drivers/media/platform/vsp1/vsp1_sru.c    |   6 +-
 drivers/media/platform/vsp1/vsp1_sru.h    |   6 +-
 drivers/media/platform/vsp1/vsp1_uds.c    |   6 +-
 drivers/media/platform/vsp1/vsp1_uds.h    |   6 +-
 drivers/media/platform/vsp1/vsp1_uif.c    | 271 ++++++++++++++++++++++++++++++
 drivers/media/platform/vsp1/vsp1_uif.h    |  32 ++++
 drivers/media/platform/vsp1/vsp1_video.c  |   6 +-
 drivers/media/platform/vsp1/vsp1_video.h  |   6 +-
 drivers/media/platform/vsp1/vsp1_wpf.c    |   6 +-
 include/media/vsp1.h                      |  39 ++++-
 44 files changed, 896 insertions(+), 417 deletions(-)
 create mode 100644 drivers/media/platform/vsp1/vsp1_uif.c
 create mode 100644 drivers/media/platform/vsp1/vsp1_uif.h

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

* [PATCH v2 1/8] v4l: vsp1: Use SPDX license headers
  2018-04-22 22:34 ` Laurent Pinchart
@ 2018-04-22 22:34   ` Laurent Pinchart
  -1 siblings, 0 replies; 82+ messages in thread
From: Laurent Pinchart @ 2018-04-22 22:34 UTC (permalink / raw)
  To: linux-media, dri-devel; +Cc: linux-renesas-soc, Kieran Bingham

Adopt the SPDX license identifier headers to ease license compliance
management. All files in the driver are licensed under the GPLv2+ except
for the vsp1_regs.h file which is licensed under the GPLv2. This is
likely an oversight, but fixing this requires contacting the copyright
owners and is out of scope for this patch.

While at it fix the file descriptions to match file names where copy and
paste error occurred.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/platform/vsp1/vsp1.h        | 6 +-----
 drivers/media/platform/vsp1/vsp1_brx.c    | 6 +-----
 drivers/media/platform/vsp1/vsp1_brx.h    | 6 +-----
 drivers/media/platform/vsp1/vsp1_clu.c    | 6 +-----
 drivers/media/platform/vsp1/vsp1_clu.h    | 6 +-----
 drivers/media/platform/vsp1/vsp1_dl.c     | 8 ++------
 drivers/media/platform/vsp1/vsp1_dl.h     | 6 +-----
 drivers/media/platform/vsp1/vsp1_drm.c    | 8 ++------
 drivers/media/platform/vsp1/vsp1_drm.h    | 6 +-----
 drivers/media/platform/vsp1/vsp1_drv.c    | 6 +-----
 drivers/media/platform/vsp1/vsp1_entity.c | 6 +-----
 drivers/media/platform/vsp1/vsp1_entity.h | 6 +-----
 drivers/media/platform/vsp1/vsp1_hgo.c    | 6 +-----
 drivers/media/platform/vsp1/vsp1_hgo.h    | 6 +-----
 drivers/media/platform/vsp1/vsp1_hgt.c    | 6 +-----
 drivers/media/platform/vsp1/vsp1_hgt.h    | 6 +-----
 drivers/media/platform/vsp1/vsp1_histo.c  | 6 +-----
 drivers/media/platform/vsp1/vsp1_histo.h  | 6 +-----
 drivers/media/platform/vsp1/vsp1_hsit.c   | 6 +-----
 drivers/media/platform/vsp1/vsp1_hsit.h   | 6 +-----
 drivers/media/platform/vsp1/vsp1_lif.c    | 6 +-----
 drivers/media/platform/vsp1/vsp1_lif.h    | 6 +-----
 drivers/media/platform/vsp1/vsp1_lut.c    | 6 +-----
 drivers/media/platform/vsp1/vsp1_lut.h    | 6 +-----
 drivers/media/platform/vsp1/vsp1_pipe.c   | 6 +-----
 drivers/media/platform/vsp1/vsp1_pipe.h   | 6 +-----
 drivers/media/platform/vsp1/vsp1_regs.h   | 5 +----
 drivers/media/platform/vsp1/vsp1_rpf.c    | 6 +-----
 drivers/media/platform/vsp1/vsp1_rwpf.c   | 6 +-----
 drivers/media/platform/vsp1/vsp1_rwpf.h   | 6 +-----
 drivers/media/platform/vsp1/vsp1_sru.c    | 6 +-----
 drivers/media/platform/vsp1/vsp1_sru.h    | 6 +-----
 drivers/media/platform/vsp1/vsp1_uds.c    | 6 +-----
 drivers/media/platform/vsp1/vsp1_uds.h    | 6 +-----
 drivers/media/platform/vsp1/vsp1_video.c  | 6 +-----
 drivers/media/platform/vsp1/vsp1_video.h  | 6 +-----
 drivers/media/platform/vsp1/vsp1_wpf.c    | 6 +-----
 37 files changed, 39 insertions(+), 186 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1.h b/drivers/media/platform/vsp1/vsp1.h
index 894cc725c2d4..9cf4e1c4b036 100644
--- a/drivers/media/platform/vsp1/vsp1.h
+++ b/drivers/media/platform/vsp1/vsp1.h
@@ -1,14 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * vsp1.h  --  R-Car VSP1 Driver
  *
  * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 #ifndef __VSP1_H__
 #define __VSP1_H__
diff --git a/drivers/media/platform/vsp1/vsp1_brx.c b/drivers/media/platform/vsp1/vsp1_brx.c
index b4af1d546022..3beec18fd863 100644
--- a/drivers/media/platform/vsp1/vsp1_brx.c
+++ b/drivers/media/platform/vsp1/vsp1_brx.c
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * vsp1_brx.c  --  R-Car VSP1 Blend ROP Unit (BRU and BRS)
  *
  * Copyright (C) 2013 Renesas Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/device.h>
diff --git a/drivers/media/platform/vsp1/vsp1_brx.h b/drivers/media/platform/vsp1/vsp1_brx.h
index 927aa4254c0f..6abbb8c3343c 100644
--- a/drivers/media/platform/vsp1/vsp1_brx.h
+++ b/drivers/media/platform/vsp1/vsp1_brx.h
@@ -1,14 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * vsp1_brx.h  --  R-Car VSP1 Blend ROP Unit (BRU and BRS)
  *
  * Copyright (C) 2013 Renesas Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 #ifndef __VSP1_BRX_H__
 #define __VSP1_BRX_H__
diff --git a/drivers/media/platform/vsp1/vsp1_clu.c b/drivers/media/platform/vsp1/vsp1_clu.c
index f2fb26e5ab4e..9626b6308585 100644
--- a/drivers/media/platform/vsp1/vsp1_clu.c
+++ b/drivers/media/platform/vsp1/vsp1_clu.c
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * vsp1_clu.c  --  R-Car VSP1 Cubic Look-Up Table
  *
  * Copyright (C) 2015-2016 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/device.h>
diff --git a/drivers/media/platform/vsp1/vsp1_clu.h b/drivers/media/platform/vsp1/vsp1_clu.h
index 036e0a2f1a42..c45e6e707592 100644
--- a/drivers/media/platform/vsp1/vsp1_clu.h
+++ b/drivers/media/platform/vsp1/vsp1_clu.h
@@ -1,14 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * vsp1_clu.h  --  R-Car VSP1 Cubic Look-Up Table
  *
  * Copyright (C) 2015 Renesas Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 #ifndef __VSP1_CLU_H__
 #define __VSP1_CLU_H__
diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c
index 30ad491605ff..801dea475740 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
- * vsp1_dl.h  --  R-Car VSP1 Display List
+ * vsp1_dl.c  --  R-Car VSP1 Display List
  *
  * Copyright (C) 2015 Renesas Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/device.h>
diff --git a/drivers/media/platform/vsp1/vsp1_dl.h b/drivers/media/platform/vsp1/vsp1_dl.h
index 1a5bbd5ddb7b..e6279b1abd19 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.h
+++ b/drivers/media/platform/vsp1/vsp1_dl.h
@@ -1,14 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * vsp1_dl.h  --  R-Car VSP1 Display List
  *
  * Copyright (C) 2015 Renesas Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 #ifndef __VSP1_DL_H__
 #define __VSP1_DL_H__
diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c
index 095dc48aa25a..2b29a83dceb9 100644
--- a/drivers/media/platform/vsp1/vsp1_drm.c
+++ b/drivers/media/platform/vsp1/vsp1_drm.c
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
- * vsp1_drm.c  --  R-Car VSP1 DRM API
+ * vsp1_drm.c  --  R-Car VSP1 DRM/KMS Interface
  *
  * Copyright (C) 2015 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/device.h>
diff --git a/drivers/media/platform/vsp1/vsp1_drm.h b/drivers/media/platform/vsp1/vsp1_drm.h
index d738cc57f0e3..f4af1b2b12d6 100644
--- a/drivers/media/platform/vsp1/vsp1_drm.h
+++ b/drivers/media/platform/vsp1/vsp1_drm.h
@@ -1,14 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * vsp1_drm.h  --  R-Car VSP1 DRM/KMS Interface
  *
  * Copyright (C) 2015 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 #ifndef __VSP1_DRM_H__
 #define __VSP1_DRM_H__
diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
index f41cd70409db..331a2e0af0d3 100644
--- a/drivers/media/platform/vsp1/vsp1_drv.c
+++ b/drivers/media/platform/vsp1/vsp1_drv.c
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * vsp1_drv.c  --  R-Car VSP1 Driver
  *
  * Copyright (C) 2013-2015 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/clk.h>
diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c
index 54de15095709..72354caf5746 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.c
+++ b/drivers/media/platform/vsp1/vsp1_entity.c
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * vsp1_entity.c  --  R-Car VSP1 Base Entity
  *
  * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/device.h>
diff --git a/drivers/media/platform/vsp1/vsp1_entity.h b/drivers/media/platform/vsp1/vsp1_entity.h
index c26523c56c05..fb20a1578f3b 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.h
+++ b/drivers/media/platform/vsp1/vsp1_entity.h
@@ -1,14 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * vsp1_entity.h  --  R-Car VSP1 Base Entity
  *
  * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 #ifndef __VSP1_ENTITY_H__
 #define __VSP1_ENTITY_H__
diff --git a/drivers/media/platform/vsp1/vsp1_hgo.c b/drivers/media/platform/vsp1/vsp1_hgo.c
index 50309c053b78..d514807ccdf4 100644
--- a/drivers/media/platform/vsp1/vsp1_hgo.c
+++ b/drivers/media/platform/vsp1/vsp1_hgo.c
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * vsp1_hgo.c  --  R-Car VSP1 Histogram Generator 1D
  *
  * Copyright (C) 2016 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/device.h>
diff --git a/drivers/media/platform/vsp1/vsp1_hgo.h b/drivers/media/platform/vsp1/vsp1_hgo.h
index c6c0b7a80e0c..6b0c8580e1bf 100644
--- a/drivers/media/platform/vsp1/vsp1_hgo.h
+++ b/drivers/media/platform/vsp1/vsp1_hgo.h
@@ -1,14 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * vsp1_hgo.h  --  R-Car VSP1 Histogram Generator 1D
  *
  * Copyright (C) 2016 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 #ifndef __VSP1_HGO_H__
 #define __VSP1_HGO_H__
diff --git a/drivers/media/platform/vsp1/vsp1_hgt.c b/drivers/media/platform/vsp1/vsp1_hgt.c
index b5ce305e3e6f..18dc89f47c45 100644
--- a/drivers/media/platform/vsp1/vsp1_hgt.c
+++ b/drivers/media/platform/vsp1/vsp1_hgt.c
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * vsp1_hgt.c  --  R-Car VSP1 Histogram Generator 2D
  *
  * Copyright (C) 2016 Renesas Electronics Corporation
  *
  * Contact: Niklas Söderlund (niklas.soderlund@ragnatech.se)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/device.h>
diff --git a/drivers/media/platform/vsp1/vsp1_hgt.h b/drivers/media/platform/vsp1/vsp1_hgt.h
index 83f2e130942a..38ec237bdd2d 100644
--- a/drivers/media/platform/vsp1/vsp1_hgt.h
+++ b/drivers/media/platform/vsp1/vsp1_hgt.h
@@ -1,14 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * vsp1_hgt.h  --  R-Car VSP1 Histogram Generator 2D
  *
  * Copyright (C) 2016 Renesas Electronics Corporation
  *
  * Contact: Niklas Söderlund (niklas.soderlund@ragnatech.se)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 #ifndef __VSP1_HGT_H__
 #define __VSP1_HGT_H__
diff --git a/drivers/media/platform/vsp1/vsp1_histo.c b/drivers/media/platform/vsp1/vsp1_histo.c
index 8638ebc514b4..029181c1fb61 100644
--- a/drivers/media/platform/vsp1/vsp1_histo.c
+++ b/drivers/media/platform/vsp1/vsp1_histo.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * vsp1_histo.c  --  R-Car VSP1 Histogram API
  *
@@ -5,11 +6,6 @@
  * Copyright (C) 2016 Laurent Pinchart
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/device.h>
diff --git a/drivers/media/platform/vsp1/vsp1_histo.h b/drivers/media/platform/vsp1/vsp1_histo.h
index e774adbf251f..06f029846244 100644
--- a/drivers/media/platform/vsp1/vsp1_histo.h
+++ b/drivers/media/platform/vsp1/vsp1_histo.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * vsp1_histo.h  --  R-Car VSP1 Histogram API
  *
@@ -5,11 +6,6 @@
  * Copyright (C) 2016 Laurent Pinchart
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 #ifndef __VSP1_HISTO_H__
 #define __VSP1_HISTO_H__
diff --git a/drivers/media/platform/vsp1/vsp1_hsit.c b/drivers/media/platform/vsp1/vsp1_hsit.c
index 764d405345ee..7ba3535f3c9b 100644
--- a/drivers/media/platform/vsp1/vsp1_hsit.c
+++ b/drivers/media/platform/vsp1/vsp1_hsit.c
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * vsp1_hsit.c  --  R-Car VSP1 Hue Saturation value (Inverse) Transform
  *
  * Copyright (C) 2013 Renesas Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/device.h>
diff --git a/drivers/media/platform/vsp1/vsp1_hsit.h b/drivers/media/platform/vsp1/vsp1_hsit.h
index 82f1c8426900..a658b1aa49e7 100644
--- a/drivers/media/platform/vsp1/vsp1_hsit.h
+++ b/drivers/media/platform/vsp1/vsp1_hsit.h
@@ -1,14 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * vsp1_hsit.h  --  R-Car VSP1 Hue Saturation value (Inverse) Transform
  *
  * Copyright (C) 2013 Renesas Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 #ifndef __VSP1_HSIT_H__
 #define __VSP1_HSIT_H__
diff --git a/drivers/media/platform/vsp1/vsp1_lif.c b/drivers/media/platform/vsp1/vsp1_lif.c
index 704920753998..b20b842f06ba 100644
--- a/drivers/media/platform/vsp1/vsp1_lif.c
+++ b/drivers/media/platform/vsp1/vsp1_lif.c
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * vsp1_lif.c  --  R-Car VSP1 LCD Controller Interface
  *
  * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/device.h>
diff --git a/drivers/media/platform/vsp1/vsp1_lif.h b/drivers/media/platform/vsp1/vsp1_lif.h
index 3417339379b1..71a4eda9c2b2 100644
--- a/drivers/media/platform/vsp1/vsp1_lif.h
+++ b/drivers/media/platform/vsp1/vsp1_lif.h
@@ -1,14 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * vsp1_lif.h  --  R-Car VSP1 LCD Controller Interface
  *
  * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 #ifndef __VSP1_LIF_H__
 #define __VSP1_LIF_H__
diff --git a/drivers/media/platform/vsp1/vsp1_lut.c b/drivers/media/platform/vsp1/vsp1_lut.c
index c67cc60db0db..7bdabb311c6c 100644
--- a/drivers/media/platform/vsp1/vsp1_lut.c
+++ b/drivers/media/platform/vsp1/vsp1_lut.c
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * vsp1_lut.c  --  R-Car VSP1 Look-Up Table
  *
  * Copyright (C) 2013 Renesas Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/device.h>
diff --git a/drivers/media/platform/vsp1/vsp1_lut.h b/drivers/media/platform/vsp1/vsp1_lut.h
index f8c4e8f0a79d..dce2fdc315f6 100644
--- a/drivers/media/platform/vsp1/vsp1_lut.h
+++ b/drivers/media/platform/vsp1/vsp1_lut.h
@@ -1,14 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * vsp1_lut.h  --  R-Car VSP1 Look-Up Table
  *
  * Copyright (C) 2013 Renesas Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 #ifndef __VSP1_LUT_H__
 #define __VSP1_LUT_H__
diff --git a/drivers/media/platform/vsp1/vsp1_pipe.c b/drivers/media/platform/vsp1/vsp1_pipe.c
index 3fc5ecfa35e8..6fde4c0b9844 100644
--- a/drivers/media/platform/vsp1/vsp1_pipe.c
+++ b/drivers/media/platform/vsp1/vsp1_pipe.c
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * vsp1_pipe.c  --  R-Car VSP1 Pipeline
  *
  * Copyright (C) 2013-2015 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/delay.h>
diff --git a/drivers/media/platform/vsp1/vsp1_pipe.h b/drivers/media/platform/vsp1/vsp1_pipe.h
index 07ccd6b810c5..663d7fed7929 100644
--- a/drivers/media/platform/vsp1/vsp1_pipe.h
+++ b/drivers/media/platform/vsp1/vsp1_pipe.h
@@ -1,14 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * vsp1_pipe.h  --  R-Car VSP1 Pipeline
  *
  * Copyright (C) 2013-2015 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 #ifndef __VSP1_PIPE_H__
 #define __VSP1_PIPE_H__
diff --git a/drivers/media/platform/vsp1/vsp1_regs.h b/drivers/media/platform/vsp1/vsp1_regs.h
index dae0c1901297..3201ad4b77d4 100644
--- a/drivers/media/platform/vsp1/vsp1_regs.h
+++ b/drivers/media/platform/vsp1/vsp1_regs.h
@@ -1,13 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * vsp1_regs.h  --  R-Car VSP1 Registers Definitions
  *
  * Copyright (C) 2013 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
  */
 
 #ifndef __VSP1_REGS_H__
diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c
index 7e74c2015070..7005a4c6aa88 100644
--- a/drivers/media/platform/vsp1/vsp1_rpf.c
+++ b/drivers/media/platform/vsp1/vsp1_rpf.c
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * vsp1_rpf.c  --  R-Car VSP1 Read Pixel Formatter
  *
  * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/device.h>
diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.c b/drivers/media/platform/vsp1/vsp1_rwpf.c
index cfd8f1904fa6..049bdd958e56 100644
--- a/drivers/media/platform/vsp1/vsp1_rwpf.c
+++ b/drivers/media/platform/vsp1/vsp1_rwpf.c
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * vsp1_rwpf.c  --  R-Car VSP1 Read and Write Pixel Formatters
  *
  * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <media/v4l2-subdev.h>
diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.h b/drivers/media/platform/vsp1/vsp1_rwpf.h
index 915aeadb21dd..70742ecf766f 100644
--- a/drivers/media/platform/vsp1/vsp1_rwpf.h
+++ b/drivers/media/platform/vsp1/vsp1_rwpf.h
@@ -1,14 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * vsp1_rwpf.h  --  R-Car VSP1 Read and Write Pixel Formatters
  *
  * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 #ifndef __VSP1_RWPF_H__
 #define __VSP1_RWPF_H__
diff --git a/drivers/media/platform/vsp1/vsp1_sru.c b/drivers/media/platform/vsp1/vsp1_sru.c
index 51e5691187c3..44cb9b134a19 100644
--- a/drivers/media/platform/vsp1/vsp1_sru.c
+++ b/drivers/media/platform/vsp1/vsp1_sru.c
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * vsp1_sru.c  --  R-Car VSP1 Super Resolution Unit
  *
  * Copyright (C) 2013 Renesas Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/device.h>
diff --git a/drivers/media/platform/vsp1/vsp1_sru.h b/drivers/media/platform/vsp1/vsp1_sru.h
index 85e241457af2..ddb00eadd1ea 100644
--- a/drivers/media/platform/vsp1/vsp1_sru.h
+++ b/drivers/media/platform/vsp1/vsp1_sru.h
@@ -1,14 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * vsp1_sru.h  --  R-Car VSP1 Super Resolution Unit
  *
  * Copyright (C) 2013 Renesas Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 #ifndef __VSP1_SRU_H__
 #define __VSP1_SRU_H__
diff --git a/drivers/media/platform/vsp1/vsp1_uds.c b/drivers/media/platform/vsp1/vsp1_uds.c
index 72f72a9d2152..e5afd69df939 100644
--- a/drivers/media/platform/vsp1/vsp1_uds.c
+++ b/drivers/media/platform/vsp1/vsp1_uds.c
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * vsp1_uds.c  --  R-Car VSP1 Up and Down Scaler
  *
  * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/device.h>
diff --git a/drivers/media/platform/vsp1/vsp1_uds.h b/drivers/media/platform/vsp1/vsp1_uds.h
index 7bf3cdcffc65..2cd9f4b95442 100644
--- a/drivers/media/platform/vsp1/vsp1_uds.h
+++ b/drivers/media/platform/vsp1/vsp1_uds.h
@@ -1,14 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * vsp1_uds.h  --  R-Car VSP1 Up and Down Scaler
  *
  * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 #ifndef __VSP1_UDS_H__
 #define __VSP1_UDS_H__
diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
index 2b1c94ffc6f5..c8c12223a267 100644
--- a/drivers/media/platform/vsp1/vsp1_video.c
+++ b/drivers/media/platform/vsp1/vsp1_video.c
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * vsp1_video.c  --  R-Car VSP1 Video Node
  *
  * Copyright (C) 2013-2015 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/list.h>
diff --git a/drivers/media/platform/vsp1/vsp1_video.h b/drivers/media/platform/vsp1/vsp1_video.h
index 50ea7f02205f..75a5a65c66fe 100644
--- a/drivers/media/platform/vsp1/vsp1_video.h
+++ b/drivers/media/platform/vsp1/vsp1_video.h
@@ -1,14 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * vsp1_video.h  --  R-Car VSP1 Video Node
  *
  * Copyright (C) 2013-2015 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 #ifndef __VSP1_VIDEO_H__
 #define __VSP1_VIDEO_H__
diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c
index 53858d100228..65ed2f849551 100644
--- a/drivers/media/platform/vsp1/vsp1_wpf.c
+++ b/drivers/media/platform/vsp1/vsp1_wpf.c
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * vsp1_wpf.c  --  R-Car VSP1 Write Pixel Formatter
  *
  * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/device.h>
-- 
Regards,

Laurent Pinchart

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

* [PATCH v2 1/8] v4l: vsp1: Use SPDX license headers
@ 2018-04-22 22:34   ` Laurent Pinchart
  0 siblings, 0 replies; 82+ messages in thread
From: Laurent Pinchart @ 2018-04-22 22:34 UTC (permalink / raw)
  To: linux-media, dri-devel; +Cc: linux-renesas-soc, Kieran Bingham

Adopt the SPDX license identifier headers to ease license compliance
management. All files in the driver are licensed under the GPLv2+ except
for the vsp1_regs.h file which is licensed under the GPLv2. This is
likely an oversight, but fixing this requires contacting the copyright
owners and is out of scope for this patch.

While at it fix the file descriptions to match file names where copy and
paste error occurred.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/platform/vsp1/vsp1.h        | 6 +-----
 drivers/media/platform/vsp1/vsp1_brx.c    | 6 +-----
 drivers/media/platform/vsp1/vsp1_brx.h    | 6 +-----
 drivers/media/platform/vsp1/vsp1_clu.c    | 6 +-----
 drivers/media/platform/vsp1/vsp1_clu.h    | 6 +-----
 drivers/media/platform/vsp1/vsp1_dl.c     | 8 ++------
 drivers/media/platform/vsp1/vsp1_dl.h     | 6 +-----
 drivers/media/platform/vsp1/vsp1_drm.c    | 8 ++------
 drivers/media/platform/vsp1/vsp1_drm.h    | 6 +-----
 drivers/media/platform/vsp1/vsp1_drv.c    | 6 +-----
 drivers/media/platform/vsp1/vsp1_entity.c | 6 +-----
 drivers/media/platform/vsp1/vsp1_entity.h | 6 +-----
 drivers/media/platform/vsp1/vsp1_hgo.c    | 6 +-----
 drivers/media/platform/vsp1/vsp1_hgo.h    | 6 +-----
 drivers/media/platform/vsp1/vsp1_hgt.c    | 6 +-----
 drivers/media/platform/vsp1/vsp1_hgt.h    | 6 +-----
 drivers/media/platform/vsp1/vsp1_histo.c  | 6 +-----
 drivers/media/platform/vsp1/vsp1_histo.h  | 6 +-----
 drivers/media/platform/vsp1/vsp1_hsit.c   | 6 +-----
 drivers/media/platform/vsp1/vsp1_hsit.h   | 6 +-----
 drivers/media/platform/vsp1/vsp1_lif.c    | 6 +-----
 drivers/media/platform/vsp1/vsp1_lif.h    | 6 +-----
 drivers/media/platform/vsp1/vsp1_lut.c    | 6 +-----
 drivers/media/platform/vsp1/vsp1_lut.h    | 6 +-----
 drivers/media/platform/vsp1/vsp1_pipe.c   | 6 +-----
 drivers/media/platform/vsp1/vsp1_pipe.h   | 6 +-----
 drivers/media/platform/vsp1/vsp1_regs.h   | 5 +----
 drivers/media/platform/vsp1/vsp1_rpf.c    | 6 +-----
 drivers/media/platform/vsp1/vsp1_rwpf.c   | 6 +-----
 drivers/media/platform/vsp1/vsp1_rwpf.h   | 6 +-----
 drivers/media/platform/vsp1/vsp1_sru.c    | 6 +-----
 drivers/media/platform/vsp1/vsp1_sru.h    | 6 +-----
 drivers/media/platform/vsp1/vsp1_uds.c    | 6 +-----
 drivers/media/platform/vsp1/vsp1_uds.h    | 6 +-----
 drivers/media/platform/vsp1/vsp1_video.c  | 6 +-----
 drivers/media/platform/vsp1/vsp1_video.h  | 6 +-----
 drivers/media/platform/vsp1/vsp1_wpf.c    | 6 +-----
 37 files changed, 39 insertions(+), 186 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1.h b/drivers/media/platform/vsp1/vsp1.h
index 894cc725c2d4..9cf4e1c4b036 100644
--- a/drivers/media/platform/vsp1/vsp1.h
+++ b/drivers/media/platform/vsp1/vsp1.h
@@ -1,14 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * vsp1.h  --  R-Car VSP1 Driver
  *
  * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 #ifndef __VSP1_H__
 #define __VSP1_H__
diff --git a/drivers/media/platform/vsp1/vsp1_brx.c b/drivers/media/platform/vsp1/vsp1_brx.c
index b4af1d546022..3beec18fd863 100644
--- a/drivers/media/platform/vsp1/vsp1_brx.c
+++ b/drivers/media/platform/vsp1/vsp1_brx.c
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * vsp1_brx.c  --  R-Car VSP1 Blend ROP Unit (BRU and BRS)
  *
  * Copyright (C) 2013 Renesas Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/device.h>
diff --git a/drivers/media/platform/vsp1/vsp1_brx.h b/drivers/media/platform/vsp1/vsp1_brx.h
index 927aa4254c0f..6abbb8c3343c 100644
--- a/drivers/media/platform/vsp1/vsp1_brx.h
+++ b/drivers/media/platform/vsp1/vsp1_brx.h
@@ -1,14 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * vsp1_brx.h  --  R-Car VSP1 Blend ROP Unit (BRU and BRS)
  *
  * Copyright (C) 2013 Renesas Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 #ifndef __VSP1_BRX_H__
 #define __VSP1_BRX_H__
diff --git a/drivers/media/platform/vsp1/vsp1_clu.c b/drivers/media/platform/vsp1/vsp1_clu.c
index f2fb26e5ab4e..9626b6308585 100644
--- a/drivers/media/platform/vsp1/vsp1_clu.c
+++ b/drivers/media/platform/vsp1/vsp1_clu.c
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * vsp1_clu.c  --  R-Car VSP1 Cubic Look-Up Table
  *
  * Copyright (C) 2015-2016 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/device.h>
diff --git a/drivers/media/platform/vsp1/vsp1_clu.h b/drivers/media/platform/vsp1/vsp1_clu.h
index 036e0a2f1a42..c45e6e707592 100644
--- a/drivers/media/platform/vsp1/vsp1_clu.h
+++ b/drivers/media/platform/vsp1/vsp1_clu.h
@@ -1,14 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * vsp1_clu.h  --  R-Car VSP1 Cubic Look-Up Table
  *
  * Copyright (C) 2015 Renesas Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 #ifndef __VSP1_CLU_H__
 #define __VSP1_CLU_H__
diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c
index 30ad491605ff..801dea475740 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
- * vsp1_dl.h  --  R-Car VSP1 Display List
+ * vsp1_dl.c  --  R-Car VSP1 Display List
  *
  * Copyright (C) 2015 Renesas Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/device.h>
diff --git a/drivers/media/platform/vsp1/vsp1_dl.h b/drivers/media/platform/vsp1/vsp1_dl.h
index 1a5bbd5ddb7b..e6279b1abd19 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.h
+++ b/drivers/media/platform/vsp1/vsp1_dl.h
@@ -1,14 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * vsp1_dl.h  --  R-Car VSP1 Display List
  *
  * Copyright (C) 2015 Renesas Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 #ifndef __VSP1_DL_H__
 #define __VSP1_DL_H__
diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c
index 095dc48aa25a..2b29a83dceb9 100644
--- a/drivers/media/platform/vsp1/vsp1_drm.c
+++ b/drivers/media/platform/vsp1/vsp1_drm.c
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
- * vsp1_drm.c  --  R-Car VSP1 DRM API
+ * vsp1_drm.c  --  R-Car VSP1 DRM/KMS Interface
  *
  * Copyright (C) 2015 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/device.h>
diff --git a/drivers/media/platform/vsp1/vsp1_drm.h b/drivers/media/platform/vsp1/vsp1_drm.h
index d738cc57f0e3..f4af1b2b12d6 100644
--- a/drivers/media/platform/vsp1/vsp1_drm.h
+++ b/drivers/media/platform/vsp1/vsp1_drm.h
@@ -1,14 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * vsp1_drm.h  --  R-Car VSP1 DRM/KMS Interface
  *
  * Copyright (C) 2015 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 #ifndef __VSP1_DRM_H__
 #define __VSP1_DRM_H__
diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
index f41cd70409db..331a2e0af0d3 100644
--- a/drivers/media/platform/vsp1/vsp1_drv.c
+++ b/drivers/media/platform/vsp1/vsp1_drv.c
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * vsp1_drv.c  --  R-Car VSP1 Driver
  *
  * Copyright (C) 2013-2015 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/clk.h>
diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c
index 54de15095709..72354caf5746 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.c
+++ b/drivers/media/platform/vsp1/vsp1_entity.c
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * vsp1_entity.c  --  R-Car VSP1 Base Entity
  *
  * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/device.h>
diff --git a/drivers/media/platform/vsp1/vsp1_entity.h b/drivers/media/platform/vsp1/vsp1_entity.h
index c26523c56c05..fb20a1578f3b 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.h
+++ b/drivers/media/platform/vsp1/vsp1_entity.h
@@ -1,14 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * vsp1_entity.h  --  R-Car VSP1 Base Entity
  *
  * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 #ifndef __VSP1_ENTITY_H__
 #define __VSP1_ENTITY_H__
diff --git a/drivers/media/platform/vsp1/vsp1_hgo.c b/drivers/media/platform/vsp1/vsp1_hgo.c
index 50309c053b78..d514807ccdf4 100644
--- a/drivers/media/platform/vsp1/vsp1_hgo.c
+++ b/drivers/media/platform/vsp1/vsp1_hgo.c
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * vsp1_hgo.c  --  R-Car VSP1 Histogram Generator 1D
  *
  * Copyright (C) 2016 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/device.h>
diff --git a/drivers/media/platform/vsp1/vsp1_hgo.h b/drivers/media/platform/vsp1/vsp1_hgo.h
index c6c0b7a80e0c..6b0c8580e1bf 100644
--- a/drivers/media/platform/vsp1/vsp1_hgo.h
+++ b/drivers/media/platform/vsp1/vsp1_hgo.h
@@ -1,14 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * vsp1_hgo.h  --  R-Car VSP1 Histogram Generator 1D
  *
  * Copyright (C) 2016 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 #ifndef __VSP1_HGO_H__
 #define __VSP1_HGO_H__
diff --git a/drivers/media/platform/vsp1/vsp1_hgt.c b/drivers/media/platform/vsp1/vsp1_hgt.c
index b5ce305e3e6f..18dc89f47c45 100644
--- a/drivers/media/platform/vsp1/vsp1_hgt.c
+++ b/drivers/media/platform/vsp1/vsp1_hgt.c
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * vsp1_hgt.c  --  R-Car VSP1 Histogram Generator 2D
  *
  * Copyright (C) 2016 Renesas Electronics Corporation
  *
  * Contact: Niklas Söderlund (niklas.soderlund@ragnatech.se)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/device.h>
diff --git a/drivers/media/platform/vsp1/vsp1_hgt.h b/drivers/media/platform/vsp1/vsp1_hgt.h
index 83f2e130942a..38ec237bdd2d 100644
--- a/drivers/media/platform/vsp1/vsp1_hgt.h
+++ b/drivers/media/platform/vsp1/vsp1_hgt.h
@@ -1,14 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * vsp1_hgt.h  --  R-Car VSP1 Histogram Generator 2D
  *
  * Copyright (C) 2016 Renesas Electronics Corporation
  *
  * Contact: Niklas Söderlund (niklas.soderlund@ragnatech.se)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 #ifndef __VSP1_HGT_H__
 #define __VSP1_HGT_H__
diff --git a/drivers/media/platform/vsp1/vsp1_histo.c b/drivers/media/platform/vsp1/vsp1_histo.c
index 8638ebc514b4..029181c1fb61 100644
--- a/drivers/media/platform/vsp1/vsp1_histo.c
+++ b/drivers/media/platform/vsp1/vsp1_histo.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * vsp1_histo.c  --  R-Car VSP1 Histogram API
  *
@@ -5,11 +6,6 @@
  * Copyright (C) 2016 Laurent Pinchart
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/device.h>
diff --git a/drivers/media/platform/vsp1/vsp1_histo.h b/drivers/media/platform/vsp1/vsp1_histo.h
index e774adbf251f..06f029846244 100644
--- a/drivers/media/platform/vsp1/vsp1_histo.h
+++ b/drivers/media/platform/vsp1/vsp1_histo.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * vsp1_histo.h  --  R-Car VSP1 Histogram API
  *
@@ -5,11 +6,6 @@
  * Copyright (C) 2016 Laurent Pinchart
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 #ifndef __VSP1_HISTO_H__
 #define __VSP1_HISTO_H__
diff --git a/drivers/media/platform/vsp1/vsp1_hsit.c b/drivers/media/platform/vsp1/vsp1_hsit.c
index 764d405345ee..7ba3535f3c9b 100644
--- a/drivers/media/platform/vsp1/vsp1_hsit.c
+++ b/drivers/media/platform/vsp1/vsp1_hsit.c
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * vsp1_hsit.c  --  R-Car VSP1 Hue Saturation value (Inverse) Transform
  *
  * Copyright (C) 2013 Renesas Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/device.h>
diff --git a/drivers/media/platform/vsp1/vsp1_hsit.h b/drivers/media/platform/vsp1/vsp1_hsit.h
index 82f1c8426900..a658b1aa49e7 100644
--- a/drivers/media/platform/vsp1/vsp1_hsit.h
+++ b/drivers/media/platform/vsp1/vsp1_hsit.h
@@ -1,14 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * vsp1_hsit.h  --  R-Car VSP1 Hue Saturation value (Inverse) Transform
  *
  * Copyright (C) 2013 Renesas Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 #ifndef __VSP1_HSIT_H__
 #define __VSP1_HSIT_H__
diff --git a/drivers/media/platform/vsp1/vsp1_lif.c b/drivers/media/platform/vsp1/vsp1_lif.c
index 704920753998..b20b842f06ba 100644
--- a/drivers/media/platform/vsp1/vsp1_lif.c
+++ b/drivers/media/platform/vsp1/vsp1_lif.c
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * vsp1_lif.c  --  R-Car VSP1 LCD Controller Interface
  *
  * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/device.h>
diff --git a/drivers/media/platform/vsp1/vsp1_lif.h b/drivers/media/platform/vsp1/vsp1_lif.h
index 3417339379b1..71a4eda9c2b2 100644
--- a/drivers/media/platform/vsp1/vsp1_lif.h
+++ b/drivers/media/platform/vsp1/vsp1_lif.h
@@ -1,14 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * vsp1_lif.h  --  R-Car VSP1 LCD Controller Interface
  *
  * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 #ifndef __VSP1_LIF_H__
 #define __VSP1_LIF_H__
diff --git a/drivers/media/platform/vsp1/vsp1_lut.c b/drivers/media/platform/vsp1/vsp1_lut.c
index c67cc60db0db..7bdabb311c6c 100644
--- a/drivers/media/platform/vsp1/vsp1_lut.c
+++ b/drivers/media/platform/vsp1/vsp1_lut.c
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * vsp1_lut.c  --  R-Car VSP1 Look-Up Table
  *
  * Copyright (C) 2013 Renesas Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/device.h>
diff --git a/drivers/media/platform/vsp1/vsp1_lut.h b/drivers/media/platform/vsp1/vsp1_lut.h
index f8c4e8f0a79d..dce2fdc315f6 100644
--- a/drivers/media/platform/vsp1/vsp1_lut.h
+++ b/drivers/media/platform/vsp1/vsp1_lut.h
@@ -1,14 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * vsp1_lut.h  --  R-Car VSP1 Look-Up Table
  *
  * Copyright (C) 2013 Renesas Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 #ifndef __VSP1_LUT_H__
 #define __VSP1_LUT_H__
diff --git a/drivers/media/platform/vsp1/vsp1_pipe.c b/drivers/media/platform/vsp1/vsp1_pipe.c
index 3fc5ecfa35e8..6fde4c0b9844 100644
--- a/drivers/media/platform/vsp1/vsp1_pipe.c
+++ b/drivers/media/platform/vsp1/vsp1_pipe.c
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * vsp1_pipe.c  --  R-Car VSP1 Pipeline
  *
  * Copyright (C) 2013-2015 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/delay.h>
diff --git a/drivers/media/platform/vsp1/vsp1_pipe.h b/drivers/media/platform/vsp1/vsp1_pipe.h
index 07ccd6b810c5..663d7fed7929 100644
--- a/drivers/media/platform/vsp1/vsp1_pipe.h
+++ b/drivers/media/platform/vsp1/vsp1_pipe.h
@@ -1,14 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * vsp1_pipe.h  --  R-Car VSP1 Pipeline
  *
  * Copyright (C) 2013-2015 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 #ifndef __VSP1_PIPE_H__
 #define __VSP1_PIPE_H__
diff --git a/drivers/media/platform/vsp1/vsp1_regs.h b/drivers/media/platform/vsp1/vsp1_regs.h
index dae0c1901297..3201ad4b77d4 100644
--- a/drivers/media/platform/vsp1/vsp1_regs.h
+++ b/drivers/media/platform/vsp1/vsp1_regs.h
@@ -1,13 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * vsp1_regs.h  --  R-Car VSP1 Registers Definitions
  *
  * Copyright (C) 2013 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
  */
 
 #ifndef __VSP1_REGS_H__
diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c
index 7e74c2015070..7005a4c6aa88 100644
--- a/drivers/media/platform/vsp1/vsp1_rpf.c
+++ b/drivers/media/platform/vsp1/vsp1_rpf.c
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * vsp1_rpf.c  --  R-Car VSP1 Read Pixel Formatter
  *
  * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/device.h>
diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.c b/drivers/media/platform/vsp1/vsp1_rwpf.c
index cfd8f1904fa6..049bdd958e56 100644
--- a/drivers/media/platform/vsp1/vsp1_rwpf.c
+++ b/drivers/media/platform/vsp1/vsp1_rwpf.c
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * vsp1_rwpf.c  --  R-Car VSP1 Read and Write Pixel Formatters
  *
  * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <media/v4l2-subdev.h>
diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.h b/drivers/media/platform/vsp1/vsp1_rwpf.h
index 915aeadb21dd..70742ecf766f 100644
--- a/drivers/media/platform/vsp1/vsp1_rwpf.h
+++ b/drivers/media/platform/vsp1/vsp1_rwpf.h
@@ -1,14 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * vsp1_rwpf.h  --  R-Car VSP1 Read and Write Pixel Formatters
  *
  * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 #ifndef __VSP1_RWPF_H__
 #define __VSP1_RWPF_H__
diff --git a/drivers/media/platform/vsp1/vsp1_sru.c b/drivers/media/platform/vsp1/vsp1_sru.c
index 51e5691187c3..44cb9b134a19 100644
--- a/drivers/media/platform/vsp1/vsp1_sru.c
+++ b/drivers/media/platform/vsp1/vsp1_sru.c
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * vsp1_sru.c  --  R-Car VSP1 Super Resolution Unit
  *
  * Copyright (C) 2013 Renesas Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/device.h>
diff --git a/drivers/media/platform/vsp1/vsp1_sru.h b/drivers/media/platform/vsp1/vsp1_sru.h
index 85e241457af2..ddb00eadd1ea 100644
--- a/drivers/media/platform/vsp1/vsp1_sru.h
+++ b/drivers/media/platform/vsp1/vsp1_sru.h
@@ -1,14 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * vsp1_sru.h  --  R-Car VSP1 Super Resolution Unit
  *
  * Copyright (C) 2013 Renesas Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 #ifndef __VSP1_SRU_H__
 #define __VSP1_SRU_H__
diff --git a/drivers/media/platform/vsp1/vsp1_uds.c b/drivers/media/platform/vsp1/vsp1_uds.c
index 72f72a9d2152..e5afd69df939 100644
--- a/drivers/media/platform/vsp1/vsp1_uds.c
+++ b/drivers/media/platform/vsp1/vsp1_uds.c
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * vsp1_uds.c  --  R-Car VSP1 Up and Down Scaler
  *
  * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/device.h>
diff --git a/drivers/media/platform/vsp1/vsp1_uds.h b/drivers/media/platform/vsp1/vsp1_uds.h
index 7bf3cdcffc65..2cd9f4b95442 100644
--- a/drivers/media/platform/vsp1/vsp1_uds.h
+++ b/drivers/media/platform/vsp1/vsp1_uds.h
@@ -1,14 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * vsp1_uds.h  --  R-Car VSP1 Up and Down Scaler
  *
  * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 #ifndef __VSP1_UDS_H__
 #define __VSP1_UDS_H__
diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
index 2b1c94ffc6f5..c8c12223a267 100644
--- a/drivers/media/platform/vsp1/vsp1_video.c
+++ b/drivers/media/platform/vsp1/vsp1_video.c
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * vsp1_video.c  --  R-Car VSP1 Video Node
  *
  * Copyright (C) 2013-2015 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/list.h>
diff --git a/drivers/media/platform/vsp1/vsp1_video.h b/drivers/media/platform/vsp1/vsp1_video.h
index 50ea7f02205f..75a5a65c66fe 100644
--- a/drivers/media/platform/vsp1/vsp1_video.h
+++ b/drivers/media/platform/vsp1/vsp1_video.h
@@ -1,14 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * vsp1_video.h  --  R-Car VSP1 Video Node
  *
  * Copyright (C) 2013-2015 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 #ifndef __VSP1_VIDEO_H__
 #define __VSP1_VIDEO_H__
diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c
index 53858d100228..65ed2f849551 100644
--- a/drivers/media/platform/vsp1/vsp1_wpf.c
+++ b/drivers/media/platform/vsp1/vsp1_wpf.c
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * vsp1_wpf.c  --  R-Car VSP1 Write Pixel Formatter
  *
  * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/device.h>
-- 
Regards,

Laurent Pinchart

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

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

* [PATCH v2 2/8] v4l: vsp1: Share the CLU, LIF and LUT set_fmt pad operation code
  2018-04-22 22:34 ` Laurent Pinchart
@ 2018-04-22 22:34   ` Laurent Pinchart
  -1 siblings, 0 replies; 82+ messages in thread
From: Laurent Pinchart @ 2018-04-22 22:34 UTC (permalink / raw)
  To: linux-media, dri-devel; +Cc: linux-renesas-soc, Kieran Bingham

The implementation of the set_fmt pad operation is identical in the
three modules. Move it to a generic helper function.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/platform/vsp1/vsp1_clu.c    | 65 +++++----------------------
 drivers/media/platform/vsp1/vsp1_entity.c | 75 +++++++++++++++++++++++++++++++
 drivers/media/platform/vsp1/vsp1_entity.h |  6 +++
 drivers/media/platform/vsp1/vsp1_lif.c    | 65 +++++----------------------
 drivers/media/platform/vsp1/vsp1_lut.c    | 65 +++++----------------------
 5 files changed, 116 insertions(+), 160 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1_clu.c b/drivers/media/platform/vsp1/vsp1_clu.c
index 9626b6308585..96a448e1504c 100644
--- a/drivers/media/platform/vsp1/vsp1_clu.c
+++ b/drivers/media/platform/vsp1/vsp1_clu.c
@@ -114,18 +114,18 @@ static const struct v4l2_ctrl_config clu_mode_control = {
  * V4L2 Subdevice Pad Operations
  */
 
+static const unsigned int clu_codes[] = {
+	MEDIA_BUS_FMT_ARGB8888_1X32,
+	MEDIA_BUS_FMT_AHSV8888_1X32,
+	MEDIA_BUS_FMT_AYUV8_1X32,
+};
+
 static int clu_enum_mbus_code(struct v4l2_subdev *subdev,
 			      struct v4l2_subdev_pad_config *cfg,
 			      struct v4l2_subdev_mbus_code_enum *code)
 {
-	static const unsigned int codes[] = {
-		MEDIA_BUS_FMT_ARGB8888_1X32,
-		MEDIA_BUS_FMT_AHSV8888_1X32,
-		MEDIA_BUS_FMT_AYUV8_1X32,
-	};
-
-	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, codes,
-					  ARRAY_SIZE(codes));
+	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, clu_codes,
+					  ARRAY_SIZE(clu_codes));
 }
 
 static int clu_enum_frame_size(struct v4l2_subdev *subdev,
@@ -141,51 +141,10 @@ static int clu_set_format(struct v4l2_subdev *subdev,
 			  struct v4l2_subdev_pad_config *cfg,
 			  struct v4l2_subdev_format *fmt)
 {
-	struct vsp1_clu *clu = to_clu(subdev);
-	struct v4l2_subdev_pad_config *config;
-	struct v4l2_mbus_framefmt *format;
-	int ret = 0;
-
-	mutex_lock(&clu->entity.lock);
-
-	config = vsp1_entity_get_pad_config(&clu->entity, cfg, fmt->which);
-	if (!config) {
-		ret = -EINVAL;
-		goto done;
-	}
-
-	/* Default to YUV if the requested format is not supported. */
-	if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
-	    fmt->format.code != MEDIA_BUS_FMT_AHSV8888_1X32 &&
-	    fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32)
-		fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32;
-
-	format = vsp1_entity_get_pad_format(&clu->entity, config, fmt->pad);
-
-	if (fmt->pad == CLU_PAD_SOURCE) {
-		/* The CLU output format can't be modified. */
-		fmt->format = *format;
-		goto done;
-	}
-
-	format->code = fmt->format.code;
-	format->width = clamp_t(unsigned int, fmt->format.width,
-				CLU_MIN_SIZE, CLU_MAX_SIZE);
-	format->height = clamp_t(unsigned int, fmt->format.height,
-				 CLU_MIN_SIZE, CLU_MAX_SIZE);
-	format->field = V4L2_FIELD_NONE;
-	format->colorspace = V4L2_COLORSPACE_SRGB;
-
-	fmt->format = *format;
-
-	/* Propagate the format to the source pad. */
-	format = vsp1_entity_get_pad_format(&clu->entity, config,
-					    CLU_PAD_SOURCE);
-	*format = fmt->format;
-
-done:
-	mutex_unlock(&clu->entity.lock);
-	return ret;
+	return vsp1_subdev_set_pad_format(subdev, cfg, fmt, clu_codes,
+					  ARRAY_SIZE(clu_codes),
+					  CLU_MIN_SIZE, CLU_MIN_SIZE,
+					  CLU_MAX_SIZE, CLU_MAX_SIZE);
 }
 
 /* -----------------------------------------------------------------------------
diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c
index 72354caf5746..239df047efd0 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.c
+++ b/drivers/media/platform/vsp1/vsp1_entity.c
@@ -307,6 +307,81 @@ int vsp1_subdev_enum_frame_size(struct v4l2_subdev *subdev,
 	return ret;
 }
 
+/*
+ * vsp1_subdev_set_pad_format - Subdev pad set_fmt handler
+ * @subdev: V4L2 subdevice
+ * @cfg: V4L2 subdev pad configuration
+ * @fmt: V4L2 subdev format
+ * @codes: Array of supported media bus codes
+ * @ncodes: Number of supported media bus codes
+ * @min_width: Minimum image width
+ * @min_height: Minimum image height
+ * @max_width: Maximum image width
+ * @max_height: Maximum image height
+ *
+ * This function implements the subdev set_fmt pad operation for entities that
+ * do not support scaling or cropping. It defaults to the first supplied media
+ * bus code if the requested code isn't supported, clamps the size to the
+ * supplied minimum and maximum, and propagates the sink pad format to the
+ * source pad.
+ */
+int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev,
+			       struct v4l2_subdev_pad_config *cfg,
+			       struct v4l2_subdev_format *fmt,
+			       const unsigned int *codes, unsigned int ncodes,
+			       unsigned int min_width, unsigned int min_height,
+			       unsigned int max_width, unsigned int max_height)
+{
+	struct vsp1_entity *entity = to_vsp1_entity(subdev);
+	struct v4l2_subdev_pad_config *config;
+	struct v4l2_mbus_framefmt *format;
+	unsigned int i;
+	int ret = 0;
+
+	mutex_lock(&entity->lock);
+
+	config = vsp1_entity_get_pad_config(entity, cfg, fmt->which);
+	if (!config) {
+		ret = -EINVAL;
+		goto done;
+	}
+
+	format = vsp1_entity_get_pad_format(entity, config, fmt->pad);
+
+	if (fmt->pad != 0) {
+		/* The output format can't be modified. */
+		fmt->format = *format;
+		goto done;
+	}
+
+	/*
+	 * Default to the first media bus code if the requested format is not
+	 * supported.
+	 */
+	for (i = 0; i < ncodes; ++i) {
+		if (fmt->format.code == codes[i])
+			break;
+	}
+
+	format->code = i < ncodes ? codes[i] : codes[0];
+	format->width = clamp_t(unsigned int, fmt->format.width,
+				min_width, max_width);
+	format->height = clamp_t(unsigned int, fmt->format.height,
+				 min_height, max_height);
+	format->field = V4L2_FIELD_NONE;
+	format->colorspace = V4L2_COLORSPACE_SRGB;
+
+	fmt->format = *format;
+
+	/* Propagate the format to the source pad. */
+	format = vsp1_entity_get_pad_format(entity, config, 1);
+	*format = fmt->format;
+
+done:
+	mutex_unlock(&entity->lock);
+	return ret;
+}
+
 /* -----------------------------------------------------------------------------
  * Media Operations
  */
diff --git a/drivers/media/platform/vsp1/vsp1_entity.h b/drivers/media/platform/vsp1/vsp1_entity.h
index fb20a1578f3b..0839a62cfa71 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.h
+++ b/drivers/media/platform/vsp1/vsp1_entity.h
@@ -160,6 +160,12 @@ struct media_pad *vsp1_entity_remote_pad(struct media_pad *pad);
 int vsp1_subdev_get_pad_format(struct v4l2_subdev *subdev,
 			       struct v4l2_subdev_pad_config *cfg,
 			       struct v4l2_subdev_format *fmt);
+int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev,
+			       struct v4l2_subdev_pad_config *cfg,
+			       struct v4l2_subdev_format *fmt,
+			       const unsigned int *codes, unsigned int ncodes,
+			       unsigned int min_width, unsigned int min_height,
+			       unsigned int max_width, unsigned int max_height);
 int vsp1_subdev_enum_mbus_code(struct v4l2_subdev *subdev,
 			       struct v4l2_subdev_pad_config *cfg,
 			       struct v4l2_subdev_mbus_code_enum *code,
diff --git a/drivers/media/platform/vsp1/vsp1_lif.c b/drivers/media/platform/vsp1/vsp1_lif.c
index b20b842f06ba..fbdd5715f829 100644
--- a/drivers/media/platform/vsp1/vsp1_lif.c
+++ b/drivers/media/platform/vsp1/vsp1_lif.c
@@ -33,17 +33,17 @@ static inline void vsp1_lif_write(struct vsp1_lif *lif, struct vsp1_dl_list *dl,
  * V4L2 Subdevice Operations
  */
 
+static const unsigned int lif_codes[] = {
+	MEDIA_BUS_FMT_ARGB8888_1X32,
+	MEDIA_BUS_FMT_AYUV8_1X32,
+};
+
 static int lif_enum_mbus_code(struct v4l2_subdev *subdev,
 			      struct v4l2_subdev_pad_config *cfg,
 			      struct v4l2_subdev_mbus_code_enum *code)
 {
-	static const unsigned int codes[] = {
-		MEDIA_BUS_FMT_ARGB8888_1X32,
-		MEDIA_BUS_FMT_AYUV8_1X32,
-	};
-
-	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, codes,
-					  ARRAY_SIZE(codes));
+	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, lif_codes,
+					  ARRAY_SIZE(lif_codes));
 }
 
 static int lif_enum_frame_size(struct v4l2_subdev *subdev,
@@ -59,53 +59,10 @@ static int lif_set_format(struct v4l2_subdev *subdev,
 			  struct v4l2_subdev_pad_config *cfg,
 			  struct v4l2_subdev_format *fmt)
 {
-	struct vsp1_lif *lif = to_lif(subdev);
-	struct v4l2_subdev_pad_config *config;
-	struct v4l2_mbus_framefmt *format;
-	int ret = 0;
-
-	mutex_lock(&lif->entity.lock);
-
-	config = vsp1_entity_get_pad_config(&lif->entity, cfg, fmt->which);
-	if (!config) {
-		ret = -EINVAL;
-		goto done;
-	}
-
-	/* Default to YUV if the requested format is not supported. */
-	if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
-	    fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32)
-		fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32;
-
-	format = vsp1_entity_get_pad_format(&lif->entity, config, fmt->pad);
-
-	if (fmt->pad == LIF_PAD_SOURCE) {
-		/*
-		 * The LIF source format is always identical to its sink
-		 * format.
-		 */
-		fmt->format = *format;
-		goto done;
-	}
-
-	format->code = fmt->format.code;
-	format->width = clamp_t(unsigned int, fmt->format.width,
-				LIF_MIN_SIZE, LIF_MAX_SIZE);
-	format->height = clamp_t(unsigned int, fmt->format.height,
-				 LIF_MIN_SIZE, LIF_MAX_SIZE);
-	format->field = V4L2_FIELD_NONE;
-	format->colorspace = V4L2_COLORSPACE_SRGB;
-
-	fmt->format = *format;
-
-	/* Propagate the format to the source pad. */
-	format = vsp1_entity_get_pad_format(&lif->entity, config,
-					    LIF_PAD_SOURCE);
-	*format = fmt->format;
-
-done:
-	mutex_unlock(&lif->entity.lock);
-	return ret;
+	return vsp1_subdev_set_pad_format(subdev, cfg, fmt, lif_codes,
+					  ARRAY_SIZE(lif_codes),
+					  LIF_MIN_SIZE, LIF_MIN_SIZE,
+					  LIF_MAX_SIZE, LIF_MAX_SIZE);
 }
 
 static const struct v4l2_subdev_pad_ops lif_pad_ops = {
diff --git a/drivers/media/platform/vsp1/vsp1_lut.c b/drivers/media/platform/vsp1/vsp1_lut.c
index 7bdabb311c6c..f2e48a02ca7d 100644
--- a/drivers/media/platform/vsp1/vsp1_lut.c
+++ b/drivers/media/platform/vsp1/vsp1_lut.c
@@ -90,18 +90,18 @@ static const struct v4l2_ctrl_config lut_table_control = {
  * V4L2 Subdevice Pad Operations
  */
 
+static const unsigned int lut_codes[] = {
+	MEDIA_BUS_FMT_ARGB8888_1X32,
+	MEDIA_BUS_FMT_AHSV8888_1X32,
+	MEDIA_BUS_FMT_AYUV8_1X32,
+};
+
 static int lut_enum_mbus_code(struct v4l2_subdev *subdev,
 			      struct v4l2_subdev_pad_config *cfg,
 			      struct v4l2_subdev_mbus_code_enum *code)
 {
-	static const unsigned int codes[] = {
-		MEDIA_BUS_FMT_ARGB8888_1X32,
-		MEDIA_BUS_FMT_AHSV8888_1X32,
-		MEDIA_BUS_FMT_AYUV8_1X32,
-	};
-
-	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, codes,
-					  ARRAY_SIZE(codes));
+	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, lut_codes,
+					  ARRAY_SIZE(lut_codes));
 }
 
 static int lut_enum_frame_size(struct v4l2_subdev *subdev,
@@ -117,51 +117,10 @@ static int lut_set_format(struct v4l2_subdev *subdev,
 			  struct v4l2_subdev_pad_config *cfg,
 			  struct v4l2_subdev_format *fmt)
 {
-	struct vsp1_lut *lut = to_lut(subdev);
-	struct v4l2_subdev_pad_config *config;
-	struct v4l2_mbus_framefmt *format;
-	int ret = 0;
-
-	mutex_lock(&lut->entity.lock);
-
-	config = vsp1_entity_get_pad_config(&lut->entity, cfg, fmt->which);
-	if (!config) {
-		ret = -EINVAL;
-		goto done;
-	}
-
-	/* Default to YUV if the requested format is not supported. */
-	if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
-	    fmt->format.code != MEDIA_BUS_FMT_AHSV8888_1X32 &&
-	    fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32)
-		fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32;
-
-	format = vsp1_entity_get_pad_format(&lut->entity, config, fmt->pad);
-
-	if (fmt->pad == LUT_PAD_SOURCE) {
-		/* The LUT output format can't be modified. */
-		fmt->format = *format;
-		goto done;
-	}
-
-	format->code = fmt->format.code;
-	format->width = clamp_t(unsigned int, fmt->format.width,
-				LUT_MIN_SIZE, LUT_MAX_SIZE);
-	format->height = clamp_t(unsigned int, fmt->format.height,
-				 LUT_MIN_SIZE, LUT_MAX_SIZE);
-	format->field = V4L2_FIELD_NONE;
-	format->colorspace = V4L2_COLORSPACE_SRGB;
-
-	fmt->format = *format;
-
-	/* Propagate the format to the source pad. */
-	format = vsp1_entity_get_pad_format(&lut->entity, config,
-					    LUT_PAD_SOURCE);
-	*format = fmt->format;
-
-done:
-	mutex_unlock(&lut->entity.lock);
-	return ret;
+	return vsp1_subdev_set_pad_format(subdev, cfg, fmt, lut_codes,
+					  ARRAY_SIZE(lut_codes),
+					  LUT_MIN_SIZE, LUT_MIN_SIZE,
+					  LUT_MAX_SIZE, LUT_MAX_SIZE);
 }
 
 /* -----------------------------------------------------------------------------
-- 
Regards,

Laurent Pinchart

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

* [PATCH v2 2/8] v4l: vsp1: Share the CLU, LIF and LUT set_fmt pad operation code
@ 2018-04-22 22:34   ` Laurent Pinchart
  0 siblings, 0 replies; 82+ messages in thread
From: Laurent Pinchart @ 2018-04-22 22:34 UTC (permalink / raw)
  To: linux-media, dri-devel; +Cc: linux-renesas-soc, Kieran Bingham

The implementation of the set_fmt pad operation is identical in the
three modules. Move it to a generic helper function.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/platform/vsp1/vsp1_clu.c    | 65 +++++----------------------
 drivers/media/platform/vsp1/vsp1_entity.c | 75 +++++++++++++++++++++++++++++++
 drivers/media/platform/vsp1/vsp1_entity.h |  6 +++
 drivers/media/platform/vsp1/vsp1_lif.c    | 65 +++++----------------------
 drivers/media/platform/vsp1/vsp1_lut.c    | 65 +++++----------------------
 5 files changed, 116 insertions(+), 160 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1_clu.c b/drivers/media/platform/vsp1/vsp1_clu.c
index 9626b6308585..96a448e1504c 100644
--- a/drivers/media/platform/vsp1/vsp1_clu.c
+++ b/drivers/media/platform/vsp1/vsp1_clu.c
@@ -114,18 +114,18 @@ static const struct v4l2_ctrl_config clu_mode_control = {
  * V4L2 Subdevice Pad Operations
  */
 
+static const unsigned int clu_codes[] = {
+	MEDIA_BUS_FMT_ARGB8888_1X32,
+	MEDIA_BUS_FMT_AHSV8888_1X32,
+	MEDIA_BUS_FMT_AYUV8_1X32,
+};
+
 static int clu_enum_mbus_code(struct v4l2_subdev *subdev,
 			      struct v4l2_subdev_pad_config *cfg,
 			      struct v4l2_subdev_mbus_code_enum *code)
 {
-	static const unsigned int codes[] = {
-		MEDIA_BUS_FMT_ARGB8888_1X32,
-		MEDIA_BUS_FMT_AHSV8888_1X32,
-		MEDIA_BUS_FMT_AYUV8_1X32,
-	};
-
-	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, codes,
-					  ARRAY_SIZE(codes));
+	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, clu_codes,
+					  ARRAY_SIZE(clu_codes));
 }
 
 static int clu_enum_frame_size(struct v4l2_subdev *subdev,
@@ -141,51 +141,10 @@ static int clu_set_format(struct v4l2_subdev *subdev,
 			  struct v4l2_subdev_pad_config *cfg,
 			  struct v4l2_subdev_format *fmt)
 {
-	struct vsp1_clu *clu = to_clu(subdev);
-	struct v4l2_subdev_pad_config *config;
-	struct v4l2_mbus_framefmt *format;
-	int ret = 0;
-
-	mutex_lock(&clu->entity.lock);
-
-	config = vsp1_entity_get_pad_config(&clu->entity, cfg, fmt->which);
-	if (!config) {
-		ret = -EINVAL;
-		goto done;
-	}
-
-	/* Default to YUV if the requested format is not supported. */
-	if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
-	    fmt->format.code != MEDIA_BUS_FMT_AHSV8888_1X32 &&
-	    fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32)
-		fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32;
-
-	format = vsp1_entity_get_pad_format(&clu->entity, config, fmt->pad);
-
-	if (fmt->pad == CLU_PAD_SOURCE) {
-		/* The CLU output format can't be modified. */
-		fmt->format = *format;
-		goto done;
-	}
-
-	format->code = fmt->format.code;
-	format->width = clamp_t(unsigned int, fmt->format.width,
-				CLU_MIN_SIZE, CLU_MAX_SIZE);
-	format->height = clamp_t(unsigned int, fmt->format.height,
-				 CLU_MIN_SIZE, CLU_MAX_SIZE);
-	format->field = V4L2_FIELD_NONE;
-	format->colorspace = V4L2_COLORSPACE_SRGB;
-
-	fmt->format = *format;
-
-	/* Propagate the format to the source pad. */
-	format = vsp1_entity_get_pad_format(&clu->entity, config,
-					    CLU_PAD_SOURCE);
-	*format = fmt->format;
-
-done:
-	mutex_unlock(&clu->entity.lock);
-	return ret;
+	return vsp1_subdev_set_pad_format(subdev, cfg, fmt, clu_codes,
+					  ARRAY_SIZE(clu_codes),
+					  CLU_MIN_SIZE, CLU_MIN_SIZE,
+					  CLU_MAX_SIZE, CLU_MAX_SIZE);
 }
 
 /* -----------------------------------------------------------------------------
diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c
index 72354caf5746..239df047efd0 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.c
+++ b/drivers/media/platform/vsp1/vsp1_entity.c
@@ -307,6 +307,81 @@ int vsp1_subdev_enum_frame_size(struct v4l2_subdev *subdev,
 	return ret;
 }
 
+/*
+ * vsp1_subdev_set_pad_format - Subdev pad set_fmt handler
+ * @subdev: V4L2 subdevice
+ * @cfg: V4L2 subdev pad configuration
+ * @fmt: V4L2 subdev format
+ * @codes: Array of supported media bus codes
+ * @ncodes: Number of supported media bus codes
+ * @min_width: Minimum image width
+ * @min_height: Minimum image height
+ * @max_width: Maximum image width
+ * @max_height: Maximum image height
+ *
+ * This function implements the subdev set_fmt pad operation for entities that
+ * do not support scaling or cropping. It defaults to the first supplied media
+ * bus code if the requested code isn't supported, clamps the size to the
+ * supplied minimum and maximum, and propagates the sink pad format to the
+ * source pad.
+ */
+int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev,
+			       struct v4l2_subdev_pad_config *cfg,
+			       struct v4l2_subdev_format *fmt,
+			       const unsigned int *codes, unsigned int ncodes,
+			       unsigned int min_width, unsigned int min_height,
+			       unsigned int max_width, unsigned int max_height)
+{
+	struct vsp1_entity *entity = to_vsp1_entity(subdev);
+	struct v4l2_subdev_pad_config *config;
+	struct v4l2_mbus_framefmt *format;
+	unsigned int i;
+	int ret = 0;
+
+	mutex_lock(&entity->lock);
+
+	config = vsp1_entity_get_pad_config(entity, cfg, fmt->which);
+	if (!config) {
+		ret = -EINVAL;
+		goto done;
+	}
+
+	format = vsp1_entity_get_pad_format(entity, config, fmt->pad);
+
+	if (fmt->pad != 0) {
+		/* The output format can't be modified. */
+		fmt->format = *format;
+		goto done;
+	}
+
+	/*
+	 * Default to the first media bus code if the requested format is not
+	 * supported.
+	 */
+	for (i = 0; i < ncodes; ++i) {
+		if (fmt->format.code == codes[i])
+			break;
+	}
+
+	format->code = i < ncodes ? codes[i] : codes[0];
+	format->width = clamp_t(unsigned int, fmt->format.width,
+				min_width, max_width);
+	format->height = clamp_t(unsigned int, fmt->format.height,
+				 min_height, max_height);
+	format->field = V4L2_FIELD_NONE;
+	format->colorspace = V4L2_COLORSPACE_SRGB;
+
+	fmt->format = *format;
+
+	/* Propagate the format to the source pad. */
+	format = vsp1_entity_get_pad_format(entity, config, 1);
+	*format = fmt->format;
+
+done:
+	mutex_unlock(&entity->lock);
+	return ret;
+}
+
 /* -----------------------------------------------------------------------------
  * Media Operations
  */
diff --git a/drivers/media/platform/vsp1/vsp1_entity.h b/drivers/media/platform/vsp1/vsp1_entity.h
index fb20a1578f3b..0839a62cfa71 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.h
+++ b/drivers/media/platform/vsp1/vsp1_entity.h
@@ -160,6 +160,12 @@ struct media_pad *vsp1_entity_remote_pad(struct media_pad *pad);
 int vsp1_subdev_get_pad_format(struct v4l2_subdev *subdev,
 			       struct v4l2_subdev_pad_config *cfg,
 			       struct v4l2_subdev_format *fmt);
+int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev,
+			       struct v4l2_subdev_pad_config *cfg,
+			       struct v4l2_subdev_format *fmt,
+			       const unsigned int *codes, unsigned int ncodes,
+			       unsigned int min_width, unsigned int min_height,
+			       unsigned int max_width, unsigned int max_height);
 int vsp1_subdev_enum_mbus_code(struct v4l2_subdev *subdev,
 			       struct v4l2_subdev_pad_config *cfg,
 			       struct v4l2_subdev_mbus_code_enum *code,
diff --git a/drivers/media/platform/vsp1/vsp1_lif.c b/drivers/media/platform/vsp1/vsp1_lif.c
index b20b842f06ba..fbdd5715f829 100644
--- a/drivers/media/platform/vsp1/vsp1_lif.c
+++ b/drivers/media/platform/vsp1/vsp1_lif.c
@@ -33,17 +33,17 @@ static inline void vsp1_lif_write(struct vsp1_lif *lif, struct vsp1_dl_list *dl,
  * V4L2 Subdevice Operations
  */
 
+static const unsigned int lif_codes[] = {
+	MEDIA_BUS_FMT_ARGB8888_1X32,
+	MEDIA_BUS_FMT_AYUV8_1X32,
+};
+
 static int lif_enum_mbus_code(struct v4l2_subdev *subdev,
 			      struct v4l2_subdev_pad_config *cfg,
 			      struct v4l2_subdev_mbus_code_enum *code)
 {
-	static const unsigned int codes[] = {
-		MEDIA_BUS_FMT_ARGB8888_1X32,
-		MEDIA_BUS_FMT_AYUV8_1X32,
-	};
-
-	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, codes,
-					  ARRAY_SIZE(codes));
+	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, lif_codes,
+					  ARRAY_SIZE(lif_codes));
 }
 
 static int lif_enum_frame_size(struct v4l2_subdev *subdev,
@@ -59,53 +59,10 @@ static int lif_set_format(struct v4l2_subdev *subdev,
 			  struct v4l2_subdev_pad_config *cfg,
 			  struct v4l2_subdev_format *fmt)
 {
-	struct vsp1_lif *lif = to_lif(subdev);
-	struct v4l2_subdev_pad_config *config;
-	struct v4l2_mbus_framefmt *format;
-	int ret = 0;
-
-	mutex_lock(&lif->entity.lock);
-
-	config = vsp1_entity_get_pad_config(&lif->entity, cfg, fmt->which);
-	if (!config) {
-		ret = -EINVAL;
-		goto done;
-	}
-
-	/* Default to YUV if the requested format is not supported. */
-	if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
-	    fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32)
-		fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32;
-
-	format = vsp1_entity_get_pad_format(&lif->entity, config, fmt->pad);
-
-	if (fmt->pad == LIF_PAD_SOURCE) {
-		/*
-		 * The LIF source format is always identical to its sink
-		 * format.
-		 */
-		fmt->format = *format;
-		goto done;
-	}
-
-	format->code = fmt->format.code;
-	format->width = clamp_t(unsigned int, fmt->format.width,
-				LIF_MIN_SIZE, LIF_MAX_SIZE);
-	format->height = clamp_t(unsigned int, fmt->format.height,
-				 LIF_MIN_SIZE, LIF_MAX_SIZE);
-	format->field = V4L2_FIELD_NONE;
-	format->colorspace = V4L2_COLORSPACE_SRGB;
-
-	fmt->format = *format;
-
-	/* Propagate the format to the source pad. */
-	format = vsp1_entity_get_pad_format(&lif->entity, config,
-					    LIF_PAD_SOURCE);
-	*format = fmt->format;
-
-done:
-	mutex_unlock(&lif->entity.lock);
-	return ret;
+	return vsp1_subdev_set_pad_format(subdev, cfg, fmt, lif_codes,
+					  ARRAY_SIZE(lif_codes),
+					  LIF_MIN_SIZE, LIF_MIN_SIZE,
+					  LIF_MAX_SIZE, LIF_MAX_SIZE);
 }
 
 static const struct v4l2_subdev_pad_ops lif_pad_ops = {
diff --git a/drivers/media/platform/vsp1/vsp1_lut.c b/drivers/media/platform/vsp1/vsp1_lut.c
index 7bdabb311c6c..f2e48a02ca7d 100644
--- a/drivers/media/platform/vsp1/vsp1_lut.c
+++ b/drivers/media/platform/vsp1/vsp1_lut.c
@@ -90,18 +90,18 @@ static const struct v4l2_ctrl_config lut_table_control = {
  * V4L2 Subdevice Pad Operations
  */
 
+static const unsigned int lut_codes[] = {
+	MEDIA_BUS_FMT_ARGB8888_1X32,
+	MEDIA_BUS_FMT_AHSV8888_1X32,
+	MEDIA_BUS_FMT_AYUV8_1X32,
+};
+
 static int lut_enum_mbus_code(struct v4l2_subdev *subdev,
 			      struct v4l2_subdev_pad_config *cfg,
 			      struct v4l2_subdev_mbus_code_enum *code)
 {
-	static const unsigned int codes[] = {
-		MEDIA_BUS_FMT_ARGB8888_1X32,
-		MEDIA_BUS_FMT_AHSV8888_1X32,
-		MEDIA_BUS_FMT_AYUV8_1X32,
-	};
-
-	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, codes,
-					  ARRAY_SIZE(codes));
+	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, lut_codes,
+					  ARRAY_SIZE(lut_codes));
 }
 
 static int lut_enum_frame_size(struct v4l2_subdev *subdev,
@@ -117,51 +117,10 @@ static int lut_set_format(struct v4l2_subdev *subdev,
 			  struct v4l2_subdev_pad_config *cfg,
 			  struct v4l2_subdev_format *fmt)
 {
-	struct vsp1_lut *lut = to_lut(subdev);
-	struct v4l2_subdev_pad_config *config;
-	struct v4l2_mbus_framefmt *format;
-	int ret = 0;
-
-	mutex_lock(&lut->entity.lock);
-
-	config = vsp1_entity_get_pad_config(&lut->entity, cfg, fmt->which);
-	if (!config) {
-		ret = -EINVAL;
-		goto done;
-	}
-
-	/* Default to YUV if the requested format is not supported. */
-	if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
-	    fmt->format.code != MEDIA_BUS_FMT_AHSV8888_1X32 &&
-	    fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32)
-		fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32;
-
-	format = vsp1_entity_get_pad_format(&lut->entity, config, fmt->pad);
-
-	if (fmt->pad == LUT_PAD_SOURCE) {
-		/* The LUT output format can't be modified. */
-		fmt->format = *format;
-		goto done;
-	}
-
-	format->code = fmt->format.code;
-	format->width = clamp_t(unsigned int, fmt->format.width,
-				LUT_MIN_SIZE, LUT_MAX_SIZE);
-	format->height = clamp_t(unsigned int, fmt->format.height,
-				 LUT_MIN_SIZE, LUT_MAX_SIZE);
-	format->field = V4L2_FIELD_NONE;
-	format->colorspace = V4L2_COLORSPACE_SRGB;
-
-	fmt->format = *format;
-
-	/* Propagate the format to the source pad. */
-	format = vsp1_entity_get_pad_format(&lut->entity, config,
-					    LUT_PAD_SOURCE);
-	*format = fmt->format;
-
-done:
-	mutex_unlock(&lut->entity.lock);
-	return ret;
+	return vsp1_subdev_set_pad_format(subdev, cfg, fmt, lut_codes,
+					  ARRAY_SIZE(lut_codes),
+					  LUT_MIN_SIZE, LUT_MIN_SIZE,
+					  LUT_MAX_SIZE, LUT_MAX_SIZE);
 }
 
 /* -----------------------------------------------------------------------------
-- 
Regards,

Laurent Pinchart

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

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

* [PATCH v2 3/8] v4l: vsp1: Reset the crop and compose rectangles in the set_fmt helper
  2018-04-22 22:34 ` Laurent Pinchart
@ 2018-04-22 22:34   ` Laurent Pinchart
  -1 siblings, 0 replies; 82+ messages in thread
From: Laurent Pinchart @ 2018-04-22 22:34 UTC (permalink / raw)
  To: linux-media, dri-devel; +Cc: linux-renesas-soc, Kieran Bingham

To make vsp1_subdev_set_pad_format() usable by entities that support
selection rectangles, we need to reset the crop and compose rectangles
when setting the format on the sink pad. Do so and replace the custom
set_fmt implementation of the histogram code by a call to
vsp1_subdev_set_pad_format().

Resetting the crop and compose rectangles for entities that don't
support crop and compose has no adverse effect as the rectangles are
ignored anyway.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/platform/vsp1/vsp1_entity.c | 16 +++++++++
 drivers/media/platform/vsp1/vsp1_histo.c  | 59 +++----------------------------
 2 files changed, 20 insertions(+), 55 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c
index 239df047efd0..181a583aecad 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.c
+++ b/drivers/media/platform/vsp1/vsp1_entity.c
@@ -335,6 +335,7 @@ int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev,
 	struct vsp1_entity *entity = to_vsp1_entity(subdev);
 	struct v4l2_subdev_pad_config *config;
 	struct v4l2_mbus_framefmt *format;
+	struct v4l2_rect *selection;
 	unsigned int i;
 	int ret = 0;
 
@@ -377,6 +378,21 @@ int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev,
 	format = vsp1_entity_get_pad_format(entity, config, 1);
 	*format = fmt->format;
 
+	/* Reset the crop and compose rectangles */
+	selection = vsp1_entity_get_pad_selection(entity, config, fmt->pad,
+						  V4L2_SEL_TGT_CROP);
+	selection->left = 0;
+	selection->top = 0;
+	selection->width = format->width;
+	selection->height = format->height;
+
+	selection = vsp1_entity_get_pad_selection(entity, config, fmt->pad,
+						  V4L2_SEL_TGT_COMPOSE);
+	selection->left = 0;
+	selection->top = 0;
+	selection->width = format->width;
+	selection->height = format->height;
+
 done:
 	mutex_unlock(&entity->lock);
 	return ret;
diff --git a/drivers/media/platform/vsp1/vsp1_histo.c b/drivers/media/platform/vsp1/vsp1_histo.c
index 029181c1fb61..5e15c8ff88d9 100644
--- a/drivers/media/platform/vsp1/vsp1_histo.c
+++ b/drivers/media/platform/vsp1/vsp1_histo.c
@@ -389,65 +389,14 @@ static int histo_set_format(struct v4l2_subdev *subdev,
 			    struct v4l2_subdev_format *fmt)
 {
 	struct vsp1_histogram *histo = subdev_to_histo(subdev);
-	struct v4l2_subdev_pad_config *config;
-	struct v4l2_mbus_framefmt *format;
-	struct v4l2_rect *selection;
-	unsigned int i;
-	int ret = 0;
 
 	if (fmt->pad != HISTO_PAD_SINK)
 		return histo_get_format(subdev, cfg, fmt);
 
-	mutex_lock(&histo->entity.lock);
-
-	config = vsp1_entity_get_pad_config(&histo->entity, cfg, fmt->which);
-	if (!config) {
-		ret = -EINVAL;
-		goto done;
-	}
-
-	/*
-	 * Default to the first format if the requested format is not
-	 * supported.
-	 */
-	for (i = 0; i < histo->num_formats; ++i) {
-		if (fmt->format.code == histo->formats[i])
-			break;
-	}
-	if (i == histo->num_formats)
-		fmt->format.code = histo->formats[0];
-
-	format = vsp1_entity_get_pad_format(&histo->entity, config, fmt->pad);
-
-	format->code = fmt->format.code;
-	format->width = clamp_t(unsigned int, fmt->format.width,
-				HISTO_MIN_SIZE, HISTO_MAX_SIZE);
-	format->height = clamp_t(unsigned int, fmt->format.height,
-				 HISTO_MIN_SIZE, HISTO_MAX_SIZE);
-	format->field = V4L2_FIELD_NONE;
-	format->colorspace = V4L2_COLORSPACE_SRGB;
-
-	fmt->format = *format;
-
-	/* Reset the crop and compose rectangles */
-	selection = vsp1_entity_get_pad_selection(&histo->entity, config,
-						  fmt->pad, V4L2_SEL_TGT_CROP);
-	selection->left = 0;
-	selection->top = 0;
-	selection->width = format->width;
-	selection->height = format->height;
-
-	selection = vsp1_entity_get_pad_selection(&histo->entity, config,
-						  fmt->pad,
-						  V4L2_SEL_TGT_COMPOSE);
-	selection->left = 0;
-	selection->top = 0;
-	selection->width = format->width;
-	selection->height = format->height;
-
-done:
-	mutex_unlock(&histo->entity.lock);
-	return ret;
+	return vsp1_subdev_set_pad_format(subdev, cfg, fmt,
+					  histo->formats, histo->num_formats,
+					  HISTO_MIN_SIZE, HISTO_MIN_SIZE,
+					  HISTO_MAX_SIZE, HISTO_MAX_SIZE);
 }
 
 static const struct v4l2_subdev_pad_ops histo_pad_ops = {
-- 
Regards,

Laurent Pinchart

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

* [PATCH v2 3/8] v4l: vsp1: Reset the crop and compose rectangles in the set_fmt helper
@ 2018-04-22 22:34   ` Laurent Pinchart
  0 siblings, 0 replies; 82+ messages in thread
From: Laurent Pinchart @ 2018-04-22 22:34 UTC (permalink / raw)
  To: linux-media, dri-devel; +Cc: linux-renesas-soc, Kieran Bingham

To make vsp1_subdev_set_pad_format() usable by entities that support
selection rectangles, we need to reset the crop and compose rectangles
when setting the format on the sink pad. Do so and replace the custom
set_fmt implementation of the histogram code by a call to
vsp1_subdev_set_pad_format().

Resetting the crop and compose rectangles for entities that don't
support crop and compose has no adverse effect as the rectangles are
ignored anyway.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/platform/vsp1/vsp1_entity.c | 16 +++++++++
 drivers/media/platform/vsp1/vsp1_histo.c  | 59 +++----------------------------
 2 files changed, 20 insertions(+), 55 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c
index 239df047efd0..181a583aecad 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.c
+++ b/drivers/media/platform/vsp1/vsp1_entity.c
@@ -335,6 +335,7 @@ int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev,
 	struct vsp1_entity *entity = to_vsp1_entity(subdev);
 	struct v4l2_subdev_pad_config *config;
 	struct v4l2_mbus_framefmt *format;
+	struct v4l2_rect *selection;
 	unsigned int i;
 	int ret = 0;
 
@@ -377,6 +378,21 @@ int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev,
 	format = vsp1_entity_get_pad_format(entity, config, 1);
 	*format = fmt->format;
 
+	/* Reset the crop and compose rectangles */
+	selection = vsp1_entity_get_pad_selection(entity, config, fmt->pad,
+						  V4L2_SEL_TGT_CROP);
+	selection->left = 0;
+	selection->top = 0;
+	selection->width = format->width;
+	selection->height = format->height;
+
+	selection = vsp1_entity_get_pad_selection(entity, config, fmt->pad,
+						  V4L2_SEL_TGT_COMPOSE);
+	selection->left = 0;
+	selection->top = 0;
+	selection->width = format->width;
+	selection->height = format->height;
+
 done:
 	mutex_unlock(&entity->lock);
 	return ret;
diff --git a/drivers/media/platform/vsp1/vsp1_histo.c b/drivers/media/platform/vsp1/vsp1_histo.c
index 029181c1fb61..5e15c8ff88d9 100644
--- a/drivers/media/platform/vsp1/vsp1_histo.c
+++ b/drivers/media/platform/vsp1/vsp1_histo.c
@@ -389,65 +389,14 @@ static int histo_set_format(struct v4l2_subdev *subdev,
 			    struct v4l2_subdev_format *fmt)
 {
 	struct vsp1_histogram *histo = subdev_to_histo(subdev);
-	struct v4l2_subdev_pad_config *config;
-	struct v4l2_mbus_framefmt *format;
-	struct v4l2_rect *selection;
-	unsigned int i;
-	int ret = 0;
 
 	if (fmt->pad != HISTO_PAD_SINK)
 		return histo_get_format(subdev, cfg, fmt);
 
-	mutex_lock(&histo->entity.lock);
-
-	config = vsp1_entity_get_pad_config(&histo->entity, cfg, fmt->which);
-	if (!config) {
-		ret = -EINVAL;
-		goto done;
-	}
-
-	/*
-	 * Default to the first format if the requested format is not
-	 * supported.
-	 */
-	for (i = 0; i < histo->num_formats; ++i) {
-		if (fmt->format.code == histo->formats[i])
-			break;
-	}
-	if (i == histo->num_formats)
-		fmt->format.code = histo->formats[0];
-
-	format = vsp1_entity_get_pad_format(&histo->entity, config, fmt->pad);
-
-	format->code = fmt->format.code;
-	format->width = clamp_t(unsigned int, fmt->format.width,
-				HISTO_MIN_SIZE, HISTO_MAX_SIZE);
-	format->height = clamp_t(unsigned int, fmt->format.height,
-				 HISTO_MIN_SIZE, HISTO_MAX_SIZE);
-	format->field = V4L2_FIELD_NONE;
-	format->colorspace = V4L2_COLORSPACE_SRGB;
-
-	fmt->format = *format;
-
-	/* Reset the crop and compose rectangles */
-	selection = vsp1_entity_get_pad_selection(&histo->entity, config,
-						  fmt->pad, V4L2_SEL_TGT_CROP);
-	selection->left = 0;
-	selection->top = 0;
-	selection->width = format->width;
-	selection->height = format->height;
-
-	selection = vsp1_entity_get_pad_selection(&histo->entity, config,
-						  fmt->pad,
-						  V4L2_SEL_TGT_COMPOSE);
-	selection->left = 0;
-	selection->top = 0;
-	selection->width = format->width;
-	selection->height = format->height;
-
-done:
-	mutex_unlock(&histo->entity.lock);
-	return ret;
+	return vsp1_subdev_set_pad_format(subdev, cfg, fmt,
+					  histo->formats, histo->num_formats,
+					  HISTO_MIN_SIZE, HISTO_MIN_SIZE,
+					  HISTO_MAX_SIZE, HISTO_MAX_SIZE);
 }
 
 static const struct v4l2_subdev_pad_ops histo_pad_ops = {
-- 
Regards,

Laurent Pinchart

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

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

* [PATCH v2 4/8] v4l: vsp1: Document the vsp1_du_atomic_config structure
  2018-04-22 22:34 ` Laurent Pinchart
@ 2018-04-22 22:34   ` Laurent Pinchart
  -1 siblings, 0 replies; 82+ messages in thread
From: Laurent Pinchart @ 2018-04-22 22:34 UTC (permalink / raw)
  To: linux-media, dri-devel; +Cc: linux-renesas-soc, Kieran Bingham

The structure is used in the API that the VSP1 driver exposes to the DU
driver. Documenting it is thus important.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
Changes since v1:

- Fixed typo
---
 include/media/vsp1.h | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/include/media/vsp1.h b/include/media/vsp1.h
index 68a8abe4fac5..ff7ef894465d 100644
--- a/include/media/vsp1.h
+++ b/include/media/vsp1.h
@@ -41,6 +41,16 @@ struct vsp1_du_lif_config {
 int vsp1_du_setup_lif(struct device *dev, unsigned int pipe_index,
 		      const struct vsp1_du_lif_config *cfg);
 
+/**
+ * struct vsp1_du_atomic_config - VSP atomic configuration parameters
+ * @pixelformat: plane pixel format (V4L2 4CC)
+ * @pitch: line pitch in bytes, for all planes
+ * @mem: DMA memory address for each plane of the frame buffer
+ * @src: source rectangle in the frame buffer (integer coordinates)
+ * @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)
+ */
 struct vsp1_du_atomic_config {
 	u32 pixelformat;
 	unsigned int pitch;
-- 
Regards,

Laurent Pinchart

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

* [PATCH v2 4/8] v4l: vsp1: Document the vsp1_du_atomic_config structure
@ 2018-04-22 22:34   ` Laurent Pinchart
  0 siblings, 0 replies; 82+ messages in thread
From: Laurent Pinchart @ 2018-04-22 22:34 UTC (permalink / raw)
  To: linux-media, dri-devel; +Cc: linux-renesas-soc, Kieran Bingham

The structure is used in the API that the VSP1 driver exposes to the DU
driver. Documenting it is thus important.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
Changes since v1:

- Fixed typo
---
 include/media/vsp1.h | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/include/media/vsp1.h b/include/media/vsp1.h
index 68a8abe4fac5..ff7ef894465d 100644
--- a/include/media/vsp1.h
+++ b/include/media/vsp1.h
@@ -41,6 +41,16 @@ struct vsp1_du_lif_config {
 int vsp1_du_setup_lif(struct device *dev, unsigned int pipe_index,
 		      const struct vsp1_du_lif_config *cfg);
 
+/**
+ * struct vsp1_du_atomic_config - VSP atomic configuration parameters
+ * @pixelformat: plane pixel format (V4L2 4CC)
+ * @pitch: line pitch in bytes, for all planes
+ * @mem: DMA memory address for each plane of the frame buffer
+ * @src: source rectangle in the frame buffer (integer coordinates)
+ * @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)
+ */
 struct vsp1_du_atomic_config {
 	u32 pixelformat;
 	unsigned int pitch;
-- 
Regards,

Laurent Pinchart

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

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

* [PATCH v2 5/8] v4l: vsp1: Extend the DU API to support CRC computation
  2018-04-22 22:34 ` Laurent Pinchart
@ 2018-04-22 22:34   ` Laurent Pinchart
  -1 siblings, 0 replies; 82+ messages in thread
From: Laurent Pinchart @ 2018-04-22 22:34 UTC (permalink / raw)
  To: linux-media, dri-devel; +Cc: linux-renesas-soc, Kieran Bingham

Add a parameter (in the form of a structure to ease future API
extensions) to the VSP atomic flush handler to pass CRC source
configuration, and pass the CRC value to the completion callback.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/gpu/drm/rcar-du/rcar_du_vsp.c  |  6 ++++--
 drivers/media/platform/vsp1/vsp1_drm.c |  6 ++++--
 drivers/media/platform/vsp1/vsp1_drm.h |  2 +-
 include/media/vsp1.h                   | 29 +++++++++++++++++++++++++++--
 4 files changed, 36 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
index 2c260c33840b..bdcec201591f 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
@@ -31,7 +31,7 @@
 #include "rcar_du_kms.h"
 #include "rcar_du_vsp.h"
 
-static void rcar_du_vsp_complete(void *private, bool completed)
+static void rcar_du_vsp_complete(void *private, bool completed, u32 crc)
 {
 	struct rcar_du_crtc *crtc = private;
 
@@ -102,7 +102,9 @@ void rcar_du_vsp_atomic_begin(struct rcar_du_crtc *crtc)
 
 void rcar_du_vsp_atomic_flush(struct rcar_du_crtc *crtc)
 {
-	vsp1_du_atomic_flush(crtc->vsp->vsp, crtc->vsp_pipe);
+	struct vsp1_du_atomic_pipe_config cfg = { { 0, } };
+
+	vsp1_du_atomic_flush(crtc->vsp->vsp, crtc->vsp_pipe, &cfg);
 }
 
 /* Keep the two tables in sync. */
diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c
index 2b29a83dceb9..5fc31578f9b0 100644
--- a/drivers/media/platform/vsp1/vsp1_drm.c
+++ b/drivers/media/platform/vsp1/vsp1_drm.c
@@ -36,7 +36,7 @@ static void vsp1_du_pipeline_frame_end(struct vsp1_pipeline *pipe,
 	bool complete = completion == VSP1_DL_FRAME_END_COMPLETED;
 
 	if (drm_pipe->du_complete)
-		drm_pipe->du_complete(drm_pipe->du_private, complete);
+		drm_pipe->du_complete(drm_pipe->du_private, complete, 0);
 
 	if (completion & VSP1_DL_FRAME_END_INTERNAL) {
 		drm_pipe->force_brx_release = false;
@@ -739,8 +739,10 @@ EXPORT_SYMBOL_GPL(vsp1_du_atomic_update);
  * vsp1_du_atomic_flush - Commit an atomic update
  * @dev: the VSP device
  * @pipe_index: the DRM pipeline index
+ * @cfg: atomic pipe configuration
  */
-void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index)
+void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index,
+			  const struct vsp1_du_atomic_pipe_config *cfg)
 {
 	struct vsp1_device *vsp1 = dev_get_drvdata(dev);
 	struct vsp1_drm_pipeline *drm_pipe = &vsp1->drm->pipe[pipe_index];
diff --git a/drivers/media/platform/vsp1/vsp1_drm.h b/drivers/media/platform/vsp1/vsp1_drm.h
index f4af1b2b12d6..e5b88b28806c 100644
--- a/drivers/media/platform/vsp1/vsp1_drm.h
+++ b/drivers/media/platform/vsp1/vsp1_drm.h
@@ -35,7 +35,7 @@ struct vsp1_drm_pipeline {
 	wait_queue_head_t wait_queue;
 
 	/* Frame synchronisation */
-	void (*du_complete)(void *, bool);
+	void (*du_complete)(void *data, bool completed, u32 crc);
 	void *du_private;
 };
 
diff --git a/include/media/vsp1.h b/include/media/vsp1.h
index ff7ef894465d..ac63a9928a79 100644
--- a/include/media/vsp1.h
+++ b/include/media/vsp1.h
@@ -34,7 +34,7 @@ struct vsp1_du_lif_config {
 	unsigned int width;
 	unsigned int height;
 
-	void (*callback)(void *, bool);
+	void (*callback)(void *data, bool completed, u32 crc);
 	void *callback_data;
 };
 
@@ -61,11 +61,36 @@ struct vsp1_du_atomic_config {
 	unsigned int zpos;
 };
 
+/**
+ * enum vsp1_du_crc_source - Source used for CRC calculation
+ * @VSP1_DU_CRC_NONE: CRC calculation disabled
+ * @VSP_DU_CRC_PLANE: Perform CRC calculation on an input plane
+ * @VSP_DU_CRC_OUTPUT: Perform CRC calculation on the composed output
+ */
+enum vsp1_du_crc_source {
+	VSP1_DU_CRC_NONE,
+	VSP1_DU_CRC_PLANE,
+	VSP1_DU_CRC_OUTPUT,
+};
+
+/**
+ * struct vsp1_du_atomic_pipe_config - VSP atomic pipe configuration parameters
+ * @crc.source: source for CRC calculation
+ * @crc.index: index of the CRC source plane (when crc.source is set to plane)
+ */
+struct vsp1_du_atomic_pipe_config {
+	struct  {
+		enum vsp1_du_crc_source source;
+		unsigned int index;
+	} crc;
+};
+
 void vsp1_du_atomic_begin(struct device *dev, unsigned int pipe_index);
 int vsp1_du_atomic_update(struct device *dev, unsigned int pipe_index,
 			  unsigned int rpf,
 			  const struct vsp1_du_atomic_config *cfg);
-void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index);
+void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index,
+			  const struct vsp1_du_atomic_pipe_config *cfg);
 int vsp1_du_map_sg(struct device *dev, struct sg_table *sgt);
 void vsp1_du_unmap_sg(struct device *dev, struct sg_table *sgt);
 
-- 
Regards,

Laurent Pinchart

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

* [PATCH v2 5/8] v4l: vsp1: Extend the DU API to support CRC computation
@ 2018-04-22 22:34   ` Laurent Pinchart
  0 siblings, 0 replies; 82+ messages in thread
From: Laurent Pinchart @ 2018-04-22 22:34 UTC (permalink / raw)
  To: linux-media, dri-devel; +Cc: linux-renesas-soc, Kieran Bingham

Add a parameter (in the form of a structure to ease future API
extensions) to the VSP atomic flush handler to pass CRC source
configuration, and pass the CRC value to the completion callback.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/gpu/drm/rcar-du/rcar_du_vsp.c  |  6 ++++--
 drivers/media/platform/vsp1/vsp1_drm.c |  6 ++++--
 drivers/media/platform/vsp1/vsp1_drm.h |  2 +-
 include/media/vsp1.h                   | 29 +++++++++++++++++++++++++++--
 4 files changed, 36 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
index 2c260c33840b..bdcec201591f 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
@@ -31,7 +31,7 @@
 #include "rcar_du_kms.h"
 #include "rcar_du_vsp.h"
 
-static void rcar_du_vsp_complete(void *private, bool completed)
+static void rcar_du_vsp_complete(void *private, bool completed, u32 crc)
 {
 	struct rcar_du_crtc *crtc = private;
 
@@ -102,7 +102,9 @@ void rcar_du_vsp_atomic_begin(struct rcar_du_crtc *crtc)
 
 void rcar_du_vsp_atomic_flush(struct rcar_du_crtc *crtc)
 {
-	vsp1_du_atomic_flush(crtc->vsp->vsp, crtc->vsp_pipe);
+	struct vsp1_du_atomic_pipe_config cfg = { { 0, } };
+
+	vsp1_du_atomic_flush(crtc->vsp->vsp, crtc->vsp_pipe, &cfg);
 }
 
 /* Keep the two tables in sync. */
diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c
index 2b29a83dceb9..5fc31578f9b0 100644
--- a/drivers/media/platform/vsp1/vsp1_drm.c
+++ b/drivers/media/platform/vsp1/vsp1_drm.c
@@ -36,7 +36,7 @@ static void vsp1_du_pipeline_frame_end(struct vsp1_pipeline *pipe,
 	bool complete = completion == VSP1_DL_FRAME_END_COMPLETED;
 
 	if (drm_pipe->du_complete)
-		drm_pipe->du_complete(drm_pipe->du_private, complete);
+		drm_pipe->du_complete(drm_pipe->du_private, complete, 0);
 
 	if (completion & VSP1_DL_FRAME_END_INTERNAL) {
 		drm_pipe->force_brx_release = false;
@@ -739,8 +739,10 @@ EXPORT_SYMBOL_GPL(vsp1_du_atomic_update);
  * vsp1_du_atomic_flush - Commit an atomic update
  * @dev: the VSP device
  * @pipe_index: the DRM pipeline index
+ * @cfg: atomic pipe configuration
  */
-void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index)
+void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index,
+			  const struct vsp1_du_atomic_pipe_config *cfg)
 {
 	struct vsp1_device *vsp1 = dev_get_drvdata(dev);
 	struct vsp1_drm_pipeline *drm_pipe = &vsp1->drm->pipe[pipe_index];
diff --git a/drivers/media/platform/vsp1/vsp1_drm.h b/drivers/media/platform/vsp1/vsp1_drm.h
index f4af1b2b12d6..e5b88b28806c 100644
--- a/drivers/media/platform/vsp1/vsp1_drm.h
+++ b/drivers/media/platform/vsp1/vsp1_drm.h
@@ -35,7 +35,7 @@ struct vsp1_drm_pipeline {
 	wait_queue_head_t wait_queue;
 
 	/* Frame synchronisation */
-	void (*du_complete)(void *, bool);
+	void (*du_complete)(void *data, bool completed, u32 crc);
 	void *du_private;
 };
 
diff --git a/include/media/vsp1.h b/include/media/vsp1.h
index ff7ef894465d..ac63a9928a79 100644
--- a/include/media/vsp1.h
+++ b/include/media/vsp1.h
@@ -34,7 +34,7 @@ struct vsp1_du_lif_config {
 	unsigned int width;
 	unsigned int height;
 
-	void (*callback)(void *, bool);
+	void (*callback)(void *data, bool completed, u32 crc);
 	void *callback_data;
 };
 
@@ -61,11 +61,36 @@ struct vsp1_du_atomic_config {
 	unsigned int zpos;
 };
 
+/**
+ * enum vsp1_du_crc_source - Source used for CRC calculation
+ * @VSP1_DU_CRC_NONE: CRC calculation disabled
+ * @VSP_DU_CRC_PLANE: Perform CRC calculation on an input plane
+ * @VSP_DU_CRC_OUTPUT: Perform CRC calculation on the composed output
+ */
+enum vsp1_du_crc_source {
+	VSP1_DU_CRC_NONE,
+	VSP1_DU_CRC_PLANE,
+	VSP1_DU_CRC_OUTPUT,
+};
+
+/**
+ * struct vsp1_du_atomic_pipe_config - VSP atomic pipe configuration parameters
+ * @crc.source: source for CRC calculation
+ * @crc.index: index of the CRC source plane (when crc.source is set to plane)
+ */
+struct vsp1_du_atomic_pipe_config {
+	struct  {
+		enum vsp1_du_crc_source source;
+		unsigned int index;
+	} crc;
+};
+
 void vsp1_du_atomic_begin(struct device *dev, unsigned int pipe_index);
 int vsp1_du_atomic_update(struct device *dev, unsigned int pipe_index,
 			  unsigned int rpf,
 			  const struct vsp1_du_atomic_config *cfg);
-void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index);
+void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index,
+			  const struct vsp1_du_atomic_pipe_config *cfg);
 int vsp1_du_map_sg(struct device *dev, struct sg_table *sgt);
 void vsp1_du_unmap_sg(struct device *dev, struct sg_table *sgt);
 
-- 
Regards,

Laurent Pinchart

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

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

* [PATCH v2 6/8] v4l: vsp1: Add support for the DISCOM entity
  2018-04-22 22:34 ` Laurent Pinchart
@ 2018-04-22 22:34   ` Laurent Pinchart
  -1 siblings, 0 replies; 82+ messages in thread
From: Laurent Pinchart @ 2018-04-22 22:34 UTC (permalink / raw)
  To: linux-media, dri-devel; +Cc: linux-renesas-soc, Kieran Bingham

The DISCOM calculates a CRC on a configurable window of the frame. It
interfaces to the VSP through the UIF glue, hence the name used in the
code.

The module supports configuration of the CRC window through the crop
rectangle on the ink pad of the corresponding entity. However, unlike
the traditional V4L2 subdevice model, the crop rectangle does not
influence the format on the source pad.

Modeling the DISCOM as a sink-only entity would allow adhering to the
V4L2 subdevice model at the expense of more complex code in the driver,
as at the hardware level the UIF is handled as a sink+source entity. As
the DISCOM is only present in R-Car Gen3 VSP-D and VSP-DL instances it
is not exposed to userspace through V4L2 but controlled through the DU
driver. We can thus change this model later if needed without fear of
affecting userspace.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
Changes since v1:

- Don't return uninitialized value from uif_set_selection()
---
 drivers/media/platform/vsp1/Makefile      |   2 +-
 drivers/media/platform/vsp1/vsp1.h        |   4 +
 drivers/media/platform/vsp1/vsp1_drv.c    |  20 +++
 drivers/media/platform/vsp1/vsp1_entity.c |   6 +
 drivers/media/platform/vsp1/vsp1_entity.h |   1 +
 drivers/media/platform/vsp1/vsp1_regs.h   |  41 +++++
 drivers/media/platform/vsp1/vsp1_uif.c    | 271 ++++++++++++++++++++++++++++++
 drivers/media/platform/vsp1/vsp1_uif.h    |  32 ++++
 8 files changed, 376 insertions(+), 1 deletion(-)
 create mode 100644 drivers/media/platform/vsp1/vsp1_uif.c
 create mode 100644 drivers/media/platform/vsp1/vsp1_uif.h

diff --git a/drivers/media/platform/vsp1/Makefile b/drivers/media/platform/vsp1/Makefile
index 596775f932c0..4bb4dcbef7b5 100644
--- a/drivers/media/platform/vsp1/Makefile
+++ b/drivers/media/platform/vsp1/Makefile
@@ -5,6 +5,6 @@ vsp1-y					+= vsp1_rpf.o vsp1_rwpf.o vsp1_wpf.o
 vsp1-y					+= vsp1_clu.o vsp1_hsit.o vsp1_lut.o
 vsp1-y					+= vsp1_brx.o vsp1_sru.o vsp1_uds.o
 vsp1-y					+= vsp1_hgo.o vsp1_hgt.o vsp1_histo.o
-vsp1-y					+= vsp1_lif.o
+vsp1-y					+= vsp1_lif.o vsp1_uif.o
 
 obj-$(CONFIG_VIDEO_RENESAS_VSP1)	+= vsp1.o
diff --git a/drivers/media/platform/vsp1/vsp1.h b/drivers/media/platform/vsp1/vsp1.h
index 9cf4e1c4b036..33f632331474 100644
--- a/drivers/media/platform/vsp1/vsp1.h
+++ b/drivers/media/platform/vsp1/vsp1.h
@@ -36,10 +36,12 @@ struct vsp1_lut;
 struct vsp1_rwpf;
 struct vsp1_sru;
 struct vsp1_uds;
+struct vsp1_uif;
 
 #define VSP1_MAX_LIF		2
 #define VSP1_MAX_RPF		5
 #define VSP1_MAX_UDS		3
+#define VSP1_MAX_UIF		2
 #define VSP1_MAX_WPF		4
 
 #define VSP1_HAS_LUT		(1 << 1)
@@ -60,6 +62,7 @@ struct vsp1_device_info {
 	unsigned int lif_count;
 	unsigned int rpf_count;
 	unsigned int uds_count;
+	unsigned int uif_count;
 	unsigned int wpf_count;
 	unsigned int num_bru_inputs;
 	bool uapi;
@@ -86,6 +89,7 @@ struct vsp1_device {
 	struct vsp1_rwpf *rpf[VSP1_MAX_RPF];
 	struct vsp1_sru *sru;
 	struct vsp1_uds *uds[VSP1_MAX_UDS];
+	struct vsp1_uif *uif[VSP1_MAX_UIF];
 	struct vsp1_rwpf *wpf[VSP1_MAX_WPF];
 
 	struct list_head entities;
diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
index 331a2e0af0d3..d29f9c4baebe 100644
--- a/drivers/media/platform/vsp1/vsp1_drv.c
+++ b/drivers/media/platform/vsp1/vsp1_drv.c
@@ -35,6 +35,7 @@
 #include "vsp1_rwpf.h"
 #include "vsp1_sru.h"
 #include "vsp1_uds.h"
+#include "vsp1_uif.h"
 #include "vsp1_video.h"
 
 /* -----------------------------------------------------------------------------
@@ -409,6 +410,19 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
 		list_add_tail(&uds->entity.list_dev, &vsp1->entities);
 	}
 
+	for (i = 0; i < vsp1->info->uif_count; ++i) {
+		struct vsp1_uif *uif;
+
+		uif = vsp1_uif_create(vsp1, i);
+		if (IS_ERR(uif)) {
+			ret = PTR_ERR(uif);
+			goto done;
+		}
+
+		vsp1->uif[i] = uif;
+		list_add_tail(&uif->entity.list_dev, &vsp1->entities);
+	}
+
 	for (i = 0; i < vsp1->info->wpf_count; ++i) {
 		struct vsp1_rwpf *wpf;
 
@@ -513,6 +527,9 @@ static int vsp1_device_init(struct vsp1_device *vsp1)
 	for (i = 0; i < vsp1->info->uds_count; ++i)
 		vsp1_write(vsp1, VI6_DPR_UDS_ROUTE(i), VI6_DPR_NODE_UNUSED);
 
+	for (i = 0; i < vsp1->info->uif_count; ++i)
+		vsp1_write(vsp1, VI6_DPR_UIF_ROUTE(i), VI6_DPR_NODE_UNUSED);
+
 	vsp1_write(vsp1, VI6_DPR_SRU_ROUTE, VI6_DPR_NODE_UNUSED);
 	vsp1_write(vsp1, VI6_DPR_LUT_ROUTE, VI6_DPR_NODE_UNUSED);
 	vsp1_write(vsp1, VI6_DPR_CLU_ROUTE, VI6_DPR_NODE_UNUSED);
@@ -740,6 +757,7 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
 		.features = VSP1_HAS_BRU | VSP1_HAS_WPF_VFLIP,
 		.lif_count = 1,
 		.rpf_count = 5,
+		.uif_count = 1,
 		.wpf_count = 2,
 		.num_bru_inputs = 5,
 	}, {
@@ -749,6 +767,7 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
 		.features = VSP1_HAS_BRS | VSP1_HAS_BRU,
 		.lif_count = 1,
 		.rpf_count = 5,
+		.uif_count = 1,
 		.wpf_count = 1,
 		.num_bru_inputs = 5,
 	}, {
@@ -758,6 +777,7 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
 		.features = VSP1_HAS_BRS | VSP1_HAS_BRU,
 		.lif_count = 2,
 		.rpf_count = 5,
+		.uif_count = 2,
 		.wpf_count = 2,
 		.num_bru_inputs = 5,
 	},
diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c
index 181a583aecad..122e60eb1489 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.c
+++ b/drivers/media/platform/vsp1/vsp1_entity.c
@@ -539,6 +539,10 @@ struct media_pad *vsp1_entity_remote_pad(struct media_pad *pad)
 	{ VSP1_ENTITY_UDS, idx, VI6_DPR_UDS_ROUTE(idx),			\
 	  { VI6_DPR_NODE_UDS(idx) }, VI6_DPR_NODE_UDS(idx) }
 
+#define VSP1_ENTITY_ROUTE_UIF(idx)					\
+	{ VSP1_ENTITY_UIF, idx, VI6_DPR_UIF_ROUTE(idx),			\
+	  { VI6_DPR_NODE_UIF(idx) }, VI6_DPR_NODE_UIF(idx) }
+
 #define VSP1_ENTITY_ROUTE_WPF(idx)					\
 	{ VSP1_ENTITY_WPF, idx, 0,					\
 	  { VI6_DPR_NODE_WPF(idx) }, VI6_DPR_NODE_WPF(idx) }
@@ -567,6 +571,8 @@ static const struct vsp1_route vsp1_routes[] = {
 	VSP1_ENTITY_ROUTE_UDS(0),
 	VSP1_ENTITY_ROUTE_UDS(1),
 	VSP1_ENTITY_ROUTE_UDS(2),
+	VSP1_ENTITY_ROUTE_UIF(0),	/* Named UIF4 in the documentation */
+	VSP1_ENTITY_ROUTE_UIF(1),	/* Named UIF5 in the documentation */
 	VSP1_ENTITY_ROUTE_WPF(0),
 	VSP1_ENTITY_ROUTE_WPF(1),
 	VSP1_ENTITY_ROUTE_WPF(2),
diff --git a/drivers/media/platform/vsp1/vsp1_entity.h b/drivers/media/platform/vsp1/vsp1_entity.h
index 0839a62cfa71..94490d697dcf 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.h
+++ b/drivers/media/platform/vsp1/vsp1_entity.h
@@ -33,6 +33,7 @@ enum vsp1_entity_type {
 	VSP1_ENTITY_RPF,
 	VSP1_ENTITY_SRU,
 	VSP1_ENTITY_UDS,
+	VSP1_ENTITY_UIF,
 	VSP1_ENTITY_WPF,
 };
 
diff --git a/drivers/media/platform/vsp1/vsp1_regs.h b/drivers/media/platform/vsp1/vsp1_regs.h
index 3201ad4b77d4..0d249ff9f564 100644
--- a/drivers/media/platform/vsp1/vsp1_regs.h
+++ b/drivers/media/platform/vsp1/vsp1_regs.h
@@ -307,6 +307,44 @@
 #define VI6_WPF_WRBCK_CTRL		0x1034
 #define VI6_WPF_WRBCK_CTRL_WBMD		(1 << 0)
 
+/* -----------------------------------------------------------------------------
+ * UIF Control Registers
+ */
+
+#define VI6_UIF_OFFSET			0x100
+
+#define VI6_UIF_DISCOM_DOCMCR		0x1c00
+#define VI6_UIF_DISCOM_DOCMCR_CMPRU	(1 << 16)
+#define VI6_UIF_DISCOM_DOCMCR_CMPR	(1 << 0)
+
+#define VI6_UIF_DISCOM_DOCMSTR		0x1c04
+#define VI6_UIF_DISCOM_DOCMSTR_CMPPRE	(1 << 1)
+#define VI6_UIF_DISCOM_DOCMSTR_CMPST	(1 << 0)
+
+#define VI6_UIF_DISCOM_DOCMCLSTR	0x1c08
+#define VI6_UIF_DISCOM_DOCMCLSTR_CMPCLPRE	(1 << 1)
+#define VI6_UIF_DISCOM_DOCMCLSTR_CMPCLST	(1 << 0)
+
+#define VI6_UIF_DISCOM_DOCMIENR		0x1c0c
+#define VI6_UIF_DISCOM_DOCMIENR_CMPPREIEN	(1 << 1)
+#define VI6_UIF_DISCOM_DOCMIENR_CMPIEN		(1 << 0)
+
+#define VI6_UIF_DISCOM_DOCMMDR		0x1c10
+#define VI6_UIF_DISCOM_DOCMMDR_INTHRH(n)	((n) << 16)
+
+#define VI6_UIF_DISCOM_DOCMPMR		0x1c14
+#define VI6_UIF_DISCOM_DOCMPMR_CMPDFF(n)	((n) << 17)
+#define VI6_UIF_DISCOM_DOCMPMR_CMPDFA(n)	((n) << 8)
+#define VI6_UIF_DISCOM_DOCMPMR_CMPDAUF		(1 << 7)
+#define VI6_UIF_DISCOM_DOCMPMR_SEL(n)		((n) << 0)
+
+#define VI6_UIF_DISCOM_DOCMECRCR	0x1c18
+#define VI6_UIF_DISCOM_DOCMCCRCR	0x1c1c
+#define VI6_UIF_DISCOM_DOCMSPXR		0x1c20
+#define VI6_UIF_DISCOM_DOCMSPYR		0x1c24
+#define VI6_UIF_DISCOM_DOCMSZXR		0x1c28
+#define VI6_UIF_DISCOM_DOCMSZYR		0x1c2c
+
 /* -----------------------------------------------------------------------------
  * DPR Control Registers
  */
@@ -339,7 +377,10 @@
 #define VI6_DPR_SMPPT_PT_MASK		(0x3f << 0)
 #define VI6_DPR_SMPPT_PT_SHIFT		0
 
+#define VI6_DPR_UIF_ROUTE(n)		(0x2074 + (n) * 4)
+
 #define VI6_DPR_NODE_RPF(n)		(n)
+#define VI6_DPR_NODE_UIF(n)		(12 + (n))
 #define VI6_DPR_NODE_SRU		16
 #define VI6_DPR_NODE_UDS(n)		(17 + (n))
 #define VI6_DPR_NODE_LUT		22
diff --git a/drivers/media/platform/vsp1/vsp1_uif.c b/drivers/media/platform/vsp1/vsp1_uif.c
new file mode 100644
index 000000000000..6de7e9c801ae
--- /dev/null
+++ b/drivers/media/platform/vsp1/vsp1_uif.c
@@ -0,0 +1,271 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * vsp1_uif.c  --  R-Car VSP1 User Logic Interface
+ *
+ * Copyright (C) 2017-2018 Laurent Pinchart
+ *
+ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
+ */
+
+#include <linux/device.h>
+#include <linux/gfp.h>
+#include <linux/sys_soc.h>
+
+#include <media/media-entity.h>
+#include <media/v4l2-subdev.h>
+
+#include "vsp1.h"
+#include "vsp1_dl.h"
+#include "vsp1_entity.h"
+#include "vsp1_uif.h"
+
+#define UIF_MIN_SIZE				4U
+#define UIF_MAX_SIZE				8190U
+
+/* -----------------------------------------------------------------------------
+ * Device Access
+ */
+
+static inline u32 vsp1_uif_read(struct vsp1_uif *uif, u32 reg)
+{
+	return vsp1_read(uif->entity.vsp1,
+			 uif->entity.index * VI6_UIF_OFFSET + reg);
+}
+static inline void vsp1_uif_write(struct vsp1_uif *uif, struct vsp1_dl_list *dl,
+				  u32 reg, u32 data)
+{
+	vsp1_dl_list_write(dl, reg + uif->entity.index * VI6_UIF_OFFSET, data);
+}
+
+u32 vsp1_uif_get_crc(struct vsp1_uif *uif)
+{
+	return vsp1_uif_read(uif, VI6_UIF_DISCOM_DOCMCCRCR);
+}
+
+/* -----------------------------------------------------------------------------
+ * V4L2 Subdevice Pad Operations
+ */
+
+static const unsigned int uif_codes[] = {
+	MEDIA_BUS_FMT_ARGB8888_1X32,
+	MEDIA_BUS_FMT_AHSV8888_1X32,
+	MEDIA_BUS_FMT_AYUV8_1X32,
+};
+
+static int uif_enum_mbus_code(struct v4l2_subdev *subdev,
+			      struct v4l2_subdev_pad_config *cfg,
+			      struct v4l2_subdev_mbus_code_enum *code)
+{
+	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, uif_codes,
+					  ARRAY_SIZE(uif_codes));
+}
+
+static int uif_enum_frame_size(struct v4l2_subdev *subdev,
+			       struct v4l2_subdev_pad_config *cfg,
+			       struct v4l2_subdev_frame_size_enum *fse)
+{
+	return vsp1_subdev_enum_frame_size(subdev, cfg, fse, UIF_MIN_SIZE,
+					   UIF_MIN_SIZE, UIF_MAX_SIZE,
+					   UIF_MAX_SIZE);
+}
+
+static int uif_set_format(struct v4l2_subdev *subdev,
+			    struct v4l2_subdev_pad_config *cfg,
+			    struct v4l2_subdev_format *fmt)
+{
+	return vsp1_subdev_set_pad_format(subdev, cfg, fmt, uif_codes,
+					  ARRAY_SIZE(uif_codes),
+					  UIF_MIN_SIZE, UIF_MIN_SIZE,
+					  UIF_MAX_SIZE, UIF_MAX_SIZE);
+}
+
+static int uif_get_selection(struct v4l2_subdev *subdev,
+			     struct v4l2_subdev_pad_config *cfg,
+			     struct v4l2_subdev_selection *sel)
+{
+	struct vsp1_uif *uif = to_uif(subdev);
+	struct v4l2_subdev_pad_config *config;
+	struct v4l2_mbus_framefmt *format;
+	int ret = 0;
+
+	if (sel->pad != UIF_PAD_SINK)
+		return -EINVAL;
+
+	mutex_lock(&uif->entity.lock);
+
+	config = vsp1_entity_get_pad_config(&uif->entity, cfg, sel->which);
+	if (!config) {
+		ret = -EINVAL;
+		goto done;
+	}
+
+	switch (sel->target) {
+	case V4L2_SEL_TGT_CROP_BOUNDS:
+	case V4L2_SEL_TGT_CROP_DEFAULT:
+		format = vsp1_entity_get_pad_format(&uif->entity, config,
+						    UIF_PAD_SINK);
+		sel->r.left = 0;
+		sel->r.top = 0;
+		sel->r.width = format->width;
+		sel->r.height = format->height;
+		break;
+
+	case V4L2_SEL_TGT_CROP:
+		sel->r = *vsp1_entity_get_pad_selection(&uif->entity, config,
+							sel->pad, sel->target);
+		break;
+
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+done:
+	mutex_unlock(&uif->entity.lock);
+	return ret;
+}
+
+static int uif_set_selection(struct v4l2_subdev *subdev,
+			     struct v4l2_subdev_pad_config *cfg,
+			     struct v4l2_subdev_selection *sel)
+{
+	struct vsp1_uif *uif = to_uif(subdev);
+	struct v4l2_subdev_pad_config *config;
+	struct v4l2_mbus_framefmt *format;
+	struct v4l2_rect *selection;
+	int ret = 0;
+
+	if (sel->pad != UIF_PAD_SINK ||
+	    sel->target != V4L2_SEL_TGT_CROP)
+		return -EINVAL;
+
+	mutex_lock(&uif->entity.lock);
+
+	config = vsp1_entity_get_pad_config(&uif->entity, cfg, sel->which);
+	if (!config) {
+		ret = -EINVAL;
+		goto done;
+	}
+
+	/* The crop rectangle must be inside the input frame. */
+	format = vsp1_entity_get_pad_format(&uif->entity, config, UIF_PAD_SINK);
+
+	sel->r.left = clamp_t(unsigned int, sel->r.left, 0, format->width - 1);
+	sel->r.top = clamp_t(unsigned int, sel->r.top, 0, format->height - 1);
+	sel->r.width = clamp_t(unsigned int, sel->r.width, UIF_MIN_SIZE,
+			       format->width - sel->r.left);
+	sel->r.height = clamp_t(unsigned int, sel->r.height, UIF_MIN_SIZE,
+				format->height - sel->r.top);
+
+	/* Store the crop rectangle. */
+	selection = vsp1_entity_get_pad_selection(&uif->entity, config,
+						  sel->pad, V4L2_SEL_TGT_CROP);
+	*selection = sel->r;
+
+done:
+	mutex_unlock(&uif->entity.lock);
+	return ret;
+}
+
+/* -----------------------------------------------------------------------------
+ * V4L2 Subdevice Operations
+ */
+
+static const struct v4l2_subdev_pad_ops uif_pad_ops = {
+	.init_cfg = vsp1_entity_init_cfg,
+	.enum_mbus_code = uif_enum_mbus_code,
+	.enum_frame_size = uif_enum_frame_size,
+	.get_fmt = vsp1_subdev_get_pad_format,
+	.set_fmt = uif_set_format,
+	.get_selection = uif_get_selection,
+	.set_selection = uif_set_selection,
+};
+
+static const struct v4l2_subdev_ops uif_ops = {
+	.pad    = &uif_pad_ops,
+};
+
+/* -----------------------------------------------------------------------------
+ * VSP1 Entity Operations
+ */
+
+static void uif_configure(struct vsp1_entity *entity,
+			  struct vsp1_pipeline *pipe,
+			  struct vsp1_dl_list *dl,
+			  enum vsp1_entity_params params)
+{
+	struct vsp1_uif *uif = to_uif(&entity->subdev);
+	const struct v4l2_rect *crop;
+	unsigned int left;
+	unsigned int width;
+
+	/*
+	 * Per-partition configuration isn't needed as the DISCOM is used in
+	 * display pipelines only.
+	 */
+	if (params != VSP1_ENTITY_PARAMS_INIT)
+		return;
+
+	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMPMR,
+		       VI6_UIF_DISCOM_DOCMPMR_SEL(9));
+
+	crop = vsp1_entity_get_pad_selection(entity, entity->config,
+					     UIF_PAD_SINK, V4L2_SEL_TGT_CROP);
+
+	/* On M3-W the horizontal coordinates are twice the register value. */
+	if (uif->m3w_quirk) {
+		left = crop->left / 2;
+		width = crop->width / 2;
+	} else {
+		left = crop->left;
+		width = crop->width;
+	}
+
+	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMSPXR, left);
+	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMSPYR, crop->top);
+	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMSZXR, width);
+	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMSZYR, crop->height);
+
+	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMCR,
+		       VI6_UIF_DISCOM_DOCMCR_CMPR);
+}
+
+static const struct vsp1_entity_operations uif_entity_ops = {
+	.configure = uif_configure,
+};
+
+/* -----------------------------------------------------------------------------
+ * Initialization and Cleanup
+ */
+
+static const struct soc_device_attribute vsp1_r8a7796[] = {
+	{ .soc_id = "r8a7796" },
+	{ /* sentinel */ }
+};
+
+struct vsp1_uif *vsp1_uif_create(struct vsp1_device *vsp1, unsigned int index)
+{
+	struct vsp1_uif *uif;
+	char name[6];
+	int ret;
+
+	uif = devm_kzalloc(vsp1->dev, sizeof(*uif), GFP_KERNEL);
+	if (uif == NULL)
+		return ERR_PTR(-ENOMEM);
+
+	if (soc_device_match(vsp1_r8a7796))
+		uif->m3w_quirk = true;
+
+	uif->entity.ops = &uif_entity_ops;
+	uif->entity.type = VSP1_ENTITY_UIF;
+	uif->entity.index = index;
+
+	/* The datasheet names the two UIF instances UIF4 and UIF5. */
+	sprintf(name, "uif.%u", index + 4);
+	ret = vsp1_entity_init(vsp1, &uif->entity, name, 2, &uif_ops,
+			       MEDIA_ENT_F_PROC_VIDEO_STATISTICS);
+	if (ret < 0)
+		return ERR_PTR(ret);
+
+	return uif;
+}
diff --git a/drivers/media/platform/vsp1/vsp1_uif.h b/drivers/media/platform/vsp1/vsp1_uif.h
new file mode 100644
index 000000000000..c71ab5f6a6f8
--- /dev/null
+++ b/drivers/media/platform/vsp1/vsp1_uif.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * vsp1_uif.h  --  R-Car VSP1 User Logic Interface
+ *
+ * Copyright (C) 2017-2018 Laurent Pinchart
+ *
+ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
+ */
+#ifndef __VSP1_UIF_H__
+#define __VSP1_UIF_H__
+
+#include "vsp1_entity.h"
+
+struct vsp1_device;
+
+#define UIF_PAD_SINK				0
+#define UIF_PAD_SOURCE				1
+
+struct vsp1_uif {
+	struct vsp1_entity entity;
+	bool m3w_quirk;
+};
+
+static inline struct vsp1_uif *to_uif(struct v4l2_subdev *subdev)
+{
+	return container_of(subdev, struct vsp1_uif, entity.subdev);
+}
+
+struct vsp1_uif *vsp1_uif_create(struct vsp1_device *vsp1, unsigned int index);
+u32 vsp1_uif_get_crc(struct vsp1_uif *uif);
+
+#endif /* __VSP1_UIF_H__ */
-- 
Regards,

Laurent Pinchart

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

* [PATCH v2 6/8] v4l: vsp1: Add support for the DISCOM entity
@ 2018-04-22 22:34   ` Laurent Pinchart
  0 siblings, 0 replies; 82+ messages in thread
From: Laurent Pinchart @ 2018-04-22 22:34 UTC (permalink / raw)
  To: linux-media, dri-devel; +Cc: linux-renesas-soc, Kieran Bingham

The DISCOM calculates a CRC on a configurable window of the frame. It
interfaces to the VSP through the UIF glue, hence the name used in the
code.

The module supports configuration of the CRC window through the crop
rectangle on the ink pad of the corresponding entity. However, unlike
the traditional V4L2 subdevice model, the crop rectangle does not
influence the format on the source pad.

Modeling the DISCOM as a sink-only entity would allow adhering to the
V4L2 subdevice model at the expense of more complex code in the driver,
as at the hardware level the UIF is handled as a sink+source entity. As
the DISCOM is only present in R-Car Gen3 VSP-D and VSP-DL instances it
is not exposed to userspace through V4L2 but controlled through the DU
driver. We can thus change this model later if needed without fear of
affecting userspace.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
Changes since v1:

- Don't return uninitialized value from uif_set_selection()
---
 drivers/media/platform/vsp1/Makefile      |   2 +-
 drivers/media/platform/vsp1/vsp1.h        |   4 +
 drivers/media/platform/vsp1/vsp1_drv.c    |  20 +++
 drivers/media/platform/vsp1/vsp1_entity.c |   6 +
 drivers/media/platform/vsp1/vsp1_entity.h |   1 +
 drivers/media/platform/vsp1/vsp1_regs.h   |  41 +++++
 drivers/media/platform/vsp1/vsp1_uif.c    | 271 ++++++++++++++++++++++++++++++
 drivers/media/platform/vsp1/vsp1_uif.h    |  32 ++++
 8 files changed, 376 insertions(+), 1 deletion(-)
 create mode 100644 drivers/media/platform/vsp1/vsp1_uif.c
 create mode 100644 drivers/media/platform/vsp1/vsp1_uif.h

diff --git a/drivers/media/platform/vsp1/Makefile b/drivers/media/platform/vsp1/Makefile
index 596775f932c0..4bb4dcbef7b5 100644
--- a/drivers/media/platform/vsp1/Makefile
+++ b/drivers/media/platform/vsp1/Makefile
@@ -5,6 +5,6 @@ vsp1-y					+= vsp1_rpf.o vsp1_rwpf.o vsp1_wpf.o
 vsp1-y					+= vsp1_clu.o vsp1_hsit.o vsp1_lut.o
 vsp1-y					+= vsp1_brx.o vsp1_sru.o vsp1_uds.o
 vsp1-y					+= vsp1_hgo.o vsp1_hgt.o vsp1_histo.o
-vsp1-y					+= vsp1_lif.o
+vsp1-y					+= vsp1_lif.o vsp1_uif.o
 
 obj-$(CONFIG_VIDEO_RENESAS_VSP1)	+= vsp1.o
diff --git a/drivers/media/platform/vsp1/vsp1.h b/drivers/media/platform/vsp1/vsp1.h
index 9cf4e1c4b036..33f632331474 100644
--- a/drivers/media/platform/vsp1/vsp1.h
+++ b/drivers/media/platform/vsp1/vsp1.h
@@ -36,10 +36,12 @@ struct vsp1_lut;
 struct vsp1_rwpf;
 struct vsp1_sru;
 struct vsp1_uds;
+struct vsp1_uif;
 
 #define VSP1_MAX_LIF		2
 #define VSP1_MAX_RPF		5
 #define VSP1_MAX_UDS		3
+#define VSP1_MAX_UIF		2
 #define VSP1_MAX_WPF		4
 
 #define VSP1_HAS_LUT		(1 << 1)
@@ -60,6 +62,7 @@ struct vsp1_device_info {
 	unsigned int lif_count;
 	unsigned int rpf_count;
 	unsigned int uds_count;
+	unsigned int uif_count;
 	unsigned int wpf_count;
 	unsigned int num_bru_inputs;
 	bool uapi;
@@ -86,6 +89,7 @@ struct vsp1_device {
 	struct vsp1_rwpf *rpf[VSP1_MAX_RPF];
 	struct vsp1_sru *sru;
 	struct vsp1_uds *uds[VSP1_MAX_UDS];
+	struct vsp1_uif *uif[VSP1_MAX_UIF];
 	struct vsp1_rwpf *wpf[VSP1_MAX_WPF];
 
 	struct list_head entities;
diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
index 331a2e0af0d3..d29f9c4baebe 100644
--- a/drivers/media/platform/vsp1/vsp1_drv.c
+++ b/drivers/media/platform/vsp1/vsp1_drv.c
@@ -35,6 +35,7 @@
 #include "vsp1_rwpf.h"
 #include "vsp1_sru.h"
 #include "vsp1_uds.h"
+#include "vsp1_uif.h"
 #include "vsp1_video.h"
 
 /* -----------------------------------------------------------------------------
@@ -409,6 +410,19 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
 		list_add_tail(&uds->entity.list_dev, &vsp1->entities);
 	}
 
+	for (i = 0; i < vsp1->info->uif_count; ++i) {
+		struct vsp1_uif *uif;
+
+		uif = vsp1_uif_create(vsp1, i);
+		if (IS_ERR(uif)) {
+			ret = PTR_ERR(uif);
+			goto done;
+		}
+
+		vsp1->uif[i] = uif;
+		list_add_tail(&uif->entity.list_dev, &vsp1->entities);
+	}
+
 	for (i = 0; i < vsp1->info->wpf_count; ++i) {
 		struct vsp1_rwpf *wpf;
 
@@ -513,6 +527,9 @@ static int vsp1_device_init(struct vsp1_device *vsp1)
 	for (i = 0; i < vsp1->info->uds_count; ++i)
 		vsp1_write(vsp1, VI6_DPR_UDS_ROUTE(i), VI6_DPR_NODE_UNUSED);
 
+	for (i = 0; i < vsp1->info->uif_count; ++i)
+		vsp1_write(vsp1, VI6_DPR_UIF_ROUTE(i), VI6_DPR_NODE_UNUSED);
+
 	vsp1_write(vsp1, VI6_DPR_SRU_ROUTE, VI6_DPR_NODE_UNUSED);
 	vsp1_write(vsp1, VI6_DPR_LUT_ROUTE, VI6_DPR_NODE_UNUSED);
 	vsp1_write(vsp1, VI6_DPR_CLU_ROUTE, VI6_DPR_NODE_UNUSED);
@@ -740,6 +757,7 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
 		.features = VSP1_HAS_BRU | VSP1_HAS_WPF_VFLIP,
 		.lif_count = 1,
 		.rpf_count = 5,
+		.uif_count = 1,
 		.wpf_count = 2,
 		.num_bru_inputs = 5,
 	}, {
@@ -749,6 +767,7 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
 		.features = VSP1_HAS_BRS | VSP1_HAS_BRU,
 		.lif_count = 1,
 		.rpf_count = 5,
+		.uif_count = 1,
 		.wpf_count = 1,
 		.num_bru_inputs = 5,
 	}, {
@@ -758,6 +777,7 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
 		.features = VSP1_HAS_BRS | VSP1_HAS_BRU,
 		.lif_count = 2,
 		.rpf_count = 5,
+		.uif_count = 2,
 		.wpf_count = 2,
 		.num_bru_inputs = 5,
 	},
diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c
index 181a583aecad..122e60eb1489 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.c
+++ b/drivers/media/platform/vsp1/vsp1_entity.c
@@ -539,6 +539,10 @@ struct media_pad *vsp1_entity_remote_pad(struct media_pad *pad)
 	{ VSP1_ENTITY_UDS, idx, VI6_DPR_UDS_ROUTE(idx),			\
 	  { VI6_DPR_NODE_UDS(idx) }, VI6_DPR_NODE_UDS(idx) }
 
+#define VSP1_ENTITY_ROUTE_UIF(idx)					\
+	{ VSP1_ENTITY_UIF, idx, VI6_DPR_UIF_ROUTE(idx),			\
+	  { VI6_DPR_NODE_UIF(idx) }, VI6_DPR_NODE_UIF(idx) }
+
 #define VSP1_ENTITY_ROUTE_WPF(idx)					\
 	{ VSP1_ENTITY_WPF, idx, 0,					\
 	  { VI6_DPR_NODE_WPF(idx) }, VI6_DPR_NODE_WPF(idx) }
@@ -567,6 +571,8 @@ static const struct vsp1_route vsp1_routes[] = {
 	VSP1_ENTITY_ROUTE_UDS(0),
 	VSP1_ENTITY_ROUTE_UDS(1),
 	VSP1_ENTITY_ROUTE_UDS(2),
+	VSP1_ENTITY_ROUTE_UIF(0),	/* Named UIF4 in the documentation */
+	VSP1_ENTITY_ROUTE_UIF(1),	/* Named UIF5 in the documentation */
 	VSP1_ENTITY_ROUTE_WPF(0),
 	VSP1_ENTITY_ROUTE_WPF(1),
 	VSP1_ENTITY_ROUTE_WPF(2),
diff --git a/drivers/media/platform/vsp1/vsp1_entity.h b/drivers/media/platform/vsp1/vsp1_entity.h
index 0839a62cfa71..94490d697dcf 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.h
+++ b/drivers/media/platform/vsp1/vsp1_entity.h
@@ -33,6 +33,7 @@ enum vsp1_entity_type {
 	VSP1_ENTITY_RPF,
 	VSP1_ENTITY_SRU,
 	VSP1_ENTITY_UDS,
+	VSP1_ENTITY_UIF,
 	VSP1_ENTITY_WPF,
 };
 
diff --git a/drivers/media/platform/vsp1/vsp1_regs.h b/drivers/media/platform/vsp1/vsp1_regs.h
index 3201ad4b77d4..0d249ff9f564 100644
--- a/drivers/media/platform/vsp1/vsp1_regs.h
+++ b/drivers/media/platform/vsp1/vsp1_regs.h
@@ -307,6 +307,44 @@
 #define VI6_WPF_WRBCK_CTRL		0x1034
 #define VI6_WPF_WRBCK_CTRL_WBMD		(1 << 0)
 
+/* -----------------------------------------------------------------------------
+ * UIF Control Registers
+ */
+
+#define VI6_UIF_OFFSET			0x100
+
+#define VI6_UIF_DISCOM_DOCMCR		0x1c00
+#define VI6_UIF_DISCOM_DOCMCR_CMPRU	(1 << 16)
+#define VI6_UIF_DISCOM_DOCMCR_CMPR	(1 << 0)
+
+#define VI6_UIF_DISCOM_DOCMSTR		0x1c04
+#define VI6_UIF_DISCOM_DOCMSTR_CMPPRE	(1 << 1)
+#define VI6_UIF_DISCOM_DOCMSTR_CMPST	(1 << 0)
+
+#define VI6_UIF_DISCOM_DOCMCLSTR	0x1c08
+#define VI6_UIF_DISCOM_DOCMCLSTR_CMPCLPRE	(1 << 1)
+#define VI6_UIF_DISCOM_DOCMCLSTR_CMPCLST	(1 << 0)
+
+#define VI6_UIF_DISCOM_DOCMIENR		0x1c0c
+#define VI6_UIF_DISCOM_DOCMIENR_CMPPREIEN	(1 << 1)
+#define VI6_UIF_DISCOM_DOCMIENR_CMPIEN		(1 << 0)
+
+#define VI6_UIF_DISCOM_DOCMMDR		0x1c10
+#define VI6_UIF_DISCOM_DOCMMDR_INTHRH(n)	((n) << 16)
+
+#define VI6_UIF_DISCOM_DOCMPMR		0x1c14
+#define VI6_UIF_DISCOM_DOCMPMR_CMPDFF(n)	((n) << 17)
+#define VI6_UIF_DISCOM_DOCMPMR_CMPDFA(n)	((n) << 8)
+#define VI6_UIF_DISCOM_DOCMPMR_CMPDAUF		(1 << 7)
+#define VI6_UIF_DISCOM_DOCMPMR_SEL(n)		((n) << 0)
+
+#define VI6_UIF_DISCOM_DOCMECRCR	0x1c18
+#define VI6_UIF_DISCOM_DOCMCCRCR	0x1c1c
+#define VI6_UIF_DISCOM_DOCMSPXR		0x1c20
+#define VI6_UIF_DISCOM_DOCMSPYR		0x1c24
+#define VI6_UIF_DISCOM_DOCMSZXR		0x1c28
+#define VI6_UIF_DISCOM_DOCMSZYR		0x1c2c
+
 /* -----------------------------------------------------------------------------
  * DPR Control Registers
  */
@@ -339,7 +377,10 @@
 #define VI6_DPR_SMPPT_PT_MASK		(0x3f << 0)
 #define VI6_DPR_SMPPT_PT_SHIFT		0
 
+#define VI6_DPR_UIF_ROUTE(n)		(0x2074 + (n) * 4)
+
 #define VI6_DPR_NODE_RPF(n)		(n)
+#define VI6_DPR_NODE_UIF(n)		(12 + (n))
 #define VI6_DPR_NODE_SRU		16
 #define VI6_DPR_NODE_UDS(n)		(17 + (n))
 #define VI6_DPR_NODE_LUT		22
diff --git a/drivers/media/platform/vsp1/vsp1_uif.c b/drivers/media/platform/vsp1/vsp1_uif.c
new file mode 100644
index 000000000000..6de7e9c801ae
--- /dev/null
+++ b/drivers/media/platform/vsp1/vsp1_uif.c
@@ -0,0 +1,271 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * vsp1_uif.c  --  R-Car VSP1 User Logic Interface
+ *
+ * Copyright (C) 2017-2018 Laurent Pinchart
+ *
+ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
+ */
+
+#include <linux/device.h>
+#include <linux/gfp.h>
+#include <linux/sys_soc.h>
+
+#include <media/media-entity.h>
+#include <media/v4l2-subdev.h>
+
+#include "vsp1.h"
+#include "vsp1_dl.h"
+#include "vsp1_entity.h"
+#include "vsp1_uif.h"
+
+#define UIF_MIN_SIZE				4U
+#define UIF_MAX_SIZE				8190U
+
+/* -----------------------------------------------------------------------------
+ * Device Access
+ */
+
+static inline u32 vsp1_uif_read(struct vsp1_uif *uif, u32 reg)
+{
+	return vsp1_read(uif->entity.vsp1,
+			 uif->entity.index * VI6_UIF_OFFSET + reg);
+}
+static inline void vsp1_uif_write(struct vsp1_uif *uif, struct vsp1_dl_list *dl,
+				  u32 reg, u32 data)
+{
+	vsp1_dl_list_write(dl, reg + uif->entity.index * VI6_UIF_OFFSET, data);
+}
+
+u32 vsp1_uif_get_crc(struct vsp1_uif *uif)
+{
+	return vsp1_uif_read(uif, VI6_UIF_DISCOM_DOCMCCRCR);
+}
+
+/* -----------------------------------------------------------------------------
+ * V4L2 Subdevice Pad Operations
+ */
+
+static const unsigned int uif_codes[] = {
+	MEDIA_BUS_FMT_ARGB8888_1X32,
+	MEDIA_BUS_FMT_AHSV8888_1X32,
+	MEDIA_BUS_FMT_AYUV8_1X32,
+};
+
+static int uif_enum_mbus_code(struct v4l2_subdev *subdev,
+			      struct v4l2_subdev_pad_config *cfg,
+			      struct v4l2_subdev_mbus_code_enum *code)
+{
+	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, uif_codes,
+					  ARRAY_SIZE(uif_codes));
+}
+
+static int uif_enum_frame_size(struct v4l2_subdev *subdev,
+			       struct v4l2_subdev_pad_config *cfg,
+			       struct v4l2_subdev_frame_size_enum *fse)
+{
+	return vsp1_subdev_enum_frame_size(subdev, cfg, fse, UIF_MIN_SIZE,
+					   UIF_MIN_SIZE, UIF_MAX_SIZE,
+					   UIF_MAX_SIZE);
+}
+
+static int uif_set_format(struct v4l2_subdev *subdev,
+			    struct v4l2_subdev_pad_config *cfg,
+			    struct v4l2_subdev_format *fmt)
+{
+	return vsp1_subdev_set_pad_format(subdev, cfg, fmt, uif_codes,
+					  ARRAY_SIZE(uif_codes),
+					  UIF_MIN_SIZE, UIF_MIN_SIZE,
+					  UIF_MAX_SIZE, UIF_MAX_SIZE);
+}
+
+static int uif_get_selection(struct v4l2_subdev *subdev,
+			     struct v4l2_subdev_pad_config *cfg,
+			     struct v4l2_subdev_selection *sel)
+{
+	struct vsp1_uif *uif = to_uif(subdev);
+	struct v4l2_subdev_pad_config *config;
+	struct v4l2_mbus_framefmt *format;
+	int ret = 0;
+
+	if (sel->pad != UIF_PAD_SINK)
+		return -EINVAL;
+
+	mutex_lock(&uif->entity.lock);
+
+	config = vsp1_entity_get_pad_config(&uif->entity, cfg, sel->which);
+	if (!config) {
+		ret = -EINVAL;
+		goto done;
+	}
+
+	switch (sel->target) {
+	case V4L2_SEL_TGT_CROP_BOUNDS:
+	case V4L2_SEL_TGT_CROP_DEFAULT:
+		format = vsp1_entity_get_pad_format(&uif->entity, config,
+						    UIF_PAD_SINK);
+		sel->r.left = 0;
+		sel->r.top = 0;
+		sel->r.width = format->width;
+		sel->r.height = format->height;
+		break;
+
+	case V4L2_SEL_TGT_CROP:
+		sel->r = *vsp1_entity_get_pad_selection(&uif->entity, config,
+							sel->pad, sel->target);
+		break;
+
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+done:
+	mutex_unlock(&uif->entity.lock);
+	return ret;
+}
+
+static int uif_set_selection(struct v4l2_subdev *subdev,
+			     struct v4l2_subdev_pad_config *cfg,
+			     struct v4l2_subdev_selection *sel)
+{
+	struct vsp1_uif *uif = to_uif(subdev);
+	struct v4l2_subdev_pad_config *config;
+	struct v4l2_mbus_framefmt *format;
+	struct v4l2_rect *selection;
+	int ret = 0;
+
+	if (sel->pad != UIF_PAD_SINK ||
+	    sel->target != V4L2_SEL_TGT_CROP)
+		return -EINVAL;
+
+	mutex_lock(&uif->entity.lock);
+
+	config = vsp1_entity_get_pad_config(&uif->entity, cfg, sel->which);
+	if (!config) {
+		ret = -EINVAL;
+		goto done;
+	}
+
+	/* The crop rectangle must be inside the input frame. */
+	format = vsp1_entity_get_pad_format(&uif->entity, config, UIF_PAD_SINK);
+
+	sel->r.left = clamp_t(unsigned int, sel->r.left, 0, format->width - 1);
+	sel->r.top = clamp_t(unsigned int, sel->r.top, 0, format->height - 1);
+	sel->r.width = clamp_t(unsigned int, sel->r.width, UIF_MIN_SIZE,
+			       format->width - sel->r.left);
+	sel->r.height = clamp_t(unsigned int, sel->r.height, UIF_MIN_SIZE,
+				format->height - sel->r.top);
+
+	/* Store the crop rectangle. */
+	selection = vsp1_entity_get_pad_selection(&uif->entity, config,
+						  sel->pad, V4L2_SEL_TGT_CROP);
+	*selection = sel->r;
+
+done:
+	mutex_unlock(&uif->entity.lock);
+	return ret;
+}
+
+/* -----------------------------------------------------------------------------
+ * V4L2 Subdevice Operations
+ */
+
+static const struct v4l2_subdev_pad_ops uif_pad_ops = {
+	.init_cfg = vsp1_entity_init_cfg,
+	.enum_mbus_code = uif_enum_mbus_code,
+	.enum_frame_size = uif_enum_frame_size,
+	.get_fmt = vsp1_subdev_get_pad_format,
+	.set_fmt = uif_set_format,
+	.get_selection = uif_get_selection,
+	.set_selection = uif_set_selection,
+};
+
+static const struct v4l2_subdev_ops uif_ops = {
+	.pad    = &uif_pad_ops,
+};
+
+/* -----------------------------------------------------------------------------
+ * VSP1 Entity Operations
+ */
+
+static void uif_configure(struct vsp1_entity *entity,
+			  struct vsp1_pipeline *pipe,
+			  struct vsp1_dl_list *dl,
+			  enum vsp1_entity_params params)
+{
+	struct vsp1_uif *uif = to_uif(&entity->subdev);
+	const struct v4l2_rect *crop;
+	unsigned int left;
+	unsigned int width;
+
+	/*
+	 * Per-partition configuration isn't needed as the DISCOM is used in
+	 * display pipelines only.
+	 */
+	if (params != VSP1_ENTITY_PARAMS_INIT)
+		return;
+
+	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMPMR,
+		       VI6_UIF_DISCOM_DOCMPMR_SEL(9));
+
+	crop = vsp1_entity_get_pad_selection(entity, entity->config,
+					     UIF_PAD_SINK, V4L2_SEL_TGT_CROP);
+
+	/* On M3-W the horizontal coordinates are twice the register value. */
+	if (uif->m3w_quirk) {
+		left = crop->left / 2;
+		width = crop->width / 2;
+	} else {
+		left = crop->left;
+		width = crop->width;
+	}
+
+	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMSPXR, left);
+	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMSPYR, crop->top);
+	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMSZXR, width);
+	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMSZYR, crop->height);
+
+	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMCR,
+		       VI6_UIF_DISCOM_DOCMCR_CMPR);
+}
+
+static const struct vsp1_entity_operations uif_entity_ops = {
+	.configure = uif_configure,
+};
+
+/* -----------------------------------------------------------------------------
+ * Initialization and Cleanup
+ */
+
+static const struct soc_device_attribute vsp1_r8a7796[] = {
+	{ .soc_id = "r8a7796" },
+	{ /* sentinel */ }
+};
+
+struct vsp1_uif *vsp1_uif_create(struct vsp1_device *vsp1, unsigned int index)
+{
+	struct vsp1_uif *uif;
+	char name[6];
+	int ret;
+
+	uif = devm_kzalloc(vsp1->dev, sizeof(*uif), GFP_KERNEL);
+	if (uif == NULL)
+		return ERR_PTR(-ENOMEM);
+
+	if (soc_device_match(vsp1_r8a7796))
+		uif->m3w_quirk = true;
+
+	uif->entity.ops = &uif_entity_ops;
+	uif->entity.type = VSP1_ENTITY_UIF;
+	uif->entity.index = index;
+
+	/* The datasheet names the two UIF instances UIF4 and UIF5. */
+	sprintf(name, "uif.%u", index + 4);
+	ret = vsp1_entity_init(vsp1, &uif->entity, name, 2, &uif_ops,
+			       MEDIA_ENT_F_PROC_VIDEO_STATISTICS);
+	if (ret < 0)
+		return ERR_PTR(ret);
+
+	return uif;
+}
diff --git a/drivers/media/platform/vsp1/vsp1_uif.h b/drivers/media/platform/vsp1/vsp1_uif.h
new file mode 100644
index 000000000000..c71ab5f6a6f8
--- /dev/null
+++ b/drivers/media/platform/vsp1/vsp1_uif.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * vsp1_uif.h  --  R-Car VSP1 User Logic Interface
+ *
+ * Copyright (C) 2017-2018 Laurent Pinchart
+ *
+ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
+ */
+#ifndef __VSP1_UIF_H__
+#define __VSP1_UIF_H__
+
+#include "vsp1_entity.h"
+
+struct vsp1_device;
+
+#define UIF_PAD_SINK				0
+#define UIF_PAD_SOURCE				1
+
+struct vsp1_uif {
+	struct vsp1_entity entity;
+	bool m3w_quirk;
+};
+
+static inline struct vsp1_uif *to_uif(struct v4l2_subdev *subdev)
+{
+	return container_of(subdev, struct vsp1_uif, entity.subdev);
+}
+
+struct vsp1_uif *vsp1_uif_create(struct vsp1_device *vsp1, unsigned int index);
+u32 vsp1_uif_get_crc(struct vsp1_uif *uif);
+
+#endif /* __VSP1_UIF_H__ */
-- 
Regards,

Laurent Pinchart

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

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

* [PATCH v2 7/8] v4l: vsp1: Integrate DISCOM in display pipeline
  2018-04-22 22:34 ` Laurent Pinchart
@ 2018-04-22 22:34   ` Laurent Pinchart
  -1 siblings, 0 replies; 82+ messages in thread
From: Laurent Pinchart @ 2018-04-22 22:34 UTC (permalink / raw)
  To: linux-media, dri-devel; +Cc: linux-renesas-soc, Kieran Bingham

The DISCOM is used to compute CRCs on display frames. Integrate it in
the display pipeline at the output of the blending unit to process
output frames.

Computing CRCs on input frames is possible by positioning the DISCOM at
a different point in the pipeline. This use case isn't supported at the
moment and could be implemented by extending the API between the VSP1
and DU drivers if needed.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/platform/vsp1/vsp1_drm.c | 115 ++++++++++++++++++++++++++++++++-
 drivers/media/platform/vsp1/vsp1_drm.h |  12 ++++
 2 files changed, 124 insertions(+), 3 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c
index 5fc31578f9b0..7864b43a90e1 100644
--- a/drivers/media/platform/vsp1/vsp1_drm.c
+++ b/drivers/media/platform/vsp1/vsp1_drm.c
@@ -22,6 +22,7 @@
 #include "vsp1_lif.h"
 #include "vsp1_pipe.h"
 #include "vsp1_rwpf.h"
+#include "vsp1_uif.h"
 
 #define BRX_NAME(e)	(e)->type == VSP1_ENTITY_BRU ? "BRU" : "BRS"
 
@@ -35,8 +36,13 @@ static void vsp1_du_pipeline_frame_end(struct vsp1_pipeline *pipe,
 	struct vsp1_drm_pipeline *drm_pipe = to_vsp1_drm_pipeline(pipe);
 	bool complete = completion == VSP1_DL_FRAME_END_COMPLETED;
 
-	if (drm_pipe->du_complete)
-		drm_pipe->du_complete(drm_pipe->du_private, complete, 0);
+	if (drm_pipe->du_complete) {
+		struct vsp1_entity *uif = drm_pipe->uif;
+		u32 crc;
+
+		crc = uif ? vsp1_uif_get_crc(to_uif(&uif->subdev)) : 0;
+		drm_pipe->du_complete(drm_pipe->du_private, complete, crc);
+	}
 
 	if (completion & VSP1_DL_FRAME_END_INTERNAL) {
 		drm_pipe->force_brx_release = false;
@@ -48,10 +54,65 @@ static void vsp1_du_pipeline_frame_end(struct vsp1_pipeline *pipe,
  * Pipeline Configuration
  */
 
+/*
+ * Insert the UIF in the pipeline between the prev and next entities. If no UIF
+ * is available connect the two entities directly.
+ */
+static int vsp1_du_insert_uif(struct vsp1_device *vsp1,
+			      struct vsp1_pipeline *pipe,
+			      struct vsp1_entity *uif,
+			      struct vsp1_entity *prev, unsigned int prev_pad,
+			      struct vsp1_entity *next, unsigned int next_pad)
+{
+	int ret;
+
+	if (uif) {
+		struct v4l2_subdev_format format;
+
+		prev->sink = uif;
+		prev->sink_pad = UIF_PAD_SINK;
+
+		memset(&format, 0, sizeof(format));
+		format.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+		format.pad = prev_pad;
+
+		ret = v4l2_subdev_call(&prev->subdev, pad, get_fmt, NULL,
+				       &format);
+		if (ret < 0)
+			return ret;
+
+		format.pad = UIF_PAD_SINK;
+
+		ret = v4l2_subdev_call(&uif->subdev, pad, set_fmt, NULL,
+				       &format);
+		if (ret < 0)
+			return ret;
+
+		dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on UIF sink\n",
+			__func__, format.format.width, format.format.height,
+			format.format.code);
+
+		/*
+		 * The UIF doesn't mangle the format between its sink and
+		 * source pads, so there is no need to retrieve the format on
+		 * its source pad.
+		 */
+
+		uif->sink = next;
+		uif->sink_pad = next_pad;
+	} else {
+		prev->sink = next;
+		prev->sink_pad = next_pad;
+	}
+
+	return 0;
+}
+
 /* Setup one RPF and the connected BRx sink pad. */
 static int vsp1_du_pipeline_setup_rpf(struct vsp1_device *vsp1,
 				      struct vsp1_pipeline *pipe,
 				      struct vsp1_rwpf *rpf,
+				      struct vsp1_entity *uif,
 				      unsigned int brx_input)
 {
 	struct v4l2_subdev_selection sel;
@@ -122,6 +183,12 @@ static int vsp1_du_pipeline_setup_rpf(struct vsp1_device *vsp1,
 	if (ret < 0)
 		return ret;
 
+	/* Insert and configure the UIF if available. */
+	ret = vsp1_du_insert_uif(vsp1, pipe, uif, &rpf->entity, RWPF_PAD_SOURCE,
+				 pipe->brx, brx_input);
+	if (ret < 0)
+		return ret;
+
 	/* BRx sink, propagate the format from the RPF source. */
 	format.pad = brx_input;
 
@@ -297,7 +364,10 @@ static unsigned int rpf_zpos(struct vsp1_device *vsp1, struct vsp1_rwpf *rpf)
 static int vsp1_du_pipeline_setup_inputs(struct vsp1_device *vsp1,
 					struct vsp1_pipeline *pipe)
 {
+	struct vsp1_drm_pipeline *drm_pipe = to_vsp1_drm_pipeline(pipe);
 	struct vsp1_rwpf *inputs[VSP1_MAX_RPF] = { NULL, };
+	struct vsp1_entity *uif;
+	bool use_uif = false;
 	struct vsp1_brx *brx;
 	unsigned int i;
 	int ret;
@@ -358,7 +428,11 @@ static int vsp1_du_pipeline_setup_inputs(struct vsp1_device *vsp1,
 		dev_dbg(vsp1->dev, "%s: connecting RPF.%u to %s:%u\n",
 			__func__, rpf->entity.index, BRX_NAME(pipe->brx), i);
 
-		ret = vsp1_du_pipeline_setup_rpf(vsp1, pipe, rpf, i);
+		uif = drm_pipe->crc.source == VSP1_DU_CRC_PLANE &&
+		      drm_pipe->crc.index == i ? drm_pipe->uif : NULL;
+		if (uif)
+			use_uif = true;
+		ret = vsp1_du_pipeline_setup_rpf(vsp1, pipe, rpf, uif, i);
 		if (ret < 0) {
 			dev_err(vsp1->dev,
 				"%s: failed to setup RPF.%u\n",
@@ -367,6 +441,31 @@ static int vsp1_du_pipeline_setup_inputs(struct vsp1_device *vsp1,
 		}
 	}
 
+	/* Insert and configure the UIF at the BRx output if available. */
+	uif = drm_pipe->crc.source == VSP1_DU_CRC_OUTPUT ? drm_pipe->uif : NULL;
+	if (uif)
+		use_uif = true;
+	ret = vsp1_du_insert_uif(vsp1, pipe, uif,
+				 pipe->brx, pipe->brx->source_pad,
+				 &pipe->output->entity, 0);
+	if (ret < 0)
+		dev_err(vsp1->dev, "%s: failed to setup UIF after %s\n",
+			__func__, BRX_NAME(pipe->brx));
+
+	/*
+	 * If the UIF is not in use schedule it for removal by setting its pipe
+	 * pointer to NULL, vsp1_du_pipeline_configure() will remove it from the
+	 * hardware pipeline and from the pipeline's list of entities. Otherwise
+	 * make sure it is present in the pipeline's list of entities if it
+	 * wasn't already.
+	 */
+	if (!use_uif) {
+		drm_pipe->uif->pipe = NULL;
+	} else if (!drm_pipe->uif->pipe) {
+		drm_pipe->uif->pipe = pipe;
+		list_add_tail(&drm_pipe->uif->list_pipe, &pipe->entities);
+	}
+
 	return 0;
 }
 
@@ -748,6 +847,9 @@ void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index,
 	struct vsp1_drm_pipeline *drm_pipe = &vsp1->drm->pipe[pipe_index];
 	struct vsp1_pipeline *pipe = &drm_pipe->pipe;
 
+	drm_pipe->crc.source = cfg->crc.source;
+	drm_pipe->crc.index = cfg->crc.index;
+
 	vsp1_du_pipeline_setup_inputs(vsp1, pipe);
 	vsp1_du_pipeline_configure(pipe);
 	mutex_unlock(&vsp1->drm->lock);
@@ -816,6 +918,13 @@ int vsp1_drm_init(struct vsp1_device *vsp1)
 
 		pipe->lif->pipe = pipe;
 		list_add_tail(&pipe->lif->list_pipe, &pipe->entities);
+
+		/*
+		 * CRC computation is initially disabled, don't add the UIF to
+		 * the pipeline.
+		 */
+		if (i < vsp1->info->uif_count)
+			drm_pipe->uif = &vsp1->uif[i]->entity;
 	}
 
 	/* Disable all RPFs initially. */
diff --git a/drivers/media/platform/vsp1/vsp1_drm.h b/drivers/media/platform/vsp1/vsp1_drm.h
index e5b88b28806c..1e7670955ef0 100644
--- a/drivers/media/platform/vsp1/vsp1_drm.h
+++ b/drivers/media/platform/vsp1/vsp1_drm.h
@@ -13,6 +13,8 @@
 #include <linux/videodev2.h>
 #include <linux/wait.h>
 
+#include <media/vsp1.h>
+
 #include "vsp1_pipe.h"
 
 /**
@@ -22,6 +24,9 @@
  * @height: output display height
  * @force_brx_release: when set, release the BRx during the next reconfiguration
  * @wait_queue: wait queue to wait for BRx release completion
+ * @uif: UIF entity if available for the pipeline
+ * @crc.source: source for CRC calculation
+ * @crc.index: index of the CRC source plane (when crc.source is set to plane)
  * @du_complete: frame completion callback for the DU driver (optional)
  * @du_private: data to be passed to the du_complete callback
  */
@@ -34,6 +39,13 @@ struct vsp1_drm_pipeline {
 	bool force_brx_release;
 	wait_queue_head_t wait_queue;
 
+	struct vsp1_entity *uif;
+
+	struct {
+		enum vsp1_du_crc_source source;
+		unsigned int index;
+	} crc;
+
 	/* Frame synchronisation */
 	void (*du_complete)(void *data, bool completed, u32 crc);
 	void *du_private;
-- 
Regards,

Laurent Pinchart

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

* [PATCH v2 7/8] v4l: vsp1: Integrate DISCOM in display pipeline
@ 2018-04-22 22:34   ` Laurent Pinchart
  0 siblings, 0 replies; 82+ messages in thread
From: Laurent Pinchart @ 2018-04-22 22:34 UTC (permalink / raw)
  To: linux-media, dri-devel; +Cc: linux-renesas-soc, Kieran Bingham

The DISCOM is used to compute CRCs on display frames. Integrate it in
the display pipeline at the output of the blending unit to process
output frames.

Computing CRCs on input frames is possible by positioning the DISCOM at
a different point in the pipeline. This use case isn't supported at the
moment and could be implemented by extending the API between the VSP1
and DU drivers if needed.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/platform/vsp1/vsp1_drm.c | 115 ++++++++++++++++++++++++++++++++-
 drivers/media/platform/vsp1/vsp1_drm.h |  12 ++++
 2 files changed, 124 insertions(+), 3 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c
index 5fc31578f9b0..7864b43a90e1 100644
--- a/drivers/media/platform/vsp1/vsp1_drm.c
+++ b/drivers/media/platform/vsp1/vsp1_drm.c
@@ -22,6 +22,7 @@
 #include "vsp1_lif.h"
 #include "vsp1_pipe.h"
 #include "vsp1_rwpf.h"
+#include "vsp1_uif.h"
 
 #define BRX_NAME(e)	(e)->type == VSP1_ENTITY_BRU ? "BRU" : "BRS"
 
@@ -35,8 +36,13 @@ static void vsp1_du_pipeline_frame_end(struct vsp1_pipeline *pipe,
 	struct vsp1_drm_pipeline *drm_pipe = to_vsp1_drm_pipeline(pipe);
 	bool complete = completion == VSP1_DL_FRAME_END_COMPLETED;
 
-	if (drm_pipe->du_complete)
-		drm_pipe->du_complete(drm_pipe->du_private, complete, 0);
+	if (drm_pipe->du_complete) {
+		struct vsp1_entity *uif = drm_pipe->uif;
+		u32 crc;
+
+		crc = uif ? vsp1_uif_get_crc(to_uif(&uif->subdev)) : 0;
+		drm_pipe->du_complete(drm_pipe->du_private, complete, crc);
+	}
 
 	if (completion & VSP1_DL_FRAME_END_INTERNAL) {
 		drm_pipe->force_brx_release = false;
@@ -48,10 +54,65 @@ static void vsp1_du_pipeline_frame_end(struct vsp1_pipeline *pipe,
  * Pipeline Configuration
  */
 
+/*
+ * Insert the UIF in the pipeline between the prev and next entities. If no UIF
+ * is available connect the two entities directly.
+ */
+static int vsp1_du_insert_uif(struct vsp1_device *vsp1,
+			      struct vsp1_pipeline *pipe,
+			      struct vsp1_entity *uif,
+			      struct vsp1_entity *prev, unsigned int prev_pad,
+			      struct vsp1_entity *next, unsigned int next_pad)
+{
+	int ret;
+
+	if (uif) {
+		struct v4l2_subdev_format format;
+
+		prev->sink = uif;
+		prev->sink_pad = UIF_PAD_SINK;
+
+		memset(&format, 0, sizeof(format));
+		format.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+		format.pad = prev_pad;
+
+		ret = v4l2_subdev_call(&prev->subdev, pad, get_fmt, NULL,
+				       &format);
+		if (ret < 0)
+			return ret;
+
+		format.pad = UIF_PAD_SINK;
+
+		ret = v4l2_subdev_call(&uif->subdev, pad, set_fmt, NULL,
+				       &format);
+		if (ret < 0)
+			return ret;
+
+		dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on UIF sink\n",
+			__func__, format.format.width, format.format.height,
+			format.format.code);
+
+		/*
+		 * The UIF doesn't mangle the format between its sink and
+		 * source pads, so there is no need to retrieve the format on
+		 * its source pad.
+		 */
+
+		uif->sink = next;
+		uif->sink_pad = next_pad;
+	} else {
+		prev->sink = next;
+		prev->sink_pad = next_pad;
+	}
+
+	return 0;
+}
+
 /* Setup one RPF and the connected BRx sink pad. */
 static int vsp1_du_pipeline_setup_rpf(struct vsp1_device *vsp1,
 				      struct vsp1_pipeline *pipe,
 				      struct vsp1_rwpf *rpf,
+				      struct vsp1_entity *uif,
 				      unsigned int brx_input)
 {
 	struct v4l2_subdev_selection sel;
@@ -122,6 +183,12 @@ static int vsp1_du_pipeline_setup_rpf(struct vsp1_device *vsp1,
 	if (ret < 0)
 		return ret;
 
+	/* Insert and configure the UIF if available. */
+	ret = vsp1_du_insert_uif(vsp1, pipe, uif, &rpf->entity, RWPF_PAD_SOURCE,
+				 pipe->brx, brx_input);
+	if (ret < 0)
+		return ret;
+
 	/* BRx sink, propagate the format from the RPF source. */
 	format.pad = brx_input;
 
@@ -297,7 +364,10 @@ static unsigned int rpf_zpos(struct vsp1_device *vsp1, struct vsp1_rwpf *rpf)
 static int vsp1_du_pipeline_setup_inputs(struct vsp1_device *vsp1,
 					struct vsp1_pipeline *pipe)
 {
+	struct vsp1_drm_pipeline *drm_pipe = to_vsp1_drm_pipeline(pipe);
 	struct vsp1_rwpf *inputs[VSP1_MAX_RPF] = { NULL, };
+	struct vsp1_entity *uif;
+	bool use_uif = false;
 	struct vsp1_brx *brx;
 	unsigned int i;
 	int ret;
@@ -358,7 +428,11 @@ static int vsp1_du_pipeline_setup_inputs(struct vsp1_device *vsp1,
 		dev_dbg(vsp1->dev, "%s: connecting RPF.%u to %s:%u\n",
 			__func__, rpf->entity.index, BRX_NAME(pipe->brx), i);
 
-		ret = vsp1_du_pipeline_setup_rpf(vsp1, pipe, rpf, i);
+		uif = drm_pipe->crc.source == VSP1_DU_CRC_PLANE &&
+		      drm_pipe->crc.index == i ? drm_pipe->uif : NULL;
+		if (uif)
+			use_uif = true;
+		ret = vsp1_du_pipeline_setup_rpf(vsp1, pipe, rpf, uif, i);
 		if (ret < 0) {
 			dev_err(vsp1->dev,
 				"%s: failed to setup RPF.%u\n",
@@ -367,6 +441,31 @@ static int vsp1_du_pipeline_setup_inputs(struct vsp1_device *vsp1,
 		}
 	}
 
+	/* Insert and configure the UIF at the BRx output if available. */
+	uif = drm_pipe->crc.source == VSP1_DU_CRC_OUTPUT ? drm_pipe->uif : NULL;
+	if (uif)
+		use_uif = true;
+	ret = vsp1_du_insert_uif(vsp1, pipe, uif,
+				 pipe->brx, pipe->brx->source_pad,
+				 &pipe->output->entity, 0);
+	if (ret < 0)
+		dev_err(vsp1->dev, "%s: failed to setup UIF after %s\n",
+			__func__, BRX_NAME(pipe->brx));
+
+	/*
+	 * If the UIF is not in use schedule it for removal by setting its pipe
+	 * pointer to NULL, vsp1_du_pipeline_configure() will remove it from the
+	 * hardware pipeline and from the pipeline's list of entities. Otherwise
+	 * make sure it is present in the pipeline's list of entities if it
+	 * wasn't already.
+	 */
+	if (!use_uif) {
+		drm_pipe->uif->pipe = NULL;
+	} else if (!drm_pipe->uif->pipe) {
+		drm_pipe->uif->pipe = pipe;
+		list_add_tail(&drm_pipe->uif->list_pipe, &pipe->entities);
+	}
+
 	return 0;
 }
 
@@ -748,6 +847,9 @@ void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index,
 	struct vsp1_drm_pipeline *drm_pipe = &vsp1->drm->pipe[pipe_index];
 	struct vsp1_pipeline *pipe = &drm_pipe->pipe;
 
+	drm_pipe->crc.source = cfg->crc.source;
+	drm_pipe->crc.index = cfg->crc.index;
+
 	vsp1_du_pipeline_setup_inputs(vsp1, pipe);
 	vsp1_du_pipeline_configure(pipe);
 	mutex_unlock(&vsp1->drm->lock);
@@ -816,6 +918,13 @@ int vsp1_drm_init(struct vsp1_device *vsp1)
 
 		pipe->lif->pipe = pipe;
 		list_add_tail(&pipe->lif->list_pipe, &pipe->entities);
+
+		/*
+		 * CRC computation is initially disabled, don't add the UIF to
+		 * the pipeline.
+		 */
+		if (i < vsp1->info->uif_count)
+			drm_pipe->uif = &vsp1->uif[i]->entity;
 	}
 
 	/* Disable all RPFs initially. */
diff --git a/drivers/media/platform/vsp1/vsp1_drm.h b/drivers/media/platform/vsp1/vsp1_drm.h
index e5b88b28806c..1e7670955ef0 100644
--- a/drivers/media/platform/vsp1/vsp1_drm.h
+++ b/drivers/media/platform/vsp1/vsp1_drm.h
@@ -13,6 +13,8 @@
 #include <linux/videodev2.h>
 #include <linux/wait.h>
 
+#include <media/vsp1.h>
+
 #include "vsp1_pipe.h"
 
 /**
@@ -22,6 +24,9 @@
  * @height: output display height
  * @force_brx_release: when set, release the BRx during the next reconfiguration
  * @wait_queue: wait queue to wait for BRx release completion
+ * @uif: UIF entity if available for the pipeline
+ * @crc.source: source for CRC calculation
+ * @crc.index: index of the CRC source plane (when crc.source is set to plane)
  * @du_complete: frame completion callback for the DU driver (optional)
  * @du_private: data to be passed to the du_complete callback
  */
@@ -34,6 +39,13 @@ struct vsp1_drm_pipeline {
 	bool force_brx_release;
 	wait_queue_head_t wait_queue;
 
+	struct vsp1_entity *uif;
+
+	struct {
+		enum vsp1_du_crc_source source;
+		unsigned int index;
+	} crc;
+
 	/* Frame synchronisation */
 	void (*du_complete)(void *data, bool completed, u32 crc);
 	void *du_private;
-- 
Regards,

Laurent Pinchart

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

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

* [PATCH v2 8/8] drm: rcar-du: Add support for CRC computation
  2018-04-22 22:34 ` Laurent Pinchart
@ 2018-04-22 22:34   ` Laurent Pinchart
  -1 siblings, 0 replies; 82+ messages in thread
From: Laurent Pinchart @ 2018-04-22 22:34 UTC (permalink / raw)
  To: linux-media, dri-devel; +Cc: linux-renesas-soc, Kieran Bingham

Implement CRC computation configuration and reporting through the DRM
debugfs-based CRC API. The CRC source can be configured to any input
plane or the pipeline output.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
Changes since v1:

- Format the source names using plane IDs instead of plane indices
---
 drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 156 +++++++++++++++++++++++++++++++--
 drivers/gpu/drm/rcar-du/rcar_du_crtc.h |  19 ++++
 drivers/gpu/drm/rcar-du/rcar_du_vsp.c  |   7 ++
 3 files changed, 176 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index c4420538ec85..d71d709fe3d9 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -691,6 +691,52 @@ static const struct drm_crtc_helper_funcs crtc_helper_funcs = {
 	.atomic_disable = rcar_du_crtc_atomic_disable,
 };
 
+static struct drm_crtc_state *
+rcar_du_crtc_atomic_duplicate_state(struct drm_crtc *crtc)
+{
+	struct rcar_du_crtc_state *state;
+	struct rcar_du_crtc_state *copy;
+
+	if (WARN_ON(!crtc->state))
+		return NULL;
+
+	state = to_rcar_crtc_state(crtc->state);
+	copy = kmemdup(state, sizeof(*state), GFP_KERNEL);
+	if (copy == NULL)
+		return NULL;
+
+	__drm_atomic_helper_crtc_duplicate_state(crtc, &copy->state);
+
+	return &copy->state;
+}
+
+static void rcar_du_crtc_atomic_destroy_state(struct drm_crtc *crtc,
+					      struct drm_crtc_state *state)
+{
+	__drm_atomic_helper_crtc_destroy_state(state);
+	kfree(to_rcar_crtc_state(state));
+}
+
+static void rcar_du_crtc_reset(struct drm_crtc *crtc)
+{
+	struct rcar_du_crtc_state *state;
+
+	if (crtc->state) {
+		rcar_du_crtc_atomic_destroy_state(crtc, crtc->state);
+		crtc->state = NULL;
+	}
+
+	state = kzalloc(sizeof(*state), GFP_KERNEL);
+	if (state == NULL)
+		return;
+
+	state->crc.source = VSP1_DU_CRC_NONE;
+	state->crc.index = 0;
+
+	crtc->state = &state->state;
+	crtc->state->crtc = crtc;
+}
+
 static int rcar_du_crtc_enable_vblank(struct drm_crtc *crtc)
 {
 	struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
@@ -710,15 +756,111 @@ static void rcar_du_crtc_disable_vblank(struct drm_crtc *crtc)
 	rcrtc->vblank_enable = false;
 }
 
-static const struct drm_crtc_funcs crtc_funcs = {
-	.reset = drm_atomic_helper_crtc_reset,
+static int rcar_du_crtc_set_crc_source(struct drm_crtc *crtc,
+				       const char *source_name,
+				       size_t *values_cnt)
+{
+	struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
+	struct drm_modeset_acquire_ctx ctx;
+	struct drm_crtc_state *crtc_state;
+	struct drm_atomic_state *state;
+	enum vsp1_du_crc_source source;
+	unsigned int index = 0;
+	unsigned int i;
+	int ret;
+
+	/*
+	 * Parse the source name. Supported values are "plane%u" to compute the
+	 * CRC on an input plane (%u is the plane ID), and "auto" to compute the
+	 * CRC on the composer (VSP) output.
+	 */
+	if (!source_name) {
+		source = VSP1_DU_CRC_NONE;
+	} else if (!strcmp(source_name, "auto")) {
+		source = VSP1_DU_CRC_OUTPUT;
+	} else if (strstarts(source_name, "plane")) {
+		source = VSP1_DU_CRC_PLANE;
+
+		ret = kstrtouint(source_name + strlen("plane"), 10, &index);
+		if (ret < 0)
+			return ret;
+
+		for (i = 0; i < rcrtc->vsp->num_planes; ++i) {
+			if (index == rcrtc->vsp->planes[i].plane.base.id) {
+				index = i;
+				break;
+			}
+		}
+
+		if (i >= rcrtc->vsp->num_planes)
+			return -EINVAL;
+	} else {
+		return -EINVAL;
+	}
+
+	*values_cnt = 1;
+
+	/* Perform an atomic commit to set the CRC source. */
+	drm_modeset_acquire_init(&ctx, 0);
+
+	state = drm_atomic_state_alloc(crtc->dev);
+	if (!state) {
+		ret = -ENOMEM;
+		goto unlock;
+	}
+
+	state->acquire_ctx = &ctx;
+
+retry:
+	crtc_state = drm_atomic_get_crtc_state(state, crtc);
+	if (!IS_ERR(crtc_state)) {
+		struct rcar_du_crtc_state *rcrtc_state;
+
+		rcrtc_state = to_rcar_crtc_state(crtc_state);
+		rcrtc_state->crc.source = source;
+		rcrtc_state->crc.index = index;
+
+		ret = drm_atomic_commit(state);
+	} else {
+		ret = PTR_ERR(crtc_state);
+	}
+
+	if (ret == -EDEADLK) {
+		drm_atomic_state_clear(state);
+		drm_modeset_backoff(&ctx);
+		goto retry;
+	}
+
+	drm_atomic_state_put(state);
+
+unlock:
+	drm_modeset_drop_locks(&ctx);
+	drm_modeset_acquire_fini(&ctx);
+
+	return 0;
+}
+
+static const struct drm_crtc_funcs crtc_funcs_gen2 = {
+	.reset = rcar_du_crtc_reset,
+	.destroy = drm_crtc_cleanup,
+	.set_config = drm_atomic_helper_set_config,
+	.page_flip = drm_atomic_helper_page_flip,
+	.atomic_duplicate_state = rcar_du_crtc_atomic_duplicate_state,
+	.atomic_destroy_state = rcar_du_crtc_atomic_destroy_state,
+	.enable_vblank = rcar_du_crtc_enable_vblank,
+	.disable_vblank = rcar_du_crtc_disable_vblank,
+};
+
+static const struct drm_crtc_funcs crtc_funcs_gen3 = {
+	.reset = rcar_du_crtc_reset,
 	.destroy = drm_crtc_cleanup,
 	.set_config = drm_atomic_helper_set_config,
 	.page_flip = drm_atomic_helper_page_flip,
-	.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
-	.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
+	.atomic_duplicate_state = rcar_du_crtc_atomic_duplicate_state,
+	.atomic_destroy_state = rcar_du_crtc_atomic_destroy_state,
 	.enable_vblank = rcar_du_crtc_enable_vblank,
 	.disable_vblank = rcar_du_crtc_disable_vblank,
+	.set_crc_source = rcar_du_crtc_set_crc_source,
 };
 
 /* -----------------------------------------------------------------------------
@@ -821,8 +963,10 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index)
 	else
 		primary = &rgrp->planes[index % 2].plane;
 
-	ret = drm_crtc_init_with_planes(rcdu->ddev, crtc, primary,
-					NULL, &crtc_funcs, NULL);
+	ret = drm_crtc_init_with_planes(rcdu->ddev, crtc, primary, NULL,
+					rcdu->info->gen <= 2 ?
+					&crtc_funcs_gen2 : &crtc_funcs_gen3,
+					NULL);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
index fdc2bf99bda1..518ee2c60eb8 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
@@ -21,6 +21,8 @@
 #include <drm/drmP.h>
 #include <drm/drm_crtc.h>
 
+#include <media/vsp1.h>
+
 struct rcar_du_group;
 struct rcar_du_vsp;
 
@@ -69,6 +71,23 @@ struct rcar_du_crtc {
 
 #define to_rcar_crtc(c)	container_of(c, struct rcar_du_crtc, crtc)
 
+/**
+ * struct rcar_du_crtc_state - Driver-specific CRTC state
+ * @state: base DRM CRTC state
+ * @crc.source: source for CRC calculation
+ * @crc.index: index of the CRC source plane (when crc.source is set to plane)
+ */
+struct rcar_du_crtc_state {
+	struct drm_crtc_state state;
+
+	struct {
+		enum vsp1_du_crc_source source;
+		unsigned int index;
+	} crc;
+};
+
+#define to_rcar_crtc_state(s) container_of(s, struct rcar_du_crtc_state, state)
+
 enum rcar_du_output {
 	RCAR_DU_OUTPUT_DPAD0,
 	RCAR_DU_OUTPUT_DPAD1,
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
index bdcec201591f..ce19b883ad16 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
@@ -40,6 +40,8 @@ static void rcar_du_vsp_complete(void *private, bool completed, u32 crc)
 
 	if (completed)
 		rcar_du_crtc_finish_page_flip(crtc);
+
+	drm_crtc_add_crc_entry(&crtc->crtc, false, 0, &crc);
 }
 
 void rcar_du_vsp_enable(struct rcar_du_crtc *crtc)
@@ -103,6 +105,11 @@ void rcar_du_vsp_atomic_begin(struct rcar_du_crtc *crtc)
 void rcar_du_vsp_atomic_flush(struct rcar_du_crtc *crtc)
 {
 	struct vsp1_du_atomic_pipe_config cfg = { { 0, } };
+	struct rcar_du_crtc_state *state;
+
+	state = to_rcar_crtc_state(crtc->crtc.state);
+	cfg.crc.source = state->crc.source;
+	cfg.crc.index = state->crc.index;
 
 	vsp1_du_atomic_flush(crtc->vsp->vsp, crtc->vsp_pipe, &cfg);
 }
-- 
Regards,

Laurent Pinchart

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

* [PATCH v2 8/8] drm: rcar-du: Add support for CRC computation
@ 2018-04-22 22:34   ` Laurent Pinchart
  0 siblings, 0 replies; 82+ messages in thread
From: Laurent Pinchart @ 2018-04-22 22:34 UTC (permalink / raw)
  To: linux-media, dri-devel; +Cc: linux-renesas-soc, Kieran Bingham

Implement CRC computation configuration and reporting through the DRM
debugfs-based CRC API. The CRC source can be configured to any input
plane or the pipeline output.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
Changes since v1:

- Format the source names using plane IDs instead of plane indices
---
 drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 156 +++++++++++++++++++++++++++++++--
 drivers/gpu/drm/rcar-du/rcar_du_crtc.h |  19 ++++
 drivers/gpu/drm/rcar-du/rcar_du_vsp.c  |   7 ++
 3 files changed, 176 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index c4420538ec85..d71d709fe3d9 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -691,6 +691,52 @@ static const struct drm_crtc_helper_funcs crtc_helper_funcs = {
 	.atomic_disable = rcar_du_crtc_atomic_disable,
 };
 
+static struct drm_crtc_state *
+rcar_du_crtc_atomic_duplicate_state(struct drm_crtc *crtc)
+{
+	struct rcar_du_crtc_state *state;
+	struct rcar_du_crtc_state *copy;
+
+	if (WARN_ON(!crtc->state))
+		return NULL;
+
+	state = to_rcar_crtc_state(crtc->state);
+	copy = kmemdup(state, sizeof(*state), GFP_KERNEL);
+	if (copy == NULL)
+		return NULL;
+
+	__drm_atomic_helper_crtc_duplicate_state(crtc, &copy->state);
+
+	return &copy->state;
+}
+
+static void rcar_du_crtc_atomic_destroy_state(struct drm_crtc *crtc,
+					      struct drm_crtc_state *state)
+{
+	__drm_atomic_helper_crtc_destroy_state(state);
+	kfree(to_rcar_crtc_state(state));
+}
+
+static void rcar_du_crtc_reset(struct drm_crtc *crtc)
+{
+	struct rcar_du_crtc_state *state;
+
+	if (crtc->state) {
+		rcar_du_crtc_atomic_destroy_state(crtc, crtc->state);
+		crtc->state = NULL;
+	}
+
+	state = kzalloc(sizeof(*state), GFP_KERNEL);
+	if (state == NULL)
+		return;
+
+	state->crc.source = VSP1_DU_CRC_NONE;
+	state->crc.index = 0;
+
+	crtc->state = &state->state;
+	crtc->state->crtc = crtc;
+}
+
 static int rcar_du_crtc_enable_vblank(struct drm_crtc *crtc)
 {
 	struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
@@ -710,15 +756,111 @@ static void rcar_du_crtc_disable_vblank(struct drm_crtc *crtc)
 	rcrtc->vblank_enable = false;
 }
 
-static const struct drm_crtc_funcs crtc_funcs = {
-	.reset = drm_atomic_helper_crtc_reset,
+static int rcar_du_crtc_set_crc_source(struct drm_crtc *crtc,
+				       const char *source_name,
+				       size_t *values_cnt)
+{
+	struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
+	struct drm_modeset_acquire_ctx ctx;
+	struct drm_crtc_state *crtc_state;
+	struct drm_atomic_state *state;
+	enum vsp1_du_crc_source source;
+	unsigned int index = 0;
+	unsigned int i;
+	int ret;
+
+	/*
+	 * Parse the source name. Supported values are "plane%u" to compute the
+	 * CRC on an input plane (%u is the plane ID), and "auto" to compute the
+	 * CRC on the composer (VSP) output.
+	 */
+	if (!source_name) {
+		source = VSP1_DU_CRC_NONE;
+	} else if (!strcmp(source_name, "auto")) {
+		source = VSP1_DU_CRC_OUTPUT;
+	} else if (strstarts(source_name, "plane")) {
+		source = VSP1_DU_CRC_PLANE;
+
+		ret = kstrtouint(source_name + strlen("plane"), 10, &index);
+		if (ret < 0)
+			return ret;
+
+		for (i = 0; i < rcrtc->vsp->num_planes; ++i) {
+			if (index == rcrtc->vsp->planes[i].plane.base.id) {
+				index = i;
+				break;
+			}
+		}
+
+		if (i >= rcrtc->vsp->num_planes)
+			return -EINVAL;
+	} else {
+		return -EINVAL;
+	}
+
+	*values_cnt = 1;
+
+	/* Perform an atomic commit to set the CRC source. */
+	drm_modeset_acquire_init(&ctx, 0);
+
+	state = drm_atomic_state_alloc(crtc->dev);
+	if (!state) {
+		ret = -ENOMEM;
+		goto unlock;
+	}
+
+	state->acquire_ctx = &ctx;
+
+retry:
+	crtc_state = drm_atomic_get_crtc_state(state, crtc);
+	if (!IS_ERR(crtc_state)) {
+		struct rcar_du_crtc_state *rcrtc_state;
+
+		rcrtc_state = to_rcar_crtc_state(crtc_state);
+		rcrtc_state->crc.source = source;
+		rcrtc_state->crc.index = index;
+
+		ret = drm_atomic_commit(state);
+	} else {
+		ret = PTR_ERR(crtc_state);
+	}
+
+	if (ret == -EDEADLK) {
+		drm_atomic_state_clear(state);
+		drm_modeset_backoff(&ctx);
+		goto retry;
+	}
+
+	drm_atomic_state_put(state);
+
+unlock:
+	drm_modeset_drop_locks(&ctx);
+	drm_modeset_acquire_fini(&ctx);
+
+	return 0;
+}
+
+static const struct drm_crtc_funcs crtc_funcs_gen2 = {
+	.reset = rcar_du_crtc_reset,
+	.destroy = drm_crtc_cleanup,
+	.set_config = drm_atomic_helper_set_config,
+	.page_flip = drm_atomic_helper_page_flip,
+	.atomic_duplicate_state = rcar_du_crtc_atomic_duplicate_state,
+	.atomic_destroy_state = rcar_du_crtc_atomic_destroy_state,
+	.enable_vblank = rcar_du_crtc_enable_vblank,
+	.disable_vblank = rcar_du_crtc_disable_vblank,
+};
+
+static const struct drm_crtc_funcs crtc_funcs_gen3 = {
+	.reset = rcar_du_crtc_reset,
 	.destroy = drm_crtc_cleanup,
 	.set_config = drm_atomic_helper_set_config,
 	.page_flip = drm_atomic_helper_page_flip,
-	.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
-	.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
+	.atomic_duplicate_state = rcar_du_crtc_atomic_duplicate_state,
+	.atomic_destroy_state = rcar_du_crtc_atomic_destroy_state,
 	.enable_vblank = rcar_du_crtc_enable_vblank,
 	.disable_vblank = rcar_du_crtc_disable_vblank,
+	.set_crc_source = rcar_du_crtc_set_crc_source,
 };
 
 /* -----------------------------------------------------------------------------
@@ -821,8 +963,10 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index)
 	else
 		primary = &rgrp->planes[index % 2].plane;
 
-	ret = drm_crtc_init_with_planes(rcdu->ddev, crtc, primary,
-					NULL, &crtc_funcs, NULL);
+	ret = drm_crtc_init_with_planes(rcdu->ddev, crtc, primary, NULL,
+					rcdu->info->gen <= 2 ?
+					&crtc_funcs_gen2 : &crtc_funcs_gen3,
+					NULL);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
index fdc2bf99bda1..518ee2c60eb8 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
@@ -21,6 +21,8 @@
 #include <drm/drmP.h>
 #include <drm/drm_crtc.h>
 
+#include <media/vsp1.h>
+
 struct rcar_du_group;
 struct rcar_du_vsp;
 
@@ -69,6 +71,23 @@ struct rcar_du_crtc {
 
 #define to_rcar_crtc(c)	container_of(c, struct rcar_du_crtc, crtc)
 
+/**
+ * struct rcar_du_crtc_state - Driver-specific CRTC state
+ * @state: base DRM CRTC state
+ * @crc.source: source for CRC calculation
+ * @crc.index: index of the CRC source plane (when crc.source is set to plane)
+ */
+struct rcar_du_crtc_state {
+	struct drm_crtc_state state;
+
+	struct {
+		enum vsp1_du_crc_source source;
+		unsigned int index;
+	} crc;
+};
+
+#define to_rcar_crtc_state(s) container_of(s, struct rcar_du_crtc_state, state)
+
 enum rcar_du_output {
 	RCAR_DU_OUTPUT_DPAD0,
 	RCAR_DU_OUTPUT_DPAD1,
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
index bdcec201591f..ce19b883ad16 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
@@ -40,6 +40,8 @@ static void rcar_du_vsp_complete(void *private, bool completed, u32 crc)
 
 	if (completed)
 		rcar_du_crtc_finish_page_flip(crtc);
+
+	drm_crtc_add_crc_entry(&crtc->crtc, false, 0, &crc);
 }
 
 void rcar_du_vsp_enable(struct rcar_du_crtc *crtc)
@@ -103,6 +105,11 @@ void rcar_du_vsp_atomic_begin(struct rcar_du_crtc *crtc)
 void rcar_du_vsp_atomic_flush(struct rcar_du_crtc *crtc)
 {
 	struct vsp1_du_atomic_pipe_config cfg = { { 0, } };
+	struct rcar_du_crtc_state *state;
+
+	state = to_rcar_crtc_state(crtc->crtc.state);
+	cfg.crc.source = state->crc.source;
+	cfg.crc.index = state->crc.index;
 
 	vsp1_du_atomic_flush(crtc->vsp->vsp, crtc->vsp_pipe, &cfg);
 }
-- 
Regards,

Laurent Pinchart

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

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

* igt trouble with planes shared between multiple CRTCs (Re: [PATCH v2 0/8] R-Car DU: Support CRC calculation)
  2018-04-22 22:34 ` Laurent Pinchart
@ 2018-04-27 21:07   ` Laurent Pinchart
  -1 siblings, 0 replies; 82+ messages in thread
From: Laurent Pinchart @ 2018-04-27 21:07 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: dri-devel, linux-renesas-soc, Kieran Bingham, Ulrich Hecht

Hi Daniel,

(Removing the linux-media mailing list from CC as it is out of scope)

You enquired on IRC whether this patch series passes the igt CRC tests.

# ./kms_pipe_crc_basic --run-subtest read-crc-pipe-A
IGT-Version: 1.22-gf447f5fc531d (aarch64) (Linux: 4.17.0-rc1-00085-g56e849d93cc9 aarch64)
read-crc-pipe-A: Testing connector LVDS-1 using pipe A
(kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Test assertion failure function igt_pipe_crc_start, file igt_debugfs.c:764:
(kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Failed assertion: pipe_crc->crc_fd != -1
(kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Last errno: 5, Input/output error
Stack trace:
Subtest read-crc-pipe-A failed.
**** DEBUG ****
(kms_pipe_crc_basic:1638) DEBUG: Test requirement passed: !(pipe >= data->display.n_pipes)
(kms_pipe_crc_basic:1638) INFO: read-crc-pipe-A: Testing connector LVDS-1 using pipe A
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: LVDS-1: set_pipe(A)
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: LVDS-1: Selecting pipe A
(kms_pipe_crc_basic:1638) DEBUG: Clearing the fb with color (0.00,1.00,0.00)
(kms_pipe_crc_basic:1638) igt-fb-DEBUG: igt_create_fb_with_bo_size(width=1024, height=768, format=0x34325258, tiling=0x0, size=0)
(kms_pipe_crc_basic:1638) igt-fb-DEBUG: igt_create_fb_with_bo_size(handle=1, pitch=4096)
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: Test requirement passed: plane_idx >= 0 && plane_idx < pipe->n_planes
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: plane_set_fb(140)
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: plane_set_size (1024x768)
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: fb_set_position(0,0)
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: fb_set_size(1024x768)
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: commit {
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     LVDS-1: SetCrtc pipe A, fb 140, src (0, 0), mode 1024x768
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe A, disabling
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 2, disabling
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 3, disabling
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 4, disabling
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe B, disabling
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 1, disabling
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 2, disabling
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 3, disabling
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 4, disabling
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe C, disabling
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 1, disabling
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 2, disabling
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 3, disabling
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 4, disabling
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe D, disabling
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe D, disabling
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 2, disabling
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 3, disabling
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 4, disabling
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: }
(kms_pipe_crc_basic:1638) igt-debugfs-DEBUG: Opening debugfs directory '/sys/kernel/debug/dri/0'
(kms_pipe_crc_basic:1638) igt-debugfs-DEBUG: Opening debugfs directory '/sys/kernel/debug/dri/0'
(kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Test assertion failure function igt_pipe_crc_start, file igt_debugfs.c:764:
(kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Failed assertion: pipe_crc->crc_fd != -1
(kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Last errno: 5, Input/output error
(kms_pipe_crc_basic:1638) igt-core-INFO: Stack trace:
****  END  ****
Subtest read-crc-pipe-A: FAIL (0.061s)

I think the answer is no, but I don't think it's the fault of this patch
series. Opening the CRC data file returns -EIO because the CRTC is not active,
and I'm trying to find out why that is the case. The debug log shows a commit
that seems strange to me, enabling pipe A and immediately disabling right
afterwards. After some investigation I believe that this is caused by sharing
primary planes between CRTCs.

The R-Car DU groups CRTCs by two and shares 5 planes between the two CRTCs of
the group. This specific SoC has two groups of two CRTCs, but that's not
relevant here, so we can ignore pipes C and D.

Pipes A and B thus shared 5 planes that I will number 0 to 4 for simplicity.
The driver sets plane 0 as the primary plane for CRTC A and plane 1 as the
primary plane for CRTC B. Planes 2, 3 and 4 are created as overlay planes.

When igt iterates over all planes for pipe A, it will first encounter plane 0
that has a framebuffer, and thus enables the pipe. It then iterates over
plane 1, recognizes it as a primary plane without a framebuffer, and thus
disables the pipe. Planes 2, 3 and 4 are recognized as overlay planes and thus
don't affect the pipe active state. Pipe B is handled the same way, and igt
disables it twice as planes 0 and 1 are primary.

I don't know if the fault here is with igt that doesn't properly support this
architecture, or with the driver that shouldn't have two primary planes
available for a CRTC. In the former case, I'm not sure how to fix it, as I'm
not familiar enough with igt to rearchitecture the commit helpers. In the
latter case, how would you recommend fixing it on the driver side ?

On Monday, 23 April 2018 01:34:22 EEST Laurent Pinchart wrote:
> Hello,
> 
> This patch series adds support for CRC calculation to the rcar-du-drm
> driver.
> 
> CRC calculation is supported starting at the Renesas R-Car Gen3 SoCs, as
> earlier versions don't have the necessary hardware. On Gen3 SoCs, the CRC is
> computed by the DISCOM module part of the VSP-D and VSP-DL.
> 
> The DISCOM is interfaced to the VSP through the UIF glue and appears as a
> VSP entity with a sink pad and a source pad.
> 
> The series starts with a switch to SPDX license headers in patch 1/8,
> prompted by a checkpatch.pl warning for a later patch that complained about
> missing SPDX license headers. It then continues with cleanup and
> refactoring. Patches 2/8 and 3/8 prepare for DISCOM and UIF support by
> extending generic code to make it usable for the UIF. Patch 4/8 documents a
> structure that will receive new fields.
> 
> Patch 5/8 then extends the API exposed by the VSP driver to the DU driver to
> support CRC computation configuration and reporting. The patch
> unfortunately needs to touch both the VSP and DU drivers, so the whole
> series will need to be merged through a single tree.
> 
> Patch 5/8 adds support for the DISCOM and UIF in the VSP driver, patch 7/8
> integrates it in the DRM pipeline, and patch 8/8 finally implements the CRC
> API in the DU driver to expose CRC computation to userspace.
> 
> The hardware supports computing the CRC at any arbitrary point in the
> pipeline on a configurable window of the frame. This patch series supports
> CRC computation on input planes or pipeline output, but on the full frame
> only. Support for CRC window configuration can be added later if needed but
> will require extending the userspace API, as the DRM/KMS CRC API doesn't
> support this feature.
> 
> Compared to v1, the CRC source names for plane inputs are now constructed
> from plane IDs instead of plane indices. This allows userspace to match CRC
> sources with planes.
> 
> Note that exposing the DISCOM and UIF though the V4L2 API isn't supported as
> the module is only found in VSP-D and VSP-DL instances that are not exposed
> through V4L2. It is possible to expose those instances through V4L2 with a
> small modification to the driver for testing purpose. If the need arises to
> test DISCOM and UIF with such an out-of-tree patch, support for CRC
> reporting through a V4L2 control can be added later without affecting how
> CRC is exposed through the DRM/KMS API.
> 
> The patches are based on top of the "[PATCH v2 00/15] R-Car VSP1:
> Dynamically assign blend units to display pipelines" patch series, itself
> based on top of the Linux media master branch and scheduled for merge in
> v4.18. The new base caused heavy conflicts, requiring this series to be
> merged through the V4L2 tree. Once the patches receive the necessary review
> I will ask Dave to ack the merge plan.
> 
> For convenience the patches are available at
> 
>         git://linuxtv.org/pinchartl/media.git vsp1-discom-v2-20180423
> 
> The code has been tested through the kms-test-crc.py script part of the DU
> test suite available at
> 
>         git://git.ideasonboard.com/renesas/kms-tests.git discom
> 
> Laurent Pinchart (8):
>   v4l: vsp1: Use SPDX license headers
>   v4l: vsp1: Share the CLU, LIF and LUT set_fmt pad operation code
>   v4l: vsp1: Reset the crop and compose rectangles in the set_fmt helper
>   v4l: vsp1: Document the vsp1_du_atomic_config structure
>   v4l: vsp1: Extend the DU API to support CRC computation
>   v4l: vsp1: Add support for the DISCOM entity
>   v4l: vsp1: Integrate DISCOM in display pipeline
>   drm: rcar-du: Add support for CRC computation
> 
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.c    | 156 ++++++++++++++++-
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.h    |  19 +++
>  drivers/gpu/drm/rcar-du/rcar_du_vsp.c     |  13 +-
>  drivers/media/platform/vsp1/Makefile      |   2 +-
>  drivers/media/platform/vsp1/vsp1.h        |  10 +-
>  drivers/media/platform/vsp1/vsp1_brx.c    |   6 +-
>  drivers/media/platform/vsp1/vsp1_brx.h    |   6 +-
>  drivers/media/platform/vsp1/vsp1_clu.c    |  71 ++------
>  drivers/media/platform/vsp1/vsp1_clu.h    |   6 +-
>  drivers/media/platform/vsp1/vsp1_dl.c     |   8 +-
>  drivers/media/platform/vsp1/vsp1_dl.h     |   6 +-
>  drivers/media/platform/vsp1/vsp1_drm.c    | 127 ++++++++++++--
>  drivers/media/platform/vsp1/vsp1_drm.h    |  20 ++-
>  drivers/media/platform/vsp1/vsp1_drv.c    |  26 ++-
>  drivers/media/platform/vsp1/vsp1_entity.c | 103 +++++++++++-
>  drivers/media/platform/vsp1/vsp1_entity.h |  13 +-
>  drivers/media/platform/vsp1/vsp1_hgo.c    |   6 +-
>  drivers/media/platform/vsp1/vsp1_hgo.h    |   6 +-
>  drivers/media/platform/vsp1/vsp1_hgt.c    |   6 +-
>  drivers/media/platform/vsp1/vsp1_hgt.h    |   6 +-
>  drivers/media/platform/vsp1/vsp1_histo.c  |  65 +------
>  drivers/media/platform/vsp1/vsp1_histo.h  |   6 +-
>  drivers/media/platform/vsp1/vsp1_hsit.c   |   6 +-
>  drivers/media/platform/vsp1/vsp1_hsit.h   |   6 +-
>  drivers/media/platform/vsp1/vsp1_lif.c    |  71 ++------
>  drivers/media/platform/vsp1/vsp1_lif.h    |   6 +-
>  drivers/media/platform/vsp1/vsp1_lut.c    |  71 ++------
>  drivers/media/platform/vsp1/vsp1_lut.h    |   6 +-
>  drivers/media/platform/vsp1/vsp1_pipe.c   |   6 +-
>  drivers/media/platform/vsp1/vsp1_pipe.h   |   6 +-
>  drivers/media/platform/vsp1/vsp1_regs.h   |  46 ++++-
>  drivers/media/platform/vsp1/vsp1_rpf.c    |   6 +-
>  drivers/media/platform/vsp1/vsp1_rwpf.c   |   6 +-
>  drivers/media/platform/vsp1/vsp1_rwpf.h   |   6 +-
>  drivers/media/platform/vsp1/vsp1_sru.c    |   6 +-
>  drivers/media/platform/vsp1/vsp1_sru.h    |   6 +-
>  drivers/media/platform/vsp1/vsp1_uds.c    |   6 +-
>  drivers/media/platform/vsp1/vsp1_uds.h    |   6 +-
>  drivers/media/platform/vsp1/vsp1_uif.c    | 271 +++++++++++++++++++++++++++
>  drivers/media/platform/vsp1/vsp1_uif.h    |  32 ++++
>  drivers/media/platform/vsp1/vsp1_video.c  |   6 +-
>  drivers/media/platform/vsp1/vsp1_video.h  |   6 +-
>  drivers/media/platform/vsp1/vsp1_wpf.c    |   6 +-
>  include/media/vsp1.h                      |  39 ++++-
>  44 files changed, 896 insertions(+), 417 deletions(-)
>  create mode 100644 drivers/media/platform/vsp1/vsp1_uif.c
>  create mode 100644 drivers/media/platform/vsp1/vsp1_uif.h

-- 
Regards,

Laurent Pinchart

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

* igt trouble with planes shared between multiple CRTCs (Re: [PATCH v2 0/8] R-Car DU: Support CRC calculation)
@ 2018-04-27 21:07   ` Laurent Pinchart
  0 siblings, 0 replies; 82+ messages in thread
From: Laurent Pinchart @ 2018-04-27 21:07 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: linux-renesas-soc, Ulrich Hecht, Kieran Bingham, dri-devel

Hi Daniel,

(Removing the linux-media mailing list from CC as it is out of scope)

You enquired on IRC whether this patch series passes the igt CRC tests.

# ./kms_pipe_crc_basic --run-subtest read-crc-pipe-A
IGT-Version: 1.22-gf447f5fc531d (aarch64) (Linux: 4.17.0-rc1-00085-g56e849d93cc9 aarch64)
read-crc-pipe-A: Testing connector LVDS-1 using pipe A
(kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Test assertion failure function igt_pipe_crc_start, file igt_debugfs.c:764:
(kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Failed assertion: pipe_crc->crc_fd != -1
(kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Last errno: 5, Input/output error
Stack trace:
Subtest read-crc-pipe-A failed.
**** DEBUG ****
(kms_pipe_crc_basic:1638) DEBUG: Test requirement passed: !(pipe >= data->display.n_pipes)
(kms_pipe_crc_basic:1638) INFO: read-crc-pipe-A: Testing connector LVDS-1 using pipe A
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: LVDS-1: set_pipe(A)
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: LVDS-1: Selecting pipe A
(kms_pipe_crc_basic:1638) DEBUG: Clearing the fb with color (0.00,1.00,0.00)
(kms_pipe_crc_basic:1638) igt-fb-DEBUG: igt_create_fb_with_bo_size(width=1024, height=768, format=0x34325258, tiling=0x0, size=0)
(kms_pipe_crc_basic:1638) igt-fb-DEBUG: igt_create_fb_with_bo_size(handle=1, pitch=4096)
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: Test requirement passed: plane_idx >= 0 && plane_idx < pipe->n_planes
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: plane_set_fb(140)
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: plane_set_size (1024x768)
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: fb_set_position(0,0)
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: fb_set_size(1024x768)
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: commit {
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     LVDS-1: SetCrtc pipe A, fb 140, src (0, 0), mode 1024x768
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe A, disabling
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 2, disabling
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 3, disabling
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 4, disabling
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe B, disabling
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 1, disabling
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 2, disabling
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 3, disabling
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 4, disabling
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe C, disabling
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 1, disabling
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 2, disabling
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 3, disabling
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 4, disabling
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe D, disabling
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe D, disabling
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 2, disabling
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 3, disabling
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 4, disabling
(kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: }
(kms_pipe_crc_basic:1638) igt-debugfs-DEBUG: Opening debugfs directory '/sys/kernel/debug/dri/0'
(kms_pipe_crc_basic:1638) igt-debugfs-DEBUG: Opening debugfs directory '/sys/kernel/debug/dri/0'
(kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Test assertion failure function igt_pipe_crc_start, file igt_debugfs.c:764:
(kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Failed assertion: pipe_crc->crc_fd != -1
(kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Last errno: 5, Input/output error
(kms_pipe_crc_basic:1638) igt-core-INFO: Stack trace:
****  END  ****
Subtest read-crc-pipe-A: FAIL (0.061s)

I think the answer is no, but I don't think it's the fault of this patch
series. Opening the CRC data file returns -EIO because the CRTC is not active,
and I'm trying to find out why that is the case. The debug log shows a commit
that seems strange to me, enabling pipe A and immediately disabling right
afterwards. After some investigation I believe that this is caused by sharing
primary planes between CRTCs.

The R-Car DU groups CRTCs by two and shares 5 planes between the two CRTCs of
the group. This specific SoC has two groups of two CRTCs, but that's not
relevant here, so we can ignore pipes C and D.

Pipes A and B thus shared 5 planes that I will number 0 to 4 for simplicity.
The driver sets plane 0 as the primary plane for CRTC A and plane 1 as the
primary plane for CRTC B. Planes 2, 3 and 4 are created as overlay planes.

When igt iterates over all planes for pipe A, it will first encounter plane 0
that has a framebuffer, and thus enables the pipe. It then iterates over
plane 1, recognizes it as a primary plane without a framebuffer, and thus
disables the pipe. Planes 2, 3 and 4 are recognized as overlay planes and thus
don't affect the pipe active state. Pipe B is handled the same way, and igt
disables it twice as planes 0 and 1 are primary.

I don't know if the fault here is with igt that doesn't properly support this
architecture, or with the driver that shouldn't have two primary planes
available for a CRTC. In the former case, I'm not sure how to fix it, as I'm
not familiar enough with igt to rearchitecture the commit helpers. In the
latter case, how would you recommend fixing it on the driver side ?

On Monday, 23 April 2018 01:34:22 EEST Laurent Pinchart wrote:
> Hello,
> 
> This patch series adds support for CRC calculation to the rcar-du-drm
> driver.
> 
> CRC calculation is supported starting at the Renesas R-Car Gen3 SoCs, as
> earlier versions don't have the necessary hardware. On Gen3 SoCs, the CRC is
> computed by the DISCOM module part of the VSP-D and VSP-DL.
> 
> The DISCOM is interfaced to the VSP through the UIF glue and appears as a
> VSP entity with a sink pad and a source pad.
> 
> The series starts with a switch to SPDX license headers in patch 1/8,
> prompted by a checkpatch.pl warning for a later patch that complained about
> missing SPDX license headers. It then continues with cleanup and
> refactoring. Patches 2/8 and 3/8 prepare for DISCOM and UIF support by
> extending generic code to make it usable for the UIF. Patch 4/8 documents a
> structure that will receive new fields.
> 
> Patch 5/8 then extends the API exposed by the VSP driver to the DU driver to
> support CRC computation configuration and reporting. The patch
> unfortunately needs to touch both the VSP and DU drivers, so the whole
> series will need to be merged through a single tree.
> 
> Patch 5/8 adds support for the DISCOM and UIF in the VSP driver, patch 7/8
> integrates it in the DRM pipeline, and patch 8/8 finally implements the CRC
> API in the DU driver to expose CRC computation to userspace.
> 
> The hardware supports computing the CRC at any arbitrary point in the
> pipeline on a configurable window of the frame. This patch series supports
> CRC computation on input planes or pipeline output, but on the full frame
> only. Support for CRC window configuration can be added later if needed but
> will require extending the userspace API, as the DRM/KMS CRC API doesn't
> support this feature.
> 
> Compared to v1, the CRC source names for plane inputs are now constructed
> from plane IDs instead of plane indices. This allows userspace to match CRC
> sources with planes.
> 
> Note that exposing the DISCOM and UIF though the V4L2 API isn't supported as
> the module is only found in VSP-D and VSP-DL instances that are not exposed
> through V4L2. It is possible to expose those instances through V4L2 with a
> small modification to the driver for testing purpose. If the need arises to
> test DISCOM and UIF with such an out-of-tree patch, support for CRC
> reporting through a V4L2 control can be added later without affecting how
> CRC is exposed through the DRM/KMS API.
> 
> The patches are based on top of the "[PATCH v2 00/15] R-Car VSP1:
> Dynamically assign blend units to display pipelines" patch series, itself
> based on top of the Linux media master branch and scheduled for merge in
> v4.18. The new base caused heavy conflicts, requiring this series to be
> merged through the V4L2 tree. Once the patches receive the necessary review
> I will ask Dave to ack the merge plan.
> 
> For convenience the patches are available at
> 
>         git://linuxtv.org/pinchartl/media.git vsp1-discom-v2-20180423
> 
> The code has been tested through the kms-test-crc.py script part of the DU
> test suite available at
> 
>         git://git.ideasonboard.com/renesas/kms-tests.git discom
> 
> Laurent Pinchart (8):
>   v4l: vsp1: Use SPDX license headers
>   v4l: vsp1: Share the CLU, LIF and LUT set_fmt pad operation code
>   v4l: vsp1: Reset the crop and compose rectangles in the set_fmt helper
>   v4l: vsp1: Document the vsp1_du_atomic_config structure
>   v4l: vsp1: Extend the DU API to support CRC computation
>   v4l: vsp1: Add support for the DISCOM entity
>   v4l: vsp1: Integrate DISCOM in display pipeline
>   drm: rcar-du: Add support for CRC computation
> 
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.c    | 156 ++++++++++++++++-
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.h    |  19 +++
>  drivers/gpu/drm/rcar-du/rcar_du_vsp.c     |  13 +-
>  drivers/media/platform/vsp1/Makefile      |   2 +-
>  drivers/media/platform/vsp1/vsp1.h        |  10 +-
>  drivers/media/platform/vsp1/vsp1_brx.c    |   6 +-
>  drivers/media/platform/vsp1/vsp1_brx.h    |   6 +-
>  drivers/media/platform/vsp1/vsp1_clu.c    |  71 ++------
>  drivers/media/platform/vsp1/vsp1_clu.h    |   6 +-
>  drivers/media/platform/vsp1/vsp1_dl.c     |   8 +-
>  drivers/media/platform/vsp1/vsp1_dl.h     |   6 +-
>  drivers/media/platform/vsp1/vsp1_drm.c    | 127 ++++++++++++--
>  drivers/media/platform/vsp1/vsp1_drm.h    |  20 ++-
>  drivers/media/platform/vsp1/vsp1_drv.c    |  26 ++-
>  drivers/media/platform/vsp1/vsp1_entity.c | 103 +++++++++++-
>  drivers/media/platform/vsp1/vsp1_entity.h |  13 +-
>  drivers/media/platform/vsp1/vsp1_hgo.c    |   6 +-
>  drivers/media/platform/vsp1/vsp1_hgo.h    |   6 +-
>  drivers/media/platform/vsp1/vsp1_hgt.c    |   6 +-
>  drivers/media/platform/vsp1/vsp1_hgt.h    |   6 +-
>  drivers/media/platform/vsp1/vsp1_histo.c  |  65 +------
>  drivers/media/platform/vsp1/vsp1_histo.h  |   6 +-
>  drivers/media/platform/vsp1/vsp1_hsit.c   |   6 +-
>  drivers/media/platform/vsp1/vsp1_hsit.h   |   6 +-
>  drivers/media/platform/vsp1/vsp1_lif.c    |  71 ++------
>  drivers/media/platform/vsp1/vsp1_lif.h    |   6 +-
>  drivers/media/platform/vsp1/vsp1_lut.c    |  71 ++------
>  drivers/media/platform/vsp1/vsp1_lut.h    |   6 +-
>  drivers/media/platform/vsp1/vsp1_pipe.c   |   6 +-
>  drivers/media/platform/vsp1/vsp1_pipe.h   |   6 +-
>  drivers/media/platform/vsp1/vsp1_regs.h   |  46 ++++-
>  drivers/media/platform/vsp1/vsp1_rpf.c    |   6 +-
>  drivers/media/platform/vsp1/vsp1_rwpf.c   |   6 +-
>  drivers/media/platform/vsp1/vsp1_rwpf.h   |   6 +-
>  drivers/media/platform/vsp1/vsp1_sru.c    |   6 +-
>  drivers/media/platform/vsp1/vsp1_sru.h    |   6 +-
>  drivers/media/platform/vsp1/vsp1_uds.c    |   6 +-
>  drivers/media/platform/vsp1/vsp1_uds.h    |   6 +-
>  drivers/media/platform/vsp1/vsp1_uif.c    | 271 +++++++++++++++++++++++++++
>  drivers/media/platform/vsp1/vsp1_uif.h    |  32 ++++
>  drivers/media/platform/vsp1/vsp1_video.c  |   6 +-
>  drivers/media/platform/vsp1/vsp1_video.h  |   6 +-
>  drivers/media/platform/vsp1/vsp1_wpf.c    |   6 +-
>  include/media/vsp1.h                      |  39 ++++-
>  44 files changed, 896 insertions(+), 417 deletions(-)
>  create mode 100644 drivers/media/platform/vsp1/vsp1_uif.c
>  create mode 100644 drivers/media/platform/vsp1/vsp1_uif.h

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

* Re: [PATCH v2 1/8] v4l: vsp1: Use SPDX license headers
  2018-04-22 22:34   ` Laurent Pinchart
@ 2018-04-27 21:25     ` Kieran Bingham
  -1 siblings, 0 replies; 82+ messages in thread
From: Kieran Bingham @ 2018-04-27 21:25 UTC (permalink / raw)
  To: Laurent Pinchart, linux-media, dri-devel
  Cc: linux-renesas-soc, Kieran Bingham

Hi Laurent,

Thank you for the patch, and going through the whole driver for this update.

On 22/04/18 23:34, Laurent Pinchart wrote:
> Adopt the SPDX license identifier headers to ease license compliance
> management. All files in the driver are licensed under the GPLv2+ except
> for the vsp1_regs.h file which is licensed under the GPLv2. This is
> likely an oversight, but fixing this requires contacting the copyright
> owners and is out of scope for this patch.

I agree that's out of scope for this patch, but it's not too exhaustive a list
to correct at a later date:

git shortlog -e -n -s -- ./drivers/media/platform/vsp1/vsp1_regs.h
    19  Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
     5  Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
     3  Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
     2  Geert Uytterhoeven <geert+renesas@glider.be>
     2  Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
     1  Linus Torvalds <torvalds@linux-foundation.org>
     1  Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
     1  Wolfram Sang <wsa+renesas@sang-engineering.com>

(Both Geert and Linus are merge commits there)

> While at it fix the file descriptions to match file names where copy and
> paste error occurred.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

It's crazy that we have two types of comment style for the SPDX identifier - but
that's not a fault in this patch, so:

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

> ---
>  drivers/media/platform/vsp1/vsp1.h        | 6 +-----
>  drivers/media/platform/vsp1/vsp1_brx.c    | 6 +-----
>  drivers/media/platform/vsp1/vsp1_brx.h    | 6 +-----
>  drivers/media/platform/vsp1/vsp1_clu.c    | 6 +-----
>  drivers/media/platform/vsp1/vsp1_clu.h    | 6 +-----
>  drivers/media/platform/vsp1/vsp1_dl.c     | 8 ++------
>  drivers/media/platform/vsp1/vsp1_dl.h     | 6 +-----
>  drivers/media/platform/vsp1/vsp1_drm.c    | 8 ++------
>  drivers/media/platform/vsp1/vsp1_drm.h    | 6 +-----
>  drivers/media/platform/vsp1/vsp1_drv.c    | 6 +-----
>  drivers/media/platform/vsp1/vsp1_entity.c | 6 +-----
>  drivers/media/platform/vsp1/vsp1_entity.h | 6 +-----
>  drivers/media/platform/vsp1/vsp1_hgo.c    | 6 +-----
>  drivers/media/platform/vsp1/vsp1_hgo.h    | 6 +-----
>  drivers/media/platform/vsp1/vsp1_hgt.c    | 6 +-----
>  drivers/media/platform/vsp1/vsp1_hgt.h    | 6 +-----
>  drivers/media/platform/vsp1/vsp1_histo.c  | 6 +-----
>  drivers/media/platform/vsp1/vsp1_histo.h  | 6 +-----
>  drivers/media/platform/vsp1/vsp1_hsit.c   | 6 +-----
>  drivers/media/platform/vsp1/vsp1_hsit.h   | 6 +-----
>  drivers/media/platform/vsp1/vsp1_lif.c    | 6 +-----
>  drivers/media/platform/vsp1/vsp1_lif.h    | 6 +-----
>  drivers/media/platform/vsp1/vsp1_lut.c    | 6 +-----
>  drivers/media/platform/vsp1/vsp1_lut.h    | 6 +-----
>  drivers/media/platform/vsp1/vsp1_pipe.c   | 6 +-----
>  drivers/media/platform/vsp1/vsp1_pipe.h   | 6 +-----
>  drivers/media/platform/vsp1/vsp1_regs.h   | 5 +----
>  drivers/media/platform/vsp1/vsp1_rpf.c    | 6 +-----
>  drivers/media/platform/vsp1/vsp1_rwpf.c   | 6 +-----
>  drivers/media/platform/vsp1/vsp1_rwpf.h   | 6 +-----
>  drivers/media/platform/vsp1/vsp1_sru.c    | 6 +-----
>  drivers/media/platform/vsp1/vsp1_sru.h    | 6 +-----
>  drivers/media/platform/vsp1/vsp1_uds.c    | 6 +-----
>  drivers/media/platform/vsp1/vsp1_uds.h    | 6 +-----
>  drivers/media/platform/vsp1/vsp1_video.c  | 6 +-----
>  drivers/media/platform/vsp1/vsp1_video.h  | 6 +-----
>  drivers/media/platform/vsp1/vsp1_wpf.c    | 6 +-----
>  37 files changed, 39 insertions(+), 186 deletions(-)
> 
> diff --git a/drivers/media/platform/vsp1/vsp1.h b/drivers/media/platform/vsp1/vsp1.h
> index 894cc725c2d4..9cf4e1c4b036 100644
> --- a/drivers/media/platform/vsp1/vsp1.h
> +++ b/drivers/media/platform/vsp1/vsp1.h
> @@ -1,14 +1,10 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
>  /*
>   * vsp1.h  --  R-Car VSP1 Driver
>   *
>   * Copyright (C) 2013-2014 Renesas Electronics Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  #ifndef __VSP1_H__
>  #define __VSP1_H__
> diff --git a/drivers/media/platform/vsp1/vsp1_brx.c b/drivers/media/platform/vsp1/vsp1_brx.c
> index b4af1d546022..3beec18fd863 100644
> --- a/drivers/media/platform/vsp1/vsp1_brx.c
> +++ b/drivers/media/platform/vsp1/vsp1_brx.c
> @@ -1,14 +1,10 @@
> +// SPDX-License-Identifier: GPL-2.0+
>  /*
>   * vsp1_brx.c  --  R-Car VSP1 Blend ROP Unit (BRU and BRS)
>   *
>   * Copyright (C) 2013 Renesas Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  
>  #include <linux/device.h>
> diff --git a/drivers/media/platform/vsp1/vsp1_brx.h b/drivers/media/platform/vsp1/vsp1_brx.h
> index 927aa4254c0f..6abbb8c3343c 100644
> --- a/drivers/media/platform/vsp1/vsp1_brx.h
> +++ b/drivers/media/platform/vsp1/vsp1_brx.h
> @@ -1,14 +1,10 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
>  /*
>   * vsp1_brx.h  --  R-Car VSP1 Blend ROP Unit (BRU and BRS)
>   *
>   * Copyright (C) 2013 Renesas Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  #ifndef __VSP1_BRX_H__
>  #define __VSP1_BRX_H__
> diff --git a/drivers/media/platform/vsp1/vsp1_clu.c b/drivers/media/platform/vsp1/vsp1_clu.c
> index f2fb26e5ab4e..9626b6308585 100644
> --- a/drivers/media/platform/vsp1/vsp1_clu.c
> +++ b/drivers/media/platform/vsp1/vsp1_clu.c
> @@ -1,14 +1,10 @@
> +// SPDX-License-Identifier: GPL-2.0+
>  /*
>   * vsp1_clu.c  --  R-Car VSP1 Cubic Look-Up Table
>   *
>   * Copyright (C) 2015-2016 Renesas Electronics Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  
>  #include <linux/device.h>
> diff --git a/drivers/media/platform/vsp1/vsp1_clu.h b/drivers/media/platform/vsp1/vsp1_clu.h
> index 036e0a2f1a42..c45e6e707592 100644
> --- a/drivers/media/platform/vsp1/vsp1_clu.h
> +++ b/drivers/media/platform/vsp1/vsp1_clu.h
> @@ -1,14 +1,10 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
>  /*
>   * vsp1_clu.h  --  R-Car VSP1 Cubic Look-Up Table
>   *
>   * Copyright (C) 2015 Renesas Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  #ifndef __VSP1_CLU_H__
>  #define __VSP1_CLU_H__
> diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c
> index 30ad491605ff..801dea475740 100644
> --- a/drivers/media/platform/vsp1/vsp1_dl.c
> +++ b/drivers/media/platform/vsp1/vsp1_dl.c
> @@ -1,14 +1,10 @@
> +// SPDX-License-Identifier: GPL-2.0+
>  /*
> - * vsp1_dl.h  --  R-Car VSP1 Display List
> + * vsp1_dl.c  --  R-Car VSP1 Display List
>   *
>   * Copyright (C) 2015 Renesas Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  
>  #include <linux/device.h>
> diff --git a/drivers/media/platform/vsp1/vsp1_dl.h b/drivers/media/platform/vsp1/vsp1_dl.h
> index 1a5bbd5ddb7b..e6279b1abd19 100644
> --- a/drivers/media/platform/vsp1/vsp1_dl.h
> +++ b/drivers/media/platform/vsp1/vsp1_dl.h
> @@ -1,14 +1,10 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
>  /*
>   * vsp1_dl.h  --  R-Car VSP1 Display List
>   *
>   * Copyright (C) 2015 Renesas Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  #ifndef __VSP1_DL_H__
>  #define __VSP1_DL_H__
> diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c
> index 095dc48aa25a..2b29a83dceb9 100644
> --- a/drivers/media/platform/vsp1/vsp1_drm.c
> +++ b/drivers/media/platform/vsp1/vsp1_drm.c
> @@ -1,14 +1,10 @@
> +// SPDX-License-Identifier: GPL-2.0+
>  /*
> - * vsp1_drm.c  --  R-Car VSP1 DRM API
> + * vsp1_drm.c  --  R-Car VSP1 DRM/KMS Interface
>   *
>   * Copyright (C) 2015 Renesas Electronics Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  
>  #include <linux/device.h>
> diff --git a/drivers/media/platform/vsp1/vsp1_drm.h b/drivers/media/platform/vsp1/vsp1_drm.h
> index d738cc57f0e3..f4af1b2b12d6 100644
> --- a/drivers/media/platform/vsp1/vsp1_drm.h
> +++ b/drivers/media/platform/vsp1/vsp1_drm.h
> @@ -1,14 +1,10 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
>  /*
>   * vsp1_drm.h  --  R-Car VSP1 DRM/KMS Interface
>   *
>   * Copyright (C) 2015 Renesas Electronics Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  #ifndef __VSP1_DRM_H__
>  #define __VSP1_DRM_H__
> diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
> index f41cd70409db..331a2e0af0d3 100644
> --- a/drivers/media/platform/vsp1/vsp1_drv.c
> +++ b/drivers/media/platform/vsp1/vsp1_drv.c
> @@ -1,14 +1,10 @@
> +// SPDX-License-Identifier: GPL-2.0+
>  /*
>   * vsp1_drv.c  --  R-Car VSP1 Driver
>   *
>   * Copyright (C) 2013-2015 Renesas Electronics Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  
>  #include <linux/clk.h>
> diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c
> index 54de15095709..72354caf5746 100644
> --- a/drivers/media/platform/vsp1/vsp1_entity.c
> +++ b/drivers/media/platform/vsp1/vsp1_entity.c
> @@ -1,14 +1,10 @@
> +// SPDX-License-Identifier: GPL-2.0+
>  /*
>   * vsp1_entity.c  --  R-Car VSP1 Base Entity
>   *
>   * Copyright (C) 2013-2014 Renesas Electronics Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  
>  #include <linux/device.h>
> diff --git a/drivers/media/platform/vsp1/vsp1_entity.h b/drivers/media/platform/vsp1/vsp1_entity.h
> index c26523c56c05..fb20a1578f3b 100644
> --- a/drivers/media/platform/vsp1/vsp1_entity.h
> +++ b/drivers/media/platform/vsp1/vsp1_entity.h
> @@ -1,14 +1,10 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
>  /*
>   * vsp1_entity.h  --  R-Car VSP1 Base Entity
>   *
>   * Copyright (C) 2013-2014 Renesas Electronics Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  #ifndef __VSP1_ENTITY_H__
>  #define __VSP1_ENTITY_H__
> diff --git a/drivers/media/platform/vsp1/vsp1_hgo.c b/drivers/media/platform/vsp1/vsp1_hgo.c
> index 50309c053b78..d514807ccdf4 100644
> --- a/drivers/media/platform/vsp1/vsp1_hgo.c
> +++ b/drivers/media/platform/vsp1/vsp1_hgo.c
> @@ -1,14 +1,10 @@
> +// SPDX-License-Identifier: GPL-2.0+
>  /*
>   * vsp1_hgo.c  --  R-Car VSP1 Histogram Generator 1D
>   *
>   * Copyright (C) 2016 Renesas Electronics Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  
>  #include <linux/device.h>
> diff --git a/drivers/media/platform/vsp1/vsp1_hgo.h b/drivers/media/platform/vsp1/vsp1_hgo.h
> index c6c0b7a80e0c..6b0c8580e1bf 100644
> --- a/drivers/media/platform/vsp1/vsp1_hgo.h
> +++ b/drivers/media/platform/vsp1/vsp1_hgo.h
> @@ -1,14 +1,10 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
>  /*
>   * vsp1_hgo.h  --  R-Car VSP1 Histogram Generator 1D
>   *
>   * Copyright (C) 2016 Renesas Electronics Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  #ifndef __VSP1_HGO_H__
>  #define __VSP1_HGO_H__
> diff --git a/drivers/media/platform/vsp1/vsp1_hgt.c b/drivers/media/platform/vsp1/vsp1_hgt.c
> index b5ce305e3e6f..18dc89f47c45 100644
> --- a/drivers/media/platform/vsp1/vsp1_hgt.c
> +++ b/drivers/media/platform/vsp1/vsp1_hgt.c
> @@ -1,14 +1,10 @@
> +// SPDX-License-Identifier: GPL-2.0+
>  /*
>   * vsp1_hgt.c  --  R-Car VSP1 Histogram Generator 2D
>   *
>   * Copyright (C) 2016 Renesas Electronics Corporation
>   *
>   * Contact: Niklas Söderlund (niklas.soderlund@ragnatech.se)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  
>  #include <linux/device.h>
> diff --git a/drivers/media/platform/vsp1/vsp1_hgt.h b/drivers/media/platform/vsp1/vsp1_hgt.h
> index 83f2e130942a..38ec237bdd2d 100644
> --- a/drivers/media/platform/vsp1/vsp1_hgt.h
> +++ b/drivers/media/platform/vsp1/vsp1_hgt.h
> @@ -1,14 +1,10 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
>  /*
>   * vsp1_hgt.h  --  R-Car VSP1 Histogram Generator 2D
>   *
>   * Copyright (C) 2016 Renesas Electronics Corporation
>   *
>   * Contact: Niklas Söderlund (niklas.soderlund@ragnatech.se)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  #ifndef __VSP1_HGT_H__
>  #define __VSP1_HGT_H__
> diff --git a/drivers/media/platform/vsp1/vsp1_histo.c b/drivers/media/platform/vsp1/vsp1_histo.c
> index 8638ebc514b4..029181c1fb61 100644
> --- a/drivers/media/platform/vsp1/vsp1_histo.c
> +++ b/drivers/media/platform/vsp1/vsp1_histo.c
> @@ -1,3 +1,4 @@
> +// SPDX-License-Identifier: GPL-2.0+
>  /*
>   * vsp1_histo.c  --  R-Car VSP1 Histogram API
>   *
> @@ -5,11 +6,6 @@
>   * Copyright (C) 2016 Laurent Pinchart
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  
>  #include <linux/device.h>
> diff --git a/drivers/media/platform/vsp1/vsp1_histo.h b/drivers/media/platform/vsp1/vsp1_histo.h
> index e774adbf251f..06f029846244 100644
> --- a/drivers/media/platform/vsp1/vsp1_histo.h
> +++ b/drivers/media/platform/vsp1/vsp1_histo.h
> @@ -1,3 +1,4 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
>  /*
>   * vsp1_histo.h  --  R-Car VSP1 Histogram API
>   *
> @@ -5,11 +6,6 @@
>   * Copyright (C) 2016 Laurent Pinchart
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  #ifndef __VSP1_HISTO_H__
>  #define __VSP1_HISTO_H__
> diff --git a/drivers/media/platform/vsp1/vsp1_hsit.c b/drivers/media/platform/vsp1/vsp1_hsit.c
> index 764d405345ee..7ba3535f3c9b 100644
> --- a/drivers/media/platform/vsp1/vsp1_hsit.c
> +++ b/drivers/media/platform/vsp1/vsp1_hsit.c
> @@ -1,14 +1,10 @@
> +// SPDX-License-Identifier: GPL-2.0+
>  /*
>   * vsp1_hsit.c  --  R-Car VSP1 Hue Saturation value (Inverse) Transform
>   *
>   * Copyright (C) 2013 Renesas Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  
>  #include <linux/device.h>
> diff --git a/drivers/media/platform/vsp1/vsp1_hsit.h b/drivers/media/platform/vsp1/vsp1_hsit.h
> index 82f1c8426900..a658b1aa49e7 100644
> --- a/drivers/media/platform/vsp1/vsp1_hsit.h
> +++ b/drivers/media/platform/vsp1/vsp1_hsit.h
> @@ -1,14 +1,10 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
>  /*
>   * vsp1_hsit.h  --  R-Car VSP1 Hue Saturation value (Inverse) Transform
>   *
>   * Copyright (C) 2013 Renesas Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  #ifndef __VSP1_HSIT_H__
>  #define __VSP1_HSIT_H__
> diff --git a/drivers/media/platform/vsp1/vsp1_lif.c b/drivers/media/platform/vsp1/vsp1_lif.c
> index 704920753998..b20b842f06ba 100644
> --- a/drivers/media/platform/vsp1/vsp1_lif.c
> +++ b/drivers/media/platform/vsp1/vsp1_lif.c
> @@ -1,14 +1,10 @@
> +// SPDX-License-Identifier: GPL-2.0+
>  /*
>   * vsp1_lif.c  --  R-Car VSP1 LCD Controller Interface
>   *
>   * Copyright (C) 2013-2014 Renesas Electronics Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  
>  #include <linux/device.h>
> diff --git a/drivers/media/platform/vsp1/vsp1_lif.h b/drivers/media/platform/vsp1/vsp1_lif.h
> index 3417339379b1..71a4eda9c2b2 100644
> --- a/drivers/media/platform/vsp1/vsp1_lif.h
> +++ b/drivers/media/platform/vsp1/vsp1_lif.h
> @@ -1,14 +1,10 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
>  /*
>   * vsp1_lif.h  --  R-Car VSP1 LCD Controller Interface
>   *
>   * Copyright (C) 2013-2014 Renesas Electronics Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  #ifndef __VSP1_LIF_H__
>  #define __VSP1_LIF_H__
> diff --git a/drivers/media/platform/vsp1/vsp1_lut.c b/drivers/media/platform/vsp1/vsp1_lut.c
> index c67cc60db0db..7bdabb311c6c 100644
> --- a/drivers/media/platform/vsp1/vsp1_lut.c
> +++ b/drivers/media/platform/vsp1/vsp1_lut.c
> @@ -1,14 +1,10 @@
> +// SPDX-License-Identifier: GPL-2.0+
>  /*
>   * vsp1_lut.c  --  R-Car VSP1 Look-Up Table
>   *
>   * Copyright (C) 2013 Renesas Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  
>  #include <linux/device.h>
> diff --git a/drivers/media/platform/vsp1/vsp1_lut.h b/drivers/media/platform/vsp1/vsp1_lut.h
> index f8c4e8f0a79d..dce2fdc315f6 100644
> --- a/drivers/media/platform/vsp1/vsp1_lut.h
> +++ b/drivers/media/platform/vsp1/vsp1_lut.h
> @@ -1,14 +1,10 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
>  /*
>   * vsp1_lut.h  --  R-Car VSP1 Look-Up Table
>   *
>   * Copyright (C) 2013 Renesas Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  #ifndef __VSP1_LUT_H__
>  #define __VSP1_LUT_H__
> diff --git a/drivers/media/platform/vsp1/vsp1_pipe.c b/drivers/media/platform/vsp1/vsp1_pipe.c
> index 3fc5ecfa35e8..6fde4c0b9844 100644
> --- a/drivers/media/platform/vsp1/vsp1_pipe.c
> +++ b/drivers/media/platform/vsp1/vsp1_pipe.c
> @@ -1,14 +1,10 @@
> +// SPDX-License-Identifier: GPL-2.0+
>  /*
>   * vsp1_pipe.c  --  R-Car VSP1 Pipeline
>   *
>   * Copyright (C) 2013-2015 Renesas Electronics Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  
>  #include <linux/delay.h>
> diff --git a/drivers/media/platform/vsp1/vsp1_pipe.h b/drivers/media/platform/vsp1/vsp1_pipe.h
> index 07ccd6b810c5..663d7fed7929 100644
> --- a/drivers/media/platform/vsp1/vsp1_pipe.h
> +++ b/drivers/media/platform/vsp1/vsp1_pipe.h
> @@ -1,14 +1,10 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
>  /*
>   * vsp1_pipe.h  --  R-Car VSP1 Pipeline
>   *
>   * Copyright (C) 2013-2015 Renesas Electronics Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  #ifndef __VSP1_PIPE_H__
>  #define __VSP1_PIPE_H__
> diff --git a/drivers/media/platform/vsp1/vsp1_regs.h b/drivers/media/platform/vsp1/vsp1_regs.h
> index dae0c1901297..3201ad4b77d4 100644
> --- a/drivers/media/platform/vsp1/vsp1_regs.h
> +++ b/drivers/media/platform/vsp1/vsp1_regs.h
> @@ -1,13 +1,10 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
>  /*
>   * vsp1_regs.h  --  R-Car VSP1 Registers Definitions
>   *
>   * Copyright (C) 2013 Renesas Electronics Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License version 2
> - * as published by the Free Software Foundation.
>   */
>  
>  #ifndef __VSP1_REGS_H__
> diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c
> index 7e74c2015070..7005a4c6aa88 100644
> --- a/drivers/media/platform/vsp1/vsp1_rpf.c
> +++ b/drivers/media/platform/vsp1/vsp1_rpf.c
> @@ -1,14 +1,10 @@
> +// SPDX-License-Identifier: GPL-2.0+
>  /*
>   * vsp1_rpf.c  --  R-Car VSP1 Read Pixel Formatter
>   *
>   * Copyright (C) 2013-2014 Renesas Electronics Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  
>  #include <linux/device.h>
> diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.c b/drivers/media/platform/vsp1/vsp1_rwpf.c
> index cfd8f1904fa6..049bdd958e56 100644
> --- a/drivers/media/platform/vsp1/vsp1_rwpf.c
> +++ b/drivers/media/platform/vsp1/vsp1_rwpf.c
> @@ -1,14 +1,10 @@
> +// SPDX-License-Identifier: GPL-2.0+
>  /*
>   * vsp1_rwpf.c  --  R-Car VSP1 Read and Write Pixel Formatters
>   *
>   * Copyright (C) 2013-2014 Renesas Electronics Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  
>  #include <media/v4l2-subdev.h>
> diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.h b/drivers/media/platform/vsp1/vsp1_rwpf.h
> index 915aeadb21dd..70742ecf766f 100644
> --- a/drivers/media/platform/vsp1/vsp1_rwpf.h
> +++ b/drivers/media/platform/vsp1/vsp1_rwpf.h
> @@ -1,14 +1,10 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
>  /*
>   * vsp1_rwpf.h  --  R-Car VSP1 Read and Write Pixel Formatters
>   *
>   * Copyright (C) 2013-2014 Renesas Electronics Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  #ifndef __VSP1_RWPF_H__
>  #define __VSP1_RWPF_H__
> diff --git a/drivers/media/platform/vsp1/vsp1_sru.c b/drivers/media/platform/vsp1/vsp1_sru.c
> index 51e5691187c3..44cb9b134a19 100644
> --- a/drivers/media/platform/vsp1/vsp1_sru.c
> +++ b/drivers/media/platform/vsp1/vsp1_sru.c
> @@ -1,14 +1,10 @@
> +// SPDX-License-Identifier: GPL-2.0+
>  /*
>   * vsp1_sru.c  --  R-Car VSP1 Super Resolution Unit
>   *
>   * Copyright (C) 2013 Renesas Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  
>  #include <linux/device.h>
> diff --git a/drivers/media/platform/vsp1/vsp1_sru.h b/drivers/media/platform/vsp1/vsp1_sru.h
> index 85e241457af2..ddb00eadd1ea 100644
> --- a/drivers/media/platform/vsp1/vsp1_sru.h
> +++ b/drivers/media/platform/vsp1/vsp1_sru.h
> @@ -1,14 +1,10 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
>  /*
>   * vsp1_sru.h  --  R-Car VSP1 Super Resolution Unit
>   *
>   * Copyright (C) 2013 Renesas Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  #ifndef __VSP1_SRU_H__
>  #define __VSP1_SRU_H__
> diff --git a/drivers/media/platform/vsp1/vsp1_uds.c b/drivers/media/platform/vsp1/vsp1_uds.c
> index 72f72a9d2152..e5afd69df939 100644
> --- a/drivers/media/platform/vsp1/vsp1_uds.c
> +++ b/drivers/media/platform/vsp1/vsp1_uds.c
> @@ -1,14 +1,10 @@
> +// SPDX-License-Identifier: GPL-2.0+
>  /*
>   * vsp1_uds.c  --  R-Car VSP1 Up and Down Scaler
>   *
>   * Copyright (C) 2013-2014 Renesas Electronics Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  
>  #include <linux/device.h>
> diff --git a/drivers/media/platform/vsp1/vsp1_uds.h b/drivers/media/platform/vsp1/vsp1_uds.h
> index 7bf3cdcffc65..2cd9f4b95442 100644
> --- a/drivers/media/platform/vsp1/vsp1_uds.h
> +++ b/drivers/media/platform/vsp1/vsp1_uds.h
> @@ -1,14 +1,10 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
>  /*
>   * vsp1_uds.h  --  R-Car VSP1 Up and Down Scaler
>   *
>   * Copyright (C) 2013-2014 Renesas Electronics Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  #ifndef __VSP1_UDS_H__
>  #define __VSP1_UDS_H__
> diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
> index 2b1c94ffc6f5..c8c12223a267 100644
> --- a/drivers/media/platform/vsp1/vsp1_video.c
> +++ b/drivers/media/platform/vsp1/vsp1_video.c
> @@ -1,14 +1,10 @@
> +// SPDX-License-Identifier: GPL-2.0+
>  /*
>   * vsp1_video.c  --  R-Car VSP1 Video Node
>   *
>   * Copyright (C) 2013-2015 Renesas Electronics Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  
>  #include <linux/list.h>
> diff --git a/drivers/media/platform/vsp1/vsp1_video.h b/drivers/media/platform/vsp1/vsp1_video.h
> index 50ea7f02205f..75a5a65c66fe 100644
> --- a/drivers/media/platform/vsp1/vsp1_video.h
> +++ b/drivers/media/platform/vsp1/vsp1_video.h
> @@ -1,14 +1,10 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
>  /*
>   * vsp1_video.h  --  R-Car VSP1 Video Node
>   *
>   * Copyright (C) 2013-2015 Renesas Electronics Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  #ifndef __VSP1_VIDEO_H__
>  #define __VSP1_VIDEO_H__
> diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c
> index 53858d100228..65ed2f849551 100644
> --- a/drivers/media/platform/vsp1/vsp1_wpf.c
> +++ b/drivers/media/platform/vsp1/vsp1_wpf.c
> @@ -1,14 +1,10 @@
> +// SPDX-License-Identifier: GPL-2.0+
>  /*
>   * vsp1_wpf.c  --  R-Car VSP1 Write Pixel Formatter
>   *
>   * Copyright (C) 2013-2014 Renesas Electronics Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  
>  #include <linux/device.h>
> 

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

* Re: [PATCH v2 1/8] v4l: vsp1: Use SPDX license headers
@ 2018-04-27 21:25     ` Kieran Bingham
  0 siblings, 0 replies; 82+ messages in thread
From: Kieran Bingham @ 2018-04-27 21:25 UTC (permalink / raw)
  To: Laurent Pinchart, linux-media, dri-devel
  Cc: linux-renesas-soc, Kieran Bingham

Hi Laurent,

Thank you for the patch, and going through the whole driver for this update.

On 22/04/18 23:34, Laurent Pinchart wrote:
> Adopt the SPDX license identifier headers to ease license compliance
> management. All files in the driver are licensed under the GPLv2+ except
> for the vsp1_regs.h file which is licensed under the GPLv2. This is
> likely an oversight, but fixing this requires contacting the copyright
> owners and is out of scope for this patch.

I agree that's out of scope for this patch, but it's not too exhaustive a list
to correct at a later date:

git shortlog -e -n -s -- ./drivers/media/platform/vsp1/vsp1_regs.h
    19  Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
     5  Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
     3  Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
     2  Geert Uytterhoeven <geert+renesas@glider.be>
     2  Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
     1  Linus Torvalds <torvalds@linux-foundation.org>
     1  Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
     1  Wolfram Sang <wsa+renesas@sang-engineering.com>

(Both Geert and Linus are merge commits there)

> While at it fix the file descriptions to match file names where copy and
> paste error occurred.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

It's crazy that we have two types of comment style for the SPDX identifier - but
that's not a fault in this patch, so:

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

> ---
>  drivers/media/platform/vsp1/vsp1.h        | 6 +-----
>  drivers/media/platform/vsp1/vsp1_brx.c    | 6 +-----
>  drivers/media/platform/vsp1/vsp1_brx.h    | 6 +-----
>  drivers/media/platform/vsp1/vsp1_clu.c    | 6 +-----
>  drivers/media/platform/vsp1/vsp1_clu.h    | 6 +-----
>  drivers/media/platform/vsp1/vsp1_dl.c     | 8 ++------
>  drivers/media/platform/vsp1/vsp1_dl.h     | 6 +-----
>  drivers/media/platform/vsp1/vsp1_drm.c    | 8 ++------
>  drivers/media/platform/vsp1/vsp1_drm.h    | 6 +-----
>  drivers/media/platform/vsp1/vsp1_drv.c    | 6 +-----
>  drivers/media/platform/vsp1/vsp1_entity.c | 6 +-----
>  drivers/media/platform/vsp1/vsp1_entity.h | 6 +-----
>  drivers/media/platform/vsp1/vsp1_hgo.c    | 6 +-----
>  drivers/media/platform/vsp1/vsp1_hgo.h    | 6 +-----
>  drivers/media/platform/vsp1/vsp1_hgt.c    | 6 +-----
>  drivers/media/platform/vsp1/vsp1_hgt.h    | 6 +-----
>  drivers/media/platform/vsp1/vsp1_histo.c  | 6 +-----
>  drivers/media/platform/vsp1/vsp1_histo.h  | 6 +-----
>  drivers/media/platform/vsp1/vsp1_hsit.c   | 6 +-----
>  drivers/media/platform/vsp1/vsp1_hsit.h   | 6 +-----
>  drivers/media/platform/vsp1/vsp1_lif.c    | 6 +-----
>  drivers/media/platform/vsp1/vsp1_lif.h    | 6 +-----
>  drivers/media/platform/vsp1/vsp1_lut.c    | 6 +-----
>  drivers/media/platform/vsp1/vsp1_lut.h    | 6 +-----
>  drivers/media/platform/vsp1/vsp1_pipe.c   | 6 +-----
>  drivers/media/platform/vsp1/vsp1_pipe.h   | 6 +-----
>  drivers/media/platform/vsp1/vsp1_regs.h   | 5 +----
>  drivers/media/platform/vsp1/vsp1_rpf.c    | 6 +-----
>  drivers/media/platform/vsp1/vsp1_rwpf.c   | 6 +-----
>  drivers/media/platform/vsp1/vsp1_rwpf.h   | 6 +-----
>  drivers/media/platform/vsp1/vsp1_sru.c    | 6 +-----
>  drivers/media/platform/vsp1/vsp1_sru.h    | 6 +-----
>  drivers/media/platform/vsp1/vsp1_uds.c    | 6 +-----
>  drivers/media/platform/vsp1/vsp1_uds.h    | 6 +-----
>  drivers/media/platform/vsp1/vsp1_video.c  | 6 +-----
>  drivers/media/platform/vsp1/vsp1_video.h  | 6 +-----
>  drivers/media/platform/vsp1/vsp1_wpf.c    | 6 +-----
>  37 files changed, 39 insertions(+), 186 deletions(-)
> 
> diff --git a/drivers/media/platform/vsp1/vsp1.h b/drivers/media/platform/vsp1/vsp1.h
> index 894cc725c2d4..9cf4e1c4b036 100644
> --- a/drivers/media/platform/vsp1/vsp1.h
> +++ b/drivers/media/platform/vsp1/vsp1.h
> @@ -1,14 +1,10 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
>  /*
>   * vsp1.h  --  R-Car VSP1 Driver
>   *
>   * Copyright (C) 2013-2014 Renesas Electronics Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  #ifndef __VSP1_H__
>  #define __VSP1_H__
> diff --git a/drivers/media/platform/vsp1/vsp1_brx.c b/drivers/media/platform/vsp1/vsp1_brx.c
> index b4af1d546022..3beec18fd863 100644
> --- a/drivers/media/platform/vsp1/vsp1_brx.c
> +++ b/drivers/media/platform/vsp1/vsp1_brx.c
> @@ -1,14 +1,10 @@
> +// SPDX-License-Identifier: GPL-2.0+
>  /*
>   * vsp1_brx.c  --  R-Car VSP1 Blend ROP Unit (BRU and BRS)
>   *
>   * Copyright (C) 2013 Renesas Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  
>  #include <linux/device.h>
> diff --git a/drivers/media/platform/vsp1/vsp1_brx.h b/drivers/media/platform/vsp1/vsp1_brx.h
> index 927aa4254c0f..6abbb8c3343c 100644
> --- a/drivers/media/platform/vsp1/vsp1_brx.h
> +++ b/drivers/media/platform/vsp1/vsp1_brx.h
> @@ -1,14 +1,10 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
>  /*
>   * vsp1_brx.h  --  R-Car VSP1 Blend ROP Unit (BRU and BRS)
>   *
>   * Copyright (C) 2013 Renesas Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  #ifndef __VSP1_BRX_H__
>  #define __VSP1_BRX_H__
> diff --git a/drivers/media/platform/vsp1/vsp1_clu.c b/drivers/media/platform/vsp1/vsp1_clu.c
> index f2fb26e5ab4e..9626b6308585 100644
> --- a/drivers/media/platform/vsp1/vsp1_clu.c
> +++ b/drivers/media/platform/vsp1/vsp1_clu.c
> @@ -1,14 +1,10 @@
> +// SPDX-License-Identifier: GPL-2.0+
>  /*
>   * vsp1_clu.c  --  R-Car VSP1 Cubic Look-Up Table
>   *
>   * Copyright (C) 2015-2016 Renesas Electronics Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  
>  #include <linux/device.h>
> diff --git a/drivers/media/platform/vsp1/vsp1_clu.h b/drivers/media/platform/vsp1/vsp1_clu.h
> index 036e0a2f1a42..c45e6e707592 100644
> --- a/drivers/media/platform/vsp1/vsp1_clu.h
> +++ b/drivers/media/platform/vsp1/vsp1_clu.h
> @@ -1,14 +1,10 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
>  /*
>   * vsp1_clu.h  --  R-Car VSP1 Cubic Look-Up Table
>   *
>   * Copyright (C) 2015 Renesas Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  #ifndef __VSP1_CLU_H__
>  #define __VSP1_CLU_H__
> diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c
> index 30ad491605ff..801dea475740 100644
> --- a/drivers/media/platform/vsp1/vsp1_dl.c
> +++ b/drivers/media/platform/vsp1/vsp1_dl.c
> @@ -1,14 +1,10 @@
> +// SPDX-License-Identifier: GPL-2.0+
>  /*
> - * vsp1_dl.h  --  R-Car VSP1 Display List
> + * vsp1_dl.c  --  R-Car VSP1 Display List
>   *
>   * Copyright (C) 2015 Renesas Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  
>  #include <linux/device.h>
> diff --git a/drivers/media/platform/vsp1/vsp1_dl.h b/drivers/media/platform/vsp1/vsp1_dl.h
> index 1a5bbd5ddb7b..e6279b1abd19 100644
> --- a/drivers/media/platform/vsp1/vsp1_dl.h
> +++ b/drivers/media/platform/vsp1/vsp1_dl.h
> @@ -1,14 +1,10 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
>  /*
>   * vsp1_dl.h  --  R-Car VSP1 Display List
>   *
>   * Copyright (C) 2015 Renesas Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  #ifndef __VSP1_DL_H__
>  #define __VSP1_DL_H__
> diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c
> index 095dc48aa25a..2b29a83dceb9 100644
> --- a/drivers/media/platform/vsp1/vsp1_drm.c
> +++ b/drivers/media/platform/vsp1/vsp1_drm.c
> @@ -1,14 +1,10 @@
> +// SPDX-License-Identifier: GPL-2.0+
>  /*
> - * vsp1_drm.c  --  R-Car VSP1 DRM API
> + * vsp1_drm.c  --  R-Car VSP1 DRM/KMS Interface
>   *
>   * Copyright (C) 2015 Renesas Electronics Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  
>  #include <linux/device.h>
> diff --git a/drivers/media/platform/vsp1/vsp1_drm.h b/drivers/media/platform/vsp1/vsp1_drm.h
> index d738cc57f0e3..f4af1b2b12d6 100644
> --- a/drivers/media/platform/vsp1/vsp1_drm.h
> +++ b/drivers/media/platform/vsp1/vsp1_drm.h
> @@ -1,14 +1,10 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
>  /*
>   * vsp1_drm.h  --  R-Car VSP1 DRM/KMS Interface
>   *
>   * Copyright (C) 2015 Renesas Electronics Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  #ifndef __VSP1_DRM_H__
>  #define __VSP1_DRM_H__
> diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
> index f41cd70409db..331a2e0af0d3 100644
> --- a/drivers/media/platform/vsp1/vsp1_drv.c
> +++ b/drivers/media/platform/vsp1/vsp1_drv.c
> @@ -1,14 +1,10 @@
> +// SPDX-License-Identifier: GPL-2.0+
>  /*
>   * vsp1_drv.c  --  R-Car VSP1 Driver
>   *
>   * Copyright (C) 2013-2015 Renesas Electronics Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  
>  #include <linux/clk.h>
> diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c
> index 54de15095709..72354caf5746 100644
> --- a/drivers/media/platform/vsp1/vsp1_entity.c
> +++ b/drivers/media/platform/vsp1/vsp1_entity.c
> @@ -1,14 +1,10 @@
> +// SPDX-License-Identifier: GPL-2.0+
>  /*
>   * vsp1_entity.c  --  R-Car VSP1 Base Entity
>   *
>   * Copyright (C) 2013-2014 Renesas Electronics Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  
>  #include <linux/device.h>
> diff --git a/drivers/media/platform/vsp1/vsp1_entity.h b/drivers/media/platform/vsp1/vsp1_entity.h
> index c26523c56c05..fb20a1578f3b 100644
> --- a/drivers/media/platform/vsp1/vsp1_entity.h
> +++ b/drivers/media/platform/vsp1/vsp1_entity.h
> @@ -1,14 +1,10 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
>  /*
>   * vsp1_entity.h  --  R-Car VSP1 Base Entity
>   *
>   * Copyright (C) 2013-2014 Renesas Electronics Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  #ifndef __VSP1_ENTITY_H__
>  #define __VSP1_ENTITY_H__
> diff --git a/drivers/media/platform/vsp1/vsp1_hgo.c b/drivers/media/platform/vsp1/vsp1_hgo.c
> index 50309c053b78..d514807ccdf4 100644
> --- a/drivers/media/platform/vsp1/vsp1_hgo.c
> +++ b/drivers/media/platform/vsp1/vsp1_hgo.c
> @@ -1,14 +1,10 @@
> +// SPDX-License-Identifier: GPL-2.0+
>  /*
>   * vsp1_hgo.c  --  R-Car VSP1 Histogram Generator 1D
>   *
>   * Copyright (C) 2016 Renesas Electronics Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  
>  #include <linux/device.h>
> diff --git a/drivers/media/platform/vsp1/vsp1_hgo.h b/drivers/media/platform/vsp1/vsp1_hgo.h
> index c6c0b7a80e0c..6b0c8580e1bf 100644
> --- a/drivers/media/platform/vsp1/vsp1_hgo.h
> +++ b/drivers/media/platform/vsp1/vsp1_hgo.h
> @@ -1,14 +1,10 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
>  /*
>   * vsp1_hgo.h  --  R-Car VSP1 Histogram Generator 1D
>   *
>   * Copyright (C) 2016 Renesas Electronics Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  #ifndef __VSP1_HGO_H__
>  #define __VSP1_HGO_H__
> diff --git a/drivers/media/platform/vsp1/vsp1_hgt.c b/drivers/media/platform/vsp1/vsp1_hgt.c
> index b5ce305e3e6f..18dc89f47c45 100644
> --- a/drivers/media/platform/vsp1/vsp1_hgt.c
> +++ b/drivers/media/platform/vsp1/vsp1_hgt.c
> @@ -1,14 +1,10 @@
> +// SPDX-License-Identifier: GPL-2.0+
>  /*
>   * vsp1_hgt.c  --  R-Car VSP1 Histogram Generator 2D
>   *
>   * Copyright (C) 2016 Renesas Electronics Corporation
>   *
>   * Contact: Niklas Söderlund (niklas.soderlund@ragnatech.se)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  
>  #include <linux/device.h>
> diff --git a/drivers/media/platform/vsp1/vsp1_hgt.h b/drivers/media/platform/vsp1/vsp1_hgt.h
> index 83f2e130942a..38ec237bdd2d 100644
> --- a/drivers/media/platform/vsp1/vsp1_hgt.h
> +++ b/drivers/media/platform/vsp1/vsp1_hgt.h
> @@ -1,14 +1,10 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
>  /*
>   * vsp1_hgt.h  --  R-Car VSP1 Histogram Generator 2D
>   *
>   * Copyright (C) 2016 Renesas Electronics Corporation
>   *
>   * Contact: Niklas Söderlund (niklas.soderlund@ragnatech.se)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  #ifndef __VSP1_HGT_H__
>  #define __VSP1_HGT_H__
> diff --git a/drivers/media/platform/vsp1/vsp1_histo.c b/drivers/media/platform/vsp1/vsp1_histo.c
> index 8638ebc514b4..029181c1fb61 100644
> --- a/drivers/media/platform/vsp1/vsp1_histo.c
> +++ b/drivers/media/platform/vsp1/vsp1_histo.c
> @@ -1,3 +1,4 @@
> +// SPDX-License-Identifier: GPL-2.0+
>  /*
>   * vsp1_histo.c  --  R-Car VSP1 Histogram API
>   *
> @@ -5,11 +6,6 @@
>   * Copyright (C) 2016 Laurent Pinchart
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  
>  #include <linux/device.h>
> diff --git a/drivers/media/platform/vsp1/vsp1_histo.h b/drivers/media/platform/vsp1/vsp1_histo.h
> index e774adbf251f..06f029846244 100644
> --- a/drivers/media/platform/vsp1/vsp1_histo.h
> +++ b/drivers/media/platform/vsp1/vsp1_histo.h
> @@ -1,3 +1,4 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
>  /*
>   * vsp1_histo.h  --  R-Car VSP1 Histogram API
>   *
> @@ -5,11 +6,6 @@
>   * Copyright (C) 2016 Laurent Pinchart
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  #ifndef __VSP1_HISTO_H__
>  #define __VSP1_HISTO_H__
> diff --git a/drivers/media/platform/vsp1/vsp1_hsit.c b/drivers/media/platform/vsp1/vsp1_hsit.c
> index 764d405345ee..7ba3535f3c9b 100644
> --- a/drivers/media/platform/vsp1/vsp1_hsit.c
> +++ b/drivers/media/platform/vsp1/vsp1_hsit.c
> @@ -1,14 +1,10 @@
> +// SPDX-License-Identifier: GPL-2.0+
>  /*
>   * vsp1_hsit.c  --  R-Car VSP1 Hue Saturation value (Inverse) Transform
>   *
>   * Copyright (C) 2013 Renesas Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  
>  #include <linux/device.h>
> diff --git a/drivers/media/platform/vsp1/vsp1_hsit.h b/drivers/media/platform/vsp1/vsp1_hsit.h
> index 82f1c8426900..a658b1aa49e7 100644
> --- a/drivers/media/platform/vsp1/vsp1_hsit.h
> +++ b/drivers/media/platform/vsp1/vsp1_hsit.h
> @@ -1,14 +1,10 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
>  /*
>   * vsp1_hsit.h  --  R-Car VSP1 Hue Saturation value (Inverse) Transform
>   *
>   * Copyright (C) 2013 Renesas Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  #ifndef __VSP1_HSIT_H__
>  #define __VSP1_HSIT_H__
> diff --git a/drivers/media/platform/vsp1/vsp1_lif.c b/drivers/media/platform/vsp1/vsp1_lif.c
> index 704920753998..b20b842f06ba 100644
> --- a/drivers/media/platform/vsp1/vsp1_lif.c
> +++ b/drivers/media/platform/vsp1/vsp1_lif.c
> @@ -1,14 +1,10 @@
> +// SPDX-License-Identifier: GPL-2.0+
>  /*
>   * vsp1_lif.c  --  R-Car VSP1 LCD Controller Interface
>   *
>   * Copyright (C) 2013-2014 Renesas Electronics Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  
>  #include <linux/device.h>
> diff --git a/drivers/media/platform/vsp1/vsp1_lif.h b/drivers/media/platform/vsp1/vsp1_lif.h
> index 3417339379b1..71a4eda9c2b2 100644
> --- a/drivers/media/platform/vsp1/vsp1_lif.h
> +++ b/drivers/media/platform/vsp1/vsp1_lif.h
> @@ -1,14 +1,10 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
>  /*
>   * vsp1_lif.h  --  R-Car VSP1 LCD Controller Interface
>   *
>   * Copyright (C) 2013-2014 Renesas Electronics Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  #ifndef __VSP1_LIF_H__
>  #define __VSP1_LIF_H__
> diff --git a/drivers/media/platform/vsp1/vsp1_lut.c b/drivers/media/platform/vsp1/vsp1_lut.c
> index c67cc60db0db..7bdabb311c6c 100644
> --- a/drivers/media/platform/vsp1/vsp1_lut.c
> +++ b/drivers/media/platform/vsp1/vsp1_lut.c
> @@ -1,14 +1,10 @@
> +// SPDX-License-Identifier: GPL-2.0+
>  /*
>   * vsp1_lut.c  --  R-Car VSP1 Look-Up Table
>   *
>   * Copyright (C) 2013 Renesas Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  
>  #include <linux/device.h>
> diff --git a/drivers/media/platform/vsp1/vsp1_lut.h b/drivers/media/platform/vsp1/vsp1_lut.h
> index f8c4e8f0a79d..dce2fdc315f6 100644
> --- a/drivers/media/platform/vsp1/vsp1_lut.h
> +++ b/drivers/media/platform/vsp1/vsp1_lut.h
> @@ -1,14 +1,10 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
>  /*
>   * vsp1_lut.h  --  R-Car VSP1 Look-Up Table
>   *
>   * Copyright (C) 2013 Renesas Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  #ifndef __VSP1_LUT_H__
>  #define __VSP1_LUT_H__
> diff --git a/drivers/media/platform/vsp1/vsp1_pipe.c b/drivers/media/platform/vsp1/vsp1_pipe.c
> index 3fc5ecfa35e8..6fde4c0b9844 100644
> --- a/drivers/media/platform/vsp1/vsp1_pipe.c
> +++ b/drivers/media/platform/vsp1/vsp1_pipe.c
> @@ -1,14 +1,10 @@
> +// SPDX-License-Identifier: GPL-2.0+
>  /*
>   * vsp1_pipe.c  --  R-Car VSP1 Pipeline
>   *
>   * Copyright (C) 2013-2015 Renesas Electronics Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  
>  #include <linux/delay.h>
> diff --git a/drivers/media/platform/vsp1/vsp1_pipe.h b/drivers/media/platform/vsp1/vsp1_pipe.h
> index 07ccd6b810c5..663d7fed7929 100644
> --- a/drivers/media/platform/vsp1/vsp1_pipe.h
> +++ b/drivers/media/platform/vsp1/vsp1_pipe.h
> @@ -1,14 +1,10 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
>  /*
>   * vsp1_pipe.h  --  R-Car VSP1 Pipeline
>   *
>   * Copyright (C) 2013-2015 Renesas Electronics Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  #ifndef __VSP1_PIPE_H__
>  #define __VSP1_PIPE_H__
> diff --git a/drivers/media/platform/vsp1/vsp1_regs.h b/drivers/media/platform/vsp1/vsp1_regs.h
> index dae0c1901297..3201ad4b77d4 100644
> --- a/drivers/media/platform/vsp1/vsp1_regs.h
> +++ b/drivers/media/platform/vsp1/vsp1_regs.h
> @@ -1,13 +1,10 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
>  /*
>   * vsp1_regs.h  --  R-Car VSP1 Registers Definitions
>   *
>   * Copyright (C) 2013 Renesas Electronics Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License version 2
> - * as published by the Free Software Foundation.
>   */
>  
>  #ifndef __VSP1_REGS_H__
> diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c
> index 7e74c2015070..7005a4c6aa88 100644
> --- a/drivers/media/platform/vsp1/vsp1_rpf.c
> +++ b/drivers/media/platform/vsp1/vsp1_rpf.c
> @@ -1,14 +1,10 @@
> +// SPDX-License-Identifier: GPL-2.0+
>  /*
>   * vsp1_rpf.c  --  R-Car VSP1 Read Pixel Formatter
>   *
>   * Copyright (C) 2013-2014 Renesas Electronics Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  
>  #include <linux/device.h>
> diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.c b/drivers/media/platform/vsp1/vsp1_rwpf.c
> index cfd8f1904fa6..049bdd958e56 100644
> --- a/drivers/media/platform/vsp1/vsp1_rwpf.c
> +++ b/drivers/media/platform/vsp1/vsp1_rwpf.c
> @@ -1,14 +1,10 @@
> +// SPDX-License-Identifier: GPL-2.0+
>  /*
>   * vsp1_rwpf.c  --  R-Car VSP1 Read and Write Pixel Formatters
>   *
>   * Copyright (C) 2013-2014 Renesas Electronics Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  
>  #include <media/v4l2-subdev.h>
> diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.h b/drivers/media/platform/vsp1/vsp1_rwpf.h
> index 915aeadb21dd..70742ecf766f 100644
> --- a/drivers/media/platform/vsp1/vsp1_rwpf.h
> +++ b/drivers/media/platform/vsp1/vsp1_rwpf.h
> @@ -1,14 +1,10 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
>  /*
>   * vsp1_rwpf.h  --  R-Car VSP1 Read and Write Pixel Formatters
>   *
>   * Copyright (C) 2013-2014 Renesas Electronics Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  #ifndef __VSP1_RWPF_H__
>  #define __VSP1_RWPF_H__
> diff --git a/drivers/media/platform/vsp1/vsp1_sru.c b/drivers/media/platform/vsp1/vsp1_sru.c
> index 51e5691187c3..44cb9b134a19 100644
> --- a/drivers/media/platform/vsp1/vsp1_sru.c
> +++ b/drivers/media/platform/vsp1/vsp1_sru.c
> @@ -1,14 +1,10 @@
> +// SPDX-License-Identifier: GPL-2.0+
>  /*
>   * vsp1_sru.c  --  R-Car VSP1 Super Resolution Unit
>   *
>   * Copyright (C) 2013 Renesas Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  
>  #include <linux/device.h>
> diff --git a/drivers/media/platform/vsp1/vsp1_sru.h b/drivers/media/platform/vsp1/vsp1_sru.h
> index 85e241457af2..ddb00eadd1ea 100644
> --- a/drivers/media/platform/vsp1/vsp1_sru.h
> +++ b/drivers/media/platform/vsp1/vsp1_sru.h
> @@ -1,14 +1,10 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
>  /*
>   * vsp1_sru.h  --  R-Car VSP1 Super Resolution Unit
>   *
>   * Copyright (C) 2013 Renesas Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  #ifndef __VSP1_SRU_H__
>  #define __VSP1_SRU_H__
> diff --git a/drivers/media/platform/vsp1/vsp1_uds.c b/drivers/media/platform/vsp1/vsp1_uds.c
> index 72f72a9d2152..e5afd69df939 100644
> --- a/drivers/media/platform/vsp1/vsp1_uds.c
> +++ b/drivers/media/platform/vsp1/vsp1_uds.c
> @@ -1,14 +1,10 @@
> +// SPDX-License-Identifier: GPL-2.0+
>  /*
>   * vsp1_uds.c  --  R-Car VSP1 Up and Down Scaler
>   *
>   * Copyright (C) 2013-2014 Renesas Electronics Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  
>  #include <linux/device.h>
> diff --git a/drivers/media/platform/vsp1/vsp1_uds.h b/drivers/media/platform/vsp1/vsp1_uds.h
> index 7bf3cdcffc65..2cd9f4b95442 100644
> --- a/drivers/media/platform/vsp1/vsp1_uds.h
> +++ b/drivers/media/platform/vsp1/vsp1_uds.h
> @@ -1,14 +1,10 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
>  /*
>   * vsp1_uds.h  --  R-Car VSP1 Up and Down Scaler
>   *
>   * Copyright (C) 2013-2014 Renesas Electronics Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  #ifndef __VSP1_UDS_H__
>  #define __VSP1_UDS_H__
> diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
> index 2b1c94ffc6f5..c8c12223a267 100644
> --- a/drivers/media/platform/vsp1/vsp1_video.c
> +++ b/drivers/media/platform/vsp1/vsp1_video.c
> @@ -1,14 +1,10 @@
> +// SPDX-License-Identifier: GPL-2.0+
>  /*
>   * vsp1_video.c  --  R-Car VSP1 Video Node
>   *
>   * Copyright (C) 2013-2015 Renesas Electronics Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  
>  #include <linux/list.h>
> diff --git a/drivers/media/platform/vsp1/vsp1_video.h b/drivers/media/platform/vsp1/vsp1_video.h
> index 50ea7f02205f..75a5a65c66fe 100644
> --- a/drivers/media/platform/vsp1/vsp1_video.h
> +++ b/drivers/media/platform/vsp1/vsp1_video.h
> @@ -1,14 +1,10 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
>  /*
>   * vsp1_video.h  --  R-Car VSP1 Video Node
>   *
>   * Copyright (C) 2013-2015 Renesas Electronics Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  #ifndef __VSP1_VIDEO_H__
>  #define __VSP1_VIDEO_H__
> diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c
> index 53858d100228..65ed2f849551 100644
> --- a/drivers/media/platform/vsp1/vsp1_wpf.c
> +++ b/drivers/media/platform/vsp1/vsp1_wpf.c
> @@ -1,14 +1,10 @@
> +// SPDX-License-Identifier: GPL-2.0+
>  /*
>   * vsp1_wpf.c  --  R-Car VSP1 Write Pixel Formatter
>   *
>   * Copyright (C) 2013-2014 Renesas Electronics Corporation
>   *
>   * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
>   */
>  
>  #include <linux/device.h>
> 
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v2 1/8] v4l: vsp1: Use SPDX license headers
  2018-04-27 21:25     ` Kieran Bingham
@ 2018-04-27 21:47       ` Laurent Pinchart
  -1 siblings, 0 replies; 82+ messages in thread
From: Laurent Pinchart @ 2018-04-27 21:47 UTC (permalink / raw)
  To: Kieran Bingham
  Cc: Laurent Pinchart, linux-media, dri-devel, linux-renesas-soc

Hi Kieran,

On Saturday, 28 April 2018 00:25:51 EEST Kieran Bingham wrote:
> Hi Laurent,
> 
> Thank you for the patch, and going through the whole driver for this update.
> On 22/04/18 23:34, Laurent Pinchart wrote:
> > Adopt the SPDX license identifier headers to ease license compliance
> > management. All files in the driver are licensed under the GPLv2+ except
> > for the vsp1_regs.h file which is licensed under the GPLv2. This is
> > likely an oversight, but fixing this requires contacting the copyright
> > owners and is out of scope for this patch.
> 
> I agree that's out of scope for this patch, but it's not too exhaustive a
> list to correct at a later date:
> 
> git shortlog -e -n -s -- ./drivers/media/platform/vsp1/vsp1_regs.h
>     19  Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
>      5  Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
>      3  Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
>      2  Geert Uytterhoeven <geert+renesas@glider.be>
>      2  Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
>      1  Linus Torvalds <torvalds@linux-foundation.org>
>      1  Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
>      1  Wolfram Sang <wsa+renesas@sang-engineering.com>
> 
> (Both Geert and Linus are merge commits there)

I agree with you, I've sent a separate patch.

> > While at it fix the file descriptions to match file names where copy and
> > paste error occurred.
> > 
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com>
> 
> It's crazy that we have two types of comment style for the SPDX identifier -
> but that's not a fault in this patch, so:
> 
> Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
> 
> > ---
> > 
> >  drivers/media/platform/vsp1/vsp1.h        | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_brx.c    | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_brx.h    | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_clu.c    | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_clu.h    | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_dl.c     | 8 ++------
> >  drivers/media/platform/vsp1/vsp1_dl.h     | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_drm.c    | 8 ++------
> >  drivers/media/platform/vsp1/vsp1_drm.h    | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_drv.c    | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_entity.c | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_entity.h | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_hgo.c    | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_hgo.h    | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_hgt.c    | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_hgt.h    | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_histo.c  | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_histo.h  | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_hsit.c   | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_hsit.h   | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_lif.c    | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_lif.h    | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_lut.c    | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_lut.h    | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_pipe.c   | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_pipe.h   | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_regs.h   | 5 +----
> >  drivers/media/platform/vsp1/vsp1_rpf.c    | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_rwpf.c   | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_rwpf.h   | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_sru.c    | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_sru.h    | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_uds.c    | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_uds.h    | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_video.c  | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_video.h  | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_wpf.c    | 6 +-----
> >  37 files changed, 39 insertions(+), 186 deletions(-)

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v2 1/8] v4l: vsp1: Use SPDX license headers
@ 2018-04-27 21:47       ` Laurent Pinchart
  0 siblings, 0 replies; 82+ messages in thread
From: Laurent Pinchart @ 2018-04-27 21:47 UTC (permalink / raw)
  To: Kieran Bingham
  Cc: linux-renesas-soc, Laurent Pinchart, dri-devel, linux-media

Hi Kieran,

On Saturday, 28 April 2018 00:25:51 EEST Kieran Bingham wrote:
> Hi Laurent,
> 
> Thank you for the patch, and going through the whole driver for this update.
> On 22/04/18 23:34, Laurent Pinchart wrote:
> > Adopt the SPDX license identifier headers to ease license compliance
> > management. All files in the driver are licensed under the GPLv2+ except
> > for the vsp1_regs.h file which is licensed under the GPLv2. This is
> > likely an oversight, but fixing this requires contacting the copyright
> > owners and is out of scope for this patch.
> 
> I agree that's out of scope for this patch, but it's not too exhaustive a
> list to correct at a later date:
> 
> git shortlog -e -n -s -- ./drivers/media/platform/vsp1/vsp1_regs.h
>     19  Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
>      5  Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
>      3  Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
>      2  Geert Uytterhoeven <geert+renesas@glider.be>
>      2  Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
>      1  Linus Torvalds <torvalds@linux-foundation.org>
>      1  Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
>      1  Wolfram Sang <wsa+renesas@sang-engineering.com>
> 
> (Both Geert and Linus are merge commits there)

I agree with you, I've sent a separate patch.

> > While at it fix the file descriptions to match file names where copy and
> > paste error occurred.
> > 
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com>
> 
> It's crazy that we have two types of comment style for the SPDX identifier -
> but that's not a fault in this patch, so:
> 
> Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
> 
> > ---
> > 
> >  drivers/media/platform/vsp1/vsp1.h        | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_brx.c    | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_brx.h    | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_clu.c    | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_clu.h    | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_dl.c     | 8 ++------
> >  drivers/media/platform/vsp1/vsp1_dl.h     | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_drm.c    | 8 ++------
> >  drivers/media/platform/vsp1/vsp1_drm.h    | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_drv.c    | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_entity.c | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_entity.h | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_hgo.c    | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_hgo.h    | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_hgt.c    | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_hgt.h    | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_histo.c  | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_histo.h  | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_hsit.c   | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_hsit.h   | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_lif.c    | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_lif.h    | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_lut.c    | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_lut.h    | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_pipe.c   | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_pipe.h   | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_regs.h   | 5 +----
> >  drivers/media/platform/vsp1/vsp1_rpf.c    | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_rwpf.c   | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_rwpf.h   | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_sru.c    | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_sru.h    | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_uds.c    | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_uds.h    | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_video.c  | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_video.h  | 6 +-----
> >  drivers/media/platform/vsp1/vsp1_wpf.c    | 6 +-----
> >  37 files changed, 39 insertions(+), 186 deletions(-)

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

* Re: [PATCH v2 2/8] v4l: vsp1: Share the CLU, LIF and LUT set_fmt pad operation code
  2018-04-22 22:34   ` Laurent Pinchart
@ 2018-04-28  9:50     ` jacopo mondi
  -1 siblings, 0 replies; 82+ messages in thread
From: jacopo mondi @ 2018-04-28  9:50 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: linux-media, dri-devel, linux-renesas-soc, Kieran Bingham

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

Hi Laurent,
   very minor comments below

On Mon, Apr 23, 2018 at 01:34:24AM +0300, Laurent Pinchart wrote:
> The implementation of the set_fmt pad operation is identical in the
> three modules. Move it to a generic helper function.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>  drivers/media/platform/vsp1/vsp1_clu.c    | 65 +++++----------------------
>  drivers/media/platform/vsp1/vsp1_entity.c | 75 +++++++++++++++++++++++++++++++
>  drivers/media/platform/vsp1/vsp1_entity.h |  6 +++
>  drivers/media/platform/vsp1/vsp1_lif.c    | 65 +++++----------------------
>  drivers/media/platform/vsp1/vsp1_lut.c    | 65 +++++----------------------
>  5 files changed, 116 insertions(+), 160 deletions(-)
>
> diff --git a/drivers/media/platform/vsp1/vsp1_clu.c b/drivers/media/platform/vsp1/vsp1_clu.c
> index 9626b6308585..96a448e1504c 100644
> --- a/drivers/media/platform/vsp1/vsp1_clu.c
> +++ b/drivers/media/platform/vsp1/vsp1_clu.c
> @@ -114,18 +114,18 @@ static const struct v4l2_ctrl_config clu_mode_control = {
>   * V4L2 Subdevice Pad Operations
>   */
>
> +static const unsigned int clu_codes[] = {
> +	MEDIA_BUS_FMT_ARGB8888_1X32,
> +	MEDIA_BUS_FMT_AHSV8888_1X32,
> +	MEDIA_BUS_FMT_AYUV8_1X32,
> +};
> +
>  static int clu_enum_mbus_code(struct v4l2_subdev *subdev,
>  			      struct v4l2_subdev_pad_config *cfg,
>  			      struct v4l2_subdev_mbus_code_enum *code)
>  {
> -	static const unsigned int codes[] = {
> -		MEDIA_BUS_FMT_ARGB8888_1X32,
> -		MEDIA_BUS_FMT_AHSV8888_1X32,
> -		MEDIA_BUS_FMT_AYUV8_1X32,
> -	};
> -
> -	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, codes,
> -					  ARRAY_SIZE(codes));
> +	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, clu_codes,
> +					  ARRAY_SIZE(clu_codes));
>  }
>
>  static int clu_enum_frame_size(struct v4l2_subdev *subdev,
> @@ -141,51 +141,10 @@ static int clu_set_format(struct v4l2_subdev *subdev,
>  			  struct v4l2_subdev_pad_config *cfg,
>  			  struct v4l2_subdev_format *fmt)
>  {
> -	struct vsp1_clu *clu = to_clu(subdev);
> -	struct v4l2_subdev_pad_config *config;
> -	struct v4l2_mbus_framefmt *format;
> -	int ret = 0;
> -
> -	mutex_lock(&clu->entity.lock);
> -
> -	config = vsp1_entity_get_pad_config(&clu->entity, cfg, fmt->which);
> -	if (!config) {
> -		ret = -EINVAL;
> -		goto done;
> -	}
> -
> -	/* Default to YUV if the requested format is not supported. */
> -	if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
> -	    fmt->format.code != MEDIA_BUS_FMT_AHSV8888_1X32 &&
> -	    fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32)
> -		fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32;

The newly implemented vsp1_subdev_set_pad_format defaults to the first
clu_codes[] member (ARGB888_1x32), while here the code chose the AYUV8_1x32
format. Is it ok? Should you revers the clu_codes[] order?

> -
> -	format = vsp1_entity_get_pad_format(&clu->entity, config, fmt->pad);
> -
> -	if (fmt->pad == CLU_PAD_SOURCE) {
> -		/* The CLU output format can't be modified. */
> -		fmt->format = *format;
> -		goto done;
> -	}
> -
> -	format->code = fmt->format.code;
> -	format->width = clamp_t(unsigned int, fmt->format.width,
> -				CLU_MIN_SIZE, CLU_MAX_SIZE);
> -	format->height = clamp_t(unsigned int, fmt->format.height,
> -				 CLU_MIN_SIZE, CLU_MAX_SIZE);
> -	format->field = V4L2_FIELD_NONE;
> -	format->colorspace = V4L2_COLORSPACE_SRGB;
> -
> -	fmt->format = *format;
> -
> -	/* Propagate the format to the source pad. */
> -	format = vsp1_entity_get_pad_format(&clu->entity, config,
> -					    CLU_PAD_SOURCE);
> -	*format = fmt->format;
> -
> -done:
> -	mutex_unlock(&clu->entity.lock);
> -	return ret;
> +	return vsp1_subdev_set_pad_format(subdev, cfg, fmt, clu_codes,
> +					  ARRAY_SIZE(clu_codes),
> +					  CLU_MIN_SIZE, CLU_MIN_SIZE,
> +					  CLU_MAX_SIZE, CLU_MAX_SIZE);
>  }
>
>  /* -----------------------------------------------------------------------------
> diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c
> index 72354caf5746..239df047efd0 100644
> --- a/drivers/media/platform/vsp1/vsp1_entity.c
> +++ b/drivers/media/platform/vsp1/vsp1_entity.c
> @@ -307,6 +307,81 @@ int vsp1_subdev_enum_frame_size(struct v4l2_subdev *subdev,
>  	return ret;
>  }
>
> +/*
> + * vsp1_subdev_set_pad_format - Subdev pad set_fmt handler
> + * @subdev: V4L2 subdevice
> + * @cfg: V4L2 subdev pad configuration
> + * @fmt: V4L2 subdev format
> + * @codes: Array of supported media bus codes
> + * @ncodes: Number of supported media bus codes
> + * @min_width: Minimum image width
> + * @min_height: Minimum image height
> + * @max_width: Maximum image width
> + * @max_height: Maximum image height
> + *
> + * This function implements the subdev set_fmt pad operation for entities that
> + * do not support scaling or cropping. It defaults to the first supplied media
> + * bus code if the requested code isn't supported, clamps the size to the
> + * supplied minimum and maximum, and propagates the sink pad format to the
> + * source pad.
> + */
> +int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev,
> +			       struct v4l2_subdev_pad_config *cfg,
> +			       struct v4l2_subdev_format *fmt,
> +			       const unsigned int *codes, unsigned int ncodes,
> +			       unsigned int min_width, unsigned int min_height,
> +			       unsigned int max_width, unsigned int max_height)
> +{
> +	struct vsp1_entity *entity = to_vsp1_entity(subdev);
> +	struct v4l2_subdev_pad_config *config;
> +	struct v4l2_mbus_framefmt *format;
> +	unsigned int i;
> +	int ret = 0;
> +
> +	mutex_lock(&entity->lock);
> +
> +	config = vsp1_entity_get_pad_config(entity, cfg, fmt->which);
> +	if (!config) {
> +		ret = -EINVAL;
> +		goto done;
> +	}
> +
> +	format = vsp1_entity_get_pad_format(entity, config, fmt->pad);
> +
> +	if (fmt->pad != 0) {

This assumes the SINK pad is always 0, which indeed is the case for
CLU, LIF and LUT entities.

> +		/* The output format can't be modified. */
> +		fmt->format = *format;
> +		goto done;
> +	}
> +
> +	/*
> +	 * Default to the first media bus code if the requested format is not
> +	 * supported.
> +	 */
> +	for (i = 0; i < ncodes; ++i) {
> +		if (fmt->format.code == codes[i])
> +			break;
> +	}

Braces not needed?

> +
> +	format->code = i < ncodes ? codes[i] : codes[0];
> +	format->width = clamp_t(unsigned int, fmt->format.width,
> +				min_width, max_width);
> +	format->height = clamp_t(unsigned int, fmt->format.height,
> +				 min_height, max_height);
> +	format->field = V4L2_FIELD_NONE;
> +	format->colorspace = V4L2_COLORSPACE_SRGB;
> +
> +	fmt->format = *format;
> +
> +	/* Propagate the format to the source pad. */
> +	format = vsp1_entity_get_pad_format(entity, config, 1);
> +	*format = fmt->format;
> +
> +done:
> +	mutex_unlock(&entity->lock);
> +	return ret;
> +}
> +
>  /* -----------------------------------------------------------------------------
>   * Media Operations
>   */
> diff --git a/drivers/media/platform/vsp1/vsp1_entity.h b/drivers/media/platform/vsp1/vsp1_entity.h
> index fb20a1578f3b..0839a62cfa71 100644
> --- a/drivers/media/platform/vsp1/vsp1_entity.h
> +++ b/drivers/media/platform/vsp1/vsp1_entity.h
> @@ -160,6 +160,12 @@ struct media_pad *vsp1_entity_remote_pad(struct media_pad *pad);
>  int vsp1_subdev_get_pad_format(struct v4l2_subdev *subdev,
>  			       struct v4l2_subdev_pad_config *cfg,
>  			       struct v4l2_subdev_format *fmt);
> +int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev,
> +			       struct v4l2_subdev_pad_config *cfg,
> +			       struct v4l2_subdev_format *fmt,
> +			       const unsigned int *codes, unsigned int ncodes,
> +			       unsigned int min_width, unsigned int min_height,
> +			       unsigned int max_width, unsigned int max_height);
>  int vsp1_subdev_enum_mbus_code(struct v4l2_subdev *subdev,
>  			       struct v4l2_subdev_pad_config *cfg,
>  			       struct v4l2_subdev_mbus_code_enum *code,
> diff --git a/drivers/media/platform/vsp1/vsp1_lif.c b/drivers/media/platform/vsp1/vsp1_lif.c
> index b20b842f06ba..fbdd5715f829 100644
> --- a/drivers/media/platform/vsp1/vsp1_lif.c
> +++ b/drivers/media/platform/vsp1/vsp1_lif.c
> @@ -33,17 +33,17 @@ static inline void vsp1_lif_write(struct vsp1_lif *lif, struct vsp1_dl_list *dl,
>   * V4L2 Subdevice Operations
>   */
>
> +static const unsigned int lif_codes[] = {
> +	MEDIA_BUS_FMT_ARGB8888_1X32,
> +	MEDIA_BUS_FMT_AYUV8_1X32,
> +};
> +
>  static int lif_enum_mbus_code(struct v4l2_subdev *subdev,
>  			      struct v4l2_subdev_pad_config *cfg,
>  			      struct v4l2_subdev_mbus_code_enum *code)
>  {
> -	static const unsigned int codes[] = {
> -		MEDIA_BUS_FMT_ARGB8888_1X32,
> -		MEDIA_BUS_FMT_AYUV8_1X32,
> -	};
> -
> -	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, codes,
> -					  ARRAY_SIZE(codes));
> +	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, lif_codes,
> +					  ARRAY_SIZE(lif_codes));
>  }
>
>  static int lif_enum_frame_size(struct v4l2_subdev *subdev,
> @@ -59,53 +59,10 @@ static int lif_set_format(struct v4l2_subdev *subdev,
>  			  struct v4l2_subdev_pad_config *cfg,
>  			  struct v4l2_subdev_format *fmt)
>  {
> -	struct vsp1_lif *lif = to_lif(subdev);
> -	struct v4l2_subdev_pad_config *config;
> -	struct v4l2_mbus_framefmt *format;
> -	int ret = 0;
> -
> -	mutex_lock(&lif->entity.lock);
> -
> -	config = vsp1_entity_get_pad_config(&lif->entity, cfg, fmt->which);
> -	if (!config) {
> -		ret = -EINVAL;
> -		goto done;
> -	}
> -
> -	/* Default to YUV if the requested format is not supported. */
> -	if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
> -	    fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32)
> -		fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32;

Same here and below

Thanks
   j

> -
> -	format = vsp1_entity_get_pad_format(&lif->entity, config, fmt->pad);
> -
> -	if (fmt->pad == LIF_PAD_SOURCE) {
> -		/*
> -		 * The LIF source format is always identical to its sink
> -		 * format.
> -		 */
> -		fmt->format = *format;
> -		goto done;
> -	}
> -
> -	format->code = fmt->format.code;
> -	format->width = clamp_t(unsigned int, fmt->format.width,
> -				LIF_MIN_SIZE, LIF_MAX_SIZE);
> -	format->height = clamp_t(unsigned int, fmt->format.height,
> -				 LIF_MIN_SIZE, LIF_MAX_SIZE);
> -	format->field = V4L2_FIELD_NONE;
> -	format->colorspace = V4L2_COLORSPACE_SRGB;
> -
> -	fmt->format = *format;
> -
> -	/* Propagate the format to the source pad. */
> -	format = vsp1_entity_get_pad_format(&lif->entity, config,
> -					    LIF_PAD_SOURCE);
> -	*format = fmt->format;
> -
> -done:
> -	mutex_unlock(&lif->entity.lock);
> -	return ret;
> +	return vsp1_subdev_set_pad_format(subdev, cfg, fmt, lif_codes,
> +					  ARRAY_SIZE(lif_codes),
> +					  LIF_MIN_SIZE, LIF_MIN_SIZE,
> +					  LIF_MAX_SIZE, LIF_MAX_SIZE);
>  }
>
>  static const struct v4l2_subdev_pad_ops lif_pad_ops = {
> diff --git a/drivers/media/platform/vsp1/vsp1_lut.c b/drivers/media/platform/vsp1/vsp1_lut.c
> index 7bdabb311c6c..f2e48a02ca7d 100644
> --- a/drivers/media/platform/vsp1/vsp1_lut.c
> +++ b/drivers/media/platform/vsp1/vsp1_lut.c
> @@ -90,18 +90,18 @@ static const struct v4l2_ctrl_config lut_table_control = {
>   * V4L2 Subdevice Pad Operations
>   */
>
> +static const unsigned int lut_codes[] = {
> +	MEDIA_BUS_FMT_ARGB8888_1X32,
> +	MEDIA_BUS_FMT_AHSV8888_1X32,
> +	MEDIA_BUS_FMT_AYUV8_1X32,
> +};
> +
>  static int lut_enum_mbus_code(struct v4l2_subdev *subdev,
>  			      struct v4l2_subdev_pad_config *cfg,
>  			      struct v4l2_subdev_mbus_code_enum *code)
>  {
> -	static const unsigned int codes[] = {
> -		MEDIA_BUS_FMT_ARGB8888_1X32,
> -		MEDIA_BUS_FMT_AHSV8888_1X32,
> -		MEDIA_BUS_FMT_AYUV8_1X32,
> -	};
> -
> -	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, codes,
> -					  ARRAY_SIZE(codes));
> +	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, lut_codes,
> +					  ARRAY_SIZE(lut_codes));
>  }
>
>  static int lut_enum_frame_size(struct v4l2_subdev *subdev,
> @@ -117,51 +117,10 @@ static int lut_set_format(struct v4l2_subdev *subdev,
>  			  struct v4l2_subdev_pad_config *cfg,
>  			  struct v4l2_subdev_format *fmt)
>  {
> -	struct vsp1_lut *lut = to_lut(subdev);
> -	struct v4l2_subdev_pad_config *config;
> -	struct v4l2_mbus_framefmt *format;
> -	int ret = 0;
> -
> -	mutex_lock(&lut->entity.lock);
> -
> -	config = vsp1_entity_get_pad_config(&lut->entity, cfg, fmt->which);
> -	if (!config) {
> -		ret = -EINVAL;
> -		goto done;
> -	}
> -
> -	/* Default to YUV if the requested format is not supported. */
> -	if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
> -	    fmt->format.code != MEDIA_BUS_FMT_AHSV8888_1X32 &&
> -	    fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32)
> -		fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32;
> -
> -	format = vsp1_entity_get_pad_format(&lut->entity, config, fmt->pad);
> -
> -	if (fmt->pad == LUT_PAD_SOURCE) {
> -		/* The LUT output format can't be modified. */
> -		fmt->format = *format;
> -		goto done;
> -	}
> -
> -	format->code = fmt->format.code;
> -	format->width = clamp_t(unsigned int, fmt->format.width,
> -				LUT_MIN_SIZE, LUT_MAX_SIZE);
> -	format->height = clamp_t(unsigned int, fmt->format.height,
> -				 LUT_MIN_SIZE, LUT_MAX_SIZE);
> -	format->field = V4L2_FIELD_NONE;
> -	format->colorspace = V4L2_COLORSPACE_SRGB;
> -
> -	fmt->format = *format;
> -
> -	/* Propagate the format to the source pad. */
> -	format = vsp1_entity_get_pad_format(&lut->entity, config,
> -					    LUT_PAD_SOURCE);
> -	*format = fmt->format;
> -
> -done:
> -	mutex_unlock(&lut->entity.lock);
> -	return ret;
> +	return vsp1_subdev_set_pad_format(subdev, cfg, fmt, lut_codes,
> +					  ARRAY_SIZE(lut_codes),
> +					  LUT_MIN_SIZE, LUT_MIN_SIZE,
> +					  LUT_MAX_SIZE, LUT_MAX_SIZE);
>  }
>
>  /* -----------------------------------------------------------------------------
> --
> Regards,
>
> Laurent Pinchart
>

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

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

* Re: [PATCH v2 2/8] v4l: vsp1: Share the CLU, LIF and LUT set_fmt pad operation code
@ 2018-04-28  9:50     ` jacopo mondi
  0 siblings, 0 replies; 82+ messages in thread
From: jacopo mondi @ 2018-04-28  9:50 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: linux-renesas-soc, Kieran Bingham, dri-devel, linux-media


[-- Attachment #1.1: Type: text/plain, Size: 13802 bytes --]

Hi Laurent,
   very minor comments below

On Mon, Apr 23, 2018 at 01:34:24AM +0300, Laurent Pinchart wrote:
> The implementation of the set_fmt pad operation is identical in the
> three modules. Move it to a generic helper function.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>  drivers/media/platform/vsp1/vsp1_clu.c    | 65 +++++----------------------
>  drivers/media/platform/vsp1/vsp1_entity.c | 75 +++++++++++++++++++++++++++++++
>  drivers/media/platform/vsp1/vsp1_entity.h |  6 +++
>  drivers/media/platform/vsp1/vsp1_lif.c    | 65 +++++----------------------
>  drivers/media/platform/vsp1/vsp1_lut.c    | 65 +++++----------------------
>  5 files changed, 116 insertions(+), 160 deletions(-)
>
> diff --git a/drivers/media/platform/vsp1/vsp1_clu.c b/drivers/media/platform/vsp1/vsp1_clu.c
> index 9626b6308585..96a448e1504c 100644
> --- a/drivers/media/platform/vsp1/vsp1_clu.c
> +++ b/drivers/media/platform/vsp1/vsp1_clu.c
> @@ -114,18 +114,18 @@ static const struct v4l2_ctrl_config clu_mode_control = {
>   * V4L2 Subdevice Pad Operations
>   */
>
> +static const unsigned int clu_codes[] = {
> +	MEDIA_BUS_FMT_ARGB8888_1X32,
> +	MEDIA_BUS_FMT_AHSV8888_1X32,
> +	MEDIA_BUS_FMT_AYUV8_1X32,
> +};
> +
>  static int clu_enum_mbus_code(struct v4l2_subdev *subdev,
>  			      struct v4l2_subdev_pad_config *cfg,
>  			      struct v4l2_subdev_mbus_code_enum *code)
>  {
> -	static const unsigned int codes[] = {
> -		MEDIA_BUS_FMT_ARGB8888_1X32,
> -		MEDIA_BUS_FMT_AHSV8888_1X32,
> -		MEDIA_BUS_FMT_AYUV8_1X32,
> -	};
> -
> -	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, codes,
> -					  ARRAY_SIZE(codes));
> +	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, clu_codes,
> +					  ARRAY_SIZE(clu_codes));
>  }
>
>  static int clu_enum_frame_size(struct v4l2_subdev *subdev,
> @@ -141,51 +141,10 @@ static int clu_set_format(struct v4l2_subdev *subdev,
>  			  struct v4l2_subdev_pad_config *cfg,
>  			  struct v4l2_subdev_format *fmt)
>  {
> -	struct vsp1_clu *clu = to_clu(subdev);
> -	struct v4l2_subdev_pad_config *config;
> -	struct v4l2_mbus_framefmt *format;
> -	int ret = 0;
> -
> -	mutex_lock(&clu->entity.lock);
> -
> -	config = vsp1_entity_get_pad_config(&clu->entity, cfg, fmt->which);
> -	if (!config) {
> -		ret = -EINVAL;
> -		goto done;
> -	}
> -
> -	/* Default to YUV if the requested format is not supported. */
> -	if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
> -	    fmt->format.code != MEDIA_BUS_FMT_AHSV8888_1X32 &&
> -	    fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32)
> -		fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32;

The newly implemented vsp1_subdev_set_pad_format defaults to the first
clu_codes[] member (ARGB888_1x32), while here the code chose the AYUV8_1x32
format. Is it ok? Should you revers the clu_codes[] order?

> -
> -	format = vsp1_entity_get_pad_format(&clu->entity, config, fmt->pad);
> -
> -	if (fmt->pad == CLU_PAD_SOURCE) {
> -		/* The CLU output format can't be modified. */
> -		fmt->format = *format;
> -		goto done;
> -	}
> -
> -	format->code = fmt->format.code;
> -	format->width = clamp_t(unsigned int, fmt->format.width,
> -				CLU_MIN_SIZE, CLU_MAX_SIZE);
> -	format->height = clamp_t(unsigned int, fmt->format.height,
> -				 CLU_MIN_SIZE, CLU_MAX_SIZE);
> -	format->field = V4L2_FIELD_NONE;
> -	format->colorspace = V4L2_COLORSPACE_SRGB;
> -
> -	fmt->format = *format;
> -
> -	/* Propagate the format to the source pad. */
> -	format = vsp1_entity_get_pad_format(&clu->entity, config,
> -					    CLU_PAD_SOURCE);
> -	*format = fmt->format;
> -
> -done:
> -	mutex_unlock(&clu->entity.lock);
> -	return ret;
> +	return vsp1_subdev_set_pad_format(subdev, cfg, fmt, clu_codes,
> +					  ARRAY_SIZE(clu_codes),
> +					  CLU_MIN_SIZE, CLU_MIN_SIZE,
> +					  CLU_MAX_SIZE, CLU_MAX_SIZE);
>  }
>
>  /* -----------------------------------------------------------------------------
> diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c
> index 72354caf5746..239df047efd0 100644
> --- a/drivers/media/platform/vsp1/vsp1_entity.c
> +++ b/drivers/media/platform/vsp1/vsp1_entity.c
> @@ -307,6 +307,81 @@ int vsp1_subdev_enum_frame_size(struct v4l2_subdev *subdev,
>  	return ret;
>  }
>
> +/*
> + * vsp1_subdev_set_pad_format - Subdev pad set_fmt handler
> + * @subdev: V4L2 subdevice
> + * @cfg: V4L2 subdev pad configuration
> + * @fmt: V4L2 subdev format
> + * @codes: Array of supported media bus codes
> + * @ncodes: Number of supported media bus codes
> + * @min_width: Minimum image width
> + * @min_height: Minimum image height
> + * @max_width: Maximum image width
> + * @max_height: Maximum image height
> + *
> + * This function implements the subdev set_fmt pad operation for entities that
> + * do not support scaling or cropping. It defaults to the first supplied media
> + * bus code if the requested code isn't supported, clamps the size to the
> + * supplied minimum and maximum, and propagates the sink pad format to the
> + * source pad.
> + */
> +int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev,
> +			       struct v4l2_subdev_pad_config *cfg,
> +			       struct v4l2_subdev_format *fmt,
> +			       const unsigned int *codes, unsigned int ncodes,
> +			       unsigned int min_width, unsigned int min_height,
> +			       unsigned int max_width, unsigned int max_height)
> +{
> +	struct vsp1_entity *entity = to_vsp1_entity(subdev);
> +	struct v4l2_subdev_pad_config *config;
> +	struct v4l2_mbus_framefmt *format;
> +	unsigned int i;
> +	int ret = 0;
> +
> +	mutex_lock(&entity->lock);
> +
> +	config = vsp1_entity_get_pad_config(entity, cfg, fmt->which);
> +	if (!config) {
> +		ret = -EINVAL;
> +		goto done;
> +	}
> +
> +	format = vsp1_entity_get_pad_format(entity, config, fmt->pad);
> +
> +	if (fmt->pad != 0) {

This assumes the SINK pad is always 0, which indeed is the case for
CLU, LIF and LUT entities.

> +		/* The output format can't be modified. */
> +		fmt->format = *format;
> +		goto done;
> +	}
> +
> +	/*
> +	 * Default to the first media bus code if the requested format is not
> +	 * supported.
> +	 */
> +	for (i = 0; i < ncodes; ++i) {
> +		if (fmt->format.code == codes[i])
> +			break;
> +	}

Braces not needed?

> +
> +	format->code = i < ncodes ? codes[i] : codes[0];
> +	format->width = clamp_t(unsigned int, fmt->format.width,
> +				min_width, max_width);
> +	format->height = clamp_t(unsigned int, fmt->format.height,
> +				 min_height, max_height);
> +	format->field = V4L2_FIELD_NONE;
> +	format->colorspace = V4L2_COLORSPACE_SRGB;
> +
> +	fmt->format = *format;
> +
> +	/* Propagate the format to the source pad. */
> +	format = vsp1_entity_get_pad_format(entity, config, 1);
> +	*format = fmt->format;
> +
> +done:
> +	mutex_unlock(&entity->lock);
> +	return ret;
> +}
> +
>  /* -----------------------------------------------------------------------------
>   * Media Operations
>   */
> diff --git a/drivers/media/platform/vsp1/vsp1_entity.h b/drivers/media/platform/vsp1/vsp1_entity.h
> index fb20a1578f3b..0839a62cfa71 100644
> --- a/drivers/media/platform/vsp1/vsp1_entity.h
> +++ b/drivers/media/platform/vsp1/vsp1_entity.h
> @@ -160,6 +160,12 @@ struct media_pad *vsp1_entity_remote_pad(struct media_pad *pad);
>  int vsp1_subdev_get_pad_format(struct v4l2_subdev *subdev,
>  			       struct v4l2_subdev_pad_config *cfg,
>  			       struct v4l2_subdev_format *fmt);
> +int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev,
> +			       struct v4l2_subdev_pad_config *cfg,
> +			       struct v4l2_subdev_format *fmt,
> +			       const unsigned int *codes, unsigned int ncodes,
> +			       unsigned int min_width, unsigned int min_height,
> +			       unsigned int max_width, unsigned int max_height);
>  int vsp1_subdev_enum_mbus_code(struct v4l2_subdev *subdev,
>  			       struct v4l2_subdev_pad_config *cfg,
>  			       struct v4l2_subdev_mbus_code_enum *code,
> diff --git a/drivers/media/platform/vsp1/vsp1_lif.c b/drivers/media/platform/vsp1/vsp1_lif.c
> index b20b842f06ba..fbdd5715f829 100644
> --- a/drivers/media/platform/vsp1/vsp1_lif.c
> +++ b/drivers/media/platform/vsp1/vsp1_lif.c
> @@ -33,17 +33,17 @@ static inline void vsp1_lif_write(struct vsp1_lif *lif, struct vsp1_dl_list *dl,
>   * V4L2 Subdevice Operations
>   */
>
> +static const unsigned int lif_codes[] = {
> +	MEDIA_BUS_FMT_ARGB8888_1X32,
> +	MEDIA_BUS_FMT_AYUV8_1X32,
> +};
> +
>  static int lif_enum_mbus_code(struct v4l2_subdev *subdev,
>  			      struct v4l2_subdev_pad_config *cfg,
>  			      struct v4l2_subdev_mbus_code_enum *code)
>  {
> -	static const unsigned int codes[] = {
> -		MEDIA_BUS_FMT_ARGB8888_1X32,
> -		MEDIA_BUS_FMT_AYUV8_1X32,
> -	};
> -
> -	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, codes,
> -					  ARRAY_SIZE(codes));
> +	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, lif_codes,
> +					  ARRAY_SIZE(lif_codes));
>  }
>
>  static int lif_enum_frame_size(struct v4l2_subdev *subdev,
> @@ -59,53 +59,10 @@ static int lif_set_format(struct v4l2_subdev *subdev,
>  			  struct v4l2_subdev_pad_config *cfg,
>  			  struct v4l2_subdev_format *fmt)
>  {
> -	struct vsp1_lif *lif = to_lif(subdev);
> -	struct v4l2_subdev_pad_config *config;
> -	struct v4l2_mbus_framefmt *format;
> -	int ret = 0;
> -
> -	mutex_lock(&lif->entity.lock);
> -
> -	config = vsp1_entity_get_pad_config(&lif->entity, cfg, fmt->which);
> -	if (!config) {
> -		ret = -EINVAL;
> -		goto done;
> -	}
> -
> -	/* Default to YUV if the requested format is not supported. */
> -	if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
> -	    fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32)
> -		fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32;

Same here and below

Thanks
   j

> -
> -	format = vsp1_entity_get_pad_format(&lif->entity, config, fmt->pad);
> -
> -	if (fmt->pad == LIF_PAD_SOURCE) {
> -		/*
> -		 * The LIF source format is always identical to its sink
> -		 * format.
> -		 */
> -		fmt->format = *format;
> -		goto done;
> -	}
> -
> -	format->code = fmt->format.code;
> -	format->width = clamp_t(unsigned int, fmt->format.width,
> -				LIF_MIN_SIZE, LIF_MAX_SIZE);
> -	format->height = clamp_t(unsigned int, fmt->format.height,
> -				 LIF_MIN_SIZE, LIF_MAX_SIZE);
> -	format->field = V4L2_FIELD_NONE;
> -	format->colorspace = V4L2_COLORSPACE_SRGB;
> -
> -	fmt->format = *format;
> -
> -	/* Propagate the format to the source pad. */
> -	format = vsp1_entity_get_pad_format(&lif->entity, config,
> -					    LIF_PAD_SOURCE);
> -	*format = fmt->format;
> -
> -done:
> -	mutex_unlock(&lif->entity.lock);
> -	return ret;
> +	return vsp1_subdev_set_pad_format(subdev, cfg, fmt, lif_codes,
> +					  ARRAY_SIZE(lif_codes),
> +					  LIF_MIN_SIZE, LIF_MIN_SIZE,
> +					  LIF_MAX_SIZE, LIF_MAX_SIZE);
>  }
>
>  static const struct v4l2_subdev_pad_ops lif_pad_ops = {
> diff --git a/drivers/media/platform/vsp1/vsp1_lut.c b/drivers/media/platform/vsp1/vsp1_lut.c
> index 7bdabb311c6c..f2e48a02ca7d 100644
> --- a/drivers/media/platform/vsp1/vsp1_lut.c
> +++ b/drivers/media/platform/vsp1/vsp1_lut.c
> @@ -90,18 +90,18 @@ static const struct v4l2_ctrl_config lut_table_control = {
>   * V4L2 Subdevice Pad Operations
>   */
>
> +static const unsigned int lut_codes[] = {
> +	MEDIA_BUS_FMT_ARGB8888_1X32,
> +	MEDIA_BUS_FMT_AHSV8888_1X32,
> +	MEDIA_BUS_FMT_AYUV8_1X32,
> +};
> +
>  static int lut_enum_mbus_code(struct v4l2_subdev *subdev,
>  			      struct v4l2_subdev_pad_config *cfg,
>  			      struct v4l2_subdev_mbus_code_enum *code)
>  {
> -	static const unsigned int codes[] = {
> -		MEDIA_BUS_FMT_ARGB8888_1X32,
> -		MEDIA_BUS_FMT_AHSV8888_1X32,
> -		MEDIA_BUS_FMT_AYUV8_1X32,
> -	};
> -
> -	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, codes,
> -					  ARRAY_SIZE(codes));
> +	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, lut_codes,
> +					  ARRAY_SIZE(lut_codes));
>  }
>
>  static int lut_enum_frame_size(struct v4l2_subdev *subdev,
> @@ -117,51 +117,10 @@ static int lut_set_format(struct v4l2_subdev *subdev,
>  			  struct v4l2_subdev_pad_config *cfg,
>  			  struct v4l2_subdev_format *fmt)
>  {
> -	struct vsp1_lut *lut = to_lut(subdev);
> -	struct v4l2_subdev_pad_config *config;
> -	struct v4l2_mbus_framefmt *format;
> -	int ret = 0;
> -
> -	mutex_lock(&lut->entity.lock);
> -
> -	config = vsp1_entity_get_pad_config(&lut->entity, cfg, fmt->which);
> -	if (!config) {
> -		ret = -EINVAL;
> -		goto done;
> -	}
> -
> -	/* Default to YUV if the requested format is not supported. */
> -	if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
> -	    fmt->format.code != MEDIA_BUS_FMT_AHSV8888_1X32 &&
> -	    fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32)
> -		fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32;
> -
> -	format = vsp1_entity_get_pad_format(&lut->entity, config, fmt->pad);
> -
> -	if (fmt->pad == LUT_PAD_SOURCE) {
> -		/* The LUT output format can't be modified. */
> -		fmt->format = *format;
> -		goto done;
> -	}
> -
> -	format->code = fmt->format.code;
> -	format->width = clamp_t(unsigned int, fmt->format.width,
> -				LUT_MIN_SIZE, LUT_MAX_SIZE);
> -	format->height = clamp_t(unsigned int, fmt->format.height,
> -				 LUT_MIN_SIZE, LUT_MAX_SIZE);
> -	format->field = V4L2_FIELD_NONE;
> -	format->colorspace = V4L2_COLORSPACE_SRGB;
> -
> -	fmt->format = *format;
> -
> -	/* Propagate the format to the source pad. */
> -	format = vsp1_entity_get_pad_format(&lut->entity, config,
> -					    LUT_PAD_SOURCE);
> -	*format = fmt->format;
> -
> -done:
> -	mutex_unlock(&lut->entity.lock);
> -	return ret;
> +	return vsp1_subdev_set_pad_format(subdev, cfg, fmt, lut_codes,
> +					  ARRAY_SIZE(lut_codes),
> +					  LUT_MIN_SIZE, LUT_MIN_SIZE,
> +					  LUT_MAX_SIZE, LUT_MAX_SIZE);
>  }
>
>  /* -----------------------------------------------------------------------------
> --
> Regards,
>
> Laurent Pinchart
>

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

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

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

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

* Re: [PATCH v2 3/8] v4l: vsp1: Reset the crop and compose rectangles in the set_fmt helper
  2018-04-22 22:34   ` Laurent Pinchart
@ 2018-04-28  9:56     ` jacopo mondi
  -1 siblings, 0 replies; 82+ messages in thread
From: jacopo mondi @ 2018-04-28  9:56 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: linux-media, dri-devel, linux-renesas-soc, Kieran Bingham

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

Hi Laurent,

On Mon, Apr 23, 2018 at 01:34:25AM +0300, Laurent Pinchart wrote:
> To make vsp1_subdev_set_pad_format() usable by entities that support
> selection rectangles, we need to reset the crop and compose rectangles
> when setting the format on the sink pad. Do so and replace the custom
> set_fmt implementation of the histogram code by a call to
> vsp1_subdev_set_pad_format().
>
> Resetting the crop and compose rectangles for entities that don't
> support crop and compose has no adverse effect as the rectangles are
> ignored anyway.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>


> ---
>  drivers/media/platform/vsp1/vsp1_entity.c | 16 +++++++++
>  drivers/media/platform/vsp1/vsp1_histo.c  | 59 +++----------------------------
>  2 files changed, 20 insertions(+), 55 deletions(-)
>
> diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c
> index 239df047efd0..181a583aecad 100644
> --- a/drivers/media/platform/vsp1/vsp1_entity.c
> +++ b/drivers/media/platform/vsp1/vsp1_entity.c
> @@ -335,6 +335,7 @@ int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev,
>  	struct vsp1_entity *entity = to_vsp1_entity(subdev);
>  	struct v4l2_subdev_pad_config *config;
>  	struct v4l2_mbus_framefmt *format;
> +	struct v4l2_rect *selection;
>  	unsigned int i;
>  	int ret = 0;
>
> @@ -377,6 +378,21 @@ int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev,
>  	format = vsp1_entity_get_pad_format(entity, config, 1);
>  	*format = fmt->format;
>
> +	/* Reset the crop and compose rectangles */
> +	selection = vsp1_entity_get_pad_selection(entity, config, fmt->pad,
> +						  V4L2_SEL_TGT_CROP);
> +	selection->left = 0;
> +	selection->top = 0;
> +	selection->width = format->width;
> +	selection->height = format->height;
> +
> +	selection = vsp1_entity_get_pad_selection(entity, config, fmt->pad,
> +						  V4L2_SEL_TGT_COMPOSE);
> +	selection->left = 0;
> +	selection->top = 0;
> +	selection->width = format->width;
> +	selection->height = format->height;
> +
>  done:
>  	mutex_unlock(&entity->lock);
>  	return ret;
> diff --git a/drivers/media/platform/vsp1/vsp1_histo.c b/drivers/media/platform/vsp1/vsp1_histo.c
> index 029181c1fb61..5e15c8ff88d9 100644
> --- a/drivers/media/platform/vsp1/vsp1_histo.c
> +++ b/drivers/media/platform/vsp1/vsp1_histo.c
> @@ -389,65 +389,14 @@ static int histo_set_format(struct v4l2_subdev *subdev,
>  			    struct v4l2_subdev_format *fmt)
>  {
>  	struct vsp1_histogram *histo = subdev_to_histo(subdev);
> -	struct v4l2_subdev_pad_config *config;
> -	struct v4l2_mbus_framefmt *format;
> -	struct v4l2_rect *selection;
> -	unsigned int i;
> -	int ret = 0;
>
>  	if (fmt->pad != HISTO_PAD_SINK)
>  		return histo_get_format(subdev, cfg, fmt);
>
> -	mutex_lock(&histo->entity.lock);
> -
> -	config = vsp1_entity_get_pad_config(&histo->entity, cfg, fmt->which);
> -	if (!config) {
> -		ret = -EINVAL;
> -		goto done;
> -	}
> -
> -	/*
> -	 * Default to the first format if the requested format is not
> -	 * supported.
> -	 */
> -	for (i = 0; i < histo->num_formats; ++i) {
> -		if (fmt->format.code == histo->formats[i])
> -			break;
> -	}
> -	if (i == histo->num_formats)
> -		fmt->format.code = histo->formats[0];
> -
> -	format = vsp1_entity_get_pad_format(&histo->entity, config, fmt->pad);
> -
> -	format->code = fmt->format.code;
> -	format->width = clamp_t(unsigned int, fmt->format.width,
> -				HISTO_MIN_SIZE, HISTO_MAX_SIZE);
> -	format->height = clamp_t(unsigned int, fmt->format.height,
> -				 HISTO_MIN_SIZE, HISTO_MAX_SIZE);
> -	format->field = V4L2_FIELD_NONE;
> -	format->colorspace = V4L2_COLORSPACE_SRGB;
> -
> -	fmt->format = *format;
> -
> -	/* Reset the crop and compose rectangles */
> -	selection = vsp1_entity_get_pad_selection(&histo->entity, config,
> -						  fmt->pad, V4L2_SEL_TGT_CROP);
> -	selection->left = 0;
> -	selection->top = 0;
> -	selection->width = format->width;
> -	selection->height = format->height;
> -
> -	selection = vsp1_entity_get_pad_selection(&histo->entity, config,
> -						  fmt->pad,
> -						  V4L2_SEL_TGT_COMPOSE);
> -	selection->left = 0;
> -	selection->top = 0;
> -	selection->width = format->width;
> -	selection->height = format->height;
> -
> -done:
> -	mutex_unlock(&histo->entity.lock);
> -	return ret;
> +	return vsp1_subdev_set_pad_format(subdev, cfg, fmt,
> +					  histo->formats, histo->num_formats,
> +					  HISTO_MIN_SIZE, HISTO_MIN_SIZE,
> +					  HISTO_MAX_SIZE, HISTO_MAX_SIZE);
>  }
>
>  static const struct v4l2_subdev_pad_ops histo_pad_ops = {
> --
> Regards,
>
> Laurent Pinchart
>

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

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

* Re: [PATCH v2 3/8] v4l: vsp1: Reset the crop and compose rectangles in the set_fmt helper
@ 2018-04-28  9:56     ` jacopo mondi
  0 siblings, 0 replies; 82+ messages in thread
From: jacopo mondi @ 2018-04-28  9:56 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: linux-renesas-soc, Kieran Bingham, dri-devel, linux-media


[-- Attachment #1.1: Type: text/plain, Size: 4645 bytes --]

Hi Laurent,

On Mon, Apr 23, 2018 at 01:34:25AM +0300, Laurent Pinchart wrote:
> To make vsp1_subdev_set_pad_format() usable by entities that support
> selection rectangles, we need to reset the crop and compose rectangles
> when setting the format on the sink pad. Do so and replace the custom
> set_fmt implementation of the histogram code by a call to
> vsp1_subdev_set_pad_format().
>
> Resetting the crop and compose rectangles for entities that don't
> support crop and compose has no adverse effect as the rectangles are
> ignored anyway.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>


> ---
>  drivers/media/platform/vsp1/vsp1_entity.c | 16 +++++++++
>  drivers/media/platform/vsp1/vsp1_histo.c  | 59 +++----------------------------
>  2 files changed, 20 insertions(+), 55 deletions(-)
>
> diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c
> index 239df047efd0..181a583aecad 100644
> --- a/drivers/media/platform/vsp1/vsp1_entity.c
> +++ b/drivers/media/platform/vsp1/vsp1_entity.c
> @@ -335,6 +335,7 @@ int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev,
>  	struct vsp1_entity *entity = to_vsp1_entity(subdev);
>  	struct v4l2_subdev_pad_config *config;
>  	struct v4l2_mbus_framefmt *format;
> +	struct v4l2_rect *selection;
>  	unsigned int i;
>  	int ret = 0;
>
> @@ -377,6 +378,21 @@ int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev,
>  	format = vsp1_entity_get_pad_format(entity, config, 1);
>  	*format = fmt->format;
>
> +	/* Reset the crop and compose rectangles */
> +	selection = vsp1_entity_get_pad_selection(entity, config, fmt->pad,
> +						  V4L2_SEL_TGT_CROP);
> +	selection->left = 0;
> +	selection->top = 0;
> +	selection->width = format->width;
> +	selection->height = format->height;
> +
> +	selection = vsp1_entity_get_pad_selection(entity, config, fmt->pad,
> +						  V4L2_SEL_TGT_COMPOSE);
> +	selection->left = 0;
> +	selection->top = 0;
> +	selection->width = format->width;
> +	selection->height = format->height;
> +
>  done:
>  	mutex_unlock(&entity->lock);
>  	return ret;
> diff --git a/drivers/media/platform/vsp1/vsp1_histo.c b/drivers/media/platform/vsp1/vsp1_histo.c
> index 029181c1fb61..5e15c8ff88d9 100644
> --- a/drivers/media/platform/vsp1/vsp1_histo.c
> +++ b/drivers/media/platform/vsp1/vsp1_histo.c
> @@ -389,65 +389,14 @@ static int histo_set_format(struct v4l2_subdev *subdev,
>  			    struct v4l2_subdev_format *fmt)
>  {
>  	struct vsp1_histogram *histo = subdev_to_histo(subdev);
> -	struct v4l2_subdev_pad_config *config;
> -	struct v4l2_mbus_framefmt *format;
> -	struct v4l2_rect *selection;
> -	unsigned int i;
> -	int ret = 0;
>
>  	if (fmt->pad != HISTO_PAD_SINK)
>  		return histo_get_format(subdev, cfg, fmt);
>
> -	mutex_lock(&histo->entity.lock);
> -
> -	config = vsp1_entity_get_pad_config(&histo->entity, cfg, fmt->which);
> -	if (!config) {
> -		ret = -EINVAL;
> -		goto done;
> -	}
> -
> -	/*
> -	 * Default to the first format if the requested format is not
> -	 * supported.
> -	 */
> -	for (i = 0; i < histo->num_formats; ++i) {
> -		if (fmt->format.code == histo->formats[i])
> -			break;
> -	}
> -	if (i == histo->num_formats)
> -		fmt->format.code = histo->formats[0];
> -
> -	format = vsp1_entity_get_pad_format(&histo->entity, config, fmt->pad);
> -
> -	format->code = fmt->format.code;
> -	format->width = clamp_t(unsigned int, fmt->format.width,
> -				HISTO_MIN_SIZE, HISTO_MAX_SIZE);
> -	format->height = clamp_t(unsigned int, fmt->format.height,
> -				 HISTO_MIN_SIZE, HISTO_MAX_SIZE);
> -	format->field = V4L2_FIELD_NONE;
> -	format->colorspace = V4L2_COLORSPACE_SRGB;
> -
> -	fmt->format = *format;
> -
> -	/* Reset the crop and compose rectangles */
> -	selection = vsp1_entity_get_pad_selection(&histo->entity, config,
> -						  fmt->pad, V4L2_SEL_TGT_CROP);
> -	selection->left = 0;
> -	selection->top = 0;
> -	selection->width = format->width;
> -	selection->height = format->height;
> -
> -	selection = vsp1_entity_get_pad_selection(&histo->entity, config,
> -						  fmt->pad,
> -						  V4L2_SEL_TGT_COMPOSE);
> -	selection->left = 0;
> -	selection->top = 0;
> -	selection->width = format->width;
> -	selection->height = format->height;
> -
> -done:
> -	mutex_unlock(&histo->entity.lock);
> -	return ret;
> +	return vsp1_subdev_set_pad_format(subdev, cfg, fmt,
> +					  histo->formats, histo->num_formats,
> +					  HISTO_MIN_SIZE, HISTO_MIN_SIZE,
> +					  HISTO_MAX_SIZE, HISTO_MAX_SIZE);
>  }
>
>  static const struct v4l2_subdev_pad_ops histo_pad_ops = {
> --
> Regards,
>
> Laurent Pinchart
>

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

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

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

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

* Re: [PATCH v2 5/8] v4l: vsp1: Extend the DU API to support CRC computation
  2018-04-22 22:34   ` Laurent Pinchart
@ 2018-04-28 10:03     ` jacopo mondi
  -1 siblings, 0 replies; 82+ messages in thread
From: jacopo mondi @ 2018-04-28 10:03 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: linux-media, dri-devel, linux-renesas-soc, Kieran Bingham

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

Hi Laurent,
   just one minor comment below

On Mon, Apr 23, 2018 at 01:34:27AM +0300, Laurent Pinchart wrote:
> Add a parameter (in the form of a structure to ease future API
> extensions) to the VSP atomic flush handler to pass CRC source
> configuration, and pass the CRC value to the completion callback.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>  drivers/gpu/drm/rcar-du/rcar_du_vsp.c  |  6 ++++--
>  drivers/media/platform/vsp1/vsp1_drm.c |  6 ++++--
>  drivers/media/platform/vsp1/vsp1_drm.h |  2 +-
>  include/media/vsp1.h                   | 29 +++++++++++++++++++++++++++--
>  4 files changed, 36 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
> index 2c260c33840b..bdcec201591f 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
> @@ -31,7 +31,7 @@
>  #include "rcar_du_kms.h"
>  #include "rcar_du_vsp.h"
>
> -static void rcar_du_vsp_complete(void *private, bool completed)
> +static void rcar_du_vsp_complete(void *private, bool completed, u32 crc)
>  {
>  	struct rcar_du_crtc *crtc = private;
>
> @@ -102,7 +102,9 @@ void rcar_du_vsp_atomic_begin(struct rcar_du_crtc *crtc)
>
>  void rcar_du_vsp_atomic_flush(struct rcar_du_crtc *crtc)
>  {
> -	vsp1_du_atomic_flush(crtc->vsp->vsp, crtc->vsp_pipe);
> +	struct vsp1_du_atomic_pipe_config cfg = { { 0, } };
> +
> +	vsp1_du_atomic_flush(crtc->vsp->vsp, crtc->vsp_pipe, &cfg);
>  }
>
>  /* Keep the two tables in sync. */
> diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c
> index 2b29a83dceb9..5fc31578f9b0 100644
> --- a/drivers/media/platform/vsp1/vsp1_drm.c
> +++ b/drivers/media/platform/vsp1/vsp1_drm.c
> @@ -36,7 +36,7 @@ static void vsp1_du_pipeline_frame_end(struct vsp1_pipeline *pipe,
>  	bool complete = completion == VSP1_DL_FRAME_END_COMPLETED;
>
>  	if (drm_pipe->du_complete)
> -		drm_pipe->du_complete(drm_pipe->du_private, complete);
> +		drm_pipe->du_complete(drm_pipe->du_private, complete, 0);
>
>  	if (completion & VSP1_DL_FRAME_END_INTERNAL) {
>  		drm_pipe->force_brx_release = false;
> @@ -739,8 +739,10 @@ EXPORT_SYMBOL_GPL(vsp1_du_atomic_update);
>   * vsp1_du_atomic_flush - Commit an atomic update
>   * @dev: the VSP device
>   * @pipe_index: the DRM pipeline index
> + * @cfg: atomic pipe configuration
>   */
> -void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index)
> +void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index,
> +			  const struct vsp1_du_atomic_pipe_config *cfg)
>  {
>  	struct vsp1_device *vsp1 = dev_get_drvdata(dev);
>  	struct vsp1_drm_pipeline *drm_pipe = &vsp1->drm->pipe[pipe_index];
> diff --git a/drivers/media/platform/vsp1/vsp1_drm.h b/drivers/media/platform/vsp1/vsp1_drm.h
> index f4af1b2b12d6..e5b88b28806c 100644
> --- a/drivers/media/platform/vsp1/vsp1_drm.h
> +++ b/drivers/media/platform/vsp1/vsp1_drm.h
> @@ -35,7 +35,7 @@ struct vsp1_drm_pipeline {
>  	wait_queue_head_t wait_queue;
>
>  	/* Frame synchronisation */
> -	void (*du_complete)(void *, bool);
> +	void (*du_complete)(void *data, bool completed, u32 crc);
>  	void *du_private;
>  };
>
> diff --git a/include/media/vsp1.h b/include/media/vsp1.h
> index ff7ef894465d..ac63a9928a79 100644
> --- a/include/media/vsp1.h
> +++ b/include/media/vsp1.h
> @@ -34,7 +34,7 @@ struct vsp1_du_lif_config {
>  	unsigned int width;
>  	unsigned int height;
>
> -	void (*callback)(void *, bool);
> +	void (*callback)(void *data, bool completed, u32 crc);
>  	void *callback_data;
>  };
>
> @@ -61,11 +61,36 @@ struct vsp1_du_atomic_config {
>  	unsigned int zpos;
>  };
>
> +/**
> + * enum vsp1_du_crc_source - Source used for CRC calculation
> + * @VSP1_DU_CRC_NONE: CRC calculation disabled
> + * @VSP_DU_CRC_PLANE: Perform CRC calculation on an input plane
> + * @VSP_DU_CRC_OUTPUT: Perform CRC calculation on the composed output

These two paramters are called VSP1_DU_CRC_* not VSP_DU_CRC_*


> + */
> +enum vsp1_du_crc_source {
> +	VSP1_DU_CRC_NONE,
> +	VSP1_DU_CRC_PLANE,
> +	VSP1_DU_CRC_OUTPUT,
> +};
> +
> +/**
> + * struct vsp1_du_atomic_pipe_config - VSP atomic pipe configuration parameters
> + * @crc.source: source for CRC calculation
> + * @crc.index: index of the CRC source plane (when crc.source is set to plane)
> + */
> +struct vsp1_du_atomic_pipe_config {
> +	struct  {
> +		enum vsp1_du_crc_source source;
> +		unsigned int index;
> +	} crc;
> +};
> +
>  void vsp1_du_atomic_begin(struct device *dev, unsigned int pipe_index);
>  int vsp1_du_atomic_update(struct device *dev, unsigned int pipe_index,
>  			  unsigned int rpf,
>  			  const struct vsp1_du_atomic_config *cfg);
> -void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index);
> +void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index,
> +			  const struct vsp1_du_atomic_pipe_config *cfg);
>  int vsp1_du_map_sg(struct device *dev, struct sg_table *sgt);
>  void vsp1_du_unmap_sg(struct device *dev, struct sg_table *sgt);
>
> --
> Regards,
>
> Laurent Pinchart
>

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

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

* Re: [PATCH v2 5/8] v4l: vsp1: Extend the DU API to support CRC computation
@ 2018-04-28 10:03     ` jacopo mondi
  0 siblings, 0 replies; 82+ messages in thread
From: jacopo mondi @ 2018-04-28 10:03 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: linux-renesas-soc, Kieran Bingham, dri-devel, linux-media


[-- Attachment #1.1: Type: text/plain, Size: 5101 bytes --]

Hi Laurent,
   just one minor comment below

On Mon, Apr 23, 2018 at 01:34:27AM +0300, Laurent Pinchart wrote:
> Add a parameter (in the form of a structure to ease future API
> extensions) to the VSP atomic flush handler to pass CRC source
> configuration, and pass the CRC value to the completion callback.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>  drivers/gpu/drm/rcar-du/rcar_du_vsp.c  |  6 ++++--
>  drivers/media/platform/vsp1/vsp1_drm.c |  6 ++++--
>  drivers/media/platform/vsp1/vsp1_drm.h |  2 +-
>  include/media/vsp1.h                   | 29 +++++++++++++++++++++++++++--
>  4 files changed, 36 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
> index 2c260c33840b..bdcec201591f 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
> @@ -31,7 +31,7 @@
>  #include "rcar_du_kms.h"
>  #include "rcar_du_vsp.h"
>
> -static void rcar_du_vsp_complete(void *private, bool completed)
> +static void rcar_du_vsp_complete(void *private, bool completed, u32 crc)
>  {
>  	struct rcar_du_crtc *crtc = private;
>
> @@ -102,7 +102,9 @@ void rcar_du_vsp_atomic_begin(struct rcar_du_crtc *crtc)
>
>  void rcar_du_vsp_atomic_flush(struct rcar_du_crtc *crtc)
>  {
> -	vsp1_du_atomic_flush(crtc->vsp->vsp, crtc->vsp_pipe);
> +	struct vsp1_du_atomic_pipe_config cfg = { { 0, } };
> +
> +	vsp1_du_atomic_flush(crtc->vsp->vsp, crtc->vsp_pipe, &cfg);
>  }
>
>  /* Keep the two tables in sync. */
> diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c
> index 2b29a83dceb9..5fc31578f9b0 100644
> --- a/drivers/media/platform/vsp1/vsp1_drm.c
> +++ b/drivers/media/platform/vsp1/vsp1_drm.c
> @@ -36,7 +36,7 @@ static void vsp1_du_pipeline_frame_end(struct vsp1_pipeline *pipe,
>  	bool complete = completion == VSP1_DL_FRAME_END_COMPLETED;
>
>  	if (drm_pipe->du_complete)
> -		drm_pipe->du_complete(drm_pipe->du_private, complete);
> +		drm_pipe->du_complete(drm_pipe->du_private, complete, 0);
>
>  	if (completion & VSP1_DL_FRAME_END_INTERNAL) {
>  		drm_pipe->force_brx_release = false;
> @@ -739,8 +739,10 @@ EXPORT_SYMBOL_GPL(vsp1_du_atomic_update);
>   * vsp1_du_atomic_flush - Commit an atomic update
>   * @dev: the VSP device
>   * @pipe_index: the DRM pipeline index
> + * @cfg: atomic pipe configuration
>   */
> -void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index)
> +void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index,
> +			  const struct vsp1_du_atomic_pipe_config *cfg)
>  {
>  	struct vsp1_device *vsp1 = dev_get_drvdata(dev);
>  	struct vsp1_drm_pipeline *drm_pipe = &vsp1->drm->pipe[pipe_index];
> diff --git a/drivers/media/platform/vsp1/vsp1_drm.h b/drivers/media/platform/vsp1/vsp1_drm.h
> index f4af1b2b12d6..e5b88b28806c 100644
> --- a/drivers/media/platform/vsp1/vsp1_drm.h
> +++ b/drivers/media/platform/vsp1/vsp1_drm.h
> @@ -35,7 +35,7 @@ struct vsp1_drm_pipeline {
>  	wait_queue_head_t wait_queue;
>
>  	/* Frame synchronisation */
> -	void (*du_complete)(void *, bool);
> +	void (*du_complete)(void *data, bool completed, u32 crc);
>  	void *du_private;
>  };
>
> diff --git a/include/media/vsp1.h b/include/media/vsp1.h
> index ff7ef894465d..ac63a9928a79 100644
> --- a/include/media/vsp1.h
> +++ b/include/media/vsp1.h
> @@ -34,7 +34,7 @@ struct vsp1_du_lif_config {
>  	unsigned int width;
>  	unsigned int height;
>
> -	void (*callback)(void *, bool);
> +	void (*callback)(void *data, bool completed, u32 crc);
>  	void *callback_data;
>  };
>
> @@ -61,11 +61,36 @@ struct vsp1_du_atomic_config {
>  	unsigned int zpos;
>  };
>
> +/**
> + * enum vsp1_du_crc_source - Source used for CRC calculation
> + * @VSP1_DU_CRC_NONE: CRC calculation disabled
> + * @VSP_DU_CRC_PLANE: Perform CRC calculation on an input plane
> + * @VSP_DU_CRC_OUTPUT: Perform CRC calculation on the composed output

These two paramters are called VSP1_DU_CRC_* not VSP_DU_CRC_*


> + */
> +enum vsp1_du_crc_source {
> +	VSP1_DU_CRC_NONE,
> +	VSP1_DU_CRC_PLANE,
> +	VSP1_DU_CRC_OUTPUT,
> +};
> +
> +/**
> + * struct vsp1_du_atomic_pipe_config - VSP atomic pipe configuration parameters
> + * @crc.source: source for CRC calculation
> + * @crc.index: index of the CRC source plane (when crc.source is set to plane)
> + */
> +struct vsp1_du_atomic_pipe_config {
> +	struct  {
> +		enum vsp1_du_crc_source source;
> +		unsigned int index;
> +	} crc;
> +};
> +
>  void vsp1_du_atomic_begin(struct device *dev, unsigned int pipe_index);
>  int vsp1_du_atomic_update(struct device *dev, unsigned int pipe_index,
>  			  unsigned int rpf,
>  			  const struct vsp1_du_atomic_config *cfg);
> -void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index);
> +void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index,
> +			  const struct vsp1_du_atomic_pipe_config *cfg);
>  int vsp1_du_map_sg(struct device *dev, struct sg_table *sgt);
>  void vsp1_du_unmap_sg(struct device *dev, struct sg_table *sgt);
>
> --
> Regards,
>
> Laurent Pinchart
>

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

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

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

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

* Re: [PATCH v2 6/8] v4l: vsp1: Add support for the DISCOM entity
  2018-04-22 22:34   ` Laurent Pinchart
@ 2018-04-28 10:40     ` jacopo mondi
  -1 siblings, 0 replies; 82+ messages in thread
From: jacopo mondi @ 2018-04-28 10:40 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: linux-media, dri-devel, linux-renesas-soc, Kieran Bingham

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

HI Laurent,
   a few comments, mostly minor ones...

On Mon, Apr 23, 2018 at 01:34:28AM +0300, Laurent Pinchart wrote:
> The DISCOM calculates a CRC on a configurable window of the frame. It
> interfaces to the VSP through the UIF glue, hence the name used in the
> code.
>
> The module supports configuration of the CRC window through the crop
> rectangle on the ink pad of the corresponding entity. However, unlike

sink pad?

> the traditional V4L2 subdevice model, the crop rectangle does not
> influence the format on the source pad.
>
> Modeling the DISCOM as a sink-only entity would allow adhering to the
> V4L2 subdevice model at the expense of more complex code in the driver,
> as at the hardware level the UIF is handled as a sink+source entity. As
> the DISCOM is only present in R-Car Gen3 VSP-D and VSP-DL instances it
> is not exposed to userspace through V4L2 but controlled through the DU
> driver. We can thus change this model later if needed without fear of
> affecting userspace.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
> Changes since v1:
>
> - Don't return uninitialized value from uif_set_selection()
> ---
>  drivers/media/platform/vsp1/Makefile      |   2 +-
>  drivers/media/platform/vsp1/vsp1.h        |   4 +
>  drivers/media/platform/vsp1/vsp1_drv.c    |  20 +++
>  drivers/media/platform/vsp1/vsp1_entity.c |   6 +
>  drivers/media/platform/vsp1/vsp1_entity.h |   1 +
>  drivers/media/platform/vsp1/vsp1_regs.h   |  41 +++++
>  drivers/media/platform/vsp1/vsp1_uif.c    | 271 ++++++++++++++++++++++++++++++
>  drivers/media/platform/vsp1/vsp1_uif.h    |  32 ++++
>  8 files changed, 376 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/media/platform/vsp1/vsp1_uif.c
>  create mode 100644 drivers/media/platform/vsp1/vsp1_uif.h
>
> diff --git a/drivers/media/platform/vsp1/Makefile b/drivers/media/platform/vsp1/Makefile
> index 596775f932c0..4bb4dcbef7b5 100644
> --- a/drivers/media/platform/vsp1/Makefile
> +++ b/drivers/media/platform/vsp1/Makefile
> @@ -5,6 +5,6 @@ vsp1-y					+= vsp1_rpf.o vsp1_rwpf.o vsp1_wpf.o
>  vsp1-y					+= vsp1_clu.o vsp1_hsit.o vsp1_lut.o
>  vsp1-y					+= vsp1_brx.o vsp1_sru.o vsp1_uds.o
>  vsp1-y					+= vsp1_hgo.o vsp1_hgt.o vsp1_histo.o
> -vsp1-y					+= vsp1_lif.o
> +vsp1-y					+= vsp1_lif.o vsp1_uif.o
>
>  obj-$(CONFIG_VIDEO_RENESAS_VSP1)	+= vsp1.o
> diff --git a/drivers/media/platform/vsp1/vsp1.h b/drivers/media/platform/vsp1/vsp1.h
> index 9cf4e1c4b036..33f632331474 100644
> --- a/drivers/media/platform/vsp1/vsp1.h
> +++ b/drivers/media/platform/vsp1/vsp1.h
> @@ -36,10 +36,12 @@ struct vsp1_lut;
>  struct vsp1_rwpf;
>  struct vsp1_sru;
>  struct vsp1_uds;
> +struct vsp1_uif;
>
>  #define VSP1_MAX_LIF		2
>  #define VSP1_MAX_RPF		5
>  #define VSP1_MAX_UDS		3
> +#define VSP1_MAX_UIF		2
>  #define VSP1_MAX_WPF		4
>
>  #define VSP1_HAS_LUT		(1 << 1)
> @@ -60,6 +62,7 @@ struct vsp1_device_info {
>  	unsigned int lif_count;
>  	unsigned int rpf_count;
>  	unsigned int uds_count;
> +	unsigned int uif_count;
>  	unsigned int wpf_count;
>  	unsigned int num_bru_inputs;
>  	bool uapi;
> @@ -86,6 +89,7 @@ struct vsp1_device {
>  	struct vsp1_rwpf *rpf[VSP1_MAX_RPF];
>  	struct vsp1_sru *sru;
>  	struct vsp1_uds *uds[VSP1_MAX_UDS];
> +	struct vsp1_uif *uif[VSP1_MAX_UIF];
>  	struct vsp1_rwpf *wpf[VSP1_MAX_WPF];
>
>  	struct list_head entities;
> diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
> index 331a2e0af0d3..d29f9c4baebe 100644
> --- a/drivers/media/platform/vsp1/vsp1_drv.c
> +++ b/drivers/media/platform/vsp1/vsp1_drv.c
> @@ -35,6 +35,7 @@
>  #include "vsp1_rwpf.h"
>  #include "vsp1_sru.h"
>  #include "vsp1_uds.h"
> +#include "vsp1_uif.h"
>  #include "vsp1_video.h"
>
>  /* -----------------------------------------------------------------------------
> @@ -409,6 +410,19 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
>  		list_add_tail(&uds->entity.list_dev, &vsp1->entities);
>  	}
>
> +	for (i = 0; i < vsp1->info->uif_count; ++i) {
> +		struct vsp1_uif *uif;
> +
> +		uif = vsp1_uif_create(vsp1, i);
> +		if (IS_ERR(uif)) {
> +			ret = PTR_ERR(uif);
> +			goto done;
> +		}
> +
> +		vsp1->uif[i] = uif;
> +		list_add_tail(&uif->entity.list_dev, &vsp1->entities);
> +	}
> +
>  	for (i = 0; i < vsp1->info->wpf_count; ++i) {
>  		struct vsp1_rwpf *wpf;
>
> @@ -513,6 +527,9 @@ static int vsp1_device_init(struct vsp1_device *vsp1)
>  	for (i = 0; i < vsp1->info->uds_count; ++i)
>  		vsp1_write(vsp1, VI6_DPR_UDS_ROUTE(i), VI6_DPR_NODE_UNUSED);
>
> +	for (i = 0; i < vsp1->info->uif_count; ++i)
> +		vsp1_write(vsp1, VI6_DPR_UIF_ROUTE(i), VI6_DPR_NODE_UNUSED);
> +
>  	vsp1_write(vsp1, VI6_DPR_SRU_ROUTE, VI6_DPR_NODE_UNUSED);
>  	vsp1_write(vsp1, VI6_DPR_LUT_ROUTE, VI6_DPR_NODE_UNUSED);
>  	vsp1_write(vsp1, VI6_DPR_CLU_ROUTE, VI6_DPR_NODE_UNUSED);
> @@ -740,6 +757,7 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
>  		.features = VSP1_HAS_BRU | VSP1_HAS_WPF_VFLIP,
>  		.lif_count = 1,
>  		.rpf_count = 5,
> +		.uif_count = 1,
>  		.wpf_count = 2,
>  		.num_bru_inputs = 5,
>  	}, {
> @@ -749,6 +767,7 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
>  		.features = VSP1_HAS_BRS | VSP1_HAS_BRU,
>  		.lif_count = 1,
>  		.rpf_count = 5,
> +		.uif_count = 1,
>  		.wpf_count = 1,
>  		.num_bru_inputs = 5,
>  	}, {
> @@ -758,6 +777,7 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
>  		.features = VSP1_HAS_BRS | VSP1_HAS_BRU,
>  		.lif_count = 2,
>  		.rpf_count = 5,
> +		.uif_count = 2,
>  		.wpf_count = 2,
>  		.num_bru_inputs = 5,
>  	},
> diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c
> index 181a583aecad..122e60eb1489 100644
> --- a/drivers/media/platform/vsp1/vsp1_entity.c
> +++ b/drivers/media/platform/vsp1/vsp1_entity.c
> @@ -539,6 +539,10 @@ struct media_pad *vsp1_entity_remote_pad(struct media_pad *pad)
>  	{ VSP1_ENTITY_UDS, idx, VI6_DPR_UDS_ROUTE(idx),			\
>  	  { VI6_DPR_NODE_UDS(idx) }, VI6_DPR_NODE_UDS(idx) }
>
> +#define VSP1_ENTITY_ROUTE_UIF(idx)					\
> +	{ VSP1_ENTITY_UIF, idx, VI6_DPR_UIF_ROUTE(idx),			\
> +	  { VI6_DPR_NODE_UIF(idx) }, VI6_DPR_NODE_UIF(idx) }
> +
>  #define VSP1_ENTITY_ROUTE_WPF(idx)					\
>  	{ VSP1_ENTITY_WPF, idx, 0,					\
>  	  { VI6_DPR_NODE_WPF(idx) }, VI6_DPR_NODE_WPF(idx) }
> @@ -567,6 +571,8 @@ static const struct vsp1_route vsp1_routes[] = {
>  	VSP1_ENTITY_ROUTE_UDS(0),
>  	VSP1_ENTITY_ROUTE_UDS(1),
>  	VSP1_ENTITY_ROUTE_UDS(2),
> +	VSP1_ENTITY_ROUTE_UIF(0),	/* Named UIF4 in the documentation */
> +	VSP1_ENTITY_ROUTE_UIF(1),	/* Named UIF5 in the documentation */
>  	VSP1_ENTITY_ROUTE_WPF(0),
>  	VSP1_ENTITY_ROUTE_WPF(1),
>  	VSP1_ENTITY_ROUTE_WPF(2),
> diff --git a/drivers/media/platform/vsp1/vsp1_entity.h b/drivers/media/platform/vsp1/vsp1_entity.h
> index 0839a62cfa71..94490d697dcf 100644
> --- a/drivers/media/platform/vsp1/vsp1_entity.h
> +++ b/drivers/media/platform/vsp1/vsp1_entity.h
> @@ -33,6 +33,7 @@ enum vsp1_entity_type {
>  	VSP1_ENTITY_RPF,
>  	VSP1_ENTITY_SRU,
>  	VSP1_ENTITY_UDS,
> +	VSP1_ENTITY_UIF,
>  	VSP1_ENTITY_WPF,
>  };
>
> diff --git a/drivers/media/platform/vsp1/vsp1_regs.h b/drivers/media/platform/vsp1/vsp1_regs.h
> index 3201ad4b77d4..0d249ff9f564 100644
> --- a/drivers/media/platform/vsp1/vsp1_regs.h
> +++ b/drivers/media/platform/vsp1/vsp1_regs.h
> @@ -307,6 +307,44 @@
>  #define VI6_WPF_WRBCK_CTRL		0x1034
>  #define VI6_WPF_WRBCK_CTRL_WBMD		(1 << 0)
>
> +/* -----------------------------------------------------------------------------
> + * UIF Control Registers
> + */
> +
> +#define VI6_UIF_OFFSET			0x100
> +
> +#define VI6_UIF_DISCOM_DOCMCR		0x1c00
> +#define VI6_UIF_DISCOM_DOCMCR_CMPRU	(1 << 16)
> +#define VI6_UIF_DISCOM_DOCMCR_CMPR	(1 << 0)
> +
> +#define VI6_UIF_DISCOM_DOCMSTR		0x1c04
> +#define VI6_UIF_DISCOM_DOCMSTR_CMPPRE	(1 << 1)
> +#define VI6_UIF_DISCOM_DOCMSTR_CMPST	(1 << 0)
> +
> +#define VI6_UIF_DISCOM_DOCMCLSTR	0x1c08
> +#define VI6_UIF_DISCOM_DOCMCLSTR_CMPCLPRE	(1 << 1)
> +#define VI6_UIF_DISCOM_DOCMCLSTR_CMPCLST	(1 << 0)
> +
> +#define VI6_UIF_DISCOM_DOCMIENR		0x1c0c
> +#define VI6_UIF_DISCOM_DOCMIENR_CMPPREIEN	(1 << 1)
> +#define VI6_UIF_DISCOM_DOCMIENR_CMPIEN		(1 << 0)
> +
> +#define VI6_UIF_DISCOM_DOCMMDR		0x1c10
> +#define VI6_UIF_DISCOM_DOCMMDR_INTHRH(n)	((n) << 16)
> +
> +#define VI6_UIF_DISCOM_DOCMPMR		0x1c14
> +#define VI6_UIF_DISCOM_DOCMPMR_CMPDFF(n)	((n) << 17)
> +#define VI6_UIF_DISCOM_DOCMPMR_CMPDFA(n)	((n) << 8)
> +#define VI6_UIF_DISCOM_DOCMPMR_CMPDAUF		(1 << 7)
> +#define VI6_UIF_DISCOM_DOCMPMR_SEL(n)		((n) << 0)
> +
> +#define VI6_UIF_DISCOM_DOCMECRCR	0x1c18
> +#define VI6_UIF_DISCOM_DOCMCCRCR	0x1c1c
> +#define VI6_UIF_DISCOM_DOCMSPXR		0x1c20
> +#define VI6_UIF_DISCOM_DOCMSPYR		0x1c24
> +#define VI6_UIF_DISCOM_DOCMSZXR		0x1c28
> +#define VI6_UIF_DISCOM_DOCMSZYR		0x1c2c
> +
>  /* -----------------------------------------------------------------------------
>   * DPR Control Registers
>   */
> @@ -339,7 +377,10 @@
>  #define VI6_DPR_SMPPT_PT_MASK		(0x3f << 0)
>  #define VI6_DPR_SMPPT_PT_SHIFT		0
>
> +#define VI6_DPR_UIF_ROUTE(n)		(0x2074 + (n) * 4)
> +
>  #define VI6_DPR_NODE_RPF(n)		(n)
> +#define VI6_DPR_NODE_UIF(n)		(12 + (n))
>  #define VI6_DPR_NODE_SRU		16
>  #define VI6_DPR_NODE_UDS(n)		(17 + (n))
>  #define VI6_DPR_NODE_LUT		22
> diff --git a/drivers/media/platform/vsp1/vsp1_uif.c b/drivers/media/platform/vsp1/vsp1_uif.c
> new file mode 100644
> index 000000000000..6de7e9c801ae
> --- /dev/null
> +++ b/drivers/media/platform/vsp1/vsp1_uif.c
> @@ -0,0 +1,271 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * vsp1_uif.c  --  R-Car VSP1 User Logic Interface
> + *
> + * Copyright (C) 2017-2018 Laurent Pinchart
> + *
> + * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> + */
> +
> +#include <linux/device.h>
> +#include <linux/gfp.h>
> +#include <linux/sys_soc.h>
> +
> +#include <media/media-entity.h>
> +#include <media/v4l2-subdev.h>
> +
> +#include "vsp1.h"
> +#include "vsp1_dl.h"
> +#include "vsp1_entity.h"
> +#include "vsp1_uif.h"
> +
> +#define UIF_MIN_SIZE				4U
> +#define UIF_MAX_SIZE				8190U
> +
> +/* -----------------------------------------------------------------------------
> + * Device Access
> + */
> +
> +static inline u32 vsp1_uif_read(struct vsp1_uif *uif, u32 reg)
> +{
> +	return vsp1_read(uif->entity.vsp1,
> +			 uif->entity.index * VI6_UIF_OFFSET + reg);
> +}
> +static inline void vsp1_uif_write(struct vsp1_uif *uif, struct vsp1_dl_list *dl,
> +				  u32 reg, u32 data)
> +{
> +	vsp1_dl_list_write(dl, reg + uif->entity.index * VI6_UIF_OFFSET, data);
> +}
> +
> +u32 vsp1_uif_get_crc(struct vsp1_uif *uif)
> +{
> +	return vsp1_uif_read(uif, VI6_UIF_DISCOM_DOCMCCRCR);
> +}
> +
> +/* -----------------------------------------------------------------------------
> + * V4L2 Subdevice Pad Operations
> + */
> +
> +static const unsigned int uif_codes[] = {
> +	MEDIA_BUS_FMT_ARGB8888_1X32,
> +	MEDIA_BUS_FMT_AHSV8888_1X32,
> +	MEDIA_BUS_FMT_AYUV8_1X32,
> +};
> +
> +static int uif_enum_mbus_code(struct v4l2_subdev *subdev,
> +			      struct v4l2_subdev_pad_config *cfg,
> +			      struct v4l2_subdev_mbus_code_enum *code)
> +{
> +	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, uif_codes,
> +					  ARRAY_SIZE(uif_codes));
> +}
> +
> +static int uif_enum_frame_size(struct v4l2_subdev *subdev,
> +			       struct v4l2_subdev_pad_config *cfg,
> +			       struct v4l2_subdev_frame_size_enum *fse)
> +{
> +	return vsp1_subdev_enum_frame_size(subdev, cfg, fse, UIF_MIN_SIZE,
> +					   UIF_MIN_SIZE, UIF_MAX_SIZE,
> +					   UIF_MAX_SIZE);
> +}
> +
> +static int uif_set_format(struct v4l2_subdev *subdev,
> +			    struct v4l2_subdev_pad_config *cfg,
> +			    struct v4l2_subdev_format *fmt)
> +{
> +	return vsp1_subdev_set_pad_format(subdev, cfg, fmt, uif_codes,
> +					  ARRAY_SIZE(uif_codes),
> +					  UIF_MIN_SIZE, UIF_MIN_SIZE,
> +					  UIF_MAX_SIZE, UIF_MAX_SIZE);
> +}
> +
> +static int uif_get_selection(struct v4l2_subdev *subdev,
> +			     struct v4l2_subdev_pad_config *cfg,
> +			     struct v4l2_subdev_selection *sel)
> +{
> +	struct vsp1_uif *uif = to_uif(subdev);
> +	struct v4l2_subdev_pad_config *config;
> +	struct v4l2_mbus_framefmt *format;
> +	int ret = 0;
> +
> +	if (sel->pad != UIF_PAD_SINK)
> +		return -EINVAL;
> +
> +	mutex_lock(&uif->entity.lock);
> +
> +	config = vsp1_entity_get_pad_config(&uif->entity, cfg, sel->which);
> +	if (!config) {
> +		ret = -EINVAL;
> +		goto done;
> +	}
> +
> +	switch (sel->target) {
> +	case V4L2_SEL_TGT_CROP_BOUNDS:
> +	case V4L2_SEL_TGT_CROP_DEFAULT:
> +		format = vsp1_entity_get_pad_format(&uif->entity, config,
> +						    UIF_PAD_SINK);
> +		sel->r.left = 0;
> +		sel->r.top = 0;
> +		sel->r.width = format->width;
> +		sel->r.height = format->height;
> +		break;
> +
> +	case V4L2_SEL_TGT_CROP:
> +		sel->r = *vsp1_entity_get_pad_selection(&uif->entity, config,
> +							sel->pad, sel->target);
> +		break;
> +
> +	default:
> +		ret = -EINVAL;
> +		break;
> +	}
> +
> +done:
> +	mutex_unlock(&uif->entity.lock);
> +	return ret;
> +}
> +
> +static int uif_set_selection(struct v4l2_subdev *subdev,
> +			     struct v4l2_subdev_pad_config *cfg,
> +			     struct v4l2_subdev_selection *sel)
> +{
> +	struct vsp1_uif *uif = to_uif(subdev);
> +	struct v4l2_subdev_pad_config *config;
> +	struct v4l2_mbus_framefmt *format;
> +	struct v4l2_rect *selection;
> +	int ret = 0;
> +
> +	if (sel->pad != UIF_PAD_SINK ||
> +	    sel->target != V4L2_SEL_TGT_CROP)
> +		return -EINVAL;
> +
> +	mutex_lock(&uif->entity.lock);
> +
> +	config = vsp1_entity_get_pad_config(&uif->entity, cfg, sel->which);
> +	if (!config) {
> +		ret = -EINVAL;
> +		goto done;
> +	}
> +
> +	/* The crop rectangle must be inside the input frame. */
> +	format = vsp1_entity_get_pad_format(&uif->entity, config, UIF_PAD_SINK);
> +
> +	sel->r.left = clamp_t(unsigned int, sel->r.left, 0, format->width - 1);
> +	sel->r.top = clamp_t(unsigned int, sel->r.top, 0, format->height - 1);
> +	sel->r.width = clamp_t(unsigned int, sel->r.width, UIF_MIN_SIZE,
> +			       format->width - sel->r.left);
> +	sel->r.height = clamp_t(unsigned int, sel->r.height, UIF_MIN_SIZE,
> +				format->height - sel->r.top);
> +
> +	/* Store the crop rectangle. */
> +	selection = vsp1_entity_get_pad_selection(&uif->entity, config,
> +						  sel->pad, V4L2_SEL_TGT_CROP);
> +	*selection = sel->r;
> +
> +done:
> +	mutex_unlock(&uif->entity.lock);
> +	return ret;
> +}
> +
> +/* -----------------------------------------------------------------------------
> + * V4L2 Subdevice Operations
> + */
> +
> +static const struct v4l2_subdev_pad_ops uif_pad_ops = {
> +	.init_cfg = vsp1_entity_init_cfg,
> +	.enum_mbus_code = uif_enum_mbus_code,
> +	.enum_frame_size = uif_enum_frame_size,
> +	.get_fmt = vsp1_subdev_get_pad_format,
> +	.set_fmt = uif_set_format,
> +	.get_selection = uif_get_selection,
> +	.set_selection = uif_set_selection,
> +};
> +
> +static const struct v4l2_subdev_ops uif_ops = {
> +	.pad    = &uif_pad_ops,
> +};
> +
> +/* -----------------------------------------------------------------------------
> + * VSP1 Entity Operations
> + */
> +
> +static void uif_configure(struct vsp1_entity *entity,
> +			  struct vsp1_pipeline *pipe,
> +			  struct vsp1_dl_list *dl,
> +			  enum vsp1_entity_params params)
> +{
> +	struct vsp1_uif *uif = to_uif(&entity->subdev);
> +	const struct v4l2_rect *crop;
> +	unsigned int left;
> +	unsigned int width;
> +
> +	/*
> +	 * Per-partition configuration isn't needed as the DISCOM is used in
> +	 * display pipelines only.
> +	 */
> +	if (params != VSP1_ENTITY_PARAMS_INIT)
> +		return;
> +
> +	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMPMR,
> +		       VI6_UIF_DISCOM_DOCMPMR_SEL(9));
> +
> +	crop = vsp1_entity_get_pad_selection(entity, entity->config,
> +					     UIF_PAD_SINK, V4L2_SEL_TGT_CROP);
> +
> +	/* On M3-W the horizontal coordinates are twice the register value. */
> +	if (uif->m3w_quirk) {
> +		left = crop->left / 2;
> +		width = crop->width / 2;
> +	} else {
> +		left = crop->left;
> +		width = crop->width;
> +	}

I would write this as

        left = crop->left;
        width = crop->width;

	/* On M3-W the horizontal coordinates are twice the register value. */
	if (uif->m3w_quirk) {
		left /= 2;
		width /= 2;
        }

But that's really up to you.

> +
> +	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMSPXR, left);
> +	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMSPYR, crop->top);
> +	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMSZXR, width);
> +	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMSZYR, crop->height);
> +
> +	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMCR,
> +		       VI6_UIF_DISCOM_DOCMCR_CMPR);
> +}
> +
> +static const struct vsp1_entity_operations uif_entity_ops = {
> +	.configure = uif_configure,
> +};
> +
> +/* -----------------------------------------------------------------------------
> + * Initialization and Cleanup
> + */
> +
> +static const struct soc_device_attribute vsp1_r8a7796[] = {
> +	{ .soc_id = "r8a7796" },
> +	{ /* sentinel */ }
> +};
> +
> +struct vsp1_uif *vsp1_uif_create(struct vsp1_device *vsp1, unsigned int index)
> +{
> +	struct vsp1_uif *uif;
> +	char name[6];
> +	int ret;
> +
> +	uif = devm_kzalloc(vsp1->dev, sizeof(*uif), GFP_KERNEL);
> +	if (uif == NULL)

        if (!uif)

Otherwise checkpatch complains iirc.

Those are very minor comments, so feel free to add my reviewed by tag

Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>

Thanks
  j

> +		return ERR_PTR(-ENOMEM);
> +
> +	if (soc_device_match(vsp1_r8a7796))
> +		uif->m3w_quirk = true;
> +
> +	uif->entity.ops = &uif_entity_ops;
> +	uif->entity.type = VSP1_ENTITY_UIF;
> +	uif->entity.index = index;
> +
> +	/* The datasheet names the two UIF instances UIF4 and UIF5. */
> +	sprintf(name, "uif.%u", index + 4);
> +	ret = vsp1_entity_init(vsp1, &uif->entity, name, 2, &uif_ops,
> +			       MEDIA_ENT_F_PROC_VIDEO_STATISTICS);
> +	if (ret < 0)
> +		return ERR_PTR(ret);
> +
> +	return uif;
> +}
> diff --git a/drivers/media/platform/vsp1/vsp1_uif.h b/drivers/media/platform/vsp1/vsp1_uif.h
> new file mode 100644
> index 000000000000..c71ab5f6a6f8
> --- /dev/null
> +++ b/drivers/media/platform/vsp1/vsp1_uif.h
> @@ -0,0 +1,32 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * vsp1_uif.h  --  R-Car VSP1 User Logic Interface
> + *
> + * Copyright (C) 2017-2018 Laurent Pinchart
> + *
> + * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> + */
> +#ifndef __VSP1_UIF_H__
> +#define __VSP1_UIF_H__
> +
> +#include "vsp1_entity.h"
> +
> +struct vsp1_device;
> +
> +#define UIF_PAD_SINK				0
> +#define UIF_PAD_SOURCE				1
> +
> +struct vsp1_uif {
> +	struct vsp1_entity entity;
> +	bool m3w_quirk;
> +};
> +
> +static inline struct vsp1_uif *to_uif(struct v4l2_subdev *subdev)
> +{
> +	return container_of(subdev, struct vsp1_uif, entity.subdev);
> +}
> +
> +struct vsp1_uif *vsp1_uif_create(struct vsp1_device *vsp1, unsigned int index);
> +u32 vsp1_uif_get_crc(struct vsp1_uif *uif);
> +
> +#endif /* __VSP1_UIF_H__ */
> --
> Regards,
>
> Laurent Pinchart
>

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

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

* Re: [PATCH v2 6/8] v4l: vsp1: Add support for the DISCOM entity
@ 2018-04-28 10:40     ` jacopo mondi
  0 siblings, 0 replies; 82+ messages in thread
From: jacopo mondi @ 2018-04-28 10:40 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: linux-renesas-soc, Kieran Bingham, dri-devel, linux-media


[-- Attachment #1.1: Type: text/plain, Size: 19052 bytes --]

HI Laurent,
   a few comments, mostly minor ones...

On Mon, Apr 23, 2018 at 01:34:28AM +0300, Laurent Pinchart wrote:
> The DISCOM calculates a CRC on a configurable window of the frame. It
> interfaces to the VSP through the UIF glue, hence the name used in the
> code.
>
> The module supports configuration of the CRC window through the crop
> rectangle on the ink pad of the corresponding entity. However, unlike

sink pad?

> the traditional V4L2 subdevice model, the crop rectangle does not
> influence the format on the source pad.
>
> Modeling the DISCOM as a sink-only entity would allow adhering to the
> V4L2 subdevice model at the expense of more complex code in the driver,
> as at the hardware level the UIF is handled as a sink+source entity. As
> the DISCOM is only present in R-Car Gen3 VSP-D and VSP-DL instances it
> is not exposed to userspace through V4L2 but controlled through the DU
> driver. We can thus change this model later if needed without fear of
> affecting userspace.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
> Changes since v1:
>
> - Don't return uninitialized value from uif_set_selection()
> ---
>  drivers/media/platform/vsp1/Makefile      |   2 +-
>  drivers/media/platform/vsp1/vsp1.h        |   4 +
>  drivers/media/platform/vsp1/vsp1_drv.c    |  20 +++
>  drivers/media/platform/vsp1/vsp1_entity.c |   6 +
>  drivers/media/platform/vsp1/vsp1_entity.h |   1 +
>  drivers/media/platform/vsp1/vsp1_regs.h   |  41 +++++
>  drivers/media/platform/vsp1/vsp1_uif.c    | 271 ++++++++++++++++++++++++++++++
>  drivers/media/platform/vsp1/vsp1_uif.h    |  32 ++++
>  8 files changed, 376 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/media/platform/vsp1/vsp1_uif.c
>  create mode 100644 drivers/media/platform/vsp1/vsp1_uif.h
>
> diff --git a/drivers/media/platform/vsp1/Makefile b/drivers/media/platform/vsp1/Makefile
> index 596775f932c0..4bb4dcbef7b5 100644
> --- a/drivers/media/platform/vsp1/Makefile
> +++ b/drivers/media/platform/vsp1/Makefile
> @@ -5,6 +5,6 @@ vsp1-y					+= vsp1_rpf.o vsp1_rwpf.o vsp1_wpf.o
>  vsp1-y					+= vsp1_clu.o vsp1_hsit.o vsp1_lut.o
>  vsp1-y					+= vsp1_brx.o vsp1_sru.o vsp1_uds.o
>  vsp1-y					+= vsp1_hgo.o vsp1_hgt.o vsp1_histo.o
> -vsp1-y					+= vsp1_lif.o
> +vsp1-y					+= vsp1_lif.o vsp1_uif.o
>
>  obj-$(CONFIG_VIDEO_RENESAS_VSP1)	+= vsp1.o
> diff --git a/drivers/media/platform/vsp1/vsp1.h b/drivers/media/platform/vsp1/vsp1.h
> index 9cf4e1c4b036..33f632331474 100644
> --- a/drivers/media/platform/vsp1/vsp1.h
> +++ b/drivers/media/platform/vsp1/vsp1.h
> @@ -36,10 +36,12 @@ struct vsp1_lut;
>  struct vsp1_rwpf;
>  struct vsp1_sru;
>  struct vsp1_uds;
> +struct vsp1_uif;
>
>  #define VSP1_MAX_LIF		2
>  #define VSP1_MAX_RPF		5
>  #define VSP1_MAX_UDS		3
> +#define VSP1_MAX_UIF		2
>  #define VSP1_MAX_WPF		4
>
>  #define VSP1_HAS_LUT		(1 << 1)
> @@ -60,6 +62,7 @@ struct vsp1_device_info {
>  	unsigned int lif_count;
>  	unsigned int rpf_count;
>  	unsigned int uds_count;
> +	unsigned int uif_count;
>  	unsigned int wpf_count;
>  	unsigned int num_bru_inputs;
>  	bool uapi;
> @@ -86,6 +89,7 @@ struct vsp1_device {
>  	struct vsp1_rwpf *rpf[VSP1_MAX_RPF];
>  	struct vsp1_sru *sru;
>  	struct vsp1_uds *uds[VSP1_MAX_UDS];
> +	struct vsp1_uif *uif[VSP1_MAX_UIF];
>  	struct vsp1_rwpf *wpf[VSP1_MAX_WPF];
>
>  	struct list_head entities;
> diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
> index 331a2e0af0d3..d29f9c4baebe 100644
> --- a/drivers/media/platform/vsp1/vsp1_drv.c
> +++ b/drivers/media/platform/vsp1/vsp1_drv.c
> @@ -35,6 +35,7 @@
>  #include "vsp1_rwpf.h"
>  #include "vsp1_sru.h"
>  #include "vsp1_uds.h"
> +#include "vsp1_uif.h"
>  #include "vsp1_video.h"
>
>  /* -----------------------------------------------------------------------------
> @@ -409,6 +410,19 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
>  		list_add_tail(&uds->entity.list_dev, &vsp1->entities);
>  	}
>
> +	for (i = 0; i < vsp1->info->uif_count; ++i) {
> +		struct vsp1_uif *uif;
> +
> +		uif = vsp1_uif_create(vsp1, i);
> +		if (IS_ERR(uif)) {
> +			ret = PTR_ERR(uif);
> +			goto done;
> +		}
> +
> +		vsp1->uif[i] = uif;
> +		list_add_tail(&uif->entity.list_dev, &vsp1->entities);
> +	}
> +
>  	for (i = 0; i < vsp1->info->wpf_count; ++i) {
>  		struct vsp1_rwpf *wpf;
>
> @@ -513,6 +527,9 @@ static int vsp1_device_init(struct vsp1_device *vsp1)
>  	for (i = 0; i < vsp1->info->uds_count; ++i)
>  		vsp1_write(vsp1, VI6_DPR_UDS_ROUTE(i), VI6_DPR_NODE_UNUSED);
>
> +	for (i = 0; i < vsp1->info->uif_count; ++i)
> +		vsp1_write(vsp1, VI6_DPR_UIF_ROUTE(i), VI6_DPR_NODE_UNUSED);
> +
>  	vsp1_write(vsp1, VI6_DPR_SRU_ROUTE, VI6_DPR_NODE_UNUSED);
>  	vsp1_write(vsp1, VI6_DPR_LUT_ROUTE, VI6_DPR_NODE_UNUSED);
>  	vsp1_write(vsp1, VI6_DPR_CLU_ROUTE, VI6_DPR_NODE_UNUSED);
> @@ -740,6 +757,7 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
>  		.features = VSP1_HAS_BRU | VSP1_HAS_WPF_VFLIP,
>  		.lif_count = 1,
>  		.rpf_count = 5,
> +		.uif_count = 1,
>  		.wpf_count = 2,
>  		.num_bru_inputs = 5,
>  	}, {
> @@ -749,6 +767,7 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
>  		.features = VSP1_HAS_BRS | VSP1_HAS_BRU,
>  		.lif_count = 1,
>  		.rpf_count = 5,
> +		.uif_count = 1,
>  		.wpf_count = 1,
>  		.num_bru_inputs = 5,
>  	}, {
> @@ -758,6 +777,7 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
>  		.features = VSP1_HAS_BRS | VSP1_HAS_BRU,
>  		.lif_count = 2,
>  		.rpf_count = 5,
> +		.uif_count = 2,
>  		.wpf_count = 2,
>  		.num_bru_inputs = 5,
>  	},
> diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c
> index 181a583aecad..122e60eb1489 100644
> --- a/drivers/media/platform/vsp1/vsp1_entity.c
> +++ b/drivers/media/platform/vsp1/vsp1_entity.c
> @@ -539,6 +539,10 @@ struct media_pad *vsp1_entity_remote_pad(struct media_pad *pad)
>  	{ VSP1_ENTITY_UDS, idx, VI6_DPR_UDS_ROUTE(idx),			\
>  	  { VI6_DPR_NODE_UDS(idx) }, VI6_DPR_NODE_UDS(idx) }
>
> +#define VSP1_ENTITY_ROUTE_UIF(idx)					\
> +	{ VSP1_ENTITY_UIF, idx, VI6_DPR_UIF_ROUTE(idx),			\
> +	  { VI6_DPR_NODE_UIF(idx) }, VI6_DPR_NODE_UIF(idx) }
> +
>  #define VSP1_ENTITY_ROUTE_WPF(idx)					\
>  	{ VSP1_ENTITY_WPF, idx, 0,					\
>  	  { VI6_DPR_NODE_WPF(idx) }, VI6_DPR_NODE_WPF(idx) }
> @@ -567,6 +571,8 @@ static const struct vsp1_route vsp1_routes[] = {
>  	VSP1_ENTITY_ROUTE_UDS(0),
>  	VSP1_ENTITY_ROUTE_UDS(1),
>  	VSP1_ENTITY_ROUTE_UDS(2),
> +	VSP1_ENTITY_ROUTE_UIF(0),	/* Named UIF4 in the documentation */
> +	VSP1_ENTITY_ROUTE_UIF(1),	/* Named UIF5 in the documentation */
>  	VSP1_ENTITY_ROUTE_WPF(0),
>  	VSP1_ENTITY_ROUTE_WPF(1),
>  	VSP1_ENTITY_ROUTE_WPF(2),
> diff --git a/drivers/media/platform/vsp1/vsp1_entity.h b/drivers/media/platform/vsp1/vsp1_entity.h
> index 0839a62cfa71..94490d697dcf 100644
> --- a/drivers/media/platform/vsp1/vsp1_entity.h
> +++ b/drivers/media/platform/vsp1/vsp1_entity.h
> @@ -33,6 +33,7 @@ enum vsp1_entity_type {
>  	VSP1_ENTITY_RPF,
>  	VSP1_ENTITY_SRU,
>  	VSP1_ENTITY_UDS,
> +	VSP1_ENTITY_UIF,
>  	VSP1_ENTITY_WPF,
>  };
>
> diff --git a/drivers/media/platform/vsp1/vsp1_regs.h b/drivers/media/platform/vsp1/vsp1_regs.h
> index 3201ad4b77d4..0d249ff9f564 100644
> --- a/drivers/media/platform/vsp1/vsp1_regs.h
> +++ b/drivers/media/platform/vsp1/vsp1_regs.h
> @@ -307,6 +307,44 @@
>  #define VI6_WPF_WRBCK_CTRL		0x1034
>  #define VI6_WPF_WRBCK_CTRL_WBMD		(1 << 0)
>
> +/* -----------------------------------------------------------------------------
> + * UIF Control Registers
> + */
> +
> +#define VI6_UIF_OFFSET			0x100
> +
> +#define VI6_UIF_DISCOM_DOCMCR		0x1c00
> +#define VI6_UIF_DISCOM_DOCMCR_CMPRU	(1 << 16)
> +#define VI6_UIF_DISCOM_DOCMCR_CMPR	(1 << 0)
> +
> +#define VI6_UIF_DISCOM_DOCMSTR		0x1c04
> +#define VI6_UIF_DISCOM_DOCMSTR_CMPPRE	(1 << 1)
> +#define VI6_UIF_DISCOM_DOCMSTR_CMPST	(1 << 0)
> +
> +#define VI6_UIF_DISCOM_DOCMCLSTR	0x1c08
> +#define VI6_UIF_DISCOM_DOCMCLSTR_CMPCLPRE	(1 << 1)
> +#define VI6_UIF_DISCOM_DOCMCLSTR_CMPCLST	(1 << 0)
> +
> +#define VI6_UIF_DISCOM_DOCMIENR		0x1c0c
> +#define VI6_UIF_DISCOM_DOCMIENR_CMPPREIEN	(1 << 1)
> +#define VI6_UIF_DISCOM_DOCMIENR_CMPIEN		(1 << 0)
> +
> +#define VI6_UIF_DISCOM_DOCMMDR		0x1c10
> +#define VI6_UIF_DISCOM_DOCMMDR_INTHRH(n)	((n) << 16)
> +
> +#define VI6_UIF_DISCOM_DOCMPMR		0x1c14
> +#define VI6_UIF_DISCOM_DOCMPMR_CMPDFF(n)	((n) << 17)
> +#define VI6_UIF_DISCOM_DOCMPMR_CMPDFA(n)	((n) << 8)
> +#define VI6_UIF_DISCOM_DOCMPMR_CMPDAUF		(1 << 7)
> +#define VI6_UIF_DISCOM_DOCMPMR_SEL(n)		((n) << 0)
> +
> +#define VI6_UIF_DISCOM_DOCMECRCR	0x1c18
> +#define VI6_UIF_DISCOM_DOCMCCRCR	0x1c1c
> +#define VI6_UIF_DISCOM_DOCMSPXR		0x1c20
> +#define VI6_UIF_DISCOM_DOCMSPYR		0x1c24
> +#define VI6_UIF_DISCOM_DOCMSZXR		0x1c28
> +#define VI6_UIF_DISCOM_DOCMSZYR		0x1c2c
> +
>  /* -----------------------------------------------------------------------------
>   * DPR Control Registers
>   */
> @@ -339,7 +377,10 @@
>  #define VI6_DPR_SMPPT_PT_MASK		(0x3f << 0)
>  #define VI6_DPR_SMPPT_PT_SHIFT		0
>
> +#define VI6_DPR_UIF_ROUTE(n)		(0x2074 + (n) * 4)
> +
>  #define VI6_DPR_NODE_RPF(n)		(n)
> +#define VI6_DPR_NODE_UIF(n)		(12 + (n))
>  #define VI6_DPR_NODE_SRU		16
>  #define VI6_DPR_NODE_UDS(n)		(17 + (n))
>  #define VI6_DPR_NODE_LUT		22
> diff --git a/drivers/media/platform/vsp1/vsp1_uif.c b/drivers/media/platform/vsp1/vsp1_uif.c
> new file mode 100644
> index 000000000000..6de7e9c801ae
> --- /dev/null
> +++ b/drivers/media/platform/vsp1/vsp1_uif.c
> @@ -0,0 +1,271 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * vsp1_uif.c  --  R-Car VSP1 User Logic Interface
> + *
> + * Copyright (C) 2017-2018 Laurent Pinchart
> + *
> + * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> + */
> +
> +#include <linux/device.h>
> +#include <linux/gfp.h>
> +#include <linux/sys_soc.h>
> +
> +#include <media/media-entity.h>
> +#include <media/v4l2-subdev.h>
> +
> +#include "vsp1.h"
> +#include "vsp1_dl.h"
> +#include "vsp1_entity.h"
> +#include "vsp1_uif.h"
> +
> +#define UIF_MIN_SIZE				4U
> +#define UIF_MAX_SIZE				8190U
> +
> +/* -----------------------------------------------------------------------------
> + * Device Access
> + */
> +
> +static inline u32 vsp1_uif_read(struct vsp1_uif *uif, u32 reg)
> +{
> +	return vsp1_read(uif->entity.vsp1,
> +			 uif->entity.index * VI6_UIF_OFFSET + reg);
> +}
> +static inline void vsp1_uif_write(struct vsp1_uif *uif, struct vsp1_dl_list *dl,
> +				  u32 reg, u32 data)
> +{
> +	vsp1_dl_list_write(dl, reg + uif->entity.index * VI6_UIF_OFFSET, data);
> +}
> +
> +u32 vsp1_uif_get_crc(struct vsp1_uif *uif)
> +{
> +	return vsp1_uif_read(uif, VI6_UIF_DISCOM_DOCMCCRCR);
> +}
> +
> +/* -----------------------------------------------------------------------------
> + * V4L2 Subdevice Pad Operations
> + */
> +
> +static const unsigned int uif_codes[] = {
> +	MEDIA_BUS_FMT_ARGB8888_1X32,
> +	MEDIA_BUS_FMT_AHSV8888_1X32,
> +	MEDIA_BUS_FMT_AYUV8_1X32,
> +};
> +
> +static int uif_enum_mbus_code(struct v4l2_subdev *subdev,
> +			      struct v4l2_subdev_pad_config *cfg,
> +			      struct v4l2_subdev_mbus_code_enum *code)
> +{
> +	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, uif_codes,
> +					  ARRAY_SIZE(uif_codes));
> +}
> +
> +static int uif_enum_frame_size(struct v4l2_subdev *subdev,
> +			       struct v4l2_subdev_pad_config *cfg,
> +			       struct v4l2_subdev_frame_size_enum *fse)
> +{
> +	return vsp1_subdev_enum_frame_size(subdev, cfg, fse, UIF_MIN_SIZE,
> +					   UIF_MIN_SIZE, UIF_MAX_SIZE,
> +					   UIF_MAX_SIZE);
> +}
> +
> +static int uif_set_format(struct v4l2_subdev *subdev,
> +			    struct v4l2_subdev_pad_config *cfg,
> +			    struct v4l2_subdev_format *fmt)
> +{
> +	return vsp1_subdev_set_pad_format(subdev, cfg, fmt, uif_codes,
> +					  ARRAY_SIZE(uif_codes),
> +					  UIF_MIN_SIZE, UIF_MIN_SIZE,
> +					  UIF_MAX_SIZE, UIF_MAX_SIZE);
> +}
> +
> +static int uif_get_selection(struct v4l2_subdev *subdev,
> +			     struct v4l2_subdev_pad_config *cfg,
> +			     struct v4l2_subdev_selection *sel)
> +{
> +	struct vsp1_uif *uif = to_uif(subdev);
> +	struct v4l2_subdev_pad_config *config;
> +	struct v4l2_mbus_framefmt *format;
> +	int ret = 0;
> +
> +	if (sel->pad != UIF_PAD_SINK)
> +		return -EINVAL;
> +
> +	mutex_lock(&uif->entity.lock);
> +
> +	config = vsp1_entity_get_pad_config(&uif->entity, cfg, sel->which);
> +	if (!config) {
> +		ret = -EINVAL;
> +		goto done;
> +	}
> +
> +	switch (sel->target) {
> +	case V4L2_SEL_TGT_CROP_BOUNDS:
> +	case V4L2_SEL_TGT_CROP_DEFAULT:
> +		format = vsp1_entity_get_pad_format(&uif->entity, config,
> +						    UIF_PAD_SINK);
> +		sel->r.left = 0;
> +		sel->r.top = 0;
> +		sel->r.width = format->width;
> +		sel->r.height = format->height;
> +		break;
> +
> +	case V4L2_SEL_TGT_CROP:
> +		sel->r = *vsp1_entity_get_pad_selection(&uif->entity, config,
> +							sel->pad, sel->target);
> +		break;
> +
> +	default:
> +		ret = -EINVAL;
> +		break;
> +	}
> +
> +done:
> +	mutex_unlock(&uif->entity.lock);
> +	return ret;
> +}
> +
> +static int uif_set_selection(struct v4l2_subdev *subdev,
> +			     struct v4l2_subdev_pad_config *cfg,
> +			     struct v4l2_subdev_selection *sel)
> +{
> +	struct vsp1_uif *uif = to_uif(subdev);
> +	struct v4l2_subdev_pad_config *config;
> +	struct v4l2_mbus_framefmt *format;
> +	struct v4l2_rect *selection;
> +	int ret = 0;
> +
> +	if (sel->pad != UIF_PAD_SINK ||
> +	    sel->target != V4L2_SEL_TGT_CROP)
> +		return -EINVAL;
> +
> +	mutex_lock(&uif->entity.lock);
> +
> +	config = vsp1_entity_get_pad_config(&uif->entity, cfg, sel->which);
> +	if (!config) {
> +		ret = -EINVAL;
> +		goto done;
> +	}
> +
> +	/* The crop rectangle must be inside the input frame. */
> +	format = vsp1_entity_get_pad_format(&uif->entity, config, UIF_PAD_SINK);
> +
> +	sel->r.left = clamp_t(unsigned int, sel->r.left, 0, format->width - 1);
> +	sel->r.top = clamp_t(unsigned int, sel->r.top, 0, format->height - 1);
> +	sel->r.width = clamp_t(unsigned int, sel->r.width, UIF_MIN_SIZE,
> +			       format->width - sel->r.left);
> +	sel->r.height = clamp_t(unsigned int, sel->r.height, UIF_MIN_SIZE,
> +				format->height - sel->r.top);
> +
> +	/* Store the crop rectangle. */
> +	selection = vsp1_entity_get_pad_selection(&uif->entity, config,
> +						  sel->pad, V4L2_SEL_TGT_CROP);
> +	*selection = sel->r;
> +
> +done:
> +	mutex_unlock(&uif->entity.lock);
> +	return ret;
> +}
> +
> +/* -----------------------------------------------------------------------------
> + * V4L2 Subdevice Operations
> + */
> +
> +static const struct v4l2_subdev_pad_ops uif_pad_ops = {
> +	.init_cfg = vsp1_entity_init_cfg,
> +	.enum_mbus_code = uif_enum_mbus_code,
> +	.enum_frame_size = uif_enum_frame_size,
> +	.get_fmt = vsp1_subdev_get_pad_format,
> +	.set_fmt = uif_set_format,
> +	.get_selection = uif_get_selection,
> +	.set_selection = uif_set_selection,
> +};
> +
> +static const struct v4l2_subdev_ops uif_ops = {
> +	.pad    = &uif_pad_ops,
> +};
> +
> +/* -----------------------------------------------------------------------------
> + * VSP1 Entity Operations
> + */
> +
> +static void uif_configure(struct vsp1_entity *entity,
> +			  struct vsp1_pipeline *pipe,
> +			  struct vsp1_dl_list *dl,
> +			  enum vsp1_entity_params params)
> +{
> +	struct vsp1_uif *uif = to_uif(&entity->subdev);
> +	const struct v4l2_rect *crop;
> +	unsigned int left;
> +	unsigned int width;
> +
> +	/*
> +	 * Per-partition configuration isn't needed as the DISCOM is used in
> +	 * display pipelines only.
> +	 */
> +	if (params != VSP1_ENTITY_PARAMS_INIT)
> +		return;
> +
> +	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMPMR,
> +		       VI6_UIF_DISCOM_DOCMPMR_SEL(9));
> +
> +	crop = vsp1_entity_get_pad_selection(entity, entity->config,
> +					     UIF_PAD_SINK, V4L2_SEL_TGT_CROP);
> +
> +	/* On M3-W the horizontal coordinates are twice the register value. */
> +	if (uif->m3w_quirk) {
> +		left = crop->left / 2;
> +		width = crop->width / 2;
> +	} else {
> +		left = crop->left;
> +		width = crop->width;
> +	}

I would write this as

        left = crop->left;
        width = crop->width;

	/* On M3-W the horizontal coordinates are twice the register value. */
	if (uif->m3w_quirk) {
		left /= 2;
		width /= 2;
        }

But that's really up to you.

> +
> +	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMSPXR, left);
> +	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMSPYR, crop->top);
> +	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMSZXR, width);
> +	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMSZYR, crop->height);
> +
> +	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMCR,
> +		       VI6_UIF_DISCOM_DOCMCR_CMPR);
> +}
> +
> +static const struct vsp1_entity_operations uif_entity_ops = {
> +	.configure = uif_configure,
> +};
> +
> +/* -----------------------------------------------------------------------------
> + * Initialization and Cleanup
> + */
> +
> +static const struct soc_device_attribute vsp1_r8a7796[] = {
> +	{ .soc_id = "r8a7796" },
> +	{ /* sentinel */ }
> +};
> +
> +struct vsp1_uif *vsp1_uif_create(struct vsp1_device *vsp1, unsigned int index)
> +{
> +	struct vsp1_uif *uif;
> +	char name[6];
> +	int ret;
> +
> +	uif = devm_kzalloc(vsp1->dev, sizeof(*uif), GFP_KERNEL);
> +	if (uif == NULL)

        if (!uif)

Otherwise checkpatch complains iirc.

Those are very minor comments, so feel free to add my reviewed by tag

Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>

Thanks
  j

> +		return ERR_PTR(-ENOMEM);
> +
> +	if (soc_device_match(vsp1_r8a7796))
> +		uif->m3w_quirk = true;
> +
> +	uif->entity.ops = &uif_entity_ops;
> +	uif->entity.type = VSP1_ENTITY_UIF;
> +	uif->entity.index = index;
> +
> +	/* The datasheet names the two UIF instances UIF4 and UIF5. */
> +	sprintf(name, "uif.%u", index + 4);
> +	ret = vsp1_entity_init(vsp1, &uif->entity, name, 2, &uif_ops,
> +			       MEDIA_ENT_F_PROC_VIDEO_STATISTICS);
> +	if (ret < 0)
> +		return ERR_PTR(ret);
> +
> +	return uif;
> +}
> diff --git a/drivers/media/platform/vsp1/vsp1_uif.h b/drivers/media/platform/vsp1/vsp1_uif.h
> new file mode 100644
> index 000000000000..c71ab5f6a6f8
> --- /dev/null
> +++ b/drivers/media/platform/vsp1/vsp1_uif.h
> @@ -0,0 +1,32 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * vsp1_uif.h  --  R-Car VSP1 User Logic Interface
> + *
> + * Copyright (C) 2017-2018 Laurent Pinchart
> + *
> + * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> + */
> +#ifndef __VSP1_UIF_H__
> +#define __VSP1_UIF_H__
> +
> +#include "vsp1_entity.h"
> +
> +struct vsp1_device;
> +
> +#define UIF_PAD_SINK				0
> +#define UIF_PAD_SOURCE				1
> +
> +struct vsp1_uif {
> +	struct vsp1_entity entity;
> +	bool m3w_quirk;
> +};
> +
> +static inline struct vsp1_uif *to_uif(struct v4l2_subdev *subdev)
> +{
> +	return container_of(subdev, struct vsp1_uif, entity.subdev);
> +}
> +
> +struct vsp1_uif *vsp1_uif_create(struct vsp1_device *vsp1, unsigned int index);
> +u32 vsp1_uif_get_crc(struct vsp1_uif *uif);
> +
> +#endif /* __VSP1_UIF_H__ */
> --
> Regards,
>
> Laurent Pinchart
>

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

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

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

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

* Re: [PATCH v2 7/8] v4l: vsp1: Integrate DISCOM in display pipeline
  2018-04-22 22:34   ` Laurent Pinchart
@ 2018-04-28 11:00     ` jacopo mondi
  -1 siblings, 0 replies; 82+ messages in thread
From: jacopo mondi @ 2018-04-28 11:00 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: linux-media, dri-devel, linux-renesas-soc, Kieran Bingham

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

HI Laurent,

On Mon, Apr 23, 2018 at 01:34:29AM +0300, Laurent Pinchart wrote:
> The DISCOM is used to compute CRCs on display frames. Integrate it in
> the display pipeline at the output of the blending unit to process
> output frames.
>
> Computing CRCs on input frames is possible by positioning the DISCOM at
> a different point in the pipeline. This use case isn't supported at the
> moment and could be implemented by extending the API between the VSP1
> and DU drivers if needed.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>  drivers/media/platform/vsp1/vsp1_drm.c | 115 ++++++++++++++++++++++++++++++++-
>  drivers/media/platform/vsp1/vsp1_drm.h |  12 ++++
>  2 files changed, 124 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c
> index 5fc31578f9b0..7864b43a90e1 100644
> --- a/drivers/media/platform/vsp1/vsp1_drm.c
> +++ b/drivers/media/platform/vsp1/vsp1_drm.c
> @@ -22,6 +22,7 @@
>  #include "vsp1_lif.h"
>  #include "vsp1_pipe.h"
>  #include "vsp1_rwpf.h"
> +#include "vsp1_uif.h"
>
>  #define BRX_NAME(e)	(e)->type == VSP1_ENTITY_BRU ? "BRU" : "BRS"
>
> @@ -35,8 +36,13 @@ static void vsp1_du_pipeline_frame_end(struct vsp1_pipeline *pipe,
>  	struct vsp1_drm_pipeline *drm_pipe = to_vsp1_drm_pipeline(pipe);
>  	bool complete = completion == VSP1_DL_FRAME_END_COMPLETED;
>
> -	if (drm_pipe->du_complete)
> -		drm_pipe->du_complete(drm_pipe->du_private, complete, 0);
> +	if (drm_pipe->du_complete) {
> +		struct vsp1_entity *uif = drm_pipe->uif;
> +		u32 crc;
> +
> +		crc = uif ? vsp1_uif_get_crc(to_uif(&uif->subdev)) : 0;
> +		drm_pipe->du_complete(drm_pipe->du_private, complete, crc);
> +	}
>
>  	if (completion & VSP1_DL_FRAME_END_INTERNAL) {
>  		drm_pipe->force_brx_release = false;
> @@ -48,10 +54,65 @@ static void vsp1_du_pipeline_frame_end(struct vsp1_pipeline *pipe,
>   * Pipeline Configuration
>   */
>
> +/*
> + * Insert the UIF in the pipeline between the prev and next entities. If no UIF
> + * is available connect the two entities directly.
> + */
> +static int vsp1_du_insert_uif(struct vsp1_device *vsp1,
> +			      struct vsp1_pipeline *pipe,
> +			      struct vsp1_entity *uif,
> +			      struct vsp1_entity *prev, unsigned int prev_pad,
> +			      struct vsp1_entity *next, unsigned int next_pad)
> +{
> +	int ret;
> +
> +	if (uif) {
> +		struct v4l2_subdev_format format;
> +
> +		prev->sink = uif;
> +		prev->sink_pad = UIF_PAD_SINK;
> +
> +		memset(&format, 0, sizeof(format));
> +		format.which = V4L2_SUBDEV_FORMAT_ACTIVE;
> +		format.pad = prev_pad;
> +
> +		ret = v4l2_subdev_call(&prev->subdev, pad, get_fmt, NULL,
> +				       &format);
> +		if (ret < 0)
> +			return ret;
> +
> +		format.pad = UIF_PAD_SINK;
> +
> +		ret = v4l2_subdev_call(&uif->subdev, pad, set_fmt, NULL,
> +				       &format);
> +		if (ret < 0)
> +			return ret;
> +
> +		dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on UIF sink\n",
> +			__func__, format.format.width, format.format.height,
> +			format.format.code);
> +
> +		/*
> +		 * The UIF doesn't mangle the format between its sink and
> +		 * source pads, so there is no need to retrieve the format on
> +		 * its source pad.
> +		 */
> +
> +		uif->sink = next;
> +		uif->sink_pad = next_pad;
> +	} else {
> +		prev->sink = next;
> +		prev->sink_pad = next_pad;

Isn't the !uif case better handled in the caller? See below...
Or otherwise, if you prefer handling it here, shouldn't the
indentation be reduced with

        if (!uif) {
		prev->sink = next;
		prev->sink_pad = next_pad;

                return 0;
        }

> +	}
> +
> +	return 0;
> +}
> +
>  /* Setup one RPF and the connected BRx sink pad. */
>  static int vsp1_du_pipeline_setup_rpf(struct vsp1_device *vsp1,
>  				      struct vsp1_pipeline *pipe,
>  				      struct vsp1_rwpf *rpf,
> +				      struct vsp1_entity *uif,
>  				      unsigned int brx_input)
>  {
>  	struct v4l2_subdev_selection sel;
> @@ -122,6 +183,12 @@ static int vsp1_du_pipeline_setup_rpf(struct vsp1_device *vsp1,
>  	if (ret < 0)
>  		return ret;
>
> +	/* Insert and configure the UIF if available. */
> +	ret = vsp1_du_insert_uif(vsp1, pipe, uif, &rpf->entity, RWPF_PAD_SOURCE,
> +				 pipe->brx, brx_input);
> +	if (ret < 0)
> +		return ret;
> +
>  	/* BRx sink, propagate the format from the RPF source. */
>  	format.pad = brx_input;
>
> @@ -297,7 +364,10 @@ static unsigned int rpf_zpos(struct vsp1_device *vsp1, struct vsp1_rwpf *rpf)
>  static int vsp1_du_pipeline_setup_inputs(struct vsp1_device *vsp1,
>  					struct vsp1_pipeline *pipe)
>  {
> +	struct vsp1_drm_pipeline *drm_pipe = to_vsp1_drm_pipeline(pipe);
>  	struct vsp1_rwpf *inputs[VSP1_MAX_RPF] = { NULL, };
> +	struct vsp1_entity *uif;
> +	bool use_uif = false;
>  	struct vsp1_brx *brx;
>  	unsigned int i;
>  	int ret;
> @@ -358,7 +428,11 @@ static int vsp1_du_pipeline_setup_inputs(struct vsp1_device *vsp1,
>  		dev_dbg(vsp1->dev, "%s: connecting RPF.%u to %s:%u\n",
>  			__func__, rpf->entity.index, BRX_NAME(pipe->brx), i);
>
> -		ret = vsp1_du_pipeline_setup_rpf(vsp1, pipe, rpf, i);
> +		uif = drm_pipe->crc.source == VSP1_DU_CRC_PLANE &&
> +		      drm_pipe->crc.index == i ? drm_pipe->uif : NULL;
> +		if (uif)
> +			use_uif = true;
> +		ret = vsp1_du_pipeline_setup_rpf(vsp1, pipe, rpf, uif, i);
>  		if (ret < 0) {
>  			dev_err(vsp1->dev,
>  				"%s: failed to setup RPF.%u\n",
> @@ -367,6 +441,31 @@ static int vsp1_du_pipeline_setup_inputs(struct vsp1_device *vsp1,
>  		}
>  	}
>
> +	/* Insert and configure the UIF at the BRx output if available. */
> +	uif = drm_pipe->crc.source == VSP1_DU_CRC_OUTPUT ? drm_pipe->uif : NULL;
> +	if (uif)
> +		use_uif = true;
> +	ret = vsp1_du_insert_uif(vsp1, pipe, uif,
> +				 pipe->brx, pipe->brx->source_pad,
> +				 &pipe->output->entity, 0);
> +	if (ret < 0)
> +		dev_err(vsp1->dev, "%s: failed to setup UIF after %s\n",
> +			__func__, BRX_NAME(pipe->brx));
> +
> +	/*
> +	 * If the UIF is not in use schedule it for removal by setting its pipe
> +	 * pointer to NULL, vsp1_du_pipeline_configure() will remove it from the
> +	 * hardware pipeline and from the pipeline's list of entities. Otherwise
> +	 * make sure it is present in the pipeline's list of entities if it
> +	 * wasn't already.
> +	 */
> +	if (!use_uif) {

... here. If you don't use uif, don't call vspi1_du_insert_uif().
True, you have to link entities explicitly here if there is not uif,
but I may be missing where this was happening before this code was
added.

Thanks
   j

> +		drm_pipe->uif->pipe = NULL;
> +	} else if (!drm_pipe->uif->pipe) {
> +		drm_pipe->uif->pipe = pipe;
> +		list_add_tail(&drm_pipe->uif->list_pipe, &pipe->entities);
> +	}
> +
>  	return 0;
>  }
>
> @@ -748,6 +847,9 @@ void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index,
>  	struct vsp1_drm_pipeline *drm_pipe = &vsp1->drm->pipe[pipe_index];
>  	struct vsp1_pipeline *pipe = &drm_pipe->pipe;
>
> +	drm_pipe->crc.source = cfg->crc.source;
> +	drm_pipe->crc.index = cfg->crc.index;
> +
>  	vsp1_du_pipeline_setup_inputs(vsp1, pipe);
>  	vsp1_du_pipeline_configure(pipe);
>  	mutex_unlock(&vsp1->drm->lock);
> @@ -816,6 +918,13 @@ int vsp1_drm_init(struct vsp1_device *vsp1)
>
>  		pipe->lif->pipe = pipe;
>  		list_add_tail(&pipe->lif->list_pipe, &pipe->entities);
> +
> +		/*
> +		 * CRC computation is initially disabled, don't add the UIF to
> +		 * the pipeline.
> +		 */
> +		if (i < vsp1->info->uif_count)

Why 'initially disabled'? This seems to me to conditionally enable the
UIF unit. Or is the lif count always the same as the uif count?

Thanks
   j

> +			drm_pipe->uif = &vsp1->uif[i]->entity;
>  	}
>
>  	/* Disable all RPFs initially. */
> diff --git a/drivers/media/platform/vsp1/vsp1_drm.h b/drivers/media/platform/vsp1/vsp1_drm.h
> index e5b88b28806c..1e7670955ef0 100644
> --- a/drivers/media/platform/vsp1/vsp1_drm.h
> +++ b/drivers/media/platform/vsp1/vsp1_drm.h
> @@ -13,6 +13,8 @@
>  #include <linux/videodev2.h>
>  #include <linux/wait.h>
>
> +#include <media/vsp1.h>
> +
>  #include "vsp1_pipe.h"
>
>  /**
> @@ -22,6 +24,9 @@
>   * @height: output display height
>   * @force_brx_release: when set, release the BRx during the next reconfiguration
>   * @wait_queue: wait queue to wait for BRx release completion
> + * @uif: UIF entity if available for the pipeline
> + * @crc.source: source for CRC calculation
> + * @crc.index: index of the CRC source plane (when crc.source is set to plane)
>   * @du_complete: frame completion callback for the DU driver (optional)
>   * @du_private: data to be passed to the du_complete callback
>   */
> @@ -34,6 +39,13 @@ struct vsp1_drm_pipeline {
>  	bool force_brx_release;
>  	wait_queue_head_t wait_queue;
>
> +	struct vsp1_entity *uif;
> +
> +	struct {
> +		enum vsp1_du_crc_source source;
> +		unsigned int index;
> +	} crc;
> +
>  	/* Frame synchronisation */
>  	void (*du_complete)(void *data, bool completed, u32 crc);
>  	void *du_private;
> --
> Regards,
>
> Laurent Pinchart
>

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

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

* Re: [PATCH v2 7/8] v4l: vsp1: Integrate DISCOM in display pipeline
@ 2018-04-28 11:00     ` jacopo mondi
  0 siblings, 0 replies; 82+ messages in thread
From: jacopo mondi @ 2018-04-28 11:00 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: linux-renesas-soc, Kieran Bingham, dri-devel, linux-media


[-- Attachment #1.1: Type: text/plain, Size: 9008 bytes --]

HI Laurent,

On Mon, Apr 23, 2018 at 01:34:29AM +0300, Laurent Pinchart wrote:
> The DISCOM is used to compute CRCs on display frames. Integrate it in
> the display pipeline at the output of the blending unit to process
> output frames.
>
> Computing CRCs on input frames is possible by positioning the DISCOM at
> a different point in the pipeline. This use case isn't supported at the
> moment and could be implemented by extending the API between the VSP1
> and DU drivers if needed.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>  drivers/media/platform/vsp1/vsp1_drm.c | 115 ++++++++++++++++++++++++++++++++-
>  drivers/media/platform/vsp1/vsp1_drm.h |  12 ++++
>  2 files changed, 124 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c
> index 5fc31578f9b0..7864b43a90e1 100644
> --- a/drivers/media/platform/vsp1/vsp1_drm.c
> +++ b/drivers/media/platform/vsp1/vsp1_drm.c
> @@ -22,6 +22,7 @@
>  #include "vsp1_lif.h"
>  #include "vsp1_pipe.h"
>  #include "vsp1_rwpf.h"
> +#include "vsp1_uif.h"
>
>  #define BRX_NAME(e)	(e)->type == VSP1_ENTITY_BRU ? "BRU" : "BRS"
>
> @@ -35,8 +36,13 @@ static void vsp1_du_pipeline_frame_end(struct vsp1_pipeline *pipe,
>  	struct vsp1_drm_pipeline *drm_pipe = to_vsp1_drm_pipeline(pipe);
>  	bool complete = completion == VSP1_DL_FRAME_END_COMPLETED;
>
> -	if (drm_pipe->du_complete)
> -		drm_pipe->du_complete(drm_pipe->du_private, complete, 0);
> +	if (drm_pipe->du_complete) {
> +		struct vsp1_entity *uif = drm_pipe->uif;
> +		u32 crc;
> +
> +		crc = uif ? vsp1_uif_get_crc(to_uif(&uif->subdev)) : 0;
> +		drm_pipe->du_complete(drm_pipe->du_private, complete, crc);
> +	}
>
>  	if (completion & VSP1_DL_FRAME_END_INTERNAL) {
>  		drm_pipe->force_brx_release = false;
> @@ -48,10 +54,65 @@ static void vsp1_du_pipeline_frame_end(struct vsp1_pipeline *pipe,
>   * Pipeline Configuration
>   */
>
> +/*
> + * Insert the UIF in the pipeline between the prev and next entities. If no UIF
> + * is available connect the two entities directly.
> + */
> +static int vsp1_du_insert_uif(struct vsp1_device *vsp1,
> +			      struct vsp1_pipeline *pipe,
> +			      struct vsp1_entity *uif,
> +			      struct vsp1_entity *prev, unsigned int prev_pad,
> +			      struct vsp1_entity *next, unsigned int next_pad)
> +{
> +	int ret;
> +
> +	if (uif) {
> +		struct v4l2_subdev_format format;
> +
> +		prev->sink = uif;
> +		prev->sink_pad = UIF_PAD_SINK;
> +
> +		memset(&format, 0, sizeof(format));
> +		format.which = V4L2_SUBDEV_FORMAT_ACTIVE;
> +		format.pad = prev_pad;
> +
> +		ret = v4l2_subdev_call(&prev->subdev, pad, get_fmt, NULL,
> +				       &format);
> +		if (ret < 0)
> +			return ret;
> +
> +		format.pad = UIF_PAD_SINK;
> +
> +		ret = v4l2_subdev_call(&uif->subdev, pad, set_fmt, NULL,
> +				       &format);
> +		if (ret < 0)
> +			return ret;
> +
> +		dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on UIF sink\n",
> +			__func__, format.format.width, format.format.height,
> +			format.format.code);
> +
> +		/*
> +		 * The UIF doesn't mangle the format between its sink and
> +		 * source pads, so there is no need to retrieve the format on
> +		 * its source pad.
> +		 */
> +
> +		uif->sink = next;
> +		uif->sink_pad = next_pad;
> +	} else {
> +		prev->sink = next;
> +		prev->sink_pad = next_pad;

Isn't the !uif case better handled in the caller? See below...
Or otherwise, if you prefer handling it here, shouldn't the
indentation be reduced with

        if (!uif) {
		prev->sink = next;
		prev->sink_pad = next_pad;

                return 0;
        }

> +	}
> +
> +	return 0;
> +}
> +
>  /* Setup one RPF and the connected BRx sink pad. */
>  static int vsp1_du_pipeline_setup_rpf(struct vsp1_device *vsp1,
>  				      struct vsp1_pipeline *pipe,
>  				      struct vsp1_rwpf *rpf,
> +				      struct vsp1_entity *uif,
>  				      unsigned int brx_input)
>  {
>  	struct v4l2_subdev_selection sel;
> @@ -122,6 +183,12 @@ static int vsp1_du_pipeline_setup_rpf(struct vsp1_device *vsp1,
>  	if (ret < 0)
>  		return ret;
>
> +	/* Insert and configure the UIF if available. */
> +	ret = vsp1_du_insert_uif(vsp1, pipe, uif, &rpf->entity, RWPF_PAD_SOURCE,
> +				 pipe->brx, brx_input);
> +	if (ret < 0)
> +		return ret;
> +
>  	/* BRx sink, propagate the format from the RPF source. */
>  	format.pad = brx_input;
>
> @@ -297,7 +364,10 @@ static unsigned int rpf_zpos(struct vsp1_device *vsp1, struct vsp1_rwpf *rpf)
>  static int vsp1_du_pipeline_setup_inputs(struct vsp1_device *vsp1,
>  					struct vsp1_pipeline *pipe)
>  {
> +	struct vsp1_drm_pipeline *drm_pipe = to_vsp1_drm_pipeline(pipe);
>  	struct vsp1_rwpf *inputs[VSP1_MAX_RPF] = { NULL, };
> +	struct vsp1_entity *uif;
> +	bool use_uif = false;
>  	struct vsp1_brx *brx;
>  	unsigned int i;
>  	int ret;
> @@ -358,7 +428,11 @@ static int vsp1_du_pipeline_setup_inputs(struct vsp1_device *vsp1,
>  		dev_dbg(vsp1->dev, "%s: connecting RPF.%u to %s:%u\n",
>  			__func__, rpf->entity.index, BRX_NAME(pipe->brx), i);
>
> -		ret = vsp1_du_pipeline_setup_rpf(vsp1, pipe, rpf, i);
> +		uif = drm_pipe->crc.source == VSP1_DU_CRC_PLANE &&
> +		      drm_pipe->crc.index == i ? drm_pipe->uif : NULL;
> +		if (uif)
> +			use_uif = true;
> +		ret = vsp1_du_pipeline_setup_rpf(vsp1, pipe, rpf, uif, i);
>  		if (ret < 0) {
>  			dev_err(vsp1->dev,
>  				"%s: failed to setup RPF.%u\n",
> @@ -367,6 +441,31 @@ static int vsp1_du_pipeline_setup_inputs(struct vsp1_device *vsp1,
>  		}
>  	}
>
> +	/* Insert and configure the UIF at the BRx output if available. */
> +	uif = drm_pipe->crc.source == VSP1_DU_CRC_OUTPUT ? drm_pipe->uif : NULL;
> +	if (uif)
> +		use_uif = true;
> +	ret = vsp1_du_insert_uif(vsp1, pipe, uif,
> +				 pipe->brx, pipe->brx->source_pad,
> +				 &pipe->output->entity, 0);
> +	if (ret < 0)
> +		dev_err(vsp1->dev, "%s: failed to setup UIF after %s\n",
> +			__func__, BRX_NAME(pipe->brx));
> +
> +	/*
> +	 * If the UIF is not in use schedule it for removal by setting its pipe
> +	 * pointer to NULL, vsp1_du_pipeline_configure() will remove it from the
> +	 * hardware pipeline and from the pipeline's list of entities. Otherwise
> +	 * make sure it is present in the pipeline's list of entities if it
> +	 * wasn't already.
> +	 */
> +	if (!use_uif) {

... here. If you don't use uif, don't call vspi1_du_insert_uif().
True, you have to link entities explicitly here if there is not uif,
but I may be missing where this was happening before this code was
added.

Thanks
   j

> +		drm_pipe->uif->pipe = NULL;
> +	} else if (!drm_pipe->uif->pipe) {
> +		drm_pipe->uif->pipe = pipe;
> +		list_add_tail(&drm_pipe->uif->list_pipe, &pipe->entities);
> +	}
> +
>  	return 0;
>  }
>
> @@ -748,6 +847,9 @@ void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index,
>  	struct vsp1_drm_pipeline *drm_pipe = &vsp1->drm->pipe[pipe_index];
>  	struct vsp1_pipeline *pipe = &drm_pipe->pipe;
>
> +	drm_pipe->crc.source = cfg->crc.source;
> +	drm_pipe->crc.index = cfg->crc.index;
> +
>  	vsp1_du_pipeline_setup_inputs(vsp1, pipe);
>  	vsp1_du_pipeline_configure(pipe);
>  	mutex_unlock(&vsp1->drm->lock);
> @@ -816,6 +918,13 @@ int vsp1_drm_init(struct vsp1_device *vsp1)
>
>  		pipe->lif->pipe = pipe;
>  		list_add_tail(&pipe->lif->list_pipe, &pipe->entities);
> +
> +		/*
> +		 * CRC computation is initially disabled, don't add the UIF to
> +		 * the pipeline.
> +		 */
> +		if (i < vsp1->info->uif_count)

Why 'initially disabled'? This seems to me to conditionally enable the
UIF unit. Or is the lif count always the same as the uif count?

Thanks
   j

> +			drm_pipe->uif = &vsp1->uif[i]->entity;
>  	}
>
>  	/* Disable all RPFs initially. */
> diff --git a/drivers/media/platform/vsp1/vsp1_drm.h b/drivers/media/platform/vsp1/vsp1_drm.h
> index e5b88b28806c..1e7670955ef0 100644
> --- a/drivers/media/platform/vsp1/vsp1_drm.h
> +++ b/drivers/media/platform/vsp1/vsp1_drm.h
> @@ -13,6 +13,8 @@
>  #include <linux/videodev2.h>
>  #include <linux/wait.h>
>
> +#include <media/vsp1.h>
> +
>  #include "vsp1_pipe.h"
>
>  /**
> @@ -22,6 +24,9 @@
>   * @height: output display height
>   * @force_brx_release: when set, release the BRx during the next reconfiguration
>   * @wait_queue: wait queue to wait for BRx release completion
> + * @uif: UIF entity if available for the pipeline
> + * @crc.source: source for CRC calculation
> + * @crc.index: index of the CRC source plane (when crc.source is set to plane)
>   * @du_complete: frame completion callback for the DU driver (optional)
>   * @du_private: data to be passed to the du_complete callback
>   */
> @@ -34,6 +39,13 @@ struct vsp1_drm_pipeline {
>  	bool force_brx_release;
>  	wait_queue_head_t wait_queue;
>
> +	struct vsp1_entity *uif;
> +
> +	struct {
> +		enum vsp1_du_crc_source source;
> +		unsigned int index;
> +	} crc;
> +
>  	/* Frame synchronisation */
>  	void (*du_complete)(void *data, bool completed, u32 crc);
>  	void *du_private;
> --
> Regards,
>
> Laurent Pinchart
>

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

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

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

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

* Re: [PATCH v2 2/8] v4l: vsp1: Share the CLU, LIF and LUT set_fmt pad operation code
  2018-04-28  9:50     ` jacopo mondi
@ 2018-04-28 16:07       ` Laurent Pinchart
  -1 siblings, 0 replies; 82+ messages in thread
From: Laurent Pinchart @ 2018-04-28 16:07 UTC (permalink / raw)
  To: jacopo mondi
  Cc: Laurent Pinchart, linux-media, dri-devel, linux-renesas-soc,
	Kieran Bingham

Hi Jacopo,

On Saturday, 28 April 2018 12:50:48 EEST jacopo mondi wrote:
> Hi Laurent,
>    very minor comments below
> 
> On Mon, Apr 23, 2018 at 01:34:24AM +0300, Laurent Pinchart wrote:
> > The implementation of the set_fmt pad operation is identical in the
> > three modules. Move it to a generic helper function.
> > 
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com>
> > ---
> > 
> >  drivers/media/platform/vsp1/vsp1_clu.c    | 65 +++++--------------------
> >  drivers/media/platform/vsp1/vsp1_entity.c | 75 ++++++++++++++++++++++++++
> >  drivers/media/platform/vsp1/vsp1_entity.h |  6 +++
> >  drivers/media/platform/vsp1/vsp1_lif.c    | 65 +++++--------------------
> >  drivers/media/platform/vsp1/vsp1_lut.c    | 65 +++++--------------------
> >  5 files changed, 116 insertions(+), 160 deletions(-)
> > 
> > diff --git a/drivers/media/platform/vsp1/vsp1_clu.c
> > b/drivers/media/platform/vsp1/vsp1_clu.c index 9626b6308585..96a448e1504c
> > 100644
> > --- a/drivers/media/platform/vsp1/vsp1_clu.c
> > +++ b/drivers/media/platform/vsp1/vsp1_clu.c
> > @@ -114,18 +114,18 @@ static const struct v4l2_ctrl_config
> > clu_mode_control = {
> >   * V4L2 Subdevice Pad Operations
> >   */
> > 
> > +static const unsigned int clu_codes[] = {
> > +	MEDIA_BUS_FMT_ARGB8888_1X32,
> > +	MEDIA_BUS_FMT_AHSV8888_1X32,
> > +	MEDIA_BUS_FMT_AYUV8_1X32,
> > +};
> > +
> >  static int clu_enum_mbus_code(struct v4l2_subdev *subdev,
> >  			      struct v4l2_subdev_pad_config *cfg,
> >  			      struct v4l2_subdev_mbus_code_enum *code)
> >  {
> > -	static const unsigned int codes[] = {
> > -		MEDIA_BUS_FMT_ARGB8888_1X32,
> > -		MEDIA_BUS_FMT_AHSV8888_1X32,
> > -		MEDIA_BUS_FMT_AYUV8_1X32,
> > -	};
> > -
> > -	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, codes,
> > -					  ARRAY_SIZE(codes));
> > +	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, clu_codes,
> > +					  ARRAY_SIZE(clu_codes));
> >  }
> >  
> >  static int clu_enum_frame_size(struct v4l2_subdev *subdev,
> > @@ -141,51 +141,10 @@ static int clu_set_format(struct v4l2_subdev
> > *subdev,
> >  			  struct v4l2_subdev_pad_config *cfg,
> >  			  struct v4l2_subdev_format *fmt)
> >  {
> > -	struct vsp1_clu *clu = to_clu(subdev);
> > -	struct v4l2_subdev_pad_config *config;
> > -	struct v4l2_mbus_framefmt *format;
> > -	int ret = 0;
> > -
> > -	mutex_lock(&clu->entity.lock);
> > -
> > -	config = vsp1_entity_get_pad_config(&clu->entity, cfg, fmt->which);
> > -	if (!config) {
> > -		ret = -EINVAL;
> > -		goto done;
> > -	}
> > -
> > -	/* Default to YUV if the requested format is not supported. */
> > -	if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
> > -	    fmt->format.code != MEDIA_BUS_FMT_AHSV8888_1X32 &&
> > -	    fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32)
> > -		fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32;
> 
> The newly implemented vsp1_subdev_set_pad_format defaults to the first
> clu_codes[] member (ARGB888_1x32), while here the code chose the AYUV8_1x32
> format. Is it ok? Should you revers the clu_codes[] order?

But that would then change the order of the format enumeration.

I don't think it's a big deal, the change here will only affect the format 
returned if userspace tries to pick a format that is not supported (and thus 
not returned by the enumeration). This shouldn't happen in the first place, 
and if it does, the driver has never guaranteed that a specific format would 
be returned.

> > -
> > -	format = vsp1_entity_get_pad_format(&clu->entity, config, fmt->pad);
> > -
> > -	if (fmt->pad == CLU_PAD_SOURCE) {
> > -		/* The CLU output format can't be modified. */
> > -		fmt->format = *format;
> > -		goto done;
> > -	}
> > -
> > -	format->code = fmt->format.code;
> > -	format->width = clamp_t(unsigned int, fmt->format.width,
> > -				CLU_MIN_SIZE, CLU_MAX_SIZE);
> > -	format->height = clamp_t(unsigned int, fmt->format.height,
> > -				 CLU_MIN_SIZE, CLU_MAX_SIZE);
> > -	format->field = V4L2_FIELD_NONE;
> > -	format->colorspace = V4L2_COLORSPACE_SRGB;
> > -
> > -	fmt->format = *format;
> > -
> > -	/* Propagate the format to the source pad. */
> > -	format = vsp1_entity_get_pad_format(&clu->entity, config,
> > -					    CLU_PAD_SOURCE);
> > -	*format = fmt->format;
> > -
> > -done:
> > -	mutex_unlock(&clu->entity.lock);
> > -	return ret;
> > +	return vsp1_subdev_set_pad_format(subdev, cfg, fmt, clu_codes,
> > +					  ARRAY_SIZE(clu_codes),
> > +					  CLU_MIN_SIZE, CLU_MIN_SIZE,
> > +					  CLU_MAX_SIZE, CLU_MAX_SIZE);
> >  }
> >  
> >  /* ----------------------------------------------------------------------
> > diff --git a/drivers/media/platform/vsp1/vsp1_entity.c
> > b/drivers/media/platform/vsp1/vsp1_entity.c index
> > 72354caf5746..239df047efd0 100644
> > --- a/drivers/media/platform/vsp1/vsp1_entity.c
> > +++ b/drivers/media/platform/vsp1/vsp1_entity.c
> > @@ -307,6 +307,81 @@ int vsp1_subdev_enum_frame_size(struct v4l2_subdev
> > *subdev,
> >  	return ret;
> >  }
> > 
> > +/*
> > + * vsp1_subdev_set_pad_format - Subdev pad set_fmt handler
> > + * @subdev: V4L2 subdevice
> > + * @cfg: V4L2 subdev pad configuration
> > + * @fmt: V4L2 subdev format
> > + * @codes: Array of supported media bus codes
> > + * @ncodes: Number of supported media bus codes
> > + * @min_width: Minimum image width
> > + * @min_height: Minimum image height
> > + * @max_width: Maximum image width
> > + * @max_height: Maximum image height
> > + *
> > + * This function implements the subdev set_fmt pad operation for entities
> > that
> > + * do not support scaling or cropping. It defaults to the first supplied
> > media
> > + * bus code if the requested code isn't supported, clamps the size to the
> > + * supplied minimum and maximum, and propagates the sink pad format to
> > the
> > + * source pad.
> > + */
> > +int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev,
> > +			       struct v4l2_subdev_pad_config *cfg,
> > +			       struct v4l2_subdev_format *fmt,
> > +			       const unsigned int *codes, unsigned int ncodes,
> > +			       unsigned int min_width, unsigned int min_height,
> > +			       unsigned int max_width, unsigned int max_height)
> > +{
> > +	struct vsp1_entity *entity = to_vsp1_entity(subdev);
> > +	struct v4l2_subdev_pad_config *config;
> > +	struct v4l2_mbus_framefmt *format;
> > +	unsigned int i;
> > +	int ret = 0;
> > +
> > +	mutex_lock(&entity->lock);
> > +
> > +	config = vsp1_entity_get_pad_config(entity, cfg, fmt->which);
> > +	if (!config) {
> > +		ret = -EINVAL;
> > +		goto done;
> > +	}
> > +
> > +	format = vsp1_entity_get_pad_format(entity, config, fmt->pad);
> > +
> > +	if (fmt->pad != 0) {
> 
> This assumes the SINK pad is always 0, which indeed is the case for
> CLU, LIF and LUT entities.
> 
> > +		/* The output format can't be modified. */
> > +		fmt->format = *format;
> > +		goto done;
> > +	}
> > +
> > +	/*
> > +	 * Default to the first media bus code if the requested format is not
> > +	 * supported.
> > +	 */
> > +	for (i = 0; i < ncodes; ++i) {
> > +		if (fmt->format.code == codes[i])
> > +			break;
> > +	}
> 
> Braces not needed?

Not strictly required but I find it more readable.

> > +
> > +	format->code = i < ncodes ? codes[i] : codes[0];
> > +	format->width = clamp_t(unsigned int, fmt->format.width,
> > +				min_width, max_width);
> > +	format->height = clamp_t(unsigned int, fmt->format.height,
> > +				 min_height, max_height);
> > +	format->field = V4L2_FIELD_NONE;
> > +	format->colorspace = V4L2_COLORSPACE_SRGB;
> > +
> > +	fmt->format = *format;
> > +
> > +	/* Propagate the format to the source pad. */
> > +	format = vsp1_entity_get_pad_format(entity, config, 1);
> > +	*format = fmt->format;
> > +
> > +done:
> > +	mutex_unlock(&entity->lock);
> > +	return ret;
> > +}

[snip]

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v2 2/8] v4l: vsp1: Share the CLU, LIF and LUT set_fmt pad operation code
@ 2018-04-28 16:07       ` Laurent Pinchart
  0 siblings, 0 replies; 82+ messages in thread
From: Laurent Pinchart @ 2018-04-28 16:07 UTC (permalink / raw)
  To: jacopo mondi
  Cc: linux-renesas-soc, Laurent Pinchart, Kieran Bingham, dri-devel,
	linux-media

Hi Jacopo,

On Saturday, 28 April 2018 12:50:48 EEST jacopo mondi wrote:
> Hi Laurent,
>    very minor comments below
> 
> On Mon, Apr 23, 2018 at 01:34:24AM +0300, Laurent Pinchart wrote:
> > The implementation of the set_fmt pad operation is identical in the
> > three modules. Move it to a generic helper function.
> > 
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com>
> > ---
> > 
> >  drivers/media/platform/vsp1/vsp1_clu.c    | 65 +++++--------------------
> >  drivers/media/platform/vsp1/vsp1_entity.c | 75 ++++++++++++++++++++++++++
> >  drivers/media/platform/vsp1/vsp1_entity.h |  6 +++
> >  drivers/media/platform/vsp1/vsp1_lif.c    | 65 +++++--------------------
> >  drivers/media/platform/vsp1/vsp1_lut.c    | 65 +++++--------------------
> >  5 files changed, 116 insertions(+), 160 deletions(-)
> > 
> > diff --git a/drivers/media/platform/vsp1/vsp1_clu.c
> > b/drivers/media/platform/vsp1/vsp1_clu.c index 9626b6308585..96a448e1504c
> > 100644
> > --- a/drivers/media/platform/vsp1/vsp1_clu.c
> > +++ b/drivers/media/platform/vsp1/vsp1_clu.c
> > @@ -114,18 +114,18 @@ static const struct v4l2_ctrl_config
> > clu_mode_control = {
> >   * V4L2 Subdevice Pad Operations
> >   */
> > 
> > +static const unsigned int clu_codes[] = {
> > +	MEDIA_BUS_FMT_ARGB8888_1X32,
> > +	MEDIA_BUS_FMT_AHSV8888_1X32,
> > +	MEDIA_BUS_FMT_AYUV8_1X32,
> > +};
> > +
> >  static int clu_enum_mbus_code(struct v4l2_subdev *subdev,
> >  			      struct v4l2_subdev_pad_config *cfg,
> >  			      struct v4l2_subdev_mbus_code_enum *code)
> >  {
> > -	static const unsigned int codes[] = {
> > -		MEDIA_BUS_FMT_ARGB8888_1X32,
> > -		MEDIA_BUS_FMT_AHSV8888_1X32,
> > -		MEDIA_BUS_FMT_AYUV8_1X32,
> > -	};
> > -
> > -	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, codes,
> > -					  ARRAY_SIZE(codes));
> > +	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, clu_codes,
> > +					  ARRAY_SIZE(clu_codes));
> >  }
> >  
> >  static int clu_enum_frame_size(struct v4l2_subdev *subdev,
> > @@ -141,51 +141,10 @@ static int clu_set_format(struct v4l2_subdev
> > *subdev,
> >  			  struct v4l2_subdev_pad_config *cfg,
> >  			  struct v4l2_subdev_format *fmt)
> >  {
> > -	struct vsp1_clu *clu = to_clu(subdev);
> > -	struct v4l2_subdev_pad_config *config;
> > -	struct v4l2_mbus_framefmt *format;
> > -	int ret = 0;
> > -
> > -	mutex_lock(&clu->entity.lock);
> > -
> > -	config = vsp1_entity_get_pad_config(&clu->entity, cfg, fmt->which);
> > -	if (!config) {
> > -		ret = -EINVAL;
> > -		goto done;
> > -	}
> > -
> > -	/* Default to YUV if the requested format is not supported. */
> > -	if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
> > -	    fmt->format.code != MEDIA_BUS_FMT_AHSV8888_1X32 &&
> > -	    fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32)
> > -		fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32;
> 
> The newly implemented vsp1_subdev_set_pad_format defaults to the first
> clu_codes[] member (ARGB888_1x32), while here the code chose the AYUV8_1x32
> format. Is it ok? Should you revers the clu_codes[] order?

But that would then change the order of the format enumeration.

I don't think it's a big deal, the change here will only affect the format 
returned if userspace tries to pick a format that is not supported (and thus 
not returned by the enumeration). This shouldn't happen in the first place, 
and if it does, the driver has never guaranteed that a specific format would 
be returned.

> > -
> > -	format = vsp1_entity_get_pad_format(&clu->entity, config, fmt->pad);
> > -
> > -	if (fmt->pad == CLU_PAD_SOURCE) {
> > -		/* The CLU output format can't be modified. */
> > -		fmt->format = *format;
> > -		goto done;
> > -	}
> > -
> > -	format->code = fmt->format.code;
> > -	format->width = clamp_t(unsigned int, fmt->format.width,
> > -				CLU_MIN_SIZE, CLU_MAX_SIZE);
> > -	format->height = clamp_t(unsigned int, fmt->format.height,
> > -				 CLU_MIN_SIZE, CLU_MAX_SIZE);
> > -	format->field = V4L2_FIELD_NONE;
> > -	format->colorspace = V4L2_COLORSPACE_SRGB;
> > -
> > -	fmt->format = *format;
> > -
> > -	/* Propagate the format to the source pad. */
> > -	format = vsp1_entity_get_pad_format(&clu->entity, config,
> > -					    CLU_PAD_SOURCE);
> > -	*format = fmt->format;
> > -
> > -done:
> > -	mutex_unlock(&clu->entity.lock);
> > -	return ret;
> > +	return vsp1_subdev_set_pad_format(subdev, cfg, fmt, clu_codes,
> > +					  ARRAY_SIZE(clu_codes),
> > +					  CLU_MIN_SIZE, CLU_MIN_SIZE,
> > +					  CLU_MAX_SIZE, CLU_MAX_SIZE);
> >  }
> >  
> >  /* ----------------------------------------------------------------------
> > diff --git a/drivers/media/platform/vsp1/vsp1_entity.c
> > b/drivers/media/platform/vsp1/vsp1_entity.c index
> > 72354caf5746..239df047efd0 100644
> > --- a/drivers/media/platform/vsp1/vsp1_entity.c
> > +++ b/drivers/media/platform/vsp1/vsp1_entity.c
> > @@ -307,6 +307,81 @@ int vsp1_subdev_enum_frame_size(struct v4l2_subdev
> > *subdev,
> >  	return ret;
> >  }
> > 
> > +/*
> > + * vsp1_subdev_set_pad_format - Subdev pad set_fmt handler
> > + * @subdev: V4L2 subdevice
> > + * @cfg: V4L2 subdev pad configuration
> > + * @fmt: V4L2 subdev format
> > + * @codes: Array of supported media bus codes
> > + * @ncodes: Number of supported media bus codes
> > + * @min_width: Minimum image width
> > + * @min_height: Minimum image height
> > + * @max_width: Maximum image width
> > + * @max_height: Maximum image height
> > + *
> > + * This function implements the subdev set_fmt pad operation for entities
> > that
> > + * do not support scaling or cropping. It defaults to the first supplied
> > media
> > + * bus code if the requested code isn't supported, clamps the size to the
> > + * supplied minimum and maximum, and propagates the sink pad format to
> > the
> > + * source pad.
> > + */
> > +int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev,
> > +			       struct v4l2_subdev_pad_config *cfg,
> > +			       struct v4l2_subdev_format *fmt,
> > +			       const unsigned int *codes, unsigned int ncodes,
> > +			       unsigned int min_width, unsigned int min_height,
> > +			       unsigned int max_width, unsigned int max_height)
> > +{
> > +	struct vsp1_entity *entity = to_vsp1_entity(subdev);
> > +	struct v4l2_subdev_pad_config *config;
> > +	struct v4l2_mbus_framefmt *format;
> > +	unsigned int i;
> > +	int ret = 0;
> > +
> > +	mutex_lock(&entity->lock);
> > +
> > +	config = vsp1_entity_get_pad_config(entity, cfg, fmt->which);
> > +	if (!config) {
> > +		ret = -EINVAL;
> > +		goto done;
> > +	}
> > +
> > +	format = vsp1_entity_get_pad_format(entity, config, fmt->pad);
> > +
> > +	if (fmt->pad != 0) {
> 
> This assumes the SINK pad is always 0, which indeed is the case for
> CLU, LIF and LUT entities.
> 
> > +		/* The output format can't be modified. */
> > +		fmt->format = *format;
> > +		goto done;
> > +	}
> > +
> > +	/*
> > +	 * Default to the first media bus code if the requested format is not
> > +	 * supported.
> > +	 */
> > +	for (i = 0; i < ncodes; ++i) {
> > +		if (fmt->format.code == codes[i])
> > +			break;
> > +	}
> 
> Braces not needed?

Not strictly required but I find it more readable.

> > +
> > +	format->code = i < ncodes ? codes[i] : codes[0];
> > +	format->width = clamp_t(unsigned int, fmt->format.width,
> > +				min_width, max_width);
> > +	format->height = clamp_t(unsigned int, fmt->format.height,
> > +				 min_height, max_height);
> > +	format->field = V4L2_FIELD_NONE;
> > +	format->colorspace = V4L2_COLORSPACE_SRGB;
> > +
> > +	fmt->format = *format;
> > +
> > +	/* Propagate the format to the source pad. */
> > +	format = vsp1_entity_get_pad_format(entity, config, 1);
> > +	*format = fmt->format;
> > +
> > +done:
> > +	mutex_unlock(&entity->lock);
> > +	return ret;
> > +}

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

* Re: [PATCH v2 5/8] v4l: vsp1: Extend the DU API to support CRC computation
  2018-04-28 10:03     ` jacopo mondi
@ 2018-04-28 16:19       ` Laurent Pinchart
  -1 siblings, 0 replies; 82+ messages in thread
From: Laurent Pinchart @ 2018-04-28 16:19 UTC (permalink / raw)
  To: jacopo mondi
  Cc: Laurent Pinchart, linux-media, dri-devel, linux-renesas-soc,
	Kieran Bingham

Hi Jacopo,

On Saturday, 28 April 2018 13:03:16 EEST jacopo mondi wrote:
> Hi Laurent,
>    just one minor comment below
> 
> On Mon, Apr 23, 2018 at 01:34:27AM +0300, Laurent Pinchart wrote:
> > Add a parameter (in the form of a structure to ease future API
> > extensions) to the VSP atomic flush handler to pass CRC source
> > configuration, and pass the CRC value to the completion callback.
> > 
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com>
> > ---
> > 
> >  drivers/gpu/drm/rcar-du/rcar_du_vsp.c  |  6 ++++--
> >  drivers/media/platform/vsp1/vsp1_drm.c |  6 ++++--
> >  drivers/media/platform/vsp1/vsp1_drm.h |  2 +-
> >  include/media/vsp1.h                   | 29 +++++++++++++++++++++++++++--
> >  4 files changed, 36 insertions(+), 7 deletions(-)

[snip]

> > diff --git a/include/media/vsp1.h b/include/media/vsp1.h
> > index ff7ef894465d..ac63a9928a79 100644
> > --- a/include/media/vsp1.h
> > +++ b/include/media/vsp1.h

[snip]

> > @@ -61,11 +61,36 @@ struct vsp1_du_atomic_config {
> >  	unsigned int zpos;
> >  };
> > 
> > +/**
> > + * enum vsp1_du_crc_source - Source used for CRC calculation
> > + * @VSP1_DU_CRC_NONE: CRC calculation disabled
> > + * @VSP_DU_CRC_PLANE: Perform CRC calculation on an input plane
> > + * @VSP_DU_CRC_OUTPUT: Perform CRC calculation on the composed output
> 
> These two paramters are called VSP1_DU_CRC_* not VSP_DU_CRC_*

My bad. I've fixed this in my tree but will wait for other review comments 
before posting a v3.

> > + */
> > +enum vsp1_du_crc_source {
> > +	VSP1_DU_CRC_NONE,
> > +	VSP1_DU_CRC_PLANE,
> > +	VSP1_DU_CRC_OUTPUT,
> > +};

[snip]

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v2 5/8] v4l: vsp1: Extend the DU API to support CRC computation
@ 2018-04-28 16:19       ` Laurent Pinchart
  0 siblings, 0 replies; 82+ messages in thread
From: Laurent Pinchart @ 2018-04-28 16:19 UTC (permalink / raw)
  To: jacopo mondi
  Cc: linux-renesas-soc, Laurent Pinchart, Kieran Bingham, dri-devel,
	linux-media

Hi Jacopo,

On Saturday, 28 April 2018 13:03:16 EEST jacopo mondi wrote:
> Hi Laurent,
>    just one minor comment below
> 
> On Mon, Apr 23, 2018 at 01:34:27AM +0300, Laurent Pinchart wrote:
> > Add a parameter (in the form of a structure to ease future API
> > extensions) to the VSP atomic flush handler to pass CRC source
> > configuration, and pass the CRC value to the completion callback.
> > 
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com>
> > ---
> > 
> >  drivers/gpu/drm/rcar-du/rcar_du_vsp.c  |  6 ++++--
> >  drivers/media/platform/vsp1/vsp1_drm.c |  6 ++++--
> >  drivers/media/platform/vsp1/vsp1_drm.h |  2 +-
> >  include/media/vsp1.h                   | 29 +++++++++++++++++++++++++++--
> >  4 files changed, 36 insertions(+), 7 deletions(-)

[snip]

> > diff --git a/include/media/vsp1.h b/include/media/vsp1.h
> > index ff7ef894465d..ac63a9928a79 100644
> > --- a/include/media/vsp1.h
> > +++ b/include/media/vsp1.h

[snip]

> > @@ -61,11 +61,36 @@ struct vsp1_du_atomic_config {
> >  	unsigned int zpos;
> >  };
> > 
> > +/**
> > + * enum vsp1_du_crc_source - Source used for CRC calculation
> > + * @VSP1_DU_CRC_NONE: CRC calculation disabled
> > + * @VSP_DU_CRC_PLANE: Perform CRC calculation on an input plane
> > + * @VSP_DU_CRC_OUTPUT: Perform CRC calculation on the composed output
> 
> These two paramters are called VSP1_DU_CRC_* not VSP_DU_CRC_*

My bad. I've fixed this in my tree but will wait for other review comments 
before posting a v3.

> > + */
> > +enum vsp1_du_crc_source {
> > +	VSP1_DU_CRC_NONE,
> > +	VSP1_DU_CRC_PLANE,
> > +	VSP1_DU_CRC_OUTPUT,
> > +};

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

* Re: [PATCH v2 6/8] v4l: vsp1: Add support for the DISCOM entity
  2018-04-28 10:40     ` jacopo mondi
@ 2018-04-28 16:50       ` Laurent Pinchart
  -1 siblings, 0 replies; 82+ messages in thread
From: Laurent Pinchart @ 2018-04-28 16:50 UTC (permalink / raw)
  To: jacopo mondi
  Cc: Laurent Pinchart, linux-media, dri-devel, linux-renesas-soc,
	Kieran Bingham

Hi Jacopo,

On Saturday, 28 April 2018 13:40:02 EEST jacopo mondi wrote:
> HI Laurent,
>    a few comments, mostly minor ones...
> 
> On Mon, Apr 23, 2018 at 01:34:28AM +0300, Laurent Pinchart wrote:
> > The DISCOM calculates a CRC on a configurable window of the frame. It
> > interfaces to the VSP through the UIF glue, hence the name used in the
> > code.
> > 
> > The module supports configuration of the CRC window through the crop
> > rectangle on the ink pad of the corresponding entity. However, unlike
> 
> sink pad?

Oops. Consider it fixed.

> > the traditional V4L2 subdevice model, the crop rectangle does not
> > influence the format on the source pad.
> > 
> > Modeling the DISCOM as a sink-only entity would allow adhering to the
> > V4L2 subdevice model at the expense of more complex code in the driver,
> > as at the hardware level the UIF is handled as a sink+source entity. As
> > the DISCOM is only present in R-Car Gen3 VSP-D and VSP-DL instances it
> > is not exposed to userspace through V4L2 but controlled through the DU
> > driver. We can thus change this model later if needed without fear of
> > affecting userspace.
> > 
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com>
> > ---
> > Changes since v1:
> > 
> > - Don't return uninitialized value from uif_set_selection()
> > ---
> > 
> >  drivers/media/platform/vsp1/Makefile      |   2 +-
> >  drivers/media/platform/vsp1/vsp1.h        |   4 +
> >  drivers/media/platform/vsp1/vsp1_drv.c    |  20 +++
> >  drivers/media/platform/vsp1/vsp1_entity.c |   6 +
> >  drivers/media/platform/vsp1/vsp1_entity.h |   1 +
> >  drivers/media/platform/vsp1/vsp1_regs.h   |  41 +++++
> >  drivers/media/platform/vsp1/vsp1_uif.c    | 271 +++++++++++++++++++++++++
> >  drivers/media/platform/vsp1/vsp1_uif.h    |  32 ++++
> >  8 files changed, 376 insertions(+), 1 deletion(-)
> >  create mode 100644 drivers/media/platform/vsp1/vsp1_uif.c
> >  create mode 100644 drivers/media/platform/vsp1/vsp1_uif.h

[snip]

> > diff --git a/drivers/media/platform/vsp1/vsp1_uif.c
> > b/drivers/media/platform/vsp1/vsp1_uif.c new file mode 100644
> > index 000000000000..6de7e9c801ae
> > --- /dev/null
> > +++ b/drivers/media/platform/vsp1/vsp1_uif.c
> > @@ -0,0 +1,271 @@

[snip]

> > +static void uif_configure(struct vsp1_entity *entity,
> > +			  struct vsp1_pipeline *pipe,
> > +			  struct vsp1_dl_list *dl,
> > +			  enum vsp1_entity_params params)
> > +{
> > +	struct vsp1_uif *uif = to_uif(&entity->subdev);
> > +	const struct v4l2_rect *crop;
> > +	unsigned int left;
> > +	unsigned int width;
> > +
> > +	/*
> > +	 * Per-partition configuration isn't needed as the DISCOM is used in
> > +	 * display pipelines only.
> > +	 */
> > +	if (params != VSP1_ENTITY_PARAMS_INIT)
> > +		return;
> > +
> > +	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMPMR,
> > +		       VI6_UIF_DISCOM_DOCMPMR_SEL(9));
> > +
> > +	crop = vsp1_entity_get_pad_selection(entity, entity->config,
> > +					     UIF_PAD_SINK, V4L2_SEL_TGT_CROP);
> > +
> > +	/* On M3-W the horizontal coordinates are twice the register value. */
> > +	if (uif->m3w_quirk) {
> > +		left = crop->left / 2;
> > +		width = crop->width / 2;
> > +	} else {
> > +		left = crop->left;
> > +		width = crop->width;
> > +	}
> 
> I would write this as
> 
>         left = crop->left;
>         width = crop->width;
> 	/* On M3-W the horizontal coordinates are twice the register value. */
> 	if (uif->m3w_quirk) {
> 		left /= 2;
> 		width /= 2;
>         }
> 
> But that's really up to you.

I prefer my style, but it looks like gcc 6.4.0 generates slightly better code 
with your version (due to the fact that the crop->left value is converted to 
unsigned before being divided by 2), so I'll go for it.

> > +
> > +	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMSPXR, left);
> > +	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMSPYR, crop->top);
> > +	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMSZXR, width);
> > +	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMSZYR, crop->height);
> > +
> > +	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMCR,
> > +		       VI6_UIF_DISCOM_DOCMCR_CMPR);
> > +}
> > +
> > +static const struct vsp1_entity_operations uif_entity_ops = {
> > +	.configure = uif_configure,
> > +};
> > +
> > +/* ----------------------------------------------------------------------
> > + * Initialization and Cleanup
> > + */
> > +
> > +static const struct soc_device_attribute vsp1_r8a7796[] = {
> > +	{ .soc_id = "r8a7796" },
> > +	{ /* sentinel */ }
> > +};
> > +
> > +struct vsp1_uif *vsp1_uif_create(struct vsp1_device *vsp1, unsigned int
> > index) +{
> > +	struct vsp1_uif *uif;
> > +	char name[6];
> > +	int ret;
> > +
> > +	uif = devm_kzalloc(vsp1->dev, sizeof(*uif), GFP_KERNEL);
> > +	if (uif == NULL)
> 
>         if (!uif)
> 
> Otherwise checkpatch complains iirc.

Only when run with --strict.

Nevertheless, even if both styles are mixed in the driver, the predominant 
style is !uif, so I'll switch to that.

> Those are very minor comments, so feel free to add my reviewed by tag
> 
> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
> 
> > +		return ERR_PTR(-ENOMEM);
> > +
> > +	if (soc_device_match(vsp1_r8a7796))
> > +		uif->m3w_quirk = true;
> > +
> > +	uif->entity.ops = &uif_entity_ops;
> > +	uif->entity.type = VSP1_ENTITY_UIF;
> > +	uif->entity.index = index;
> > +
> > +	/* The datasheet names the two UIF instances UIF4 and UIF5. */
> > +	sprintf(name, "uif.%u", index + 4);
> > +	ret = vsp1_entity_init(vsp1, &uif->entity, name, 2, &uif_ops,
> > +			       MEDIA_ENT_F_PROC_VIDEO_STATISTICS);
> > +	if (ret < 0)
> > +		return ERR_PTR(ret);
> > +
> > +	return uif;
> > +}

[snip]

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v2 6/8] v4l: vsp1: Add support for the DISCOM entity
@ 2018-04-28 16:50       ` Laurent Pinchart
  0 siblings, 0 replies; 82+ messages in thread
From: Laurent Pinchart @ 2018-04-28 16:50 UTC (permalink / raw)
  To: jacopo mondi
  Cc: linux-renesas-soc, Laurent Pinchart, Kieran Bingham, dri-devel,
	linux-media

Hi Jacopo,

On Saturday, 28 April 2018 13:40:02 EEST jacopo mondi wrote:
> HI Laurent,
>    a few comments, mostly minor ones...
> 
> On Mon, Apr 23, 2018 at 01:34:28AM +0300, Laurent Pinchart wrote:
> > The DISCOM calculates a CRC on a configurable window of the frame. It
> > interfaces to the VSP through the UIF glue, hence the name used in the
> > code.
> > 
> > The module supports configuration of the CRC window through the crop
> > rectangle on the ink pad of the corresponding entity. However, unlike
> 
> sink pad?

Oops. Consider it fixed.

> > the traditional V4L2 subdevice model, the crop rectangle does not
> > influence the format on the source pad.
> > 
> > Modeling the DISCOM as a sink-only entity would allow adhering to the
> > V4L2 subdevice model at the expense of more complex code in the driver,
> > as at the hardware level the UIF is handled as a sink+source entity. As
> > the DISCOM is only present in R-Car Gen3 VSP-D and VSP-DL instances it
> > is not exposed to userspace through V4L2 but controlled through the DU
> > driver. We can thus change this model later if needed without fear of
> > affecting userspace.
> > 
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com>
> > ---
> > Changes since v1:
> > 
> > - Don't return uninitialized value from uif_set_selection()
> > ---
> > 
> >  drivers/media/platform/vsp1/Makefile      |   2 +-
> >  drivers/media/platform/vsp1/vsp1.h        |   4 +
> >  drivers/media/platform/vsp1/vsp1_drv.c    |  20 +++
> >  drivers/media/platform/vsp1/vsp1_entity.c |   6 +
> >  drivers/media/platform/vsp1/vsp1_entity.h |   1 +
> >  drivers/media/platform/vsp1/vsp1_regs.h   |  41 +++++
> >  drivers/media/platform/vsp1/vsp1_uif.c    | 271 +++++++++++++++++++++++++
> >  drivers/media/platform/vsp1/vsp1_uif.h    |  32 ++++
> >  8 files changed, 376 insertions(+), 1 deletion(-)
> >  create mode 100644 drivers/media/platform/vsp1/vsp1_uif.c
> >  create mode 100644 drivers/media/platform/vsp1/vsp1_uif.h

[snip]

> > diff --git a/drivers/media/platform/vsp1/vsp1_uif.c
> > b/drivers/media/platform/vsp1/vsp1_uif.c new file mode 100644
> > index 000000000000..6de7e9c801ae
> > --- /dev/null
> > +++ b/drivers/media/platform/vsp1/vsp1_uif.c
> > @@ -0,0 +1,271 @@

[snip]

> > +static void uif_configure(struct vsp1_entity *entity,
> > +			  struct vsp1_pipeline *pipe,
> > +			  struct vsp1_dl_list *dl,
> > +			  enum vsp1_entity_params params)
> > +{
> > +	struct vsp1_uif *uif = to_uif(&entity->subdev);
> > +	const struct v4l2_rect *crop;
> > +	unsigned int left;
> > +	unsigned int width;
> > +
> > +	/*
> > +	 * Per-partition configuration isn't needed as the DISCOM is used in
> > +	 * display pipelines only.
> > +	 */
> > +	if (params != VSP1_ENTITY_PARAMS_INIT)
> > +		return;
> > +
> > +	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMPMR,
> > +		       VI6_UIF_DISCOM_DOCMPMR_SEL(9));
> > +
> > +	crop = vsp1_entity_get_pad_selection(entity, entity->config,
> > +					     UIF_PAD_SINK, V4L2_SEL_TGT_CROP);
> > +
> > +	/* On M3-W the horizontal coordinates are twice the register value. */
> > +	if (uif->m3w_quirk) {
> > +		left = crop->left / 2;
> > +		width = crop->width / 2;
> > +	} else {
> > +		left = crop->left;
> > +		width = crop->width;
> > +	}
> 
> I would write this as
> 
>         left = crop->left;
>         width = crop->width;
> 	/* On M3-W the horizontal coordinates are twice the register value. */
> 	if (uif->m3w_quirk) {
> 		left /= 2;
> 		width /= 2;
>         }
> 
> But that's really up to you.

I prefer my style, but it looks like gcc 6.4.0 generates slightly better code 
with your version (due to the fact that the crop->left value is converted to 
unsigned before being divided by 2), so I'll go for it.

> > +
> > +	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMSPXR, left);
> > +	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMSPYR, crop->top);
> > +	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMSZXR, width);
> > +	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMSZYR, crop->height);
> > +
> > +	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMCR,
> > +		       VI6_UIF_DISCOM_DOCMCR_CMPR);
> > +}
> > +
> > +static const struct vsp1_entity_operations uif_entity_ops = {
> > +	.configure = uif_configure,
> > +};
> > +
> > +/* ----------------------------------------------------------------------
> > + * Initialization and Cleanup
> > + */
> > +
> > +static const struct soc_device_attribute vsp1_r8a7796[] = {
> > +	{ .soc_id = "r8a7796" },
> > +	{ /* sentinel */ }
> > +};
> > +
> > +struct vsp1_uif *vsp1_uif_create(struct vsp1_device *vsp1, unsigned int
> > index) +{
> > +	struct vsp1_uif *uif;
> > +	char name[6];
> > +	int ret;
> > +
> > +	uif = devm_kzalloc(vsp1->dev, sizeof(*uif), GFP_KERNEL);
> > +	if (uif == NULL)
> 
>         if (!uif)
> 
> Otherwise checkpatch complains iirc.

Only when run with --strict.

Nevertheless, even if both styles are mixed in the driver, the predominant 
style is !uif, so I'll switch to that.

> Those are very minor comments, so feel free to add my reviewed by tag
> 
> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
> 
> > +		return ERR_PTR(-ENOMEM);
> > +
> > +	if (soc_device_match(vsp1_r8a7796))
> > +		uif->m3w_quirk = true;
> > +
> > +	uif->entity.ops = &uif_entity_ops;
> > +	uif->entity.type = VSP1_ENTITY_UIF;
> > +	uif->entity.index = index;
> > +
> > +	/* The datasheet names the two UIF instances UIF4 and UIF5. */
> > +	sprintf(name, "uif.%u", index + 4);
> > +	ret = vsp1_entity_init(vsp1, &uif->entity, name, 2, &uif_ops,
> > +			       MEDIA_ENT_F_PROC_VIDEO_STATISTICS);
> > +	if (ret < 0)
> > +		return ERR_PTR(ret);
> > +
> > +	return uif;
> > +}

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

* Re: [PATCH v2 7/8] v4l: vsp1: Integrate DISCOM in display pipeline
  2018-04-28 11:00     ` jacopo mondi
@ 2018-04-28 16:57       ` Laurent Pinchart
  -1 siblings, 0 replies; 82+ messages in thread
From: Laurent Pinchart @ 2018-04-28 16:57 UTC (permalink / raw)
  To: jacopo mondi
  Cc: Laurent Pinchart, linux-media, dri-devel, linux-renesas-soc,
	Kieran Bingham

Hi Jacopo,

On Saturday, 28 April 2018 14:00:26 EEST jacopo mondi wrote:
> On Mon, Apr 23, 2018 at 01:34:29AM +0300, Laurent Pinchart wrote:
> > The DISCOM is used to compute CRCs on display frames. Integrate it in
> > the display pipeline at the output of the blending unit to process
> > output frames.
> > 
> > Computing CRCs on input frames is possible by positioning the DISCOM at
> > a different point in the pipeline. This use case isn't supported at the
> > moment and could be implemented by extending the API between the VSP1
> > and DU drivers if needed.
> > 
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com>
> > ---
> > 
> >  drivers/media/platform/vsp1/vsp1_drm.c | 115 +++++++++++++++++++++++++++-
> >  drivers/media/platform/vsp1/vsp1_drm.h |  12 ++++
> >  2 files changed, 124 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/media/platform/vsp1/vsp1_drm.c
> > b/drivers/media/platform/vsp1/vsp1_drm.c index 5fc31578f9b0..7864b43a90e1
> > 100644
> > --- a/drivers/media/platform/vsp1/vsp1_drm.c
> > +++ b/drivers/media/platform/vsp1/vsp1_drm.c

[snip]

> > @@ -48,10 +54,65 @@ static void vsp1_du_pipeline_frame_end(struct
> > vsp1_pipeline *pipe,> 
> >   * Pipeline Configuration
> >   */
> > 
> > +/*
> > + * Insert the UIF in the pipeline between the prev and next entities. If
> > no UIF + * is available connect the two entities directly.
> > + */
> > +static int vsp1_du_insert_uif(struct vsp1_device *vsp1,
> > +			      struct vsp1_pipeline *pipe,
> > +			      struct vsp1_entity *uif,
> > +			      struct vsp1_entity *prev, unsigned int prev_pad,
> > +			      struct vsp1_entity *next, unsigned int next_pad)
> > +{
> > +	int ret;
> > +
> > +	if (uif) {
> > +		struct v4l2_subdev_format format;
> > +
> > +		prev->sink = uif;
> > +		prev->sink_pad = UIF_PAD_SINK;
> > +
> > +		memset(&format, 0, sizeof(format));
> > +		format.which = V4L2_SUBDEV_FORMAT_ACTIVE;
> > +		format.pad = prev_pad;
> > +
> > +		ret = v4l2_subdev_call(&prev->subdev, pad, get_fmt, NULL,
> > +				       &format);
> > +		if (ret < 0)
> > +			return ret;
> > +
> > +		format.pad = UIF_PAD_SINK;
> > +
> > +		ret = v4l2_subdev_call(&uif->subdev, pad, set_fmt, NULL,
> > +				       &format);
> > +		if (ret < 0)
> > +			return ret;
> > +
> > +		dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on UIF sink\n",
> > +			__func__, format.format.width, format.format.height,
> > +			format.format.code);
> > +
> > +		/*
> > +		 * The UIF doesn't mangle the format between its sink and
> > +		 * source pads, so there is no need to retrieve the format on
> > +		 * its source pad.
> > +		 */
> > +
> > +		uif->sink = next;
> > +		uif->sink_pad = next_pad;
> > +	} else {
> > +		prev->sink = next;
> > +		prev->sink_pad = next_pad;
> 
> Isn't the !uif case better handled in the caller? See below...
> Or otherwise, if you prefer handling it here, shouldn't the
> indentation be reduced with

I don't think it's better handled in the caller, I prefer keeping the entities 
linking code in a single place. I'll reduce the indentation.

>         if (!uif) {
> 		prev->sink = next;
> 		prev->sink_pad = next_pad;
>                 return 0;
>         }
> 
> > +	}
> > +
> > +	return 0;
> > +}

[snip]

> > @@ -367,6 +441,31 @@ static int vsp1_du_pipeline_setup_inputs(struct
> > vsp1_device *vsp1,
> >  		}
> >  	}
> > 
> > +	/* Insert and configure the UIF at the BRx output if available. */
> > +	uif = drm_pipe->crc.source == VSP1_DU_CRC_OUTPUT ? drm_pipe->uif : 
NULL;
> > +	if (uif)
> > +		use_uif = true;
> > +	ret = vsp1_du_insert_uif(vsp1, pipe, uif,
> > +				 pipe->brx, pipe->brx->source_pad,
> > +				 &pipe->output->entity, 0);
> > +	if (ret < 0)
> > +		dev_err(vsp1->dev, "%s: failed to setup UIF after %s\n",
> > +			__func__, BRX_NAME(pipe->brx));
> > +
> > +	/*
> > +	 * If the UIF is not in use schedule it for removal by setting its pipe
> > +	 * pointer to NULL, vsp1_du_pipeline_configure() will remove it from 
the
> > +	 * hardware pipeline and from the pipeline's list of entities. 
Otherwise
> > +	 * make sure it is present in the pipeline's list of entities if it
> > +	 * wasn't already.
> > +	 */
> > +	if (!use_uif) {
> 
> ... here. If you don't use uif, don't call vspi1_du_insert_uif().
> True, you have to link entities explicitly here if there is not uif,
> but I may be missing where this was happening before this code was
> added.
> 
> > +		drm_pipe->uif->pipe = NULL;
> > +	} else if (!drm_pipe->uif->pipe) {
> > +		drm_pipe->uif->pipe = pipe;
> > +		list_add_tail(&drm_pipe->uif->list_pipe, &pipe->entities);
> > +	}
> > +
> >  	return 0;
> >  }
> > 
> > @@ -748,6 +847,9 @@ void vsp1_du_atomic_flush(struct device *dev, unsigned
> > int pipe_index,> 
> >  	struct vsp1_drm_pipeline *drm_pipe = &vsp1->drm->pipe[pipe_index];
> >  	struct vsp1_pipeline *pipe = &drm_pipe->pipe;
> > 
> > +	drm_pipe->crc.source = cfg->crc.source;
> > +	drm_pipe->crc.index = cfg->crc.index;
> > +
> >  	vsp1_du_pipeline_setup_inputs(vsp1, pipe);
> >  	vsp1_du_pipeline_configure(pipe);
> >  	mutex_unlock(&vsp1->drm->lock);
> > @@ -816,6 +918,13 @@ int vsp1_drm_init(struct vsp1_device *vsp1)
> > 
> >  		pipe->lif->pipe = pipe;
> >  		list_add_tail(&pipe->lif->list_pipe, &pipe->entities);
> > +
> > +		/*
> > +		 * CRC computation is initially disabled, don't add the UIF to
> > +		 * the pipeline.
> > +		 */
> > +		if (i < vsp1->info->uif_count)
> 
> Why 'initially disabled'? This seems to me to conditionally enable the
> UIF unit. Or is the lif count always the same as the uif count?

Setting drm_pipe->uif isn't adding the UIF to the pipeline, that would be done 
by adding it to the pipe->entities list and setting the uif->pipe pointer.

> > +			drm_pipe->uif = &vsp1->uif[i]->entity;
> >  	}

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v2 7/8] v4l: vsp1: Integrate DISCOM in display pipeline
@ 2018-04-28 16:57       ` Laurent Pinchart
  0 siblings, 0 replies; 82+ messages in thread
From: Laurent Pinchart @ 2018-04-28 16:57 UTC (permalink / raw)
  To: jacopo mondi
  Cc: linux-renesas-soc, Laurent Pinchart, Kieran Bingham, dri-devel,
	linux-media

Hi Jacopo,

On Saturday, 28 April 2018 14:00:26 EEST jacopo mondi wrote:
> On Mon, Apr 23, 2018 at 01:34:29AM +0300, Laurent Pinchart wrote:
> > The DISCOM is used to compute CRCs on display frames. Integrate it in
> > the display pipeline at the output of the blending unit to process
> > output frames.
> > 
> > Computing CRCs on input frames is possible by positioning the DISCOM at
> > a different point in the pipeline. This use case isn't supported at the
> > moment and could be implemented by extending the API between the VSP1
> > and DU drivers if needed.
> > 
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com>
> > ---
> > 
> >  drivers/media/platform/vsp1/vsp1_drm.c | 115 +++++++++++++++++++++++++++-
> >  drivers/media/platform/vsp1/vsp1_drm.h |  12 ++++
> >  2 files changed, 124 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/media/platform/vsp1/vsp1_drm.c
> > b/drivers/media/platform/vsp1/vsp1_drm.c index 5fc31578f9b0..7864b43a90e1
> > 100644
> > --- a/drivers/media/platform/vsp1/vsp1_drm.c
> > +++ b/drivers/media/platform/vsp1/vsp1_drm.c

[snip]

> > @@ -48,10 +54,65 @@ static void vsp1_du_pipeline_frame_end(struct
> > vsp1_pipeline *pipe,> 
> >   * Pipeline Configuration
> >   */
> > 
> > +/*
> > + * Insert the UIF in the pipeline between the prev and next entities. If
> > no UIF + * is available connect the two entities directly.
> > + */
> > +static int vsp1_du_insert_uif(struct vsp1_device *vsp1,
> > +			      struct vsp1_pipeline *pipe,
> > +			      struct vsp1_entity *uif,
> > +			      struct vsp1_entity *prev, unsigned int prev_pad,
> > +			      struct vsp1_entity *next, unsigned int next_pad)
> > +{
> > +	int ret;
> > +
> > +	if (uif) {
> > +		struct v4l2_subdev_format format;
> > +
> > +		prev->sink = uif;
> > +		prev->sink_pad = UIF_PAD_SINK;
> > +
> > +		memset(&format, 0, sizeof(format));
> > +		format.which = V4L2_SUBDEV_FORMAT_ACTIVE;
> > +		format.pad = prev_pad;
> > +
> > +		ret = v4l2_subdev_call(&prev->subdev, pad, get_fmt, NULL,
> > +				       &format);
> > +		if (ret < 0)
> > +			return ret;
> > +
> > +		format.pad = UIF_PAD_SINK;
> > +
> > +		ret = v4l2_subdev_call(&uif->subdev, pad, set_fmt, NULL,
> > +				       &format);
> > +		if (ret < 0)
> > +			return ret;
> > +
> > +		dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on UIF sink\n",
> > +			__func__, format.format.width, format.format.height,
> > +			format.format.code);
> > +
> > +		/*
> > +		 * The UIF doesn't mangle the format between its sink and
> > +		 * source pads, so there is no need to retrieve the format on
> > +		 * its source pad.
> > +		 */
> > +
> > +		uif->sink = next;
> > +		uif->sink_pad = next_pad;
> > +	} else {
> > +		prev->sink = next;
> > +		prev->sink_pad = next_pad;
> 
> Isn't the !uif case better handled in the caller? See below...
> Or otherwise, if you prefer handling it here, shouldn't the
> indentation be reduced with

I don't think it's better handled in the caller, I prefer keeping the entities 
linking code in a single place. I'll reduce the indentation.

>         if (!uif) {
> 		prev->sink = next;
> 		prev->sink_pad = next_pad;
>                 return 0;
>         }
> 
> > +	}
> > +
> > +	return 0;
> > +}

[snip]

> > @@ -367,6 +441,31 @@ static int vsp1_du_pipeline_setup_inputs(struct
> > vsp1_device *vsp1,
> >  		}
> >  	}
> > 
> > +	/* Insert and configure the UIF at the BRx output if available. */
> > +	uif = drm_pipe->crc.source == VSP1_DU_CRC_OUTPUT ? drm_pipe->uif : 
NULL;
> > +	if (uif)
> > +		use_uif = true;
> > +	ret = vsp1_du_insert_uif(vsp1, pipe, uif,
> > +				 pipe->brx, pipe->brx->source_pad,
> > +				 &pipe->output->entity, 0);
> > +	if (ret < 0)
> > +		dev_err(vsp1->dev, "%s: failed to setup UIF after %s\n",
> > +			__func__, BRX_NAME(pipe->brx));
> > +
> > +	/*
> > +	 * If the UIF is not in use schedule it for removal by setting its pipe
> > +	 * pointer to NULL, vsp1_du_pipeline_configure() will remove it from 
the
> > +	 * hardware pipeline and from the pipeline's list of entities. 
Otherwise
> > +	 * make sure it is present in the pipeline's list of entities if it
> > +	 * wasn't already.
> > +	 */
> > +	if (!use_uif) {
> 
> ... here. If you don't use uif, don't call vspi1_du_insert_uif().
> True, you have to link entities explicitly here if there is not uif,
> but I may be missing where this was happening before this code was
> added.
> 
> > +		drm_pipe->uif->pipe = NULL;
> > +	} else if (!drm_pipe->uif->pipe) {
> > +		drm_pipe->uif->pipe = pipe;
> > +		list_add_tail(&drm_pipe->uif->list_pipe, &pipe->entities);
> > +	}
> > +
> >  	return 0;
> >  }
> > 
> > @@ -748,6 +847,9 @@ void vsp1_du_atomic_flush(struct device *dev, unsigned
> > int pipe_index,> 
> >  	struct vsp1_drm_pipeline *drm_pipe = &vsp1->drm->pipe[pipe_index];
> >  	struct vsp1_pipeline *pipe = &drm_pipe->pipe;
> > 
> > +	drm_pipe->crc.source = cfg->crc.source;
> > +	drm_pipe->crc.index = cfg->crc.index;
> > +
> >  	vsp1_du_pipeline_setup_inputs(vsp1, pipe);
> >  	vsp1_du_pipeline_configure(pipe);
> >  	mutex_unlock(&vsp1->drm->lock);
> > @@ -816,6 +918,13 @@ int vsp1_drm_init(struct vsp1_device *vsp1)
> > 
> >  		pipe->lif->pipe = pipe;
> >  		list_add_tail(&pipe->lif->list_pipe, &pipe->entities);
> > +
> > +		/*
> > +		 * CRC computation is initially disabled, don't add the UIF to
> > +		 * the pipeline.
> > +		 */
> > +		if (i < vsp1->info->uif_count)
> 
> Why 'initially disabled'? This seems to me to conditionally enable the
> UIF unit. Or is the lif count always the same as the uif count?

Setting drm_pipe->uif isn't adding the UIF to the pipeline, that would be done 
by adding it to the pipe->entities list and setting the uif->pipe pointer.

> > +			drm_pipe->uif = &vsp1->uif[i]->entity;
> >  	}

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

* Re: [PATCH v2 2/8] v4l: vsp1: Share the CLU, LIF and LUT set_fmt pad operation code
  2018-04-22 22:34   ` Laurent Pinchart
@ 2018-04-28 17:16     ` Kieran Bingham
  -1 siblings, 0 replies; 82+ messages in thread
From: Kieran Bingham @ 2018-04-28 17:16 UTC (permalink / raw)
  To: Laurent Pinchart, linux-media, dri-devel; +Cc: linux-renesas-soc


[-- Attachment #1.1: Type: text/plain, Size: 14241 bytes --]

Hi Laurent,

On 22/04/18 23:34, Laurent Pinchart wrote:
> The implementation of the set_fmt pad operation is identical in the
> three modules. Move it to a generic helper function.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

Only a minor pair of comments below regarding source/sink pad descriptions.

If it's not convenient/accurate to define these with an enum then don't worry
about it.

Otherwise,

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

> ---
>  drivers/media/platform/vsp1/vsp1_clu.c    | 65 +++++----------------------
>  drivers/media/platform/vsp1/vsp1_entity.c | 75 +++++++++++++++++++++++++++++++
>  drivers/media/platform/vsp1/vsp1_entity.h |  6 +++
>  drivers/media/platform/vsp1/vsp1_lif.c    | 65 +++++----------------------
>  drivers/media/platform/vsp1/vsp1_lut.c    | 65 +++++----------------------
>  5 files changed, 116 insertions(+), 160 deletions(-)

That's a nice diffstat :-)


> 
> diff --git a/drivers/media/platform/vsp1/vsp1_clu.c b/drivers/media/platform/vsp1/vsp1_clu.c
> index 9626b6308585..96a448e1504c 100644
> --- a/drivers/media/platform/vsp1/vsp1_clu.c
> +++ b/drivers/media/platform/vsp1/vsp1_clu.c
> @@ -114,18 +114,18 @@ static const struct v4l2_ctrl_config clu_mode_control = {
>   * V4L2 Subdevice Pad Operations
>   */
>  
> +static const unsigned int clu_codes[] = {
> +	MEDIA_BUS_FMT_ARGB8888_1X32,
> +	MEDIA_BUS_FMT_AHSV8888_1X32,
> +	MEDIA_BUS_FMT_AYUV8_1X32,
> +};
> +
>  static int clu_enum_mbus_code(struct v4l2_subdev *subdev,
>  			      struct v4l2_subdev_pad_config *cfg,
>  			      struct v4l2_subdev_mbus_code_enum *code)
>  {
> -	static const unsigned int codes[] = {
> -		MEDIA_BUS_FMT_ARGB8888_1X32,
> -		MEDIA_BUS_FMT_AHSV8888_1X32,
> -		MEDIA_BUS_FMT_AYUV8_1X32,
> -	};
> -
> -	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, codes,
> -					  ARRAY_SIZE(codes));
> +	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, clu_codes,
> +					  ARRAY_SIZE(clu_codes));
>  }
>  
>  static int clu_enum_frame_size(struct v4l2_subdev *subdev,
> @@ -141,51 +141,10 @@ static int clu_set_format(struct v4l2_subdev *subdev,
>  			  struct v4l2_subdev_pad_config *cfg,
>  			  struct v4l2_subdev_format *fmt)
>  {
> -	struct vsp1_clu *clu = to_clu(subdev);
> -	struct v4l2_subdev_pad_config *config;
> -	struct v4l2_mbus_framefmt *format;
> -	int ret = 0;
> -
> -	mutex_lock(&clu->entity.lock);
> -
> -	config = vsp1_entity_get_pad_config(&clu->entity, cfg, fmt->which);
> -	if (!config) {
> -		ret = -EINVAL;
> -		goto done;
> -	}
> -
> -	/* Default to YUV if the requested format is not supported. */
> -	if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
> -	    fmt->format.code != MEDIA_BUS_FMT_AHSV8888_1X32 &&
> -	    fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32)
> -		fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32;
> -
> -	format = vsp1_entity_get_pad_format(&clu->entity, config, fmt->pad);
> -
> -	if (fmt->pad == CLU_PAD_SOURCE) {
> -		/* The CLU output format can't be modified. */
> -		fmt->format = *format;
> -		goto done;
> -	}
> -
> -	format->code = fmt->format.code;
> -	format->width = clamp_t(unsigned int, fmt->format.width,
> -				CLU_MIN_SIZE, CLU_MAX_SIZE);
> -	format->height = clamp_t(unsigned int, fmt->format.height,
> -				 CLU_MIN_SIZE, CLU_MAX_SIZE);
> -	format->field = V4L2_FIELD_NONE;
> -	format->colorspace = V4L2_COLORSPACE_SRGB;
> -
> -	fmt->format = *format;
> -
> -	/* Propagate the format to the source pad. */
> -	format = vsp1_entity_get_pad_format(&clu->entity, config,
> -					    CLU_PAD_SOURCE);
> -	*format = fmt->format;
> -
> -done:
> -	mutex_unlock(&clu->entity.lock);
> -	return ret;
> +	return vsp1_subdev_set_pad_format(subdev, cfg, fmt, clu_codes,
> +					  ARRAY_SIZE(clu_codes),
> +					  CLU_MIN_SIZE, CLU_MIN_SIZE,
> +					  CLU_MAX_SIZE, CLU_MAX_SIZE);
>  }
>  
>  /* -----------------------------------------------------------------------------
> diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c
> index 72354caf5746..239df047efd0 100644
> --- a/drivers/media/platform/vsp1/vsp1_entity.c
> +++ b/drivers/media/platform/vsp1/vsp1_entity.c
> @@ -307,6 +307,81 @@ int vsp1_subdev_enum_frame_size(struct v4l2_subdev *subdev,
>  	return ret;
>  }
>  
> +/*
> + * vsp1_subdev_set_pad_format - Subdev pad set_fmt handler
> + * @subdev: V4L2 subdevice
> + * @cfg: V4L2 subdev pad configuration
> + * @fmt: V4L2 subdev format
> + * @codes: Array of supported media bus codes
> + * @ncodes: Number of supported media bus codes
> + * @min_width: Minimum image width
> + * @min_height: Minimum image height
> + * @max_width: Maximum image width
> + * @max_height: Maximum image height
> + *
> + * This function implements the subdev set_fmt pad operation for entities that
> + * do not support scaling or cropping. It defaults to the first supplied media
> + * bus code if the requested code isn't supported, clamps the size to the
> + * supplied minimum and maximum, and propagates the sink pad format to the
> + * source pad.
> + */
> +int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev,
> +			       struct v4l2_subdev_pad_config *cfg,
> +			       struct v4l2_subdev_format *fmt,
> +			       const unsigned int *codes, unsigned int ncodes,
> +			       unsigned int min_width, unsigned int min_height,
> +			       unsigned int max_width, unsigned int max_height)
> +{
> +	struct vsp1_entity *entity = to_vsp1_entity(subdev);
> +	struct v4l2_subdev_pad_config *config;
> +	struct v4l2_mbus_framefmt *format;
> +	unsigned int i;
> +	int ret = 0;
> +
> +	mutex_lock(&entity->lock);
> +
> +	config = vsp1_entity_get_pad_config(entity, cfg, fmt->which);
> +	if (!config) {
> +		ret = -EINVAL;
> +		goto done;
> +	}
> +
> +	format = vsp1_entity_get_pad_format(entity, config, fmt->pad);
> +
> +	if (fmt->pad != 0) {

I guess we don't have any clear way to say != *_PAD_SINK here do we ..

> +		/* The output format can't be modified. */
> +		fmt->format = *format;
> +		goto done;
> +	}
> +
> +	/*
> +	 * Default to the first media bus code if the requested format is not
> +	 * supported.
> +	 */
> +	for (i = 0; i < ncodes; ++i) {
> +		if (fmt->format.code == codes[i])
> +			break;
> +	}
> +
> +	format->code = i < ncodes ? codes[i] : codes[0];
> +	format->width = clamp_t(unsigned int, fmt->format.width,
> +				min_width, max_width);
> +	format->height = clamp_t(unsigned int, fmt->format.height,
> +				 min_height, max_height);
> +	format->field = V4L2_FIELD_NONE;
> +	format->colorspace = V4L2_COLORSPACE_SRGB;
> +
> +	fmt->format = *format;
> +
> +	/* Propagate the format to the source pad. */
> +	format = vsp1_entity_get_pad_format(entity, config, 1);

If we can guarantee that ENTITY_PAD_SINK == 0 and ENTITY_PAD_SOURCE == 1, can we
put those into an enum ?


> +	*format = fmt->format;
> +
> +done:
> +	mutex_unlock(&entity->lock);
> +	return ret;
> +}
> +
>  /* -----------------------------------------------------------------------------
>   * Media Operations
>   */
> diff --git a/drivers/media/platform/vsp1/vsp1_entity.h b/drivers/media/platform/vsp1/vsp1_entity.h
> index fb20a1578f3b..0839a62cfa71 100644
> --- a/drivers/media/platform/vsp1/vsp1_entity.h
> +++ b/drivers/media/platform/vsp1/vsp1_entity.h
> @@ -160,6 +160,12 @@ struct media_pad *vsp1_entity_remote_pad(struct media_pad *pad);
>  int vsp1_subdev_get_pad_format(struct v4l2_subdev *subdev,
>  			       struct v4l2_subdev_pad_config *cfg,
>  			       struct v4l2_subdev_format *fmt);
> +int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev,
> +			       struct v4l2_subdev_pad_config *cfg,
> +			       struct v4l2_subdev_format *fmt,
> +			       const unsigned int *codes, unsigned int ncodes,
> +			       unsigned int min_width, unsigned int min_height,
> +			       unsigned int max_width, unsigned int max_height);
>  int vsp1_subdev_enum_mbus_code(struct v4l2_subdev *subdev,
>  			       struct v4l2_subdev_pad_config *cfg,
>  			       struct v4l2_subdev_mbus_code_enum *code,
> diff --git a/drivers/media/platform/vsp1/vsp1_lif.c b/drivers/media/platform/vsp1/vsp1_lif.c
> index b20b842f06ba..fbdd5715f829 100644
> --- a/drivers/media/platform/vsp1/vsp1_lif.c
> +++ b/drivers/media/platform/vsp1/vsp1_lif.c
> @@ -33,17 +33,17 @@ static inline void vsp1_lif_write(struct vsp1_lif *lif, struct vsp1_dl_list *dl,
>   * V4L2 Subdevice Operations
>   */
>  
> +static const unsigned int lif_codes[] = {
> +	MEDIA_BUS_FMT_ARGB8888_1X32,
> +	MEDIA_BUS_FMT_AYUV8_1X32,
> +};
> +
>  static int lif_enum_mbus_code(struct v4l2_subdev *subdev,
>  			      struct v4l2_subdev_pad_config *cfg,
>  			      struct v4l2_subdev_mbus_code_enum *code)
>  {
> -	static const unsigned int codes[] = {
> -		MEDIA_BUS_FMT_ARGB8888_1X32,
> -		MEDIA_BUS_FMT_AYUV8_1X32,
> -	};
> -
> -	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, codes,
> -					  ARRAY_SIZE(codes));
> +	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, lif_codes,
> +					  ARRAY_SIZE(lif_codes));
>  }
>  
>  static int lif_enum_frame_size(struct v4l2_subdev *subdev,
> @@ -59,53 +59,10 @@ static int lif_set_format(struct v4l2_subdev *subdev,
>  			  struct v4l2_subdev_pad_config *cfg,
>  			  struct v4l2_subdev_format *fmt)
>  {
> -	struct vsp1_lif *lif = to_lif(subdev);
> -	struct v4l2_subdev_pad_config *config;
> -	struct v4l2_mbus_framefmt *format;
> -	int ret = 0;
> -
> -	mutex_lock(&lif->entity.lock);
> -
> -	config = vsp1_entity_get_pad_config(&lif->entity, cfg, fmt->which);
> -	if (!config) {
> -		ret = -EINVAL;
> -		goto done;
> -	}
> -
> -	/* Default to YUV if the requested format is not supported. */
> -	if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
> -	    fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32)
> -		fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32;
> -
> -	format = vsp1_entity_get_pad_format(&lif->entity, config, fmt->pad);
> -
> -	if (fmt->pad == LIF_PAD_SOURCE) {
> -		/*
> -		 * The LIF source format is always identical to its sink
> -		 * format.
> -		 */
> -		fmt->format = *format;
> -		goto done;
> -	}
> -
> -	format->code = fmt->format.code;
> -	format->width = clamp_t(unsigned int, fmt->format.width,
> -				LIF_MIN_SIZE, LIF_MAX_SIZE);
> -	format->height = clamp_t(unsigned int, fmt->format.height,
> -				 LIF_MIN_SIZE, LIF_MAX_SIZE);
> -	format->field = V4L2_FIELD_NONE;
> -	format->colorspace = V4L2_COLORSPACE_SRGB;
> -
> -	fmt->format = *format;
> -
> -	/* Propagate the format to the source pad. */
> -	format = vsp1_entity_get_pad_format(&lif->entity, config,
> -					    LIF_PAD_SOURCE);
> -	*format = fmt->format;
> -
> -done:
> -	mutex_unlock(&lif->entity.lock);
> -	return ret;
> +	return vsp1_subdev_set_pad_format(subdev, cfg, fmt, lif_codes,
> +					  ARRAY_SIZE(lif_codes),
> +					  LIF_MIN_SIZE, LIF_MIN_SIZE,
> +					  LIF_MAX_SIZE, LIF_MAX_SIZE);
>  }
>  
>  static const struct v4l2_subdev_pad_ops lif_pad_ops = {
> diff --git a/drivers/media/platform/vsp1/vsp1_lut.c b/drivers/media/platform/vsp1/vsp1_lut.c
> index 7bdabb311c6c..f2e48a02ca7d 100644
> --- a/drivers/media/platform/vsp1/vsp1_lut.c
> +++ b/drivers/media/platform/vsp1/vsp1_lut.c
> @@ -90,18 +90,18 @@ static const struct v4l2_ctrl_config lut_table_control = {
>   * V4L2 Subdevice Pad Operations
>   */
>  
> +static const unsigned int lut_codes[] = {
> +	MEDIA_BUS_FMT_ARGB8888_1X32,
> +	MEDIA_BUS_FMT_AHSV8888_1X32,
> +	MEDIA_BUS_FMT_AYUV8_1X32,
> +};
> +
>  static int lut_enum_mbus_code(struct v4l2_subdev *subdev,
>  			      struct v4l2_subdev_pad_config *cfg,
>  			      struct v4l2_subdev_mbus_code_enum *code)
>  {
> -	static const unsigned int codes[] = {
> -		MEDIA_BUS_FMT_ARGB8888_1X32,
> -		MEDIA_BUS_FMT_AHSV8888_1X32,
> -		MEDIA_BUS_FMT_AYUV8_1X32,
> -	};
> -
> -	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, codes,
> -					  ARRAY_SIZE(codes));
> +	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, lut_codes,
> +					  ARRAY_SIZE(lut_codes));
>  }
>  
>  static int lut_enum_frame_size(struct v4l2_subdev *subdev,
> @@ -117,51 +117,10 @@ static int lut_set_format(struct v4l2_subdev *subdev,
>  			  struct v4l2_subdev_pad_config *cfg,
>  			  struct v4l2_subdev_format *fmt)
>  {
> -	struct vsp1_lut *lut = to_lut(subdev);
> -	struct v4l2_subdev_pad_config *config;
> -	struct v4l2_mbus_framefmt *format;
> -	int ret = 0;
> -
> -	mutex_lock(&lut->entity.lock);
> -
> -	config = vsp1_entity_get_pad_config(&lut->entity, cfg, fmt->which);
> -	if (!config) {
> -		ret = -EINVAL;
> -		goto done;
> -	}
> -
> -	/* Default to YUV if the requested format is not supported. */
> -	if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
> -	    fmt->format.code != MEDIA_BUS_FMT_AHSV8888_1X32 &&
> -	    fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32)
> -		fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32;
> -
> -	format = vsp1_entity_get_pad_format(&lut->entity, config, fmt->pad);
> -
> -	if (fmt->pad == LUT_PAD_SOURCE) {
> -		/* The LUT output format can't be modified. */
> -		fmt->format = *format;
> -		goto done;
> -	}
> -
> -	format->code = fmt->format.code;
> -	format->width = clamp_t(unsigned int, fmt->format.width,
> -				LUT_MIN_SIZE, LUT_MAX_SIZE);
> -	format->height = clamp_t(unsigned int, fmt->format.height,
> -				 LUT_MIN_SIZE, LUT_MAX_SIZE);
> -	format->field = V4L2_FIELD_NONE;
> -	format->colorspace = V4L2_COLORSPACE_SRGB;
> -
> -	fmt->format = *format;
> -
> -	/* Propagate the format to the source pad. */
> -	format = vsp1_entity_get_pad_format(&lut->entity, config,
> -					    LUT_PAD_SOURCE);
> -	*format = fmt->format;
> -
> -done:
> -	mutex_unlock(&lut->entity.lock);
> -	return ret;
> +	return vsp1_subdev_set_pad_format(subdev, cfg, fmt, lut_codes,
> +					  ARRAY_SIZE(lut_codes),
> +					  LUT_MIN_SIZE, LUT_MIN_SIZE,
> +					  LUT_MAX_SIZE, LUT_MAX_SIZE);
>  }
>  
>  /* -----------------------------------------------------------------------------
> 


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v2 2/8] v4l: vsp1: Share the CLU, LIF and LUT set_fmt pad operation code
@ 2018-04-28 17:16     ` Kieran Bingham
  0 siblings, 0 replies; 82+ messages in thread
From: Kieran Bingham @ 2018-04-28 17:16 UTC (permalink / raw)
  To: Laurent Pinchart, linux-media, dri-devel; +Cc: linux-renesas-soc


[-- Attachment #1.1.1: Type: text/plain, Size: 14241 bytes --]

Hi Laurent,

On 22/04/18 23:34, Laurent Pinchart wrote:
> The implementation of the set_fmt pad operation is identical in the
> three modules. Move it to a generic helper function.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

Only a minor pair of comments below regarding source/sink pad descriptions.

If it's not convenient/accurate to define these with an enum then don't worry
about it.

Otherwise,

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

> ---
>  drivers/media/platform/vsp1/vsp1_clu.c    | 65 +++++----------------------
>  drivers/media/platform/vsp1/vsp1_entity.c | 75 +++++++++++++++++++++++++++++++
>  drivers/media/platform/vsp1/vsp1_entity.h |  6 +++
>  drivers/media/platform/vsp1/vsp1_lif.c    | 65 +++++----------------------
>  drivers/media/platform/vsp1/vsp1_lut.c    | 65 +++++----------------------
>  5 files changed, 116 insertions(+), 160 deletions(-)

That's a nice diffstat :-)


> 
> diff --git a/drivers/media/platform/vsp1/vsp1_clu.c b/drivers/media/platform/vsp1/vsp1_clu.c
> index 9626b6308585..96a448e1504c 100644
> --- a/drivers/media/platform/vsp1/vsp1_clu.c
> +++ b/drivers/media/platform/vsp1/vsp1_clu.c
> @@ -114,18 +114,18 @@ static const struct v4l2_ctrl_config clu_mode_control = {
>   * V4L2 Subdevice Pad Operations
>   */
>  
> +static const unsigned int clu_codes[] = {
> +	MEDIA_BUS_FMT_ARGB8888_1X32,
> +	MEDIA_BUS_FMT_AHSV8888_1X32,
> +	MEDIA_BUS_FMT_AYUV8_1X32,
> +};
> +
>  static int clu_enum_mbus_code(struct v4l2_subdev *subdev,
>  			      struct v4l2_subdev_pad_config *cfg,
>  			      struct v4l2_subdev_mbus_code_enum *code)
>  {
> -	static const unsigned int codes[] = {
> -		MEDIA_BUS_FMT_ARGB8888_1X32,
> -		MEDIA_BUS_FMT_AHSV8888_1X32,
> -		MEDIA_BUS_FMT_AYUV8_1X32,
> -	};
> -
> -	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, codes,
> -					  ARRAY_SIZE(codes));
> +	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, clu_codes,
> +					  ARRAY_SIZE(clu_codes));
>  }
>  
>  static int clu_enum_frame_size(struct v4l2_subdev *subdev,
> @@ -141,51 +141,10 @@ static int clu_set_format(struct v4l2_subdev *subdev,
>  			  struct v4l2_subdev_pad_config *cfg,
>  			  struct v4l2_subdev_format *fmt)
>  {
> -	struct vsp1_clu *clu = to_clu(subdev);
> -	struct v4l2_subdev_pad_config *config;
> -	struct v4l2_mbus_framefmt *format;
> -	int ret = 0;
> -
> -	mutex_lock(&clu->entity.lock);
> -
> -	config = vsp1_entity_get_pad_config(&clu->entity, cfg, fmt->which);
> -	if (!config) {
> -		ret = -EINVAL;
> -		goto done;
> -	}
> -
> -	/* Default to YUV if the requested format is not supported. */
> -	if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
> -	    fmt->format.code != MEDIA_BUS_FMT_AHSV8888_1X32 &&
> -	    fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32)
> -		fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32;
> -
> -	format = vsp1_entity_get_pad_format(&clu->entity, config, fmt->pad);
> -
> -	if (fmt->pad == CLU_PAD_SOURCE) {
> -		/* The CLU output format can't be modified. */
> -		fmt->format = *format;
> -		goto done;
> -	}
> -
> -	format->code = fmt->format.code;
> -	format->width = clamp_t(unsigned int, fmt->format.width,
> -				CLU_MIN_SIZE, CLU_MAX_SIZE);
> -	format->height = clamp_t(unsigned int, fmt->format.height,
> -				 CLU_MIN_SIZE, CLU_MAX_SIZE);
> -	format->field = V4L2_FIELD_NONE;
> -	format->colorspace = V4L2_COLORSPACE_SRGB;
> -
> -	fmt->format = *format;
> -
> -	/* Propagate the format to the source pad. */
> -	format = vsp1_entity_get_pad_format(&clu->entity, config,
> -					    CLU_PAD_SOURCE);
> -	*format = fmt->format;
> -
> -done:
> -	mutex_unlock(&clu->entity.lock);
> -	return ret;
> +	return vsp1_subdev_set_pad_format(subdev, cfg, fmt, clu_codes,
> +					  ARRAY_SIZE(clu_codes),
> +					  CLU_MIN_SIZE, CLU_MIN_SIZE,
> +					  CLU_MAX_SIZE, CLU_MAX_SIZE);
>  }
>  
>  /* -----------------------------------------------------------------------------
> diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c
> index 72354caf5746..239df047efd0 100644
> --- a/drivers/media/platform/vsp1/vsp1_entity.c
> +++ b/drivers/media/platform/vsp1/vsp1_entity.c
> @@ -307,6 +307,81 @@ int vsp1_subdev_enum_frame_size(struct v4l2_subdev *subdev,
>  	return ret;
>  }
>  
> +/*
> + * vsp1_subdev_set_pad_format - Subdev pad set_fmt handler
> + * @subdev: V4L2 subdevice
> + * @cfg: V4L2 subdev pad configuration
> + * @fmt: V4L2 subdev format
> + * @codes: Array of supported media bus codes
> + * @ncodes: Number of supported media bus codes
> + * @min_width: Minimum image width
> + * @min_height: Minimum image height
> + * @max_width: Maximum image width
> + * @max_height: Maximum image height
> + *
> + * This function implements the subdev set_fmt pad operation for entities that
> + * do not support scaling or cropping. It defaults to the first supplied media
> + * bus code if the requested code isn't supported, clamps the size to the
> + * supplied minimum and maximum, and propagates the sink pad format to the
> + * source pad.
> + */
> +int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev,
> +			       struct v4l2_subdev_pad_config *cfg,
> +			       struct v4l2_subdev_format *fmt,
> +			       const unsigned int *codes, unsigned int ncodes,
> +			       unsigned int min_width, unsigned int min_height,
> +			       unsigned int max_width, unsigned int max_height)
> +{
> +	struct vsp1_entity *entity = to_vsp1_entity(subdev);
> +	struct v4l2_subdev_pad_config *config;
> +	struct v4l2_mbus_framefmt *format;
> +	unsigned int i;
> +	int ret = 0;
> +
> +	mutex_lock(&entity->lock);
> +
> +	config = vsp1_entity_get_pad_config(entity, cfg, fmt->which);
> +	if (!config) {
> +		ret = -EINVAL;
> +		goto done;
> +	}
> +
> +	format = vsp1_entity_get_pad_format(entity, config, fmt->pad);
> +
> +	if (fmt->pad != 0) {

I guess we don't have any clear way to say != *_PAD_SINK here do we ..

> +		/* The output format can't be modified. */
> +		fmt->format = *format;
> +		goto done;
> +	}
> +
> +	/*
> +	 * Default to the first media bus code if the requested format is not
> +	 * supported.
> +	 */
> +	for (i = 0; i < ncodes; ++i) {
> +		if (fmt->format.code == codes[i])
> +			break;
> +	}
> +
> +	format->code = i < ncodes ? codes[i] : codes[0];
> +	format->width = clamp_t(unsigned int, fmt->format.width,
> +				min_width, max_width);
> +	format->height = clamp_t(unsigned int, fmt->format.height,
> +				 min_height, max_height);
> +	format->field = V4L2_FIELD_NONE;
> +	format->colorspace = V4L2_COLORSPACE_SRGB;
> +
> +	fmt->format = *format;
> +
> +	/* Propagate the format to the source pad. */
> +	format = vsp1_entity_get_pad_format(entity, config, 1);

If we can guarantee that ENTITY_PAD_SINK == 0 and ENTITY_PAD_SOURCE == 1, can we
put those into an enum ?


> +	*format = fmt->format;
> +
> +done:
> +	mutex_unlock(&entity->lock);
> +	return ret;
> +}
> +
>  /* -----------------------------------------------------------------------------
>   * Media Operations
>   */
> diff --git a/drivers/media/platform/vsp1/vsp1_entity.h b/drivers/media/platform/vsp1/vsp1_entity.h
> index fb20a1578f3b..0839a62cfa71 100644
> --- a/drivers/media/platform/vsp1/vsp1_entity.h
> +++ b/drivers/media/platform/vsp1/vsp1_entity.h
> @@ -160,6 +160,12 @@ struct media_pad *vsp1_entity_remote_pad(struct media_pad *pad);
>  int vsp1_subdev_get_pad_format(struct v4l2_subdev *subdev,
>  			       struct v4l2_subdev_pad_config *cfg,
>  			       struct v4l2_subdev_format *fmt);
> +int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev,
> +			       struct v4l2_subdev_pad_config *cfg,
> +			       struct v4l2_subdev_format *fmt,
> +			       const unsigned int *codes, unsigned int ncodes,
> +			       unsigned int min_width, unsigned int min_height,
> +			       unsigned int max_width, unsigned int max_height);
>  int vsp1_subdev_enum_mbus_code(struct v4l2_subdev *subdev,
>  			       struct v4l2_subdev_pad_config *cfg,
>  			       struct v4l2_subdev_mbus_code_enum *code,
> diff --git a/drivers/media/platform/vsp1/vsp1_lif.c b/drivers/media/platform/vsp1/vsp1_lif.c
> index b20b842f06ba..fbdd5715f829 100644
> --- a/drivers/media/platform/vsp1/vsp1_lif.c
> +++ b/drivers/media/platform/vsp1/vsp1_lif.c
> @@ -33,17 +33,17 @@ static inline void vsp1_lif_write(struct vsp1_lif *lif, struct vsp1_dl_list *dl,
>   * V4L2 Subdevice Operations
>   */
>  
> +static const unsigned int lif_codes[] = {
> +	MEDIA_BUS_FMT_ARGB8888_1X32,
> +	MEDIA_BUS_FMT_AYUV8_1X32,
> +};
> +
>  static int lif_enum_mbus_code(struct v4l2_subdev *subdev,
>  			      struct v4l2_subdev_pad_config *cfg,
>  			      struct v4l2_subdev_mbus_code_enum *code)
>  {
> -	static const unsigned int codes[] = {
> -		MEDIA_BUS_FMT_ARGB8888_1X32,
> -		MEDIA_BUS_FMT_AYUV8_1X32,
> -	};
> -
> -	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, codes,
> -					  ARRAY_SIZE(codes));
> +	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, lif_codes,
> +					  ARRAY_SIZE(lif_codes));
>  }
>  
>  static int lif_enum_frame_size(struct v4l2_subdev *subdev,
> @@ -59,53 +59,10 @@ static int lif_set_format(struct v4l2_subdev *subdev,
>  			  struct v4l2_subdev_pad_config *cfg,
>  			  struct v4l2_subdev_format *fmt)
>  {
> -	struct vsp1_lif *lif = to_lif(subdev);
> -	struct v4l2_subdev_pad_config *config;
> -	struct v4l2_mbus_framefmt *format;
> -	int ret = 0;
> -
> -	mutex_lock(&lif->entity.lock);
> -
> -	config = vsp1_entity_get_pad_config(&lif->entity, cfg, fmt->which);
> -	if (!config) {
> -		ret = -EINVAL;
> -		goto done;
> -	}
> -
> -	/* Default to YUV if the requested format is not supported. */
> -	if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
> -	    fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32)
> -		fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32;
> -
> -	format = vsp1_entity_get_pad_format(&lif->entity, config, fmt->pad);
> -
> -	if (fmt->pad == LIF_PAD_SOURCE) {
> -		/*
> -		 * The LIF source format is always identical to its sink
> -		 * format.
> -		 */
> -		fmt->format = *format;
> -		goto done;
> -	}
> -
> -	format->code = fmt->format.code;
> -	format->width = clamp_t(unsigned int, fmt->format.width,
> -				LIF_MIN_SIZE, LIF_MAX_SIZE);
> -	format->height = clamp_t(unsigned int, fmt->format.height,
> -				 LIF_MIN_SIZE, LIF_MAX_SIZE);
> -	format->field = V4L2_FIELD_NONE;
> -	format->colorspace = V4L2_COLORSPACE_SRGB;
> -
> -	fmt->format = *format;
> -
> -	/* Propagate the format to the source pad. */
> -	format = vsp1_entity_get_pad_format(&lif->entity, config,
> -					    LIF_PAD_SOURCE);
> -	*format = fmt->format;
> -
> -done:
> -	mutex_unlock(&lif->entity.lock);
> -	return ret;
> +	return vsp1_subdev_set_pad_format(subdev, cfg, fmt, lif_codes,
> +					  ARRAY_SIZE(lif_codes),
> +					  LIF_MIN_SIZE, LIF_MIN_SIZE,
> +					  LIF_MAX_SIZE, LIF_MAX_SIZE);
>  }
>  
>  static const struct v4l2_subdev_pad_ops lif_pad_ops = {
> diff --git a/drivers/media/platform/vsp1/vsp1_lut.c b/drivers/media/platform/vsp1/vsp1_lut.c
> index 7bdabb311c6c..f2e48a02ca7d 100644
> --- a/drivers/media/platform/vsp1/vsp1_lut.c
> +++ b/drivers/media/platform/vsp1/vsp1_lut.c
> @@ -90,18 +90,18 @@ static const struct v4l2_ctrl_config lut_table_control = {
>   * V4L2 Subdevice Pad Operations
>   */
>  
> +static const unsigned int lut_codes[] = {
> +	MEDIA_BUS_FMT_ARGB8888_1X32,
> +	MEDIA_BUS_FMT_AHSV8888_1X32,
> +	MEDIA_BUS_FMT_AYUV8_1X32,
> +};
> +
>  static int lut_enum_mbus_code(struct v4l2_subdev *subdev,
>  			      struct v4l2_subdev_pad_config *cfg,
>  			      struct v4l2_subdev_mbus_code_enum *code)
>  {
> -	static const unsigned int codes[] = {
> -		MEDIA_BUS_FMT_ARGB8888_1X32,
> -		MEDIA_BUS_FMT_AHSV8888_1X32,
> -		MEDIA_BUS_FMT_AYUV8_1X32,
> -	};
> -
> -	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, codes,
> -					  ARRAY_SIZE(codes));
> +	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, lut_codes,
> +					  ARRAY_SIZE(lut_codes));
>  }
>  
>  static int lut_enum_frame_size(struct v4l2_subdev *subdev,
> @@ -117,51 +117,10 @@ static int lut_set_format(struct v4l2_subdev *subdev,
>  			  struct v4l2_subdev_pad_config *cfg,
>  			  struct v4l2_subdev_format *fmt)
>  {
> -	struct vsp1_lut *lut = to_lut(subdev);
> -	struct v4l2_subdev_pad_config *config;
> -	struct v4l2_mbus_framefmt *format;
> -	int ret = 0;
> -
> -	mutex_lock(&lut->entity.lock);
> -
> -	config = vsp1_entity_get_pad_config(&lut->entity, cfg, fmt->which);
> -	if (!config) {
> -		ret = -EINVAL;
> -		goto done;
> -	}
> -
> -	/* Default to YUV if the requested format is not supported. */
> -	if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
> -	    fmt->format.code != MEDIA_BUS_FMT_AHSV8888_1X32 &&
> -	    fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32)
> -		fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32;
> -
> -	format = vsp1_entity_get_pad_format(&lut->entity, config, fmt->pad);
> -
> -	if (fmt->pad == LUT_PAD_SOURCE) {
> -		/* The LUT output format can't be modified. */
> -		fmt->format = *format;
> -		goto done;
> -	}
> -
> -	format->code = fmt->format.code;
> -	format->width = clamp_t(unsigned int, fmt->format.width,
> -				LUT_MIN_SIZE, LUT_MAX_SIZE);
> -	format->height = clamp_t(unsigned int, fmt->format.height,
> -				 LUT_MIN_SIZE, LUT_MAX_SIZE);
> -	format->field = V4L2_FIELD_NONE;
> -	format->colorspace = V4L2_COLORSPACE_SRGB;
> -
> -	fmt->format = *format;
> -
> -	/* Propagate the format to the source pad. */
> -	format = vsp1_entity_get_pad_format(&lut->entity, config,
> -					    LUT_PAD_SOURCE);
> -	*format = fmt->format;
> -
> -done:
> -	mutex_unlock(&lut->entity.lock);
> -	return ret;
> +	return vsp1_subdev_set_pad_format(subdev, cfg, fmt, lut_codes,
> +					  ARRAY_SIZE(lut_codes),
> +					  LUT_MIN_SIZE, LUT_MIN_SIZE,
> +					  LUT_MAX_SIZE, LUT_MAX_SIZE);
>  }
>  
>  /* -----------------------------------------------------------------------------
> 


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

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

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

* Re: [PATCH v2 3/8] v4l: vsp1: Reset the crop and compose rectangles in the set_fmt helper
  2018-04-22 22:34   ` Laurent Pinchart
@ 2018-04-28 17:22     ` Kieran Bingham
  -1 siblings, 0 replies; 82+ messages in thread
From: Kieran Bingham @ 2018-04-28 17:22 UTC (permalink / raw)
  To: Laurent Pinchart, linux-media, dri-devel; +Cc: linux-renesas-soc


[-- Attachment #1.1: Type: text/plain, Size: 4798 bytes --]

Hi Laurent,

On 22/04/18 23:34, Laurent Pinchart wrote:
> To make vsp1_subdev_set_pad_format() usable by entities that support
> selection rectangles, we need to reset the crop and compose rectangles
> when setting the format on the sink pad. Do so and replace the custom
> set_fmt implementation of the histogram code by a call to
> vsp1_subdev_set_pad_format().
> 
> Resetting the crop and compose rectangles for entities that don't
> support crop and compose has no adverse effect as the rectangles are
> ignored anyway.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

This one looks fairly straight forward.

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

> ---
>  drivers/media/platform/vsp1/vsp1_entity.c | 16 +++++++++
>  drivers/media/platform/vsp1/vsp1_histo.c  | 59 +++----------------------------
>  2 files changed, 20 insertions(+), 55 deletions(-)
> 
> diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c
> index 239df047efd0..181a583aecad 100644
> --- a/drivers/media/platform/vsp1/vsp1_entity.c
> +++ b/drivers/media/platform/vsp1/vsp1_entity.c
> @@ -335,6 +335,7 @@ int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev,
>  	struct vsp1_entity *entity = to_vsp1_entity(subdev);
>  	struct v4l2_subdev_pad_config *config;
>  	struct v4l2_mbus_framefmt *format;
> +	struct v4l2_rect *selection;
>  	unsigned int i;
>  	int ret = 0;
>  
> @@ -377,6 +378,21 @@ int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev,
>  	format = vsp1_entity_get_pad_format(entity, config, 1);
>  	*format = fmt->format;
>  
> +	/* Reset the crop and compose rectangles */
> +	selection = vsp1_entity_get_pad_selection(entity, config, fmt->pad,
> +						  V4L2_SEL_TGT_CROP);
> +	selection->left = 0;
> +	selection->top = 0;
> +	selection->width = format->width;
> +	selection->height = format->height;
> +
> +	selection = vsp1_entity_get_pad_selection(entity, config, fmt->pad,
> +						  V4L2_SEL_TGT_COMPOSE);
> +	selection->left = 0;
> +	selection->top = 0;
> +	selection->width = format->width;
> +	selection->height = format->height;
> +
>  done:
>  	mutex_unlock(&entity->lock);
>  	return ret;
> diff --git a/drivers/media/platform/vsp1/vsp1_histo.c b/drivers/media/platform/vsp1/vsp1_histo.c
> index 029181c1fb61..5e15c8ff88d9 100644
> --- a/drivers/media/platform/vsp1/vsp1_histo.c
> +++ b/drivers/media/platform/vsp1/vsp1_histo.c
> @@ -389,65 +389,14 @@ static int histo_set_format(struct v4l2_subdev *subdev,
>  			    struct v4l2_subdev_format *fmt)
>  {
>  	struct vsp1_histogram *histo = subdev_to_histo(subdev);
> -	struct v4l2_subdev_pad_config *config;
> -	struct v4l2_mbus_framefmt *format;
> -	struct v4l2_rect *selection;
> -	unsigned int i;
> -	int ret = 0;
>  
>  	if (fmt->pad != HISTO_PAD_SINK)
>  		return histo_get_format(subdev, cfg, fmt);
>  
> -	mutex_lock(&histo->entity.lock);
> -
> -	config = vsp1_entity_get_pad_config(&histo->entity, cfg, fmt->which);
> -	if (!config) {
> -		ret = -EINVAL;
> -		goto done;
> -	}
> -
> -	/*
> -	 * Default to the first format if the requested format is not
> -	 * supported.
> -	 */
> -	for (i = 0; i < histo->num_formats; ++i) {
> -		if (fmt->format.code == histo->formats[i])
> -			break;
> -	}
> -	if (i == histo->num_formats)
> -		fmt->format.code = histo->formats[0];
> -
> -	format = vsp1_entity_get_pad_format(&histo->entity, config, fmt->pad);
> -
> -	format->code = fmt->format.code;
> -	format->width = clamp_t(unsigned int, fmt->format.width,
> -				HISTO_MIN_SIZE, HISTO_MAX_SIZE);
> -	format->height = clamp_t(unsigned int, fmt->format.height,
> -				 HISTO_MIN_SIZE, HISTO_MAX_SIZE);
> -	format->field = V4L2_FIELD_NONE;
> -	format->colorspace = V4L2_COLORSPACE_SRGB;
> -
> -	fmt->format = *format;
> -
> -	/* Reset the crop and compose rectangles */
> -	selection = vsp1_entity_get_pad_selection(&histo->entity, config,
> -						  fmt->pad, V4L2_SEL_TGT_CROP);
> -	selection->left = 0;
> -	selection->top = 0;
> -	selection->width = format->width;
> -	selection->height = format->height;
> -
> -	selection = vsp1_entity_get_pad_selection(&histo->entity, config,
> -						  fmt->pad,
> -						  V4L2_SEL_TGT_COMPOSE);
> -	selection->left = 0;
> -	selection->top = 0;
> -	selection->width = format->width;
> -	selection->height = format->height;
> -
> -done:
> -	mutex_unlock(&histo->entity.lock);
> -	return ret;
> +	return vsp1_subdev_set_pad_format(subdev, cfg, fmt,
> +					  histo->formats, histo->num_formats,
> +					  HISTO_MIN_SIZE, HISTO_MIN_SIZE,
> +					  HISTO_MAX_SIZE, HISTO_MAX_SIZE);
>  }
>  
>  static const struct v4l2_subdev_pad_ops histo_pad_ops = {
> 


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v2 3/8] v4l: vsp1: Reset the crop and compose rectangles in the set_fmt helper
@ 2018-04-28 17:22     ` Kieran Bingham
  0 siblings, 0 replies; 82+ messages in thread
From: Kieran Bingham @ 2018-04-28 17:22 UTC (permalink / raw)
  To: Laurent Pinchart, linux-media, dri-devel; +Cc: linux-renesas-soc


[-- Attachment #1.1.1: Type: text/plain, Size: 4798 bytes --]

Hi Laurent,

On 22/04/18 23:34, Laurent Pinchart wrote:
> To make vsp1_subdev_set_pad_format() usable by entities that support
> selection rectangles, we need to reset the crop and compose rectangles
> when setting the format on the sink pad. Do so and replace the custom
> set_fmt implementation of the histogram code by a call to
> vsp1_subdev_set_pad_format().
> 
> Resetting the crop and compose rectangles for entities that don't
> support crop and compose has no adverse effect as the rectangles are
> ignored anyway.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

This one looks fairly straight forward.

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

> ---
>  drivers/media/platform/vsp1/vsp1_entity.c | 16 +++++++++
>  drivers/media/platform/vsp1/vsp1_histo.c  | 59 +++----------------------------
>  2 files changed, 20 insertions(+), 55 deletions(-)
> 
> diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c
> index 239df047efd0..181a583aecad 100644
> --- a/drivers/media/platform/vsp1/vsp1_entity.c
> +++ b/drivers/media/platform/vsp1/vsp1_entity.c
> @@ -335,6 +335,7 @@ int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev,
>  	struct vsp1_entity *entity = to_vsp1_entity(subdev);
>  	struct v4l2_subdev_pad_config *config;
>  	struct v4l2_mbus_framefmt *format;
> +	struct v4l2_rect *selection;
>  	unsigned int i;
>  	int ret = 0;
>  
> @@ -377,6 +378,21 @@ int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev,
>  	format = vsp1_entity_get_pad_format(entity, config, 1);
>  	*format = fmt->format;
>  
> +	/* Reset the crop and compose rectangles */
> +	selection = vsp1_entity_get_pad_selection(entity, config, fmt->pad,
> +						  V4L2_SEL_TGT_CROP);
> +	selection->left = 0;
> +	selection->top = 0;
> +	selection->width = format->width;
> +	selection->height = format->height;
> +
> +	selection = vsp1_entity_get_pad_selection(entity, config, fmt->pad,
> +						  V4L2_SEL_TGT_COMPOSE);
> +	selection->left = 0;
> +	selection->top = 0;
> +	selection->width = format->width;
> +	selection->height = format->height;
> +
>  done:
>  	mutex_unlock(&entity->lock);
>  	return ret;
> diff --git a/drivers/media/platform/vsp1/vsp1_histo.c b/drivers/media/platform/vsp1/vsp1_histo.c
> index 029181c1fb61..5e15c8ff88d9 100644
> --- a/drivers/media/platform/vsp1/vsp1_histo.c
> +++ b/drivers/media/platform/vsp1/vsp1_histo.c
> @@ -389,65 +389,14 @@ static int histo_set_format(struct v4l2_subdev *subdev,
>  			    struct v4l2_subdev_format *fmt)
>  {
>  	struct vsp1_histogram *histo = subdev_to_histo(subdev);
> -	struct v4l2_subdev_pad_config *config;
> -	struct v4l2_mbus_framefmt *format;
> -	struct v4l2_rect *selection;
> -	unsigned int i;
> -	int ret = 0;
>  
>  	if (fmt->pad != HISTO_PAD_SINK)
>  		return histo_get_format(subdev, cfg, fmt);
>  
> -	mutex_lock(&histo->entity.lock);
> -
> -	config = vsp1_entity_get_pad_config(&histo->entity, cfg, fmt->which);
> -	if (!config) {
> -		ret = -EINVAL;
> -		goto done;
> -	}
> -
> -	/*
> -	 * Default to the first format if the requested format is not
> -	 * supported.
> -	 */
> -	for (i = 0; i < histo->num_formats; ++i) {
> -		if (fmt->format.code == histo->formats[i])
> -			break;
> -	}
> -	if (i == histo->num_formats)
> -		fmt->format.code = histo->formats[0];
> -
> -	format = vsp1_entity_get_pad_format(&histo->entity, config, fmt->pad);
> -
> -	format->code = fmt->format.code;
> -	format->width = clamp_t(unsigned int, fmt->format.width,
> -				HISTO_MIN_SIZE, HISTO_MAX_SIZE);
> -	format->height = clamp_t(unsigned int, fmt->format.height,
> -				 HISTO_MIN_SIZE, HISTO_MAX_SIZE);
> -	format->field = V4L2_FIELD_NONE;
> -	format->colorspace = V4L2_COLORSPACE_SRGB;
> -
> -	fmt->format = *format;
> -
> -	/* Reset the crop and compose rectangles */
> -	selection = vsp1_entity_get_pad_selection(&histo->entity, config,
> -						  fmt->pad, V4L2_SEL_TGT_CROP);
> -	selection->left = 0;
> -	selection->top = 0;
> -	selection->width = format->width;
> -	selection->height = format->height;
> -
> -	selection = vsp1_entity_get_pad_selection(&histo->entity, config,
> -						  fmt->pad,
> -						  V4L2_SEL_TGT_COMPOSE);
> -	selection->left = 0;
> -	selection->top = 0;
> -	selection->width = format->width;
> -	selection->height = format->height;
> -
> -done:
> -	mutex_unlock(&histo->entity.lock);
> -	return ret;
> +	return vsp1_subdev_set_pad_format(subdev, cfg, fmt,
> +					  histo->formats, histo->num_formats,
> +					  HISTO_MIN_SIZE, HISTO_MIN_SIZE,
> +					  HISTO_MAX_SIZE, HISTO_MAX_SIZE);
>  }
>  
>  static const struct v4l2_subdev_pad_ops histo_pad_ops = {
> 


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

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

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

* Re: [PATCH v2 2/8] v4l: vsp1: Share the CLU, LIF and LUT set_fmt pad operation code
  2018-04-28 17:16     ` Kieran Bingham
@ 2018-04-28 17:25       ` Laurent Pinchart
  -1 siblings, 0 replies; 82+ messages in thread
From: Laurent Pinchart @ 2018-04-28 17:25 UTC (permalink / raw)
  To: Kieran Bingham
  Cc: Laurent Pinchart, linux-media, dri-devel, linux-renesas-soc

Hi Kieran,

On Saturday, 28 April 2018 20:16:11 EEST Kieran Bingham wrote:
> On 22/04/18 23:34, Laurent Pinchart wrote:
> > The implementation of the set_fmt pad operation is identical in the
> > three modules. Move it to a generic helper function.
> > 
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com>
> 
> Only a minor pair of comments below regarding source/sink pad descriptions.
> 
> If it's not convenient/accurate to define these with an enum then don't
> worry about it.

It's a good point. There are however other locations in vsp1_entity.c that 
hardcode pad numbers, so I'll submit a patch on top of this series to fix them 
all in one go.

> Otherwise,
> 
> Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
> 
> > ---
> > 
> >  drivers/media/platform/vsp1/vsp1_clu.c    | 65 +++++-------------------
> >  drivers/media/platform/vsp1/vsp1_entity.c | 75 ++++++++++++++++++++++++++
> >  drivers/media/platform/vsp1/vsp1_entity.h |  6 +++
> >  drivers/media/platform/vsp1/vsp1_lif.c    | 65 +++++--------------------
> >  drivers/media/platform/vsp1/vsp1_lut.c    | 65 +++++--------------------
> >  5 files changed, 116 insertions(+), 160 deletions(-)
> 
> That's a nice diffstat :-)
> 
> > diff --git a/drivers/media/platform/vsp1/vsp1_clu.c
> > b/drivers/media/platform/vsp1/vsp1_clu.c index 9626b6308585..96a448e1504c
> > 100644
> > --- a/drivers/media/platform/vsp1/vsp1_clu.c
> > +++ b/drivers/media/platform/vsp1/vsp1_clu.c
> > @@ -114,18 +114,18 @@ static const struct v4l2_ctrl_config
> > clu_mode_control = {> 
> >   * V4L2 Subdevice Pad Operations
> >   */
> > 
> > +static const unsigned int clu_codes[] = {
> > +	MEDIA_BUS_FMT_ARGB8888_1X32,
> > +	MEDIA_BUS_FMT_AHSV8888_1X32,
> > +	MEDIA_BUS_FMT_AYUV8_1X32,
> > +};
> > +
> > 
> >  static int clu_enum_mbus_code(struct v4l2_subdev *subdev,
> >  
> >  			      struct v4l2_subdev_pad_config *cfg,
> >  			      struct v4l2_subdev_mbus_code_enum *code)
> >  
> >  {
> > 
> > -	static const unsigned int codes[] = {
> > -		MEDIA_BUS_FMT_ARGB8888_1X32,
> > -		MEDIA_BUS_FMT_AHSV8888_1X32,
> > -		MEDIA_BUS_FMT_AYUV8_1X32,
> > -	};
> > -
> > -	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, codes,
> > -					  ARRAY_SIZE(codes));
> > +	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, clu_codes,
> > +					  ARRAY_SIZE(clu_codes));
> > 
> >  }
> >  
> >  static int clu_enum_frame_size(struct v4l2_subdev *subdev,
> > 
> > @@ -141,51 +141,10 @@ static int clu_set_format(struct v4l2_subdev
> > *subdev,
> > 
> >  			  struct v4l2_subdev_pad_config *cfg,
> >  			  struct v4l2_subdev_format *fmt)
> >  
> >  {
> > 
> > -	struct vsp1_clu *clu = to_clu(subdev);
> > -	struct v4l2_subdev_pad_config *config;
> > -	struct v4l2_mbus_framefmt *format;
> > -	int ret = 0;
> > -
> > -	mutex_lock(&clu->entity.lock);
> > -
> > -	config = vsp1_entity_get_pad_config(&clu->entity, cfg, fmt->which);
> > -	if (!config) {
> > -		ret = -EINVAL;
> > -		goto done;
> > -	}
> > -
> > -	/* Default to YUV if the requested format is not supported. */
> > -	if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
> > -	    fmt->format.code != MEDIA_BUS_FMT_AHSV8888_1X32 &&
> > -	    fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32)
> > -		fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32;
> > -
> > -	format = vsp1_entity_get_pad_format(&clu->entity, config, fmt->pad);
> > -
> > -	if (fmt->pad == CLU_PAD_SOURCE) {
> > -		/* The CLU output format can't be modified. */
> > -		fmt->format = *format;
> > -		goto done;
> > -	}
> > -
> > -	format->code = fmt->format.code;
> > -	format->width = clamp_t(unsigned int, fmt->format.width,
> > -				CLU_MIN_SIZE, CLU_MAX_SIZE);
> > -	format->height = clamp_t(unsigned int, fmt->format.height,
> > -				 CLU_MIN_SIZE, CLU_MAX_SIZE);
> > -	format->field = V4L2_FIELD_NONE;
> > -	format->colorspace = V4L2_COLORSPACE_SRGB;
> > -
> > -	fmt->format = *format;
> > -
> > -	/* Propagate the format to the source pad. */
> > -	format = vsp1_entity_get_pad_format(&clu->entity, config,
> > -					    CLU_PAD_SOURCE);
> > -	*format = fmt->format;
> > -
> > -done:
> > -	mutex_unlock(&clu->entity.lock);
> > -	return ret;
> > +	return vsp1_subdev_set_pad_format(subdev, cfg, fmt, clu_codes,
> > +					  ARRAY_SIZE(clu_codes),
> > +					  CLU_MIN_SIZE, CLU_MIN_SIZE,
> > +					  CLU_MAX_SIZE, CLU_MAX_SIZE);
> > 
> >  }
> >  
> >  /*
> >  ------------------------------------------------------------------------
> >  -----> 
> > diff --git a/drivers/media/platform/vsp1/vsp1_entity.c
> > b/drivers/media/platform/vsp1/vsp1_entity.c index
> > 72354caf5746..239df047efd0 100644
> > --- a/drivers/media/platform/vsp1/vsp1_entity.c
> > +++ b/drivers/media/platform/vsp1/vsp1_entity.c
> > @@ -307,6 +307,81 @@ int vsp1_subdev_enum_frame_size(struct v4l2_subdev
> > *subdev,> 
> >  	return ret;
> >  
> >  }
> > 
> > +/*
> > + * vsp1_subdev_set_pad_format - Subdev pad set_fmt handler
> > + * @subdev: V4L2 subdevice
> > + * @cfg: V4L2 subdev pad configuration
> > + * @fmt: V4L2 subdev format
> > + * @codes: Array of supported media bus codes
> > + * @ncodes: Number of supported media bus codes
> > + * @min_width: Minimum image width
> > + * @min_height: Minimum image height
> > + * @max_width: Maximum image width
> > + * @max_height: Maximum image height
> > + *
> > + * This function implements the subdev set_fmt pad operation for entities
> > that
> > + * do not support scaling or cropping. It defaults to the first supplied
> > media
> > + * bus code if the requested code isn't supported, clamps the size to the
> > + * supplied minimum and maximum, and propagates the sink pad format to
> > the
> > + * source pad.
> > + */
> > +int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev,
> > +			       struct v4l2_subdev_pad_config *cfg,
> > +			       struct v4l2_subdev_format *fmt,
> > +			       const unsigned int *codes, unsigned int ncodes,
> > +			       unsigned int min_width, unsigned int min_height,
> > +			       unsigned int max_width, unsigned int max_height)
> > +{
> > +	struct vsp1_entity *entity = to_vsp1_entity(subdev);
> > +	struct v4l2_subdev_pad_config *config;
> > +	struct v4l2_mbus_framefmt *format;
> > +	unsigned int i;
> > +	int ret = 0;
> > +
> > +	mutex_lock(&entity->lock);
> > +
> > +	config = vsp1_entity_get_pad_config(entity, cfg, fmt->which);
> > +	if (!config) {
> > +		ret = -EINVAL;
> > +		goto done;
> > +	}
> > +
> > +	format = vsp1_entity_get_pad_format(entity, config, fmt->pad);
> > +
> > +	if (fmt->pad != 0) {
> 
> I guess we don't have any clear way to say != *_PAD_SINK here do we ..
> 
> > +		/* The output format can't be modified. */
> > +		fmt->format = *format;
> > +		goto done;
> > +	}
> > +
> > +	/*
> > +	 * Default to the first media bus code if the requested format is not
> > +	 * supported.
> > +	 */
> > +	for (i = 0; i < ncodes; ++i) {
> > +		if (fmt->format.code == codes[i])
> > +			break;
> > +	}
> > +
> > +	format->code = i < ncodes ? codes[i] : codes[0];
> > +	format->width = clamp_t(unsigned int, fmt->format.width,
> > +				min_width, max_width);
> > +	format->height = clamp_t(unsigned int, fmt->format.height,
> > +				 min_height, max_height);
> > +	format->field = V4L2_FIELD_NONE;
> > +	format->colorspace = V4L2_COLORSPACE_SRGB;
> > +
> > +	fmt->format = *format;
> > +
> > +	/* Propagate the format to the source pad. */
> > +	format = vsp1_entity_get_pad_format(entity, config, 1);
> 
> If we can guarantee that ENTITY_PAD_SINK == 0 and ENTITY_PAD_SOURCE == 1,
> can we put those into an enum ?
> 
> > +	*format = fmt->format;
> > +
> > +done:
> > +	mutex_unlock(&entity->lock);
> > +	return ret;
> > +}
> > +
> > 
> >  /*
> >  ------------------------------------------------------------------------
> >  ----->  
> >   * Media Operations
> >   */
> > 
> > diff --git a/drivers/media/platform/vsp1/vsp1_entity.h
> > b/drivers/media/platform/vsp1/vsp1_entity.h index
> > fb20a1578f3b..0839a62cfa71 100644
> > --- a/drivers/media/platform/vsp1/vsp1_entity.h
> > +++ b/drivers/media/platform/vsp1/vsp1_entity.h
> > @@ -160,6 +160,12 @@ struct media_pad *vsp1_entity_remote_pad(struct
> > media_pad *pad);> 
> >  int vsp1_subdev_get_pad_format(struct v4l2_subdev *subdev,
> >  
> >  			       struct v4l2_subdev_pad_config *cfg,
> >  			       struct v4l2_subdev_format *fmt);
> > 
> > +int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev,
> > +			       struct v4l2_subdev_pad_config *cfg,
> > +			       struct v4l2_subdev_format *fmt,
> > +			       const unsigned int *codes, unsigned int ncodes,
> > +			       unsigned int min_width, unsigned int min_height,
> > +			       unsigned int max_width, unsigned int max_height);
> > 
> >  int vsp1_subdev_enum_mbus_code(struct v4l2_subdev *subdev,
> >  
> >  			       struct v4l2_subdev_pad_config *cfg,
> >  			       struct v4l2_subdev_mbus_code_enum *code,
> > 
> > diff --git a/drivers/media/platform/vsp1/vsp1_lif.c
> > b/drivers/media/platform/vsp1/vsp1_lif.c index b20b842f06ba..fbdd5715f829
> > 100644
> > --- a/drivers/media/platform/vsp1/vsp1_lif.c
> > +++ b/drivers/media/platform/vsp1/vsp1_lif.c
> > @@ -33,17 +33,17 @@ static inline void vsp1_lif_write(struct vsp1_lif
> > *lif, struct vsp1_dl_list *dl,> 
> >   * V4L2 Subdevice Operations
> >   */
> > 
> > +static const unsigned int lif_codes[] = {
> > +	MEDIA_BUS_FMT_ARGB8888_1X32,
> > +	MEDIA_BUS_FMT_AYUV8_1X32,
> > +};
> > +
> > 
> >  static int lif_enum_mbus_code(struct v4l2_subdev *subdev,
> >  
> >  			      struct v4l2_subdev_pad_config *cfg,
> >  			      struct v4l2_subdev_mbus_code_enum *code)
> >  
> >  {
> > 
> > -	static const unsigned int codes[] = {
> > -		MEDIA_BUS_FMT_ARGB8888_1X32,
> > -		MEDIA_BUS_FMT_AYUV8_1X32,
> > -	};
> > -
> > -	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, codes,
> > -					  ARRAY_SIZE(codes));
> > +	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, lif_codes,
> > +					  ARRAY_SIZE(lif_codes));
> > 
> >  }
> >  
> >  static int lif_enum_frame_size(struct v4l2_subdev *subdev,
> > 
> > @@ -59,53 +59,10 @@ static int lif_set_format(struct v4l2_subdev *subdev,
> > 
> >  			  struct v4l2_subdev_pad_config *cfg,
> >  			  struct v4l2_subdev_format *fmt)
> >  
> >  {
> > 
> > -	struct vsp1_lif *lif = to_lif(subdev);
> > -	struct v4l2_subdev_pad_config *config;
> > -	struct v4l2_mbus_framefmt *format;
> > -	int ret = 0;
> > -
> > -	mutex_lock(&lif->entity.lock);
> > -
> > -	config = vsp1_entity_get_pad_config(&lif->entity, cfg, fmt->which);
> > -	if (!config) {
> > -		ret = -EINVAL;
> > -		goto done;
> > -	}
> > -
> > -	/* Default to YUV if the requested format is not supported. */
> > -	if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
> > -	    fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32)
> > -		fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32;
> > -
> > -	format = vsp1_entity_get_pad_format(&lif->entity, config, fmt->pad);
> > -
> > -	if (fmt->pad == LIF_PAD_SOURCE) {
> > -		/*
> > -		 * The LIF source format is always identical to its sink
> > -		 * format.
> > -		 */
> > -		fmt->format = *format;
> > -		goto done;
> > -	}
> > -
> > -	format->code = fmt->format.code;
> > -	format->width = clamp_t(unsigned int, fmt->format.width,
> > -				LIF_MIN_SIZE, LIF_MAX_SIZE);
> > -	format->height = clamp_t(unsigned int, fmt->format.height,
> > -				 LIF_MIN_SIZE, LIF_MAX_SIZE);
> > -	format->field = V4L2_FIELD_NONE;
> > -	format->colorspace = V4L2_COLORSPACE_SRGB;
> > -
> > -	fmt->format = *format;
> > -
> > -	/* Propagate the format to the source pad. */
> > -	format = vsp1_entity_get_pad_format(&lif->entity, config,
> > -					    LIF_PAD_SOURCE);
> > -	*format = fmt->format;
> > -
> > -done:
> > -	mutex_unlock(&lif->entity.lock);
> > -	return ret;
> > +	return vsp1_subdev_set_pad_format(subdev, cfg, fmt, lif_codes,
> > +					  ARRAY_SIZE(lif_codes),
> > +					  LIF_MIN_SIZE, LIF_MIN_SIZE,
> > +					  LIF_MAX_SIZE, LIF_MAX_SIZE);
> > 
> >  }
> >  
> >  static const struct v4l2_subdev_pad_ops lif_pad_ops = {
> > 
> > diff --git a/drivers/media/platform/vsp1/vsp1_lut.c
> > b/drivers/media/platform/vsp1/vsp1_lut.c index 7bdabb311c6c..f2e48a02ca7d
> > 100644
> > --- a/drivers/media/platform/vsp1/vsp1_lut.c
> > +++ b/drivers/media/platform/vsp1/vsp1_lut.c
> > @@ -90,18 +90,18 @@ static const struct v4l2_ctrl_config lut_table_control
> > = {> 
> >   * V4L2 Subdevice Pad Operations
> >   */
> > 
> > +static const unsigned int lut_codes[] = {
> > +	MEDIA_BUS_FMT_ARGB8888_1X32,
> > +	MEDIA_BUS_FMT_AHSV8888_1X32,
> > +	MEDIA_BUS_FMT_AYUV8_1X32,
> > +};
> > +
> > 
> >  static int lut_enum_mbus_code(struct v4l2_subdev *subdev,
> >  
> >  			      struct v4l2_subdev_pad_config *cfg,
> >  			      struct v4l2_subdev_mbus_code_enum *code)
> >  
> >  {
> > 
> > -	static const unsigned int codes[] = {
> > -		MEDIA_BUS_FMT_ARGB8888_1X32,
> > -		MEDIA_BUS_FMT_AHSV8888_1X32,
> > -		MEDIA_BUS_FMT_AYUV8_1X32,
> > -	};
> > -
> > -	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, codes,
> > -					  ARRAY_SIZE(codes));
> > +	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, lut_codes,
> > +					  ARRAY_SIZE(lut_codes));
> > 
> >  }
> >  
> >  static int lut_enum_frame_size(struct v4l2_subdev *subdev,
> > 
> > @@ -117,51 +117,10 @@ static int lut_set_format(struct v4l2_subdev
> > *subdev,
> > 
> >  			  struct v4l2_subdev_pad_config *cfg,
> >  			  struct v4l2_subdev_format *fmt)
> >  
> >  {
> > 
> > -	struct vsp1_lut *lut = to_lut(subdev);
> > -	struct v4l2_subdev_pad_config *config;
> > -	struct v4l2_mbus_framefmt *format;
> > -	int ret = 0;
> > -
> > -	mutex_lock(&lut->entity.lock);
> > -
> > -	config = vsp1_entity_get_pad_config(&lut->entity, cfg, fmt->which);
> > -	if (!config) {
> > -		ret = -EINVAL;
> > -		goto done;
> > -	}
> > -
> > -	/* Default to YUV if the requested format is not supported. */
> > -	if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
> > -	    fmt->format.code != MEDIA_BUS_FMT_AHSV8888_1X32 &&
> > -	    fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32)
> > -		fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32;
> > -
> > -	format = vsp1_entity_get_pad_format(&lut->entity, config, fmt->pad);
> > -
> > -	if (fmt->pad == LUT_PAD_SOURCE) {
> > -		/* The LUT output format can't be modified. */
> > -		fmt->format = *format;
> > -		goto done;
> > -	}
> > -
> > -	format->code = fmt->format.code;
> > -	format->width = clamp_t(unsigned int, fmt->format.width,
> > -				LUT_MIN_SIZE, LUT_MAX_SIZE);
> > -	format->height = clamp_t(unsigned int, fmt->format.height,
> > -				 LUT_MIN_SIZE, LUT_MAX_SIZE);
> > -	format->field = V4L2_FIELD_NONE;
> > -	format->colorspace = V4L2_COLORSPACE_SRGB;
> > -
> > -	fmt->format = *format;
> > -
> > -	/* Propagate the format to the source pad. */
> > -	format = vsp1_entity_get_pad_format(&lut->entity, config,
> > -					    LUT_PAD_SOURCE);
> > -	*format = fmt->format;
> > -
> > -done:
> > -	mutex_unlock(&lut->entity.lock);
> > -	return ret;
> > +	return vsp1_subdev_set_pad_format(subdev, cfg, fmt, lut_codes,
> > +					  ARRAY_SIZE(lut_codes),
> > +					  LUT_MIN_SIZE, LUT_MIN_SIZE,
> > +					  LUT_MAX_SIZE, LUT_MAX_SIZE);
> > 
> >  }
> >  
> >  /*
> >  ------------------------------------------------------------------------
> >  -----


-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v2 2/8] v4l: vsp1: Share the CLU, LIF and LUT set_fmt pad operation code
@ 2018-04-28 17:25       ` Laurent Pinchart
  0 siblings, 0 replies; 82+ messages in thread
From: Laurent Pinchart @ 2018-04-28 17:25 UTC (permalink / raw)
  To: Kieran Bingham
  Cc: linux-renesas-soc, Laurent Pinchart, dri-devel, linux-media

Hi Kieran,

On Saturday, 28 April 2018 20:16:11 EEST Kieran Bingham wrote:
> On 22/04/18 23:34, Laurent Pinchart wrote:
> > The implementation of the set_fmt pad operation is identical in the
> > three modules. Move it to a generic helper function.
> > 
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com>
> 
> Only a minor pair of comments below regarding source/sink pad descriptions.
> 
> If it's not convenient/accurate to define these with an enum then don't
> worry about it.

It's a good point. There are however other locations in vsp1_entity.c that 
hardcode pad numbers, so I'll submit a patch on top of this series to fix them 
all in one go.

> Otherwise,
> 
> Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
> 
> > ---
> > 
> >  drivers/media/platform/vsp1/vsp1_clu.c    | 65 +++++-------------------
> >  drivers/media/platform/vsp1/vsp1_entity.c | 75 ++++++++++++++++++++++++++
> >  drivers/media/platform/vsp1/vsp1_entity.h |  6 +++
> >  drivers/media/platform/vsp1/vsp1_lif.c    | 65 +++++--------------------
> >  drivers/media/platform/vsp1/vsp1_lut.c    | 65 +++++--------------------
> >  5 files changed, 116 insertions(+), 160 deletions(-)
> 
> That's a nice diffstat :-)
> 
> > diff --git a/drivers/media/platform/vsp1/vsp1_clu.c
> > b/drivers/media/platform/vsp1/vsp1_clu.c index 9626b6308585..96a448e1504c
> > 100644
> > --- a/drivers/media/platform/vsp1/vsp1_clu.c
> > +++ b/drivers/media/platform/vsp1/vsp1_clu.c
> > @@ -114,18 +114,18 @@ static const struct v4l2_ctrl_config
> > clu_mode_control = {> 
> >   * V4L2 Subdevice Pad Operations
> >   */
> > 
> > +static const unsigned int clu_codes[] = {
> > +	MEDIA_BUS_FMT_ARGB8888_1X32,
> > +	MEDIA_BUS_FMT_AHSV8888_1X32,
> > +	MEDIA_BUS_FMT_AYUV8_1X32,
> > +};
> > +
> > 
> >  static int clu_enum_mbus_code(struct v4l2_subdev *subdev,
> >  
> >  			      struct v4l2_subdev_pad_config *cfg,
> >  			      struct v4l2_subdev_mbus_code_enum *code)
> >  
> >  {
> > 
> > -	static const unsigned int codes[] = {
> > -		MEDIA_BUS_FMT_ARGB8888_1X32,
> > -		MEDIA_BUS_FMT_AHSV8888_1X32,
> > -		MEDIA_BUS_FMT_AYUV8_1X32,
> > -	};
> > -
> > -	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, codes,
> > -					  ARRAY_SIZE(codes));
> > +	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, clu_codes,
> > +					  ARRAY_SIZE(clu_codes));
> > 
> >  }
> >  
> >  static int clu_enum_frame_size(struct v4l2_subdev *subdev,
> > 
> > @@ -141,51 +141,10 @@ static int clu_set_format(struct v4l2_subdev
> > *subdev,
> > 
> >  			  struct v4l2_subdev_pad_config *cfg,
> >  			  struct v4l2_subdev_format *fmt)
> >  
> >  {
> > 
> > -	struct vsp1_clu *clu = to_clu(subdev);
> > -	struct v4l2_subdev_pad_config *config;
> > -	struct v4l2_mbus_framefmt *format;
> > -	int ret = 0;
> > -
> > -	mutex_lock(&clu->entity.lock);
> > -
> > -	config = vsp1_entity_get_pad_config(&clu->entity, cfg, fmt->which);
> > -	if (!config) {
> > -		ret = -EINVAL;
> > -		goto done;
> > -	}
> > -
> > -	/* Default to YUV if the requested format is not supported. */
> > -	if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
> > -	    fmt->format.code != MEDIA_BUS_FMT_AHSV8888_1X32 &&
> > -	    fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32)
> > -		fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32;
> > -
> > -	format = vsp1_entity_get_pad_format(&clu->entity, config, fmt->pad);
> > -
> > -	if (fmt->pad == CLU_PAD_SOURCE) {
> > -		/* The CLU output format can't be modified. */
> > -		fmt->format = *format;
> > -		goto done;
> > -	}
> > -
> > -	format->code = fmt->format.code;
> > -	format->width = clamp_t(unsigned int, fmt->format.width,
> > -				CLU_MIN_SIZE, CLU_MAX_SIZE);
> > -	format->height = clamp_t(unsigned int, fmt->format.height,
> > -				 CLU_MIN_SIZE, CLU_MAX_SIZE);
> > -	format->field = V4L2_FIELD_NONE;
> > -	format->colorspace = V4L2_COLORSPACE_SRGB;
> > -
> > -	fmt->format = *format;
> > -
> > -	/* Propagate the format to the source pad. */
> > -	format = vsp1_entity_get_pad_format(&clu->entity, config,
> > -					    CLU_PAD_SOURCE);
> > -	*format = fmt->format;
> > -
> > -done:
> > -	mutex_unlock(&clu->entity.lock);
> > -	return ret;
> > +	return vsp1_subdev_set_pad_format(subdev, cfg, fmt, clu_codes,
> > +					  ARRAY_SIZE(clu_codes),
> > +					  CLU_MIN_SIZE, CLU_MIN_SIZE,
> > +					  CLU_MAX_SIZE, CLU_MAX_SIZE);
> > 
> >  }
> >  
> >  /*
> >  ------------------------------------------------------------------------
> >  -----> 
> > diff --git a/drivers/media/platform/vsp1/vsp1_entity.c
> > b/drivers/media/platform/vsp1/vsp1_entity.c index
> > 72354caf5746..239df047efd0 100644
> > --- a/drivers/media/platform/vsp1/vsp1_entity.c
> > +++ b/drivers/media/platform/vsp1/vsp1_entity.c
> > @@ -307,6 +307,81 @@ int vsp1_subdev_enum_frame_size(struct v4l2_subdev
> > *subdev,> 
> >  	return ret;
> >  
> >  }
> > 
> > +/*
> > + * vsp1_subdev_set_pad_format - Subdev pad set_fmt handler
> > + * @subdev: V4L2 subdevice
> > + * @cfg: V4L2 subdev pad configuration
> > + * @fmt: V4L2 subdev format
> > + * @codes: Array of supported media bus codes
> > + * @ncodes: Number of supported media bus codes
> > + * @min_width: Minimum image width
> > + * @min_height: Minimum image height
> > + * @max_width: Maximum image width
> > + * @max_height: Maximum image height
> > + *
> > + * This function implements the subdev set_fmt pad operation for entities
> > that
> > + * do not support scaling or cropping. It defaults to the first supplied
> > media
> > + * bus code if the requested code isn't supported, clamps the size to the
> > + * supplied minimum and maximum, and propagates the sink pad format to
> > the
> > + * source pad.
> > + */
> > +int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev,
> > +			       struct v4l2_subdev_pad_config *cfg,
> > +			       struct v4l2_subdev_format *fmt,
> > +			       const unsigned int *codes, unsigned int ncodes,
> > +			       unsigned int min_width, unsigned int min_height,
> > +			       unsigned int max_width, unsigned int max_height)
> > +{
> > +	struct vsp1_entity *entity = to_vsp1_entity(subdev);
> > +	struct v4l2_subdev_pad_config *config;
> > +	struct v4l2_mbus_framefmt *format;
> > +	unsigned int i;
> > +	int ret = 0;
> > +
> > +	mutex_lock(&entity->lock);
> > +
> > +	config = vsp1_entity_get_pad_config(entity, cfg, fmt->which);
> > +	if (!config) {
> > +		ret = -EINVAL;
> > +		goto done;
> > +	}
> > +
> > +	format = vsp1_entity_get_pad_format(entity, config, fmt->pad);
> > +
> > +	if (fmt->pad != 0) {
> 
> I guess we don't have any clear way to say != *_PAD_SINK here do we ..
> 
> > +		/* The output format can't be modified. */
> > +		fmt->format = *format;
> > +		goto done;
> > +	}
> > +
> > +	/*
> > +	 * Default to the first media bus code if the requested format is not
> > +	 * supported.
> > +	 */
> > +	for (i = 0; i < ncodes; ++i) {
> > +		if (fmt->format.code == codes[i])
> > +			break;
> > +	}
> > +
> > +	format->code = i < ncodes ? codes[i] : codes[0];
> > +	format->width = clamp_t(unsigned int, fmt->format.width,
> > +				min_width, max_width);
> > +	format->height = clamp_t(unsigned int, fmt->format.height,
> > +				 min_height, max_height);
> > +	format->field = V4L2_FIELD_NONE;
> > +	format->colorspace = V4L2_COLORSPACE_SRGB;
> > +
> > +	fmt->format = *format;
> > +
> > +	/* Propagate the format to the source pad. */
> > +	format = vsp1_entity_get_pad_format(entity, config, 1);
> 
> If we can guarantee that ENTITY_PAD_SINK == 0 and ENTITY_PAD_SOURCE == 1,
> can we put those into an enum ?
> 
> > +	*format = fmt->format;
> > +
> > +done:
> > +	mutex_unlock(&entity->lock);
> > +	return ret;
> > +}
> > +
> > 
> >  /*
> >  ------------------------------------------------------------------------
> >  ----->  
> >   * Media Operations
> >   */
> > 
> > diff --git a/drivers/media/platform/vsp1/vsp1_entity.h
> > b/drivers/media/platform/vsp1/vsp1_entity.h index
> > fb20a1578f3b..0839a62cfa71 100644
> > --- a/drivers/media/platform/vsp1/vsp1_entity.h
> > +++ b/drivers/media/platform/vsp1/vsp1_entity.h
> > @@ -160,6 +160,12 @@ struct media_pad *vsp1_entity_remote_pad(struct
> > media_pad *pad);> 
> >  int vsp1_subdev_get_pad_format(struct v4l2_subdev *subdev,
> >  
> >  			       struct v4l2_subdev_pad_config *cfg,
> >  			       struct v4l2_subdev_format *fmt);
> > 
> > +int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev,
> > +			       struct v4l2_subdev_pad_config *cfg,
> > +			       struct v4l2_subdev_format *fmt,
> > +			       const unsigned int *codes, unsigned int ncodes,
> > +			       unsigned int min_width, unsigned int min_height,
> > +			       unsigned int max_width, unsigned int max_height);
> > 
> >  int vsp1_subdev_enum_mbus_code(struct v4l2_subdev *subdev,
> >  
> >  			       struct v4l2_subdev_pad_config *cfg,
> >  			       struct v4l2_subdev_mbus_code_enum *code,
> > 
> > diff --git a/drivers/media/platform/vsp1/vsp1_lif.c
> > b/drivers/media/platform/vsp1/vsp1_lif.c index b20b842f06ba..fbdd5715f829
> > 100644
> > --- a/drivers/media/platform/vsp1/vsp1_lif.c
> > +++ b/drivers/media/platform/vsp1/vsp1_lif.c
> > @@ -33,17 +33,17 @@ static inline void vsp1_lif_write(struct vsp1_lif
> > *lif, struct vsp1_dl_list *dl,> 
> >   * V4L2 Subdevice Operations
> >   */
> > 
> > +static const unsigned int lif_codes[] = {
> > +	MEDIA_BUS_FMT_ARGB8888_1X32,
> > +	MEDIA_BUS_FMT_AYUV8_1X32,
> > +};
> > +
> > 
> >  static int lif_enum_mbus_code(struct v4l2_subdev *subdev,
> >  
> >  			      struct v4l2_subdev_pad_config *cfg,
> >  			      struct v4l2_subdev_mbus_code_enum *code)
> >  
> >  {
> > 
> > -	static const unsigned int codes[] = {
> > -		MEDIA_BUS_FMT_ARGB8888_1X32,
> > -		MEDIA_BUS_FMT_AYUV8_1X32,
> > -	};
> > -
> > -	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, codes,
> > -					  ARRAY_SIZE(codes));
> > +	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, lif_codes,
> > +					  ARRAY_SIZE(lif_codes));
> > 
> >  }
> >  
> >  static int lif_enum_frame_size(struct v4l2_subdev *subdev,
> > 
> > @@ -59,53 +59,10 @@ static int lif_set_format(struct v4l2_subdev *subdev,
> > 
> >  			  struct v4l2_subdev_pad_config *cfg,
> >  			  struct v4l2_subdev_format *fmt)
> >  
> >  {
> > 
> > -	struct vsp1_lif *lif = to_lif(subdev);
> > -	struct v4l2_subdev_pad_config *config;
> > -	struct v4l2_mbus_framefmt *format;
> > -	int ret = 0;
> > -
> > -	mutex_lock(&lif->entity.lock);
> > -
> > -	config = vsp1_entity_get_pad_config(&lif->entity, cfg, fmt->which);
> > -	if (!config) {
> > -		ret = -EINVAL;
> > -		goto done;
> > -	}
> > -
> > -	/* Default to YUV if the requested format is not supported. */
> > -	if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
> > -	    fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32)
> > -		fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32;
> > -
> > -	format = vsp1_entity_get_pad_format(&lif->entity, config, fmt->pad);
> > -
> > -	if (fmt->pad == LIF_PAD_SOURCE) {
> > -		/*
> > -		 * The LIF source format is always identical to its sink
> > -		 * format.
> > -		 */
> > -		fmt->format = *format;
> > -		goto done;
> > -	}
> > -
> > -	format->code = fmt->format.code;
> > -	format->width = clamp_t(unsigned int, fmt->format.width,
> > -				LIF_MIN_SIZE, LIF_MAX_SIZE);
> > -	format->height = clamp_t(unsigned int, fmt->format.height,
> > -				 LIF_MIN_SIZE, LIF_MAX_SIZE);
> > -	format->field = V4L2_FIELD_NONE;
> > -	format->colorspace = V4L2_COLORSPACE_SRGB;
> > -
> > -	fmt->format = *format;
> > -
> > -	/* Propagate the format to the source pad. */
> > -	format = vsp1_entity_get_pad_format(&lif->entity, config,
> > -					    LIF_PAD_SOURCE);
> > -	*format = fmt->format;
> > -
> > -done:
> > -	mutex_unlock(&lif->entity.lock);
> > -	return ret;
> > +	return vsp1_subdev_set_pad_format(subdev, cfg, fmt, lif_codes,
> > +					  ARRAY_SIZE(lif_codes),
> > +					  LIF_MIN_SIZE, LIF_MIN_SIZE,
> > +					  LIF_MAX_SIZE, LIF_MAX_SIZE);
> > 
> >  }
> >  
> >  static const struct v4l2_subdev_pad_ops lif_pad_ops = {
> > 
> > diff --git a/drivers/media/platform/vsp1/vsp1_lut.c
> > b/drivers/media/platform/vsp1/vsp1_lut.c index 7bdabb311c6c..f2e48a02ca7d
> > 100644
> > --- a/drivers/media/platform/vsp1/vsp1_lut.c
> > +++ b/drivers/media/platform/vsp1/vsp1_lut.c
> > @@ -90,18 +90,18 @@ static const struct v4l2_ctrl_config lut_table_control
> > = {> 
> >   * V4L2 Subdevice Pad Operations
> >   */
> > 
> > +static const unsigned int lut_codes[] = {
> > +	MEDIA_BUS_FMT_ARGB8888_1X32,
> > +	MEDIA_BUS_FMT_AHSV8888_1X32,
> > +	MEDIA_BUS_FMT_AYUV8_1X32,
> > +};
> > +
> > 
> >  static int lut_enum_mbus_code(struct v4l2_subdev *subdev,
> >  
> >  			      struct v4l2_subdev_pad_config *cfg,
> >  			      struct v4l2_subdev_mbus_code_enum *code)
> >  
> >  {
> > 
> > -	static const unsigned int codes[] = {
> > -		MEDIA_BUS_FMT_ARGB8888_1X32,
> > -		MEDIA_BUS_FMT_AHSV8888_1X32,
> > -		MEDIA_BUS_FMT_AYUV8_1X32,
> > -	};
> > -
> > -	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, codes,
> > -					  ARRAY_SIZE(codes));
> > +	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, lut_codes,
> > +					  ARRAY_SIZE(lut_codes));
> > 
> >  }
> >  
> >  static int lut_enum_frame_size(struct v4l2_subdev *subdev,
> > 
> > @@ -117,51 +117,10 @@ static int lut_set_format(struct v4l2_subdev
> > *subdev,
> > 
> >  			  struct v4l2_subdev_pad_config *cfg,
> >  			  struct v4l2_subdev_format *fmt)
> >  
> >  {
> > 
> > -	struct vsp1_lut *lut = to_lut(subdev);
> > -	struct v4l2_subdev_pad_config *config;
> > -	struct v4l2_mbus_framefmt *format;
> > -	int ret = 0;
> > -
> > -	mutex_lock(&lut->entity.lock);
> > -
> > -	config = vsp1_entity_get_pad_config(&lut->entity, cfg, fmt->which);
> > -	if (!config) {
> > -		ret = -EINVAL;
> > -		goto done;
> > -	}
> > -
> > -	/* Default to YUV if the requested format is not supported. */
> > -	if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
> > -	    fmt->format.code != MEDIA_BUS_FMT_AHSV8888_1X32 &&
> > -	    fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32)
> > -		fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32;
> > -
> > -	format = vsp1_entity_get_pad_format(&lut->entity, config, fmt->pad);
> > -
> > -	if (fmt->pad == LUT_PAD_SOURCE) {
> > -		/* The LUT output format can't be modified. */
> > -		fmt->format = *format;
> > -		goto done;
> > -	}
> > -
> > -	format->code = fmt->format.code;
> > -	format->width = clamp_t(unsigned int, fmt->format.width,
> > -				LUT_MIN_SIZE, LUT_MAX_SIZE);
> > -	format->height = clamp_t(unsigned int, fmt->format.height,
> > -				 LUT_MIN_SIZE, LUT_MAX_SIZE);
> > -	format->field = V4L2_FIELD_NONE;
> > -	format->colorspace = V4L2_COLORSPACE_SRGB;
> > -
> > -	fmt->format = *format;
> > -
> > -	/* Propagate the format to the source pad. */
> > -	format = vsp1_entity_get_pad_format(&lut->entity, config,
> > -					    LUT_PAD_SOURCE);
> > -	*format = fmt->format;
> > -
> > -done:
> > -	mutex_unlock(&lut->entity.lock);
> > -	return ret;
> > +	return vsp1_subdev_set_pad_format(subdev, cfg, fmt, lut_codes,
> > +					  ARRAY_SIZE(lut_codes),
> > +					  LUT_MIN_SIZE, LUT_MIN_SIZE,
> > +					  LUT_MAX_SIZE, LUT_MAX_SIZE);
> > 
> >  }
> >  
> >  /*
> >  ------------------------------------------------------------------------
> >  -----


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

* Re: [PATCH v2 4/8] v4l: vsp1: Document the vsp1_du_atomic_config structure
  2018-04-22 22:34   ` Laurent Pinchart
@ 2018-04-28 17:29     ` Kieran Bingham
  -1 siblings, 0 replies; 82+ messages in thread
From: Kieran Bingham @ 2018-04-28 17:29 UTC (permalink / raw)
  To: Laurent Pinchart, linux-media, dri-devel; +Cc: linux-renesas-soc


[-- Attachment #1.1: Type: text/plain, Size: 1766 bytes --]

Hi Laurent,

On 22/04/18 23:34, Laurent Pinchart wrote:
> The structure is used in the API that the VSP1 driver exposes to the DU
> driver. Documenting it is thus important.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

I look forward to being reminded to add a doc-line to this structure for my
interlaced support branch which added 'bool interlaced' to this structure before
it was documented, (thus doesn't add a doc string). Maybe me writing this
comment will remind me in the future when I rebase the interlaced patches ;-)


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

> ---
> Changes since v1:
> 
> - Fixed typo
> ---
>  include/media/vsp1.h | 10 ++++++++++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/include/media/vsp1.h b/include/media/vsp1.h
> index 68a8abe4fac5..ff7ef894465d 100644
> --- a/include/media/vsp1.h
> +++ b/include/media/vsp1.h
> @@ -41,6 +41,16 @@ struct vsp1_du_lif_config {
>  int vsp1_du_setup_lif(struct device *dev, unsigned int pipe_index,
>  		      const struct vsp1_du_lif_config *cfg);
>  
> +/**
> + * struct vsp1_du_atomic_config - VSP atomic configuration parameters
> + * @pixelformat: plane pixel format (V4L2 4CC)
> + * @pitch: line pitch in bytes, for all planes
> + * @mem: DMA memory address for each plane of the frame buffer
> + * @src: source rectangle in the frame buffer (integer coordinates)
> + * @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)
> + */
>  struct vsp1_du_atomic_config {
>  	u32 pixelformat;
>  	unsigned int pitch;
> 


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v2 4/8] v4l: vsp1: Document the vsp1_du_atomic_config structure
@ 2018-04-28 17:29     ` Kieran Bingham
  0 siblings, 0 replies; 82+ messages in thread
From: Kieran Bingham @ 2018-04-28 17:29 UTC (permalink / raw)
  To: Laurent Pinchart, linux-media, dri-devel; +Cc: linux-renesas-soc


[-- Attachment #1.1.1: Type: text/plain, Size: 1766 bytes --]

Hi Laurent,

On 22/04/18 23:34, Laurent Pinchart wrote:
> The structure is used in the API that the VSP1 driver exposes to the DU
> driver. Documenting it is thus important.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

I look forward to being reminded to add a doc-line to this structure for my
interlaced support branch which added 'bool interlaced' to this structure before
it was documented, (thus doesn't add a doc string). Maybe me writing this
comment will remind me in the future when I rebase the interlaced patches ;-)


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

> ---
> Changes since v1:
> 
> - Fixed typo
> ---
>  include/media/vsp1.h | 10 ++++++++++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/include/media/vsp1.h b/include/media/vsp1.h
> index 68a8abe4fac5..ff7ef894465d 100644
> --- a/include/media/vsp1.h
> +++ b/include/media/vsp1.h
> @@ -41,6 +41,16 @@ struct vsp1_du_lif_config {
>  int vsp1_du_setup_lif(struct device *dev, unsigned int pipe_index,
>  		      const struct vsp1_du_lif_config *cfg);
>  
> +/**
> + * struct vsp1_du_atomic_config - VSP atomic configuration parameters
> + * @pixelformat: plane pixel format (V4L2 4CC)
> + * @pitch: line pitch in bytes, for all planes
> + * @mem: DMA memory address for each plane of the frame buffer
> + * @src: source rectangle in the frame buffer (integer coordinates)
> + * @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)
> + */
>  struct vsp1_du_atomic_config {
>  	u32 pixelformat;
>  	unsigned int pitch;
> 


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

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

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

* Re: [PATCH v2 2/8] v4l: vsp1: Share the CLU, LIF and LUT set_fmt pad operation code
  2018-04-28 17:25       ` Laurent Pinchart
@ 2018-04-28 17:30         ` Laurent Pinchart
  -1 siblings, 0 replies; 82+ messages in thread
From: Laurent Pinchart @ 2018-04-28 17:30 UTC (permalink / raw)
  To: Kieran Bingham
  Cc: Laurent Pinchart, linux-media, dri-devel, linux-renesas-soc

Hi again,

On Saturday, 28 April 2018 20:25:44 EEST Laurent Pinchart wrote:
> On Saturday, 28 April 2018 20:16:11 EEST Kieran Bingham wrote:
> > On 22/04/18 23:34, Laurent Pinchart wrote:
> > > The implementation of the set_fmt pad operation is identical in the
> > > three modules. Move it to a generic helper function.
> > > 
> > > Signed-off-by: Laurent Pinchart
> > > <laurent.pinchart+renesas@ideasonboard.com>
> > 
> > Only a minor pair of comments below regarding source/sink pad
> > descriptions.
> > 
> > If it's not convenient/accurate to define these with an enum then don't
> > worry about it.
> 
> It's a good point. There are however other locations in vsp1_entity.c that
> hardcode pad numbers, so I'll submit a patch on top of this series to fix
> them all in one go.

Actually I can compare the pad number to entity->source_pad, I'll update this 
patch accordingly in v3.

> > Otherwise,
> > 
> > Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
> > 
> > > ---
> > > 
> > >  drivers/media/platform/vsp1/vsp1_clu.c    | 65 +++++-------------------
> > >  drivers/media/platform/vsp1/vsp1_entity.c | 75
> > >  ++++++++++++++++++++++++++
> > >  drivers/media/platform/vsp1/vsp1_entity.h |  6 +++
> > >  drivers/media/platform/vsp1/vsp1_lif.c    | 65
> > >  +++++--------------------
> > >  drivers/media/platform/vsp1/vsp1_lut.c    | 65
> > >  +++++--------------------
> > >  5 files changed, 116 insertions(+), 160 deletions(-)
> > 
> > That's a nice diffstat :-)
> > 
> > > diff --git a/drivers/media/platform/vsp1/vsp1_clu.c
> > > b/drivers/media/platform/vsp1/vsp1_clu.c index
> > > 9626b6308585..96a448e1504c
> > > 100644
> > > --- a/drivers/media/platform/vsp1/vsp1_clu.c
> > > +++ b/drivers/media/platform/vsp1/vsp1_clu.c
> > > @@ -114,18 +114,18 @@ static const struct v4l2_ctrl_config
> > > clu_mode_control = {>
> > > 
> > >   * V4L2 Subdevice Pad Operations
> > >   */
> > > 
> > > +static const unsigned int clu_codes[] = {
> > > +	MEDIA_BUS_FMT_ARGB8888_1X32,
> > > +	MEDIA_BUS_FMT_AHSV8888_1X32,
> > > +	MEDIA_BUS_FMT_AYUV8_1X32,
> > > +};
> > > +
> > > 
> > >  static int clu_enum_mbus_code(struct v4l2_subdev *subdev,
> > >  
> > >  			      struct v4l2_subdev_pad_config *cfg,
> > >  			      struct v4l2_subdev_mbus_code_enum *code)
> > >  
> > >  {
> > > 
> > > -	static const unsigned int codes[] = {
> > > -		MEDIA_BUS_FMT_ARGB8888_1X32,
> > > -		MEDIA_BUS_FMT_AHSV8888_1X32,
> > > -		MEDIA_BUS_FMT_AYUV8_1X32,
> > > -	};
> > > -
> > > -	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, codes,
> > > -					  ARRAY_SIZE(codes));
> > > +	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, clu_codes,
> > > +					  ARRAY_SIZE(clu_codes));
> > > 
> > >  }
> > >  
> > >  static int clu_enum_frame_size(struct v4l2_subdev *subdev,
> > > 
> > > @@ -141,51 +141,10 @@ static int clu_set_format(struct v4l2_subdev
> > > *subdev,
> > > 
> > >  			  struct v4l2_subdev_pad_config *cfg,
> > >  			  struct v4l2_subdev_format *fmt)
> > >  
> > >  {
> > > 
> > > -	struct vsp1_clu *clu = to_clu(subdev);
> > > -	struct v4l2_subdev_pad_config *config;
> > > -	struct v4l2_mbus_framefmt *format;
> > > -	int ret = 0;
> > > -
> > > -	mutex_lock(&clu->entity.lock);
> > > -
> > > -	config = vsp1_entity_get_pad_config(&clu->entity, cfg, fmt->which);
> > > -	if (!config) {
> > > -		ret = -EINVAL;
> > > -		goto done;
> > > -	}
> > > -
> > > -	/* Default to YUV if the requested format is not supported. */
> > > -	if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
> > > -	    fmt->format.code != MEDIA_BUS_FMT_AHSV8888_1X32 &&
> > > -	    fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32)
> > > -		fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32;
> > > -
> > > -	format = vsp1_entity_get_pad_format(&clu->entity, config, fmt->pad);
> > > -
> > > -	if (fmt->pad == CLU_PAD_SOURCE) {
> > > -		/* The CLU output format can't be modified. */
> > > -		fmt->format = *format;
> > > -		goto done;
> > > -	}
> > > -
> > > -	format->code = fmt->format.code;
> > > -	format->width = clamp_t(unsigned int, fmt->format.width,
> > > -				CLU_MIN_SIZE, CLU_MAX_SIZE);
> > > -	format->height = clamp_t(unsigned int, fmt->format.height,
> > > -				 CLU_MIN_SIZE, CLU_MAX_SIZE);
> > > -	format->field = V4L2_FIELD_NONE;
> > > -	format->colorspace = V4L2_COLORSPACE_SRGB;
> > > -
> > > -	fmt->format = *format;
> > > -
> > > -	/* Propagate the format to the source pad. */
> > > -	format = vsp1_entity_get_pad_format(&clu->entity, config,
> > > -					    CLU_PAD_SOURCE);
> > > -	*format = fmt->format;
> > > -
> > > -done:
> > > -	mutex_unlock(&clu->entity.lock);
> > > -	return ret;
> > > +	return vsp1_subdev_set_pad_format(subdev, cfg, fmt, clu_codes,
> > > +					  ARRAY_SIZE(clu_codes),
> > > +					  CLU_MIN_SIZE, CLU_MIN_SIZE,
> > > +					  CLU_MAX_SIZE, CLU_MAX_SIZE);
> > > 
> > >  }
> > >  
> > >  /*
> > >  -----------------------------------------------------------------------
> > >  -
> > >  ----->
> > > 
> > > diff --git a/drivers/media/platform/vsp1/vsp1_entity.c
> > > b/drivers/media/platform/vsp1/vsp1_entity.c index
> > > 72354caf5746..239df047efd0 100644
> > > --- a/drivers/media/platform/vsp1/vsp1_entity.c
> > > +++ b/drivers/media/platform/vsp1/vsp1_entity.c
> > > @@ -307,6 +307,81 @@ int vsp1_subdev_enum_frame_size(struct v4l2_subdev
> > > *subdev,>
> > > 
> > >  	return ret;
> > >  
> > >  }
> > > 
> > > +/*
> > > + * vsp1_subdev_set_pad_format - Subdev pad set_fmt handler
> > > + * @subdev: V4L2 subdevice
> > > + * @cfg: V4L2 subdev pad configuration
> > > + * @fmt: V4L2 subdev format
> > > + * @codes: Array of supported media bus codes
> > > + * @ncodes: Number of supported media bus codes
> > > + * @min_width: Minimum image width
> > > + * @min_height: Minimum image height
> > > + * @max_width: Maximum image width
> > > + * @max_height: Maximum image height
> > > + *
> > > + * This function implements the subdev set_fmt pad operation for
> > > entities
> > > that
> > > + * do not support scaling or cropping. It defaults to the first
> > > supplied
> > > media
> > > + * bus code if the requested code isn't supported, clamps the size to
> > > the
> > > + * supplied minimum and maximum, and propagates the sink pad format to
> > > the
> > > + * source pad.
> > > + */
> > > +int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev,
> > > +			       struct v4l2_subdev_pad_config *cfg,
> > > +			       struct v4l2_subdev_format *fmt,
> > > +			       const unsigned int *codes, unsigned int ncodes,
> > > +			       unsigned int min_width, unsigned int min_height,
> > > +			       unsigned int max_width, unsigned int max_height)
> > > +{
> > > +	struct vsp1_entity *entity = to_vsp1_entity(subdev);
> > > +	struct v4l2_subdev_pad_config *config;
> > > +	struct v4l2_mbus_framefmt *format;
> > > +	unsigned int i;
> > > +	int ret = 0;
> > > +
> > > +	mutex_lock(&entity->lock);
> > > +
> > > +	config = vsp1_entity_get_pad_config(entity, cfg, fmt->which);
> > > +	if (!config) {
> > > +		ret = -EINVAL;
> > > +		goto done;
> > > +	}
> > > +
> > > +	format = vsp1_entity_get_pad_format(entity, config, fmt->pad);
> > > +
> > > +	if (fmt->pad != 0) {
> > 
> > I guess we don't have any clear way to say != *_PAD_SINK here do we ..
> > 
> > > +		/* The output format can't be modified. */
> > > +		fmt->format = *format;
> > > +		goto done;
> > > +	}
> > > +
> > > +	/*
> > > +	 * Default to the first media bus code if the requested format is 
not
> > > +	 * supported.
> > > +	 */
> > > +	for (i = 0; i < ncodes; ++i) {
> > > +		if (fmt->format.code == codes[i])
> > > +			break;
> > > +	}
> > > +
> > > +	format->code = i < ncodes ? codes[i] : codes[0];
> > > +	format->width = clamp_t(unsigned int, fmt->format.width,
> > > +				min_width, max_width);
> > > +	format->height = clamp_t(unsigned int, fmt->format.height,
> > > +				 min_height, max_height);
> > > +	format->field = V4L2_FIELD_NONE;
> > > +	format->colorspace = V4L2_COLORSPACE_SRGB;
> > > +
> > > +	fmt->format = *format;
> > > +
> > > +	/* Propagate the format to the source pad. */
> > > +	format = vsp1_entity_get_pad_format(entity, config, 1);
> > 
> > If we can guarantee that ENTITY_PAD_SINK == 0 and ENTITY_PAD_SOURCE == 1,
> > can we put those into an enum ?
> > 
> > > +	*format = fmt->format;
> > > +
> > > +done:
> > > +	mutex_unlock(&entity->lock);
> > > +	return ret;
> > > +}
> > > +
> > > 
> > >  /*
> > >  -----------------------------------------------------------------------
> > >  -
> > >  ----->
> > >  
> > >   * Media Operations
> > >   */
> > > 
> > > diff --git a/drivers/media/platform/vsp1/vsp1_entity.h
> > > b/drivers/media/platform/vsp1/vsp1_entity.h index
> > > fb20a1578f3b..0839a62cfa71 100644
> > > --- a/drivers/media/platform/vsp1/vsp1_entity.h
> > > +++ b/drivers/media/platform/vsp1/vsp1_entity.h
> > > @@ -160,6 +160,12 @@ struct media_pad *vsp1_entity_remote_pad(struct
> > > media_pad *pad);>
> > > 
> > >  int vsp1_subdev_get_pad_format(struct v4l2_subdev *subdev,
> > >  
> > >  			       struct v4l2_subdev_pad_config *cfg,
> > >  			       struct v4l2_subdev_format *fmt);
> > > 
> > > +int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev,
> > > +			       struct v4l2_subdev_pad_config *cfg,
> > > +			       struct v4l2_subdev_format *fmt,
> > > +			       const unsigned int *codes, unsigned int ncodes,
> > > +			       unsigned int min_width, unsigned int min_height,
> > > +			       unsigned int max_width, unsigned int max_height);
> > > 
> > >  int vsp1_subdev_enum_mbus_code(struct v4l2_subdev *subdev,
> > >  
> > >  			       struct v4l2_subdev_pad_config *cfg,
> > >  			       struct v4l2_subdev_mbus_code_enum *code,
> > > 
> > > diff --git a/drivers/media/platform/vsp1/vsp1_lif.c
> > > b/drivers/media/platform/vsp1/vsp1_lif.c index
> > > b20b842f06ba..fbdd5715f829
> > > 100644
> > > --- a/drivers/media/platform/vsp1/vsp1_lif.c
> > > +++ b/drivers/media/platform/vsp1/vsp1_lif.c
> > > @@ -33,17 +33,17 @@ static inline void vsp1_lif_write(struct vsp1_lif
> > > *lif, struct vsp1_dl_list *dl,>
> > > 
> > >   * V4L2 Subdevice Operations
> > >   */
> > > 
> > > +static const unsigned int lif_codes[] = {
> > > +	MEDIA_BUS_FMT_ARGB8888_1X32,
> > > +	MEDIA_BUS_FMT_AYUV8_1X32,
> > > +};
> > > +
> > > 
> > >  static int lif_enum_mbus_code(struct v4l2_subdev *subdev,
> > >  
> > >  			      struct v4l2_subdev_pad_config *cfg,
> > >  			      struct v4l2_subdev_mbus_code_enum *code)
> > >  
> > >  {
> > > 
> > > -	static const unsigned int codes[] = {
> > > -		MEDIA_BUS_FMT_ARGB8888_1X32,
> > > -		MEDIA_BUS_FMT_AYUV8_1X32,
> > > -	};
> > > -
> > > -	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, codes,
> > > -					  ARRAY_SIZE(codes));
> > > +	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, lif_codes,
> > > +					  ARRAY_SIZE(lif_codes));
> > > 
> > >  }
> > >  
> > >  static int lif_enum_frame_size(struct v4l2_subdev *subdev,
> > > 
> > > @@ -59,53 +59,10 @@ static int lif_set_format(struct v4l2_subdev
> > > *subdev,
> > > 
> > >  			  struct v4l2_subdev_pad_config *cfg,
> > >  			  struct v4l2_subdev_format *fmt)
> > >  
> > >  {
> > > 
> > > -	struct vsp1_lif *lif = to_lif(subdev);
> > > -	struct v4l2_subdev_pad_config *config;
> > > -	struct v4l2_mbus_framefmt *format;
> > > -	int ret = 0;
> > > -
> > > -	mutex_lock(&lif->entity.lock);
> > > -
> > > -	config = vsp1_entity_get_pad_config(&lif->entity, cfg, fmt->which);
> > > -	if (!config) {
> > > -		ret = -EINVAL;
> > > -		goto done;
> > > -	}
> > > -
> > > -	/* Default to YUV if the requested format is not supported. */
> > > -	if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
> > > -	    fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32)
> > > -		fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32;
> > > -
> > > -	format = vsp1_entity_get_pad_format(&lif->entity, config, fmt->pad);
> > > -
> > > -	if (fmt->pad == LIF_PAD_SOURCE) {
> > > -		/*
> > > -		 * The LIF source format is always identical to its sink
> > > -		 * format.
> > > -		 */
> > > -		fmt->format = *format;
> > > -		goto done;
> > > -	}
> > > -
> > > -	format->code = fmt->format.code;
> > > -	format->width = clamp_t(unsigned int, fmt->format.width,
> > > -				LIF_MIN_SIZE, LIF_MAX_SIZE);
> > > -	format->height = clamp_t(unsigned int, fmt->format.height,
> > > -				 LIF_MIN_SIZE, LIF_MAX_SIZE);
> > > -	format->field = V4L2_FIELD_NONE;
> > > -	format->colorspace = V4L2_COLORSPACE_SRGB;
> > > -
> > > -	fmt->format = *format;
> > > -
> > > -	/* Propagate the format to the source pad. */
> > > -	format = vsp1_entity_get_pad_format(&lif->entity, config,
> > > -					    LIF_PAD_SOURCE);
> > > -	*format = fmt->format;
> > > -
> > > -done:
> > > -	mutex_unlock(&lif->entity.lock);
> > > -	return ret;
> > > +	return vsp1_subdev_set_pad_format(subdev, cfg, fmt, lif_codes,
> > > +					  ARRAY_SIZE(lif_codes),
> > > +					  LIF_MIN_SIZE, LIF_MIN_SIZE,
> > > +					  LIF_MAX_SIZE, LIF_MAX_SIZE);
> > > 
> > >  }
> > >  
> > >  static const struct v4l2_subdev_pad_ops lif_pad_ops = {
> > > 
> > > diff --git a/drivers/media/platform/vsp1/vsp1_lut.c
> > > b/drivers/media/platform/vsp1/vsp1_lut.c index
> > > 7bdabb311c6c..f2e48a02ca7d
> > > 100644
> > > --- a/drivers/media/platform/vsp1/vsp1_lut.c
> > > +++ b/drivers/media/platform/vsp1/vsp1_lut.c
> > > @@ -90,18 +90,18 @@ static const struct v4l2_ctrl_config
> > > lut_table_control
> > > = {>
> > > 
> > >   * V4L2 Subdevice Pad Operations
> > >   */
> > > 
> > > +static const unsigned int lut_codes[] = {
> > > +	MEDIA_BUS_FMT_ARGB8888_1X32,
> > > +	MEDIA_BUS_FMT_AHSV8888_1X32,
> > > +	MEDIA_BUS_FMT_AYUV8_1X32,
> > > +};
> > > +
> > > 
> > >  static int lut_enum_mbus_code(struct v4l2_subdev *subdev,
> > >  
> > >  			      struct v4l2_subdev_pad_config *cfg,
> > >  			      struct v4l2_subdev_mbus_code_enum *code)
> > >  
> > >  {
> > > 
> > > -	static const unsigned int codes[] = {
> > > -		MEDIA_BUS_FMT_ARGB8888_1X32,
> > > -		MEDIA_BUS_FMT_AHSV8888_1X32,
> > > -		MEDIA_BUS_FMT_AYUV8_1X32,
> > > -	};
> > > -
> > > -	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, codes,
> > > -					  ARRAY_SIZE(codes));
> > > +	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, lut_codes,
> > > +					  ARRAY_SIZE(lut_codes));
> > > 
> > >  }
> > >  
> > >  static int lut_enum_frame_size(struct v4l2_subdev *subdev,
> > > 
> > > @@ -117,51 +117,10 @@ static int lut_set_format(struct v4l2_subdev
> > > *subdev,
> > > 
> > >  			  struct v4l2_subdev_pad_config *cfg,
> > >  			  struct v4l2_subdev_format *fmt)
> > >  
> > >  {
> > > 
> > > -	struct vsp1_lut *lut = to_lut(subdev);
> > > -	struct v4l2_subdev_pad_config *config;
> > > -	struct v4l2_mbus_framefmt *format;
> > > -	int ret = 0;
> > > -
> > > -	mutex_lock(&lut->entity.lock);
> > > -
> > > -	config = vsp1_entity_get_pad_config(&lut->entity, cfg, fmt->which);
> > > -	if (!config) {
> > > -		ret = -EINVAL;
> > > -		goto done;
> > > -	}
> > > -
> > > -	/* Default to YUV if the requested format is not supported. */
> > > -	if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
> > > -	    fmt->format.code != MEDIA_BUS_FMT_AHSV8888_1X32 &&
> > > -	    fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32)
> > > -		fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32;
> > > -
> > > -	format = vsp1_entity_get_pad_format(&lut->entity, config, fmt->pad);
> > > -
> > > -	if (fmt->pad == LUT_PAD_SOURCE) {
> > > -		/* The LUT output format can't be modified. */
> > > -		fmt->format = *format;
> > > -		goto done;
> > > -	}
> > > -
> > > -	format->code = fmt->format.code;
> > > -	format->width = clamp_t(unsigned int, fmt->format.width,
> > > -				LUT_MIN_SIZE, LUT_MAX_SIZE);
> > > -	format->height = clamp_t(unsigned int, fmt->format.height,
> > > -				 LUT_MIN_SIZE, LUT_MAX_SIZE);
> > > -	format->field = V4L2_FIELD_NONE;
> > > -	format->colorspace = V4L2_COLORSPACE_SRGB;
> > > -
> > > -	fmt->format = *format;
> > > -
> > > -	/* Propagate the format to the source pad. */
> > > -	format = vsp1_entity_get_pad_format(&lut->entity, config,
> > > -					    LUT_PAD_SOURCE);
> > > -	*format = fmt->format;
> > > -
> > > -done:
> > > -	mutex_unlock(&lut->entity.lock);
> > > -	return ret;
> > > +	return vsp1_subdev_set_pad_format(subdev, cfg, fmt, lut_codes,
> > > +					  ARRAY_SIZE(lut_codes),
> > > +					  LUT_MIN_SIZE, LUT_MIN_SIZE,
> > > +					  LUT_MAX_SIZE, LUT_MAX_SIZE);
> > > 
> > >  }
> > >  
> > >  /*
> > >  -----------------------------------------------------------------------
> > >  -
> > >  -----


-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v2 2/8] v4l: vsp1: Share the CLU, LIF and LUT set_fmt pad operation code
@ 2018-04-28 17:30         ` Laurent Pinchart
  0 siblings, 0 replies; 82+ messages in thread
From: Laurent Pinchart @ 2018-04-28 17:30 UTC (permalink / raw)
  To: Kieran Bingham
  Cc: linux-renesas-soc, Laurent Pinchart, dri-devel, linux-media

Hi again,

On Saturday, 28 April 2018 20:25:44 EEST Laurent Pinchart wrote:
> On Saturday, 28 April 2018 20:16:11 EEST Kieran Bingham wrote:
> > On 22/04/18 23:34, Laurent Pinchart wrote:
> > > The implementation of the set_fmt pad operation is identical in the
> > > three modules. Move it to a generic helper function.
> > > 
> > > Signed-off-by: Laurent Pinchart
> > > <laurent.pinchart+renesas@ideasonboard.com>
> > 
> > Only a minor pair of comments below regarding source/sink pad
> > descriptions.
> > 
> > If it's not convenient/accurate to define these with an enum then don't
> > worry about it.
> 
> It's a good point. There are however other locations in vsp1_entity.c that
> hardcode pad numbers, so I'll submit a patch on top of this series to fix
> them all in one go.

Actually I can compare the pad number to entity->source_pad, I'll update this 
patch accordingly in v3.

> > Otherwise,
> > 
> > Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
> > 
> > > ---
> > > 
> > >  drivers/media/platform/vsp1/vsp1_clu.c    | 65 +++++-------------------
> > >  drivers/media/platform/vsp1/vsp1_entity.c | 75
> > >  ++++++++++++++++++++++++++
> > >  drivers/media/platform/vsp1/vsp1_entity.h |  6 +++
> > >  drivers/media/platform/vsp1/vsp1_lif.c    | 65
> > >  +++++--------------------
> > >  drivers/media/platform/vsp1/vsp1_lut.c    | 65
> > >  +++++--------------------
> > >  5 files changed, 116 insertions(+), 160 deletions(-)
> > 
> > That's a nice diffstat :-)
> > 
> > > diff --git a/drivers/media/platform/vsp1/vsp1_clu.c
> > > b/drivers/media/platform/vsp1/vsp1_clu.c index
> > > 9626b6308585..96a448e1504c
> > > 100644
> > > --- a/drivers/media/platform/vsp1/vsp1_clu.c
> > > +++ b/drivers/media/platform/vsp1/vsp1_clu.c
> > > @@ -114,18 +114,18 @@ static const struct v4l2_ctrl_config
> > > clu_mode_control = {>
> > > 
> > >   * V4L2 Subdevice Pad Operations
> > >   */
> > > 
> > > +static const unsigned int clu_codes[] = {
> > > +	MEDIA_BUS_FMT_ARGB8888_1X32,
> > > +	MEDIA_BUS_FMT_AHSV8888_1X32,
> > > +	MEDIA_BUS_FMT_AYUV8_1X32,
> > > +};
> > > +
> > > 
> > >  static int clu_enum_mbus_code(struct v4l2_subdev *subdev,
> > >  
> > >  			      struct v4l2_subdev_pad_config *cfg,
> > >  			      struct v4l2_subdev_mbus_code_enum *code)
> > >  
> > >  {
> > > 
> > > -	static const unsigned int codes[] = {
> > > -		MEDIA_BUS_FMT_ARGB8888_1X32,
> > > -		MEDIA_BUS_FMT_AHSV8888_1X32,
> > > -		MEDIA_BUS_FMT_AYUV8_1X32,
> > > -	};
> > > -
> > > -	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, codes,
> > > -					  ARRAY_SIZE(codes));
> > > +	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, clu_codes,
> > > +					  ARRAY_SIZE(clu_codes));
> > > 
> > >  }
> > >  
> > >  static int clu_enum_frame_size(struct v4l2_subdev *subdev,
> > > 
> > > @@ -141,51 +141,10 @@ static int clu_set_format(struct v4l2_subdev
> > > *subdev,
> > > 
> > >  			  struct v4l2_subdev_pad_config *cfg,
> > >  			  struct v4l2_subdev_format *fmt)
> > >  
> > >  {
> > > 
> > > -	struct vsp1_clu *clu = to_clu(subdev);
> > > -	struct v4l2_subdev_pad_config *config;
> > > -	struct v4l2_mbus_framefmt *format;
> > > -	int ret = 0;
> > > -
> > > -	mutex_lock(&clu->entity.lock);
> > > -
> > > -	config = vsp1_entity_get_pad_config(&clu->entity, cfg, fmt->which);
> > > -	if (!config) {
> > > -		ret = -EINVAL;
> > > -		goto done;
> > > -	}
> > > -
> > > -	/* Default to YUV if the requested format is not supported. */
> > > -	if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
> > > -	    fmt->format.code != MEDIA_BUS_FMT_AHSV8888_1X32 &&
> > > -	    fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32)
> > > -		fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32;
> > > -
> > > -	format = vsp1_entity_get_pad_format(&clu->entity, config, fmt->pad);
> > > -
> > > -	if (fmt->pad == CLU_PAD_SOURCE) {
> > > -		/* The CLU output format can't be modified. */
> > > -		fmt->format = *format;
> > > -		goto done;
> > > -	}
> > > -
> > > -	format->code = fmt->format.code;
> > > -	format->width = clamp_t(unsigned int, fmt->format.width,
> > > -				CLU_MIN_SIZE, CLU_MAX_SIZE);
> > > -	format->height = clamp_t(unsigned int, fmt->format.height,
> > > -				 CLU_MIN_SIZE, CLU_MAX_SIZE);
> > > -	format->field = V4L2_FIELD_NONE;
> > > -	format->colorspace = V4L2_COLORSPACE_SRGB;
> > > -
> > > -	fmt->format = *format;
> > > -
> > > -	/* Propagate the format to the source pad. */
> > > -	format = vsp1_entity_get_pad_format(&clu->entity, config,
> > > -					    CLU_PAD_SOURCE);
> > > -	*format = fmt->format;
> > > -
> > > -done:
> > > -	mutex_unlock(&clu->entity.lock);
> > > -	return ret;
> > > +	return vsp1_subdev_set_pad_format(subdev, cfg, fmt, clu_codes,
> > > +					  ARRAY_SIZE(clu_codes),
> > > +					  CLU_MIN_SIZE, CLU_MIN_SIZE,
> > > +					  CLU_MAX_SIZE, CLU_MAX_SIZE);
> > > 
> > >  }
> > >  
> > >  /*
> > >  -----------------------------------------------------------------------
> > >  -
> > >  ----->
> > > 
> > > diff --git a/drivers/media/platform/vsp1/vsp1_entity.c
> > > b/drivers/media/platform/vsp1/vsp1_entity.c index
> > > 72354caf5746..239df047efd0 100644
> > > --- a/drivers/media/platform/vsp1/vsp1_entity.c
> > > +++ b/drivers/media/platform/vsp1/vsp1_entity.c
> > > @@ -307,6 +307,81 @@ int vsp1_subdev_enum_frame_size(struct v4l2_subdev
> > > *subdev,>
> > > 
> > >  	return ret;
> > >  
> > >  }
> > > 
> > > +/*
> > > + * vsp1_subdev_set_pad_format - Subdev pad set_fmt handler
> > > + * @subdev: V4L2 subdevice
> > > + * @cfg: V4L2 subdev pad configuration
> > > + * @fmt: V4L2 subdev format
> > > + * @codes: Array of supported media bus codes
> > > + * @ncodes: Number of supported media bus codes
> > > + * @min_width: Minimum image width
> > > + * @min_height: Minimum image height
> > > + * @max_width: Maximum image width
> > > + * @max_height: Maximum image height
> > > + *
> > > + * This function implements the subdev set_fmt pad operation for
> > > entities
> > > that
> > > + * do not support scaling or cropping. It defaults to the first
> > > supplied
> > > media
> > > + * bus code if the requested code isn't supported, clamps the size to
> > > the
> > > + * supplied minimum and maximum, and propagates the sink pad format to
> > > the
> > > + * source pad.
> > > + */
> > > +int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev,
> > > +			       struct v4l2_subdev_pad_config *cfg,
> > > +			       struct v4l2_subdev_format *fmt,
> > > +			       const unsigned int *codes, unsigned int ncodes,
> > > +			       unsigned int min_width, unsigned int min_height,
> > > +			       unsigned int max_width, unsigned int max_height)
> > > +{
> > > +	struct vsp1_entity *entity = to_vsp1_entity(subdev);
> > > +	struct v4l2_subdev_pad_config *config;
> > > +	struct v4l2_mbus_framefmt *format;
> > > +	unsigned int i;
> > > +	int ret = 0;
> > > +
> > > +	mutex_lock(&entity->lock);
> > > +
> > > +	config = vsp1_entity_get_pad_config(entity, cfg, fmt->which);
> > > +	if (!config) {
> > > +		ret = -EINVAL;
> > > +		goto done;
> > > +	}
> > > +
> > > +	format = vsp1_entity_get_pad_format(entity, config, fmt->pad);
> > > +
> > > +	if (fmt->pad != 0) {
> > 
> > I guess we don't have any clear way to say != *_PAD_SINK here do we ..
> > 
> > > +		/* The output format can't be modified. */
> > > +		fmt->format = *format;
> > > +		goto done;
> > > +	}
> > > +
> > > +	/*
> > > +	 * Default to the first media bus code if the requested format is 
not
> > > +	 * supported.
> > > +	 */
> > > +	for (i = 0; i < ncodes; ++i) {
> > > +		if (fmt->format.code == codes[i])
> > > +			break;
> > > +	}
> > > +
> > > +	format->code = i < ncodes ? codes[i] : codes[0];
> > > +	format->width = clamp_t(unsigned int, fmt->format.width,
> > > +				min_width, max_width);
> > > +	format->height = clamp_t(unsigned int, fmt->format.height,
> > > +				 min_height, max_height);
> > > +	format->field = V4L2_FIELD_NONE;
> > > +	format->colorspace = V4L2_COLORSPACE_SRGB;
> > > +
> > > +	fmt->format = *format;
> > > +
> > > +	/* Propagate the format to the source pad. */
> > > +	format = vsp1_entity_get_pad_format(entity, config, 1);
> > 
> > If we can guarantee that ENTITY_PAD_SINK == 0 and ENTITY_PAD_SOURCE == 1,
> > can we put those into an enum ?
> > 
> > > +	*format = fmt->format;
> > > +
> > > +done:
> > > +	mutex_unlock(&entity->lock);
> > > +	return ret;
> > > +}
> > > +
> > > 
> > >  /*
> > >  -----------------------------------------------------------------------
> > >  -
> > >  ----->
> > >  
> > >   * Media Operations
> > >   */
> > > 
> > > diff --git a/drivers/media/platform/vsp1/vsp1_entity.h
> > > b/drivers/media/platform/vsp1/vsp1_entity.h index
> > > fb20a1578f3b..0839a62cfa71 100644
> > > --- a/drivers/media/platform/vsp1/vsp1_entity.h
> > > +++ b/drivers/media/platform/vsp1/vsp1_entity.h
> > > @@ -160,6 +160,12 @@ struct media_pad *vsp1_entity_remote_pad(struct
> > > media_pad *pad);>
> > > 
> > >  int vsp1_subdev_get_pad_format(struct v4l2_subdev *subdev,
> > >  
> > >  			       struct v4l2_subdev_pad_config *cfg,
> > >  			       struct v4l2_subdev_format *fmt);
> > > 
> > > +int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev,
> > > +			       struct v4l2_subdev_pad_config *cfg,
> > > +			       struct v4l2_subdev_format *fmt,
> > > +			       const unsigned int *codes, unsigned int ncodes,
> > > +			       unsigned int min_width, unsigned int min_height,
> > > +			       unsigned int max_width, unsigned int max_height);
> > > 
> > >  int vsp1_subdev_enum_mbus_code(struct v4l2_subdev *subdev,
> > >  
> > >  			       struct v4l2_subdev_pad_config *cfg,
> > >  			       struct v4l2_subdev_mbus_code_enum *code,
> > > 
> > > diff --git a/drivers/media/platform/vsp1/vsp1_lif.c
> > > b/drivers/media/platform/vsp1/vsp1_lif.c index
> > > b20b842f06ba..fbdd5715f829
> > > 100644
> > > --- a/drivers/media/platform/vsp1/vsp1_lif.c
> > > +++ b/drivers/media/platform/vsp1/vsp1_lif.c
> > > @@ -33,17 +33,17 @@ static inline void vsp1_lif_write(struct vsp1_lif
> > > *lif, struct vsp1_dl_list *dl,>
> > > 
> > >   * V4L2 Subdevice Operations
> > >   */
> > > 
> > > +static const unsigned int lif_codes[] = {
> > > +	MEDIA_BUS_FMT_ARGB8888_1X32,
> > > +	MEDIA_BUS_FMT_AYUV8_1X32,
> > > +};
> > > +
> > > 
> > >  static int lif_enum_mbus_code(struct v4l2_subdev *subdev,
> > >  
> > >  			      struct v4l2_subdev_pad_config *cfg,
> > >  			      struct v4l2_subdev_mbus_code_enum *code)
> > >  
> > >  {
> > > 
> > > -	static const unsigned int codes[] = {
> > > -		MEDIA_BUS_FMT_ARGB8888_1X32,
> > > -		MEDIA_BUS_FMT_AYUV8_1X32,
> > > -	};
> > > -
> > > -	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, codes,
> > > -					  ARRAY_SIZE(codes));
> > > +	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, lif_codes,
> > > +					  ARRAY_SIZE(lif_codes));
> > > 
> > >  }
> > >  
> > >  static int lif_enum_frame_size(struct v4l2_subdev *subdev,
> > > 
> > > @@ -59,53 +59,10 @@ static int lif_set_format(struct v4l2_subdev
> > > *subdev,
> > > 
> > >  			  struct v4l2_subdev_pad_config *cfg,
> > >  			  struct v4l2_subdev_format *fmt)
> > >  
> > >  {
> > > 
> > > -	struct vsp1_lif *lif = to_lif(subdev);
> > > -	struct v4l2_subdev_pad_config *config;
> > > -	struct v4l2_mbus_framefmt *format;
> > > -	int ret = 0;
> > > -
> > > -	mutex_lock(&lif->entity.lock);
> > > -
> > > -	config = vsp1_entity_get_pad_config(&lif->entity, cfg, fmt->which);
> > > -	if (!config) {
> > > -		ret = -EINVAL;
> > > -		goto done;
> > > -	}
> > > -
> > > -	/* Default to YUV if the requested format is not supported. */
> > > -	if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
> > > -	    fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32)
> > > -		fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32;
> > > -
> > > -	format = vsp1_entity_get_pad_format(&lif->entity, config, fmt->pad);
> > > -
> > > -	if (fmt->pad == LIF_PAD_SOURCE) {
> > > -		/*
> > > -		 * The LIF source format is always identical to its sink
> > > -		 * format.
> > > -		 */
> > > -		fmt->format = *format;
> > > -		goto done;
> > > -	}
> > > -
> > > -	format->code = fmt->format.code;
> > > -	format->width = clamp_t(unsigned int, fmt->format.width,
> > > -				LIF_MIN_SIZE, LIF_MAX_SIZE);
> > > -	format->height = clamp_t(unsigned int, fmt->format.height,
> > > -				 LIF_MIN_SIZE, LIF_MAX_SIZE);
> > > -	format->field = V4L2_FIELD_NONE;
> > > -	format->colorspace = V4L2_COLORSPACE_SRGB;
> > > -
> > > -	fmt->format = *format;
> > > -
> > > -	/* Propagate the format to the source pad. */
> > > -	format = vsp1_entity_get_pad_format(&lif->entity, config,
> > > -					    LIF_PAD_SOURCE);
> > > -	*format = fmt->format;
> > > -
> > > -done:
> > > -	mutex_unlock(&lif->entity.lock);
> > > -	return ret;
> > > +	return vsp1_subdev_set_pad_format(subdev, cfg, fmt, lif_codes,
> > > +					  ARRAY_SIZE(lif_codes),
> > > +					  LIF_MIN_SIZE, LIF_MIN_SIZE,
> > > +					  LIF_MAX_SIZE, LIF_MAX_SIZE);
> > > 
> > >  }
> > >  
> > >  static const struct v4l2_subdev_pad_ops lif_pad_ops = {
> > > 
> > > diff --git a/drivers/media/platform/vsp1/vsp1_lut.c
> > > b/drivers/media/platform/vsp1/vsp1_lut.c index
> > > 7bdabb311c6c..f2e48a02ca7d
> > > 100644
> > > --- a/drivers/media/platform/vsp1/vsp1_lut.c
> > > +++ b/drivers/media/platform/vsp1/vsp1_lut.c
> > > @@ -90,18 +90,18 @@ static const struct v4l2_ctrl_config
> > > lut_table_control
> > > = {>
> > > 
> > >   * V4L2 Subdevice Pad Operations
> > >   */
> > > 
> > > +static const unsigned int lut_codes[] = {
> > > +	MEDIA_BUS_FMT_ARGB8888_1X32,
> > > +	MEDIA_BUS_FMT_AHSV8888_1X32,
> > > +	MEDIA_BUS_FMT_AYUV8_1X32,
> > > +};
> > > +
> > > 
> > >  static int lut_enum_mbus_code(struct v4l2_subdev *subdev,
> > >  
> > >  			      struct v4l2_subdev_pad_config *cfg,
> > >  			      struct v4l2_subdev_mbus_code_enum *code)
> > >  
> > >  {
> > > 
> > > -	static const unsigned int codes[] = {
> > > -		MEDIA_BUS_FMT_ARGB8888_1X32,
> > > -		MEDIA_BUS_FMT_AHSV8888_1X32,
> > > -		MEDIA_BUS_FMT_AYUV8_1X32,
> > > -	};
> > > -
> > > -	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, codes,
> > > -					  ARRAY_SIZE(codes));
> > > +	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, lut_codes,
> > > +					  ARRAY_SIZE(lut_codes));
> > > 
> > >  }
> > >  
> > >  static int lut_enum_frame_size(struct v4l2_subdev *subdev,
> > > 
> > > @@ -117,51 +117,10 @@ static int lut_set_format(struct v4l2_subdev
> > > *subdev,
> > > 
> > >  			  struct v4l2_subdev_pad_config *cfg,
> > >  			  struct v4l2_subdev_format *fmt)
> > >  
> > >  {
> > > 
> > > -	struct vsp1_lut *lut = to_lut(subdev);
> > > -	struct v4l2_subdev_pad_config *config;
> > > -	struct v4l2_mbus_framefmt *format;
> > > -	int ret = 0;
> > > -
> > > -	mutex_lock(&lut->entity.lock);
> > > -
> > > -	config = vsp1_entity_get_pad_config(&lut->entity, cfg, fmt->which);
> > > -	if (!config) {
> > > -		ret = -EINVAL;
> > > -		goto done;
> > > -	}
> > > -
> > > -	/* Default to YUV if the requested format is not supported. */
> > > -	if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
> > > -	    fmt->format.code != MEDIA_BUS_FMT_AHSV8888_1X32 &&
> > > -	    fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32)
> > > -		fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32;
> > > -
> > > -	format = vsp1_entity_get_pad_format(&lut->entity, config, fmt->pad);
> > > -
> > > -	if (fmt->pad == LUT_PAD_SOURCE) {
> > > -		/* The LUT output format can't be modified. */
> > > -		fmt->format = *format;
> > > -		goto done;
> > > -	}
> > > -
> > > -	format->code = fmt->format.code;
> > > -	format->width = clamp_t(unsigned int, fmt->format.width,
> > > -				LUT_MIN_SIZE, LUT_MAX_SIZE);
> > > -	format->height = clamp_t(unsigned int, fmt->format.height,
> > > -				 LUT_MIN_SIZE, LUT_MAX_SIZE);
> > > -	format->field = V4L2_FIELD_NONE;
> > > -	format->colorspace = V4L2_COLORSPACE_SRGB;
> > > -
> > > -	fmt->format = *format;
> > > -
> > > -	/* Propagate the format to the source pad. */
> > > -	format = vsp1_entity_get_pad_format(&lut->entity, config,
> > > -					    LUT_PAD_SOURCE);
> > > -	*format = fmt->format;
> > > -
> > > -done:
> > > -	mutex_unlock(&lut->entity.lock);
> > > -	return ret;
> > > +	return vsp1_subdev_set_pad_format(subdev, cfg, fmt, lut_codes,
> > > +					  ARRAY_SIZE(lut_codes),
> > > +					  LUT_MIN_SIZE, LUT_MIN_SIZE,
> > > +					  LUT_MAX_SIZE, LUT_MAX_SIZE);
> > > 
> > >  }
> > >  
> > >  /*
> > >  -----------------------------------------------------------------------
> > >  -
> > >  -----


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

* Re: [PATCH v2 2/8] v4l: vsp1: Share the CLU, LIF and LUT set_fmt pad operation code
  2018-04-28 17:30         ` Laurent Pinchart
@ 2018-04-28 17:32           ` Kieran Bingham
  -1 siblings, 0 replies; 82+ messages in thread
From: Kieran Bingham @ 2018-04-28 17:32 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Laurent Pinchart, linux-media, dri-devel, linux-renesas-soc


[-- Attachment #1.1: Type: text/plain, Size: 1110 bytes --]

On 28/04/18 18:30, Laurent Pinchart wrote:
> Hi again,
> 
> On Saturday, 28 April 2018 20:25:44 EEST Laurent Pinchart wrote:
>> On Saturday, 28 April 2018 20:16:11 EEST Kieran Bingham wrote:
>>> On 22/04/18 23:34, Laurent Pinchart wrote:
>>>> The implementation of the set_fmt pad operation is identical in the
>>>> three modules. Move it to a generic helper function.
>>>>
>>>> Signed-off-by: Laurent Pinchart
>>>> <laurent.pinchart+renesas@ideasonboard.com>
>>>
>>> Only a minor pair of comments below regarding source/sink pad
>>> descriptions.
>>>
>>> If it's not convenient/accurate to define these with an enum then don't
>>> worry about it.
>>
>> It's a good point. There are however other locations in vsp1_entity.c that
>> hardcode pad numbers, so I'll submit a patch on top of this series to fix
>> them all in one go.
> 
> Actually I can compare the pad number to entity->source_pad, I'll update this 
> patch accordingly in v3.

Perfect, that sounds more explicit, easier to read, and future proof against
entities with multiple sinks, such as the BRx.

--
Kieran



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v2 2/8] v4l: vsp1: Share the CLU, LIF and LUT set_fmt pad operation code
@ 2018-04-28 17:32           ` Kieran Bingham
  0 siblings, 0 replies; 82+ messages in thread
From: Kieran Bingham @ 2018-04-28 17:32 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: linux-renesas-soc, Laurent Pinchart, dri-devel, linux-media


[-- Attachment #1.1.1: Type: text/plain, Size: 1110 bytes --]

On 28/04/18 18:30, Laurent Pinchart wrote:
> Hi again,
> 
> On Saturday, 28 April 2018 20:25:44 EEST Laurent Pinchart wrote:
>> On Saturday, 28 April 2018 20:16:11 EEST Kieran Bingham wrote:
>>> On 22/04/18 23:34, Laurent Pinchart wrote:
>>>> The implementation of the set_fmt pad operation is identical in the
>>>> three modules. Move it to a generic helper function.
>>>>
>>>> Signed-off-by: Laurent Pinchart
>>>> <laurent.pinchart+renesas@ideasonboard.com>
>>>
>>> Only a minor pair of comments below regarding source/sink pad
>>> descriptions.
>>>
>>> If it's not convenient/accurate to define these with an enum then don't
>>> worry about it.
>>
>> It's a good point. There are however other locations in vsp1_entity.c that
>> hardcode pad numbers, so I'll submit a patch on top of this series to fix
>> them all in one go.
> 
> Actually I can compare the pad number to entity->source_pad, I'll update this 
> patch accordingly in v3.

Perfect, that sounds more explicit, easier to read, and future proof against
entities with multiple sinks, such as the BRx.

--
Kieran



[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

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

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

* Re: [PATCH v2 5/8] v4l: vsp1: Extend the DU API to support CRC computation
  2018-04-22 22:34   ` Laurent Pinchart
@ 2018-04-28 17:48     ` Kieran Bingham
  -1 siblings, 0 replies; 82+ messages in thread
From: Kieran Bingham @ 2018-04-28 17:48 UTC (permalink / raw)
  To: Laurent Pinchart, linux-media, dri-devel; +Cc: linux-renesas-soc


[-- Attachment #1.1: Type: text/plain, Size: 5840 bytes --]

Hi Laurent,

On 22/04/18 23:34, Laurent Pinchart wrote:
> Add a parameter (in the form of a structure to ease future API
> extensions) to the VSP atomic flush handler to pass CRC source
> configuration, and pass the CRC value to the completion callback.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

Only a minor 'thought' below.
(And Jacopo already caught the enum typos, so with those are fixed...)

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

> ---
>  drivers/gpu/drm/rcar-du/rcar_du_vsp.c  |  6 ++++--
>  drivers/media/platform/vsp1/vsp1_drm.c |  6 ++++--
>  drivers/media/platform/vsp1/vsp1_drm.h |  2 +-
>  include/media/vsp1.h                   | 29 +++++++++++++++++++++++++++--
>  4 files changed, 36 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
> index 2c260c33840b..bdcec201591f 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
> @@ -31,7 +31,7 @@
>  #include "rcar_du_kms.h"
>  #include "rcar_du_vsp.h"
>  
> -static void rcar_du_vsp_complete(void *private, bool completed)
> +static void rcar_du_vsp_complete(void *private, bool completed, u32 crc)
>  {
>  	struct rcar_du_crtc *crtc = private;
>  
> @@ -102,7 +102,9 @@ void rcar_du_vsp_atomic_begin(struct rcar_du_crtc *crtc)
>  
>  void rcar_du_vsp_atomic_flush(struct rcar_du_crtc *crtc)
>  {
> -	vsp1_du_atomic_flush(crtc->vsp->vsp, crtc->vsp_pipe);
> +	struct vsp1_du_atomic_pipe_config cfg = { { 0, } }> +
> +	vsp1_du_atomic_flush(crtc->vsp->vsp, crtc->vsp_pipe, &cfg);
>  }
>  
>  /* Keep the two tables in sync. */
> diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c
> index 2b29a83dceb9..5fc31578f9b0 100644
> --- a/drivers/media/platform/vsp1/vsp1_drm.c
> +++ b/drivers/media/platform/vsp1/vsp1_drm.c
> @@ -36,7 +36,7 @@ static void vsp1_du_pipeline_frame_end(struct vsp1_pipeline *pipe,
>  	bool complete = completion == VSP1_DL_FRAME_END_COMPLETED;
>  
>  	if (drm_pipe->du_complete)
> -		drm_pipe->du_complete(drm_pipe->du_private, complete);
> +		drm_pipe->du_complete(drm_pipe->du_private, complete, 0);
>  
>  	if (completion & VSP1_DL_FRAME_END_INTERNAL) {
>  		drm_pipe->force_brx_release = false;
> @@ -739,8 +739,10 @@ EXPORT_SYMBOL_GPL(vsp1_du_atomic_update);
>   * vsp1_du_atomic_flush - Commit an atomic update
>   * @dev: the VSP device
>   * @pipe_index: the DRM pipeline index
> + * @cfg: atomic pipe configuration
>   */
> -void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index)
> +void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index,
> +			  const struct vsp1_du_atomic_pipe_config *cfg)
>  {
>  	struct vsp1_device *vsp1 = dev_get_drvdata(dev);
>  	struct vsp1_drm_pipeline *drm_pipe = &vsp1->drm->pipe[pipe_index];
> diff --git a/drivers/media/platform/vsp1/vsp1_drm.h b/drivers/media/platform/vsp1/vsp1_drm.h
> index f4af1b2b12d6..e5b88b28806c 100644
> --- a/drivers/media/platform/vsp1/vsp1_drm.h
> +++ b/drivers/media/platform/vsp1/vsp1_drm.h
> @@ -35,7 +35,7 @@ struct vsp1_drm_pipeline {
>  	wait_queue_head_t wait_queue;
>  
>  	/* Frame synchronisation */
> -	void (*du_complete)(void *, bool);
> +	void (*du_complete)(void *data, bool completed, u32 crc);
>  	void *du_private;
>  };
>  
> diff --git a/include/media/vsp1.h b/include/media/vsp1.h
> index ff7ef894465d..ac63a9928a79 100644
> --- a/include/media/vsp1.h
> +++ b/include/media/vsp1.h
> @@ -34,7 +34,7 @@ struct vsp1_du_lif_config {
>  	unsigned int width;
>  	unsigned int height;
>  
> -	void (*callback)(void *, bool);
> +	void (*callback)(void *data, bool completed, u32 crc);

Did we have to add parameters to this callback for the dynamic BRx work ?

</me struggles to remember correctly>. If so we might have to consider turning
it into a struct perhaps! - but for now or otherwise I think this will be OK.

Ok - so I stopped being lazy and went to take a look. We turned completed into a
bitfield - so I think actually that's enough to store any more flags we might
come up with, and the CRC doesn't fit in there :D

So lets leave this as adding an extra parameter for now.

>  	void *callback_data;
>  };
>  
> @@ -61,11 +61,36 @@ struct vsp1_du_atomic_config {
>  	unsigned int zpos;
>  };
>  
> +/**
> + * enum vsp1_du_crc_source - Source used for CRC calculation
> + * @VSP1_DU_CRC_NONE: CRC calculation disabled
> + * @VSP_DU_CRC_PLANE: Perform CRC calculation on an input plane
> + * @VSP_DU_CRC_OUTPUT: Perform CRC calculation on the composed output

I see Jacopo has already caught these ...

> + */
> +enum vsp1_du_crc_source {
> +	VSP1_DU_CRC_NONE,
> +	VSP1_DU_CRC_PLANE,
> +	VSP1_DU_CRC_OUTPUT,
> +};
> +
> +/**
> + * struct vsp1_du_atomic_pipe_config - VSP atomic pipe configuration parameters
> + * @crc.source: source for CRC calculation
> + * @crc.index: index of the CRC source plane (when crc.source is set to plane)
> + */
> +struct vsp1_du_atomic_pipe_config {
> +	struct  {
> +		enum vsp1_du_crc_source source;
> +		unsigned int index;
> +	} crc;
> +};
> +
>  void vsp1_du_atomic_begin(struct device *dev, unsigned int pipe_index);
>  int vsp1_du_atomic_update(struct device *dev, unsigned int pipe_index,
>  			  unsigned int rpf,
>  			  const struct vsp1_du_atomic_config *cfg);
> -void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index);
> +void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index,
> +			  const struct vsp1_du_atomic_pipe_config *cfg);
>  int vsp1_du_map_sg(struct device *dev, struct sg_table *sgt);
>  void vsp1_du_unmap_sg(struct device *dev, struct sg_table *sgt);
>  
> 


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v2 5/8] v4l: vsp1: Extend the DU API to support CRC computation
@ 2018-04-28 17:48     ` Kieran Bingham
  0 siblings, 0 replies; 82+ messages in thread
From: Kieran Bingham @ 2018-04-28 17:48 UTC (permalink / raw)
  To: Laurent Pinchart, linux-media, dri-devel; +Cc: linux-renesas-soc


[-- Attachment #1.1.1: Type: text/plain, Size: 5840 bytes --]

Hi Laurent,

On 22/04/18 23:34, Laurent Pinchart wrote:
> Add a parameter (in the form of a structure to ease future API
> extensions) to the VSP atomic flush handler to pass CRC source
> configuration, and pass the CRC value to the completion callback.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

Only a minor 'thought' below.
(And Jacopo already caught the enum typos, so with those are fixed...)

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

> ---
>  drivers/gpu/drm/rcar-du/rcar_du_vsp.c  |  6 ++++--
>  drivers/media/platform/vsp1/vsp1_drm.c |  6 ++++--
>  drivers/media/platform/vsp1/vsp1_drm.h |  2 +-
>  include/media/vsp1.h                   | 29 +++++++++++++++++++++++++++--
>  4 files changed, 36 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
> index 2c260c33840b..bdcec201591f 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
> @@ -31,7 +31,7 @@
>  #include "rcar_du_kms.h"
>  #include "rcar_du_vsp.h"
>  
> -static void rcar_du_vsp_complete(void *private, bool completed)
> +static void rcar_du_vsp_complete(void *private, bool completed, u32 crc)
>  {
>  	struct rcar_du_crtc *crtc = private;
>  
> @@ -102,7 +102,9 @@ void rcar_du_vsp_atomic_begin(struct rcar_du_crtc *crtc)
>  
>  void rcar_du_vsp_atomic_flush(struct rcar_du_crtc *crtc)
>  {
> -	vsp1_du_atomic_flush(crtc->vsp->vsp, crtc->vsp_pipe);
> +	struct vsp1_du_atomic_pipe_config cfg = { { 0, } }> +
> +	vsp1_du_atomic_flush(crtc->vsp->vsp, crtc->vsp_pipe, &cfg);
>  }
>  
>  /* Keep the two tables in sync. */
> diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c
> index 2b29a83dceb9..5fc31578f9b0 100644
> --- a/drivers/media/platform/vsp1/vsp1_drm.c
> +++ b/drivers/media/platform/vsp1/vsp1_drm.c
> @@ -36,7 +36,7 @@ static void vsp1_du_pipeline_frame_end(struct vsp1_pipeline *pipe,
>  	bool complete = completion == VSP1_DL_FRAME_END_COMPLETED;
>  
>  	if (drm_pipe->du_complete)
> -		drm_pipe->du_complete(drm_pipe->du_private, complete);
> +		drm_pipe->du_complete(drm_pipe->du_private, complete, 0);
>  
>  	if (completion & VSP1_DL_FRAME_END_INTERNAL) {
>  		drm_pipe->force_brx_release = false;
> @@ -739,8 +739,10 @@ EXPORT_SYMBOL_GPL(vsp1_du_atomic_update);
>   * vsp1_du_atomic_flush - Commit an atomic update
>   * @dev: the VSP device
>   * @pipe_index: the DRM pipeline index
> + * @cfg: atomic pipe configuration
>   */
> -void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index)
> +void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index,
> +			  const struct vsp1_du_atomic_pipe_config *cfg)
>  {
>  	struct vsp1_device *vsp1 = dev_get_drvdata(dev);
>  	struct vsp1_drm_pipeline *drm_pipe = &vsp1->drm->pipe[pipe_index];
> diff --git a/drivers/media/platform/vsp1/vsp1_drm.h b/drivers/media/platform/vsp1/vsp1_drm.h
> index f4af1b2b12d6..e5b88b28806c 100644
> --- a/drivers/media/platform/vsp1/vsp1_drm.h
> +++ b/drivers/media/platform/vsp1/vsp1_drm.h
> @@ -35,7 +35,7 @@ struct vsp1_drm_pipeline {
>  	wait_queue_head_t wait_queue;
>  
>  	/* Frame synchronisation */
> -	void (*du_complete)(void *, bool);
> +	void (*du_complete)(void *data, bool completed, u32 crc);
>  	void *du_private;
>  };
>  
> diff --git a/include/media/vsp1.h b/include/media/vsp1.h
> index ff7ef894465d..ac63a9928a79 100644
> --- a/include/media/vsp1.h
> +++ b/include/media/vsp1.h
> @@ -34,7 +34,7 @@ struct vsp1_du_lif_config {
>  	unsigned int width;
>  	unsigned int height;
>  
> -	void (*callback)(void *, bool);
> +	void (*callback)(void *data, bool completed, u32 crc);

Did we have to add parameters to this callback for the dynamic BRx work ?

</me struggles to remember correctly>. If so we might have to consider turning
it into a struct perhaps! - but for now or otherwise I think this will be OK.

Ok - so I stopped being lazy and went to take a look. We turned completed into a
bitfield - so I think actually that's enough to store any more flags we might
come up with, and the CRC doesn't fit in there :D

So lets leave this as adding an extra parameter for now.

>  	void *callback_data;
>  };
>  
> @@ -61,11 +61,36 @@ struct vsp1_du_atomic_config {
>  	unsigned int zpos;
>  };
>  
> +/**
> + * enum vsp1_du_crc_source - Source used for CRC calculation
> + * @VSP1_DU_CRC_NONE: CRC calculation disabled
> + * @VSP_DU_CRC_PLANE: Perform CRC calculation on an input plane
> + * @VSP_DU_CRC_OUTPUT: Perform CRC calculation on the composed output

I see Jacopo has already caught these ...

> + */
> +enum vsp1_du_crc_source {
> +	VSP1_DU_CRC_NONE,
> +	VSP1_DU_CRC_PLANE,
> +	VSP1_DU_CRC_OUTPUT,
> +};
> +
> +/**
> + * struct vsp1_du_atomic_pipe_config - VSP atomic pipe configuration parameters
> + * @crc.source: source for CRC calculation
> + * @crc.index: index of the CRC source plane (when crc.source is set to plane)
> + */
> +struct vsp1_du_atomic_pipe_config {
> +	struct  {
> +		enum vsp1_du_crc_source source;
> +		unsigned int index;
> +	} crc;
> +};
> +
>  void vsp1_du_atomic_begin(struct device *dev, unsigned int pipe_index);
>  int vsp1_du_atomic_update(struct device *dev, unsigned int pipe_index,
>  			  unsigned int rpf,
>  			  const struct vsp1_du_atomic_config *cfg);
> -void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index);
> +void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index,
> +			  const struct vsp1_du_atomic_pipe_config *cfg);
>  int vsp1_du_map_sg(struct device *dev, struct sg_table *sgt);
>  void vsp1_du_unmap_sg(struct device *dev, struct sg_table *sgt);
>  
> 


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

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

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

* Re: [PATCH v2 6/8] v4l: vsp1: Add support for the DISCOM entity
  2018-04-22 22:34   ` Laurent Pinchart
@ 2018-04-28 18:28     ` Kieran Bingham
  -1 siblings, 0 replies; 82+ messages in thread
From: Kieran Bingham @ 2018-04-28 18:28 UTC (permalink / raw)
  To: Laurent Pinchart, linux-media, dri-devel; +Cc: linux-renesas-soc


[-- Attachment #1.1: Type: text/plain, Size: 19666 bytes --]

Hi Laurent,

On 22/04/18 23:34, Laurent Pinchart wrote:
> The DISCOM calculates a CRC on a configurable window of the frame. It
> interfaces to the VSP through the UIF glue, hence the name used in the
> code.
> 
> The module supports configuration of the CRC window through the crop
> rectangle on the ink pad of the corresponding entity. However, unlike
> the traditional V4L2 subdevice model, the crop rectangle does not
> influence the format on the source pad.
> 
> Modeling the DISCOM as a sink-only entity would allow adhering to the
> V4L2 subdevice model at the expense of more complex code in the driver,
> as at the hardware level the UIF is handled as a sink+source entity. As
> the DISCOM is only present in R-Car Gen3 VSP-D and VSP-DL instances it
> is not exposed to userspace through V4L2 but controlled through the DU
> driver. We can thus change this model later if needed without fear of
> affecting userspace.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

Registers check out against the data sheet, and I haven't spotted anything else
here on top of the comments Jacopo has highlighted.

I'll put a +1 on Jacopo's suggestion for handling the m3-w quirk though. It's an
adjustment to the width/height in the event the quirk is active - so adjusting
the values after they are set feels 'right' to me.


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



> ---
> Changes since v1:
> 
> - Don't return uninitialized value from uif_set_selection()
> ---
>  drivers/media/platform/vsp1/Makefile      |   2 +-
>  drivers/media/platform/vsp1/vsp1.h        |   4 +
>  drivers/media/platform/vsp1/vsp1_drv.c    |  20 +++
>  drivers/media/platform/vsp1/vsp1_entity.c |   6 +
>  drivers/media/platform/vsp1/vsp1_entity.h |   1 +
>  drivers/media/platform/vsp1/vsp1_regs.h   |  41 +++++
>  drivers/media/platform/vsp1/vsp1_uif.c    | 271 ++++++++++++++++++++++++++++++
>  drivers/media/platform/vsp1/vsp1_uif.h    |  32 ++++
>  8 files changed, 376 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/media/platform/vsp1/vsp1_uif.c
>  create mode 100644 drivers/media/platform/vsp1/vsp1_uif.h
> 
> diff --git a/drivers/media/platform/vsp1/Makefile b/drivers/media/platform/vsp1/Makefile
> index 596775f932c0..4bb4dcbef7b5 100644
> --- a/drivers/media/platform/vsp1/Makefile
> +++ b/drivers/media/platform/vsp1/Makefile
> @@ -5,6 +5,6 @@ vsp1-y					+= vsp1_rpf.o vsp1_rwpf.o vsp1_wpf.o
>  vsp1-y					+= vsp1_clu.o vsp1_hsit.o vsp1_lut.o
>  vsp1-y					+= vsp1_brx.o vsp1_sru.o vsp1_uds.o
>  vsp1-y					+= vsp1_hgo.o vsp1_hgt.o vsp1_histo.o
> -vsp1-y					+= vsp1_lif.o
> +vsp1-y					+= vsp1_lif.o vsp1_uif.o
>  
>  obj-$(CONFIG_VIDEO_RENESAS_VSP1)	+= vsp1.o
> diff --git a/drivers/media/platform/vsp1/vsp1.h b/drivers/media/platform/vsp1/vsp1.h
> index 9cf4e1c4b036..33f632331474 100644
> --- a/drivers/media/platform/vsp1/vsp1.h
> +++ b/drivers/media/platform/vsp1/vsp1.h
> @@ -36,10 +36,12 @@ struct vsp1_lut;
>  struct vsp1_rwpf;
>  struct vsp1_sru;
>  struct vsp1_uds;
> +struct vsp1_uif;
>  
>  #define VSP1_MAX_LIF		2
>  #define VSP1_MAX_RPF		5
>  #define VSP1_MAX_UDS		3
> +#define VSP1_MAX_UIF		2
>  #define VSP1_MAX_WPF		4
>  
>  #define VSP1_HAS_LUT		(1 << 1)
> @@ -60,6 +62,7 @@ struct vsp1_device_info {
>  	unsigned int lif_count;
>  	unsigned int rpf_count;
>  	unsigned int uds_count;
> +	unsigned int uif_count;
>  	unsigned int wpf_count;
>  	unsigned int num_bru_inputs;
>  	bool uapi;
> @@ -86,6 +89,7 @@ struct vsp1_device {
>  	struct vsp1_rwpf *rpf[VSP1_MAX_RPF];
>  	struct vsp1_sru *sru;
>  	struct vsp1_uds *uds[VSP1_MAX_UDS];
> +	struct vsp1_uif *uif[VSP1_MAX_UIF];
>  	struct vsp1_rwpf *wpf[VSP1_MAX_WPF];
>  
>  	struct list_head entities;
> diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
> index 331a2e0af0d3..d29f9c4baebe 100644
> --- a/drivers/media/platform/vsp1/vsp1_drv.c
> +++ b/drivers/media/platform/vsp1/vsp1_drv.c
> @@ -35,6 +35,7 @@
>  #include "vsp1_rwpf.h"
>  #include "vsp1_sru.h"
>  #include "vsp1_uds.h"
> +#include "vsp1_uif.h"
>  #include "vsp1_video.h"
>  
>  /* -----------------------------------------------------------------------------
> @@ -409,6 +410,19 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
>  		list_add_tail(&uds->entity.list_dev, &vsp1->entities);
>  	}
>  
> +	for (i = 0; i < vsp1->info->uif_count; ++i) {
> +		struct vsp1_uif *uif;
> +
> +		uif = vsp1_uif_create(vsp1, i);
> +		if (IS_ERR(uif)) {
> +			ret = PTR_ERR(uif);
> +			goto done;
> +		}
> +
> +		vsp1->uif[i] = uif;
> +		list_add_tail(&uif->entity.list_dev, &vsp1->entities);
> +	}
> +
>  	for (i = 0; i < vsp1->info->wpf_count; ++i) {
>  		struct vsp1_rwpf *wpf;
>  
> @@ -513,6 +527,9 @@ static int vsp1_device_init(struct vsp1_device *vsp1)
>  	for (i = 0; i < vsp1->info->uds_count; ++i)
>  		vsp1_write(vsp1, VI6_DPR_UDS_ROUTE(i), VI6_DPR_NODE_UNUSED);
>  
> +	for (i = 0; i < vsp1->info->uif_count; ++i)
> +		vsp1_write(vsp1, VI6_DPR_UIF_ROUTE(i), VI6_DPR_NODE_UNUSED);
> +
>  	vsp1_write(vsp1, VI6_DPR_SRU_ROUTE, VI6_DPR_NODE_UNUSED);
>  	vsp1_write(vsp1, VI6_DPR_LUT_ROUTE, VI6_DPR_NODE_UNUSED);
>  	vsp1_write(vsp1, VI6_DPR_CLU_ROUTE, VI6_DPR_NODE_UNUSED);
> @@ -740,6 +757,7 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
>  		.features = VSP1_HAS_BRU | VSP1_HAS_WPF_VFLIP,
>  		.lif_count = 1,
>  		.rpf_count = 5,
> +		.uif_count = 1,
>  		.wpf_count = 2,
>  		.num_bru_inputs = 5,
>  	}, {
> @@ -749,6 +767,7 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
>  		.features = VSP1_HAS_BRS | VSP1_HAS_BRU,
>  		.lif_count = 1,
>  		.rpf_count = 5,
> +		.uif_count = 1,
>  		.wpf_count = 1,
>  		.num_bru_inputs = 5,
>  	}, {
> @@ -758,6 +777,7 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
>  		.features = VSP1_HAS_BRS | VSP1_HAS_BRU,
>  		.lif_count = 2,
>  		.rpf_count = 5,
> +		.uif_count = 2,
>  		.wpf_count = 2,
>  		.num_bru_inputs = 5,
>  	},
> diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c
> index 181a583aecad..122e60eb1489 100644
> --- a/drivers/media/platform/vsp1/vsp1_entity.c
> +++ b/drivers/media/platform/vsp1/vsp1_entity.c
> @@ -539,6 +539,10 @@ struct media_pad *vsp1_entity_remote_pad(struct media_pad *pad)
>  	{ VSP1_ENTITY_UDS, idx, VI6_DPR_UDS_ROUTE(idx),			\
>  	  { VI6_DPR_NODE_UDS(idx) }, VI6_DPR_NODE_UDS(idx) }
>  
> +#define VSP1_ENTITY_ROUTE_UIF(idx)					\
> +	{ VSP1_ENTITY_UIF, idx, VI6_DPR_UIF_ROUTE(idx),			\
> +	  { VI6_DPR_NODE_UIF(idx) }, VI6_DPR_NODE_UIF(idx) }
> +
>  #define VSP1_ENTITY_ROUTE_WPF(idx)					\
>  	{ VSP1_ENTITY_WPF, idx, 0,					\
>  	  { VI6_DPR_NODE_WPF(idx) }, VI6_DPR_NODE_WPF(idx) }
> @@ -567,6 +571,8 @@ static const struct vsp1_route vsp1_routes[] = {
>  	VSP1_ENTITY_ROUTE_UDS(0),
>  	VSP1_ENTITY_ROUTE_UDS(1),
>  	VSP1_ENTITY_ROUTE_UDS(2),
> +	VSP1_ENTITY_ROUTE_UIF(0),	/* Named UIF4 in the documentation */
> +	VSP1_ENTITY_ROUTE_UIF(1),	/* Named UIF5 in the documentation */

Intriguing - I wonder what happened to UIF{0-3} :-)

>  	VSP1_ENTITY_ROUTE_WPF(0),
>  	VSP1_ENTITY_ROUTE_WPF(1),
>  	VSP1_ENTITY_ROUTE_WPF(2),
> diff --git a/drivers/media/platform/vsp1/vsp1_entity.h b/drivers/media/platform/vsp1/vsp1_entity.h
> index 0839a62cfa71..94490d697dcf 100644
> --- a/drivers/media/platform/vsp1/vsp1_entity.h
> +++ b/drivers/media/platform/vsp1/vsp1_entity.h
> @@ -33,6 +33,7 @@ enum vsp1_entity_type {
>  	VSP1_ENTITY_RPF,
>  	VSP1_ENTITY_SRU,
>  	VSP1_ENTITY_UDS,
> +	VSP1_ENTITY_UIF,
>  	VSP1_ENTITY_WPF,
>  };
>  
> diff --git a/drivers/media/platform/vsp1/vsp1_regs.h b/drivers/media/platform/vsp1/vsp1_regs.h
> index 3201ad4b77d4..0d249ff9f564 100644
> --- a/drivers/media/platform/vsp1/vsp1_regs.h
> +++ b/drivers/media/platform/vsp1/vsp1_regs.h
> @@ -307,6 +307,44 @@
>  #define VI6_WPF_WRBCK_CTRL		0x1034
>  #define VI6_WPF_WRBCK_CTRL_WBMD		(1 << 0)
>  
> +/* -----------------------------------------------------------------------------
> + * UIF Control Registers
> + */
> +
> +#define VI6_UIF_OFFSET			0x100
> +
> +#define VI6_UIF_DISCOM_DOCMCR		0x1c00
> +#define VI6_UIF_DISCOM_DOCMCR_CMPRU	(1 << 16)
> +#define VI6_UIF_DISCOM_DOCMCR_CMPR	(1 << 0)
> +
> +#define VI6_UIF_DISCOM_DOCMSTR		0x1c04
> +#define VI6_UIF_DISCOM_DOCMSTR_CMPPRE	(1 << 1)
> +#define VI6_UIF_DISCOM_DOCMSTR_CMPST	(1 << 0)
> +
> +#define VI6_UIF_DISCOM_DOCMCLSTR	0x1c08
> +#define VI6_UIF_DISCOM_DOCMCLSTR_CMPCLPRE	(1 << 1)
> +#define VI6_UIF_DISCOM_DOCMCLSTR_CMPCLST	(1 << 0)
> +
> +#define VI6_UIF_DISCOM_DOCMIENR		0x1c0c
> +#define VI6_UIF_DISCOM_DOCMIENR_CMPPREIEN	(1 << 1)
> +#define VI6_UIF_DISCOM_DOCMIENR_CMPIEN		(1 << 0)
> +
> +#define VI6_UIF_DISCOM_DOCMMDR		0x1c10
> +#define VI6_UIF_DISCOM_DOCMMDR_INTHRH(n)	((n) << 16)
> +
> +#define VI6_UIF_DISCOM_DOCMPMR		0x1c14
> +#define VI6_UIF_DISCOM_DOCMPMR_CMPDFF(n)	((n) << 17)
> +#define VI6_UIF_DISCOM_DOCMPMR_CMPDFA(n)	((n) << 8)
> +#define VI6_UIF_DISCOM_DOCMPMR_CMPDAUF		(1 << 7)
> +#define VI6_UIF_DISCOM_DOCMPMR_SEL(n)		((n) << 0)
> +
> +#define VI6_UIF_DISCOM_DOCMECRCR	0x1c18
> +#define VI6_UIF_DISCOM_DOCMCCRCR	0x1c1c
> +#define VI6_UIF_DISCOM_DOCMSPXR		0x1c20
> +#define VI6_UIF_DISCOM_DOCMSPYR		0x1c24
> +#define VI6_UIF_DISCOM_DOCMSZXR		0x1c28
> +#define VI6_UIF_DISCOM_DOCMSZYR		0x1c2c
> +
>  /* -----------------------------------------------------------------------------
>   * DPR Control Registers
>   */
> @@ -339,7 +377,10 @@
>  #define VI6_DPR_SMPPT_PT_MASK		(0x3f << 0)
>  #define VI6_DPR_SMPPT_PT_SHIFT		0
>  
> +#define VI6_DPR_UIF_ROUTE(n)		(0x2074 + (n) * 4)
> +
>  #define VI6_DPR_NODE_RPF(n)		(n)
> +#define VI6_DPR_NODE_UIF(n)		(12 + (n))
>  #define VI6_DPR_NODE_SRU		16
>  #define VI6_DPR_NODE_UDS(n)		(17 + (n))
>  #define VI6_DPR_NODE_LUT		22
> diff --git a/drivers/media/platform/vsp1/vsp1_uif.c b/drivers/media/platform/vsp1/vsp1_uif.c
> new file mode 100644
> index 000000000000..6de7e9c801ae
> --- /dev/null
> +++ b/drivers/media/platform/vsp1/vsp1_uif.c
> @@ -0,0 +1,271 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * vsp1_uif.c  --  R-Car VSP1 User Logic Interface
> + *
> + * Copyright (C) 2017-2018 Laurent Pinchart
> + *
> + * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> + */
> +
> +#include <linux/device.h>
> +#include <linux/gfp.h>
> +#include <linux/sys_soc.h>
> +
> +#include <media/media-entity.h>
> +#include <media/v4l2-subdev.h>
> +
> +#include "vsp1.h"
> +#include "vsp1_dl.h"
> +#include "vsp1_entity.h"
> +#include "vsp1_uif.h"
> +
> +#define UIF_MIN_SIZE				4U
> +#define UIF_MAX_SIZE				8190U
> +
> +/* -----------------------------------------------------------------------------
> + * Device Access
> + */
> +
> +static inline u32 vsp1_uif_read(struct vsp1_uif *uif, u32 reg)
> +{
> +	return vsp1_read(uif->entity.vsp1,
> +			 uif->entity.index * VI6_UIF_OFFSET + reg);
> +}
> +static inline void vsp1_uif_write(struct vsp1_uif *uif, struct vsp1_dl_list *dl,
> +				  u32 reg, u32 data)
> +{
> +	vsp1_dl_list_write(dl, reg + uif->entity.index * VI6_UIF_OFFSET, data);
> +}
> +
> +u32 vsp1_uif_get_crc(struct vsp1_uif *uif)
> +{
> +	return vsp1_uif_read(uif, VI6_UIF_DISCOM_DOCMCCRCR);
> +}
> +
> +/* -----------------------------------------------------------------------------
> + * V4L2 Subdevice Pad Operations
> + */
> +
> +static const unsigned int uif_codes[] = {
> +	MEDIA_BUS_FMT_ARGB8888_1X32,
> +	MEDIA_BUS_FMT_AHSV8888_1X32,
> +	MEDIA_BUS_FMT_AYUV8_1X32,
> +};
> +
> +static int uif_enum_mbus_code(struct v4l2_subdev *subdev,
> +			      struct v4l2_subdev_pad_config *cfg,
> +			      struct v4l2_subdev_mbus_code_enum *code)
> +{
> +	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, uif_codes,
> +					  ARRAY_SIZE(uif_codes));
> +}
> +
> +static int uif_enum_frame_size(struct v4l2_subdev *subdev,
> +			       struct v4l2_subdev_pad_config *cfg,
> +			       struct v4l2_subdev_frame_size_enum *fse)
> +{
> +	return vsp1_subdev_enum_frame_size(subdev, cfg, fse, UIF_MIN_SIZE,
> +					   UIF_MIN_SIZE, UIF_MAX_SIZE,
> +					   UIF_MAX_SIZE);
> +}
> +
> +static int uif_set_format(struct v4l2_subdev *subdev,
> +			    struct v4l2_subdev_pad_config *cfg,
> +			    struct v4l2_subdev_format *fmt)
> +{
> +	return vsp1_subdev_set_pad_format(subdev, cfg, fmt, uif_codes,
> +					  ARRAY_SIZE(uif_codes),
> +					  UIF_MIN_SIZE, UIF_MIN_SIZE,
> +					  UIF_MAX_SIZE, UIF_MAX_SIZE);
> +}
> +
> +static int uif_get_selection(struct v4l2_subdev *subdev,
> +			     struct v4l2_subdev_pad_config *cfg,
> +			     struct v4l2_subdev_selection *sel)
> +{
> +	struct vsp1_uif *uif = to_uif(subdev);
> +	struct v4l2_subdev_pad_config *config;
> +	struct v4l2_mbus_framefmt *format;
> +	int ret = 0;
> +
> +	if (sel->pad != UIF_PAD_SINK)
> +		return -EINVAL;
> +
> +	mutex_lock(&uif->entity.lock);
> +
> +	config = vsp1_entity_get_pad_config(&uif->entity, cfg, sel->which);
> +	if (!config) {
> +		ret = -EINVAL;
> +		goto done;
> +	}
> +
> +	switch (sel->target) {
> +	case V4L2_SEL_TGT_CROP_BOUNDS:
> +	case V4L2_SEL_TGT_CROP_DEFAULT:
> +		format = vsp1_entity_get_pad_format(&uif->entity, config,
> +						    UIF_PAD_SINK);
> +		sel->r.left = 0;
> +		sel->r.top = 0;
> +		sel->r.width = format->width;
> +		sel->r.height = format->height;
> +		break;
> +
> +	case V4L2_SEL_TGT_CROP:
> +		sel->r = *vsp1_entity_get_pad_selection(&uif->entity, config,
> +							sel->pad, sel->target);
> +		break;
> +
> +	default:
> +		ret = -EINVAL;
> +		break;
> +	}
> +
> +done:
> +	mutex_unlock(&uif->entity.lock);
> +	return ret;
> +}
> +
> +static int uif_set_selection(struct v4l2_subdev *subdev,
> +			     struct v4l2_subdev_pad_config *cfg,
> +			     struct v4l2_subdev_selection *sel)
> +{
> +	struct vsp1_uif *uif = to_uif(subdev);
> +	struct v4l2_subdev_pad_config *config;
> +	struct v4l2_mbus_framefmt *format;
> +	struct v4l2_rect *selection;
> +	int ret = 0;
> +
> +	if (sel->pad != UIF_PAD_SINK ||
> +	    sel->target != V4L2_SEL_TGT_CROP)
> +		return -EINVAL;
> +
> +	mutex_lock(&uif->entity.lock);
> +
> +	config = vsp1_entity_get_pad_config(&uif->entity, cfg, sel->which);
> +	if (!config) {
> +		ret = -EINVAL;
> +		goto done;
> +	}
> +
> +	/* The crop rectangle must be inside the input frame. */
> +	format = vsp1_entity_get_pad_format(&uif->entity, config, UIF_PAD_SINK);
> +
> +	sel->r.left = clamp_t(unsigned int, sel->r.left, 0, format->width - 1);
> +	sel->r.top = clamp_t(unsigned int, sel->r.top, 0, format->height - 1);
> +	sel->r.width = clamp_t(unsigned int, sel->r.width, UIF_MIN_SIZE,
> +			       format->width - sel->r.left);
> +	sel->r.height = clamp_t(unsigned int, sel->r.height, UIF_MIN_SIZE,
> +				format->height - sel->r.top);
> +
> +	/* Store the crop rectangle. */
> +	selection = vsp1_entity_get_pad_selection(&uif->entity, config,
> +						  sel->pad, V4L2_SEL_TGT_CROP);
> +	*selection = sel->r;
> +
> +done:
> +	mutex_unlock(&uif->entity.lock);
> +	return ret;
> +}
> +
> +/* -----------------------------------------------------------------------------
> + * V4L2 Subdevice Operations
> + */
> +
> +static const struct v4l2_subdev_pad_ops uif_pad_ops = {
> +	.init_cfg = vsp1_entity_init_cfg,
> +	.enum_mbus_code = uif_enum_mbus_code,
> +	.enum_frame_size = uif_enum_frame_size,
> +	.get_fmt = vsp1_subdev_get_pad_format,
> +	.set_fmt = uif_set_format,
> +	.get_selection = uif_get_selection,
> +	.set_selection = uif_set_selection,
> +};
> +
> +static const struct v4l2_subdev_ops uif_ops = {
> +	.pad    = &uif_pad_ops,
> +};
> +
> +/* -----------------------------------------------------------------------------
> + * VSP1 Entity Operations
> + */
> +
> +static void uif_configure(struct vsp1_entity *entity,
> +			  struct vsp1_pipeline *pipe,
> +			  struct vsp1_dl_list *dl,
> +			  enum vsp1_entity_params params)
> +{
> +	struct vsp1_uif *uif = to_uif(&entity->subdev);
> +	const struct v4l2_rect *crop;
> +	unsigned int left;
> +	unsigned int width;
> +
> +	/*
> +	 * Per-partition configuration isn't needed as the DISCOM is used in
> +	 * display pipelines only.
> +	 */
> +	if (params != VSP1_ENTITY_PARAMS_INIT)
> +		return;
> +
> +	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMPMR,
> +		       VI6_UIF_DISCOM_DOCMPMR_SEL(9));
> +
> +	crop = vsp1_entity_get_pad_selection(entity, entity->config,
> +					     UIF_PAD_SINK, V4L2_SEL_TGT_CROP);
> +
> +	/* On M3-W the horizontal coordinates are twice the register value. */

Well that's just awkward :D

> +	if (uif->m3w_quirk) {
> +		left = crop->left / 2;
> +		width = crop->width / 2;
> +	} else {
> +		left = crop->left;
> +		width = crop->width;
> +	}

+1 here on Jacopo's suggestion :-)


> +
> +	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMSPXR, left);
> +	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMSPYR, crop->top);
> +	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMSZXR, width);
> +	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMSZYR, crop->height);
> +
> +	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMCR,
> +		       VI6_UIF_DISCOM_DOCMCR_CMPR);
> +}
> +
> +static const struct vsp1_entity_operations uif_entity_ops = {
> +	.configure = uif_configure,
> +};
> +
> +/* -----------------------------------------------------------------------------
> + * Initialization and Cleanup
> + */
> +
> +static const struct soc_device_attribute vsp1_r8a7796[] = {
> +	{ .soc_id = "r8a7796" },
> +	{ /* sentinel */ }
> +};
> +
> +struct vsp1_uif *vsp1_uif_create(struct vsp1_device *vsp1, unsigned int index)
> +{
> +	struct vsp1_uif *uif;
> +	char name[6];
> +	int ret;
> +
> +	uif = devm_kzalloc(vsp1->dev, sizeof(*uif), GFP_KERNEL);
> +	if (uif == NULL)
> +		return ERR_PTR(-ENOMEM);
> +
> +	if (soc_device_match(vsp1_r8a7796))
> +		uif->m3w_quirk = true;
> +
> +	uif->entity.ops = &uif_entity_ops;
> +	uif->entity.type = VSP1_ENTITY_UIF;
> +	uif->entity.index = index;
> +
> +	/* The datasheet names the two UIF instances UIF4 and UIF5. */
> +	sprintf(name, "uif.%u", index + 4);
> +	ret = vsp1_entity_init(vsp1, &uif->entity, name, 2, &uif_ops,
> +			       MEDIA_ENT_F_PROC_VIDEO_STATISTICS);
> +	if (ret < 0)
> +		return ERR_PTR(ret);
> +
> +	return uif;
> +}
> diff --git a/drivers/media/platform/vsp1/vsp1_uif.h b/drivers/media/platform/vsp1/vsp1_uif.h
> new file mode 100644
> index 000000000000..c71ab5f6a6f8
> --- /dev/null
> +++ b/drivers/media/platform/vsp1/vsp1_uif.h
> @@ -0,0 +1,32 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * vsp1_uif.h  --  R-Car VSP1 User Logic Interface
> + *
> + * Copyright (C) 2017-2018 Laurent Pinchart
> + *
> + * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> + */
> +#ifndef __VSP1_UIF_H__
> +#define __VSP1_UIF_H__
> +
> +#include "vsp1_entity.h"
> +
> +struct vsp1_device;
> +
> +#define UIF_PAD_SINK				0
> +#define UIF_PAD_SOURCE				1
> +
> +struct vsp1_uif {
> +	struct vsp1_entity entity;
> +	bool m3w_quirk;
> +};
> +
> +static inline struct vsp1_uif *to_uif(struct v4l2_subdev *subdev)
> +{
> +	return container_of(subdev, struct vsp1_uif, entity.subdev);
> +}
> +
> +struct vsp1_uif *vsp1_uif_create(struct vsp1_device *vsp1, unsigned int index);
> +u32 vsp1_uif_get_crc(struct vsp1_uif *uif);
> +
> +#endif /* __VSP1_UIF_H__ */
> 


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v2 6/8] v4l: vsp1: Add support for the DISCOM entity
@ 2018-04-28 18:28     ` Kieran Bingham
  0 siblings, 0 replies; 82+ messages in thread
From: Kieran Bingham @ 2018-04-28 18:28 UTC (permalink / raw)
  To: Laurent Pinchart, linux-media, dri-devel; +Cc: linux-renesas-soc


[-- Attachment #1.1.1: Type: text/plain, Size: 19666 bytes --]

Hi Laurent,

On 22/04/18 23:34, Laurent Pinchart wrote:
> The DISCOM calculates a CRC on a configurable window of the frame. It
> interfaces to the VSP through the UIF glue, hence the name used in the
> code.
> 
> The module supports configuration of the CRC window through the crop
> rectangle on the ink pad of the corresponding entity. However, unlike
> the traditional V4L2 subdevice model, the crop rectangle does not
> influence the format on the source pad.
> 
> Modeling the DISCOM as a sink-only entity would allow adhering to the
> V4L2 subdevice model at the expense of more complex code in the driver,
> as at the hardware level the UIF is handled as a sink+source entity. As
> the DISCOM is only present in R-Car Gen3 VSP-D and VSP-DL instances it
> is not exposed to userspace through V4L2 but controlled through the DU
> driver. We can thus change this model later if needed without fear of
> affecting userspace.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

Registers check out against the data sheet, and I haven't spotted anything else
here on top of the comments Jacopo has highlighted.

I'll put a +1 on Jacopo's suggestion for handling the m3-w quirk though. It's an
adjustment to the width/height in the event the quirk is active - so adjusting
the values after they are set feels 'right' to me.


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



> ---
> Changes since v1:
> 
> - Don't return uninitialized value from uif_set_selection()
> ---
>  drivers/media/platform/vsp1/Makefile      |   2 +-
>  drivers/media/platform/vsp1/vsp1.h        |   4 +
>  drivers/media/platform/vsp1/vsp1_drv.c    |  20 +++
>  drivers/media/platform/vsp1/vsp1_entity.c |   6 +
>  drivers/media/platform/vsp1/vsp1_entity.h |   1 +
>  drivers/media/platform/vsp1/vsp1_regs.h   |  41 +++++
>  drivers/media/platform/vsp1/vsp1_uif.c    | 271 ++++++++++++++++++++++++++++++
>  drivers/media/platform/vsp1/vsp1_uif.h    |  32 ++++
>  8 files changed, 376 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/media/platform/vsp1/vsp1_uif.c
>  create mode 100644 drivers/media/platform/vsp1/vsp1_uif.h
> 
> diff --git a/drivers/media/platform/vsp1/Makefile b/drivers/media/platform/vsp1/Makefile
> index 596775f932c0..4bb4dcbef7b5 100644
> --- a/drivers/media/platform/vsp1/Makefile
> +++ b/drivers/media/platform/vsp1/Makefile
> @@ -5,6 +5,6 @@ vsp1-y					+= vsp1_rpf.o vsp1_rwpf.o vsp1_wpf.o
>  vsp1-y					+= vsp1_clu.o vsp1_hsit.o vsp1_lut.o
>  vsp1-y					+= vsp1_brx.o vsp1_sru.o vsp1_uds.o
>  vsp1-y					+= vsp1_hgo.o vsp1_hgt.o vsp1_histo.o
> -vsp1-y					+= vsp1_lif.o
> +vsp1-y					+= vsp1_lif.o vsp1_uif.o
>  
>  obj-$(CONFIG_VIDEO_RENESAS_VSP1)	+= vsp1.o
> diff --git a/drivers/media/platform/vsp1/vsp1.h b/drivers/media/platform/vsp1/vsp1.h
> index 9cf4e1c4b036..33f632331474 100644
> --- a/drivers/media/platform/vsp1/vsp1.h
> +++ b/drivers/media/platform/vsp1/vsp1.h
> @@ -36,10 +36,12 @@ struct vsp1_lut;
>  struct vsp1_rwpf;
>  struct vsp1_sru;
>  struct vsp1_uds;
> +struct vsp1_uif;
>  
>  #define VSP1_MAX_LIF		2
>  #define VSP1_MAX_RPF		5
>  #define VSP1_MAX_UDS		3
> +#define VSP1_MAX_UIF		2
>  #define VSP1_MAX_WPF		4
>  
>  #define VSP1_HAS_LUT		(1 << 1)
> @@ -60,6 +62,7 @@ struct vsp1_device_info {
>  	unsigned int lif_count;
>  	unsigned int rpf_count;
>  	unsigned int uds_count;
> +	unsigned int uif_count;
>  	unsigned int wpf_count;
>  	unsigned int num_bru_inputs;
>  	bool uapi;
> @@ -86,6 +89,7 @@ struct vsp1_device {
>  	struct vsp1_rwpf *rpf[VSP1_MAX_RPF];
>  	struct vsp1_sru *sru;
>  	struct vsp1_uds *uds[VSP1_MAX_UDS];
> +	struct vsp1_uif *uif[VSP1_MAX_UIF];
>  	struct vsp1_rwpf *wpf[VSP1_MAX_WPF];
>  
>  	struct list_head entities;
> diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
> index 331a2e0af0d3..d29f9c4baebe 100644
> --- a/drivers/media/platform/vsp1/vsp1_drv.c
> +++ b/drivers/media/platform/vsp1/vsp1_drv.c
> @@ -35,6 +35,7 @@
>  #include "vsp1_rwpf.h"
>  #include "vsp1_sru.h"
>  #include "vsp1_uds.h"
> +#include "vsp1_uif.h"
>  #include "vsp1_video.h"
>  
>  /* -----------------------------------------------------------------------------
> @@ -409,6 +410,19 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
>  		list_add_tail(&uds->entity.list_dev, &vsp1->entities);
>  	}
>  
> +	for (i = 0; i < vsp1->info->uif_count; ++i) {
> +		struct vsp1_uif *uif;
> +
> +		uif = vsp1_uif_create(vsp1, i);
> +		if (IS_ERR(uif)) {
> +			ret = PTR_ERR(uif);
> +			goto done;
> +		}
> +
> +		vsp1->uif[i] = uif;
> +		list_add_tail(&uif->entity.list_dev, &vsp1->entities);
> +	}
> +
>  	for (i = 0; i < vsp1->info->wpf_count; ++i) {
>  		struct vsp1_rwpf *wpf;
>  
> @@ -513,6 +527,9 @@ static int vsp1_device_init(struct vsp1_device *vsp1)
>  	for (i = 0; i < vsp1->info->uds_count; ++i)
>  		vsp1_write(vsp1, VI6_DPR_UDS_ROUTE(i), VI6_DPR_NODE_UNUSED);
>  
> +	for (i = 0; i < vsp1->info->uif_count; ++i)
> +		vsp1_write(vsp1, VI6_DPR_UIF_ROUTE(i), VI6_DPR_NODE_UNUSED);
> +
>  	vsp1_write(vsp1, VI6_DPR_SRU_ROUTE, VI6_DPR_NODE_UNUSED);
>  	vsp1_write(vsp1, VI6_DPR_LUT_ROUTE, VI6_DPR_NODE_UNUSED);
>  	vsp1_write(vsp1, VI6_DPR_CLU_ROUTE, VI6_DPR_NODE_UNUSED);
> @@ -740,6 +757,7 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
>  		.features = VSP1_HAS_BRU | VSP1_HAS_WPF_VFLIP,
>  		.lif_count = 1,
>  		.rpf_count = 5,
> +		.uif_count = 1,
>  		.wpf_count = 2,
>  		.num_bru_inputs = 5,
>  	}, {
> @@ -749,6 +767,7 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
>  		.features = VSP1_HAS_BRS | VSP1_HAS_BRU,
>  		.lif_count = 1,
>  		.rpf_count = 5,
> +		.uif_count = 1,
>  		.wpf_count = 1,
>  		.num_bru_inputs = 5,
>  	}, {
> @@ -758,6 +777,7 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
>  		.features = VSP1_HAS_BRS | VSP1_HAS_BRU,
>  		.lif_count = 2,
>  		.rpf_count = 5,
> +		.uif_count = 2,
>  		.wpf_count = 2,
>  		.num_bru_inputs = 5,
>  	},
> diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c
> index 181a583aecad..122e60eb1489 100644
> --- a/drivers/media/platform/vsp1/vsp1_entity.c
> +++ b/drivers/media/platform/vsp1/vsp1_entity.c
> @@ -539,6 +539,10 @@ struct media_pad *vsp1_entity_remote_pad(struct media_pad *pad)
>  	{ VSP1_ENTITY_UDS, idx, VI6_DPR_UDS_ROUTE(idx),			\
>  	  { VI6_DPR_NODE_UDS(idx) }, VI6_DPR_NODE_UDS(idx) }
>  
> +#define VSP1_ENTITY_ROUTE_UIF(idx)					\
> +	{ VSP1_ENTITY_UIF, idx, VI6_DPR_UIF_ROUTE(idx),			\
> +	  { VI6_DPR_NODE_UIF(idx) }, VI6_DPR_NODE_UIF(idx) }
> +
>  #define VSP1_ENTITY_ROUTE_WPF(idx)					\
>  	{ VSP1_ENTITY_WPF, idx, 0,					\
>  	  { VI6_DPR_NODE_WPF(idx) }, VI6_DPR_NODE_WPF(idx) }
> @@ -567,6 +571,8 @@ static const struct vsp1_route vsp1_routes[] = {
>  	VSP1_ENTITY_ROUTE_UDS(0),
>  	VSP1_ENTITY_ROUTE_UDS(1),
>  	VSP1_ENTITY_ROUTE_UDS(2),
> +	VSP1_ENTITY_ROUTE_UIF(0),	/* Named UIF4 in the documentation */
> +	VSP1_ENTITY_ROUTE_UIF(1),	/* Named UIF5 in the documentation */

Intriguing - I wonder what happened to UIF{0-3} :-)

>  	VSP1_ENTITY_ROUTE_WPF(0),
>  	VSP1_ENTITY_ROUTE_WPF(1),
>  	VSP1_ENTITY_ROUTE_WPF(2),
> diff --git a/drivers/media/platform/vsp1/vsp1_entity.h b/drivers/media/platform/vsp1/vsp1_entity.h
> index 0839a62cfa71..94490d697dcf 100644
> --- a/drivers/media/platform/vsp1/vsp1_entity.h
> +++ b/drivers/media/platform/vsp1/vsp1_entity.h
> @@ -33,6 +33,7 @@ enum vsp1_entity_type {
>  	VSP1_ENTITY_RPF,
>  	VSP1_ENTITY_SRU,
>  	VSP1_ENTITY_UDS,
> +	VSP1_ENTITY_UIF,
>  	VSP1_ENTITY_WPF,
>  };
>  
> diff --git a/drivers/media/platform/vsp1/vsp1_regs.h b/drivers/media/platform/vsp1/vsp1_regs.h
> index 3201ad4b77d4..0d249ff9f564 100644
> --- a/drivers/media/platform/vsp1/vsp1_regs.h
> +++ b/drivers/media/platform/vsp1/vsp1_regs.h
> @@ -307,6 +307,44 @@
>  #define VI6_WPF_WRBCK_CTRL		0x1034
>  #define VI6_WPF_WRBCK_CTRL_WBMD		(1 << 0)
>  
> +/* -----------------------------------------------------------------------------
> + * UIF Control Registers
> + */
> +
> +#define VI6_UIF_OFFSET			0x100
> +
> +#define VI6_UIF_DISCOM_DOCMCR		0x1c00
> +#define VI6_UIF_DISCOM_DOCMCR_CMPRU	(1 << 16)
> +#define VI6_UIF_DISCOM_DOCMCR_CMPR	(1 << 0)
> +
> +#define VI6_UIF_DISCOM_DOCMSTR		0x1c04
> +#define VI6_UIF_DISCOM_DOCMSTR_CMPPRE	(1 << 1)
> +#define VI6_UIF_DISCOM_DOCMSTR_CMPST	(1 << 0)
> +
> +#define VI6_UIF_DISCOM_DOCMCLSTR	0x1c08
> +#define VI6_UIF_DISCOM_DOCMCLSTR_CMPCLPRE	(1 << 1)
> +#define VI6_UIF_DISCOM_DOCMCLSTR_CMPCLST	(1 << 0)
> +
> +#define VI6_UIF_DISCOM_DOCMIENR		0x1c0c
> +#define VI6_UIF_DISCOM_DOCMIENR_CMPPREIEN	(1 << 1)
> +#define VI6_UIF_DISCOM_DOCMIENR_CMPIEN		(1 << 0)
> +
> +#define VI6_UIF_DISCOM_DOCMMDR		0x1c10
> +#define VI6_UIF_DISCOM_DOCMMDR_INTHRH(n)	((n) << 16)
> +
> +#define VI6_UIF_DISCOM_DOCMPMR		0x1c14
> +#define VI6_UIF_DISCOM_DOCMPMR_CMPDFF(n)	((n) << 17)
> +#define VI6_UIF_DISCOM_DOCMPMR_CMPDFA(n)	((n) << 8)
> +#define VI6_UIF_DISCOM_DOCMPMR_CMPDAUF		(1 << 7)
> +#define VI6_UIF_DISCOM_DOCMPMR_SEL(n)		((n) << 0)
> +
> +#define VI6_UIF_DISCOM_DOCMECRCR	0x1c18
> +#define VI6_UIF_DISCOM_DOCMCCRCR	0x1c1c
> +#define VI6_UIF_DISCOM_DOCMSPXR		0x1c20
> +#define VI6_UIF_DISCOM_DOCMSPYR		0x1c24
> +#define VI6_UIF_DISCOM_DOCMSZXR		0x1c28
> +#define VI6_UIF_DISCOM_DOCMSZYR		0x1c2c
> +
>  /* -----------------------------------------------------------------------------
>   * DPR Control Registers
>   */
> @@ -339,7 +377,10 @@
>  #define VI6_DPR_SMPPT_PT_MASK		(0x3f << 0)
>  #define VI6_DPR_SMPPT_PT_SHIFT		0
>  
> +#define VI6_DPR_UIF_ROUTE(n)		(0x2074 + (n) * 4)
> +
>  #define VI6_DPR_NODE_RPF(n)		(n)
> +#define VI6_DPR_NODE_UIF(n)		(12 + (n))
>  #define VI6_DPR_NODE_SRU		16
>  #define VI6_DPR_NODE_UDS(n)		(17 + (n))
>  #define VI6_DPR_NODE_LUT		22
> diff --git a/drivers/media/platform/vsp1/vsp1_uif.c b/drivers/media/platform/vsp1/vsp1_uif.c
> new file mode 100644
> index 000000000000..6de7e9c801ae
> --- /dev/null
> +++ b/drivers/media/platform/vsp1/vsp1_uif.c
> @@ -0,0 +1,271 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * vsp1_uif.c  --  R-Car VSP1 User Logic Interface
> + *
> + * Copyright (C) 2017-2018 Laurent Pinchart
> + *
> + * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> + */
> +
> +#include <linux/device.h>
> +#include <linux/gfp.h>
> +#include <linux/sys_soc.h>
> +
> +#include <media/media-entity.h>
> +#include <media/v4l2-subdev.h>
> +
> +#include "vsp1.h"
> +#include "vsp1_dl.h"
> +#include "vsp1_entity.h"
> +#include "vsp1_uif.h"
> +
> +#define UIF_MIN_SIZE				4U
> +#define UIF_MAX_SIZE				8190U
> +
> +/* -----------------------------------------------------------------------------
> + * Device Access
> + */
> +
> +static inline u32 vsp1_uif_read(struct vsp1_uif *uif, u32 reg)
> +{
> +	return vsp1_read(uif->entity.vsp1,
> +			 uif->entity.index * VI6_UIF_OFFSET + reg);
> +}
> +static inline void vsp1_uif_write(struct vsp1_uif *uif, struct vsp1_dl_list *dl,
> +				  u32 reg, u32 data)
> +{
> +	vsp1_dl_list_write(dl, reg + uif->entity.index * VI6_UIF_OFFSET, data);
> +}
> +
> +u32 vsp1_uif_get_crc(struct vsp1_uif *uif)
> +{
> +	return vsp1_uif_read(uif, VI6_UIF_DISCOM_DOCMCCRCR);
> +}
> +
> +/* -----------------------------------------------------------------------------
> + * V4L2 Subdevice Pad Operations
> + */
> +
> +static const unsigned int uif_codes[] = {
> +	MEDIA_BUS_FMT_ARGB8888_1X32,
> +	MEDIA_BUS_FMT_AHSV8888_1X32,
> +	MEDIA_BUS_FMT_AYUV8_1X32,
> +};
> +
> +static int uif_enum_mbus_code(struct v4l2_subdev *subdev,
> +			      struct v4l2_subdev_pad_config *cfg,
> +			      struct v4l2_subdev_mbus_code_enum *code)
> +{
> +	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, uif_codes,
> +					  ARRAY_SIZE(uif_codes));
> +}
> +
> +static int uif_enum_frame_size(struct v4l2_subdev *subdev,
> +			       struct v4l2_subdev_pad_config *cfg,
> +			       struct v4l2_subdev_frame_size_enum *fse)
> +{
> +	return vsp1_subdev_enum_frame_size(subdev, cfg, fse, UIF_MIN_SIZE,
> +					   UIF_MIN_SIZE, UIF_MAX_SIZE,
> +					   UIF_MAX_SIZE);
> +}
> +
> +static int uif_set_format(struct v4l2_subdev *subdev,
> +			    struct v4l2_subdev_pad_config *cfg,
> +			    struct v4l2_subdev_format *fmt)
> +{
> +	return vsp1_subdev_set_pad_format(subdev, cfg, fmt, uif_codes,
> +					  ARRAY_SIZE(uif_codes),
> +					  UIF_MIN_SIZE, UIF_MIN_SIZE,
> +					  UIF_MAX_SIZE, UIF_MAX_SIZE);
> +}
> +
> +static int uif_get_selection(struct v4l2_subdev *subdev,
> +			     struct v4l2_subdev_pad_config *cfg,
> +			     struct v4l2_subdev_selection *sel)
> +{
> +	struct vsp1_uif *uif = to_uif(subdev);
> +	struct v4l2_subdev_pad_config *config;
> +	struct v4l2_mbus_framefmt *format;
> +	int ret = 0;
> +
> +	if (sel->pad != UIF_PAD_SINK)
> +		return -EINVAL;
> +
> +	mutex_lock(&uif->entity.lock);
> +
> +	config = vsp1_entity_get_pad_config(&uif->entity, cfg, sel->which);
> +	if (!config) {
> +		ret = -EINVAL;
> +		goto done;
> +	}
> +
> +	switch (sel->target) {
> +	case V4L2_SEL_TGT_CROP_BOUNDS:
> +	case V4L2_SEL_TGT_CROP_DEFAULT:
> +		format = vsp1_entity_get_pad_format(&uif->entity, config,
> +						    UIF_PAD_SINK);
> +		sel->r.left = 0;
> +		sel->r.top = 0;
> +		sel->r.width = format->width;
> +		sel->r.height = format->height;
> +		break;
> +
> +	case V4L2_SEL_TGT_CROP:
> +		sel->r = *vsp1_entity_get_pad_selection(&uif->entity, config,
> +							sel->pad, sel->target);
> +		break;
> +
> +	default:
> +		ret = -EINVAL;
> +		break;
> +	}
> +
> +done:
> +	mutex_unlock(&uif->entity.lock);
> +	return ret;
> +}
> +
> +static int uif_set_selection(struct v4l2_subdev *subdev,
> +			     struct v4l2_subdev_pad_config *cfg,
> +			     struct v4l2_subdev_selection *sel)
> +{
> +	struct vsp1_uif *uif = to_uif(subdev);
> +	struct v4l2_subdev_pad_config *config;
> +	struct v4l2_mbus_framefmt *format;
> +	struct v4l2_rect *selection;
> +	int ret = 0;
> +
> +	if (sel->pad != UIF_PAD_SINK ||
> +	    sel->target != V4L2_SEL_TGT_CROP)
> +		return -EINVAL;
> +
> +	mutex_lock(&uif->entity.lock);
> +
> +	config = vsp1_entity_get_pad_config(&uif->entity, cfg, sel->which);
> +	if (!config) {
> +		ret = -EINVAL;
> +		goto done;
> +	}
> +
> +	/* The crop rectangle must be inside the input frame. */
> +	format = vsp1_entity_get_pad_format(&uif->entity, config, UIF_PAD_SINK);
> +
> +	sel->r.left = clamp_t(unsigned int, sel->r.left, 0, format->width - 1);
> +	sel->r.top = clamp_t(unsigned int, sel->r.top, 0, format->height - 1);
> +	sel->r.width = clamp_t(unsigned int, sel->r.width, UIF_MIN_SIZE,
> +			       format->width - sel->r.left);
> +	sel->r.height = clamp_t(unsigned int, sel->r.height, UIF_MIN_SIZE,
> +				format->height - sel->r.top);
> +
> +	/* Store the crop rectangle. */
> +	selection = vsp1_entity_get_pad_selection(&uif->entity, config,
> +						  sel->pad, V4L2_SEL_TGT_CROP);
> +	*selection = sel->r;
> +
> +done:
> +	mutex_unlock(&uif->entity.lock);
> +	return ret;
> +}
> +
> +/* -----------------------------------------------------------------------------
> + * V4L2 Subdevice Operations
> + */
> +
> +static const struct v4l2_subdev_pad_ops uif_pad_ops = {
> +	.init_cfg = vsp1_entity_init_cfg,
> +	.enum_mbus_code = uif_enum_mbus_code,
> +	.enum_frame_size = uif_enum_frame_size,
> +	.get_fmt = vsp1_subdev_get_pad_format,
> +	.set_fmt = uif_set_format,
> +	.get_selection = uif_get_selection,
> +	.set_selection = uif_set_selection,
> +};
> +
> +static const struct v4l2_subdev_ops uif_ops = {
> +	.pad    = &uif_pad_ops,
> +};
> +
> +/* -----------------------------------------------------------------------------
> + * VSP1 Entity Operations
> + */
> +
> +static void uif_configure(struct vsp1_entity *entity,
> +			  struct vsp1_pipeline *pipe,
> +			  struct vsp1_dl_list *dl,
> +			  enum vsp1_entity_params params)
> +{
> +	struct vsp1_uif *uif = to_uif(&entity->subdev);
> +	const struct v4l2_rect *crop;
> +	unsigned int left;
> +	unsigned int width;
> +
> +	/*
> +	 * Per-partition configuration isn't needed as the DISCOM is used in
> +	 * display pipelines only.
> +	 */
> +	if (params != VSP1_ENTITY_PARAMS_INIT)
> +		return;
> +
> +	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMPMR,
> +		       VI6_UIF_DISCOM_DOCMPMR_SEL(9));
> +
> +	crop = vsp1_entity_get_pad_selection(entity, entity->config,
> +					     UIF_PAD_SINK, V4L2_SEL_TGT_CROP);
> +
> +	/* On M3-W the horizontal coordinates are twice the register value. */

Well that's just awkward :D

> +	if (uif->m3w_quirk) {
> +		left = crop->left / 2;
> +		width = crop->width / 2;
> +	} else {
> +		left = crop->left;
> +		width = crop->width;
> +	}

+1 here on Jacopo's suggestion :-)


> +
> +	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMSPXR, left);
> +	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMSPYR, crop->top);
> +	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMSZXR, width);
> +	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMSZYR, crop->height);
> +
> +	vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMCR,
> +		       VI6_UIF_DISCOM_DOCMCR_CMPR);
> +}
> +
> +static const struct vsp1_entity_operations uif_entity_ops = {
> +	.configure = uif_configure,
> +};
> +
> +/* -----------------------------------------------------------------------------
> + * Initialization and Cleanup
> + */
> +
> +static const struct soc_device_attribute vsp1_r8a7796[] = {
> +	{ .soc_id = "r8a7796" },
> +	{ /* sentinel */ }
> +};
> +
> +struct vsp1_uif *vsp1_uif_create(struct vsp1_device *vsp1, unsigned int index)
> +{
> +	struct vsp1_uif *uif;
> +	char name[6];
> +	int ret;
> +
> +	uif = devm_kzalloc(vsp1->dev, sizeof(*uif), GFP_KERNEL);
> +	if (uif == NULL)
> +		return ERR_PTR(-ENOMEM);
> +
> +	if (soc_device_match(vsp1_r8a7796))
> +		uif->m3w_quirk = true;
> +
> +	uif->entity.ops = &uif_entity_ops;
> +	uif->entity.type = VSP1_ENTITY_UIF;
> +	uif->entity.index = index;
> +
> +	/* The datasheet names the two UIF instances UIF4 and UIF5. */
> +	sprintf(name, "uif.%u", index + 4);
> +	ret = vsp1_entity_init(vsp1, &uif->entity, name, 2, &uif_ops,
> +			       MEDIA_ENT_F_PROC_VIDEO_STATISTICS);
> +	if (ret < 0)
> +		return ERR_PTR(ret);
> +
> +	return uif;
> +}
> diff --git a/drivers/media/platform/vsp1/vsp1_uif.h b/drivers/media/platform/vsp1/vsp1_uif.h
> new file mode 100644
> index 000000000000..c71ab5f6a6f8
> --- /dev/null
> +++ b/drivers/media/platform/vsp1/vsp1_uif.h
> @@ -0,0 +1,32 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * vsp1_uif.h  --  R-Car VSP1 User Logic Interface
> + *
> + * Copyright (C) 2017-2018 Laurent Pinchart
> + *
> + * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
> + */
> +#ifndef __VSP1_UIF_H__
> +#define __VSP1_UIF_H__
> +
> +#include "vsp1_entity.h"
> +
> +struct vsp1_device;
> +
> +#define UIF_PAD_SINK				0
> +#define UIF_PAD_SOURCE				1
> +
> +struct vsp1_uif {
> +	struct vsp1_entity entity;
> +	bool m3w_quirk;
> +};
> +
> +static inline struct vsp1_uif *to_uif(struct v4l2_subdev *subdev)
> +{
> +	return container_of(subdev, struct vsp1_uif, entity.subdev);
> +}
> +
> +struct vsp1_uif *vsp1_uif_create(struct vsp1_device *vsp1, unsigned int index);
> +u32 vsp1_uif_get_crc(struct vsp1_uif *uif);
> +
> +#endif /* __VSP1_UIF_H__ */
> 


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

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

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

* Re: [PATCH v2 7/8] v4l: vsp1: Integrate DISCOM in display pipeline
  2018-04-22 22:34   ` Laurent Pinchart
@ 2018-04-28 18:58     ` Kieran Bingham
  -1 siblings, 0 replies; 82+ messages in thread
From: Kieran Bingham @ 2018-04-28 18:58 UTC (permalink / raw)
  To: Laurent Pinchart, linux-media, dri-devel; +Cc: linux-renesas-soc


[-- Attachment #1.1: Type: text/plain, Size: 9190 bytes --]

Hi Laurent,

On 22/04/18 23:34, Laurent Pinchart wrote:
> The DISCOM is used to compute CRCs on display frames. Integrate it in
> the display pipeline at the output of the blending unit to process
> output frames.
> 
> Computing CRCs on input frames is possible by positioning the DISCOM at
> a different point in the pipeline. This use case isn't supported at the
> moment and could be implemented by extending the API between the VSP1
> and DU drivers if needed.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

Only a couple of small questions - but nothing to block an RB tag.

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

> ---
>  drivers/media/platform/vsp1/vsp1_drm.c | 115 ++++++++++++++++++++++++++++++++-
>  drivers/media/platform/vsp1/vsp1_drm.h |  12 ++++
>  2 files changed, 124 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c
> index 5fc31578f9b0..7864b43a90e1 100644
> --- a/drivers/media/platform/vsp1/vsp1_drm.c
> +++ b/drivers/media/platform/vsp1/vsp1_drm.c
> @@ -22,6 +22,7 @@
>  #include "vsp1_lif.h"
>  #include "vsp1_pipe.h"
>  #include "vsp1_rwpf.h"
> +#include "vsp1_uif.h"
>  
>  #define BRX_NAME(e)	(e)->type == VSP1_ENTITY_BRU ? "BRU" : "BRS"
>  
> @@ -35,8 +36,13 @@ static void vsp1_du_pipeline_frame_end(struct vsp1_pipeline *pipe,
>  	struct vsp1_drm_pipeline *drm_pipe = to_vsp1_drm_pipeline(pipe);
>  	bool complete = completion == VSP1_DL_FRAME_END_COMPLETED;
>  
> -	if (drm_pipe->du_complete)
> -		drm_pipe->du_complete(drm_pipe->du_private, complete, 0);
> +	if (drm_pipe->du_complete) {
> +		struct vsp1_entity *uif = drm_pipe->uif;
> +		u32 crc;
> +
> +		crc = uif ? vsp1_uif_get_crc(to_uif(&uif->subdev)) : 0;
> +		drm_pipe->du_complete(drm_pipe->du_private, complete, crc);
> +	}
>  
>  	if (completion & VSP1_DL_FRAME_END_INTERNAL) {
>  		drm_pipe->force_brx_release = false;
> @@ -48,10 +54,65 @@ static void vsp1_du_pipeline_frame_end(struct vsp1_pipeline *pipe,
>   * Pipeline Configuration
>   */
>  
> +/*
> + * Insert the UIF in the pipeline between the prev and next entities. If no UIF
> + * is available connect the two entities directly.
> + */
> +static int vsp1_du_insert_uif(struct vsp1_device *vsp1,
> +			      struct vsp1_pipeline *pipe,
> +			      struct vsp1_entity *uif,
> +			      struct vsp1_entity *prev, unsigned int prev_pad,
> +			      struct vsp1_entity *next, unsigned int next_pad)
> +{
> +	int ret;
> +
> +	if (uif) {
> +		struct v4l2_subdev_format format;
> +
> +		prev->sink = uif;
> +		prev->sink_pad = UIF_PAD_SINK;
> +
> +		memset(&format, 0, sizeof(format));
> +		format.which = V4L2_SUBDEV_FORMAT_ACTIVE;
> +		format.pad = prev_pad;
> +
> +		ret = v4l2_subdev_call(&prev->subdev, pad, get_fmt, NULL,
> +				       &format);
> +		if (ret < 0)
> +			return ret;
> +
> +		format.pad = UIF_PAD_SINK;
> +
> +		ret = v4l2_subdev_call(&uif->subdev, pad, set_fmt, NULL,
> +				       &format);
> +		if (ret < 0)
> +			return ret;
> +
> +		dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on UIF sink\n",
> +			__func__, format.format.width, format.format.height,
> +			format.format.code);
> +
> +		/*
> +		 * The UIF doesn't mangle the format between its sink and
> +		 * source pads, so there is no need to retrieve the format on
> +		 * its source pad.
> +		 */
> +
> +		uif->sink = next;
> +		uif->sink_pad = next_pad;
> +	} else {
> +		prev->sink = next;
> +		prev->sink_pad = next_pad;
> +	}
> +
> +	return 0;
> +}
> +
>  /* Setup one RPF and the connected BRx sink pad. */
>  static int vsp1_du_pipeline_setup_rpf(struct vsp1_device *vsp1,
>  				      struct vsp1_pipeline *pipe,
>  				      struct vsp1_rwpf *rpf,
> +				      struct vsp1_entity *uif,
>  				      unsigned int brx_input)
>  {
>  	struct v4l2_subdev_selection sel;
> @@ -122,6 +183,12 @@ static int vsp1_du_pipeline_setup_rpf(struct vsp1_device *vsp1,
>  	if (ret < 0)
>  		return ret;
>  
> +	/* Insert and configure the UIF if available. */
> +	ret = vsp1_du_insert_uif(vsp1, pipe, uif, &rpf->entity, RWPF_PAD_SOURCE,
> +				 pipe->brx, brx_input);
> +	if (ret < 0)
> +		return ret;
> +
>  	/* BRx sink, propagate the format from the RPF source. */
>  	format.pad = brx_input;
>  
> @@ -297,7 +364,10 @@ static unsigned int rpf_zpos(struct vsp1_device *vsp1, struct vsp1_rwpf *rpf)
>  static int vsp1_du_pipeline_setup_inputs(struct vsp1_device *vsp1,
>  					struct vsp1_pipeline *pipe)
>  {
> +	struct vsp1_drm_pipeline *drm_pipe = to_vsp1_drm_pipeline(pipe);
>  	struct vsp1_rwpf *inputs[VSP1_MAX_RPF] = { NULL, };
> +	struct vsp1_entity *uif;
> +	bool use_uif = false;
>  	struct vsp1_brx *brx;
>  	unsigned int i;
>  	int ret;
> @@ -358,7 +428,11 @@ static int vsp1_du_pipeline_setup_inputs(struct vsp1_device *vsp1,
>  		dev_dbg(vsp1->dev, "%s: connecting RPF.%u to %s:%u\n",
>  			__func__, rpf->entity.index, BRX_NAME(pipe->brx), i);
>  
> -		ret = vsp1_du_pipeline_setup_rpf(vsp1, pipe, rpf, i);
> +		uif = drm_pipe->crc.source == VSP1_DU_CRC_PLANE &&
> +		      drm_pipe->crc.index == i ? drm_pipe->uif : NULL;
> +		if (uif)
> +			use_uif = true;
> +		ret = vsp1_du_pipeline_setup_rpf(vsp1, pipe, rpf, uif, i);
>  		if (ret < 0) {
>  			dev_err(vsp1->dev,
>  				"%s: failed to setup RPF.%u\n",
> @@ -367,6 +441,31 @@ static int vsp1_du_pipeline_setup_inputs(struct vsp1_device *vsp1,
>  		}
>  	}
>  
> +	/* Insert and configure the UIF at the BRx output if available. */
> +	uif = drm_pipe->crc.source == VSP1_DU_CRC_OUTPUT ? drm_pipe->uif : NULL;
> +	if (uif)
> +		use_uif = true;
> +	ret = vsp1_du_insert_uif(vsp1, pipe, uif,
> +				 pipe->brx, pipe->brx->source_pad,
> +				 &pipe->output->entity, 0);
> +	if (ret < 0)
> +		dev_err(vsp1->dev, "%s: failed to setup UIF after %s\n",
> +			__func__, BRX_NAME(pipe->brx));
> +
> +	/*
> +	 * If the UIF is not in use schedule it for removal by setting its pipe
> +	 * pointer to NULL, vsp1_du_pipeline_configure() will remove it from the
> +	 * hardware pipeline and from the pipeline's list of entities. Otherwise
> +	 * make sure it is present in the pipeline's list of entities if it
> +	 * wasn't already.
> +	 */
> +	if (!use_uif) {

Do we need use_uif here? Wouldn't uif suffice? - Oh - no it wouldn't. A UIF at
RPF would get overwritten by the lack of UIF at BRx.

Nothing to see here. Move along...


> +		drm_pipe->uif->pipe = NULL;
> +	} else if (!drm_pipe->uif->pipe) {
> +		drm_pipe->uif->pipe = pipe;
> +		list_add_tail(&drm_pipe->uif->list_pipe, &pipe->entities);
> +	}
> +
>  	return 0;
>  }
>  
> @@ -748,6 +847,9 @@ void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index,
>  	struct vsp1_drm_pipeline *drm_pipe = &vsp1->drm->pipe[pipe_index];
>  	struct vsp1_pipeline *pipe = &drm_pipe->pipe;
>  
> +	drm_pipe->crc.source = cfg->crc.source;
> +	drm_pipe->crc.index = cfg->crc.index;

I think this could be shortened to

	drm_pipe->crc = cfg->crc;

Or is that a GCC extension. Either way, it's just a matter of taste, and you
might prefer to be more explicit.


> +
>  	vsp1_du_pipeline_setup_inputs(vsp1, pipe);
>  	vsp1_du_pipeline_configure(pipe);
>  	mutex_unlock(&vsp1->drm->lock);
> @@ -816,6 +918,13 @@ int vsp1_drm_init(struct vsp1_device *vsp1)
>  
>  		pipe->lif->pipe = pipe;
>  		list_add_tail(&pipe->lif->list_pipe, &pipe->entities);
> +
> +		/*
> +		 * CRC computation is initially disabled, don't add the UIF to
> +		 * the pipeline.
> +		 */
> +		if (i < vsp1->info->uif_count)
> +			drm_pipe->uif = &vsp1->uif[i]->entity;
>  	}
>  
>  	/* Disable all RPFs initially. */
> diff --git a/drivers/media/platform/vsp1/vsp1_drm.h b/drivers/media/platform/vsp1/vsp1_drm.h
> index e5b88b28806c..1e7670955ef0 100644
> --- a/drivers/media/platform/vsp1/vsp1_drm.h
> +++ b/drivers/media/platform/vsp1/vsp1_drm.h
> @@ -13,6 +13,8 @@
>  #include <linux/videodev2.h>
>  #include <linux/wait.h>
>  
> +#include <media/vsp1.h>
> +
>  #include "vsp1_pipe.h"
>  
>  /**
> @@ -22,6 +24,9 @@
>   * @height: output display height
>   * @force_brx_release: when set, release the BRx during the next reconfiguration
>   * @wait_queue: wait queue to wait for BRx release completion
> + * @uif: UIF entity if available for the pipeline
> + * @crc.source: source for CRC calculation
> + * @crc.index: index of the CRC source plane (when crc.source is set to plane)
>   * @du_complete: frame completion callback for the DU driver (optional)
>   * @du_private: data to be passed to the du_complete callback
>   */
> @@ -34,6 +39,13 @@ struct vsp1_drm_pipeline {
>  	bool force_brx_release;
>  	wait_queue_head_t wait_queue;
>  
> +	struct vsp1_entity *uif;
> +
> +	struct {
> +		enum vsp1_du_crc_source source;
> +		unsigned int index;
> +	} crc;

Does this have to be duplicated ? Or can it be included from the API header...


> +
>  	/* Frame synchronisation */
>  	void (*du_complete)(void *data, bool completed, u32 crc);
>  	void *du_private;
> 


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v2 7/8] v4l: vsp1: Integrate DISCOM in display pipeline
@ 2018-04-28 18:58     ` Kieran Bingham
  0 siblings, 0 replies; 82+ messages in thread
From: Kieran Bingham @ 2018-04-28 18:58 UTC (permalink / raw)
  To: Laurent Pinchart, linux-media, dri-devel; +Cc: linux-renesas-soc


[-- Attachment #1.1.1: Type: text/plain, Size: 9190 bytes --]

Hi Laurent,

On 22/04/18 23:34, Laurent Pinchart wrote:
> The DISCOM is used to compute CRCs on display frames. Integrate it in
> the display pipeline at the output of the blending unit to process
> output frames.
> 
> Computing CRCs on input frames is possible by positioning the DISCOM at
> a different point in the pipeline. This use case isn't supported at the
> moment and could be implemented by extending the API between the VSP1
> and DU drivers if needed.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

Only a couple of small questions - but nothing to block an RB tag.

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

> ---
>  drivers/media/platform/vsp1/vsp1_drm.c | 115 ++++++++++++++++++++++++++++++++-
>  drivers/media/platform/vsp1/vsp1_drm.h |  12 ++++
>  2 files changed, 124 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c
> index 5fc31578f9b0..7864b43a90e1 100644
> --- a/drivers/media/platform/vsp1/vsp1_drm.c
> +++ b/drivers/media/platform/vsp1/vsp1_drm.c
> @@ -22,6 +22,7 @@
>  #include "vsp1_lif.h"
>  #include "vsp1_pipe.h"
>  #include "vsp1_rwpf.h"
> +#include "vsp1_uif.h"
>  
>  #define BRX_NAME(e)	(e)->type == VSP1_ENTITY_BRU ? "BRU" : "BRS"
>  
> @@ -35,8 +36,13 @@ static void vsp1_du_pipeline_frame_end(struct vsp1_pipeline *pipe,
>  	struct vsp1_drm_pipeline *drm_pipe = to_vsp1_drm_pipeline(pipe);
>  	bool complete = completion == VSP1_DL_FRAME_END_COMPLETED;
>  
> -	if (drm_pipe->du_complete)
> -		drm_pipe->du_complete(drm_pipe->du_private, complete, 0);
> +	if (drm_pipe->du_complete) {
> +		struct vsp1_entity *uif = drm_pipe->uif;
> +		u32 crc;
> +
> +		crc = uif ? vsp1_uif_get_crc(to_uif(&uif->subdev)) : 0;
> +		drm_pipe->du_complete(drm_pipe->du_private, complete, crc);
> +	}
>  
>  	if (completion & VSP1_DL_FRAME_END_INTERNAL) {
>  		drm_pipe->force_brx_release = false;
> @@ -48,10 +54,65 @@ static void vsp1_du_pipeline_frame_end(struct vsp1_pipeline *pipe,
>   * Pipeline Configuration
>   */
>  
> +/*
> + * Insert the UIF in the pipeline between the prev and next entities. If no UIF
> + * is available connect the two entities directly.
> + */
> +static int vsp1_du_insert_uif(struct vsp1_device *vsp1,
> +			      struct vsp1_pipeline *pipe,
> +			      struct vsp1_entity *uif,
> +			      struct vsp1_entity *prev, unsigned int prev_pad,
> +			      struct vsp1_entity *next, unsigned int next_pad)
> +{
> +	int ret;
> +
> +	if (uif) {
> +		struct v4l2_subdev_format format;
> +
> +		prev->sink = uif;
> +		prev->sink_pad = UIF_PAD_SINK;
> +
> +		memset(&format, 0, sizeof(format));
> +		format.which = V4L2_SUBDEV_FORMAT_ACTIVE;
> +		format.pad = prev_pad;
> +
> +		ret = v4l2_subdev_call(&prev->subdev, pad, get_fmt, NULL,
> +				       &format);
> +		if (ret < 0)
> +			return ret;
> +
> +		format.pad = UIF_PAD_SINK;
> +
> +		ret = v4l2_subdev_call(&uif->subdev, pad, set_fmt, NULL,
> +				       &format);
> +		if (ret < 0)
> +			return ret;
> +
> +		dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on UIF sink\n",
> +			__func__, format.format.width, format.format.height,
> +			format.format.code);
> +
> +		/*
> +		 * The UIF doesn't mangle the format between its sink and
> +		 * source pads, so there is no need to retrieve the format on
> +		 * its source pad.
> +		 */
> +
> +		uif->sink = next;
> +		uif->sink_pad = next_pad;
> +	} else {
> +		prev->sink = next;
> +		prev->sink_pad = next_pad;
> +	}
> +
> +	return 0;
> +}
> +
>  /* Setup one RPF and the connected BRx sink pad. */
>  static int vsp1_du_pipeline_setup_rpf(struct vsp1_device *vsp1,
>  				      struct vsp1_pipeline *pipe,
>  				      struct vsp1_rwpf *rpf,
> +				      struct vsp1_entity *uif,
>  				      unsigned int brx_input)
>  {
>  	struct v4l2_subdev_selection sel;
> @@ -122,6 +183,12 @@ static int vsp1_du_pipeline_setup_rpf(struct vsp1_device *vsp1,
>  	if (ret < 0)
>  		return ret;
>  
> +	/* Insert and configure the UIF if available. */
> +	ret = vsp1_du_insert_uif(vsp1, pipe, uif, &rpf->entity, RWPF_PAD_SOURCE,
> +				 pipe->brx, brx_input);
> +	if (ret < 0)
> +		return ret;
> +
>  	/* BRx sink, propagate the format from the RPF source. */
>  	format.pad = brx_input;
>  
> @@ -297,7 +364,10 @@ static unsigned int rpf_zpos(struct vsp1_device *vsp1, struct vsp1_rwpf *rpf)
>  static int vsp1_du_pipeline_setup_inputs(struct vsp1_device *vsp1,
>  					struct vsp1_pipeline *pipe)
>  {
> +	struct vsp1_drm_pipeline *drm_pipe = to_vsp1_drm_pipeline(pipe);
>  	struct vsp1_rwpf *inputs[VSP1_MAX_RPF] = { NULL, };
> +	struct vsp1_entity *uif;
> +	bool use_uif = false;
>  	struct vsp1_brx *brx;
>  	unsigned int i;
>  	int ret;
> @@ -358,7 +428,11 @@ static int vsp1_du_pipeline_setup_inputs(struct vsp1_device *vsp1,
>  		dev_dbg(vsp1->dev, "%s: connecting RPF.%u to %s:%u\n",
>  			__func__, rpf->entity.index, BRX_NAME(pipe->brx), i);
>  
> -		ret = vsp1_du_pipeline_setup_rpf(vsp1, pipe, rpf, i);
> +		uif = drm_pipe->crc.source == VSP1_DU_CRC_PLANE &&
> +		      drm_pipe->crc.index == i ? drm_pipe->uif : NULL;
> +		if (uif)
> +			use_uif = true;
> +		ret = vsp1_du_pipeline_setup_rpf(vsp1, pipe, rpf, uif, i);
>  		if (ret < 0) {
>  			dev_err(vsp1->dev,
>  				"%s: failed to setup RPF.%u\n",
> @@ -367,6 +441,31 @@ static int vsp1_du_pipeline_setup_inputs(struct vsp1_device *vsp1,
>  		}
>  	}
>  
> +	/* Insert and configure the UIF at the BRx output if available. */
> +	uif = drm_pipe->crc.source == VSP1_DU_CRC_OUTPUT ? drm_pipe->uif : NULL;
> +	if (uif)
> +		use_uif = true;
> +	ret = vsp1_du_insert_uif(vsp1, pipe, uif,
> +				 pipe->brx, pipe->brx->source_pad,
> +				 &pipe->output->entity, 0);
> +	if (ret < 0)
> +		dev_err(vsp1->dev, "%s: failed to setup UIF after %s\n",
> +			__func__, BRX_NAME(pipe->brx));
> +
> +	/*
> +	 * If the UIF is not in use schedule it for removal by setting its pipe
> +	 * pointer to NULL, vsp1_du_pipeline_configure() will remove it from the
> +	 * hardware pipeline and from the pipeline's list of entities. Otherwise
> +	 * make sure it is present in the pipeline's list of entities if it
> +	 * wasn't already.
> +	 */
> +	if (!use_uif) {

Do we need use_uif here? Wouldn't uif suffice? - Oh - no it wouldn't. A UIF at
RPF would get overwritten by the lack of UIF at BRx.

Nothing to see here. Move along...


> +		drm_pipe->uif->pipe = NULL;
> +	} else if (!drm_pipe->uif->pipe) {
> +		drm_pipe->uif->pipe = pipe;
> +		list_add_tail(&drm_pipe->uif->list_pipe, &pipe->entities);
> +	}
> +
>  	return 0;
>  }
>  
> @@ -748,6 +847,9 @@ void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index,
>  	struct vsp1_drm_pipeline *drm_pipe = &vsp1->drm->pipe[pipe_index];
>  	struct vsp1_pipeline *pipe = &drm_pipe->pipe;
>  
> +	drm_pipe->crc.source = cfg->crc.source;
> +	drm_pipe->crc.index = cfg->crc.index;

I think this could be shortened to

	drm_pipe->crc = cfg->crc;

Or is that a GCC extension. Either way, it's just a matter of taste, and you
might prefer to be more explicit.


> +
>  	vsp1_du_pipeline_setup_inputs(vsp1, pipe);
>  	vsp1_du_pipeline_configure(pipe);
>  	mutex_unlock(&vsp1->drm->lock);
> @@ -816,6 +918,13 @@ int vsp1_drm_init(struct vsp1_device *vsp1)
>  
>  		pipe->lif->pipe = pipe;
>  		list_add_tail(&pipe->lif->list_pipe, &pipe->entities);
> +
> +		/*
> +		 * CRC computation is initially disabled, don't add the UIF to
> +		 * the pipeline.
> +		 */
> +		if (i < vsp1->info->uif_count)
> +			drm_pipe->uif = &vsp1->uif[i]->entity;
>  	}
>  
>  	/* Disable all RPFs initially. */
> diff --git a/drivers/media/platform/vsp1/vsp1_drm.h b/drivers/media/platform/vsp1/vsp1_drm.h
> index e5b88b28806c..1e7670955ef0 100644
> --- a/drivers/media/platform/vsp1/vsp1_drm.h
> +++ b/drivers/media/platform/vsp1/vsp1_drm.h
> @@ -13,6 +13,8 @@
>  #include <linux/videodev2.h>
>  #include <linux/wait.h>
>  
> +#include <media/vsp1.h>
> +
>  #include "vsp1_pipe.h"
>  
>  /**
> @@ -22,6 +24,9 @@
>   * @height: output display height
>   * @force_brx_release: when set, release the BRx during the next reconfiguration
>   * @wait_queue: wait queue to wait for BRx release completion
> + * @uif: UIF entity if available for the pipeline
> + * @crc.source: source for CRC calculation
> + * @crc.index: index of the CRC source plane (when crc.source is set to plane)
>   * @du_complete: frame completion callback for the DU driver (optional)
>   * @du_private: data to be passed to the du_complete callback
>   */
> @@ -34,6 +39,13 @@ struct vsp1_drm_pipeline {
>  	bool force_brx_release;
>  	wait_queue_head_t wait_queue;
>  
> +	struct vsp1_entity *uif;
> +
> +	struct {
> +		enum vsp1_du_crc_source source;
> +		unsigned int index;
> +	} crc;

Does this have to be duplicated ? Or can it be included from the API header...


> +
>  	/* Frame synchronisation */
>  	void (*du_complete)(void *data, bool completed, u32 crc);
>  	void *du_private;
> 


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

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

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

* Re: [PATCH v2 7/8] v4l: vsp1: Integrate DISCOM in display pipeline
  2018-04-28 18:58     ` Kieran Bingham
@ 2018-04-28 19:15       ` Laurent Pinchart
  -1 siblings, 0 replies; 82+ messages in thread
From: Laurent Pinchart @ 2018-04-28 19:15 UTC (permalink / raw)
  To: Kieran Bingham
  Cc: Laurent Pinchart, linux-media, dri-devel, linux-renesas-soc

Hi Kieran,

On Saturday, 28 April 2018 21:58:53 EEST Kieran Bingham wrote:
> On 22/04/18 23:34, Laurent Pinchart wrote:
> > The DISCOM is used to compute CRCs on display frames. Integrate it in
> > the display pipeline at the output of the blending unit to process
> > output frames.
> > 
> > Computing CRCs on input frames is possible by positioning the DISCOM at
> > a different point in the pipeline. This use case isn't supported at the
> > moment and could be implemented by extending the API between the VSP1
> > and DU drivers if needed.
> > 
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com>
> 
> Only a couple of small questions - but nothing to block an RB tag.
> 
> Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
> 
> > ---
> > 
> >  drivers/media/platform/vsp1/vsp1_drm.c | 115 +++++++++++++++++++++++++++-
> >  drivers/media/platform/vsp1/vsp1_drm.h |  12 ++++
> >  2 files changed, 124 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/media/platform/vsp1/vsp1_drm.c
> > b/drivers/media/platform/vsp1/vsp1_drm.c index 5fc31578f9b0..7864b43a90e1
> > 100644
> > --- a/drivers/media/platform/vsp1/vsp1_drm.c
> > +++ b/drivers/media/platform/vsp1/vsp1_drm.c

[snip]

> > @@ -748,6 +847,9 @@ void vsp1_du_atomic_flush(struct device *dev, unsigned
> > int pipe_index,> 
> >  	struct vsp1_drm_pipeline *drm_pipe = &vsp1->drm->pipe[pipe_index];
> >  	struct vsp1_pipeline *pipe = &drm_pipe->pipe;
> > 
> > +	drm_pipe->crc.source = cfg->crc.source;
> > +	drm_pipe->crc.index = cfg->crc.index;
> 
> I think this could be shortened to
> 
> 	drm_pipe->crc = cfg->crc;
> 
> Or is that a GCC extension. Either way, it's just a matter of taste, and you
> might prefer to be more explicit.

That's what I had written in the first place, only to have gcc throwing an 
error because the crc fields are anonymous structures.

> > +
> >  	vsp1_du_pipeline_setup_inputs(vsp1, pipe);
> >  	vsp1_du_pipeline_configure(pipe);
> >  	mutex_unlock(&vsp1->drm->lock);

[snip]

> > diff --git a/drivers/media/platform/vsp1/vsp1_drm.h
> > b/drivers/media/platform/vsp1/vsp1_drm.h index e5b88b28806c..1e7670955ef0
> > 100644
> > --- a/drivers/media/platform/vsp1/vsp1_drm.h
> > +++ b/drivers/media/platform/vsp1/vsp1_drm.h
> > @@ -13,6 +13,8 @@
> >  #include <linux/videodev2.h>
> >  #include <linux/wait.h>
> > 
> > +#include <media/vsp1.h>
> > +
> >  #include "vsp1_pipe.h"
> >  
> >  /**
> > @@ -22,6 +24,9 @@
> >   * @height: output display height
> >   * @force_brx_release: when set, release the BRx during the next
> >   reconfiguration
> >   * @wait_queue: wait queue to wait for BRx release completion
> > + * @uif: UIF entity if available for the pipeline
> > + * @crc.source: source for CRC calculation
> > + * @crc.index: index of the CRC source plane (when crc.source is set to
> > plane)
> >   * @du_complete: frame completion callback for the DU driver (optional)
> >   * @du_private: data to be passed to the du_complete callback
> >   */
> > @@ -34,6 +39,13 @@ struct vsp1_drm_pipeline {
> >  	bool force_brx_release;
> >  	wait_queue_head_t wait_queue;
> > 
> > +	struct vsp1_entity *uif;
> > +
> > +	struct {
> > +		enum vsp1_du_crc_source source;
> > +		unsigned int index;
> > +	} crc;
> 
> Does this have to be duplicated ? Or can it be included from the API
> header...

It's a good point. I thought it might not be worth it just for two fields, but 
I see no compelling reason against it. I'll introduce a new structure.

> > +
> >  	/* Frame synchronisation */
> >  	void (*du_complete)(void *data, bool completed, u32 crc);
> >  	void *du_private;

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v2 7/8] v4l: vsp1: Integrate DISCOM in display pipeline
@ 2018-04-28 19:15       ` Laurent Pinchart
  0 siblings, 0 replies; 82+ messages in thread
From: Laurent Pinchart @ 2018-04-28 19:15 UTC (permalink / raw)
  To: Kieran Bingham
  Cc: linux-renesas-soc, Laurent Pinchart, dri-devel, linux-media

Hi Kieran,

On Saturday, 28 April 2018 21:58:53 EEST Kieran Bingham wrote:
> On 22/04/18 23:34, Laurent Pinchart wrote:
> > The DISCOM is used to compute CRCs on display frames. Integrate it in
> > the display pipeline at the output of the blending unit to process
> > output frames.
> > 
> > Computing CRCs on input frames is possible by positioning the DISCOM at
> > a different point in the pipeline. This use case isn't supported at the
> > moment and could be implemented by extending the API between the VSP1
> > and DU drivers if needed.
> > 
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com>
> 
> Only a couple of small questions - but nothing to block an RB tag.
> 
> Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
> 
> > ---
> > 
> >  drivers/media/platform/vsp1/vsp1_drm.c | 115 +++++++++++++++++++++++++++-
> >  drivers/media/platform/vsp1/vsp1_drm.h |  12 ++++
> >  2 files changed, 124 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/media/platform/vsp1/vsp1_drm.c
> > b/drivers/media/platform/vsp1/vsp1_drm.c index 5fc31578f9b0..7864b43a90e1
> > 100644
> > --- a/drivers/media/platform/vsp1/vsp1_drm.c
> > +++ b/drivers/media/platform/vsp1/vsp1_drm.c

[snip]

> > @@ -748,6 +847,9 @@ void vsp1_du_atomic_flush(struct device *dev, unsigned
> > int pipe_index,> 
> >  	struct vsp1_drm_pipeline *drm_pipe = &vsp1->drm->pipe[pipe_index];
> >  	struct vsp1_pipeline *pipe = &drm_pipe->pipe;
> > 
> > +	drm_pipe->crc.source = cfg->crc.source;
> > +	drm_pipe->crc.index = cfg->crc.index;
> 
> I think this could be shortened to
> 
> 	drm_pipe->crc = cfg->crc;
> 
> Or is that a GCC extension. Either way, it's just a matter of taste, and you
> might prefer to be more explicit.

That's what I had written in the first place, only to have gcc throwing an 
error because the crc fields are anonymous structures.

> > +
> >  	vsp1_du_pipeline_setup_inputs(vsp1, pipe);
> >  	vsp1_du_pipeline_configure(pipe);
> >  	mutex_unlock(&vsp1->drm->lock);

[snip]

> > diff --git a/drivers/media/platform/vsp1/vsp1_drm.h
> > b/drivers/media/platform/vsp1/vsp1_drm.h index e5b88b28806c..1e7670955ef0
> > 100644
> > --- a/drivers/media/platform/vsp1/vsp1_drm.h
> > +++ b/drivers/media/platform/vsp1/vsp1_drm.h
> > @@ -13,6 +13,8 @@
> >  #include <linux/videodev2.h>
> >  #include <linux/wait.h>
> > 
> > +#include <media/vsp1.h>
> > +
> >  #include "vsp1_pipe.h"
> >  
> >  /**
> > @@ -22,6 +24,9 @@
> >   * @height: output display height
> >   * @force_brx_release: when set, release the BRx during the next
> >   reconfiguration
> >   * @wait_queue: wait queue to wait for BRx release completion
> > + * @uif: UIF entity if available for the pipeline
> > + * @crc.source: source for CRC calculation
> > + * @crc.index: index of the CRC source plane (when crc.source is set to
> > plane)
> >   * @du_complete: frame completion callback for the DU driver (optional)
> >   * @du_private: data to be passed to the du_complete callback
> >   */
> > @@ -34,6 +39,13 @@ struct vsp1_drm_pipeline {
> >  	bool force_brx_release;
> >  	wait_queue_head_t wait_queue;
> > 
> > +	struct vsp1_entity *uif;
> > +
> > +	struct {
> > +		enum vsp1_du_crc_source source;
> > +		unsigned int index;
> > +	} crc;
> 
> Does this have to be duplicated ? Or can it be included from the API
> header...

It's a good point. I thought it might not be worth it just for two fields, but 
I see no compelling reason against it. I'll introduce a new structure.

> > +
> >  	/* Frame synchronisation */
> >  	void (*du_complete)(void *data, bool completed, u32 crc);
> >  	void *du_private;

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

* Re: [PATCH v2 8/8] drm: rcar-du: Add support for CRC computation
  2018-04-22 22:34   ` Laurent Pinchart
@ 2018-04-28 19:16     ` Kieran Bingham
  -1 siblings, 0 replies; 82+ messages in thread
From: Kieran Bingham @ 2018-04-28 19:16 UTC (permalink / raw)
  To: Laurent Pinchart, linux-media, dri-devel; +Cc: linux-renesas-soc


[-- Attachment #1.1: Type: text/plain, Size: 9421 bytes --]

Hi Laurent,

On 22/04/18 23:34, Laurent Pinchart wrote:
> Implement CRC computation configuration and reporting through the DRM
> debugfs-based CRC API. The CRC source can be configured to any input
> plane or the pipeline output.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

I don't think I have any actual blocking questions here, so feel free to add a

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

I'll not be in distress if the CRC structures remain duplicated (although I see
from your other mail you've considered defining the structure non-anonymously

--
Kieran



> ---
> Changes since v1:
> 
> - Format the source names using plane IDs instead of plane indices
> ---
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 156 +++++++++++++++++++++++++++++++--
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.h |  19 ++++
>  drivers/gpu/drm/rcar-du/rcar_du_vsp.c  |   7 ++
>  3 files changed, 176 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> index c4420538ec85..d71d709fe3d9 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> @@ -691,6 +691,52 @@ static const struct drm_crtc_helper_funcs crtc_helper_funcs = {
>  	.atomic_disable = rcar_du_crtc_atomic_disable,
>  };
>  
> +static struct drm_crtc_state *
> +rcar_du_crtc_atomic_duplicate_state(struct drm_crtc *crtc)
> +{
> +	struct rcar_du_crtc_state *state;
> +	struct rcar_du_crtc_state *copy;
> +
> +	if (WARN_ON(!crtc->state))
> +		return NULL;
> +
> +	state = to_rcar_crtc_state(crtc->state);
> +	copy = kmemdup(state, sizeof(*state), GFP_KERNEL);
> +	if (copy == NULL)
> +		return NULL;
> +
> +	__drm_atomic_helper_crtc_duplicate_state(crtc, &copy->state);
> +
> +	return &copy->state;
> +}
> +
> +static void rcar_du_crtc_atomic_destroy_state(struct drm_crtc *crtc,
> +					      struct drm_crtc_state *state)
> +{
> +	__drm_atomic_helper_crtc_destroy_state(state);
> +	kfree(to_rcar_crtc_state(state));
> +}
> +
> +static void rcar_du_crtc_reset(struct drm_crtc *crtc)
> +{
> +	struct rcar_du_crtc_state *state;
> +
> +	if (crtc->state) {
> +		rcar_du_crtc_atomic_destroy_state(crtc, crtc->state);
> +		crtc->state = NULL;
> +	}
> +
> +	state = kzalloc(sizeof(*state), GFP_KERNEL);
> +	if (state == NULL)
> +		return;
> +
> +	state->crc.source = VSP1_DU_CRC_NONE;
> +	state->crc.index = 0;
> +
> +	crtc->state = &state->state;
> +	crtc->state->crtc = crtc;
> +}
> +
>  static int rcar_du_crtc_enable_vblank(struct drm_crtc *crtc)
>  {
>  	struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
> @@ -710,15 +756,111 @@ static void rcar_du_crtc_disable_vblank(struct drm_crtc *crtc)
>  	rcrtc->vblank_enable = false;
>  }
>  
> -static const struct drm_crtc_funcs crtc_funcs = {
> -	.reset = drm_atomic_helper_crtc_reset,
> +static int rcar_du_crtc_set_crc_source(struct drm_crtc *crtc,
> +				       const char *source_name,
> +				       size_t *values_cnt)
> +{
> +	struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
> +	struct drm_modeset_acquire_ctx ctx;
> +	struct drm_crtc_state *crtc_state;
> +	struct drm_atomic_state *state;
> +	enum vsp1_du_crc_source source;
> +	unsigned int index = 0;
> +	unsigned int i;
> +	int ret;
> +
> +	/*
> +	 * Parse the source name. Supported values are "plane%u" to compute the
> +	 * CRC on an input plane (%u is the plane ID), and "auto" to compute the
> +	 * CRC on the composer (VSP) output.
> +	 */
> +	if (!source_name) {
> +		source = VSP1_DU_CRC_NONE;
> +	} else if (!strcmp(source_name, "auto")) {
> +		source = VSP1_DU_CRC_OUTPUT;
> +	} else if (strstarts(source_name, "plane")) {
> +		source = VSP1_DU_CRC_PLANE;
> +
> +		ret = kstrtouint(source_name + strlen("plane"), 10, &index);
> +		if (ret < 0)
> +			return ret;
> +
> +		for (i = 0; i < rcrtc->vsp->num_planes; ++i) {
> +			if (index == rcrtc->vsp->planes[i].plane.base.id) {
> +				index = i;
> +				break;
> +			}
> +		}
> +
> +		if (i >= rcrtc->vsp->num_planes)
> +			return -EINVAL;
> +	} else {
> +		return -EINVAL;
> +	}
> +
> +	*values_cnt = 1;
> +
> +	/* Perform an atomic commit to set the CRC source. */
> +	drm_modeset_acquire_init(&ctx, 0);
> +
> +	state = drm_atomic_state_alloc(crtc->dev);
> +	if (!state) {
> +		ret = -ENOMEM;
> +		goto unlock;
> +	}
> +
> +	state->acquire_ctx = &ctx;
> +
> +retry:
> +	crtc_state = drm_atomic_get_crtc_state(state, crtc);
> +	if (!IS_ERR(crtc_state)) {
> +		struct rcar_du_crtc_state *rcrtc_state;
> +
> +		rcrtc_state = to_rcar_crtc_state(crtc_state);
> +		rcrtc_state->crc.source = source;
> +		rcrtc_state->crc.index = index;
> +
> +		ret = drm_atomic_commit(state);

Does this 'cost' a vblank ? (as in - does this action being performed from
userspace have the capability to cause flicker, or loss of frame?)

> +	} else {
> +		ret = PTR_ERR(crtc_state);
> +	}
> +
> +	if (ret == -EDEADLK) {
> +		drm_atomic_state_clear(state);
> +		drm_modeset_backoff(&ctx);
> +		goto retry;

Not knowing what the -EDEADLK represents yet, this isn't an infinite loop
opportunity is it ? (I assume the state_clear(),backoff() clean up and prevent
that.)

> +	}
> +
> +	drm_atomic_state_put(state);
> +
> +unlock:
> +	drm_modeset_drop_locks(&ctx);
> +	drm_modeset_acquire_fini(&ctx);
> +
> +	return 0;
> +}
> +
> +static const struct drm_crtc_funcs crtc_funcs_gen2 = {
> +	.reset = rcar_du_crtc_reset,
> +	.destroy = drm_crtc_cleanup,
> +	.set_config = drm_atomic_helper_set_config,
> +	.page_flip = drm_atomic_helper_page_flip,
> +	.atomic_duplicate_state = rcar_du_crtc_atomic_duplicate_state,
> +	.atomic_destroy_state = rcar_du_crtc_atomic_destroy_state,
> +	.enable_vblank = rcar_du_crtc_enable_vblank,
> +	.disable_vblank = rcar_du_crtc_disable_vblank,
> +};
> +
> +static const struct drm_crtc_funcs crtc_funcs_gen3 = {
> +	.reset = rcar_du_crtc_reset,
>  	.destroy = drm_crtc_cleanup,
>  	.set_config = drm_atomic_helper_set_config,
>  	.page_flip = drm_atomic_helper_page_flip,
> -	.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
> -	.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
> +	.atomic_duplicate_state = rcar_du_crtc_atomic_duplicate_state,
> +	.atomic_destroy_state = rcar_du_crtc_atomic_destroy_state,
>  	.enable_vblank = rcar_du_crtc_enable_vblank,
>  	.disable_vblank = rcar_du_crtc_disable_vblank,
> +	.set_crc_source = rcar_du_crtc_set_crc_source,
>  };
>  
>  /* -----------------------------------------------------------------------------
> @@ -821,8 +963,10 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index)
>  	else
>  		primary = &rgrp->planes[index % 2].plane;
>  
> -	ret = drm_crtc_init_with_planes(rcdu->ddev, crtc, primary,
> -					NULL, &crtc_funcs, NULL);
> +	ret = drm_crtc_init_with_planes(rcdu->ddev, crtc, primary, NULL,
> +					rcdu->info->gen <= 2 ?
> +					&crtc_funcs_gen2 : &crtc_funcs_gen3,
> +					NULL);
>  	if (ret < 0)
>  		return ret;
>  
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
> index fdc2bf99bda1..518ee2c60eb8 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
> @@ -21,6 +21,8 @@
>  #include <drm/drmP.h>
>  #include <drm/drm_crtc.h>
>  
> +#include <media/vsp1.h>
> +
>  struct rcar_du_group;
>  struct rcar_du_vsp;
>  
> @@ -69,6 +71,23 @@ struct rcar_du_crtc {
>  
>  #define to_rcar_crtc(c)	container_of(c, struct rcar_du_crtc, crtc)
>  
> +/**
> + * struct rcar_du_crtc_state - Driver-specific CRTC state
> + * @state: base DRM CRTC state
> + * @crc.source: source for CRC calculation
> + * @crc.index: index of the CRC source plane (when crc.source is set to plane)
> + */
> +struct rcar_du_crtc_state {
> +	struct drm_crtc_state state;
> +
> +	struct {
> +		enum vsp1_du_crc_source source;
> +		unsigned int index;
> +	} crc;

Another definition of this structure ... (is this the third?) do we need to
replicate it each time ? (I know it's small ... but I love to keep things DRY)

> +};
> +
> +#define to_rcar_crtc_state(s) container_of(s, struct rcar_du_crtc_state, state)
> +
>  enum rcar_du_output {
>  	RCAR_DU_OUTPUT_DPAD0,
>  	RCAR_DU_OUTPUT_DPAD1,
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
> index bdcec201591f..ce19b883ad16 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
> @@ -40,6 +40,8 @@ static void rcar_du_vsp_complete(void *private, bool completed, u32 crc)
>  
>  	if (completed)
>  		rcar_du_crtc_finish_page_flip(crtc);
> +
> +	drm_crtc_add_crc_entry(&crtc->crtc, false, 0, &crc);
>  }
>  
>  void rcar_du_vsp_enable(struct rcar_du_crtc *crtc)
> @@ -103,6 +105,11 @@ void rcar_du_vsp_atomic_begin(struct rcar_du_crtc *crtc)
>  void rcar_du_vsp_atomic_flush(struct rcar_du_crtc *crtc)
>  {
>  	struct vsp1_du_atomic_pipe_config cfg = { { 0, } };
> +	struct rcar_du_crtc_state *state;
> +
> +	state = to_rcar_crtc_state(crtc->crtc.state);
> +	cfg.crc.source = state->crc.source;
> +	cfg.crc.index = state->crc.index;
>  
>  	vsp1_du_atomic_flush(crtc->vsp->vsp, crtc->vsp_pipe, &cfg);
>  }
> 


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v2 8/8] drm: rcar-du: Add support for CRC computation
@ 2018-04-28 19:16     ` Kieran Bingham
  0 siblings, 0 replies; 82+ messages in thread
From: Kieran Bingham @ 2018-04-28 19:16 UTC (permalink / raw)
  To: Laurent Pinchart, linux-media, dri-devel; +Cc: linux-renesas-soc


[-- Attachment #1.1.1: Type: text/plain, Size: 9421 bytes --]

Hi Laurent,

On 22/04/18 23:34, Laurent Pinchart wrote:
> Implement CRC computation configuration and reporting through the DRM
> debugfs-based CRC API. The CRC source can be configured to any input
> plane or the pipeline output.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

I don't think I have any actual blocking questions here, so feel free to add a

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

I'll not be in distress if the CRC structures remain duplicated (although I see
from your other mail you've considered defining the structure non-anonymously

--
Kieran



> ---
> Changes since v1:
> 
> - Format the source names using plane IDs instead of plane indices
> ---
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 156 +++++++++++++++++++++++++++++++--
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.h |  19 ++++
>  drivers/gpu/drm/rcar-du/rcar_du_vsp.c  |   7 ++
>  3 files changed, 176 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> index c4420538ec85..d71d709fe3d9 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> @@ -691,6 +691,52 @@ static const struct drm_crtc_helper_funcs crtc_helper_funcs = {
>  	.atomic_disable = rcar_du_crtc_atomic_disable,
>  };
>  
> +static struct drm_crtc_state *
> +rcar_du_crtc_atomic_duplicate_state(struct drm_crtc *crtc)
> +{
> +	struct rcar_du_crtc_state *state;
> +	struct rcar_du_crtc_state *copy;
> +
> +	if (WARN_ON(!crtc->state))
> +		return NULL;
> +
> +	state = to_rcar_crtc_state(crtc->state);
> +	copy = kmemdup(state, sizeof(*state), GFP_KERNEL);
> +	if (copy == NULL)
> +		return NULL;
> +
> +	__drm_atomic_helper_crtc_duplicate_state(crtc, &copy->state);
> +
> +	return &copy->state;
> +}
> +
> +static void rcar_du_crtc_atomic_destroy_state(struct drm_crtc *crtc,
> +					      struct drm_crtc_state *state)
> +{
> +	__drm_atomic_helper_crtc_destroy_state(state);
> +	kfree(to_rcar_crtc_state(state));
> +}
> +
> +static void rcar_du_crtc_reset(struct drm_crtc *crtc)
> +{
> +	struct rcar_du_crtc_state *state;
> +
> +	if (crtc->state) {
> +		rcar_du_crtc_atomic_destroy_state(crtc, crtc->state);
> +		crtc->state = NULL;
> +	}
> +
> +	state = kzalloc(sizeof(*state), GFP_KERNEL);
> +	if (state == NULL)
> +		return;
> +
> +	state->crc.source = VSP1_DU_CRC_NONE;
> +	state->crc.index = 0;
> +
> +	crtc->state = &state->state;
> +	crtc->state->crtc = crtc;
> +}
> +
>  static int rcar_du_crtc_enable_vblank(struct drm_crtc *crtc)
>  {
>  	struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
> @@ -710,15 +756,111 @@ static void rcar_du_crtc_disable_vblank(struct drm_crtc *crtc)
>  	rcrtc->vblank_enable = false;
>  }
>  
> -static const struct drm_crtc_funcs crtc_funcs = {
> -	.reset = drm_atomic_helper_crtc_reset,
> +static int rcar_du_crtc_set_crc_source(struct drm_crtc *crtc,
> +				       const char *source_name,
> +				       size_t *values_cnt)
> +{
> +	struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
> +	struct drm_modeset_acquire_ctx ctx;
> +	struct drm_crtc_state *crtc_state;
> +	struct drm_atomic_state *state;
> +	enum vsp1_du_crc_source source;
> +	unsigned int index = 0;
> +	unsigned int i;
> +	int ret;
> +
> +	/*
> +	 * Parse the source name. Supported values are "plane%u" to compute the
> +	 * CRC on an input plane (%u is the plane ID), and "auto" to compute the
> +	 * CRC on the composer (VSP) output.
> +	 */
> +	if (!source_name) {
> +		source = VSP1_DU_CRC_NONE;
> +	} else if (!strcmp(source_name, "auto")) {
> +		source = VSP1_DU_CRC_OUTPUT;
> +	} else if (strstarts(source_name, "plane")) {
> +		source = VSP1_DU_CRC_PLANE;
> +
> +		ret = kstrtouint(source_name + strlen("plane"), 10, &index);
> +		if (ret < 0)
> +			return ret;
> +
> +		for (i = 0; i < rcrtc->vsp->num_planes; ++i) {
> +			if (index == rcrtc->vsp->planes[i].plane.base.id) {
> +				index = i;
> +				break;
> +			}
> +		}
> +
> +		if (i >= rcrtc->vsp->num_planes)
> +			return -EINVAL;
> +	} else {
> +		return -EINVAL;
> +	}
> +
> +	*values_cnt = 1;
> +
> +	/* Perform an atomic commit to set the CRC source. */
> +	drm_modeset_acquire_init(&ctx, 0);
> +
> +	state = drm_atomic_state_alloc(crtc->dev);
> +	if (!state) {
> +		ret = -ENOMEM;
> +		goto unlock;
> +	}
> +
> +	state->acquire_ctx = &ctx;
> +
> +retry:
> +	crtc_state = drm_atomic_get_crtc_state(state, crtc);
> +	if (!IS_ERR(crtc_state)) {
> +		struct rcar_du_crtc_state *rcrtc_state;
> +
> +		rcrtc_state = to_rcar_crtc_state(crtc_state);
> +		rcrtc_state->crc.source = source;
> +		rcrtc_state->crc.index = index;
> +
> +		ret = drm_atomic_commit(state);

Does this 'cost' a vblank ? (as in - does this action being performed from
userspace have the capability to cause flicker, or loss of frame?)

> +	} else {
> +		ret = PTR_ERR(crtc_state);
> +	}
> +
> +	if (ret == -EDEADLK) {
> +		drm_atomic_state_clear(state);
> +		drm_modeset_backoff(&ctx);
> +		goto retry;

Not knowing what the -EDEADLK represents yet, this isn't an infinite loop
opportunity is it ? (I assume the state_clear(),backoff() clean up and prevent
that.)

> +	}
> +
> +	drm_atomic_state_put(state);
> +
> +unlock:
> +	drm_modeset_drop_locks(&ctx);
> +	drm_modeset_acquire_fini(&ctx);
> +
> +	return 0;
> +}
> +
> +static const struct drm_crtc_funcs crtc_funcs_gen2 = {
> +	.reset = rcar_du_crtc_reset,
> +	.destroy = drm_crtc_cleanup,
> +	.set_config = drm_atomic_helper_set_config,
> +	.page_flip = drm_atomic_helper_page_flip,
> +	.atomic_duplicate_state = rcar_du_crtc_atomic_duplicate_state,
> +	.atomic_destroy_state = rcar_du_crtc_atomic_destroy_state,
> +	.enable_vblank = rcar_du_crtc_enable_vblank,
> +	.disable_vblank = rcar_du_crtc_disable_vblank,
> +};
> +
> +static const struct drm_crtc_funcs crtc_funcs_gen3 = {
> +	.reset = rcar_du_crtc_reset,
>  	.destroy = drm_crtc_cleanup,
>  	.set_config = drm_atomic_helper_set_config,
>  	.page_flip = drm_atomic_helper_page_flip,
> -	.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
> -	.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
> +	.atomic_duplicate_state = rcar_du_crtc_atomic_duplicate_state,
> +	.atomic_destroy_state = rcar_du_crtc_atomic_destroy_state,
>  	.enable_vblank = rcar_du_crtc_enable_vblank,
>  	.disable_vblank = rcar_du_crtc_disable_vblank,
> +	.set_crc_source = rcar_du_crtc_set_crc_source,
>  };
>  
>  /* -----------------------------------------------------------------------------
> @@ -821,8 +963,10 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index)
>  	else
>  		primary = &rgrp->planes[index % 2].plane;
>  
> -	ret = drm_crtc_init_with_planes(rcdu->ddev, crtc, primary,
> -					NULL, &crtc_funcs, NULL);
> +	ret = drm_crtc_init_with_planes(rcdu->ddev, crtc, primary, NULL,
> +					rcdu->info->gen <= 2 ?
> +					&crtc_funcs_gen2 : &crtc_funcs_gen3,
> +					NULL);
>  	if (ret < 0)
>  		return ret;
>  
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
> index fdc2bf99bda1..518ee2c60eb8 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
> @@ -21,6 +21,8 @@
>  #include <drm/drmP.h>
>  #include <drm/drm_crtc.h>
>  
> +#include <media/vsp1.h>
> +
>  struct rcar_du_group;
>  struct rcar_du_vsp;
>  
> @@ -69,6 +71,23 @@ struct rcar_du_crtc {
>  
>  #define to_rcar_crtc(c)	container_of(c, struct rcar_du_crtc, crtc)
>  
> +/**
> + * struct rcar_du_crtc_state - Driver-specific CRTC state
> + * @state: base DRM CRTC state
> + * @crc.source: source for CRC calculation
> + * @crc.index: index of the CRC source plane (when crc.source is set to plane)
> + */
> +struct rcar_du_crtc_state {
> +	struct drm_crtc_state state;
> +
> +	struct {
> +		enum vsp1_du_crc_source source;
> +		unsigned int index;
> +	} crc;

Another definition of this structure ... (is this the third?) do we need to
replicate it each time ? (I know it's small ... but I love to keep things DRY)

> +};
> +
> +#define to_rcar_crtc_state(s) container_of(s, struct rcar_du_crtc_state, state)
> +
>  enum rcar_du_output {
>  	RCAR_DU_OUTPUT_DPAD0,
>  	RCAR_DU_OUTPUT_DPAD1,
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
> index bdcec201591f..ce19b883ad16 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
> @@ -40,6 +40,8 @@ static void rcar_du_vsp_complete(void *private, bool completed, u32 crc)
>  
>  	if (completed)
>  		rcar_du_crtc_finish_page_flip(crtc);
> +
> +	drm_crtc_add_crc_entry(&crtc->crtc, false, 0, &crc);
>  }
>  
>  void rcar_du_vsp_enable(struct rcar_du_crtc *crtc)
> @@ -103,6 +105,11 @@ void rcar_du_vsp_atomic_begin(struct rcar_du_crtc *crtc)
>  void rcar_du_vsp_atomic_flush(struct rcar_du_crtc *crtc)
>  {
>  	struct vsp1_du_atomic_pipe_config cfg = { { 0, } };
> +	struct rcar_du_crtc_state *state;
> +
> +	state = to_rcar_crtc_state(crtc->crtc.state);
> +	cfg.crc.source = state->crc.source;
> +	cfg.crc.index = state->crc.index;
>  
>  	vsp1_du_atomic_flush(crtc->vsp->vsp, crtc->vsp_pipe, &cfg);
>  }
> 


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

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

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

* Re: [PATCH v2 8/8] drm: rcar-du: Add support for CRC computation
  2018-04-28 19:16     ` Kieran Bingham
@ 2018-04-28 20:15       ` Laurent Pinchart
  -1 siblings, 0 replies; 82+ messages in thread
From: Laurent Pinchart @ 2018-04-28 20:15 UTC (permalink / raw)
  To: Kieran Bingham
  Cc: Laurent Pinchart, linux-media, dri-devel, linux-renesas-soc

Hi Kieran,

On Saturday, 28 April 2018 22:16:48 EEST Kieran Bingham wrote:
> On 22/04/18 23:34, Laurent Pinchart wrote:
> > Implement CRC computation configuration and reporting through the DRM
> > debugfs-based CRC API. The CRC source can be configured to any input
> > plane or the pipeline output.
> > 
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com>
> 
> I don't think I have any actual blocking questions here, so feel free to add
> a
> 
> Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
> 
> I'll not be in distress if the CRC structures remain duplicated (although I
> see from your other mail you've considered defining the structure
> non-anonymously
> 
> > ---
> > Changes since v1:
> > 
> > - Format the source names using plane IDs instead of plane indices
> > ---
> > 
> >  drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 156 ++++++++++++++++++++++++++--
> >  drivers/gpu/drm/rcar-du/rcar_du_crtc.h |  19 ++++
> >  drivers/gpu/drm/rcar-du/rcar_du_vsp.c  |   7 ++
> >  3 files changed, 176 insertions(+), 6 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> > b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c index c4420538ec85..d71d709fe3d9
> > 100644
> > --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> > +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c

[snip]

> > @@ -710,15 +756,111 @@ static void rcar_du_crtc_disable_vblank(struct
> > drm_crtc *crtc)
> >  	rcrtc->vblank_enable = false;
> >  }
> > 
> > -static const struct drm_crtc_funcs crtc_funcs = {
> > -	.reset = drm_atomic_helper_crtc_reset,
> > +static int rcar_du_crtc_set_crc_source(struct drm_crtc *crtc,
> > +				       const char *source_name,
> > +				       size_t *values_cnt)
> > +{
> > +	struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
> > +	struct drm_modeset_acquire_ctx ctx;
> > +	struct drm_crtc_state *crtc_state;
> > +	struct drm_atomic_state *state;
> > +	enum vsp1_du_crc_source source;
> > +	unsigned int index = 0;
> > +	unsigned int i;
> > +	int ret;
> > +
> > +	/*
> > +	 * Parse the source name. Supported values are "plane%u" to compute the
> > +	 * CRC on an input plane (%u is the plane ID), and "auto" to compute
> > the
> > +	 * CRC on the composer (VSP) output.
> > +	 */
> > +	if (!source_name) {
> > +		source = VSP1_DU_CRC_NONE;
> > +	} else if (!strcmp(source_name, "auto")) {
> > +		source = VSP1_DU_CRC_OUTPUT;
> > +	} else if (strstarts(source_name, "plane")) {
> > +		source = VSP1_DU_CRC_PLANE;
> > +
> > +		ret = kstrtouint(source_name + strlen("plane"), 10, &index);
> > +		if (ret < 0)
> > +			return ret;
> > +
> > +		for (i = 0; i < rcrtc->vsp->num_planes; ++i) {
> > +			if (index == rcrtc->vsp->planes[i].plane.base.id) {
> > +				index = i;
> > +				break;
> > +			}
> > +		}
> > +
> > +		if (i >= rcrtc->vsp->num_planes)
> > +			return -EINVAL;
> > +	} else {
> > +		return -EINVAL;
> > +	}
> > +
> > +	*values_cnt = 1;
> > +
> > +	/* Perform an atomic commit to set the CRC source. */
> > +	drm_modeset_acquire_init(&ctx, 0);
> > +
> > +	state = drm_atomic_state_alloc(crtc->dev);
> > +	if (!state) {
> > +		ret = -ENOMEM;
> > +		goto unlock;
> > +	}
> > +
> > +	state->acquire_ctx = &ctx;
> > +
> > +retry:
> > +	crtc_state = drm_atomic_get_crtc_state(state, crtc);
> > +	if (!IS_ERR(crtc_state)) {
> > +		struct rcar_du_crtc_state *rcrtc_state;
> > +
> > +		rcrtc_state = to_rcar_crtc_state(crtc_state);
> > +		rcrtc_state->crc.source = source;
> > +		rcrtc_state->crc.index = index;
> > +
> > +		ret = drm_atomic_commit(state);
> 
> Does this 'cost' a vblank ? (as in - does this action being performed from
> userspace have the capability to cause flicker, or loss of frame?)

It shouldn't cause flicker, but it could delay atomic commits queued by 
userspace by one frame. It's not ideal, but given that changing the CRC source 
requires a pipeline update on the VSP side, creating an atomic commit 
internally in the driver was the easiest solution.

Now that the BRU/BRS series has created infrastructure on the VSP side to 
perform pipeline reconfiguration we could also take advantage of that, but it 
would still incur a delay of one frame, so I don't think that would really 
help.

> > +	} else {
> > +		ret = PTR_ERR(crtc_state);
> > +	}
> > +
> > +	if (ret == -EDEADLK) {
> > +		drm_atomic_state_clear(state);
> > +		drm_modeset_backoff(&ctx);
> > +		goto retry;
> 
> Not knowing what the -EDEADLK represents yet, this isn't an infinite loop
> opportunity is it ? (I assume the state_clear(),backoff() clean up and
> prevent that.)

-EDEADLK comes from the drm_atomic_get_crtc_state() or drm_atomic_commit() 
calls trying to lock a ww-mutex in a way that would cause a deadlock. In that 
case a backoff sequence is needed to release all locks that have been 
successfully taken, followed by a retry. The ww-mutex API should prevent 
infinite loops by ensuring fairness between the contenders.

> > +	}
> > +
> > +	drm_atomic_state_put(state);
> > +
> > +unlock:
> > +	drm_modeset_drop_locks(&ctx);
> > +	drm_modeset_acquire_fini(&ctx);
> > +
> > +	return 0;
> > +}

[snip]

> > diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
> > b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h index fdc2bf99bda1..518ee2c60eb8
> > 100644
> > --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
> > +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
> > @@ -21,6 +21,8 @@
> >  #include <drm/drmP.h>
> >  #include <drm/drm_crtc.h>
> > 
> > +#include <media/vsp1.h>
> > +
> >  struct rcar_du_group;
> >  struct rcar_du_vsp;
> > 
> > @@ -69,6 +71,23 @@ struct rcar_du_crtc {
> > 
> >  #define to_rcar_crtc(c)	container_of(c, struct rcar_du_crtc, crtc)
> > 
> > +/**
> > + * struct rcar_du_crtc_state - Driver-specific CRTC state
> > + * @state: base DRM CRTC state
> > + * @crc.source: source for CRC calculation
> > + * @crc.index: index of the CRC source plane (when crc.source is set to
> > plane)
> > + */
> > +struct rcar_du_crtc_state {
> > +	struct drm_crtc_state state;
> > +
> > +	struct {
> > +		enum vsp1_du_crc_source source;
> > +		unsigned int index;
> > +	} crc;
> 
> Another definition of this structure ... (is this the third?) do we need to
> replicate it each time ? (I know it's small ... but I love to keep things
> DRY)

I'll fix that as I've introduced a vsp1_du_crc_config structure in response to 
your review of patch 7/8.

> > +};
> > +
> > +#define to_rcar_crtc_state(s) container_of(s, struct rcar_du_crtc_state,
> > state)
> > +
> >  enum rcar_du_output {
> >  	RCAR_DU_OUTPUT_DPAD0,
> >  	RCAR_DU_OUTPUT_DPAD1,

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v2 8/8] drm: rcar-du: Add support for CRC computation
@ 2018-04-28 20:15       ` Laurent Pinchart
  0 siblings, 0 replies; 82+ messages in thread
From: Laurent Pinchart @ 2018-04-28 20:15 UTC (permalink / raw)
  To: Kieran Bingham
  Cc: linux-renesas-soc, Laurent Pinchart, dri-devel, linux-media

Hi Kieran,

On Saturday, 28 April 2018 22:16:48 EEST Kieran Bingham wrote:
> On 22/04/18 23:34, Laurent Pinchart wrote:
> > Implement CRC computation configuration and reporting through the DRM
> > debugfs-based CRC API. The CRC source can be configured to any input
> > plane or the pipeline output.
> > 
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com>
> 
> I don't think I have any actual blocking questions here, so feel free to add
> a
> 
> Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
> 
> I'll not be in distress if the CRC structures remain duplicated (although I
> see from your other mail you've considered defining the structure
> non-anonymously
> 
> > ---
> > Changes since v1:
> > 
> > - Format the source names using plane IDs instead of plane indices
> > ---
> > 
> >  drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 156 ++++++++++++++++++++++++++--
> >  drivers/gpu/drm/rcar-du/rcar_du_crtc.h |  19 ++++
> >  drivers/gpu/drm/rcar-du/rcar_du_vsp.c  |   7 ++
> >  3 files changed, 176 insertions(+), 6 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> > b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c index c4420538ec85..d71d709fe3d9
> > 100644
> > --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> > +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c

[snip]

> > @@ -710,15 +756,111 @@ static void rcar_du_crtc_disable_vblank(struct
> > drm_crtc *crtc)
> >  	rcrtc->vblank_enable = false;
> >  }
> > 
> > -static const struct drm_crtc_funcs crtc_funcs = {
> > -	.reset = drm_atomic_helper_crtc_reset,
> > +static int rcar_du_crtc_set_crc_source(struct drm_crtc *crtc,
> > +				       const char *source_name,
> > +				       size_t *values_cnt)
> > +{
> > +	struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
> > +	struct drm_modeset_acquire_ctx ctx;
> > +	struct drm_crtc_state *crtc_state;
> > +	struct drm_atomic_state *state;
> > +	enum vsp1_du_crc_source source;
> > +	unsigned int index = 0;
> > +	unsigned int i;
> > +	int ret;
> > +
> > +	/*
> > +	 * Parse the source name. Supported values are "plane%u" to compute the
> > +	 * CRC on an input plane (%u is the plane ID), and "auto" to compute
> > the
> > +	 * CRC on the composer (VSP) output.
> > +	 */
> > +	if (!source_name) {
> > +		source = VSP1_DU_CRC_NONE;
> > +	} else if (!strcmp(source_name, "auto")) {
> > +		source = VSP1_DU_CRC_OUTPUT;
> > +	} else if (strstarts(source_name, "plane")) {
> > +		source = VSP1_DU_CRC_PLANE;
> > +
> > +		ret = kstrtouint(source_name + strlen("plane"), 10, &index);
> > +		if (ret < 0)
> > +			return ret;
> > +
> > +		for (i = 0; i < rcrtc->vsp->num_planes; ++i) {
> > +			if (index == rcrtc->vsp->planes[i].plane.base.id) {
> > +				index = i;
> > +				break;
> > +			}
> > +		}
> > +
> > +		if (i >= rcrtc->vsp->num_planes)
> > +			return -EINVAL;
> > +	} else {
> > +		return -EINVAL;
> > +	}
> > +
> > +	*values_cnt = 1;
> > +
> > +	/* Perform an atomic commit to set the CRC source. */
> > +	drm_modeset_acquire_init(&ctx, 0);
> > +
> > +	state = drm_atomic_state_alloc(crtc->dev);
> > +	if (!state) {
> > +		ret = -ENOMEM;
> > +		goto unlock;
> > +	}
> > +
> > +	state->acquire_ctx = &ctx;
> > +
> > +retry:
> > +	crtc_state = drm_atomic_get_crtc_state(state, crtc);
> > +	if (!IS_ERR(crtc_state)) {
> > +		struct rcar_du_crtc_state *rcrtc_state;
> > +
> > +		rcrtc_state = to_rcar_crtc_state(crtc_state);
> > +		rcrtc_state->crc.source = source;
> > +		rcrtc_state->crc.index = index;
> > +
> > +		ret = drm_atomic_commit(state);
> 
> Does this 'cost' a vblank ? (as in - does this action being performed from
> userspace have the capability to cause flicker, or loss of frame?)

It shouldn't cause flicker, but it could delay atomic commits queued by 
userspace by one frame. It's not ideal, but given that changing the CRC source 
requires a pipeline update on the VSP side, creating an atomic commit 
internally in the driver was the easiest solution.

Now that the BRU/BRS series has created infrastructure on the VSP side to 
perform pipeline reconfiguration we could also take advantage of that, but it 
would still incur a delay of one frame, so I don't think that would really 
help.

> > +	} else {
> > +		ret = PTR_ERR(crtc_state);
> > +	}
> > +
> > +	if (ret == -EDEADLK) {
> > +		drm_atomic_state_clear(state);
> > +		drm_modeset_backoff(&ctx);
> > +		goto retry;
> 
> Not knowing what the -EDEADLK represents yet, this isn't an infinite loop
> opportunity is it ? (I assume the state_clear(),backoff() clean up and
> prevent that.)

-EDEADLK comes from the drm_atomic_get_crtc_state() or drm_atomic_commit() 
calls trying to lock a ww-mutex in a way that would cause a deadlock. In that 
case a backoff sequence is needed to release all locks that have been 
successfully taken, followed by a retry. The ww-mutex API should prevent 
infinite loops by ensuring fairness between the contenders.

> > +	}
> > +
> > +	drm_atomic_state_put(state);
> > +
> > +unlock:
> > +	drm_modeset_drop_locks(&ctx);
> > +	drm_modeset_acquire_fini(&ctx);
> > +
> > +	return 0;
> > +}

[snip]

> > diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
> > b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h index fdc2bf99bda1..518ee2c60eb8
> > 100644
> > --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
> > +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
> > @@ -21,6 +21,8 @@
> >  #include <drm/drmP.h>
> >  #include <drm/drm_crtc.h>
> > 
> > +#include <media/vsp1.h>
> > +
> >  struct rcar_du_group;
> >  struct rcar_du_vsp;
> > 
> > @@ -69,6 +71,23 @@ struct rcar_du_crtc {
> > 
> >  #define to_rcar_crtc(c)	container_of(c, struct rcar_du_crtc, crtc)
> > 
> > +/**
> > + * struct rcar_du_crtc_state - Driver-specific CRTC state
> > + * @state: base DRM CRTC state
> > + * @crc.source: source for CRC calculation
> > + * @crc.index: index of the CRC source plane (when crc.source is set to
> > plane)
> > + */
> > +struct rcar_du_crtc_state {
> > +	struct drm_crtc_state state;
> > +
> > +	struct {
> > +		enum vsp1_du_crc_source source;
> > +		unsigned int index;
> > +	} crc;
> 
> Another definition of this structure ... (is this the third?) do we need to
> replicate it each time ? (I know it's small ... but I love to keep things
> DRY)

I'll fix that as I've introduced a vsp1_du_crc_config structure in response to 
your review of patch 7/8.

> > +};
> > +
> > +#define to_rcar_crtc_state(s) container_of(s, struct rcar_du_crtc_state,
> > state)
> > +
> >  enum rcar_du_output {
> >  	RCAR_DU_OUTPUT_DPAD0,
> >  	RCAR_DU_OUTPUT_DPAD1,

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

* Re: igt trouble with planes shared between multiple CRTCs (Re: [PATCH v2 0/8] R-Car DU: Support CRC calculation)
  2018-04-27 21:07   ` Laurent Pinchart
@ 2018-04-30 14:55     ` Daniel Vetter
  -1 siblings, 0 replies; 82+ messages in thread
From: Daniel Vetter @ 2018-04-30 14:55 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Daniel Vetter, dri-devel, linux-renesas-soc, Kieran Bingham,
	Ulrich Hecht

On Sat, Apr 28, 2018 at 12:07:04AM +0300, Laurent Pinchart wrote:
> Hi Daniel,
> 
> (Removing the linux-media mailing list from CC as it is out of scope)
> 
> You enquired on IRC whether this patch series passes the igt CRC tests.
> 
> # ./kms_pipe_crc_basic --run-subtest read-crc-pipe-A
> IGT-Version: 1.22-gf447f5fc531d (aarch64) (Linux: 4.17.0-rc1-00085-g56e849d93cc9 aarch64)
> read-crc-pipe-A: Testing connector LVDS-1 using pipe A
> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Test assertion failure function igt_pipe_crc_start, file igt_debugfs.c:764:
> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Failed assertion: pipe_crc->crc_fd != -1
> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Last errno: 5, Input/output error
> Stack trace:
> Subtest read-crc-pipe-A failed.
> **** DEBUG ****
> (kms_pipe_crc_basic:1638) DEBUG: Test requirement passed: !(pipe >= data->display.n_pipes)
> (kms_pipe_crc_basic:1638) INFO: read-crc-pipe-A: Testing connector LVDS-1 using pipe A
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: LVDS-1: set_pipe(A)
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: LVDS-1: Selecting pipe A
> (kms_pipe_crc_basic:1638) DEBUG: Clearing the fb with color (0.00,1.00,0.00)
> (kms_pipe_crc_basic:1638) igt-fb-DEBUG: igt_create_fb_with_bo_size(width=1024, height=768, format=0x34325258, tiling=0x0, size=0)
> (kms_pipe_crc_basic:1638) igt-fb-DEBUG: igt_create_fb_with_bo_size(handle=1, pitch=4096)
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: Test requirement passed: plane_idx >= 0 && plane_idx < pipe->n_planes
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: plane_set_fb(140)
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: plane_set_size (1024x768)
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: fb_set_position(0,0)
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: fb_set_size(1024x768)
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: commit {
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     LVDS-1: SetCrtc pipe A, fb 140, src (0, 0), mode 1024x768
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe A, disabling
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 2, disabling
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 3, disabling
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 4, disabling
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe B, disabling
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 1, disabling
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 2, disabling
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 3, disabling
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 4, disabling
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe C, disabling
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 1, disabling
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 2, disabling
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 3, disabling
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 4, disabling
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe D, disabling
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe D, disabling
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 2, disabling
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 3, disabling
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 4, disabling
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: }
> (kms_pipe_crc_basic:1638) igt-debugfs-DEBUG: Opening debugfs directory '/sys/kernel/debug/dri/0'
> (kms_pipe_crc_basic:1638) igt-debugfs-DEBUG: Opening debugfs directory '/sys/kernel/debug/dri/0'
> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Test assertion failure function igt_pipe_crc_start, file igt_debugfs.c:764:
> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Failed assertion: pipe_crc->crc_fd != -1
> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Last errno: 5, Input/output error
> (kms_pipe_crc_basic:1638) igt-core-INFO: Stack trace:
> ****  END  ****
> Subtest read-crc-pipe-A: FAIL (0.061s)
> 
> I think the answer is no, but I don't think it's the fault of this patch
> series. Opening the CRC data file returns -EIO because the CRTC is not active,
> and I'm trying to find out why that is the case. The debug log shows a commit
> that seems strange to me, enabling pipe A and immediately disabling right
> afterwards. After some investigation I believe that this is caused by sharing
> primary planes between CRTCs.
> 
> The R-Car DU groups CRTCs by two and shares 5 planes between the two CRTCs of
> the group. This specific SoC has two groups of two CRTCs, but that's not
> relevant here, so we can ignore pipes C and D.
> 
> Pipes A and B thus shared 5 planes that I will number 0 to 4 for simplicity.
> The driver sets plane 0 as the primary plane for CRTC A and plane 1 as the
> primary plane for CRTC B. Planes 2, 3 and 4 are created as overlay planes.
> 
> When igt iterates over all planes for pipe A, it will first encounter plane 0
> that has a framebuffer, and thus enables the pipe. It then iterates over
> plane 1, recognizes it as a primary plane without a framebuffer, and thus
> disables the pipe. Planes 2, 3 and 4 are recognized as overlay planes and thus
> don't affect the pipe active state. Pipe B is handled the same way, and igt
> disables it twice as planes 0 and 1 are primary.
> 
> I don't know if the fault here is with igt that doesn't properly support this
> architecture, or with the driver that shouldn't have two primary planes
> available for a CRTC. In the former case, I'm not sure how to fix it, as I'm
> not familiar enough with igt to rearchitecture the commit helpers. In the
> latter case, how would you recommend fixing it on the driver side ?

I guess thus far no one did run igt on a chip which did have reassignable
primary planes. The problem here is that it's pretty hard to figure out
which one is the real primary plane, since with possible CRTCs you could
have multiple primary planes on 1 CRTC. There's no property or anything
that explicitly tells you this. Two fixes:

1. Change drivers to limit primary planes to 1 crtc. Same for cursor
   overlays. There's probably other userspace than igt that gets confused
   by this, but this has the ugly downside that we artifically limit plane
   usage - if only 1 CRTC is on, we want to use all the available planes
   on that one.

2. Add some implicit or explicit uapi to allow userspace to figure out
   which primary plane is the primary plane for this crtc.

   a) Explicit option: We add a PRIMARY_ID property (and CURSOR_ID prop
      while at it) on the CRTC which points at the primary/cursor plane.

   b) Implicit option: We require primary planes are assigned to CRTC in the
      same order as they're created. So first primary plane you encouter
      is the one for the first CRTC, 2nd primary plane is the one for the
      2nd CRTC and so on. If we go with this we probably should add a bit
      of code to the kernel to check that invariant (by making sure the
      primary plane has the corresponding CRTC included in its
      possible_crtc mask).

Either way igt needs to be patched to not treat any primary plane that
could work on a CRTC as the primary plane for that CRTC.

Personally I'm leaning towards 2b).

Cheers, Daniel

> 
> On Monday, 23 April 2018 01:34:22 EEST Laurent Pinchart wrote:
> > Hello,
> > 
> > This patch series adds support for CRC calculation to the rcar-du-drm
> > driver.
> > 
> > CRC calculation is supported starting at the Renesas R-Car Gen3 SoCs, as
> > earlier versions don't have the necessary hardware. On Gen3 SoCs, the CRC is
> > computed by the DISCOM module part of the VSP-D and VSP-DL.
> > 
> > The DISCOM is interfaced to the VSP through the UIF glue and appears as a
> > VSP entity with a sink pad and a source pad.
> > 
> > The series starts with a switch to SPDX license headers in patch 1/8,
> > prompted by a checkpatch.pl warning for a later patch that complained about
> > missing SPDX license headers. It then continues with cleanup and
> > refactoring. Patches 2/8 and 3/8 prepare for DISCOM and UIF support by
> > extending generic code to make it usable for the UIF. Patch 4/8 documents a
> > structure that will receive new fields.
> > 
> > Patch 5/8 then extends the API exposed by the VSP driver to the DU driver to
> > support CRC computation configuration and reporting. The patch
> > unfortunately needs to touch both the VSP and DU drivers, so the whole
> > series will need to be merged through a single tree.
> > 
> > Patch 5/8 adds support for the DISCOM and UIF in the VSP driver, patch 7/8
> > integrates it in the DRM pipeline, and patch 8/8 finally implements the CRC
> > API in the DU driver to expose CRC computation to userspace.
> > 
> > The hardware supports computing the CRC at any arbitrary point in the
> > pipeline on a configurable window of the frame. This patch series supports
> > CRC computation on input planes or pipeline output, but on the full frame
> > only. Support for CRC window configuration can be added later if needed but
> > will require extending the userspace API, as the DRM/KMS CRC API doesn't
> > support this feature.
> > 
> > Compared to v1, the CRC source names for plane inputs are now constructed
> > from plane IDs instead of plane indices. This allows userspace to match CRC
> > sources with planes.
> > 
> > Note that exposing the DISCOM and UIF though the V4L2 API isn't supported as
> > the module is only found in VSP-D and VSP-DL instances that are not exposed
> > through V4L2. It is possible to expose those instances through V4L2 with a
> > small modification to the driver for testing purpose. If the need arises to
> > test DISCOM and UIF with such an out-of-tree patch, support for CRC
> > reporting through a V4L2 control can be added later without affecting how
> > CRC is exposed through the DRM/KMS API.
> > 
> > The patches are based on top of the "[PATCH v2 00/15] R-Car VSP1:
> > Dynamically assign blend units to display pipelines" patch series, itself
> > based on top of the Linux media master branch and scheduled for merge in
> > v4.18. The new base caused heavy conflicts, requiring this series to be
> > merged through the V4L2 tree. Once the patches receive the necessary review
> > I will ask Dave to ack the merge plan.
> > 
> > For convenience the patches are available at
> > 
> >         git://linuxtv.org/pinchartl/media.git vsp1-discom-v2-20180423
> > 
> > The code has been tested through the kms-test-crc.py script part of the DU
> > test suite available at
> > 
> >         git://git.ideasonboard.com/renesas/kms-tests.git discom
> > 
> > Laurent Pinchart (8):
> >   v4l: vsp1: Use SPDX license headers
> >   v4l: vsp1: Share the CLU, LIF and LUT set_fmt pad operation code
> >   v4l: vsp1: Reset the crop and compose rectangles in the set_fmt helper
> >   v4l: vsp1: Document the vsp1_du_atomic_config structure
> >   v4l: vsp1: Extend the DU API to support CRC computation
> >   v4l: vsp1: Add support for the DISCOM entity
> >   v4l: vsp1: Integrate DISCOM in display pipeline
> >   drm: rcar-du: Add support for CRC computation
> > 
> >  drivers/gpu/drm/rcar-du/rcar_du_crtc.c    | 156 ++++++++++++++++-
> >  drivers/gpu/drm/rcar-du/rcar_du_crtc.h    |  19 +++
> >  drivers/gpu/drm/rcar-du/rcar_du_vsp.c     |  13 +-
> >  drivers/media/platform/vsp1/Makefile      |   2 +-
> >  drivers/media/platform/vsp1/vsp1.h        |  10 +-
> >  drivers/media/platform/vsp1/vsp1_brx.c    |   6 +-
> >  drivers/media/platform/vsp1/vsp1_brx.h    |   6 +-
> >  drivers/media/platform/vsp1/vsp1_clu.c    |  71 ++------
> >  drivers/media/platform/vsp1/vsp1_clu.h    |   6 +-
> >  drivers/media/platform/vsp1/vsp1_dl.c     |   8 +-
> >  drivers/media/platform/vsp1/vsp1_dl.h     |   6 +-
> >  drivers/media/platform/vsp1/vsp1_drm.c    | 127 ++++++++++++--
> >  drivers/media/platform/vsp1/vsp1_drm.h    |  20 ++-
> >  drivers/media/platform/vsp1/vsp1_drv.c    |  26 ++-
> >  drivers/media/platform/vsp1/vsp1_entity.c | 103 +++++++++++-
> >  drivers/media/platform/vsp1/vsp1_entity.h |  13 +-
> >  drivers/media/platform/vsp1/vsp1_hgo.c    |   6 +-
> >  drivers/media/platform/vsp1/vsp1_hgo.h    |   6 +-
> >  drivers/media/platform/vsp1/vsp1_hgt.c    |   6 +-
> >  drivers/media/platform/vsp1/vsp1_hgt.h    |   6 +-
> >  drivers/media/platform/vsp1/vsp1_histo.c  |  65 +------
> >  drivers/media/platform/vsp1/vsp1_histo.h  |   6 +-
> >  drivers/media/platform/vsp1/vsp1_hsit.c   |   6 +-
> >  drivers/media/platform/vsp1/vsp1_hsit.h   |   6 +-
> >  drivers/media/platform/vsp1/vsp1_lif.c    |  71 ++------
> >  drivers/media/platform/vsp1/vsp1_lif.h    |   6 +-
> >  drivers/media/platform/vsp1/vsp1_lut.c    |  71 ++------
> >  drivers/media/platform/vsp1/vsp1_lut.h    |   6 +-
> >  drivers/media/platform/vsp1/vsp1_pipe.c   |   6 +-
> >  drivers/media/platform/vsp1/vsp1_pipe.h   |   6 +-
> >  drivers/media/platform/vsp1/vsp1_regs.h   |  46 ++++-
> >  drivers/media/platform/vsp1/vsp1_rpf.c    |   6 +-
> >  drivers/media/platform/vsp1/vsp1_rwpf.c   |   6 +-
> >  drivers/media/platform/vsp1/vsp1_rwpf.h   |   6 +-
> >  drivers/media/platform/vsp1/vsp1_sru.c    |   6 +-
> >  drivers/media/platform/vsp1/vsp1_sru.h    |   6 +-
> >  drivers/media/platform/vsp1/vsp1_uds.c    |   6 +-
> >  drivers/media/platform/vsp1/vsp1_uds.h    |   6 +-
> >  drivers/media/platform/vsp1/vsp1_uif.c    | 271 +++++++++++++++++++++++++++
> >  drivers/media/platform/vsp1/vsp1_uif.h    |  32 ++++
> >  drivers/media/platform/vsp1/vsp1_video.c  |   6 +-
> >  drivers/media/platform/vsp1/vsp1_video.h  |   6 +-
> >  drivers/media/platform/vsp1/vsp1_wpf.c    |   6 +-
> >  include/media/vsp1.h                      |  39 ++++-
> >  44 files changed, 896 insertions(+), 417 deletions(-)
> >  create mode 100644 drivers/media/platform/vsp1/vsp1_uif.c
> >  create mode 100644 drivers/media/platform/vsp1/vsp1_uif.h
> 
> -- 
> Regards,
> 
> Laurent Pinchart
> 
> 
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

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

* Re: igt trouble with planes shared between multiple CRTCs (Re: [PATCH v2 0/8] R-Car DU: Support CRC calculation)
@ 2018-04-30 14:55     ` Daniel Vetter
  0 siblings, 0 replies; 82+ messages in thread
From: Daniel Vetter @ 2018-04-30 14:55 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: linux-renesas-soc, Ulrich Hecht, dri-devel, Kieran Bingham

On Sat, Apr 28, 2018 at 12:07:04AM +0300, Laurent Pinchart wrote:
> Hi Daniel,
> 
> (Removing the linux-media mailing list from CC as it is out of scope)
> 
> You enquired on IRC whether this patch series passes the igt CRC tests.
> 
> # ./kms_pipe_crc_basic --run-subtest read-crc-pipe-A
> IGT-Version: 1.22-gf447f5fc531d (aarch64) (Linux: 4.17.0-rc1-00085-g56e849d93cc9 aarch64)
> read-crc-pipe-A: Testing connector LVDS-1 using pipe A
> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Test assertion failure function igt_pipe_crc_start, file igt_debugfs.c:764:
> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Failed assertion: pipe_crc->crc_fd != -1
> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Last errno: 5, Input/output error
> Stack trace:
> Subtest read-crc-pipe-A failed.
> **** DEBUG ****
> (kms_pipe_crc_basic:1638) DEBUG: Test requirement passed: !(pipe >= data->display.n_pipes)
> (kms_pipe_crc_basic:1638) INFO: read-crc-pipe-A: Testing connector LVDS-1 using pipe A
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: LVDS-1: set_pipe(A)
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: LVDS-1: Selecting pipe A
> (kms_pipe_crc_basic:1638) DEBUG: Clearing the fb with color (0.00,1.00,0.00)
> (kms_pipe_crc_basic:1638) igt-fb-DEBUG: igt_create_fb_with_bo_size(width=1024, height=768, format=0x34325258, tiling=0x0, size=0)
> (kms_pipe_crc_basic:1638) igt-fb-DEBUG: igt_create_fb_with_bo_size(handle=1, pitch=4096)
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: Test requirement passed: plane_idx >= 0 && plane_idx < pipe->n_planes
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: plane_set_fb(140)
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: plane_set_size (1024x768)
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: fb_set_position(0,0)
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: fb_set_size(1024x768)
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: commit {
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     LVDS-1: SetCrtc pipe A, fb 140, src (0, 0), mode 1024x768
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe A, disabling
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 2, disabling
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 3, disabling
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 4, disabling
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe B, disabling
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 1, disabling
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 2, disabling
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 3, disabling
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 4, disabling
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe C, disabling
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 1, disabling
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 2, disabling
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 3, disabling
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 4, disabling
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe D, disabling
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe D, disabling
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 2, disabling
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 3, disabling
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 4, disabling
> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: }
> (kms_pipe_crc_basic:1638) igt-debugfs-DEBUG: Opening debugfs directory '/sys/kernel/debug/dri/0'
> (kms_pipe_crc_basic:1638) igt-debugfs-DEBUG: Opening debugfs directory '/sys/kernel/debug/dri/0'
> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Test assertion failure function igt_pipe_crc_start, file igt_debugfs.c:764:
> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Failed assertion: pipe_crc->crc_fd != -1
> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Last errno: 5, Input/output error
> (kms_pipe_crc_basic:1638) igt-core-INFO: Stack trace:
> ****  END  ****
> Subtest read-crc-pipe-A: FAIL (0.061s)
> 
> I think the answer is no, but I don't think it's the fault of this patch
> series. Opening the CRC data file returns -EIO because the CRTC is not active,
> and I'm trying to find out why that is the case. The debug log shows a commit
> that seems strange to me, enabling pipe A and immediately disabling right
> afterwards. After some investigation I believe that this is caused by sharing
> primary planes between CRTCs.
> 
> The R-Car DU groups CRTCs by two and shares 5 planes between the two CRTCs of
> the group. This specific SoC has two groups of two CRTCs, but that's not
> relevant here, so we can ignore pipes C and D.
> 
> Pipes A and B thus shared 5 planes that I will number 0 to 4 for simplicity.
> The driver sets plane 0 as the primary plane for CRTC A and plane 1 as the
> primary plane for CRTC B. Planes 2, 3 and 4 are created as overlay planes.
> 
> When igt iterates over all planes for pipe A, it will first encounter plane 0
> that has a framebuffer, and thus enables the pipe. It then iterates over
> plane 1, recognizes it as a primary plane without a framebuffer, and thus
> disables the pipe. Planes 2, 3 and 4 are recognized as overlay planes and thus
> don't affect the pipe active state. Pipe B is handled the same way, and igt
> disables it twice as planes 0 and 1 are primary.
> 
> I don't know if the fault here is with igt that doesn't properly support this
> architecture, or with the driver that shouldn't have two primary planes
> available for a CRTC. In the former case, I'm not sure how to fix it, as I'm
> not familiar enough with igt to rearchitecture the commit helpers. In the
> latter case, how would you recommend fixing it on the driver side ?

I guess thus far no one did run igt on a chip which did have reassignable
primary planes. The problem here is that it's pretty hard to figure out
which one is the real primary plane, since with possible CRTCs you could
have multiple primary planes on 1 CRTC. There's no property or anything
that explicitly tells you this. Two fixes:

1. Change drivers to limit primary planes to 1 crtc. Same for cursor
   overlays. There's probably other userspace than igt that gets confused
   by this, but this has the ugly downside that we artifically limit plane
   usage - if only 1 CRTC is on, we want to use all the available planes
   on that one.

2. Add some implicit or explicit uapi to allow userspace to figure out
   which primary plane is the primary plane for this crtc.

   a) Explicit option: We add a PRIMARY_ID property (and CURSOR_ID prop
      while at it) on the CRTC which points at the primary/cursor plane.

   b) Implicit option: We require primary planes are assigned to CRTC in the
      same order as they're created. So first primary plane you encouter
      is the one for the first CRTC, 2nd primary plane is the one for the
      2nd CRTC and so on. If we go with this we probably should add a bit
      of code to the kernel to check that invariant (by making sure the
      primary plane has the corresponding CRTC included in its
      possible_crtc mask).

Either way igt needs to be patched to not treat any primary plane that
could work on a CRTC as the primary plane for that CRTC.

Personally I'm leaning towards 2b).

Cheers, Daniel

> 
> On Monday, 23 April 2018 01:34:22 EEST Laurent Pinchart wrote:
> > Hello,
> > 
> > This patch series adds support for CRC calculation to the rcar-du-drm
> > driver.
> > 
> > CRC calculation is supported starting at the Renesas R-Car Gen3 SoCs, as
> > earlier versions don't have the necessary hardware. On Gen3 SoCs, the CRC is
> > computed by the DISCOM module part of the VSP-D and VSP-DL.
> > 
> > The DISCOM is interfaced to the VSP through the UIF glue and appears as a
> > VSP entity with a sink pad and a source pad.
> > 
> > The series starts with a switch to SPDX license headers in patch 1/8,
> > prompted by a checkpatch.pl warning for a later patch that complained about
> > missing SPDX license headers. It then continues with cleanup and
> > refactoring. Patches 2/8 and 3/8 prepare for DISCOM and UIF support by
> > extending generic code to make it usable for the UIF. Patch 4/8 documents a
> > structure that will receive new fields.
> > 
> > Patch 5/8 then extends the API exposed by the VSP driver to the DU driver to
> > support CRC computation configuration and reporting. The patch
> > unfortunately needs to touch both the VSP and DU drivers, so the whole
> > series will need to be merged through a single tree.
> > 
> > Patch 5/8 adds support for the DISCOM and UIF in the VSP driver, patch 7/8
> > integrates it in the DRM pipeline, and patch 8/8 finally implements the CRC
> > API in the DU driver to expose CRC computation to userspace.
> > 
> > The hardware supports computing the CRC at any arbitrary point in the
> > pipeline on a configurable window of the frame. This patch series supports
> > CRC computation on input planes or pipeline output, but on the full frame
> > only. Support for CRC window configuration can be added later if needed but
> > will require extending the userspace API, as the DRM/KMS CRC API doesn't
> > support this feature.
> > 
> > Compared to v1, the CRC source names for plane inputs are now constructed
> > from plane IDs instead of plane indices. This allows userspace to match CRC
> > sources with planes.
> > 
> > Note that exposing the DISCOM and UIF though the V4L2 API isn't supported as
> > the module is only found in VSP-D and VSP-DL instances that are not exposed
> > through V4L2. It is possible to expose those instances through V4L2 with a
> > small modification to the driver for testing purpose. If the need arises to
> > test DISCOM and UIF with such an out-of-tree patch, support for CRC
> > reporting through a V4L2 control can be added later without affecting how
> > CRC is exposed through the DRM/KMS API.
> > 
> > The patches are based on top of the "[PATCH v2 00/15] R-Car VSP1:
> > Dynamically assign blend units to display pipelines" patch series, itself
> > based on top of the Linux media master branch and scheduled for merge in
> > v4.18. The new base caused heavy conflicts, requiring this series to be
> > merged through the V4L2 tree. Once the patches receive the necessary review
> > I will ask Dave to ack the merge plan.
> > 
> > For convenience the patches are available at
> > 
> >         git://linuxtv.org/pinchartl/media.git vsp1-discom-v2-20180423
> > 
> > The code has been tested through the kms-test-crc.py script part of the DU
> > test suite available at
> > 
> >         git://git.ideasonboard.com/renesas/kms-tests.git discom
> > 
> > Laurent Pinchart (8):
> >   v4l: vsp1: Use SPDX license headers
> >   v4l: vsp1: Share the CLU, LIF and LUT set_fmt pad operation code
> >   v4l: vsp1: Reset the crop and compose rectangles in the set_fmt helper
> >   v4l: vsp1: Document the vsp1_du_atomic_config structure
> >   v4l: vsp1: Extend the DU API to support CRC computation
> >   v4l: vsp1: Add support for the DISCOM entity
> >   v4l: vsp1: Integrate DISCOM in display pipeline
> >   drm: rcar-du: Add support for CRC computation
> > 
> >  drivers/gpu/drm/rcar-du/rcar_du_crtc.c    | 156 ++++++++++++++++-
> >  drivers/gpu/drm/rcar-du/rcar_du_crtc.h    |  19 +++
> >  drivers/gpu/drm/rcar-du/rcar_du_vsp.c     |  13 +-
> >  drivers/media/platform/vsp1/Makefile      |   2 +-
> >  drivers/media/platform/vsp1/vsp1.h        |  10 +-
> >  drivers/media/platform/vsp1/vsp1_brx.c    |   6 +-
> >  drivers/media/platform/vsp1/vsp1_brx.h    |   6 +-
> >  drivers/media/platform/vsp1/vsp1_clu.c    |  71 ++------
> >  drivers/media/platform/vsp1/vsp1_clu.h    |   6 +-
> >  drivers/media/platform/vsp1/vsp1_dl.c     |   8 +-
> >  drivers/media/platform/vsp1/vsp1_dl.h     |   6 +-
> >  drivers/media/platform/vsp1/vsp1_drm.c    | 127 ++++++++++++--
> >  drivers/media/platform/vsp1/vsp1_drm.h    |  20 ++-
> >  drivers/media/platform/vsp1/vsp1_drv.c    |  26 ++-
> >  drivers/media/platform/vsp1/vsp1_entity.c | 103 +++++++++++-
> >  drivers/media/platform/vsp1/vsp1_entity.h |  13 +-
> >  drivers/media/platform/vsp1/vsp1_hgo.c    |   6 +-
> >  drivers/media/platform/vsp1/vsp1_hgo.h    |   6 +-
> >  drivers/media/platform/vsp1/vsp1_hgt.c    |   6 +-
> >  drivers/media/platform/vsp1/vsp1_hgt.h    |   6 +-
> >  drivers/media/platform/vsp1/vsp1_histo.c  |  65 +------
> >  drivers/media/platform/vsp1/vsp1_histo.h  |   6 +-
> >  drivers/media/platform/vsp1/vsp1_hsit.c   |   6 +-
> >  drivers/media/platform/vsp1/vsp1_hsit.h   |   6 +-
> >  drivers/media/platform/vsp1/vsp1_lif.c    |  71 ++------
> >  drivers/media/platform/vsp1/vsp1_lif.h    |   6 +-
> >  drivers/media/platform/vsp1/vsp1_lut.c    |  71 ++------
> >  drivers/media/platform/vsp1/vsp1_lut.h    |   6 +-
> >  drivers/media/platform/vsp1/vsp1_pipe.c   |   6 +-
> >  drivers/media/platform/vsp1/vsp1_pipe.h   |   6 +-
> >  drivers/media/platform/vsp1/vsp1_regs.h   |  46 ++++-
> >  drivers/media/platform/vsp1/vsp1_rpf.c    |   6 +-
> >  drivers/media/platform/vsp1/vsp1_rwpf.c   |   6 +-
> >  drivers/media/platform/vsp1/vsp1_rwpf.h   |   6 +-
> >  drivers/media/platform/vsp1/vsp1_sru.c    |   6 +-
> >  drivers/media/platform/vsp1/vsp1_sru.h    |   6 +-
> >  drivers/media/platform/vsp1/vsp1_uds.c    |   6 +-
> >  drivers/media/platform/vsp1/vsp1_uds.h    |   6 +-
> >  drivers/media/platform/vsp1/vsp1_uif.c    | 271 +++++++++++++++++++++++++++
> >  drivers/media/platform/vsp1/vsp1_uif.h    |  32 ++++
> >  drivers/media/platform/vsp1/vsp1_video.c  |   6 +-
> >  drivers/media/platform/vsp1/vsp1_video.h  |   6 +-
> >  drivers/media/platform/vsp1/vsp1_wpf.c    |   6 +-
> >  include/media/vsp1.h                      |  39 ++++-
> >  44 files changed, 896 insertions(+), 417 deletions(-)
> >  create mode 100644 drivers/media/platform/vsp1/vsp1_uif.c
> >  create mode 100644 drivers/media/platform/vsp1/vsp1_uif.h
> 
> -- 
> Regards,
> 
> Laurent Pinchart
> 
> 
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: igt trouble with planes shared between multiple CRTCs (Re: [PATCH v2 0/8] R-Car DU: Support CRC calculation)
  2018-04-30 14:55     ` Daniel Vetter
  (?)
@ 2018-04-30 14:56       ` Daniel Vetter
  -1 siblings, 0 replies; 82+ messages in thread
From: Daniel Vetter @ 2018-04-30 14:56 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Daniel Vetter, dri-devel, linux-renesas-soc, Kieran Bingham,
	Ulrich Hecht, Maarten Lankhorst, IGT development

On Mon, Apr 30, 2018 at 04:55:24PM +0200, Daniel Vetter wrote:
> On Sat, Apr 28, 2018 at 12:07:04AM +0300, Laurent Pinchart wrote:
> > Hi Daniel,
> > 
> > (Removing the linux-media mailing list from CC as it is out of scope)
> > 
> > You enquired on IRC whether this patch series passes the igt CRC tests.
> > 
> > # ./kms_pipe_crc_basic --run-subtest read-crc-pipe-A
> > IGT-Version: 1.22-gf447f5fc531d (aarch64) (Linux: 4.17.0-rc1-00085-g56e849d93cc9 aarch64)
> > read-crc-pipe-A: Testing connector LVDS-1 using pipe A
> > (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Test assertion failure function igt_pipe_crc_start, file igt_debugfs.c:764:
> > (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Failed assertion: pipe_crc->crc_fd != -1
> > (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Last errno: 5, Input/output error
> > Stack trace:
> > Subtest read-crc-pipe-A failed.
> > **** DEBUG ****
> > (kms_pipe_crc_basic:1638) DEBUG: Test requirement passed: !(pipe >= data->display.n_pipes)
> > (kms_pipe_crc_basic:1638) INFO: read-crc-pipe-A: Testing connector LVDS-1 using pipe A
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: LVDS-1: set_pipe(A)
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: LVDS-1: Selecting pipe A
> > (kms_pipe_crc_basic:1638) DEBUG: Clearing the fb with color (0.00,1.00,0.00)
> > (kms_pipe_crc_basic:1638) igt-fb-DEBUG: igt_create_fb_with_bo_size(width=1024, height=768, format=0x34325258, tiling=0x0, size=0)
> > (kms_pipe_crc_basic:1638) igt-fb-DEBUG: igt_create_fb_with_bo_size(handle=1, pitch=4096)
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: Test requirement passed: plane_idx >= 0 && plane_idx < pipe->n_planes
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: plane_set_fb(140)
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: plane_set_size (1024x768)
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: fb_set_position(0,0)
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: fb_set_size(1024x768)
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: commit {
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     LVDS-1: SetCrtc pipe A, fb 140, src (0, 0), mode 1024x768
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe A, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 2, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 3, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 4, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe B, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 1, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 2, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 3, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 4, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe C, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 1, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 2, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 3, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 4, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe D, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe D, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 2, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 3, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 4, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: }
> > (kms_pipe_crc_basic:1638) igt-debugfs-DEBUG: Opening debugfs directory '/sys/kernel/debug/dri/0'
> > (kms_pipe_crc_basic:1638) igt-debugfs-DEBUG: Opening debugfs directory '/sys/kernel/debug/dri/0'
> > (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Test assertion failure function igt_pipe_crc_start, file igt_debugfs.c:764:
> > (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Failed assertion: pipe_crc->crc_fd != -1
> > (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Last errno: 5, Input/output error
> > (kms_pipe_crc_basic:1638) igt-core-INFO: Stack trace:
> > ****  END  ****
> > Subtest read-crc-pipe-A: FAIL (0.061s)
> > 
> > I think the answer is no, but I don't think it's the fault of this patch
> > series. Opening the CRC data file returns -EIO because the CRTC is not active,
> > and I'm trying to find out why that is the case. The debug log shows a commit
> > that seems strange to me, enabling pipe A and immediately disabling right
> > afterwards. After some investigation I believe that this is caused by sharing
> > primary planes between CRTCs.
> > 
> > The R-Car DU groups CRTCs by two and shares 5 planes between the two CRTCs of
> > the group. This specific SoC has two groups of two CRTCs, but that's not
> > relevant here, so we can ignore pipes C and D.
> > 
> > Pipes A and B thus shared 5 planes that I will number 0 to 4 for simplicity.
> > The driver sets plane 0 as the primary plane for CRTC A and plane 1 as the
> > primary plane for CRTC B. Planes 2, 3 and 4 are created as overlay planes.
> > 
> > When igt iterates over all planes for pipe A, it will first encounter plane 0
> > that has a framebuffer, and thus enables the pipe. It then iterates over
> > plane 1, recognizes it as a primary plane without a framebuffer, and thus
> > disables the pipe. Planes 2, 3 and 4 are recognized as overlay planes and thus
> > don't affect the pipe active state. Pipe B is handled the same way, and igt
> > disables it twice as planes 0 and 1 are primary.
> > 
> > I don't know if the fault here is with igt that doesn't properly support this
> > architecture, or with the driver that shouldn't have two primary planes
> > available for a CRTC. In the former case, I'm not sure how to fix it, as I'm
> > not familiar enough with igt to rearchitecture the commit helpers. In the
> > latter case, how would you recommend fixing it on the driver side ?
> 
> I guess thus far no one did run igt on a chip which did have reassignable
> primary planes. The problem here is that it's pretty hard to figure out
> which one is the real primary plane, since with possible CRTCs you could
> have multiple primary planes on 1 CRTC. There's no property or anything
> that explicitly tells you this. Two fixes:
> 
> 1. Change drivers to limit primary planes to 1 crtc. Same for cursor
>    overlays. There's probably other userspace than igt that gets confused
>    by this, but this has the ugly downside that we artifically limit plane
>    usage - if only 1 CRTC is on, we want to use all the available planes
>    on that one.
> 
> 2. Add some implicit or explicit uapi to allow userspace to figure out
>    which primary plane is the primary plane for this crtc.
> 
>    a) Explicit option: We add a PRIMARY_ID property (and CURSOR_ID prop
>       while at it) on the CRTC which points at the primary/cursor plane.
> 
>    b) Implicit option: We require primary planes are assigned to CRTC in the
>       same order as they're created. So first primary plane you encouter
>       is the one for the first CRTC, 2nd primary plane is the one for the
>       2nd CRTC and so on. If we go with this we probably should add a bit
>       of code to the kernel to check that invariant (by making sure the
>       primary plane has the corresponding CRTC included in its
>       possible_crtc mask).
> 
> Either way igt needs to be patched to not treat any primary plane that
> could work on a CRTC as the primary plane for that CRTC.
> 
> Personally I'm leaning towards 2b).

Adding Maarten and igt-dev.
-Daniel

> 
> Cheers, Daniel
> 
> > 
> > On Monday, 23 April 2018 01:34:22 EEST Laurent Pinchart wrote:
> > > Hello,
> > > 
> > > This patch series adds support for CRC calculation to the rcar-du-drm
> > > driver.
> > > 
> > > CRC calculation is supported starting at the Renesas R-Car Gen3 SoCs, as
> > > earlier versions don't have the necessary hardware. On Gen3 SoCs, the CRC is
> > > computed by the DISCOM module part of the VSP-D and VSP-DL.
> > > 
> > > The DISCOM is interfaced to the VSP through the UIF glue and appears as a
> > > VSP entity with a sink pad and a source pad.
> > > 
> > > The series starts with a switch to SPDX license headers in patch 1/8,
> > > prompted by a checkpatch.pl warning for a later patch that complained about
> > > missing SPDX license headers. It then continues with cleanup and
> > > refactoring. Patches 2/8 and 3/8 prepare for DISCOM and UIF support by
> > > extending generic code to make it usable for the UIF. Patch 4/8 documents a
> > > structure that will receive new fields.
> > > 
> > > Patch 5/8 then extends the API exposed by the VSP driver to the DU driver to
> > > support CRC computation configuration and reporting. The patch
> > > unfortunately needs to touch both the VSP and DU drivers, so the whole
> > > series will need to be merged through a single tree.
> > > 
> > > Patch 5/8 adds support for the DISCOM and UIF in the VSP driver, patch 7/8
> > > integrates it in the DRM pipeline, and patch 8/8 finally implements the CRC
> > > API in the DU driver to expose CRC computation to userspace.
> > > 
> > > The hardware supports computing the CRC at any arbitrary point in the
> > > pipeline on a configurable window of the frame. This patch series supports
> > > CRC computation on input planes or pipeline output, but on the full frame
> > > only. Support for CRC window configuration can be added later if needed but
> > > will require extending the userspace API, as the DRM/KMS CRC API doesn't
> > > support this feature.
> > > 
> > > Compared to v1, the CRC source names for plane inputs are now constructed
> > > from plane IDs instead of plane indices. This allows userspace to match CRC
> > > sources with planes.
> > > 
> > > Note that exposing the DISCOM and UIF though the V4L2 API isn't supported as
> > > the module is only found in VSP-D and VSP-DL instances that are not exposed
> > > through V4L2. It is possible to expose those instances through V4L2 with a
> > > small modification to the driver for testing purpose. If the need arises to
> > > test DISCOM and UIF with such an out-of-tree patch, support for CRC
> > > reporting through a V4L2 control can be added later without affecting how
> > > CRC is exposed through the DRM/KMS API.
> > > 
> > > The patches are based on top of the "[PATCH v2 00/15] R-Car VSP1:
> > > Dynamically assign blend units to display pipelines" patch series, itself
> > > based on top of the Linux media master branch and scheduled for merge in
> > > v4.18. The new base caused heavy conflicts, requiring this series to be
> > > merged through the V4L2 tree. Once the patches receive the necessary review
> > > I will ask Dave to ack the merge plan.
> > > 
> > > For convenience the patches are available at
> > > 
> > >         git://linuxtv.org/pinchartl/media.git vsp1-discom-v2-20180423
> > > 
> > > The code has been tested through the kms-test-crc.py script part of the DU
> > > test suite available at
> > > 
> > >         git://git.ideasonboard.com/renesas/kms-tests.git discom
> > > 
> > > Laurent Pinchart (8):
> > >   v4l: vsp1: Use SPDX license headers
> > >   v4l: vsp1: Share the CLU, LIF and LUT set_fmt pad operation code
> > >   v4l: vsp1: Reset the crop and compose rectangles in the set_fmt helper
> > >   v4l: vsp1: Document the vsp1_du_atomic_config structure
> > >   v4l: vsp1: Extend the DU API to support CRC computation
> > >   v4l: vsp1: Add support for the DISCOM entity
> > >   v4l: vsp1: Integrate DISCOM in display pipeline
> > >   drm: rcar-du: Add support for CRC computation
> > > 
> > >  drivers/gpu/drm/rcar-du/rcar_du_crtc.c    | 156 ++++++++++++++++-
> > >  drivers/gpu/drm/rcar-du/rcar_du_crtc.h    |  19 +++
> > >  drivers/gpu/drm/rcar-du/rcar_du_vsp.c     |  13 +-
> > >  drivers/media/platform/vsp1/Makefile      |   2 +-
> > >  drivers/media/platform/vsp1/vsp1.h        |  10 +-
> > >  drivers/media/platform/vsp1/vsp1_brx.c    |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_brx.h    |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_clu.c    |  71 ++------
> > >  drivers/media/platform/vsp1/vsp1_clu.h    |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_dl.c     |   8 +-
> > >  drivers/media/platform/vsp1/vsp1_dl.h     |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_drm.c    | 127 ++++++++++++--
> > >  drivers/media/platform/vsp1/vsp1_drm.h    |  20 ++-
> > >  drivers/media/platform/vsp1/vsp1_drv.c    |  26 ++-
> > >  drivers/media/platform/vsp1/vsp1_entity.c | 103 +++++++++++-
> > >  drivers/media/platform/vsp1/vsp1_entity.h |  13 +-
> > >  drivers/media/platform/vsp1/vsp1_hgo.c    |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_hgo.h    |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_hgt.c    |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_hgt.h    |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_histo.c  |  65 +------
> > >  drivers/media/platform/vsp1/vsp1_histo.h  |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_hsit.c   |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_hsit.h   |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_lif.c    |  71 ++------
> > >  drivers/media/platform/vsp1/vsp1_lif.h    |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_lut.c    |  71 ++------
> > >  drivers/media/platform/vsp1/vsp1_lut.h    |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_pipe.c   |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_pipe.h   |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_regs.h   |  46 ++++-
> > >  drivers/media/platform/vsp1/vsp1_rpf.c    |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_rwpf.c   |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_rwpf.h   |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_sru.c    |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_sru.h    |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_uds.c    |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_uds.h    |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_uif.c    | 271 +++++++++++++++++++++++++++
> > >  drivers/media/platform/vsp1/vsp1_uif.h    |  32 ++++
> > >  drivers/media/platform/vsp1/vsp1_video.c  |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_video.h  |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_wpf.c    |   6 +-
> > >  include/media/vsp1.h                      |  39 ++++-
> > >  44 files changed, 896 insertions(+), 417 deletions(-)
> > >  create mode 100644 drivers/media/platform/vsp1/vsp1_uif.c
> > >  create mode 100644 drivers/media/platform/vsp1/vsp1_uif.h
> > 
> > -- 
> > Regards,
> > 
> > Laurent Pinchart
> > 
> > 
> > 
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

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

* Re: igt trouble with planes shared between multiple CRTCs (Re: [PATCH v2 0/8] R-Car DU: Support CRC calculation)
@ 2018-04-30 14:56       ` Daniel Vetter
  0 siblings, 0 replies; 82+ messages in thread
From: Daniel Vetter @ 2018-04-30 14:56 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: IGT development, Kieran Bingham, dri-devel, linux-renesas-soc,
	Ulrich Hecht

On Mon, Apr 30, 2018 at 04:55:24PM +0200, Daniel Vetter wrote:
> On Sat, Apr 28, 2018 at 12:07:04AM +0300, Laurent Pinchart wrote:
> > Hi Daniel,
> > 
> > (Removing the linux-media mailing list from CC as it is out of scope)
> > 
> > You enquired on IRC whether this patch series passes the igt CRC tests.
> > 
> > # ./kms_pipe_crc_basic --run-subtest read-crc-pipe-A
> > IGT-Version: 1.22-gf447f5fc531d (aarch64) (Linux: 4.17.0-rc1-00085-g56e849d93cc9 aarch64)
> > read-crc-pipe-A: Testing connector LVDS-1 using pipe A
> > (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Test assertion failure function igt_pipe_crc_start, file igt_debugfs.c:764:
> > (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Failed assertion: pipe_crc->crc_fd != -1
> > (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Last errno: 5, Input/output error
> > Stack trace:
> > Subtest read-crc-pipe-A failed.
> > **** DEBUG ****
> > (kms_pipe_crc_basic:1638) DEBUG: Test requirement passed: !(pipe >= data->display.n_pipes)
> > (kms_pipe_crc_basic:1638) INFO: read-crc-pipe-A: Testing connector LVDS-1 using pipe A
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: LVDS-1: set_pipe(A)
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: LVDS-1: Selecting pipe A
> > (kms_pipe_crc_basic:1638) DEBUG: Clearing the fb with color (0.00,1.00,0.00)
> > (kms_pipe_crc_basic:1638) igt-fb-DEBUG: igt_create_fb_with_bo_size(width=1024, height=768, format=0x34325258, tiling=0x0, size=0)
> > (kms_pipe_crc_basic:1638) igt-fb-DEBUG: igt_create_fb_with_bo_size(handle=1, pitch=4096)
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: Test requirement passed: plane_idx >= 0 && plane_idx < pipe->n_planes
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: plane_set_fb(140)
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: plane_set_size (1024x768)
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: fb_set_position(0,0)
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: fb_set_size(1024x768)
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: commit {
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     LVDS-1: SetCrtc pipe A, fb 140, src (0, 0), mode 1024x768
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe A, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 2, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 3, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 4, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe B, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 1, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 2, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 3, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 4, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe C, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 1, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 2, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 3, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 4, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe D, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe D, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 2, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 3, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 4, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: }
> > (kms_pipe_crc_basic:1638) igt-debugfs-DEBUG: Opening debugfs directory '/sys/kernel/debug/dri/0'
> > (kms_pipe_crc_basic:1638) igt-debugfs-DEBUG: Opening debugfs directory '/sys/kernel/debug/dri/0'
> > (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Test assertion failure function igt_pipe_crc_start, file igt_debugfs.c:764:
> > (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Failed assertion: pipe_crc->crc_fd != -1
> > (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Last errno: 5, Input/output error
> > (kms_pipe_crc_basic:1638) igt-core-INFO: Stack trace:
> > ****  END  ****
> > Subtest read-crc-pipe-A: FAIL (0.061s)
> > 
> > I think the answer is no, but I don't think it's the fault of this patch
> > series. Opening the CRC data file returns -EIO because the CRTC is not active,
> > and I'm trying to find out why that is the case. The debug log shows a commit
> > that seems strange to me, enabling pipe A and immediately disabling right
> > afterwards. After some investigation I believe that this is caused by sharing
> > primary planes between CRTCs.
> > 
> > The R-Car DU groups CRTCs by two and shares 5 planes between the two CRTCs of
> > the group. This specific SoC has two groups of two CRTCs, but that's not
> > relevant here, so we can ignore pipes C and D.
> > 
> > Pipes A and B thus shared 5 planes that I will number 0 to 4 for simplicity.
> > The driver sets plane 0 as the primary plane for CRTC A and plane 1 as the
> > primary plane for CRTC B. Planes 2, 3 and 4 are created as overlay planes.
> > 
> > When igt iterates over all planes for pipe A, it will first encounter plane 0
> > that has a framebuffer, and thus enables the pipe. It then iterates over
> > plane 1, recognizes it as a primary plane without a framebuffer, and thus
> > disables the pipe. Planes 2, 3 and 4 are recognized as overlay planes and thus
> > don't affect the pipe active state. Pipe B is handled the same way, and igt
> > disables it twice as planes 0 and 1 are primary.
> > 
> > I don't know if the fault here is with igt that doesn't properly support this
> > architecture, or with the driver that shouldn't have two primary planes
> > available for a CRTC. In the former case, I'm not sure how to fix it, as I'm
> > not familiar enough with igt to rearchitecture the commit helpers. In the
> > latter case, how would you recommend fixing it on the driver side ?
> 
> I guess thus far no one did run igt on a chip which did have reassignable
> primary planes. The problem here is that it's pretty hard to figure out
> which one is the real primary plane, since with possible CRTCs you could
> have multiple primary planes on 1 CRTC. There's no property or anything
> that explicitly tells you this. Two fixes:
> 
> 1. Change drivers to limit primary planes to 1 crtc. Same for cursor
>    overlays. There's probably other userspace than igt that gets confused
>    by this, but this has the ugly downside that we artifically limit plane
>    usage - if only 1 CRTC is on, we want to use all the available planes
>    on that one.
> 
> 2. Add some implicit or explicit uapi to allow userspace to figure out
>    which primary plane is the primary plane for this crtc.
> 
>    a) Explicit option: We add a PRIMARY_ID property (and CURSOR_ID prop
>       while at it) on the CRTC which points at the primary/cursor plane.
> 
>    b) Implicit option: We require primary planes are assigned to CRTC in the
>       same order as they're created. So first primary plane you encouter
>       is the one for the first CRTC, 2nd primary plane is the one for the
>       2nd CRTC and so on. If we go with this we probably should add a bit
>       of code to the kernel to check that invariant (by making sure the
>       primary plane has the corresponding CRTC included in its
>       possible_crtc mask).
> 
> Either way igt needs to be patched to not treat any primary plane that
> could work on a CRTC as the primary plane for that CRTC.
> 
> Personally I'm leaning towards 2b).

Adding Maarten and igt-dev.
-Daniel

> 
> Cheers, Daniel
> 
> > 
> > On Monday, 23 April 2018 01:34:22 EEST Laurent Pinchart wrote:
> > > Hello,
> > > 
> > > This patch series adds support for CRC calculation to the rcar-du-drm
> > > driver.
> > > 
> > > CRC calculation is supported starting at the Renesas R-Car Gen3 SoCs, as
> > > earlier versions don't have the necessary hardware. On Gen3 SoCs, the CRC is
> > > computed by the DISCOM module part of the VSP-D and VSP-DL.
> > > 
> > > The DISCOM is interfaced to the VSP through the UIF glue and appears as a
> > > VSP entity with a sink pad and a source pad.
> > > 
> > > The series starts with a switch to SPDX license headers in patch 1/8,
> > > prompted by a checkpatch.pl warning for a later patch that complained about
> > > missing SPDX license headers. It then continues with cleanup and
> > > refactoring. Patches 2/8 and 3/8 prepare for DISCOM and UIF support by
> > > extending generic code to make it usable for the UIF. Patch 4/8 documents a
> > > structure that will receive new fields.
> > > 
> > > Patch 5/8 then extends the API exposed by the VSP driver to the DU driver to
> > > support CRC computation configuration and reporting. The patch
> > > unfortunately needs to touch both the VSP and DU drivers, so the whole
> > > series will need to be merged through a single tree.
> > > 
> > > Patch 5/8 adds support for the DISCOM and UIF in the VSP driver, patch 7/8
> > > integrates it in the DRM pipeline, and patch 8/8 finally implements the CRC
> > > API in the DU driver to expose CRC computation to userspace.
> > > 
> > > The hardware supports computing the CRC at any arbitrary point in the
> > > pipeline on a configurable window of the frame. This patch series supports
> > > CRC computation on input planes or pipeline output, but on the full frame
> > > only. Support for CRC window configuration can be added later if needed but
> > > will require extending the userspace API, as the DRM/KMS CRC API doesn't
> > > support this feature.
> > > 
> > > Compared to v1, the CRC source names for plane inputs are now constructed
> > > from plane IDs instead of plane indices. This allows userspace to match CRC
> > > sources with planes.
> > > 
> > > Note that exposing the DISCOM and UIF though the V4L2 API isn't supported as
> > > the module is only found in VSP-D and VSP-DL instances that are not exposed
> > > through V4L2. It is possible to expose those instances through V4L2 with a
> > > small modification to the driver for testing purpose. If the need arises to
> > > test DISCOM and UIF with such an out-of-tree patch, support for CRC
> > > reporting through a V4L2 control can be added later without affecting how
> > > CRC is exposed through the DRM/KMS API.
> > > 
> > > The patches are based on top of the "[PATCH v2 00/15] R-Car VSP1:
> > > Dynamically assign blend units to display pipelines" patch series, itself
> > > based on top of the Linux media master branch and scheduled for merge in
> > > v4.18. The new base caused heavy conflicts, requiring this series to be
> > > merged through the V4L2 tree. Once the patches receive the necessary review
> > > I will ask Dave to ack the merge plan.
> > > 
> > > For convenience the patches are available at
> > > 
> > >         git://linuxtv.org/pinchartl/media.git vsp1-discom-v2-20180423
> > > 
> > > The code has been tested through the kms-test-crc.py script part of the DU
> > > test suite available at
> > > 
> > >         git://git.ideasonboard.com/renesas/kms-tests.git discom
> > > 
> > > Laurent Pinchart (8):
> > >   v4l: vsp1: Use SPDX license headers
> > >   v4l: vsp1: Share the CLU, LIF and LUT set_fmt pad operation code
> > >   v4l: vsp1: Reset the crop and compose rectangles in the set_fmt helper
> > >   v4l: vsp1: Document the vsp1_du_atomic_config structure
> > >   v4l: vsp1: Extend the DU API to support CRC computation
> > >   v4l: vsp1: Add support for the DISCOM entity
> > >   v4l: vsp1: Integrate DISCOM in display pipeline
> > >   drm: rcar-du: Add support for CRC computation
> > > 
> > >  drivers/gpu/drm/rcar-du/rcar_du_crtc.c    | 156 ++++++++++++++++-
> > >  drivers/gpu/drm/rcar-du/rcar_du_crtc.h    |  19 +++
> > >  drivers/gpu/drm/rcar-du/rcar_du_vsp.c     |  13 +-
> > >  drivers/media/platform/vsp1/Makefile      |   2 +-
> > >  drivers/media/platform/vsp1/vsp1.h        |  10 +-
> > >  drivers/media/platform/vsp1/vsp1_brx.c    |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_brx.h    |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_clu.c    |  71 ++------
> > >  drivers/media/platform/vsp1/vsp1_clu.h    |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_dl.c     |   8 +-
> > >  drivers/media/platform/vsp1/vsp1_dl.h     |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_drm.c    | 127 ++++++++++++--
> > >  drivers/media/platform/vsp1/vsp1_drm.h    |  20 ++-
> > >  drivers/media/platform/vsp1/vsp1_drv.c    |  26 ++-
> > >  drivers/media/platform/vsp1/vsp1_entity.c | 103 +++++++++++-
> > >  drivers/media/platform/vsp1/vsp1_entity.h |  13 +-
> > >  drivers/media/platform/vsp1/vsp1_hgo.c    |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_hgo.h    |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_hgt.c    |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_hgt.h    |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_histo.c  |  65 +------
> > >  drivers/media/platform/vsp1/vsp1_histo.h  |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_hsit.c   |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_hsit.h   |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_lif.c    |  71 ++------
> > >  drivers/media/platform/vsp1/vsp1_lif.h    |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_lut.c    |  71 ++------
> > >  drivers/media/platform/vsp1/vsp1_lut.h    |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_pipe.c   |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_pipe.h   |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_regs.h   |  46 ++++-
> > >  drivers/media/platform/vsp1/vsp1_rpf.c    |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_rwpf.c   |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_rwpf.h   |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_sru.c    |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_sru.h    |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_uds.c    |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_uds.h    |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_uif.c    | 271 +++++++++++++++++++++++++++
> > >  drivers/media/platform/vsp1/vsp1_uif.h    |  32 ++++
> > >  drivers/media/platform/vsp1/vsp1_video.c  |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_video.h  |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_wpf.c    |   6 +-
> > >  include/media/vsp1.h                      |  39 ++++-
> > >  44 files changed, 896 insertions(+), 417 deletions(-)
> > >  create mode 100644 drivers/media/platform/vsp1/vsp1_uif.c
> > >  create mode 100644 drivers/media/platform/vsp1/vsp1_uif.h
> > 
> > -- 
> > Regards,
> > 
> > Laurent Pinchart
> > 
> > 
> > 
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [igt-dev] igt trouble with planes shared between multiple CRTCs (Re: [PATCH v2 0/8] R-Car DU: Support CRC calculation)
@ 2018-04-30 14:56       ` Daniel Vetter
  0 siblings, 0 replies; 82+ messages in thread
From: Daniel Vetter @ 2018-04-30 14:56 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: IGT development, Daniel Vetter, Kieran Bingham, dri-devel,
	linux-renesas-soc

On Mon, Apr 30, 2018 at 04:55:24PM +0200, Daniel Vetter wrote:
> On Sat, Apr 28, 2018 at 12:07:04AM +0300, Laurent Pinchart wrote:
> > Hi Daniel,
> > 
> > (Removing the linux-media mailing list from CC as it is out of scope)
> > 
> > You enquired on IRC whether this patch series passes the igt CRC tests.
> > 
> > # ./kms_pipe_crc_basic --run-subtest read-crc-pipe-A
> > IGT-Version: 1.22-gf447f5fc531d (aarch64) (Linux: 4.17.0-rc1-00085-g56e849d93cc9 aarch64)
> > read-crc-pipe-A: Testing connector LVDS-1 using pipe A
> > (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Test assertion failure function igt_pipe_crc_start, file igt_debugfs.c:764:
> > (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Failed assertion: pipe_crc->crc_fd != -1
> > (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Last errno: 5, Input/output error
> > Stack trace:
> > Subtest read-crc-pipe-A failed.
> > **** DEBUG ****
> > (kms_pipe_crc_basic:1638) DEBUG: Test requirement passed: !(pipe >= data->display.n_pipes)
> > (kms_pipe_crc_basic:1638) INFO: read-crc-pipe-A: Testing connector LVDS-1 using pipe A
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: LVDS-1: set_pipe(A)
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: LVDS-1: Selecting pipe A
> > (kms_pipe_crc_basic:1638) DEBUG: Clearing the fb with color (0.00,1.00,0.00)
> > (kms_pipe_crc_basic:1638) igt-fb-DEBUG: igt_create_fb_with_bo_size(width=1024, height=768, format=0x34325258, tiling=0x0, size=0)
> > (kms_pipe_crc_basic:1638) igt-fb-DEBUG: igt_create_fb_with_bo_size(handle=1, pitch=4096)
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: Test requirement passed: plane_idx >= 0 && plane_idx < pipe->n_planes
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: plane_set_fb(140)
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: plane_set_size (1024x768)
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: fb_set_position(0,0)
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: fb_set_size(1024x768)
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: commit {
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     LVDS-1: SetCrtc pipe A, fb 140, src (0, 0), mode 1024x768
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe A, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 2, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 3, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 4, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe B, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 1, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 2, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 3, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 4, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe C, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 1, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 2, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 3, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 4, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe D, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe D, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 2, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 3, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 4, disabling
> > (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: }
> > (kms_pipe_crc_basic:1638) igt-debugfs-DEBUG: Opening debugfs directory '/sys/kernel/debug/dri/0'
> > (kms_pipe_crc_basic:1638) igt-debugfs-DEBUG: Opening debugfs directory '/sys/kernel/debug/dri/0'
> > (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Test assertion failure function igt_pipe_crc_start, file igt_debugfs.c:764:
> > (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Failed assertion: pipe_crc->crc_fd != -1
> > (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Last errno: 5, Input/output error
> > (kms_pipe_crc_basic:1638) igt-core-INFO: Stack trace:
> > ****  END  ****
> > Subtest read-crc-pipe-A: FAIL (0.061s)
> > 
> > I think the answer is no, but I don't think it's the fault of this patch
> > series. Opening the CRC data file returns -EIO because the CRTC is not active,
> > and I'm trying to find out why that is the case. The debug log shows a commit
> > that seems strange to me, enabling pipe A and immediately disabling right
> > afterwards. After some investigation I believe that this is caused by sharing
> > primary planes between CRTCs.
> > 
> > The R-Car DU groups CRTCs by two and shares 5 planes between the two CRTCs of
> > the group. This specific SoC has two groups of two CRTCs, but that's not
> > relevant here, so we can ignore pipes C and D.
> > 
> > Pipes A and B thus shared 5 planes that I will number 0 to 4 for simplicity.
> > The driver sets plane 0 as the primary plane for CRTC A and plane 1 as the
> > primary plane for CRTC B. Planes 2, 3 and 4 are created as overlay planes.
> > 
> > When igt iterates over all planes for pipe A, it will first encounter plane 0
> > that has a framebuffer, and thus enables the pipe. It then iterates over
> > plane 1, recognizes it as a primary plane without a framebuffer, and thus
> > disables the pipe. Planes 2, 3 and 4 are recognized as overlay planes and thus
> > don't affect the pipe active state. Pipe B is handled the same way, and igt
> > disables it twice as planes 0 and 1 are primary.
> > 
> > I don't know if the fault here is with igt that doesn't properly support this
> > architecture, or with the driver that shouldn't have two primary planes
> > available for a CRTC. In the former case, I'm not sure how to fix it, as I'm
> > not familiar enough with igt to rearchitecture the commit helpers. In the
> > latter case, how would you recommend fixing it on the driver side ?
> 
> I guess thus far no one did run igt on a chip which did have reassignable
> primary planes. The problem here is that it's pretty hard to figure out
> which one is the real primary plane, since with possible CRTCs you could
> have multiple primary planes on 1 CRTC. There's no property or anything
> that explicitly tells you this. Two fixes:
> 
> 1. Change drivers to limit primary planes to 1 crtc. Same for cursor
>    overlays. There's probably other userspace than igt that gets confused
>    by this, but this has the ugly downside that we artifically limit plane
>    usage - if only 1 CRTC is on, we want to use all the available planes
>    on that one.
> 
> 2. Add some implicit or explicit uapi to allow userspace to figure out
>    which primary plane is the primary plane for this crtc.
> 
>    a) Explicit option: We add a PRIMARY_ID property (and CURSOR_ID prop
>       while at it) on the CRTC which points at the primary/cursor plane.
> 
>    b) Implicit option: We require primary planes are assigned to CRTC in the
>       same order as they're created. So first primary plane you encouter
>       is the one for the first CRTC, 2nd primary plane is the one for the
>       2nd CRTC and so on. If we go with this we probably should add a bit
>       of code to the kernel to check that invariant (by making sure the
>       primary plane has the corresponding CRTC included in its
>       possible_crtc mask).
> 
> Either way igt needs to be patched to not treat any primary plane that
> could work on a CRTC as the primary plane for that CRTC.
> 
> Personally I'm leaning towards 2b).

Adding Maarten and igt-dev.
-Daniel

> 
> Cheers, Daniel
> 
> > 
> > On Monday, 23 April 2018 01:34:22 EEST Laurent Pinchart wrote:
> > > Hello,
> > > 
> > > This patch series adds support for CRC calculation to the rcar-du-drm
> > > driver.
> > > 
> > > CRC calculation is supported starting at the Renesas R-Car Gen3 SoCs, as
> > > earlier versions don't have the necessary hardware. On Gen3 SoCs, the CRC is
> > > computed by the DISCOM module part of the VSP-D and VSP-DL.
> > > 
> > > The DISCOM is interfaced to the VSP through the UIF glue and appears as a
> > > VSP entity with a sink pad and a source pad.
> > > 
> > > The series starts with a switch to SPDX license headers in patch 1/8,
> > > prompted by a checkpatch.pl warning for a later patch that complained about
> > > missing SPDX license headers. It then continues with cleanup and
> > > refactoring. Patches 2/8 and 3/8 prepare for DISCOM and UIF support by
> > > extending generic code to make it usable for the UIF. Patch 4/8 documents a
> > > structure that will receive new fields.
> > > 
> > > Patch 5/8 then extends the API exposed by the VSP driver to the DU driver to
> > > support CRC computation configuration and reporting. The patch
> > > unfortunately needs to touch both the VSP and DU drivers, so the whole
> > > series will need to be merged through a single tree.
> > > 
> > > Patch 5/8 adds support for the DISCOM and UIF in the VSP driver, patch 7/8
> > > integrates it in the DRM pipeline, and patch 8/8 finally implements the CRC
> > > API in the DU driver to expose CRC computation to userspace.
> > > 
> > > The hardware supports computing the CRC at any arbitrary point in the
> > > pipeline on a configurable window of the frame. This patch series supports
> > > CRC computation on input planes or pipeline output, but on the full frame
> > > only. Support for CRC window configuration can be added later if needed but
> > > will require extending the userspace API, as the DRM/KMS CRC API doesn't
> > > support this feature.
> > > 
> > > Compared to v1, the CRC source names for plane inputs are now constructed
> > > from plane IDs instead of plane indices. This allows userspace to match CRC
> > > sources with planes.
> > > 
> > > Note that exposing the DISCOM and UIF though the V4L2 API isn't supported as
> > > the module is only found in VSP-D and VSP-DL instances that are not exposed
> > > through V4L2. It is possible to expose those instances through V4L2 with a
> > > small modification to the driver for testing purpose. If the need arises to
> > > test DISCOM and UIF with such an out-of-tree patch, support for CRC
> > > reporting through a V4L2 control can be added later without affecting how
> > > CRC is exposed through the DRM/KMS API.
> > > 
> > > The patches are based on top of the "[PATCH v2 00/15] R-Car VSP1:
> > > Dynamically assign blend units to display pipelines" patch series, itself
> > > based on top of the Linux media master branch and scheduled for merge in
> > > v4.18. The new base caused heavy conflicts, requiring this series to be
> > > merged through the V4L2 tree. Once the patches receive the necessary review
> > > I will ask Dave to ack the merge plan.
> > > 
> > > For convenience the patches are available at
> > > 
> > >         git://linuxtv.org/pinchartl/media.git vsp1-discom-v2-20180423
> > > 
> > > The code has been tested through the kms-test-crc.py script part of the DU
> > > test suite available at
> > > 
> > >         git://git.ideasonboard.com/renesas/kms-tests.git discom
> > > 
> > > Laurent Pinchart (8):
> > >   v4l: vsp1: Use SPDX license headers
> > >   v4l: vsp1: Share the CLU, LIF and LUT set_fmt pad operation code
> > >   v4l: vsp1: Reset the crop and compose rectangles in the set_fmt helper
> > >   v4l: vsp1: Document the vsp1_du_atomic_config structure
> > >   v4l: vsp1: Extend the DU API to support CRC computation
> > >   v4l: vsp1: Add support for the DISCOM entity
> > >   v4l: vsp1: Integrate DISCOM in display pipeline
> > >   drm: rcar-du: Add support for CRC computation
> > > 
> > >  drivers/gpu/drm/rcar-du/rcar_du_crtc.c    | 156 ++++++++++++++++-
> > >  drivers/gpu/drm/rcar-du/rcar_du_crtc.h    |  19 +++
> > >  drivers/gpu/drm/rcar-du/rcar_du_vsp.c     |  13 +-
> > >  drivers/media/platform/vsp1/Makefile      |   2 +-
> > >  drivers/media/platform/vsp1/vsp1.h        |  10 +-
> > >  drivers/media/platform/vsp1/vsp1_brx.c    |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_brx.h    |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_clu.c    |  71 ++------
> > >  drivers/media/platform/vsp1/vsp1_clu.h    |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_dl.c     |   8 +-
> > >  drivers/media/platform/vsp1/vsp1_dl.h     |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_drm.c    | 127 ++++++++++++--
> > >  drivers/media/platform/vsp1/vsp1_drm.h    |  20 ++-
> > >  drivers/media/platform/vsp1/vsp1_drv.c    |  26 ++-
> > >  drivers/media/platform/vsp1/vsp1_entity.c | 103 +++++++++++-
> > >  drivers/media/platform/vsp1/vsp1_entity.h |  13 +-
> > >  drivers/media/platform/vsp1/vsp1_hgo.c    |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_hgo.h    |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_hgt.c    |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_hgt.h    |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_histo.c  |  65 +------
> > >  drivers/media/platform/vsp1/vsp1_histo.h  |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_hsit.c   |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_hsit.h   |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_lif.c    |  71 ++------
> > >  drivers/media/platform/vsp1/vsp1_lif.h    |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_lut.c    |  71 ++------
> > >  drivers/media/platform/vsp1/vsp1_lut.h    |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_pipe.c   |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_pipe.h   |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_regs.h   |  46 ++++-
> > >  drivers/media/platform/vsp1/vsp1_rpf.c    |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_rwpf.c   |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_rwpf.h   |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_sru.c    |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_sru.h    |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_uds.c    |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_uds.h    |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_uif.c    | 271 +++++++++++++++++++++++++++
> > >  drivers/media/platform/vsp1/vsp1_uif.h    |  32 ++++
> > >  drivers/media/platform/vsp1/vsp1_video.c  |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_video.h  |   6 +-
> > >  drivers/media/platform/vsp1/vsp1_wpf.c    |   6 +-
> > >  include/media/vsp1.h                      |  39 ++++-
> > >  44 files changed, 896 insertions(+), 417 deletions(-)
> > >  create mode 100644 drivers/media/platform/vsp1/vsp1_uif.c
> > >  create mode 100644 drivers/media/platform/vsp1/vsp1_uif.h
> > 
> > -- 
> > Regards,
> > 
> > Laurent Pinchart
> > 
> > 
> > 
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

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

* Re: igt trouble with planes shared between multiple CRTCs (Re: [PATCH v2 0/8] R-Car DU: Support CRC calculation)
  2018-04-30 14:56       ` Daniel Vetter
  (?)
@ 2018-05-01  8:58         ` Maarten Lankhorst
  -1 siblings, 0 replies; 82+ messages in thread
From: Maarten Lankhorst @ 2018-05-01  8:58 UTC (permalink / raw)
  To: Daniel Vetter, Laurent Pinchart
  Cc: dri-devel, linux-renesas-soc, Kieran Bingham, Ulrich Hecht,
	IGT development

Hey,

Op 30-04-18 om 16:56 schreef Daniel Vetter:
> On Mon, Apr 30, 2018 at 04:55:24PM +0200, Daniel Vetter wrote:
>> On Sat, Apr 28, 2018 at 12:07:04AM +0300, Laurent Pinchart wrote:
>>> Hi Daniel,
>>>
>>> (Removing the linux-media mailing list from CC as it is out of scope)
>>>
>>> You enquired on IRC whether this patch series passes the igt CRC tests.
>>>
>>> # ./kms_pipe_crc_basic --run-subtest read-crc-pipe-A
>>> IGT-Version: 1.22-gf447f5fc531d (aarch64) (Linux: 4.17.0-rc1-00085-g56e849d93cc9 aarch64)
>>> read-crc-pipe-A: Testing connector LVDS-1 using pipe A
>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Test assertion failure function igt_pipe_crc_start, file igt_debugfs.c:764:
>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Failed assertion: pipe_crc->crc_fd != -1
>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Last errno: 5, Input/output error
>>> Stack trace:
>>> Subtest read-crc-pipe-A failed.
>>> **** DEBUG ****
>>> (kms_pipe_crc_basic:1638) DEBUG: Test requirement passed: !(pipe >= data->display.n_pipes)
>>> (kms_pipe_crc_basic:1638) INFO: read-crc-pipe-A: Testing connector LVDS-1 using pipe A
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: LVDS-1: set_pipe(A)
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: LVDS-1: Selecting pipe A
>>> (kms_pipe_crc_basic:1638) DEBUG: Clearing the fb with color (0.00,1.00,0.00)
>>> (kms_pipe_crc_basic:1638) igt-fb-DEBUG: igt_create_fb_with_bo_size(width=1024, height=768, format=0x34325258, tiling=0x0, size=0)
>>> (kms_pipe_crc_basic:1638) igt-fb-DEBUG: igt_create_fb_with_bo_size(handle=1, pitch=4096)
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: Test requirement passed: plane_idx >= 0 && plane_idx < pipe->n_planes
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: plane_set_fb(140)
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: plane_set_size (1024x768)
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: fb_set_position(0,0)
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: fb_set_size(1024x768)
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: commit {
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     LVDS-1: SetCrtc pipe A, fb 140, src (0, 0), mode 1024x768
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe A, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 2, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 3, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 4, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe B, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 1, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 2, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 3, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 4, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe C, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 1, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 2, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 3, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 4, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe D, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe D, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 2, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 3, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 4, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: }
>>> (kms_pipe_crc_basic:1638) igt-debugfs-DEBUG: Opening debugfs directory '/sys/kernel/debug/dri/0'
>>> (kms_pipe_crc_basic:1638) igt-debugfs-DEBUG: Opening debugfs directory '/sys/kernel/debug/dri/0'
>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Test assertion failure function igt_pipe_crc_start, file igt_debugfs.c:764:
>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Failed assertion: pipe_crc->crc_fd != -1
>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Last errno: 5, Input/output error
>>> (kms_pipe_crc_basic:1638) igt-core-INFO: Stack trace:
>>> ****  END  ****
>>> Subtest read-crc-pipe-A: FAIL (0.061s)
>>>
>>> I think the answer is no, but I don't think it's the fault of this patch
>>> series. Opening the CRC data file returns -EIO because the CRTC is not active,
>>> and I'm trying to find out why that is the case. The debug log shows a commit
>>> that seems strange to me, enabling pipe A and immediately disabling right
>>> afterwards. After some investigation I believe that this is caused by sharing
>>> primary planes between CRTCs.
>>>
>>> The R-Car DU groups CRTCs by two and shares 5 planes between the two CRTCs of
>>> the group. This specific SoC has two groups of two CRTCs, but that's not
>>> relevant here, so we can ignore pipes C and D.
>>>
>>> Pipes A and B thus shared 5 planes that I will number 0 to 4 for simplicity.
>>> The driver sets plane 0 as the primary plane for CRTC A and plane 1 as the
>>> primary plane for CRTC B. Planes 2, 3 and 4 are created as overlay planes.
>>>
>>> When igt iterates over all planes for pipe A, it will first encounter plane 0
>>> that has a framebuffer, and thus enables the pipe. It then iterates over
>>> plane 1, recognizes it as a primary plane without a framebuffer, and thus
>>> disables the pipe. Planes 2, 3 and 4 are recognized as overlay planes and thus
>>> don't affect the pipe active state. Pipe B is handled the same way, and igt
>>> disables it twice as planes 0 and 1 are primary.
>>>
>>> I don't know if the fault here is with igt that doesn't properly support this
>>> architecture, or with the driver that shouldn't have two primary planes
>>> available for a CRTC. In the former case, I'm not sure how to fix it, as I'm
>>> not familiar enough with igt to rearchitecture the commit helpers. In the
>>> latter case, how would you recommend fixing it on the driver side ?
>> I guess thus far no one did run igt on a chip which did have reassignable
>> primary planes. The problem here is that it's pretty hard to figure out
>> which one is the real primary plane, since with possible CRTCs you could
>> have multiple primary planes on 1 CRTC. There's no property or anything
>> that explicitly tells you this. Two fixes:
>>
>> 1. Change drivers to limit primary planes to 1 crtc. Same for cursor
>>    overlays. There's probably other userspace than igt that gets confused
>>    by this, but this has the ugly downside that we artifically limit plane
>>    usage - if only 1 CRTC is on, we want to use all the available planes
>>    on that one.
>>
>> 2. Add some implicit or explicit uapi to allow userspace to figure out
>>    which primary plane is the primary plane for this crtc.
>>
>>    a) Explicit option: We add a PRIMARY_ID property (and CURSOR_ID prop
>>       while at it) on the CRTC which points at the primary/cursor plane.
>>
>>    b) Implicit option: We require primary planes are assigned to CRTC in the
>>       same order as they're created. So first primary plane you encouter
>>       is the one for the first CRTC, 2nd primary plane is the one for the
>>       2nd CRTC and so on. If we go with this we probably should add a bit
>>       of code to the kernel to check that invariant (by making sure the
>>       primary plane has the corresponding CRTC included in its
>>       possible_crtc mask).
>>
>> Either way igt needs to be patched to not treat any primary plane that
>> could work on a CRTC as the primary plane for that CRTC.
>>
>> Personally I'm leaning towards 2b).
> Adding Maarten and igt-dev.

We should first make the plane array global, instead of per crtc.

That means removing plane->pipe and plane->index.

And pipe_obj->planes and pipe_obj->n_planes need to be gone too. I think it's
easiest to make

There is one problem. Most of the tests are not aware of the limitations.
If we make the plane array global it should be possible to make
a for_each_possible_plane_on_pipe enumerate all planes that could be assigned
to a certain pipe. We need to sort by z order somehow, but if we then add
igt_plane_set_pipe() which updates the IGT_PLANE_CRTC_ID property, we should
be good.

Only thing we don't see is how the default crtc->primary and crtc->cursor are
assigned. For the calls with COMMIT_LEGACY we need to know the mappings, but
I don't think the kernel exposes them?
I guess we could put it in a FIFO way, first enumerated plane with PRIMARY type
is bound to the first crtc, same for cursor.

This will hopefully allow legacy tests to keep working, while atomic plane aware
tests will be able to use all planes.

~Maarten

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

* Re: igt trouble with planes shared between multiple CRTCs (Re: [PATCH v2 0/8] R-Car DU: Support CRC calculation)
@ 2018-05-01  8:58         ` Maarten Lankhorst
  0 siblings, 0 replies; 82+ messages in thread
From: Maarten Lankhorst @ 2018-05-01  8:58 UTC (permalink / raw)
  To: Daniel Vetter, Laurent Pinchart
  Cc: linux-renesas-soc, IGT development, Ulrich Hecht, Kieran Bingham,
	dri-devel

Hey,

Op 30-04-18 om 16:56 schreef Daniel Vetter:
> On Mon, Apr 30, 2018 at 04:55:24PM +0200, Daniel Vetter wrote:
>> On Sat, Apr 28, 2018 at 12:07:04AM +0300, Laurent Pinchart wrote:
>>> Hi Daniel,
>>>
>>> (Removing the linux-media mailing list from CC as it is out of scope)
>>>
>>> You enquired on IRC whether this patch series passes the igt CRC tests.
>>>
>>> # ./kms_pipe_crc_basic --run-subtest read-crc-pipe-A
>>> IGT-Version: 1.22-gf447f5fc531d (aarch64) (Linux: 4.17.0-rc1-00085-g56e849d93cc9 aarch64)
>>> read-crc-pipe-A: Testing connector LVDS-1 using pipe A
>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Test assertion failure function igt_pipe_crc_start, file igt_debugfs.c:764:
>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Failed assertion: pipe_crc->crc_fd != -1
>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Last errno: 5, Input/output error
>>> Stack trace:
>>> Subtest read-crc-pipe-A failed.
>>> **** DEBUG ****
>>> (kms_pipe_crc_basic:1638) DEBUG: Test requirement passed: !(pipe >= data->display.n_pipes)
>>> (kms_pipe_crc_basic:1638) INFO: read-crc-pipe-A: Testing connector LVDS-1 using pipe A
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: LVDS-1: set_pipe(A)
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: LVDS-1: Selecting pipe A
>>> (kms_pipe_crc_basic:1638) DEBUG: Clearing the fb with color (0.00,1.00,0.00)
>>> (kms_pipe_crc_basic:1638) igt-fb-DEBUG: igt_create_fb_with_bo_size(width=1024, height=768, format=0x34325258, tiling=0x0, size=0)
>>> (kms_pipe_crc_basic:1638) igt-fb-DEBUG: igt_create_fb_with_bo_size(handle=1, pitch=4096)
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: Test requirement passed: plane_idx >= 0 && plane_idx < pipe->n_planes
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: plane_set_fb(140)
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: plane_set_size (1024x768)
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: fb_set_position(0,0)
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: fb_set_size(1024x768)
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: commit {
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     LVDS-1: SetCrtc pipe A, fb 140, src (0, 0), mode 1024x768
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe A, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 2, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 3, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 4, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe B, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 1, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 2, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 3, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 4, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe C, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 1, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 2, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 3, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 4, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe D, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe D, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 2, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 3, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 4, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: }
>>> (kms_pipe_crc_basic:1638) igt-debugfs-DEBUG: Opening debugfs directory '/sys/kernel/debug/dri/0'
>>> (kms_pipe_crc_basic:1638) igt-debugfs-DEBUG: Opening debugfs directory '/sys/kernel/debug/dri/0'
>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Test assertion failure function igt_pipe_crc_start, file igt_debugfs.c:764:
>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Failed assertion: pipe_crc->crc_fd != -1
>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Last errno: 5, Input/output error
>>> (kms_pipe_crc_basic:1638) igt-core-INFO: Stack trace:
>>> ****  END  ****
>>> Subtest read-crc-pipe-A: FAIL (0.061s)
>>>
>>> I think the answer is no, but I don't think it's the fault of this patch
>>> series. Opening the CRC data file returns -EIO because the CRTC is not active,
>>> and I'm trying to find out why that is the case. The debug log shows a commit
>>> that seems strange to me, enabling pipe A and immediately disabling right
>>> afterwards. After some investigation I believe that this is caused by sharing
>>> primary planes between CRTCs.
>>>
>>> The R-Car DU groups CRTCs by two and shares 5 planes between the two CRTCs of
>>> the group. This specific SoC has two groups of two CRTCs, but that's not
>>> relevant here, so we can ignore pipes C and D.
>>>
>>> Pipes A and B thus shared 5 planes that I will number 0 to 4 for simplicity.
>>> The driver sets plane 0 as the primary plane for CRTC A and plane 1 as the
>>> primary plane for CRTC B. Planes 2, 3 and 4 are created as overlay planes.
>>>
>>> When igt iterates over all planes for pipe A, it will first encounter plane 0
>>> that has a framebuffer, and thus enables the pipe. It then iterates over
>>> plane 1, recognizes it as a primary plane without a framebuffer, and thus
>>> disables the pipe. Planes 2, 3 and 4 are recognized as overlay planes and thus
>>> don't affect the pipe active state. Pipe B is handled the same way, and igt
>>> disables it twice as planes 0 and 1 are primary.
>>>
>>> I don't know if the fault here is with igt that doesn't properly support this
>>> architecture, or with the driver that shouldn't have two primary planes
>>> available for a CRTC. In the former case, I'm not sure how to fix it, as I'm
>>> not familiar enough with igt to rearchitecture the commit helpers. In the
>>> latter case, how would you recommend fixing it on the driver side ?
>> I guess thus far no one did run igt on a chip which did have reassignable
>> primary planes. The problem here is that it's pretty hard to figure out
>> which one is the real primary plane, since with possible CRTCs you could
>> have multiple primary planes on 1 CRTC. There's no property or anything
>> that explicitly tells you this. Two fixes:
>>
>> 1. Change drivers to limit primary planes to 1 crtc. Same for cursor
>>    overlays. There's probably other userspace than igt that gets confused
>>    by this, but this has the ugly downside that we artifically limit plane
>>    usage - if only 1 CRTC is on, we want to use all the available planes
>>    on that one.
>>
>> 2. Add some implicit or explicit uapi to allow userspace to figure out
>>    which primary plane is the primary plane for this crtc.
>>
>>    a) Explicit option: We add a PRIMARY_ID property (and CURSOR_ID prop
>>       while at it) on the CRTC which points at the primary/cursor plane.
>>
>>    b) Implicit option: We require primary planes are assigned to CRTC in the
>>       same order as they're created. So first primary plane you encouter
>>       is the one for the first CRTC, 2nd primary plane is the one for the
>>       2nd CRTC and so on. If we go with this we probably should add a bit
>>       of code to the kernel to check that invariant (by making sure the
>>       primary plane has the corresponding CRTC included in its
>>       possible_crtc mask).
>>
>> Either way igt needs to be patched to not treat any primary plane that
>> could work on a CRTC as the primary plane for that CRTC.
>>
>> Personally I'm leaning towards 2b).
> Adding Maarten and igt-dev.

We should first make the plane array global, instead of per crtc.

That means removing plane->pipe and plane->index.

And pipe_obj->planes and pipe_obj->n_planes need to be gone too. I think it's
easiest to make

There is one problem. Most of the tests are not aware of the limitations.
If we make the plane array global it should be possible to make
a for_each_possible_plane_on_pipe enumerate all planes that could be assigned
to a certain pipe. We need to sort by z order somehow, but if we then add
igt_plane_set_pipe() which updates the IGT_PLANE_CRTC_ID property, we should
be good.

Only thing we don't see is how the default crtc->primary and crtc->cursor are
assigned. For the calls with COMMIT_LEGACY we need to know the mappings, but
I don't think the kernel exposes them?
I guess we could put it in a FIFO way, first enumerated plane with PRIMARY type
is bound to the first crtc, same for cursor.

This will hopefully allow legacy tests to keep working, while atomic plane aware
tests will be able to use all planes.

~Maarten

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

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

* Re: [igt-dev] igt trouble with planes shared between multiple CRTCs (Re: [PATCH v2 0/8] R-Car DU: Support CRC calculation)
@ 2018-05-01  8:58         ` Maarten Lankhorst
  0 siblings, 0 replies; 82+ messages in thread
From: Maarten Lankhorst @ 2018-05-01  8:58 UTC (permalink / raw)
  To: Daniel Vetter, Laurent Pinchart
  Cc: linux-renesas-soc, IGT development, Kieran Bingham, dri-devel

Hey,

Op 30-04-18 om 16:56 schreef Daniel Vetter:
> On Mon, Apr 30, 2018 at 04:55:24PM +0200, Daniel Vetter wrote:
>> On Sat, Apr 28, 2018 at 12:07:04AM +0300, Laurent Pinchart wrote:
>>> Hi Daniel,
>>>
>>> (Removing the linux-media mailing list from CC as it is out of scope)
>>>
>>> You enquired on IRC whether this patch series passes the igt CRC tests.
>>>
>>> # ./kms_pipe_crc_basic --run-subtest read-crc-pipe-A
>>> IGT-Version: 1.22-gf447f5fc531d (aarch64) (Linux: 4.17.0-rc1-00085-g56e849d93cc9 aarch64)
>>> read-crc-pipe-A: Testing connector LVDS-1 using pipe A
>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Test assertion failure function igt_pipe_crc_start, file igt_debugfs.c:764:
>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Failed assertion: pipe_crc->crc_fd != -1
>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Last errno: 5, Input/output error
>>> Stack trace:
>>> Subtest read-crc-pipe-A failed.
>>> **** DEBUG ****
>>> (kms_pipe_crc_basic:1638) DEBUG: Test requirement passed: !(pipe >= data->display.n_pipes)
>>> (kms_pipe_crc_basic:1638) INFO: read-crc-pipe-A: Testing connector LVDS-1 using pipe A
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: LVDS-1: set_pipe(A)
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: LVDS-1: Selecting pipe A
>>> (kms_pipe_crc_basic:1638) DEBUG: Clearing the fb with color (0.00,1.00,0.00)
>>> (kms_pipe_crc_basic:1638) igt-fb-DEBUG: igt_create_fb_with_bo_size(width=1024, height=768, format=0x34325258, tiling=0x0, size=0)
>>> (kms_pipe_crc_basic:1638) igt-fb-DEBUG: igt_create_fb_with_bo_size(handle=1, pitch=4096)
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: Test requirement passed: plane_idx >= 0 && plane_idx < pipe->n_planes
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: plane_set_fb(140)
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: plane_set_size (1024x768)
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: fb_set_position(0,0)
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: fb_set_size(1024x768)
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: commit {
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     LVDS-1: SetCrtc pipe A, fb 140, src (0, 0), mode 1024x768
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe A, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 2, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 3, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 4, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe B, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 1, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 2, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 3, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 4, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe C, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 1, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 2, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 3, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 4, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe D, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe D, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 2, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 3, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 4, disabling
>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: }
>>> (kms_pipe_crc_basic:1638) igt-debugfs-DEBUG: Opening debugfs directory '/sys/kernel/debug/dri/0'
>>> (kms_pipe_crc_basic:1638) igt-debugfs-DEBUG: Opening debugfs directory '/sys/kernel/debug/dri/0'
>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Test assertion failure function igt_pipe_crc_start, file igt_debugfs.c:764:
>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Failed assertion: pipe_crc->crc_fd != -1
>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Last errno: 5, Input/output error
>>> (kms_pipe_crc_basic:1638) igt-core-INFO: Stack trace:
>>> ****  END  ****
>>> Subtest read-crc-pipe-A: FAIL (0.061s)
>>>
>>> I think the answer is no, but I don't think it's the fault of this patch
>>> series. Opening the CRC data file returns -EIO because the CRTC is not active,
>>> and I'm trying to find out why that is the case. The debug log shows a commit
>>> that seems strange to me, enabling pipe A and immediately disabling right
>>> afterwards. After some investigation I believe that this is caused by sharing
>>> primary planes between CRTCs.
>>>
>>> The R-Car DU groups CRTCs by two and shares 5 planes between the two CRTCs of
>>> the group. This specific SoC has two groups of two CRTCs, but that's not
>>> relevant here, so we can ignore pipes C and D.
>>>
>>> Pipes A and B thus shared 5 planes that I will number 0 to 4 for simplicity.
>>> The driver sets plane 0 as the primary plane for CRTC A and plane 1 as the
>>> primary plane for CRTC B. Planes 2, 3 and 4 are created as overlay planes.
>>>
>>> When igt iterates over all planes for pipe A, it will first encounter plane 0
>>> that has a framebuffer, and thus enables the pipe. It then iterates over
>>> plane 1, recognizes it as a primary plane without a framebuffer, and thus
>>> disables the pipe. Planes 2, 3 and 4 are recognized as overlay planes and thus
>>> don't affect the pipe active state. Pipe B is handled the same way, and igt
>>> disables it twice as planes 0 and 1 are primary.
>>>
>>> I don't know if the fault here is with igt that doesn't properly support this
>>> architecture, or with the driver that shouldn't have two primary planes
>>> available for a CRTC. In the former case, I'm not sure how to fix it, as I'm
>>> not familiar enough with igt to rearchitecture the commit helpers. In the
>>> latter case, how would you recommend fixing it on the driver side ?
>> I guess thus far no one did run igt on a chip which did have reassignable
>> primary planes. The problem here is that it's pretty hard to figure out
>> which one is the real primary plane, since with possible CRTCs you could
>> have multiple primary planes on 1 CRTC. There's no property or anything
>> that explicitly tells you this. Two fixes:
>>
>> 1. Change drivers to limit primary planes to 1 crtc. Same for cursor
>>    overlays. There's probably other userspace than igt that gets confused
>>    by this, but this has the ugly downside that we artifically limit plane
>>    usage - if only 1 CRTC is on, we want to use all the available planes
>>    on that one.
>>
>> 2. Add some implicit or explicit uapi to allow userspace to figure out
>>    which primary plane is the primary plane for this crtc.
>>
>>    a) Explicit option: We add a PRIMARY_ID property (and CURSOR_ID prop
>>       while at it) on the CRTC which points at the primary/cursor plane.
>>
>>    b) Implicit option: We require primary planes are assigned to CRTC in the
>>       same order as they're created. So first primary plane you encouter
>>       is the one for the first CRTC, 2nd primary plane is the one for the
>>       2nd CRTC and so on. If we go with this we probably should add a bit
>>       of code to the kernel to check that invariant (by making sure the
>>       primary plane has the corresponding CRTC included in its
>>       possible_crtc mask).
>>
>> Either way igt needs to be patched to not treat any primary plane that
>> could work on a CRTC as the primary plane for that CRTC.
>>
>> Personally I'm leaning towards 2b).
> Adding Maarten and igt-dev.

We should first make the plane array global, instead of per crtc.

That means removing plane->pipe and plane->index.

And pipe_obj->planes and pipe_obj->n_planes need to be gone too. I think it's
easiest to make

There is one problem. Most of the tests are not aware of the limitations.
If we make the plane array global it should be possible to make
a for_each_possible_plane_on_pipe enumerate all planes that could be assigned
to a certain pipe. We need to sort by z order somehow, but if we then add
igt_plane_set_pipe() which updates the IGT_PLANE_CRTC_ID property, we should
be good.

Only thing we don't see is how the default crtc->primary and crtc->cursor are
assigned. For the calls with COMMIT_LEGACY we need to know the mappings, but
I don't think the kernel exposes them?
I guess we could put it in a FIFO way, first enumerated plane with PRIMARY type
is bound to the first crtc, same for cursor.

This will hopefully allow legacy tests to keep working, while atomic plane aware
tests will be able to use all planes.

~Maarten

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

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

* Re: igt trouble with planes shared between multiple CRTCs (Re: [PATCH v2 0/8] R-Car DU: Support CRC calculation)
  2018-05-01  8:58         ` Maarten Lankhorst
  (?)
@ 2018-05-01 15:47           ` Maarten Lankhorst
  -1 siblings, 0 replies; 82+ messages in thread
From: Maarten Lankhorst @ 2018-05-01 15:47 UTC (permalink / raw)
  To: Daniel Vetter, Laurent Pinchart
  Cc: dri-devel, linux-renesas-soc, Kieran Bingham, Ulrich Hecht,
	IGT development

Op 01-05-18 om 10:58 schreef Maarten Lankhorst:
> Hey,
>
> Op 30-04-18 om 16:56 schreef Daniel Vetter:
>> On Mon, Apr 30, 2018 at 04:55:24PM +0200, Daniel Vetter wrote:
>>> On Sat, Apr 28, 2018 at 12:07:04AM +0300, Laurent Pinchart wrote:
>>>> Hi Daniel,
>>>>
>>>> (Removing the linux-media mailing list from CC as it is out of scope)
>>>>
>>>> You enquired on IRC whether this patch series passes the igt CRC tests.
>>>>
>>>> # ./kms_pipe_crc_basic --run-subtest read-crc-pipe-A
>>>> IGT-Version: 1.22-gf447f5fc531d (aarch64) (Linux: 4.17.0-rc1-00085-g56e849d93cc9 aarch64)
>>>> read-crc-pipe-A: Testing connector LVDS-1 using pipe A
>>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Test assertion failure function igt_pipe_crc_start, file igt_debugfs.c:764:
>>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Failed assertion: pipe_crc->crc_fd != -1
>>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Last errno: 5, Input/output error
>>>> Stack trace:
>>>> Subtest read-crc-pipe-A failed.
>>>> **** DEBUG ****
>>>> (kms_pipe_crc_basic:1638) DEBUG: Test requirement passed: !(pipe >= data->display.n_pipes)
>>>> (kms_pipe_crc_basic:1638) INFO: read-crc-pipe-A: Testing connector LVDS-1 using pipe A
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: LVDS-1: set_pipe(A)
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: LVDS-1: Selecting pipe A
>>>> (kms_pipe_crc_basic:1638) DEBUG: Clearing the fb with color (0.00,1.00,0.00)
>>>> (kms_pipe_crc_basic:1638) igt-fb-DEBUG: igt_create_fb_with_bo_size(width=1024, height=768, format=0x34325258, tiling=0x0, size=0)
>>>> (kms_pipe_crc_basic:1638) igt-fb-DEBUG: igt_create_fb_with_bo_size(handle=1, pitch=4096)
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: Test requirement passed: plane_idx >= 0 && plane_idx < pipe->n_planes
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: plane_set_fb(140)
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: plane_set_size (1024x768)
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: fb_set_position(0,0)
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: fb_set_size(1024x768)
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: commit {
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     LVDS-1: SetCrtc pipe A, fb 140, src (0, 0), mode 1024x768
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe A, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 2, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 3, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 4, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe B, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 1, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 2, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 3, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 4, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe C, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 1, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 2, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 3, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 4, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe D, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe D, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 2, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 3, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 4, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: }
>>>> (kms_pipe_crc_basic:1638) igt-debugfs-DEBUG: Opening debugfs directory '/sys/kernel/debug/dri/0'
>>>> (kms_pipe_crc_basic:1638) igt-debugfs-DEBUG: Opening debugfs directory '/sys/kernel/debug/dri/0'
>>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Test assertion failure function igt_pipe_crc_start, file igt_debugfs.c:764:
>>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Failed assertion: pipe_crc->crc_fd != -1
>>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Last errno: 5, Input/output error
>>>> (kms_pipe_crc_basic:1638) igt-core-INFO: Stack trace:
>>>> ****  END  ****
>>>> Subtest read-crc-pipe-A: FAIL (0.061s)
>>>>
>>>> I think the answer is no, but I don't think it's the fault of this patch
>>>> series. Opening the CRC data file returns -EIO because the CRTC is not active,
>>>> and I'm trying to find out why that is the case. The debug log shows a commit
>>>> that seems strange to me, enabling pipe A and immediately disabling right
>>>> afterwards. After some investigation I believe that this is caused by sharing
>>>> primary planes between CRTCs.
>>>>
>>>> The R-Car DU groups CRTCs by two and shares 5 planes between the two CRTCs of
>>>> the group. This specific SoC has two groups of two CRTCs, but that's not
>>>> relevant here, so we can ignore pipes C and D.
>>>>
>>>> Pipes A and B thus shared 5 planes that I will number 0 to 4 for simplicity.
>>>> The driver sets plane 0 as the primary plane for CRTC A and plane 1 as the
>>>> primary plane for CRTC B. Planes 2, 3 and 4 are created as overlay planes.
>>>>
>>>> When igt iterates over all planes for pipe A, it will first encounter plane 0
>>>> that has a framebuffer, and thus enables the pipe. It then iterates over
>>>> plane 1, recognizes it as a primary plane without a framebuffer, and thus
>>>> disables the pipe. Planes 2, 3 and 4 are recognized as overlay planes and thus
>>>> don't affect the pipe active state. Pipe B is handled the same way, and igt
>>>> disables it twice as planes 0 and 1 are primary.
>>>>
>>>> I don't know if the fault here is with igt that doesn't properly support this
>>>> architecture, or with the driver that shouldn't have two primary planes
>>>> available for a CRTC. In the former case, I'm not sure how to fix it, as I'm
>>>> not familiar enough with igt to rearchitecture the commit helpers. In the
>>>> latter case, how would you recommend fixing it on the driver side ?
>>> I guess thus far no one did run igt on a chip which did have reassignable
>>> primary planes. The problem here is that it's pretty hard to figure out
>>> which one is the real primary plane, since with possible CRTCs you could
>>> have multiple primary planes on 1 CRTC. There's no property or anything
>>> that explicitly tells you this. Two fixes:
>>>
>>> 1. Change drivers to limit primary planes to 1 crtc. Same for cursor
>>>    overlays. There's probably other userspace than igt that gets confused
>>>    by this, but this has the ugly downside that we artifically limit plane
>>>    usage - if only 1 CRTC is on, we want to use all the available planes
>>>    on that one.
>>>
>>> 2. Add some implicit or explicit uapi to allow userspace to figure out
>>>    which primary plane is the primary plane for this crtc.
>>>
>>>    a) Explicit option: We add a PRIMARY_ID property (and CURSOR_ID prop
>>>       while at it) on the CRTC which points at the primary/cursor plane.
>>>
>>>    b) Implicit option: We require primary planes are assigned to CRTC in the
>>>       same order as they're created. So first primary plane you encouter
>>>       is the one for the first CRTC, 2nd primary plane is the one for the
>>>       2nd CRTC and so on. If we go with this we probably should add a bit
>>>       of code to the kernel to check that invariant (by making sure the
>>>       primary plane has the corresponding CRTC included in its
>>>       possible_crtc mask).
>>>
>>> Either way igt needs to be patched to not treat any primary plane that
>>> could work on a CRTC as the primary plane for that CRTC.
>>>
>>> Personally I'm leaning towards 2b).
>> Adding Maarten and igt-dev.
> We should first make the plane array global, instead of per crtc.
>
> That means removing plane->pipe and plane->index.
>
> And pipe_obj->planes and pipe_obj->n_planes need to be gone too. I think it's
> easiest to make
>
> There is one problem. Most of the tests are not aware of the limitations.
> If we make the plane array global it should be possible to make
> a for_each_possible_plane_on_pipe enumerate all planes that could be assigned
> to a certain pipe. We need to sort by z order somehow, but if we then add
> igt_plane_set_pipe() which updates the IGT_PLANE_CRTC_ID property, we should
> be good.
>
> Only thing we don't see is how the default crtc->primary and crtc->cursor are
> assigned. For the calls with COMMIT_LEGACY we need to know the mappings, but
> I don't think the kernel exposes them?
> I guess we could put it in a FIFO way, first enumerated plane with PRIMARY type
> is bound to the first crtc, same for cursor.
>
> This will hopefully allow legacy tests to keep working, while atomic plane aware
> tests will be able to use all planes.
>
> ~Maarten
>
https://cgit.freedesktop.org/~mlankhorst/intel-gpu-tools is what I was thinking
about, didn't test if it works, only compiles.

What's missing is that we should only create 1 igt_plane_t for each drm plane
instead of one for each pipe. Not sure how to get that working without
breaking a lot of assumptions in the tests, mainly the dual output tests. I think
that we should prevent for_each_plane_on_pipe until an output is set on the pipe,
and then automatically assign all planes to it and set plane->type to something matching.

When a second output is bound, steal unused sprite planes as required and divide them
equally. :)

~Maarten

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

* Re: igt trouble with planes shared between multiple CRTCs (Re: [PATCH v2 0/8] R-Car DU: Support CRC calculation)
@ 2018-05-01 15:47           ` Maarten Lankhorst
  0 siblings, 0 replies; 82+ messages in thread
From: Maarten Lankhorst @ 2018-05-01 15:47 UTC (permalink / raw)
  To: Daniel Vetter, Laurent Pinchart
  Cc: linux-renesas-soc, IGT development, Ulrich Hecht, Kieran Bingham,
	dri-devel

Op 01-05-18 om 10:58 schreef Maarten Lankhorst:
> Hey,
>
> Op 30-04-18 om 16:56 schreef Daniel Vetter:
>> On Mon, Apr 30, 2018 at 04:55:24PM +0200, Daniel Vetter wrote:
>>> On Sat, Apr 28, 2018 at 12:07:04AM +0300, Laurent Pinchart wrote:
>>>> Hi Daniel,
>>>>
>>>> (Removing the linux-media mailing list from CC as it is out of scope)
>>>>
>>>> You enquired on IRC whether this patch series passes the igt CRC tests.
>>>>
>>>> # ./kms_pipe_crc_basic --run-subtest read-crc-pipe-A
>>>> IGT-Version: 1.22-gf447f5fc531d (aarch64) (Linux: 4.17.0-rc1-00085-g56e849d93cc9 aarch64)
>>>> read-crc-pipe-A: Testing connector LVDS-1 using pipe A
>>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Test assertion failure function igt_pipe_crc_start, file igt_debugfs.c:764:
>>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Failed assertion: pipe_crc->crc_fd != -1
>>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Last errno: 5, Input/output error
>>>> Stack trace:
>>>> Subtest read-crc-pipe-A failed.
>>>> **** DEBUG ****
>>>> (kms_pipe_crc_basic:1638) DEBUG: Test requirement passed: !(pipe >= data->display.n_pipes)
>>>> (kms_pipe_crc_basic:1638) INFO: read-crc-pipe-A: Testing connector LVDS-1 using pipe A
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: LVDS-1: set_pipe(A)
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: LVDS-1: Selecting pipe A
>>>> (kms_pipe_crc_basic:1638) DEBUG: Clearing the fb with color (0.00,1.00,0.00)
>>>> (kms_pipe_crc_basic:1638) igt-fb-DEBUG: igt_create_fb_with_bo_size(width=1024, height=768, format=0x34325258, tiling=0x0, size=0)
>>>> (kms_pipe_crc_basic:1638) igt-fb-DEBUG: igt_create_fb_with_bo_size(handle=1, pitch=4096)
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: Test requirement passed: plane_idx >= 0 && plane_idx < pipe->n_planes
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: plane_set_fb(140)
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: plane_set_size (1024x768)
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: fb_set_position(0,0)
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: fb_set_size(1024x768)
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: commit {
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     LVDS-1: SetCrtc pipe A, fb 140, src (0, 0), mode 1024x768
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe A, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 2, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 3, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 4, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe B, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 1, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 2, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 3, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 4, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe C, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 1, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 2, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 3, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 4, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe D, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe D, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 2, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 3, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 4, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: }
>>>> (kms_pipe_crc_basic:1638) igt-debugfs-DEBUG: Opening debugfs directory '/sys/kernel/debug/dri/0'
>>>> (kms_pipe_crc_basic:1638) igt-debugfs-DEBUG: Opening debugfs directory '/sys/kernel/debug/dri/0'
>>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Test assertion failure function igt_pipe_crc_start, file igt_debugfs.c:764:
>>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Failed assertion: pipe_crc->crc_fd != -1
>>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Last errno: 5, Input/output error
>>>> (kms_pipe_crc_basic:1638) igt-core-INFO: Stack trace:
>>>> ****  END  ****
>>>> Subtest read-crc-pipe-A: FAIL (0.061s)
>>>>
>>>> I think the answer is no, but I don't think it's the fault of this patch
>>>> series. Opening the CRC data file returns -EIO because the CRTC is not active,
>>>> and I'm trying to find out why that is the case. The debug log shows a commit
>>>> that seems strange to me, enabling pipe A and immediately disabling right
>>>> afterwards. After some investigation I believe that this is caused by sharing
>>>> primary planes between CRTCs.
>>>>
>>>> The R-Car DU groups CRTCs by two and shares 5 planes between the two CRTCs of
>>>> the group. This specific SoC has two groups of two CRTCs, but that's not
>>>> relevant here, so we can ignore pipes C and D.
>>>>
>>>> Pipes A and B thus shared 5 planes that I will number 0 to 4 for simplicity.
>>>> The driver sets plane 0 as the primary plane for CRTC A and plane 1 as the
>>>> primary plane for CRTC B. Planes 2, 3 and 4 are created as overlay planes.
>>>>
>>>> When igt iterates over all planes for pipe A, it will first encounter plane 0
>>>> that has a framebuffer, and thus enables the pipe. It then iterates over
>>>> plane 1, recognizes it as a primary plane without a framebuffer, and thus
>>>> disables the pipe. Planes 2, 3 and 4 are recognized as overlay planes and thus
>>>> don't affect the pipe active state. Pipe B is handled the same way, and igt
>>>> disables it twice as planes 0 and 1 are primary.
>>>>
>>>> I don't know if the fault here is with igt that doesn't properly support this
>>>> architecture, or with the driver that shouldn't have two primary planes
>>>> available for a CRTC. In the former case, I'm not sure how to fix it, as I'm
>>>> not familiar enough with igt to rearchitecture the commit helpers. In the
>>>> latter case, how would you recommend fixing it on the driver side ?
>>> I guess thus far no one did run igt on a chip which did have reassignable
>>> primary planes. The problem here is that it's pretty hard to figure out
>>> which one is the real primary plane, since with possible CRTCs you could
>>> have multiple primary planes on 1 CRTC. There's no property or anything
>>> that explicitly tells you this. Two fixes:
>>>
>>> 1. Change drivers to limit primary planes to 1 crtc. Same for cursor
>>>    overlays. There's probably other userspace than igt that gets confused
>>>    by this, but this has the ugly downside that we artifically limit plane
>>>    usage - if only 1 CRTC is on, we want to use all the available planes
>>>    on that one.
>>>
>>> 2. Add some implicit or explicit uapi to allow userspace to figure out
>>>    which primary plane is the primary plane for this crtc.
>>>
>>>    a) Explicit option: We add a PRIMARY_ID property (and CURSOR_ID prop
>>>       while at it) on the CRTC which points at the primary/cursor plane.
>>>
>>>    b) Implicit option: We require primary planes are assigned to CRTC in the
>>>       same order as they're created. So first primary plane you encouter
>>>       is the one for the first CRTC, 2nd primary plane is the one for the
>>>       2nd CRTC and so on. If we go with this we probably should add a bit
>>>       of code to the kernel to check that invariant (by making sure the
>>>       primary plane has the corresponding CRTC included in its
>>>       possible_crtc mask).
>>>
>>> Either way igt needs to be patched to not treat any primary plane that
>>> could work on a CRTC as the primary plane for that CRTC.
>>>
>>> Personally I'm leaning towards 2b).
>> Adding Maarten and igt-dev.
> We should first make the plane array global, instead of per crtc.
>
> That means removing plane->pipe and plane->index.
>
> And pipe_obj->planes and pipe_obj->n_planes need to be gone too. I think it's
> easiest to make
>
> There is one problem. Most of the tests are not aware of the limitations.
> If we make the plane array global it should be possible to make
> a for_each_possible_plane_on_pipe enumerate all planes that could be assigned
> to a certain pipe. We need to sort by z order somehow, but if we then add
> igt_plane_set_pipe() which updates the IGT_PLANE_CRTC_ID property, we should
> be good.
>
> Only thing we don't see is how the default crtc->primary and crtc->cursor are
> assigned. For the calls with COMMIT_LEGACY we need to know the mappings, but
> I don't think the kernel exposes them?
> I guess we could put it in a FIFO way, first enumerated plane with PRIMARY type
> is bound to the first crtc, same for cursor.
>
> This will hopefully allow legacy tests to keep working, while atomic plane aware
> tests will be able to use all planes.
>
> ~Maarten
>
https://cgit.freedesktop.org/~mlankhorst/intel-gpu-tools is what I was thinking
about, didn't test if it works, only compiles.

What's missing is that we should only create 1 igt_plane_t for each drm plane
instead of one for each pipe. Not sure how to get that working without
breaking a lot of assumptions in the tests, mainly the dual output tests. I think
that we should prevent for_each_plane_on_pipe until an output is set on the pipe,
and then automatically assign all planes to it and set plane->type to something matching.

When a second output is bound, steal unused sprite planes as required and divide them
equally. :)

~Maarten

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

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

* Re: [igt-dev] igt trouble with planes shared between multiple CRTCs (Re: [PATCH v2 0/8] R-Car DU: Support CRC calculation)
@ 2018-05-01 15:47           ` Maarten Lankhorst
  0 siblings, 0 replies; 82+ messages in thread
From: Maarten Lankhorst @ 2018-05-01 15:47 UTC (permalink / raw)
  To: Daniel Vetter, Laurent Pinchart
  Cc: linux-renesas-soc, IGT development, Kieran Bingham, dri-devel

Op 01-05-18 om 10:58 schreef Maarten Lankhorst:
> Hey,
>
> Op 30-04-18 om 16:56 schreef Daniel Vetter:
>> On Mon, Apr 30, 2018 at 04:55:24PM +0200, Daniel Vetter wrote:
>>> On Sat, Apr 28, 2018 at 12:07:04AM +0300, Laurent Pinchart wrote:
>>>> Hi Daniel,
>>>>
>>>> (Removing the linux-media mailing list from CC as it is out of scope)
>>>>
>>>> You enquired on IRC whether this patch series passes the igt CRC tests.
>>>>
>>>> # ./kms_pipe_crc_basic --run-subtest read-crc-pipe-A
>>>> IGT-Version: 1.22-gf447f5fc531d (aarch64) (Linux: 4.17.0-rc1-00085-g56e849d93cc9 aarch64)
>>>> read-crc-pipe-A: Testing connector LVDS-1 using pipe A
>>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Test assertion failure function igt_pipe_crc_start, file igt_debugfs.c:764:
>>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Failed assertion: pipe_crc->crc_fd != -1
>>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Last errno: 5, Input/output error
>>>> Stack trace:
>>>> Subtest read-crc-pipe-A failed.
>>>> **** DEBUG ****
>>>> (kms_pipe_crc_basic:1638) DEBUG: Test requirement passed: !(pipe >= data->display.n_pipes)
>>>> (kms_pipe_crc_basic:1638) INFO: read-crc-pipe-A: Testing connector LVDS-1 using pipe A
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: LVDS-1: set_pipe(A)
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: LVDS-1: Selecting pipe A
>>>> (kms_pipe_crc_basic:1638) DEBUG: Clearing the fb with color (0.00,1.00,0.00)
>>>> (kms_pipe_crc_basic:1638) igt-fb-DEBUG: igt_create_fb_with_bo_size(width=1024, height=768, format=0x34325258, tiling=0x0, size=0)
>>>> (kms_pipe_crc_basic:1638) igt-fb-DEBUG: igt_create_fb_with_bo_size(handle=1, pitch=4096)
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: Test requirement passed: plane_idx >= 0 && plane_idx < pipe->n_planes
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: plane_set_fb(140)
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: plane_set_size (1024x768)
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: fb_set_position(0,0)
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: fb_set_size(1024x768)
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: commit {
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     LVDS-1: SetCrtc pipe A, fb 140, src (0, 0), mode 1024x768
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe A, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 2, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 3, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 4, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe B, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 1, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 2, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 3, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 4, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe C, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 1, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 2, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 3, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 4, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe D, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe D, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 2, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 3, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 4, disabling
>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: }
>>>> (kms_pipe_crc_basic:1638) igt-debugfs-DEBUG: Opening debugfs directory '/sys/kernel/debug/dri/0'
>>>> (kms_pipe_crc_basic:1638) igt-debugfs-DEBUG: Opening debugfs directory '/sys/kernel/debug/dri/0'
>>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Test assertion failure function igt_pipe_crc_start, file igt_debugfs.c:764:
>>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Failed assertion: pipe_crc->crc_fd != -1
>>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Last errno: 5, Input/output error
>>>> (kms_pipe_crc_basic:1638) igt-core-INFO: Stack trace:
>>>> ****  END  ****
>>>> Subtest read-crc-pipe-A: FAIL (0.061s)
>>>>
>>>> I think the answer is no, but I don't think it's the fault of this patch
>>>> series. Opening the CRC data file returns -EIO because the CRTC is not active,
>>>> and I'm trying to find out why that is the case. The debug log shows a commit
>>>> that seems strange to me, enabling pipe A and immediately disabling right
>>>> afterwards. After some investigation I believe that this is caused by sharing
>>>> primary planes between CRTCs.
>>>>
>>>> The R-Car DU groups CRTCs by two and shares 5 planes between the two CRTCs of
>>>> the group. This specific SoC has two groups of two CRTCs, but that's not
>>>> relevant here, so we can ignore pipes C and D.
>>>>
>>>> Pipes A and B thus shared 5 planes that I will number 0 to 4 for simplicity.
>>>> The driver sets plane 0 as the primary plane for CRTC A and plane 1 as the
>>>> primary plane for CRTC B. Planes 2, 3 and 4 are created as overlay planes.
>>>>
>>>> When igt iterates over all planes for pipe A, it will first encounter plane 0
>>>> that has a framebuffer, and thus enables the pipe. It then iterates over
>>>> plane 1, recognizes it as a primary plane without a framebuffer, and thus
>>>> disables the pipe. Planes 2, 3 and 4 are recognized as overlay planes and thus
>>>> don't affect the pipe active state. Pipe B is handled the same way, and igt
>>>> disables it twice as planes 0 and 1 are primary.
>>>>
>>>> I don't know if the fault here is with igt that doesn't properly support this
>>>> architecture, or with the driver that shouldn't have two primary planes
>>>> available for a CRTC. In the former case, I'm not sure how to fix it, as I'm
>>>> not familiar enough with igt to rearchitecture the commit helpers. In the
>>>> latter case, how would you recommend fixing it on the driver side ?
>>> I guess thus far no one did run igt on a chip which did have reassignable
>>> primary planes. The problem here is that it's pretty hard to figure out
>>> which one is the real primary plane, since with possible CRTCs you could
>>> have multiple primary planes on 1 CRTC. There's no property or anything
>>> that explicitly tells you this. Two fixes:
>>>
>>> 1. Change drivers to limit primary planes to 1 crtc. Same for cursor
>>>    overlays. There's probably other userspace than igt that gets confused
>>>    by this, but this has the ugly downside that we artifically limit plane
>>>    usage - if only 1 CRTC is on, we want to use all the available planes
>>>    on that one.
>>>
>>> 2. Add some implicit or explicit uapi to allow userspace to figure out
>>>    which primary plane is the primary plane for this crtc.
>>>
>>>    a) Explicit option: We add a PRIMARY_ID property (and CURSOR_ID prop
>>>       while at it) on the CRTC which points at the primary/cursor plane.
>>>
>>>    b) Implicit option: We require primary planes are assigned to CRTC in the
>>>       same order as they're created. So first primary plane you encouter
>>>       is the one for the first CRTC, 2nd primary plane is the one for the
>>>       2nd CRTC and so on. If we go with this we probably should add a bit
>>>       of code to the kernel to check that invariant (by making sure the
>>>       primary plane has the corresponding CRTC included in its
>>>       possible_crtc mask).
>>>
>>> Either way igt needs to be patched to not treat any primary plane that
>>> could work on a CRTC as the primary plane for that CRTC.
>>>
>>> Personally I'm leaning towards 2b).
>> Adding Maarten and igt-dev.
> We should first make the plane array global, instead of per crtc.
>
> That means removing plane->pipe and plane->index.
>
> And pipe_obj->planes and pipe_obj->n_planes need to be gone too. I think it's
> easiest to make
>
> There is one problem. Most of the tests are not aware of the limitations.
> If we make the plane array global it should be possible to make
> a for_each_possible_plane_on_pipe enumerate all planes that could be assigned
> to a certain pipe. We need to sort by z order somehow, but if we then add
> igt_plane_set_pipe() which updates the IGT_PLANE_CRTC_ID property, we should
> be good.
>
> Only thing we don't see is how the default crtc->primary and crtc->cursor are
> assigned. For the calls with COMMIT_LEGACY we need to know the mappings, but
> I don't think the kernel exposes them?
> I guess we could put it in a FIFO way, first enumerated plane with PRIMARY type
> is bound to the first crtc, same for cursor.
>
> This will hopefully allow legacy tests to keep working, while atomic plane aware
> tests will be able to use all planes.
>
> ~Maarten
>
https://cgit.freedesktop.org/~mlankhorst/intel-gpu-tools is what I was thinking
about, didn't test if it works, only compiles.

What's missing is that we should only create 1 igt_plane_t for each drm plane
instead of one for each pipe. Not sure how to get that working without
breaking a lot of assumptions in the tests, mainly the dual output tests. I think
that we should prevent for_each_plane_on_pipe until an output is set on the pipe,
and then automatically assign all planes to it and set plane->type to something matching.

When a second output is bound, steal unused sprite planes as required and divide them
equally. :)

~Maarten

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

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

* Re: igt trouble with planes shared between multiple CRTCs (Re: [PATCH v2 0/8] R-Car DU: Support CRC calculation)
  2018-05-01  8:58         ` Maarten Lankhorst
@ 2018-05-02  7:32           ` Daniel Vetter
  -1 siblings, 0 replies; 82+ messages in thread
From: Daniel Vetter @ 2018-05-02  7:32 UTC (permalink / raw)
  To: Maarten Lankhorst
  Cc: Daniel Vetter, Laurent Pinchart, dri-devel, linux-renesas-soc,
	Kieran Bingham, Ulrich Hecht, IGT development

On Tue, May 01, 2018 at 10:58:02AM +0200, Maarten Lankhorst wrote:
> Hey,
> 
> Op 30-04-18 om 16:56 schreef Daniel Vetter:
> > On Mon, Apr 30, 2018 at 04:55:24PM +0200, Daniel Vetter wrote:
> >> On Sat, Apr 28, 2018 at 12:07:04AM +0300, Laurent Pinchart wrote:
> >>> Hi Daniel,
> >>>
> >>> (Removing the linux-media mailing list from CC as it is out of scope)
> >>>
> >>> You enquired on IRC whether this patch series passes the igt CRC tests.
> >>>
> >>> # ./kms_pipe_crc_basic --run-subtest read-crc-pipe-A
> >>> IGT-Version: 1.22-gf447f5fc531d (aarch64) (Linux: 4.17.0-rc1-00085-g56e849d93cc9 aarch64)
> >>> read-crc-pipe-A: Testing connector LVDS-1 using pipe A
> >>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Test assertion failure function igt_pipe_crc_start, file igt_debugfs.c:764:
> >>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Failed assertion: pipe_crc->crc_fd != -1
> >>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Last errno: 5, Input/output error
> >>> Stack trace:
> >>> Subtest read-crc-pipe-A failed.
> >>> **** DEBUG ****
> >>> (kms_pipe_crc_basic:1638) DEBUG: Test requirement passed: !(pipe >= data->display.n_pipes)
> >>> (kms_pipe_crc_basic:1638) INFO: read-crc-pipe-A: Testing connector LVDS-1 using pipe A
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: LVDS-1: set_pipe(A)
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: LVDS-1: Selecting pipe A
> >>> (kms_pipe_crc_basic:1638) DEBUG: Clearing the fb with color (0.00,1.00,0.00)
> >>> (kms_pipe_crc_basic:1638) igt-fb-DEBUG: igt_create_fb_with_bo_size(width=1024, height=768, format=0x34325258, tiling=0x0, size=0)
> >>> (kms_pipe_crc_basic:1638) igt-fb-DEBUG: igt_create_fb_with_bo_size(handle=1, pitch=4096)
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: Test requirement passed: plane_idx >= 0 && plane_idx < pipe->n_planes
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: plane_set_fb(140)
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: plane_set_size (1024x768)
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: fb_set_position(0,0)
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: fb_set_size(1024x768)
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: commit {
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     LVDS-1: SetCrtc pipe A, fb 140, src (0, 0), mode 1024x768
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe A, disabling
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 2, disabling
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 3, disabling
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 4, disabling
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe B, disabling
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 1, disabling
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 2, disabling
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 3, disabling
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 4, disabling
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe C, disabling
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 1, disabling
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 2, disabling
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 3, disabling
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 4, disabling
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe D, disabling
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe D, disabling
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 2, disabling
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 3, disabling
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 4, disabling
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: }
> >>> (kms_pipe_crc_basic:1638) igt-debugfs-DEBUG: Opening debugfs directory '/sys/kernel/debug/dri/0'
> >>> (kms_pipe_crc_basic:1638) igt-debugfs-DEBUG: Opening debugfs directory '/sys/kernel/debug/dri/0'
> >>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Test assertion failure function igt_pipe_crc_start, file igt_debugfs.c:764:
> >>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Failed assertion: pipe_crc->crc_fd != -1
> >>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Last errno: 5, Input/output error
> >>> (kms_pipe_crc_basic:1638) igt-core-INFO: Stack trace:
> >>> ****  END  ****
> >>> Subtest read-crc-pipe-A: FAIL (0.061s)
> >>>
> >>> I think the answer is no, but I don't think it's the fault of this patch
> >>> series. Opening the CRC data file returns -EIO because the CRTC is not active,
> >>> and I'm trying to find out why that is the case. The debug log shows a commit
> >>> that seems strange to me, enabling pipe A and immediately disabling right
> >>> afterwards. After some investigation I believe that this is caused by sharing
> >>> primary planes between CRTCs.
> >>>
> >>> The R-Car DU groups CRTCs by two and shares 5 planes between the two CRTCs of
> >>> the group. This specific SoC has two groups of two CRTCs, but that's not
> >>> relevant here, so we can ignore pipes C and D.
> >>>
> >>> Pipes A and B thus shared 5 planes that I will number 0 to 4 for simplicity.
> >>> The driver sets plane 0 as the primary plane for CRTC A and plane 1 as the
> >>> primary plane for CRTC B. Planes 2, 3 and 4 are created as overlay planes.
> >>>
> >>> When igt iterates over all planes for pipe A, it will first encounter plane 0
> >>> that has a framebuffer, and thus enables the pipe. It then iterates over
> >>> plane 1, recognizes it as a primary plane without a framebuffer, and thus
> >>> disables the pipe. Planes 2, 3 and 4 are recognized as overlay planes and thus
> >>> don't affect the pipe active state. Pipe B is handled the same way, and igt
> >>> disables it twice as planes 0 and 1 are primary.
> >>>
> >>> I don't know if the fault here is with igt that doesn't properly support this
> >>> architecture, or with the driver that shouldn't have two primary planes
> >>> available for a CRTC. In the former case, I'm not sure how to fix it, as I'm
> >>> not familiar enough with igt to rearchitecture the commit helpers. In the
> >>> latter case, how would you recommend fixing it on the driver side ?
> >> I guess thus far no one did run igt on a chip which did have reassignable
> >> primary planes. The problem here is that it's pretty hard to figure out
> >> which one is the real primary plane, since with possible CRTCs you could
> >> have multiple primary planes on 1 CRTC. There's no property or anything
> >> that explicitly tells you this. Two fixes:
> >>
> >> 1. Change drivers to limit primary planes to 1 crtc. Same for cursor
> >>    overlays. There's probably other userspace than igt that gets confused
> >>    by this, but this has the ugly downside that we artifically limit plane
> >>    usage - if only 1 CRTC is on, we want to use all the available planes
> >>    on that one.
> >>
> >> 2. Add some implicit or explicit uapi to allow userspace to figure out
> >>    which primary plane is the primary plane for this crtc.
> >>
> >>    a) Explicit option: We add a PRIMARY_ID property (and CURSOR_ID prop
> >>       while at it) on the CRTC which points at the primary/cursor plane.
> >>
> >>    b) Implicit option: We require primary planes are assigned to CRTC in the
> >>       same order as they're created. So first primary plane you encouter
> >>       is the one for the first CRTC, 2nd primary plane is the one for the
> >>       2nd CRTC and so on. If we go with this we probably should add a bit
> >>       of code to the kernel to check that invariant (by making sure the
> >>       primary plane has the corresponding CRTC included in its
> >>       possible_crtc mask).
> >>
> >> Either way igt needs to be patched to not treat any primary plane that
> >> could work on a CRTC as the primary plane for that CRTC.
> >>
> >> Personally I'm leaning towards 2b).
> > Adding Maarten and igt-dev.
> 
> We should first make the plane array global, instead of per crtc.
> 
> That means removing plane->pipe and plane->index.
> 
> And pipe_obj->planes and pipe_obj->n_planes need to be gone too. I think it's
> easiest to make
> 
> There is one problem. Most of the tests are not aware of the limitations.
> If we make the plane array global it should be possible to make
> a for_each_possible_plane_on_pipe enumerate all planes that could be assigned
> to a certain pipe. We need to sort by z order somehow, but if we then add
> igt_plane_set_pipe() which updates the IGT_PLANE_CRTC_ID property, we should
> be good.
> 
> Only thing we don't see is how the default crtc->primary and crtc->cursor are
> assigned. For the calls with COMMIT_LEGACY we need to know the mappings, but
> I don't think the kernel exposes them?
> I guess we could put it in a FIFO way, first enumerated plane with PRIMARY type
> is bound to the first crtc, same for cursor.

Solutions for that problem is what I proposed in my mail, since atm the
kernel is indeed not exposing that in any fasion.

> This will hopefully allow legacy tests to keep working, while atomic plane aware
> tests will be able to use all planes.

Yeah ..
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

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

* Re: igt trouble with planes shared between multiple CRTCs (Re: [PATCH v2 0/8] R-Car DU: Support CRC calculation)
@ 2018-05-02  7:32           ` Daniel Vetter
  0 siblings, 0 replies; 82+ messages in thread
From: Daniel Vetter @ 2018-05-02  7:32 UTC (permalink / raw)
  To: Maarten Lankhorst
  Cc: IGT development, Kieran Bingham, dri-devel, linux-renesas-soc,
	Laurent Pinchart, Ulrich Hecht

On Tue, May 01, 2018 at 10:58:02AM +0200, Maarten Lankhorst wrote:
> Hey,
> 
> Op 30-04-18 om 16:56 schreef Daniel Vetter:
> > On Mon, Apr 30, 2018 at 04:55:24PM +0200, Daniel Vetter wrote:
> >> On Sat, Apr 28, 2018 at 12:07:04AM +0300, Laurent Pinchart wrote:
> >>> Hi Daniel,
> >>>
> >>> (Removing the linux-media mailing list from CC as it is out of scope)
> >>>
> >>> You enquired on IRC whether this patch series passes the igt CRC tests.
> >>>
> >>> # ./kms_pipe_crc_basic --run-subtest read-crc-pipe-A
> >>> IGT-Version: 1.22-gf447f5fc531d (aarch64) (Linux: 4.17.0-rc1-00085-g56e849d93cc9 aarch64)
> >>> read-crc-pipe-A: Testing connector LVDS-1 using pipe A
> >>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Test assertion failure function igt_pipe_crc_start, file igt_debugfs.c:764:
> >>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Failed assertion: pipe_crc->crc_fd != -1
> >>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Last errno: 5, Input/output error
> >>> Stack trace:
> >>> Subtest read-crc-pipe-A failed.
> >>> **** DEBUG ****
> >>> (kms_pipe_crc_basic:1638) DEBUG: Test requirement passed: !(pipe >= data->display.n_pipes)
> >>> (kms_pipe_crc_basic:1638) INFO: read-crc-pipe-A: Testing connector LVDS-1 using pipe A
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: LVDS-1: set_pipe(A)
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: LVDS-1: Selecting pipe A
> >>> (kms_pipe_crc_basic:1638) DEBUG: Clearing the fb with color (0.00,1.00,0.00)
> >>> (kms_pipe_crc_basic:1638) igt-fb-DEBUG: igt_create_fb_with_bo_size(width=1024, height=768, format=0x34325258, tiling=0x0, size=0)
> >>> (kms_pipe_crc_basic:1638) igt-fb-DEBUG: igt_create_fb_with_bo_size(handle=1, pitch=4096)
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: Test requirement passed: plane_idx >= 0 && plane_idx < pipe->n_planes
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: plane_set_fb(140)
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: plane_set_size (1024x768)
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: fb_set_position(0,0)
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: fb_set_size(1024x768)
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: commit {
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     LVDS-1: SetCrtc pipe A, fb 140, src (0, 0), mode 1024x768
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe A, disabling
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 2, disabling
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 3, disabling
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 4, disabling
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe B, disabling
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 1, disabling
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 2, disabling
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 3, disabling
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 4, disabling
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe C, disabling
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 1, disabling
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 2, disabling
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 3, disabling
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 4, disabling
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe D, disabling
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe D, disabling
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 2, disabling
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 3, disabling
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 4, disabling
> >>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: }
> >>> (kms_pipe_crc_basic:1638) igt-debugfs-DEBUG: Opening debugfs directory '/sys/kernel/debug/dri/0'
> >>> (kms_pipe_crc_basic:1638) igt-debugfs-DEBUG: Opening debugfs directory '/sys/kernel/debug/dri/0'
> >>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Test assertion failure function igt_pipe_crc_start, file igt_debugfs.c:764:
> >>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Failed assertion: pipe_crc->crc_fd != -1
> >>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Last errno: 5, Input/output error
> >>> (kms_pipe_crc_basic:1638) igt-core-INFO: Stack trace:
> >>> ****  END  ****
> >>> Subtest read-crc-pipe-A: FAIL (0.061s)
> >>>
> >>> I think the answer is no, but I don't think it's the fault of this patch
> >>> series. Opening the CRC data file returns -EIO because the CRTC is not active,
> >>> and I'm trying to find out why that is the case. The debug log shows a commit
> >>> that seems strange to me, enabling pipe A and immediately disabling right
> >>> afterwards. After some investigation I believe that this is caused by sharing
> >>> primary planes between CRTCs.
> >>>
> >>> The R-Car DU groups CRTCs by two and shares 5 planes between the two CRTCs of
> >>> the group. This specific SoC has two groups of two CRTCs, but that's not
> >>> relevant here, so we can ignore pipes C and D.
> >>>
> >>> Pipes A and B thus shared 5 planes that I will number 0 to 4 for simplicity.
> >>> The driver sets plane 0 as the primary plane for CRTC A and plane 1 as the
> >>> primary plane for CRTC B. Planes 2, 3 and 4 are created as overlay planes.
> >>>
> >>> When igt iterates over all planes for pipe A, it will first encounter plane 0
> >>> that has a framebuffer, and thus enables the pipe. It then iterates over
> >>> plane 1, recognizes it as a primary plane without a framebuffer, and thus
> >>> disables the pipe. Planes 2, 3 and 4 are recognized as overlay planes and thus
> >>> don't affect the pipe active state. Pipe B is handled the same way, and igt
> >>> disables it twice as planes 0 and 1 are primary.
> >>>
> >>> I don't know if the fault here is with igt that doesn't properly support this
> >>> architecture, or with the driver that shouldn't have two primary planes
> >>> available for a CRTC. In the former case, I'm not sure how to fix it, as I'm
> >>> not familiar enough with igt to rearchitecture the commit helpers. In the
> >>> latter case, how would you recommend fixing it on the driver side ?
> >> I guess thus far no one did run igt on a chip which did have reassignable
> >> primary planes. The problem here is that it's pretty hard to figure out
> >> which one is the real primary plane, since with possible CRTCs you could
> >> have multiple primary planes on 1 CRTC. There's no property or anything
> >> that explicitly tells you this. Two fixes:
> >>
> >> 1. Change drivers to limit primary planes to 1 crtc. Same for cursor
> >>    overlays. There's probably other userspace than igt that gets confused
> >>    by this, but this has the ugly downside that we artifically limit plane
> >>    usage - if only 1 CRTC is on, we want to use all the available planes
> >>    on that one.
> >>
> >> 2. Add some implicit or explicit uapi to allow userspace to figure out
> >>    which primary plane is the primary plane for this crtc.
> >>
> >>    a) Explicit option: We add a PRIMARY_ID property (and CURSOR_ID prop
> >>       while at it) on the CRTC which points at the primary/cursor plane.
> >>
> >>    b) Implicit option: We require primary planes are assigned to CRTC in the
> >>       same order as they're created. So first primary plane you encouter
> >>       is the one for the first CRTC, 2nd primary plane is the one for the
> >>       2nd CRTC and so on. If we go with this we probably should add a bit
> >>       of code to the kernel to check that invariant (by making sure the
> >>       primary plane has the corresponding CRTC included in its
> >>       possible_crtc mask).
> >>
> >> Either way igt needs to be patched to not treat any primary plane that
> >> could work on a CRTC as the primary plane for that CRTC.
> >>
> >> Personally I'm leaning towards 2b).
> > Adding Maarten and igt-dev.
> 
> We should first make the plane array global, instead of per crtc.
> 
> That means removing plane->pipe and plane->index.
> 
> And pipe_obj->planes and pipe_obj->n_planes need to be gone too. I think it's
> easiest to make
> 
> There is one problem. Most of the tests are not aware of the limitations.
> If we make the plane array global it should be possible to make
> a for_each_possible_plane_on_pipe enumerate all planes that could be assigned
> to a certain pipe. We need to sort by z order somehow, but if we then add
> igt_plane_set_pipe() which updates the IGT_PLANE_CRTC_ID property, we should
> be good.
> 
> Only thing we don't see is how the default crtc->primary and crtc->cursor are
> assigned. For the calls with COMMIT_LEGACY we need to know the mappings, but
> I don't think the kernel exposes them?
> I guess we could put it in a FIFO way, first enumerated plane with PRIMARY type
> is bound to the first crtc, same for cursor.

Solutions for that problem is what I proposed in my mail, since atm the
kernel is indeed not exposing that in any fasion.

> This will hopefully allow legacy tests to keep working, while atomic plane aware
> tests will be able to use all planes.

Yeah ..
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: igt trouble with planes shared between multiple CRTCs (Re: [PATCH v2 0/8] R-Car DU: Support CRC calculation)
  2018-05-02  7:32           ` Daniel Vetter
  (?)
@ 2018-05-07 13:28             ` Maarten Lankhorst
  -1 siblings, 0 replies; 82+ messages in thread
From: Maarten Lankhorst @ 2018-05-07 13:28 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Laurent Pinchart, dri-devel, linux-renesas-soc, Kieran Bingham,
	Ulrich Hecht, IGT development

Op 02-05-18 om 09:32 schreef Daniel Vetter:
> On Tue, May 01, 2018 at 10:58:02AM +0200, Maarten Lankhorst wrote:
>> Hey,
>>
>> Op 30-04-18 om 16:56 schreef Daniel Vetter:
>>> On Mon, Apr 30, 2018 at 04:55:24PM +0200, Daniel Vetter wrote:
>>>> On Sat, Apr 28, 2018 at 12:07:04AM +0300, Laurent Pinchart wrote:
>>>>> Hi Daniel,
>>>>>
>>>>> (Removing the linux-media mailing list from CC as it is out of scope)
>>>>>
>>>>> You enquired on IRC whether this patch series passes the igt CRC tests.
>>>>>
>>>>> # ./kms_pipe_crc_basic --run-subtest read-crc-pipe-A
>>>>> IGT-Version: 1.22-gf447f5fc531d (aarch64) (Linux: 4.17.0-rc1-00085-g56e849d93cc9 aarch64)
>>>>> read-crc-pipe-A: Testing connector LVDS-1 using pipe A
>>>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Test assertion failure function igt_pipe_crc_start, file igt_debugfs.c:764:
>>>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Failed assertion: pipe_crc->crc_fd != -1
>>>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Last errno: 5, Input/output error
>>>>> Stack trace:
>>>>> Subtest read-crc-pipe-A failed.
>>>>> **** DEBUG ****
>>>>> (kms_pipe_crc_basic:1638) DEBUG: Test requirement passed: !(pipe >= data->display.n_pipes)
>>>>> (kms_pipe_crc_basic:1638) INFO: read-crc-pipe-A: Testing connector LVDS-1 using pipe A
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: LVDS-1: set_pipe(A)
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: LVDS-1: Selecting pipe A
>>>>> (kms_pipe_crc_basic:1638) DEBUG: Clearing the fb with color (0.00,1.00,0.00)
>>>>> (kms_pipe_crc_basic:1638) igt-fb-DEBUG: igt_create_fb_with_bo_size(width=1024, height=768, format=0x34325258, tiling=0x0, size=0)
>>>>> (kms_pipe_crc_basic:1638) igt-fb-DEBUG: igt_create_fb_with_bo_size(handle=1, pitch=4096)
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: Test requirement passed: plane_idx >= 0 && plane_idx < pipe->n_planes
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: plane_set_fb(140)
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: plane_set_size (1024x768)
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: fb_set_position(0,0)
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: fb_set_size(1024x768)
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: commit {
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     LVDS-1: SetCrtc pipe A, fb 140, src (0, 0), mode 1024x768
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe A, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 2, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 3, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 4, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe B, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 1, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 2, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 3, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 4, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe C, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 1, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 2, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 3, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 4, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe D, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe D, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 2, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 3, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 4, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: }
>>>>> (kms_pipe_crc_basic:1638) igt-debugfs-DEBUG: Opening debugfs directory '/sys/kernel/debug/dri/0'
>>>>> (kms_pipe_crc_basic:1638) igt-debugfs-DEBUG: Opening debugfs directory '/sys/kernel/debug/dri/0'
>>>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Test assertion failure function igt_pipe_crc_start, file igt_debugfs.c:764:
>>>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Failed assertion: pipe_crc->crc_fd != -1
>>>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Last errno: 5, Input/output error
>>>>> (kms_pipe_crc_basic:1638) igt-core-INFO: Stack trace:
>>>>> ****  END  ****
>>>>> Subtest read-crc-pipe-A: FAIL (0.061s)
>>>>>
>>>>> I think the answer is no, but I don't think it's the fault of this patch
>>>>> series. Opening the CRC data file returns -EIO because the CRTC is not active,
>>>>> and I'm trying to find out why that is the case. The debug log shows a commit
>>>>> that seems strange to me, enabling pipe A and immediately disabling right
>>>>> afterwards. After some investigation I believe that this is caused by sharing
>>>>> primary planes between CRTCs.
>>>>>
>>>>> The R-Car DU groups CRTCs by two and shares 5 planes between the two CRTCs of
>>>>> the group. This specific SoC has two groups of two CRTCs, but that's not
>>>>> relevant here, so we can ignore pipes C and D.
>>>>>
>>>>> Pipes A and B thus shared 5 planes that I will number 0 to 4 for simplicity.
>>>>> The driver sets plane 0 as the primary plane for CRTC A and plane 1 as the
>>>>> primary plane for CRTC B. Planes 2, 3 and 4 are created as overlay planes.
>>>>>
>>>>> When igt iterates over all planes for pipe A, it will first encounter plane 0
>>>>> that has a framebuffer, and thus enables the pipe. It then iterates over
>>>>> plane 1, recognizes it as a primary plane without a framebuffer, and thus
>>>>> disables the pipe. Planes 2, 3 and 4 are recognized as overlay planes and thus
>>>>> don't affect the pipe active state. Pipe B is handled the same way, and igt
>>>>> disables it twice as planes 0 and 1 are primary.
>>>>>
>>>>> I don't know if the fault here is with igt that doesn't properly support this
>>>>> architecture, or with the driver that shouldn't have two primary planes
>>>>> available for a CRTC. In the former case, I'm not sure how to fix it, as I'm
>>>>> not familiar enough with igt to rearchitecture the commit helpers. In the
>>>>> latter case, how would you recommend fixing it on the driver side ?
>>>> I guess thus far no one did run igt on a chip which did have reassignable
>>>> primary planes. The problem here is that it's pretty hard to figure out
>>>> which one is the real primary plane, since with possible CRTCs you could
>>>> have multiple primary planes on 1 CRTC. There's no property or anything
>>>> that explicitly tells you this. Two fixes:
>>>>
>>>> 1. Change drivers to limit primary planes to 1 crtc. Same for cursor
>>>>    overlays. There's probably other userspace than igt that gets confused
>>>>    by this, but this has the ugly downside that we artifically limit plane
>>>>    usage - if only 1 CRTC is on, we want to use all the available planes
>>>>    on that one.
>>>>
>>>> 2. Add some implicit or explicit uapi to allow userspace to figure out
>>>>    which primary plane is the primary plane for this crtc.
>>>>
>>>>    a) Explicit option: We add a PRIMARY_ID property (and CURSOR_ID prop
>>>>       while at it) on the CRTC which points at the primary/cursor plane.
>>>>
>>>>    b) Implicit option: We require primary planes are assigned to CRTC in the
>>>>       same order as they're created. So first primary plane you encouter
>>>>       is the one for the first CRTC, 2nd primary plane is the one for the
>>>>       2nd CRTC and so on. If we go with this we probably should add a bit
>>>>       of code to the kernel to check that invariant (by making sure the
>>>>       primary plane has the corresponding CRTC included in its
>>>>       possible_crtc mask).
>>>>
>>>> Either way igt needs to be patched to not treat any primary plane that
>>>> could work on a CRTC as the primary plane for that CRTC.
>>>>
>>>> Personally I'm leaning towards 2b).
>>> Adding Maarten and igt-dev.
>> We should first make the plane array global, instead of per crtc.
>>
>> That means removing plane->pipe and plane->index.
>>
>> And pipe_obj->planes and pipe_obj->n_planes need to be gone too. I think it's
>> easiest to make
>>
>> There is one problem. Most of the tests are not aware of the limitations.
>> If we make the plane array global it should be possible to make
>> a for_each_possible_plane_on_pipe enumerate all planes that could be assigned
>> to a certain pipe. We need to sort by z order somehow, but if we then add
>> igt_plane_set_pipe() which updates the IGT_PLANE_CRTC_ID property, we should
>> be good.
>>
>> Only thing we don't see is how the default crtc->primary and crtc->cursor are
>> assigned. For the calls with COMMIT_LEGACY we need to know the mappings, but
>> I don't think the kernel exposes them?
>> I guess we could put it in a FIFO way, first enumerated plane with PRIMARY type
>> is bound to the first crtc, same for cursor.
> Solutions for that problem is what I proposed in my mail, since atm the
> kernel is indeed not exposing that in any fasion.
>
>> This will hopefully allow legacy tests to keep working, while atomic plane aware
>> tests will be able to use all planes.
> Yeah ..
> -Daniel

For reference: https://patchwork.freedesktop.org/series/42814/

The part where planes are reassigned isn't done yet, but that will depend on the final kernel api.

~Maarten

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

* Re: igt trouble with planes shared between multiple CRTCs (Re: [PATCH v2 0/8] R-Car DU: Support CRC calculation)
@ 2018-05-07 13:28             ` Maarten Lankhorst
  0 siblings, 0 replies; 82+ messages in thread
From: Maarten Lankhorst @ 2018-05-07 13:28 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: IGT development, Kieran Bingham, dri-devel, linux-renesas-soc,
	Laurent Pinchart, Ulrich Hecht

Op 02-05-18 om 09:32 schreef Daniel Vetter:
> On Tue, May 01, 2018 at 10:58:02AM +0200, Maarten Lankhorst wrote:
>> Hey,
>>
>> Op 30-04-18 om 16:56 schreef Daniel Vetter:
>>> On Mon, Apr 30, 2018 at 04:55:24PM +0200, Daniel Vetter wrote:
>>>> On Sat, Apr 28, 2018 at 12:07:04AM +0300, Laurent Pinchart wrote:
>>>>> Hi Daniel,
>>>>>
>>>>> (Removing the linux-media mailing list from CC as it is out of scope)
>>>>>
>>>>> You enquired on IRC whether this patch series passes the igt CRC tests.
>>>>>
>>>>> # ./kms_pipe_crc_basic --run-subtest read-crc-pipe-A
>>>>> IGT-Version: 1.22-gf447f5fc531d (aarch64) (Linux: 4.17.0-rc1-00085-g56e849d93cc9 aarch64)
>>>>> read-crc-pipe-A: Testing connector LVDS-1 using pipe A
>>>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Test assertion failure function igt_pipe_crc_start, file igt_debugfs.c:764:
>>>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Failed assertion: pipe_crc->crc_fd != -1
>>>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Last errno: 5, Input/output error
>>>>> Stack trace:
>>>>> Subtest read-crc-pipe-A failed.
>>>>> **** DEBUG ****
>>>>> (kms_pipe_crc_basic:1638) DEBUG: Test requirement passed: !(pipe >= data->display.n_pipes)
>>>>> (kms_pipe_crc_basic:1638) INFO: read-crc-pipe-A: Testing connector LVDS-1 using pipe A
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: LVDS-1: set_pipe(A)
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: LVDS-1: Selecting pipe A
>>>>> (kms_pipe_crc_basic:1638) DEBUG: Clearing the fb with color (0.00,1.00,0.00)
>>>>> (kms_pipe_crc_basic:1638) igt-fb-DEBUG: igt_create_fb_with_bo_size(width=1024, height=768, format=0x34325258, tiling=0x0, size=0)
>>>>> (kms_pipe_crc_basic:1638) igt-fb-DEBUG: igt_create_fb_with_bo_size(handle=1, pitch=4096)
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: Test requirement passed: plane_idx >= 0 && plane_idx < pipe->n_planes
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: plane_set_fb(140)
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: plane_set_size (1024x768)
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: fb_set_position(0,0)
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: fb_set_size(1024x768)
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: commit {
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     LVDS-1: SetCrtc pipe A, fb 140, src (0, 0), mode 1024x768
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe A, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 2, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 3, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 4, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe B, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 1, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 2, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 3, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 4, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe C, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 1, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 2, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 3, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 4, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe D, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe D, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 2, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 3, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 4, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: }
>>>>> (kms_pipe_crc_basic:1638) igt-debugfs-DEBUG: Opening debugfs directory '/sys/kernel/debug/dri/0'
>>>>> (kms_pipe_crc_basic:1638) igt-debugfs-DEBUG: Opening debugfs directory '/sys/kernel/debug/dri/0'
>>>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Test assertion failure function igt_pipe_crc_start, file igt_debugfs.c:764:
>>>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Failed assertion: pipe_crc->crc_fd != -1
>>>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Last errno: 5, Input/output error
>>>>> (kms_pipe_crc_basic:1638) igt-core-INFO: Stack trace:
>>>>> ****  END  ****
>>>>> Subtest read-crc-pipe-A: FAIL (0.061s)
>>>>>
>>>>> I think the answer is no, but I don't think it's the fault of this patch
>>>>> series. Opening the CRC data file returns -EIO because the CRTC is not active,
>>>>> and I'm trying to find out why that is the case. The debug log shows a commit
>>>>> that seems strange to me, enabling pipe A and immediately disabling right
>>>>> afterwards. After some investigation I believe that this is caused by sharing
>>>>> primary planes between CRTCs.
>>>>>
>>>>> The R-Car DU groups CRTCs by two and shares 5 planes between the two CRTCs of
>>>>> the group. This specific SoC has two groups of two CRTCs, but that's not
>>>>> relevant here, so we can ignore pipes C and D.
>>>>>
>>>>> Pipes A and B thus shared 5 planes that I will number 0 to 4 for simplicity.
>>>>> The driver sets plane 0 as the primary plane for CRTC A and plane 1 as the
>>>>> primary plane for CRTC B. Planes 2, 3 and 4 are created as overlay planes.
>>>>>
>>>>> When igt iterates over all planes for pipe A, it will first encounter plane 0
>>>>> that has a framebuffer, and thus enables the pipe. It then iterates over
>>>>> plane 1, recognizes it as a primary plane without a framebuffer, and thus
>>>>> disables the pipe. Planes 2, 3 and 4 are recognized as overlay planes and thus
>>>>> don't affect the pipe active state. Pipe B is handled the same way, and igt
>>>>> disables it twice as planes 0 and 1 are primary.
>>>>>
>>>>> I don't know if the fault here is with igt that doesn't properly support this
>>>>> architecture, or with the driver that shouldn't have two primary planes
>>>>> available for a CRTC. In the former case, I'm not sure how to fix it, as I'm
>>>>> not familiar enough with igt to rearchitecture the commit helpers. In the
>>>>> latter case, how would you recommend fixing it on the driver side ?
>>>> I guess thus far no one did run igt on a chip which did have reassignable
>>>> primary planes. The problem here is that it's pretty hard to figure out
>>>> which one is the real primary plane, since with possible CRTCs you could
>>>> have multiple primary planes on 1 CRTC. There's no property or anything
>>>> that explicitly tells you this. Two fixes:
>>>>
>>>> 1. Change drivers to limit primary planes to 1 crtc. Same for cursor
>>>>    overlays. There's probably other userspace than igt that gets confused
>>>>    by this, but this has the ugly downside that we artifically limit plane
>>>>    usage - if only 1 CRTC is on, we want to use all the available planes
>>>>    on that one.
>>>>
>>>> 2. Add some implicit or explicit uapi to allow userspace to figure out
>>>>    which primary plane is the primary plane for this crtc.
>>>>
>>>>    a) Explicit option: We add a PRIMARY_ID property (and CURSOR_ID prop
>>>>       while at it) on the CRTC which points at the primary/cursor plane.
>>>>
>>>>    b) Implicit option: We require primary planes are assigned to CRTC in the
>>>>       same order as they're created. So first primary plane you encouter
>>>>       is the one for the first CRTC, 2nd primary plane is the one for the
>>>>       2nd CRTC and so on. If we go with this we probably should add a bit
>>>>       of code to the kernel to check that invariant (by making sure the
>>>>       primary plane has the corresponding CRTC included in its
>>>>       possible_crtc mask).
>>>>
>>>> Either way igt needs to be patched to not treat any primary plane that
>>>> could work on a CRTC as the primary plane for that CRTC.
>>>>
>>>> Personally I'm leaning towards 2b).
>>> Adding Maarten and igt-dev.
>> We should first make the plane array global, instead of per crtc.
>>
>> That means removing plane->pipe and plane->index.
>>
>> And pipe_obj->planes and pipe_obj->n_planes need to be gone too. I think it's
>> easiest to make
>>
>> There is one problem. Most of the tests are not aware of the limitations.
>> If we make the plane array global it should be possible to make
>> a for_each_possible_plane_on_pipe enumerate all planes that could be assigned
>> to a certain pipe. We need to sort by z order somehow, but if we then add
>> igt_plane_set_pipe() which updates the IGT_PLANE_CRTC_ID property, we should
>> be good.
>>
>> Only thing we don't see is how the default crtc->primary and crtc->cursor are
>> assigned. For the calls with COMMIT_LEGACY we need to know the mappings, but
>> I don't think the kernel exposes them?
>> I guess we could put it in a FIFO way, first enumerated plane with PRIMARY type
>> is bound to the first crtc, same for cursor.
> Solutions for that problem is what I proposed in my mail, since atm the
> kernel is indeed not exposing that in any fasion.
>
>> This will hopefully allow legacy tests to keep working, while atomic plane aware
>> tests will be able to use all planes.
> Yeah ..
> -Daniel

For reference: https://patchwork.freedesktop.org/series/42814/

The part where planes are reassigned isn't done yet, but that will depend on the final kernel api.

~Maarten

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

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

* Re: [igt-dev] igt trouble with planes shared between multiple CRTCs (Re: [PATCH v2 0/8] R-Car DU: Support CRC calculation)
@ 2018-05-07 13:28             ` Maarten Lankhorst
  0 siblings, 0 replies; 82+ messages in thread
From: Maarten Lankhorst @ 2018-05-07 13:28 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: IGT development, Kieran Bingham, dri-devel, linux-renesas-soc,
	Laurent Pinchart

Op 02-05-18 om 09:32 schreef Daniel Vetter:
> On Tue, May 01, 2018 at 10:58:02AM +0200, Maarten Lankhorst wrote:
>> Hey,
>>
>> Op 30-04-18 om 16:56 schreef Daniel Vetter:
>>> On Mon, Apr 30, 2018 at 04:55:24PM +0200, Daniel Vetter wrote:
>>>> On Sat, Apr 28, 2018 at 12:07:04AM +0300, Laurent Pinchart wrote:
>>>>> Hi Daniel,
>>>>>
>>>>> (Removing the linux-media mailing list from CC as it is out of scope)
>>>>>
>>>>> You enquired on IRC whether this patch series passes the igt CRC tests.
>>>>>
>>>>> # ./kms_pipe_crc_basic --run-subtest read-crc-pipe-A
>>>>> IGT-Version: 1.22-gf447f5fc531d (aarch64) (Linux: 4.17.0-rc1-00085-g56e849d93cc9 aarch64)
>>>>> read-crc-pipe-A: Testing connector LVDS-1 using pipe A
>>>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Test assertion failure function igt_pipe_crc_start, file igt_debugfs.c:764:
>>>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Failed assertion: pipe_crc->crc_fd != -1
>>>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Last errno: 5, Input/output error
>>>>> Stack trace:
>>>>> Subtest read-crc-pipe-A failed.
>>>>> **** DEBUG ****
>>>>> (kms_pipe_crc_basic:1638) DEBUG: Test requirement passed: !(pipe >= data->display.n_pipes)
>>>>> (kms_pipe_crc_basic:1638) INFO: read-crc-pipe-A: Testing connector LVDS-1 using pipe A
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: LVDS-1: set_pipe(A)
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: LVDS-1: Selecting pipe A
>>>>> (kms_pipe_crc_basic:1638) DEBUG: Clearing the fb with color (0.00,1.00,0.00)
>>>>> (kms_pipe_crc_basic:1638) igt-fb-DEBUG: igt_create_fb_with_bo_size(width=1024, height=768, format=0x34325258, tiling=0x0, size=0)
>>>>> (kms_pipe_crc_basic:1638) igt-fb-DEBUG: igt_create_fb_with_bo_size(handle=1, pitch=4096)
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: Test requirement passed: plane_idx >= 0 && plane_idx < pipe->n_planes
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: plane_set_fb(140)
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: plane_set_size (1024x768)
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: fb_set_position(0,0)
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: A.0: fb_set_size(1024x768)
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: commit {
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     LVDS-1: SetCrtc pipe A, fb 140, src (0, 0), mode 1024x768
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe A, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 2, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 3, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe A, plane 4, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe B, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 1, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 2, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 3, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe B, plane 4, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe C, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 1, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 2, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 3, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe C, plane 4, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe D, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetCrtc pipe D, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 2, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 3, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display:     SetPlane pipe D, plane 4, disabling
>>>>> (kms_pipe_crc_basic:1638) igt-kms-DEBUG: display: }
>>>>> (kms_pipe_crc_basic:1638) igt-debugfs-DEBUG: Opening debugfs directory '/sys/kernel/debug/dri/0'
>>>>> (kms_pipe_crc_basic:1638) igt-debugfs-DEBUG: Opening debugfs directory '/sys/kernel/debug/dri/0'
>>>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Test assertion failure function igt_pipe_crc_start, file igt_debugfs.c:764:
>>>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Failed assertion: pipe_crc->crc_fd != -1
>>>>> (kms_pipe_crc_basic:1638) igt-debugfs-CRITICAL: Last errno: 5, Input/output error
>>>>> (kms_pipe_crc_basic:1638) igt-core-INFO: Stack trace:
>>>>> ****  END  ****
>>>>> Subtest read-crc-pipe-A: FAIL (0.061s)
>>>>>
>>>>> I think the answer is no, but I don't think it's the fault of this patch
>>>>> series. Opening the CRC data file returns -EIO because the CRTC is not active,
>>>>> and I'm trying to find out why that is the case. The debug log shows a commit
>>>>> that seems strange to me, enabling pipe A and immediately disabling right
>>>>> afterwards. After some investigation I believe that this is caused by sharing
>>>>> primary planes between CRTCs.
>>>>>
>>>>> The R-Car DU groups CRTCs by two and shares 5 planes between the two CRTCs of
>>>>> the group. This specific SoC has two groups of two CRTCs, but that's not
>>>>> relevant here, so we can ignore pipes C and D.
>>>>>
>>>>> Pipes A and B thus shared 5 planes that I will number 0 to 4 for simplicity.
>>>>> The driver sets plane 0 as the primary plane for CRTC A and plane 1 as the
>>>>> primary plane for CRTC B. Planes 2, 3 and 4 are created as overlay planes.
>>>>>
>>>>> When igt iterates over all planes for pipe A, it will first encounter plane 0
>>>>> that has a framebuffer, and thus enables the pipe. It then iterates over
>>>>> plane 1, recognizes it as a primary plane without a framebuffer, and thus
>>>>> disables the pipe. Planes 2, 3 and 4 are recognized as overlay planes and thus
>>>>> don't affect the pipe active state. Pipe B is handled the same way, and igt
>>>>> disables it twice as planes 0 and 1 are primary.
>>>>>
>>>>> I don't know if the fault here is with igt that doesn't properly support this
>>>>> architecture, or with the driver that shouldn't have two primary planes
>>>>> available for a CRTC. In the former case, I'm not sure how to fix it, as I'm
>>>>> not familiar enough with igt to rearchitecture the commit helpers. In the
>>>>> latter case, how would you recommend fixing it on the driver side ?
>>>> I guess thus far no one did run igt on a chip which did have reassignable
>>>> primary planes. The problem here is that it's pretty hard to figure out
>>>> which one is the real primary plane, since with possible CRTCs you could
>>>> have multiple primary planes on 1 CRTC. There's no property or anything
>>>> that explicitly tells you this. Two fixes:
>>>>
>>>> 1. Change drivers to limit primary planes to 1 crtc. Same for cursor
>>>>    overlays. There's probably other userspace than igt that gets confused
>>>>    by this, but this has the ugly downside that we artifically limit plane
>>>>    usage - if only 1 CRTC is on, we want to use all the available planes
>>>>    on that one.
>>>>
>>>> 2. Add some implicit or explicit uapi to allow userspace to figure out
>>>>    which primary plane is the primary plane for this crtc.
>>>>
>>>>    a) Explicit option: We add a PRIMARY_ID property (and CURSOR_ID prop
>>>>       while at it) on the CRTC which points at the primary/cursor plane.
>>>>
>>>>    b) Implicit option: We require primary planes are assigned to CRTC in the
>>>>       same order as they're created. So first primary plane you encouter
>>>>       is the one for the first CRTC, 2nd primary plane is the one for the
>>>>       2nd CRTC and so on. If we go with this we probably should add a bit
>>>>       of code to the kernel to check that invariant (by making sure the
>>>>       primary plane has the corresponding CRTC included in its
>>>>       possible_crtc mask).
>>>>
>>>> Either way igt needs to be patched to not treat any primary plane that
>>>> could work on a CRTC as the primary plane for that CRTC.
>>>>
>>>> Personally I'm leaning towards 2b).
>>> Adding Maarten and igt-dev.
>> We should first make the plane array global, instead of per crtc.
>>
>> That means removing plane->pipe and plane->index.
>>
>> And pipe_obj->planes and pipe_obj->n_planes need to be gone too. I think it's
>> easiest to make
>>
>> There is one problem. Most of the tests are not aware of the limitations.
>> If we make the plane array global it should be possible to make
>> a for_each_possible_plane_on_pipe enumerate all planes that could be assigned
>> to a certain pipe. We need to sort by z order somehow, but if we then add
>> igt_plane_set_pipe() which updates the IGT_PLANE_CRTC_ID property, we should
>> be good.
>>
>> Only thing we don't see is how the default crtc->primary and crtc->cursor are
>> assigned. For the calls with COMMIT_LEGACY we need to know the mappings, but
>> I don't think the kernel exposes them?
>> I guess we could put it in a FIFO way, first enumerated plane with PRIMARY type
>> is bound to the first crtc, same for cursor.
> Solutions for that problem is what I proposed in my mail, since atm the
> kernel is indeed not exposing that in any fasion.
>
>> This will hopefully allow legacy tests to keep working, while atomic plane aware
>> tests will be able to use all planes.
> Yeah ..
> -Daniel

For reference: https://patchwork.freedesktop.org/series/42814/

The part where planes are reassigned isn't done yet, but that will depend on the final kernel api.

~Maarten

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

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

end of thread, other threads:[~2018-05-07 13:42 UTC | newest]

Thread overview: 82+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-04-22 22:34 [PATCH v2 0/8] R-Car DU: Support CRC calculation Laurent Pinchart
2018-04-22 22:34 ` Laurent Pinchart
2018-04-22 22:34 ` [PATCH v2 1/8] v4l: vsp1: Use SPDX license headers Laurent Pinchart
2018-04-22 22:34   ` Laurent Pinchart
2018-04-27 21:25   ` Kieran Bingham
2018-04-27 21:25     ` Kieran Bingham
2018-04-27 21:47     ` Laurent Pinchart
2018-04-27 21:47       ` Laurent Pinchart
2018-04-22 22:34 ` [PATCH v2 2/8] v4l: vsp1: Share the CLU, LIF and LUT set_fmt pad operation code Laurent Pinchart
2018-04-22 22:34   ` Laurent Pinchart
2018-04-28  9:50   ` jacopo mondi
2018-04-28  9:50     ` jacopo mondi
2018-04-28 16:07     ` Laurent Pinchart
2018-04-28 16:07       ` Laurent Pinchart
2018-04-28 17:16   ` Kieran Bingham
2018-04-28 17:16     ` Kieran Bingham
2018-04-28 17:25     ` Laurent Pinchart
2018-04-28 17:25       ` Laurent Pinchart
2018-04-28 17:30       ` Laurent Pinchart
2018-04-28 17:30         ` Laurent Pinchart
2018-04-28 17:32         ` Kieran Bingham
2018-04-28 17:32           ` Kieran Bingham
2018-04-22 22:34 ` [PATCH v2 3/8] v4l: vsp1: Reset the crop and compose rectangles in the set_fmt helper Laurent Pinchart
2018-04-22 22:34   ` Laurent Pinchart
2018-04-28  9:56   ` jacopo mondi
2018-04-28  9:56     ` jacopo mondi
2018-04-28 17:22   ` Kieran Bingham
2018-04-28 17:22     ` Kieran Bingham
2018-04-22 22:34 ` [PATCH v2 4/8] v4l: vsp1: Document the vsp1_du_atomic_config structure Laurent Pinchart
2018-04-22 22:34   ` Laurent Pinchart
2018-04-28 17:29   ` Kieran Bingham
2018-04-28 17:29     ` Kieran Bingham
2018-04-22 22:34 ` [PATCH v2 5/8] v4l: vsp1: Extend the DU API to support CRC computation Laurent Pinchart
2018-04-22 22:34   ` Laurent Pinchart
2018-04-28 10:03   ` jacopo mondi
2018-04-28 10:03     ` jacopo mondi
2018-04-28 16:19     ` Laurent Pinchart
2018-04-28 16:19       ` Laurent Pinchart
2018-04-28 17:48   ` Kieran Bingham
2018-04-28 17:48     ` Kieran Bingham
2018-04-22 22:34 ` [PATCH v2 6/8] v4l: vsp1: Add support for the DISCOM entity Laurent Pinchart
2018-04-22 22:34   ` Laurent Pinchart
2018-04-28 10:40   ` jacopo mondi
2018-04-28 10:40     ` jacopo mondi
2018-04-28 16:50     ` Laurent Pinchart
2018-04-28 16:50       ` Laurent Pinchart
2018-04-28 18:28   ` Kieran Bingham
2018-04-28 18:28     ` Kieran Bingham
2018-04-22 22:34 ` [PATCH v2 7/8] v4l: vsp1: Integrate DISCOM in display pipeline Laurent Pinchart
2018-04-22 22:34   ` Laurent Pinchart
2018-04-28 11:00   ` jacopo mondi
2018-04-28 11:00     ` jacopo mondi
2018-04-28 16:57     ` Laurent Pinchart
2018-04-28 16:57       ` Laurent Pinchart
2018-04-28 18:58   ` Kieran Bingham
2018-04-28 18:58     ` Kieran Bingham
2018-04-28 19:15     ` Laurent Pinchart
2018-04-28 19:15       ` Laurent Pinchart
2018-04-22 22:34 ` [PATCH v2 8/8] drm: rcar-du: Add support for CRC computation Laurent Pinchart
2018-04-22 22:34   ` Laurent Pinchart
2018-04-28 19:16   ` Kieran Bingham
2018-04-28 19:16     ` Kieran Bingham
2018-04-28 20:15     ` Laurent Pinchart
2018-04-28 20:15       ` Laurent Pinchart
2018-04-27 21:07 ` igt trouble with planes shared between multiple CRTCs (Re: [PATCH v2 0/8] R-Car DU: Support CRC calculation) Laurent Pinchart
2018-04-27 21:07   ` Laurent Pinchart
2018-04-30 14:55   ` Daniel Vetter
2018-04-30 14:55     ` Daniel Vetter
2018-04-30 14:56     ` Daniel Vetter
2018-04-30 14:56       ` [igt-dev] " Daniel Vetter
2018-04-30 14:56       ` Daniel Vetter
2018-05-01  8:58       ` Maarten Lankhorst
2018-05-01  8:58         ` [igt-dev] " Maarten Lankhorst
2018-05-01  8:58         ` Maarten Lankhorst
2018-05-01 15:47         ` Maarten Lankhorst
2018-05-01 15:47           ` [igt-dev] " Maarten Lankhorst
2018-05-01 15:47           ` Maarten Lankhorst
2018-05-02  7:32         ` Daniel Vetter
2018-05-02  7:32           ` Daniel Vetter
2018-05-07 13:28           ` Maarten Lankhorst
2018-05-07 13:28             ` [igt-dev] " Maarten Lankhorst
2018-05-07 13:28             ` Maarten Lankhorst

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.