All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC 00/13] R-Car: Enable lossy compression in VSP video pipelines
@ 2017-09-26 10:05 Laurent Pinchart
  2017-09-26 10:05 ` [RFC] [FW] bl2: plat: renesas: rcar: Enable all lossy decompression areas Laurent Pinchart
                   ` (14 more replies)
  0 siblings, 15 replies; 23+ messages in thread
From: Laurent Pinchart @ 2017-09-26 10:05 UTC (permalink / raw)
  To: linux-renesas-soc

Hello,

These patches are a proof-of-concept implementation of lossy compression and
decompression support for the VSP driver.

Patches for the whole stack are needed, in the ARM trusted firmware BL2, U-Boot
and the Linux kernel. For convenience, and because this is an RFC, I've included
them all in a single series.

The ARM trusted firmware and U-Boot patches are based on the Renesas firmware
v2.16.0, which contains

	git://github.com/renesas-rcar/arm-trusted-firmware.git#c040be5a757a945da75cf97d3a3e1db3a43168f9

	git://github.com/renesas-rcar/u-boot.git#rcar-3.5.0

The kernel patches are based on v4.14-rc2, which contains the following required
v4.14-rc1 regression fix.

commit 6d57339890c9a9dfcd4ba4f8931b911b962968e3
Author: Arnd Bergmann <arnd@arndb.de>
Date:   Fri Sep 15 17:08:16 2017 +0200

    dma-coherent: fix rmem_dma_device_init regression

The DT bindings and userspace APIs are really work in progress. In particular
allocation of lossy decompression memory (implemented in the VSP driver in
13/13) should probably not be specific to the VSP.

A preliminary test that exercices the compression and decompression is available
from

	git://git.ideasonboard.com/renesas/vsp-tests.git#fcnl

The test currently passes unconditionally without attempting to check whether
the results are correct.

Laurent Pinchart (13):
  dt-bindings: reserved-memory: Add binding for the Renesas lossy
    decompression area
  dt-bindings: media: renesas-fcp: Add a compatible string for VSPI FCP
  dt-bindings: media: renesas-fcp: Add memory-region property
  arm64: dts: renesas: Use renesas,fcpvi compatible string
  arm64: dts: r8a7795: Add lossy decompression reserved memory nodes
  arm64: dts: r8a7795: Reference the lossy memory region from the FCPss
  arm64: dts: r8a7795: Add dma-ranges property in the /soc node
  v4l: rcar-fcp: Check device revision at probe time
  v4l: rcar-fcp: Configure the number of outstanding read transactions
  v4l: rcar-fcp: Prepare driver API for FCNL support
  v4l: rcar-fcp: Support FCNL decompression
  v4l: vsp1: Add support for near-lossless compression (FCNL) in the WPF
  v4l: vsp1: Add support for near-lossless compression (FCNL) in the RPF

 .../devicetree/bindings/media/renesas,fcp.txt      |  10 +-
 .../renesas,lossy-decompression.txt                | 102 ++++++
 arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi       |   2 +-
 arch/arm64/boot/dts/renesas/r8a7795.dtsi           |  58 +++-
 arch/arm64/boot/dts/renesas/r8a7796.dtsi           |   2 +-
 drivers/media/platform/rcar-fcp.c                  | 358 ++++++++++++++++++++-
 drivers/media/platform/vsp1/vsp1.h                 |   1 +
 drivers/media/platform/vsp1/vsp1_drv.c             |  10 +-
 drivers/media/platform/vsp1/vsp1_pipe.c            |  57 ++--
 drivers/media/platform/vsp1/vsp1_pipe.h            |   2 +
 drivers/media/platform/vsp1/vsp1_regs.h            |   1 +
 drivers/media/platform/vsp1/vsp1_rwpf.c            |  50 +++
 drivers/media/platform/vsp1/vsp1_rwpf.h            |   1 +
 drivers/media/platform/vsp1/vsp1_video.c           |  22 +-
 drivers/media/platform/vsp1/vsp1_wpf.c             |  17 +-
 include/media/rcar-fcp.h                           |  14 +-
 16 files changed, 650 insertions(+), 57 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/reserved-memory/renesas,lossy-decompression.txt

-- 
Regards,

Laurent Pinchart

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

* [RFC] [FW] bl2: plat: renesas: rcar: Enable all lossy decompression areas
  2017-09-26 10:05 [RFC 00/13] R-Car: Enable lossy compression in VSP video pipelines Laurent Pinchart
@ 2017-09-26 10:05 ` Laurent Pinchart
  2017-09-26 10:05 ` [RFC] [U-BOOT] board: salvator-x: Add reserved lossy decompression areas to DT Laurent Pinchart
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: Laurent Pinchart @ 2017-09-26 10:05 UTC (permalink / raw)
  To: linux-renesas-soc

From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

Enable lossy decompression areas 1 and 2 with a memory region of 48MB
each to support the RGB32 and packed YUV formats.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 plat/renesas/rcar/bl2_rcar_setup.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/plat/renesas/rcar/bl2_rcar_setup.c b/plat/renesas/rcar/bl2_rcar_setup.c
index 716ec8aa1c66..5b31bda75039 100755
--- a/plat/renesas/rcar/bl2_rcar_setup.c
+++ b/plat/renesas/rcar/bl2_rcar_setup.c
@@ -277,16 +277,16 @@ struct entry_point_info *bl2_plat_get_bl31_ep_info(void)
 #define	LOSSY_ENA_DIS0			LOSSY_ENABLE
 
 /* Settings of Entry 1 */
-#define	LOSSY_ST_ADDR1			0x0U /* Undefined */
-#define	LOSSY_END_ADDR1			0x0U /* Undefined */
+#define	LOSSY_ST_ADDR1			(0x57000000U)
+#define	LOSSY_END_ADDR1			(0x5a000000U)
 #define	LOSSY_FMT1				LOSSY_FMT_ARGB8888
-#define	LOSSY_ENA_DIS1			LOSSY_DISABLE
+#define	LOSSY_ENA_DIS1			LOSSY_ENABLE
 
 /* Settings of Entry 2 */
-#define	LOSSY_ST_ADDR2			0x0U /* Undefined */
-#define	LOSSY_END_ADDR2			0x0U /* Undefined */
+#define	LOSSY_ST_ADDR2			(0x5a000000U)
+#define	LOSSY_END_ADDR2			(0x5d000000U)
 #define	LOSSY_FMT2				LOSSY_FMT_YUV422INTLV
-#define	LOSSY_ENA_DIS2			LOSSY_DISABLE
+#define	LOSSY_ENA_DIS2			LOSSY_ENABLE
 
 static void bl2_lossy_setting(uint32_t no, uint64_t start_addr, 
 	uint64_t end_addr, uint32_t format, uint32_t enable);
-- 
Regards,

Laurent Pinchart

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

* [RFC] [U-BOOT] board: salvator-x: Add reserved lossy decompression areas to DT
  2017-09-26 10:05 [RFC 00/13] R-Car: Enable lossy compression in VSP video pipelines Laurent Pinchart
  2017-09-26 10:05 ` [RFC] [FW] bl2: plat: renesas: rcar: Enable all lossy decompression areas Laurent Pinchart
@ 2017-09-26 10:05 ` Laurent Pinchart
  2017-09-26 10:05 ` [RFC 01/13] dt-bindings: reserved-memory: Add binding for the Renesas lossy decompression area Laurent Pinchart
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: Laurent Pinchart @ 2017-09-26 10:05 UTC (permalink / raw)
  To: linux-renesas-soc

From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

Lossy decompression memory areas can't be used as normal system memory
as reading from them will automatically perform lossy decompression.

The decompression areas are configured by the BL2 in registers that are
accessible from secure mode only, and thus can't be read by U-boot.
Fortunately BL2 stores a copy of these registers at a fixed address in
SRAM, where the values can be read.

Parse the SRAM registers copy to add all lossy decompression memory
areas to DT in reserved-memory nodes.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 board/renesas/salvator-x/salvator-x.c | 192 ++++++++++++++++++++++++++++++++++
 include/configs/rcar-gen3-common.h    |   1 +
 2 files changed, 193 insertions(+)

diff --git a/board/renesas/salvator-x/salvator-x.c b/board/renesas/salvator-x/salvator-x.c
index 8af0e1080022..0d052ba5ed88 100644
--- a/board/renesas/salvator-x/salvator-x.c
+++ b/board/renesas/salvator-x/salvator-x.c
@@ -25,6 +25,7 @@
 #include <asm/arch/sh_sdhi.h>
 #include <i2c.h>
 #include <mmc.h>
+#include <fdt_support.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -475,3 +476,194 @@ int checkboard(void)
 	return 0;
 }
 #endif
+
+#if defined(CONFIG_OF_BOARD_SETUP)
+struct bl2_lossy_info {
+	u32 magic;
+	u32 a0;
+	u32 b0;
+};
+
+#define BL2_LOSSY_INFO_ADDRESS		0x47fd7000
+#define BL2_LOSSY_INFO_ENTRIES		16
+#define BL2_LOSSY_INFO_MAGIC		0x12345678
+
+#define DCMPAREACRA_EN			(1UL << 31)
+#define DCMPAREACRA_FMT_GET(reg)	(((reg) >> 29) & 3)
+#define DCMPAREACRA_SADDR_MASK		(0x3ffff << 0)
+#define DCMPAREACRB_EADDR_MASK		(0x3ffff << 0)
+
+#define LOSSY_DECOMPRESSION_COMPAT	"renesas,lossy-decompression\0shared-dma-pool"
+#define LOSSY_MAX_FORMATS		3
+
+static int ft_get_lossy_region(void *fdt, int parent, u64 unit_address,
+			       unsigned int format)
+{
+	char name[35];
+	int node;
+	int ret;
+
+	/*
+	 * Find the lossy-decompression reserved-memory node. The node name in
+	 * the DTB is "lossy-decompression-<format>" without a unit address to
+	 * allow referencing it through phandles in the DTS. We will rename it
+	 * with a unit address later.
+	 */
+	snprintf(name, sizeof(name), "lossy-decompression-%u", format);
+	node = fdt_subnode_offset(fdt, parent, name);
+	if (node >= 0)
+		return node;
+
+	/*
+	 * If the node can't be found, create it and set the required
+	 * properties. The DTB is expected to have those properties set if the
+	 * node exists.
+	 */
+	node = fdt_add_subnode(fdt, parent, name);
+	if (node < 0)
+		return node;
+
+	ret = fdt_setprop(fdt, node, "compatible", LOSSY_DECOMPRESSION_COMPAT,
+			  sizeof(LOSSY_DECOMPRESSION_COMPAT));
+	if (ret < 0)
+		return ret;
+
+	ret = fdt_setprop(fdt, node, "reg", NULL, 0);
+	if (ret < 0)
+		return ret;
+
+	ret = fdt_setprop(fdt, node, "no-map", NULL, 0);
+	if (ret < 0)
+		return ret;
+
+	ret = fdt_setprop_u32(fdt, node, "renesas,format", format);
+	if (ret < 0)
+		return ret;
+
+	return node;
+}
+
+int ft_board_setup(void *fdt, bd_t *bd)
+{
+	struct bl2_lossy_info *lossy_info =
+		(struct bl2_lossy_info *)BL2_LOSSY_INFO_ADDRESS;
+	u64 unit_addresses[LOSSY_MAX_FORMATS] = { 0, };
+	const void *prop;
+	unsigned int i;
+	int rsv_node;
+	int len;
+	int ret;
+
+	/* Return immediately if no enabled lossy info entry exists. */
+	for (i = 0; i < BL2_LOSSY_INFO_ENTRIES; ++i) {
+		if (lossy_info[i].magic == BL2_LOSSY_INFO_MAGIC &&
+		    lossy_info[i].a0 & DCMPAREACRA_EN)
+			break;
+	}
+
+	if (i == BL2_LOSSY_INFO_ENTRIES)
+		return 0;
+
+	/*
+	 * Find the /reserved-memory node, create it if needed. Add or validate
+	 * the #address-cells and #size-cells properties.
+	 */
+	rsv_node = fdt_find_or_add_subnode(fdt, 0, "reserved-memory");
+	if (rsv_node < 0)
+		return rsv_node;
+
+	prop = fdt_getprop(fdt, rsv_node, "#address-cells", &len);
+	if (!prop) {
+		ret = fdt_setprop_u32(fdt, rsv_node, "#address-cells", 2);
+		if (ret)
+			return ret;
+	} else {
+		if (len != 4 || fdt32_to_cpu(*(fdt32_t *)prop) != 2)
+			return -FDT_ERR_BADNCELLS;
+	}
+
+	prop = fdt_getprop(fdt, rsv_node, "#size-cells", &len);
+	if (!prop) {
+		ret = fdt_setprop_u32(fdt, rsv_node, "#size-cells", 2);
+		if (ret)
+			return ret;
+	} else {
+		if (len != 4 || fdt32_to_cpu(*(fdt32_t *)prop) != 2)
+			return -FDT_ERR_BADNCELLS;
+	}
+
+	prop = fdt_getprop(fdt, rsv_node, "ranges", &len);
+	if (!prop) {
+		ret = fdt_setprop(fdt, rsv_node, "ranges", NULL, 0);
+		if (ret)
+			return ret;
+	}
+
+	/* Add the reserved memory entries. */
+	for (i = 0; i < BL2_LOSSY_INFO_ENTRIES; ++i) {
+		struct fdt_reserve_entry rsv_mem;
+		int node;
+		u32 format;
+		u64 start;
+		u64 end;
+
+		/* Skip disabled entries and invalid formats. */
+		if (lossy_info[i].magic != BL2_LOSSY_INFO_MAGIC ||
+		    !(lossy_info[i].a0 & DCMPAREACRA_EN))
+			continue;
+
+		format = DCMPAREACRA_FMT_GET(lossy_info[i].a0);
+		if (format >= LOSSY_MAX_FORMATS)
+			continue;
+
+		/*
+		 * Get the lossy region node offset. We can't cache the value
+		 * as we're modifying properties, which could result in offset
+		 * changes.
+		 */
+		start = (u64)(lossy_info[i].a0 & DCMPAREACRA_SADDR_MASK) << 20;
+		end = (u64)(lossy_info[i].b0 & DCMPAREACRB_EADDR_MASK) << 20;
+		if (!unit_addresses[format])
+			unit_addresses[format] = start;
+
+		node = ft_get_lossy_region(fdt, rsv_node, start, format);
+		if (node < 0)
+			return node;
+
+		rsv_mem.address = cpu_to_fdt64(start);
+		rsv_mem.size = cpu_to_fdt64(end - start);
+		ret = fdt_appendprop(fdt, node, "reg", &rsv_mem,
+				     sizeof(rsv_mem));
+		if (ret < 0)
+			return ret;
+	}
+
+	/*
+	 * Now that we're done rename all the lossy decompression nodes with
+	 * a unit address or remove them if they are empty.
+	 */
+	for (i = 0; i < LOSSY_MAX_FORMATS; ++i) {
+		char name[35];
+		int node;
+
+		snprintf(name, sizeof(name), "lossy-decompression-%u", i);
+		node = fdt_subnode_offset(fdt, rsv_node, name);
+		if (node < 0)
+			continue;
+
+		if (unit_addresses[i]) {
+			snprintf(name, sizeof(name), "lossy-decompression@%llx",
+				 unit_addresses[i]);
+			ret = fdt_set_name(fdt, node, name);
+			if (ret < 0)
+				return ret;
+		} else {
+			ret = fdt_del_node(fdt, node);
+			if (ret < 0)
+				return ret;
+		}
+	}
+
+	return 0;
+}
+#endif
diff --git a/include/configs/rcar-gen3-common.h b/include/configs/rcar-gen3-common.h
index 7217a66def70..c0ad2c8b21d5 100644
--- a/include/configs/rcar-gen3-common.h
+++ b/include/configs/rcar-gen3-common.h
@@ -52,6 +52,7 @@
 #define CONFIG_INITRD_TAG
 #define CONFIG_CMDLINE_EDITING
 #define CONFIG_OF_LIBFDT
+#define CONFIG_OF_BOARD_SETUP
 
 #define CONFIG_BAUDRATE		115200
 #define CONFIG_BOOTDELAY	3
-- 
Regards,

Laurent Pinchart

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

* [RFC 01/13] dt-bindings: reserved-memory: Add binding for the Renesas lossy decompression area
  2017-09-26 10:05 [RFC 00/13] R-Car: Enable lossy compression in VSP video pipelines Laurent Pinchart
  2017-09-26 10:05 ` [RFC] [FW] bl2: plat: renesas: rcar: Enable all lossy decompression areas Laurent Pinchart
  2017-09-26 10:05 ` [RFC] [U-BOOT] board: salvator-x: Add reserved lossy decompression areas to DT Laurent Pinchart
@ 2017-09-26 10:05 ` Laurent Pinchart
  2017-09-26 10:05 ` [RFC 02/13] dt-bindings: media: renesas-fcp: Add a compatible string for VSPI FCP Laurent Pinchart
                   ` (11 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: Laurent Pinchart @ 2017-09-26 10:05 UTC (permalink / raw)
  To: linux-renesas-soc

The Renesas R-Car Gen3 DDR3/4 controller supports transparent
decompression of data stored in the Renesas near-lossless image
compression format (FCNL). Decompression is controlled based on system
memory ranges configured by the secure mode boot loader. As any data
located within those memory ranges will be automatically decompressed
when read, those ranges are not usable as normal system memory.

The memory ranges for lossy decompression are system-specific and fixed
from a non-secure software point of view. These bindings describe the
ranges in the form of a reserved memory node.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 .../renesas,lossy-decompression.txt                | 102 +++++++++++++++++++++
 1 file changed, 102 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/reserved-memory/renesas,lossy-decompression.txt

diff --git a/Documentation/devicetree/bindings/reserved-memory/renesas,lossy-decompression.txt b/Documentation/devicetree/bindings/reserved-memory/renesas,lossy-decompression.txt
new file mode 100644
index 000000000000..a70f84ae7b4a
--- /dev/null
+++ b/Documentation/devicetree/bindings/reserved-memory/renesas,lossy-decompression.txt
@@ -0,0 +1,102 @@
+Renesas Lossy Decompression Reserved Memory Area
+------------------------------------------------
+
+The Renesas R-Car Gen3 DDR3/4 controller supports transparent decompression of
+data stored in the Renesas near-lossless image compression format (FCNL).
+Decompression is controlled based on system memory ranges configured by the
+secure mode boot loader. As any data located within those memory ranges will
+be automatically decompressed when read, those ranges are not usable as normal
+system memory.
+
+The memory ranges for lossy decompression are system-specific and fixed from a
+non-secure software point of view. These bindings describe the ranges in the
+form of a reserved memory node.
+
+Required properties:
+
+- compatible: Shall be "renesas,lossy-decompression", "shared-dma-pool".
+- reg: Reserved memory ranges for the lossy decompression (up to 16).
+- no-map: Shall be set.
+- renesas,format: The image format used for the memory range. Valid formats
+  are:
+
+  - 0: YUV planar
+  - 1: YUV422 interleaved
+  - 2: ARGB8888
+
+The Lossy Decompression nodes must be located as direct children of the
+/reserved-memory node. See reserved-memory.txt for more information.
+
+In order to allow references to those reserved memory nodes (through
+memory-region properties) in device tree sources, they are meant to be
+included without a reg property, and later updated in the device tree blob by
+the boot loader before passing control to the operating system.
+
+Without a reg property in the device tree source the Lossy Decompression nodes
+can't have a unit address, and would thus all have the same name, which isn't
+valid. To solve that problem the device tree sources should name the nodes
+lossy-decompression-<format> where format is the value of the renesas,format
+property. The boot loader is expected to rename the nodes to
+lossy-decompression@<unit-address>.
+
+
+Example: R8A7795 (R-Car H3) Lossy Decompression Nodes
+
+- Original device tree source
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+
+		lossy-decompression-0 {
+			compatible = "renesas,lossy-decompression",
+				     "shared-dma-pool";
+			no-map;
+			renesas,formats = <0>;
+		};
+
+		lossy-decompression-1 {
+			compatible = "renesas,lossy-decompression",
+				     "shared-dma-pool";
+			no-map;
+			renesas,formats = <1>;
+		};
+
+		lossy-decompression-2 {
+			compatible = "renesas,lossy-decompression",
+				     "shared-dma-pool";
+			no-map;
+			renesas,formats = <2>;
+		};
+	};
+
+- Device tree after being patched by the boot loader
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+
+		lossy-decompression@54000000 {
+			compatible = "renesas,lossy-decompression",
+				     "shared-dma-pool";
+			reg = <0 0x54000000 0 0x03000000>;
+			no-map;
+			renesas,formats = <2>;
+		};
+
+		lossy-decompression@57000000 {
+			compatible = "renesas,lossy-decompression",
+				     "shared-dma-pool";
+			reg = <0 0x57000000 0 0x03000000>;
+			no-map;
+			renesas,formats = <0>;
+		};
+
+		lossy-decompression@5a000000 {
+			compatible = "renesas,lossy-decompression",
+				     "shared-dma-pool";
+			reg = <0 0x5a000000 0 0x03000000>;
+			no-map;
+			renesas,formats = <1>;
+		};
+	};
-- 
Regards,

Laurent Pinchart

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

* [RFC 02/13] dt-bindings: media: renesas-fcp: Add a compatible string for VSPI FCP
  2017-09-26 10:05 [RFC 00/13] R-Car: Enable lossy compression in VSP video pipelines Laurent Pinchart
                   ` (2 preceding siblings ...)
  2017-09-26 10:05 ` [RFC 01/13] dt-bindings: reserved-memory: Add binding for the Renesas lossy decompression area Laurent Pinchart
@ 2017-09-26 10:05 ` Laurent Pinchart
  2017-09-26 11:47   ` Geert Uytterhoeven
  2017-09-26 10:05 ` [RFC 03/13] dt-bindings: media: renesas-fcp: Add memory-region property Laurent Pinchart
                   ` (10 subsequent siblings)
  14 siblings, 1 reply; 23+ messages in thread
From: Laurent Pinchart @ 2017-09-26 10:05 UTC (permalink / raw)
  To: linux-renesas-soc

The FCP instances associated with a VSPI must be treated differently
than the ones associated with another type of VSP. Add a new compatible
string to allow telling them apart.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 Documentation/devicetree/bindings/media/renesas,fcp.txt | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/media/renesas,fcp.txt b/Documentation/devicetree/bindings/media/renesas,fcp.txt
index 3ec91803ba58..c1f28736e2d6 100644
--- a/Documentation/devicetree/bindings/media/renesas,fcp.txt
+++ b/Documentation/devicetree/bindings/media/renesas,fcp.txt
@@ -11,7 +11,8 @@ are paired with. These DT bindings currently support the FCPV and FCPF.
 
  - compatible: Must be one or more of the following
 
-   - "renesas,fcpv" for generic compatible 'FCP for VSP'
+   - "renesas,fcpvi" for generic compatible 'FCP for VSPI'
+   - "renesas,fcpv" for generic compatible 'FCP for VSP' (all other VSPs)
    - "renesas,fcpf" for generic compatible 'FCP for FDP'
 
  - reg: the register base and size for the device registers
-- 
Regards,

Laurent Pinchart

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

* [RFC 03/13] dt-bindings: media: renesas-fcp: Add memory-region property
  2017-09-26 10:05 [RFC 00/13] R-Car: Enable lossy compression in VSP video pipelines Laurent Pinchart
                   ` (3 preceding siblings ...)
  2017-09-26 10:05 ` [RFC 02/13] dt-bindings: media: renesas-fcp: Add a compatible string for VSPI FCP Laurent Pinchart
@ 2017-09-26 10:05 ` Laurent Pinchart
  2017-09-26 10:05 ` [RFC 04/13] arm64: dts: renesas: Use renesas,fcpvi compatible string Laurent Pinchart
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: Laurent Pinchart @ 2017-09-26 10:05 UTC (permalink / raw)
  To: linux-renesas-soc

The FCP can't perform lossy decompression by itself, but relies instead
on the DDR controller to provide that feature. To do so, it needs to
allocate buffers from a special lossy decompression reserved memory
area. This DT property references that memory area.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 Documentation/devicetree/bindings/media/renesas,fcp.txt | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/media/renesas,fcp.txt b/Documentation/devicetree/bindings/media/renesas,fcp.txt
index c1f28736e2d6..489b026c4016 100644
--- a/Documentation/devicetree/bindings/media/renesas,fcp.txt
+++ b/Documentation/devicetree/bindings/media/renesas,fcp.txt
@@ -19,8 +19,11 @@ are paired with. These DT bindings currently support the FCPV and FCPF.
  - clocks: Reference to the functional clock
 
 Optional properties:
- - power-domains : power-domain property defined with a power domain specifier
-		   to respective power domain.
+ - memory-region: list of phandles referencing the lossy decompression reserved
+ 		  memory regions associated with the FCP, if any. Valid for FCPV
+		  and FCPVI instances only.
+ - power-domains: power-domain property defined with a power domain specifier
+		  to respective power domain.
 
 
 Device node example
-- 
Regards,

Laurent Pinchart

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

* [RFC 04/13] arm64: dts: renesas: Use renesas,fcpvi compatible string
  2017-09-26 10:05 [RFC 00/13] R-Car: Enable lossy compression in VSP video pipelines Laurent Pinchart
                   ` (4 preceding siblings ...)
  2017-09-26 10:05 ` [RFC 03/13] dt-bindings: media: renesas-fcp: Add memory-region property Laurent Pinchart
@ 2017-09-26 10:05 ` Laurent Pinchart
  2017-09-26 10:05 ` [RFC 05/13] arm64: dts: r8a7795: Add lossy decompression reserved memory nodes Laurent Pinchart
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: Laurent Pinchart @ 2017-09-26 10:05 UTC (permalink / raw)
  To: linux-renesas-soc

The FCP instances associated with a VSPI must be treated differently
than the ones associated with another type of VSP. Use the appropriate
compatible string.

The fallback renesas,fcpv compatible string allows for backward
compatibility with platforms that don't recognize the new compatible
string yet.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi | 2 +-
 arch/arm64/boot/dts/renesas/r8a7795.dtsi     | 4 ++--
 arch/arm64/boot/dts/renesas/r8a7796.dtsi     | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi
index 655dd30639c5..0fe4093434a5 100644
--- a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi
@@ -49,7 +49,7 @@
 	};
 
 	fcpvi2: fcp@fe9cf000 {
-		compatible = "renesas,fcpv";
+		compatible = "renesas,fcpvi", "renesas,fcpv";
 		reg = <0 0xfe9cf000 0 0x200>;
 		clocks = <&cpg CPG_MOD 609>;
 		power-domains = <&sysc R8A7795_PD_A3VP>;
diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
index d5cfd1a1c539..ce2a59361a82 100644
--- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
@@ -1922,7 +1922,7 @@
 		};
 
 		fcpvi0: fcp@fe9af000 {
-			compatible = "renesas,fcpv";
+			compatible = "renesas,fcpvi", "renesas,fcpv";
 			reg = <0 0xfe9af000 0 0x200>;
 			clocks = <&cpg CPG_MOD 611>;
 			power-domains = <&sysc R8A7795_PD_A3VP>;
@@ -1941,7 +1941,7 @@
 		};
 
 		fcpvi1: fcp@fe9bf000 {
-			compatible = "renesas,fcpv";
+			compatible = "renesas,fcpvi", "renesas,fcpv";
 			reg = <0 0xfe9bf000 0 0x200>;
 			clocks = <&cpg CPG_MOD 610>;
 			power-domains = <&sysc R8A7795_PD_A3VP>;
diff --git a/arch/arm64/boot/dts/renesas/r8a7796.dtsi b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
index 57ac5ca6ed98..38b3d8f9c9d2 100644
--- a/arch/arm64/boot/dts/renesas/r8a7796.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
@@ -1719,7 +1719,7 @@
 		};
 
 		fcpvi0: fcp@fe9af000 {
-			compatible = "renesas,fcpv";
+			compatible = "renesas,fcpvi", "renesas,fcpv";
 			reg = <0 0xfe9af000 0 0x200>;
 			clocks = <&cpg CPG_MOD 611>;
 			power-domains = <&sysc R8A7796_PD_A3VC>;
-- 
Regards,

Laurent Pinchart

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

* [RFC 05/13] arm64: dts: r8a7795: Add lossy decompression reserved memory nodes
  2017-09-26 10:05 [RFC 00/13] R-Car: Enable lossy compression in VSP video pipelines Laurent Pinchart
                   ` (5 preceding siblings ...)
  2017-09-26 10:05 ` [RFC 04/13] arm64: dts: renesas: Use renesas,fcpvi compatible string Laurent Pinchart
@ 2017-09-26 10:05 ` Laurent Pinchart
  2017-09-26 10:05 ` [RFC 06/13] arm64: dts: r8a7795: Reference the lossy memory region from the FCPss Laurent Pinchart
                   ` (7 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: Laurent Pinchart @ 2017-09-26 10:05 UTC (permalink / raw)
  To: linux-renesas-soc

The secure mode boot loader on R8A7795 platforms can program the DDR
controller to perform transparent image decompression when accessing
certain areas of RAM. Those areas must be kept out of system memory.

Add place-holder nodes for the boot loader to fill with the list of
lossy decompression areas, if any.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm64/boot/dts/renesas/r8a7795.dtsi | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
index ce2a59361a82..1320ec3b6a5e 100644
--- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
@@ -126,6 +126,38 @@
 		};
 	};
 
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		/*
+		 * Up to three lossy decompression regions are supported, one
+		 * per format. The boot loader will populate them and rename
+		 * them to lossy-decompression@<unit-address>.
+		 */
+		lossy_decompression_0: lossy-decompression-0 {
+			compatible = "renesas,lossy-decompression",
+				     "shared-dma-pool";
+			renesas,format = <0>;
+			no-map;
+		};
+
+		lossy_decompression_1: lossy-decompression-1 {
+			compatible = "renesas,lossy-decompression",
+				     "shared-dma-pool";
+			renesas,format = <1>;
+			no-map;
+		};
+
+		lossy_decompression_2: lossy-decompression-2 {
+			compatible = "renesas,lossy-decompression",
+				     "shared-dma-pool";
+			renesas,format = <2>;
+			no-map;
+		};
+	};
+
 	extal_clk: extal {
 		compatible = "fixed-clock";
 		#clock-cells = <0>;
-- 
Regards,

Laurent Pinchart

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

* [RFC 06/13] arm64: dts: r8a7795: Reference the lossy memory region from the FCPss
  2017-09-26 10:05 [RFC 00/13] R-Car: Enable lossy compression in VSP video pipelines Laurent Pinchart
                   ` (6 preceding siblings ...)
  2017-09-26 10:05 ` [RFC 05/13] arm64: dts: r8a7795: Add lossy decompression reserved memory nodes Laurent Pinchart
@ 2017-09-26 10:05 ` Laurent Pinchart
  2017-09-26 10:05 ` [RFC 07/13] arm64: dts: r8a7795: Add dma-ranges property in the /soc node Laurent Pinchart
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: Laurent Pinchart @ 2017-09-26 10:05 UTC (permalink / raw)
  To: linux-renesas-soc

The FCPV instances can perform transparent near-lossless compression
internally but need the DDR controller to perform decompression.
Reference the DDR controller lossy decompression memory region to model
that relationship.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm64/boot/dts/renesas/r8a7795.dtsi | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
index 1320ec3b6a5e..c55003563f61 100644
--- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
@@ -1901,6 +1901,9 @@
 
 		fcpvb1: fcp@fe92f000 {
 			compatible = "renesas,fcpv";
+			memory-region = <&lossy_decompression_0
+					 &lossy_decompression_1
+					 &lossy_decompression_2>;
 			reg = <0 0xfe92f000 0 0x200>;
 			clocks = <&cpg CPG_MOD 606>;
 			power-domains = <&sysc R8A7795_PD_A3VP>;
@@ -1936,6 +1939,9 @@
 
 		fcpvb0: fcp@fe96f000 {
 			compatible = "renesas,fcpv";
+			memory-region = <&lossy_decompression_0
+					 &lossy_decompression_1
+					 &lossy_decompression_2>;
 			reg = <0 0xfe96f000 0 0x200>;
 			clocks = <&cpg CPG_MOD 607>;
 			power-domains = <&sysc R8A7795_PD_A3VP>;
@@ -1955,6 +1961,9 @@
 
 		fcpvi0: fcp@fe9af000 {
 			compatible = "renesas,fcpvi", "renesas,fcpv";
+			memory-region = <&lossy_decompression_0
+					 &lossy_decompression_1
+					 &lossy_decompression_2>;
 			reg = <0 0xfe9af000 0 0x200>;
 			clocks = <&cpg CPG_MOD 611>;
 			power-domains = <&sysc R8A7795_PD_A3VP>;
@@ -1974,6 +1983,9 @@
 
 		fcpvi1: fcp@fe9bf000 {
 			compatible = "renesas,fcpvi", "renesas,fcpv";
+			memory-region = <&lossy_decompression_0
+					 &lossy_decompression_1
+					 &lossy_decompression_2>;
 			reg = <0 0xfe9bf000 0 0x200>;
 			clocks = <&cpg CPG_MOD 610>;
 			power-domains = <&sysc R8A7795_PD_A3VP>;
@@ -1993,6 +2005,9 @@
 
 		fcpvd0: fcp@fea27000 {
 			compatible = "renesas,fcpv";
+			memory-region = <&lossy_decompression_0
+					 &lossy_decompression_1
+					 &lossy_decompression_2>;
 			reg = <0 0xfea27000 0 0x200>;
 			clocks = <&cpg CPG_MOD 603>;
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
@@ -2012,6 +2027,9 @@
 
 		fcpvd1: fcp@fea2f000 {
 			compatible = "renesas,fcpv";
+			memory-region = <&lossy_decompression_0
+					 &lossy_decompression_1
+					 &lossy_decompression_2>;
 			reg = <0 0xfea2f000 0 0x200>;
 			clocks = <&cpg CPG_MOD 602>;
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
@@ -2031,6 +2049,9 @@
 
 		fcpvd2: fcp@fea37000 {
 			compatible = "renesas,fcpv";
+			memory-region = <&lossy_decompression_0
+					 &lossy_decompression_1
+					 &lossy_decompression_2>;
 			reg = <0 0xfea37000 0 0x200>;
 			clocks = <&cpg CPG_MOD 601>;
 			power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-- 
Regards,

Laurent Pinchart

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

* [RFC 07/13] arm64: dts: r8a7795: Add dma-ranges property in the /soc node
  2017-09-26 10:05 [RFC 00/13] R-Car: Enable lossy compression in VSP video pipelines Laurent Pinchart
                   ` (7 preceding siblings ...)
  2017-09-26 10:05 ` [RFC 06/13] arm64: dts: r8a7795: Reference the lossy memory region from the FCPss Laurent Pinchart
@ 2017-09-26 10:05 ` Laurent Pinchart
  2017-09-26 10:06 ` [RFC 08/13] v4l: rcar-fcp: Check device revision at probe time Laurent Pinchart
                   ` (5 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: Laurent Pinchart @ 2017-09-26 10:05 UTC (permalink / raw)
  To: linux-renesas-soc

DMA address translation requires a dma-ranges property in bus nodes.
While some operating systems work around the absence of such property in
an attempt to implement compatibility with incorrect DT, the property is
nonetheless required.

Add the dma-ranges property to the /soc node that contains all on-SoC
peripherals. The bus supports 40-bit DMA addressing without any address
translation.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm64/boot/dts/renesas/r8a7795.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
index c55003563f61..e6a008d9d5f8 100644
--- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
@@ -222,6 +222,7 @@
 
 		#address-cells = <2>;
 		#size-cells = <2>;
+		dma-ranges = <0 0x00000000 0 0x00000000 0x100 0x00000000>;
 		ranges;
 
 		gic: interrupt-controller@f1010000 {
-- 
Regards,

Laurent Pinchart

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

* [RFC 08/13] v4l: rcar-fcp: Check device revision at probe time
  2017-09-26 10:05 [RFC 00/13] R-Car: Enable lossy compression in VSP video pipelines Laurent Pinchart
                   ` (8 preceding siblings ...)
  2017-09-26 10:05 ` [RFC 07/13] arm64: dts: r8a7795: Add dma-ranges property in the /soc node Laurent Pinchart
@ 2017-09-26 10:06 ` Laurent Pinchart
  2017-09-26 10:06 ` [RFC 09/13] v4l: rcar-fcp: Configure the number of outstanding read transactions Laurent Pinchart
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: Laurent Pinchart @ 2017-09-26 10:06 UTC (permalink / raw)
  To: linux-renesas-soc

Verify that the device revision register reports a valid value,
otherwise reject the device.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/platform/rcar-fcp.c | 139 ++++++++++++++++++++++++++++++++++++--
 1 file changed, 132 insertions(+), 7 deletions(-)

diff --git a/drivers/media/platform/rcar-fcp.c b/drivers/media/platform/rcar-fcp.c
index 2988031d285d..ddbc960f8458 100644
--- a/drivers/media/platform/rcar-fcp.c
+++ b/drivers/media/platform/rcar-fcp.c
@@ -12,24 +12,84 @@
  */
 
 #include <linux/device.h>
+#include <linux/io.h>
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/slab.h>
 
 #include <media/rcar-fcp.h>
 
+#define FCP_VCR				0x0000
+#define FCP_VCR_CATEGORY		(1 << 8)
+#define FCP_VCR_REVISION_H3_ES1		(1 << 0)
+#define FCP_VCR_REVISION_M3W		(2 << 0)
+#define FCP_VCR_REVISION_V3M		(3 << 0)
+#define FCP_VCR_REVISION_H3		(4 << 0)
+#define FCP_VCR_REVISION_D3		(5 << 0)
+#define FCP_VCR_REVISION_M3N		(6 << 0)
+#define FCP_VCR_REVISION_V3H		(7 << 0)
+#define FCP_VCR_REVISION_E3		(8 << 0)
+
+#define FCP_CFG0			0x0004
+#define FCP_CFG0_FCPVSEL		BIT(1)
+
+#define FCP_RST				0x0010
+#define FCP_RST_RIIFRST			BIT(22)
+#define FCP_RST_RSIFRST			BIT(21)
+#define FCP_RST_DCMPRST			BIT(20)
+#define FCP_RST_MODRST			BIT(4)
+#define FCP_RST_SOFTRST			BIT(0)
+
+#define FCP_STA				0x0018
+#define FCP_STA_ACT			BIT(0)
+
+#define FCP_TL_CTRL			0x0070
+#define FCP_TL_CTRL_TLEN		BIT(31)
+#define FCP_TL_CTRL_VPOS_C(n)		((n) << 16)
+#define FCP_TL_CTRL_VPOS_Y(n)		((n) << 0)
+
+#define FCP_PICINFO1			0x00c4
+#define FCP_PICINFO1_STRIDE_DIV16	((n) << 0)
+
+#define FCP_BA_ANC_Y0			0x0100
+#define FCP_BA_ANC_Y1			0x0104
+#define FCP_BA_ANC_Y2			0x0108
+#define FCP_BA_ANC_C			0x010c
+#define FCP_BA_REF_Y0			0x0110
+#define FCP_BA_REF_Y1			0x0114
+#define FCP_BA_REF_Y2			0x0118
+#define FCP_BA_REF_C			0x011c
+
+enum rcar_fcp_type {
+	RCAR_FCPF,
+	RCAR_FCPV,
+};
+
 struct rcar_fcp_device {
 	struct list_head list;
 	struct device *dev;
+
+	enum rcar_fcp_type type;
+	void __iomem *mmio;
 };
 
 static LIST_HEAD(fcp_devices);
 static DEFINE_MUTEX(fcp_lock);
 
 /* -----------------------------------------------------------------------------
+ * Device Configuration
+ */
+
+static u32 rcar_fcp_read(struct rcar_fcp_device *fcp, unsigned int reg)
+{
+	return ioread32(fcp->mmio + reg);
+}
+
+/* -----------------------------------------------------------------------------
  * Public API
  */
 
@@ -129,17 +189,83 @@ EXPORT_SYMBOL_GPL(rcar_fcp_disable);
  * Platform Driver
  */
 
+static int rcar_fcp_setup(struct rcar_fcp_device *fcp)
+{
+	static const char * const models[] = {
+		[RCAR_FCPF] = "FCPF",
+		[RCAR_FCPV] = "FCPV",
+	};
+	static struct {
+		u32 version;
+		const char *name;
+	} versions[] = {
+		{ FCP_VCR_CATEGORY | FCP_VCR_REVISION_H3_ES1, "H3 ES1.x" },
+		{ FCP_VCR_CATEGORY | FCP_VCR_REVISION_M3W, "M3W" },
+		{ FCP_VCR_CATEGORY | FCP_VCR_REVISION_V3M, "V3M" },
+		{ FCP_VCR_CATEGORY | FCP_VCR_REVISION_H3, "H3" },
+		{ FCP_VCR_CATEGORY | FCP_VCR_REVISION_D3, "D3" },
+		{ FCP_VCR_CATEGORY | FCP_VCR_REVISION_M3N, "M3N" },
+		{ FCP_VCR_CATEGORY | FCP_VCR_REVISION_V3H, "V3H" },
+		{ FCP_VCR_CATEGORY | FCP_VCR_REVISION_E3, "E3" },
+	};
+
+	unsigned int i;
+	u32 version;
+
+	/* Check the device version register. */
+	version = rcar_fcp_read(fcp, FCP_VCR);
+
+	for (i = 0; i < ARRAY_SIZE(versions); ++i) {
+		if (versions[i].version == version)
+			break;
+	}
+
+	if (i >= ARRAY_SIZE(versions)) {
+		dev_err(fcp->dev, "Invalid FCP version 0x%08x\n", version);
+		return -ENODEV;
+	}
+
+	dev_dbg(fcp->dev, "%s %s device found\n", models[fcp->type],
+		versions[i].name);
+
+	return 0;
+}
+
+static const struct of_device_id rcar_fcp_of_match[] = {
+	{ .compatible = "renesas,fcpf", .data = (void *)RCAR_FCPF },
+	{ .compatible = "renesas,fcpv", .data = (void *)RCAR_FCPV },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, rcar_fcp_of_match);
+
 static int rcar_fcp_probe(struct platform_device *pdev)
 {
 	struct rcar_fcp_device *fcp;
+	struct resource *io;
+	int ret;
 
 	fcp = devm_kzalloc(&pdev->dev, sizeof(*fcp), GFP_KERNEL);
 	if (fcp == NULL)
 		return -ENOMEM;
 
 	fcp->dev = &pdev->dev;
+	fcp->type = (enum rcar_fcp_type)of_device_get_match_data(&pdev->dev);
+
+	io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	fcp->mmio = devm_ioremap_resource(&pdev->dev, io);
+	if (IS_ERR(fcp->mmio))
+		return PTR_ERR(fcp->mmio);
 
 	pm_runtime_enable(&pdev->dev);
+	ret = pm_runtime_get_sync(&pdev->dev);
+	if (ret < 0)
+		goto error_pm_disable;
+
+	ret = rcar_fcp_setup(fcp);
+	if (ret < 0)
+		goto error_pm_put;
+
+	pm_runtime_put(&pdev->dev);
 
 	mutex_lock(&fcp_lock);
 	list_add_tail(&fcp->list, &fcp_devices);
@@ -148,6 +274,12 @@ static int rcar_fcp_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, fcp);
 
 	return 0;
+
+error_pm_put:
+	pm_runtime_put(&pdev->dev);
+error_pm_disable:
+	pm_runtime_disable(&pdev->dev);
+	return ret;
 }
 
 static int rcar_fcp_remove(struct platform_device *pdev)
@@ -163,13 +295,6 @@ static int rcar_fcp_remove(struct platform_device *pdev)
 	return 0;
 }
 
-static const struct of_device_id rcar_fcp_of_match[] = {
-	{ .compatible = "renesas,fcpf" },
-	{ .compatible = "renesas,fcpv" },
-	{ },
-};
-MODULE_DEVICE_TABLE(of, rcar_fcp_of_match);
-
 static struct platform_driver rcar_fcp_platform_driver = {
 	.probe		= rcar_fcp_probe,
 	.remove		= rcar_fcp_remove,
-- 
Regards,

Laurent Pinchart

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

* [RFC 09/13] v4l: rcar-fcp: Configure the number of outstanding read transactions
  2017-09-26 10:05 [RFC 00/13] R-Car: Enable lossy compression in VSP video pipelines Laurent Pinchart
                   ` (9 preceding siblings ...)
  2017-09-26 10:06 ` [RFC 08/13] v4l: rcar-fcp: Check device revision at probe time Laurent Pinchart
@ 2017-09-26 10:06 ` Laurent Pinchart
  2017-09-26 11:50   ` Geert Uytterhoeven
  2017-09-26 10:06 ` [RFC 10/13] v4l: rcar-fcp: Prepare driver API for FCNL support Laurent Pinchart
                   ` (3 subsequent siblings)
  14 siblings, 1 reply; 23+ messages in thread
From: Laurent Pinchart @ 2017-09-26 10:06 UTC (permalink / raw)
  To: linux-renesas-soc

The FCPV has a selectable number of outstanding read transactions.
According to the documentation the value must be set based on the type
of the VSP the FCPV is connected to. Set the register accordingly at
probe time.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/platform/rcar-fcp.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/drivers/media/platform/rcar-fcp.c b/drivers/media/platform/rcar-fcp.c
index ddbc960f8458..e93e9c4227d9 100644
--- a/drivers/media/platform/rcar-fcp.c
+++ b/drivers/media/platform/rcar-fcp.c
@@ -67,6 +67,7 @@
 enum rcar_fcp_type {
 	RCAR_FCPF,
 	RCAR_FCPV,
+	RCAR_FCPVI,
 };
 
 struct rcar_fcp_device {
@@ -89,6 +90,12 @@ static u32 rcar_fcp_read(struct rcar_fcp_device *fcp, unsigned int reg)
 	return ioread32(fcp->mmio + reg);
 }
 
+static void rcar_fcp_write(struct rcar_fcp_device *fcp, unsigned int reg,
+			   u32 value)
+{
+	iowrite32(value, fcp->mmio + reg);
+}
+
 /* -----------------------------------------------------------------------------
  * Public API
  */
@@ -194,6 +201,7 @@ static int rcar_fcp_setup(struct rcar_fcp_device *fcp)
 	static const char * const models[] = {
 		[RCAR_FCPF] = "FCPF",
 		[RCAR_FCPV] = "FCPV",
+		[RCAR_FCPVI] = "FCPVI",
 	};
 	static struct {
 		u32 version;
@@ -228,12 +236,29 @@ static int rcar_fcp_setup(struct rcar_fcp_device *fcp)
 	dev_dbg(fcp->dev, "%s %s device found\n", models[fcp->type],
 		versions[i].name);
 
+	/* Set the processing mode (needed for FCPV only). */
+	switch (fcp->type) {
+	case RCAR_FCPV:
+		/* 64 outstanding read transactions */
+		rcar_fcp_write(fcp, FCP_CFG0, 0);
+		break;
+
+	case RCAR_FCPVI:
+		/* 16 outstanding read transactions */
+		rcar_fcp_write(fcp, FCP_CFG0, FCP_CFG0_FCPVSEL);
+		break;
+
+	default:
+		break;
+	}
+
 	return 0;
 }
 
 static const struct of_device_id rcar_fcp_of_match[] = {
 	{ .compatible = "renesas,fcpf", .data = (void *)RCAR_FCPF },
 	{ .compatible = "renesas,fcpv", .data = (void *)RCAR_FCPV },
+	{ .compatible = "renesas,fcpvi", .data = (void *)RCAR_FCPVI },
 	{ },
 };
 MODULE_DEVICE_TABLE(of, rcar_fcp_of_match);
-- 
Regards,

Laurent Pinchart

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

* [RFC 10/13] v4l: rcar-fcp: Prepare driver API for FCNL support
  2017-09-26 10:05 [RFC 00/13] R-Car: Enable lossy compression in VSP video pipelines Laurent Pinchart
                   ` (10 preceding siblings ...)
  2017-09-26 10:06 ` [RFC 09/13] v4l: rcar-fcp: Configure the number of outstanding read transactions Laurent Pinchart
@ 2017-09-26 10:06 ` Laurent Pinchart
  2017-09-26 10:06 ` [RFC 11/13] v4l: rcar-fcp: Support FCNL decompression Laurent Pinchart
                   ` (2 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: Laurent Pinchart @ 2017-09-26 10:06 UTC (permalink / raw)
  To: linux-renesas-soc

To support transparent FCNL decompression the FCP users will need to use
different bus master devices for compressed and uncompressed formats.
Rename the rcar_fcp_get_device() function to rcar_fcp_get_bus_master()
and add a new argument to select the bus master in order to prepare for
that change.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/platform/rcar-fcp.c      | 29 +++++++++++++++++++++++++++--
 drivers/media/platform/vsp1/vsp1_drv.c |  4 +++-
 include/media/rcar-fcp.h               | 14 ++++++++++++--
 3 files changed, 42 insertions(+), 5 deletions(-)

diff --git a/drivers/media/platform/rcar-fcp.c b/drivers/media/platform/rcar-fcp.c
index e93e9c4227d9..ca5e1dddba03 100644
--- a/drivers/media/platform/rcar-fcp.c
+++ b/drivers/media/platform/rcar-fcp.c
@@ -145,11 +145,36 @@ void rcar_fcp_put(struct rcar_fcp_device *fcp)
 }
 EXPORT_SYMBOL_GPL(rcar_fcp_put);
 
-struct device *rcar_fcp_get_device(struct rcar_fcp_device *fcp)
+/**
+ * rcar_fcp_get_bus_master - Get the FCP bus master device
+ * @fcp: the FCP device
+ * @format: the data format handled by the bus master
+ *
+ * The FCP performs read and write bus mastering operations for image data and
+ * display lists. This function returns a &struct device that the FCP user can
+ * use for DMA memory allocation.
+ *
+ * When @format is RCAR_FCP_UNCOMPRESSED, the returned bus master will perform
+ * normal read accesses. This bus master is guaranteed to always be available.
+ *
+ * Otherwise, the returned bus master will perform transparent FCNL
+ * decompression of data on read accesses for the specified @format. It must
+ * thus be used for FCNL-compressed image data only. Not all FCP instances
+ * support FCNL decompression, this function may return NULL in that case.
+ *
+ * The returned device borrows a reference from the FCP device. The borrowed
+ * reference doesn't need to be released, and shall not be accessed once the
+ * caller releases its reference to the FCP with rcar_fcp_put().
+ *
+ * Return the bus master &struct device for the given purpose, or NULL if no bus
+ * master is available.
+ */
+struct device *rcar_fcp_get_bus_master(struct rcar_fcp_device *fcp,
+				       enum rcar_fcp_data_format format)
 {
 	return fcp->dev;
 }
-EXPORT_SYMBOL_GPL(rcar_fcp_get_device);
+EXPORT_SYMBOL_GPL(rcar_fcp_get_bus_master);
 
 /**
  * rcar_fcp_enable - Enable an FCP
diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
index 962e4c304076..4253a76cc484 100644
--- a/drivers/media/platform/vsp1/vsp1_drv.c
+++ b/drivers/media/platform/vsp1/vsp1_drv.c
@@ -809,7 +809,9 @@ static int vsp1_probe(struct platform_device *pdev)
 		 * for the VSP and must thus be used in place of the VSP device
 		 * to map DMA buffers.
 		 */
-		vsp1->bus_master = rcar_fcp_get_device(vsp1->fcp);
+		vsp1->bus_master =
+			rcar_fcp_get_bus_master(vsp1->fcp,
+						RCAR_FCP_UNCOMPRESSED);
 	} else {
 		vsp1->bus_master = vsp1->dev;
 	}
diff --git a/include/media/rcar-fcp.h b/include/media/rcar-fcp.h
index b60a7b176c37..dffffddf8ff3 100644
--- a/include/media/rcar-fcp.h
+++ b/include/media/rcar-fcp.h
@@ -16,10 +16,18 @@
 struct device_node;
 struct rcar_fcp_device;
 
+enum rcar_fcp_data_format {
+	RCAR_FCP_UNCOMPRESSED,
+	RCAR_FCP_FCNL_YUV_PLANAR,
+	RCAR_FCP_FCNL_YUV_PACKED,
+	RCAR_FCP_FCNL_RGB,
+};
+
 #if IS_ENABLED(CONFIG_VIDEO_RENESAS_FCP)
 struct rcar_fcp_device *rcar_fcp_get(const struct device_node *np);
 void rcar_fcp_put(struct rcar_fcp_device *fcp);
-struct device *rcar_fcp_get_device(struct rcar_fcp_device *fcp);
+struct device *rcar_fcp_get_bus_master(struct rcar_fcp_device *fcp,
+				       enum rcar_fcp_data_format format);
 int rcar_fcp_enable(struct rcar_fcp_device *fcp);
 void rcar_fcp_disable(struct rcar_fcp_device *fcp);
 #else
@@ -28,7 +36,9 @@ static inline struct rcar_fcp_device *rcar_fcp_get(const struct device_node *np)
 	return ERR_PTR(-ENOENT);
 }
 static inline void rcar_fcp_put(struct rcar_fcp_device *fcp) { }
-static inline struct device *rcar_fcp_get_device(struct rcar_fcp_device *fcp)
+static inline struct device *
+rcar_fcp_get_bus_master(struct rcar_fcp_device *fcp,
+			enum rcar_fcp_data_format format)
 {
 	return NULL;
 }
-- 
Regards,

Laurent Pinchart

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

* [RFC 11/13] v4l: rcar-fcp: Support FCNL decompression
  2017-09-26 10:05 [RFC 00/13] R-Car: Enable lossy compression in VSP video pipelines Laurent Pinchart
                   ` (11 preceding siblings ...)
  2017-09-26 10:06 ` [RFC 10/13] v4l: rcar-fcp: Prepare driver API for FCNL support Laurent Pinchart
@ 2017-09-26 10:06 ` Laurent Pinchart
  2017-09-26 10:06 ` [RFC 12/13] v4l: vsp1: Add support for near-lossless compression (FCNL) in the WPF Laurent Pinchart
  2017-09-26 10:06 ` [RFC 13/13] v4l: vsp1: Add support for near-lossless compression (FCNL) in the RPF Laurent Pinchart
  14 siblings, 0 replies; 23+ messages in thread
From: Laurent Pinchart @ 2017-09-26 10:06 UTC (permalink / raw)
  To: linux-renesas-soc

Create child devices associated with the lossy decompression reserved
memory areas and return them as decompression bus masters.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/platform/rcar-fcp.c | 165 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 161 insertions(+), 4 deletions(-)

diff --git a/drivers/media/platform/rcar-fcp.c b/drivers/media/platform/rcar-fcp.c
index ca5e1dddba03..445094f6a25e 100644
--- a/drivers/media/platform/rcar-fcp.c
+++ b/drivers/media/platform/rcar-fcp.c
@@ -17,6 +17,7 @@
 #include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/of_device.h>
+#include <linux/of_reserved_mem.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/slab.h>
@@ -70,12 +71,21 @@ enum rcar_fcp_type {
 	RCAR_FCPVI,
 };
 
+/**
+ * struct rcar_fcp_device - FCP device private data
+ * @list: list entry in the fcp_devices list
+ * @dev: physical (platform) device for the FCP
+ * @type: FCP device type (FCPF, FCPV, FCPVI)
+ * @mmio: memory-mapped I/O registers base
+ * @bus_masters: devices used for lossy decompression memory allocation
+ */
 struct rcar_fcp_device {
 	struct list_head list;
 	struct device *dev;
 
 	enum rcar_fcp_type type;
 	void __iomem *mmio;
+	struct device *bus_masters[4];
 };
 
 static LIST_HEAD(fcp_devices);
@@ -113,6 +123,7 @@ static void rcar_fcp_write(struct rcar_fcp_device *fcp, unsigned int reg,
 struct rcar_fcp_device *rcar_fcp_get(const struct device_node *np)
 {
 	struct rcar_fcp_device *fcp;
+	unsigned int i;
 
 	mutex_lock(&fcp_lock);
 
@@ -120,7 +131,8 @@ struct rcar_fcp_device *rcar_fcp_get(const struct device_node *np)
 		if (fcp->dev->of_node != np)
 			continue;
 
-		get_device(fcp->dev);
+		for (i = 0; i < ARRAY_SIZE(fcp->bus_masters); ++i)
+			get_device(fcp->bus_masters[i]);
 		goto done;
 	}
 
@@ -140,8 +152,12 @@ EXPORT_SYMBOL_GPL(rcar_fcp_get);
  */
 void rcar_fcp_put(struct rcar_fcp_device *fcp)
 {
-	if (fcp)
-		put_device(fcp->dev);
+	unsigned int i;
+
+	if (fcp) {
+		for (i = 0; i < ARRAY_SIZE(fcp->bus_masters); ++i)
+			get_device(fcp->bus_masters[i]);
+	}
 }
 EXPORT_SYMBOL_GPL(rcar_fcp_put);
 
@@ -172,7 +188,10 @@ EXPORT_SYMBOL_GPL(rcar_fcp_put);
 struct device *rcar_fcp_get_bus_master(struct rcar_fcp_device *fcp,
 				       enum rcar_fcp_data_format format)
 {
-	return fcp->dev;
+	if (format < ARRAY_SIZE(fcp->bus_masters))
+		return fcp->bus_masters[format];
+	else
+		return NULL;
 }
 EXPORT_SYMBOL_GPL(rcar_fcp_get_bus_master);
 
@@ -221,6 +240,136 @@ EXPORT_SYMBOL_GPL(rcar_fcp_disable);
  * Platform Driver
  */
 
+static void rcar_fcp_fcnl_dev_release(struct device *dev)
+{
+	of_reserved_mem_device_release(dev);
+	kfree(dev);
+}
+
+static int rcar_fcp_fcnl_dev_alloc(struct rcar_fcp_device *fcp,
+				   enum rcar_fcp_data_format format,
+				   unsigned int index)
+{
+	struct device *dev;
+	int ret;
+
+	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+	if (!dev)
+		return -ENOMEM;
+
+	device_initialize(dev);
+	dev_set_name(dev, "%s:fcnl%u", dev_name(fcp->dev), format);
+	dev->parent = fcp->dev;
+	dev->coherent_dma_mask = fcp->dev->coherent_dma_mask;
+	dev->dma_mask = fcp->dev->dma_mask;
+	dev->release = rcar_fcp_fcnl_dev_release;
+
+	ret = device_add(dev);
+	if (ret < 0)
+		goto error_put;
+
+	ret = of_reserved_mem_device_init_by_idx(dev, fcp->dev->of_node, index);
+	if (ret < 0)
+		goto error_del;
+
+	fcp->bus_masters[format] = dev;
+	return 0;
+
+error_del:
+	device_del(dev);
+error_put:
+	put_device(dev);
+	return ret;
+}
+
+static int rcar_fcp_fcnl_setup(struct rcar_fcp_device *fcp)
+{
+	unsigned int i;
+	int n_ranges;
+	int ret;
+
+	/* The uncompressed bus master must always be available. */
+	fcp->bus_masters[RCAR_FCP_UNCOMPRESSED] = get_device(fcp->dev);
+
+	n_ranges = of_property_count_elems_of_size(fcp->dev->of_node,
+						   "memory-region", 4);
+	if (n_ranges == -EINVAL) {
+		/*
+		 * The "memory-region" property is optional, treat the -EINVAL
+		 * error code as a non-fatal error. FCNL decompression will not
+		 * be available.
+		 */
+		return 0;
+	}
+
+	if (n_ranges < 0) {
+		dev_dbg(fcp->dev, "Invalid memory-region property\n");
+		return n_ranges;
+	}
+
+	/*
+	 * For each memory range retrieve the compression format and create the
+	 * DMA memory allocation device.
+	 */
+	for (i = 0; i < n_ranges; ++i) {
+		struct device_node *node;
+		enum rcar_fcp_data_format format;
+		u32 value;
+
+		node = of_parse_phandle(fcp->dev->of_node, "memory-region", i);
+		if (!node) {
+			/*
+			 * The target memory region might have been deleted by
+			 * the boot loader if empty. Do not treat this as an
+			 * error.
+			 */
+			continue;
+		}
+
+		ret = of_property_read_u32(node, "renesas,format", &value);
+		if (ret < 0) {
+			dev_dbg(fcp->dev,
+				"Skipping %s with no valid format property\n",
+				of_node_full_name(node));
+			continue;
+		}
+
+		/*
+		 * The software formats is equal to the hardware format plus
+		 * one.
+		 */
+		format = value + 1;
+
+		if (format == 0 || format >= ARRAY_SIZE(fcp->bus_masters)) {
+			dev_dbg(fcp->dev,
+				"Skipping %s with invalid format %u\n",
+				of_node_full_name(node), format);
+			continue;
+		}
+
+		if (fcp->bus_masters[format]) {
+			dev_dbg(fcp->dev,
+				"Skipping %s with duplicate format %u\n",
+				of_node_full_name(node), format);
+			continue;
+		}
+
+		ret = rcar_fcp_fcnl_dev_alloc(fcp, format, i);
+		if (ret < 0) {
+			dev_dbg(fcp->dev,
+				"Failed to allocate bus master device (%s) for format %u\n",
+				of_node_full_name(node), format);
+			return ret;
+		}
+
+		dev_dbg(fcp->dev,
+			"Allocated bus master device (%s) for format %u\n",
+			of_node_full_name(node), format);
+	}
+
+	return 0;
+}
+
 static int rcar_fcp_setup(struct rcar_fcp_device *fcp)
 {
 	static const char * const models[] = {
@@ -317,6 +466,10 @@ static int rcar_fcp_probe(struct platform_device *pdev)
 
 	pm_runtime_put(&pdev->dev);
 
+	ret = rcar_fcp_fcnl_setup(fcp);
+	if (ret < 0)
+		goto error_pm_disable;
+
 	mutex_lock(&fcp_lock);
 	list_add_tail(&fcp->list, &fcp_devices);
 	mutex_unlock(&fcp_lock);
@@ -335,11 +488,15 @@ static int rcar_fcp_probe(struct platform_device *pdev)
 static int rcar_fcp_remove(struct platform_device *pdev)
 {
 	struct rcar_fcp_device *fcp = platform_get_drvdata(pdev);
+	unsigned int i;
 
 	mutex_lock(&fcp_lock);
 	list_del(&fcp->list);
 	mutex_unlock(&fcp_lock);
 
+	for (i = 0; i < ARRAY_SIZE(fcp->bus_masters); ++i)
+		put_device(fcp->bus_masters[i]);
+
 	pm_runtime_disable(&pdev->dev);
 
 	return 0;
-- 
Regards,

Laurent Pinchart

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

* [RFC 12/13] v4l: vsp1: Add support for near-lossless compression (FCNL) in the WPF
  2017-09-26 10:05 [RFC 00/13] R-Car: Enable lossy compression in VSP video pipelines Laurent Pinchart
                   ` (12 preceding siblings ...)
  2017-09-26 10:06 ` [RFC 11/13] v4l: rcar-fcp: Support FCNL decompression Laurent Pinchart
@ 2017-09-26 10:06 ` Laurent Pinchart
  2017-09-26 10:06 ` [RFC 13/13] v4l: vsp1: Add support for near-lossless compression (FCNL) in the RPF Laurent Pinchart
  14 siblings, 0 replies; 23+ messages in thread
From: Laurent Pinchart @ 2017-09-26 10:06 UTC (permalink / raw)
  To: linux-renesas-soc

Visual near-lossless compression is a technique used to lower the memory
bandwidth consumption by transparently (de)compressing frames when
reading them from or writing them to memory.

When writing frames to memory the VSPI, VSPBC and VSPBD (through their
connnected FCP) can transparently compress them using FCNL. Implement
support for it.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/platform/vsp1/vsp1.h      |   1 +
 drivers/media/platform/vsp1/vsp1_drv.c  |   6 +-
 drivers/media/platform/vsp1/vsp1_pipe.c |  57 ++++++------
 drivers/media/platform/vsp1/vsp1_pipe.h |   2 +
 drivers/media/platform/vsp1/vsp1_regs.h |   1 +
 drivers/media/platform/vsp1/vsp1_rwpf.h |   1 +
 drivers/media/platform/vsp1/vsp1_wpf.c  | 157 ++++++++++++++++++++++----------
 7 files changed, 147 insertions(+), 78 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1.h b/drivers/media/platform/vsp1/vsp1.h
index 78ef838416b3..1295accca011 100644
--- a/drivers/media/platform/vsp1/vsp1.h
+++ b/drivers/media/platform/vsp1/vsp1.h
@@ -55,6 +55,7 @@ struct vsp1_uds;
 #define VSP1_HAS_HGO		(1 << 7)
 #define VSP1_HAS_HGT		(1 << 8)
 #define VSP1_HAS_BRS		(1 << 9)
+#define VSP1_HAS_FCNL		(1 << 10)
 
 struct vsp1_device_info {
 	u32 version;
diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
index 4253a76cc484..d74a2cd37a52 100644
--- a/drivers/media/platform/vsp1/vsp1_drv.c
+++ b/drivers/media/platform/vsp1/vsp1_drv.c
@@ -693,7 +693,7 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
 		.gen = 3,
 		.features = VSP1_HAS_CLU | VSP1_HAS_HGO | VSP1_HAS_HGT
 			  | VSP1_HAS_LUT | VSP1_HAS_SRU | VSP1_HAS_WPF_HFLIP
-			  | VSP1_HAS_WPF_VFLIP,
+			  | VSP1_HAS_WPF_VFLIP | VSP1_HAS_FCNL,
 		.rpf_count = 1,
 		.uds_count = 1,
 		.wpf_count = 1,
@@ -702,7 +702,7 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
 		.version = VI6_IP_VERSION_MODEL_VSPBD_GEN3,
 		.model = "VSP2-BD",
 		.gen = 3,
-		.features = VSP1_HAS_BRU | VSP1_HAS_WPF_VFLIP,
+		.features = VSP1_HAS_BRU | VSP1_HAS_WPF_VFLIP | VSP1_HAS_FCNL,
 		.rpf_count = 5,
 		.wpf_count = 1,
 		.num_bru_inputs = 5,
@@ -712,7 +712,7 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
 		.model = "VSP2-BC",
 		.gen = 3,
 		.features = VSP1_HAS_BRU | VSP1_HAS_CLU | VSP1_HAS_HGO
-			  | VSP1_HAS_LUT | VSP1_HAS_WPF_VFLIP,
+			  | VSP1_HAS_LUT | VSP1_HAS_WPF_VFLIP | VSP1_HAS_FCNL,
 		.rpf_count = 5,
 		.wpf_count = 1,
 		.num_bru_inputs = 5,
diff --git a/drivers/media/platform/vsp1/vsp1_pipe.c b/drivers/media/platform/vsp1/vsp1_pipe.c
index 44944ac86d9b..a2414266815c 100644
--- a/drivers/media/platform/vsp1/vsp1_pipe.c
+++ b/drivers/media/platform/vsp1/vsp1_pipe.c
@@ -17,6 +17,7 @@
 #include <linux/wait.h>
 
 #include <media/media-entity.h>
+#include <media/rcar-fcp.h>
 #include <media/v4l2-subdev.h>
 
 #include "vsp1.h"
@@ -37,113 +38,113 @@ static const struct vsp1_format_info vsp1_video_formats[] = {
 	{ V4L2_PIX_FMT_RGB332, MEDIA_BUS_FMT_ARGB8888_1X32,
 	  VI6_FMT_RGB_332, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
-	  1, { 8, 0, 0 }, false, false, 1, 1, false },
+	  1, { 8, 0, 0 }, false, false, 1, 1, false, RCAR_FCP_UNCOMPRESSED },
 	{ V4L2_PIX_FMT_ARGB444, MEDIA_BUS_FMT_ARGB8888_1X32,
 	  VI6_FMT_ARGB_4444, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 	  VI6_RPF_DSWAP_P_WDS,
-	  1, { 16, 0, 0 }, false, false, 1, 1, true },
+	  1, { 16, 0, 0 }, false, false, 1, 1, true, RCAR_FCP_UNCOMPRESSED },
 	{ V4L2_PIX_FMT_XRGB444, MEDIA_BUS_FMT_ARGB8888_1X32,
 	  VI6_FMT_XRGB_4444, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 	  VI6_RPF_DSWAP_P_WDS,
-	  1, { 16, 0, 0 }, false, false, 1, 1, false },
+	  1, { 16, 0, 0 }, false, false, 1, 1, false, RCAR_FCP_UNCOMPRESSED },
 	{ V4L2_PIX_FMT_ARGB555, MEDIA_BUS_FMT_ARGB8888_1X32,
 	  VI6_FMT_ARGB_1555, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 	  VI6_RPF_DSWAP_P_WDS,
-	  1, { 16, 0, 0 }, false, false, 1, 1, true },
+	  1, { 16, 0, 0 }, false, false, 1, 1, true, RCAR_FCP_UNCOMPRESSED },
 	{ V4L2_PIX_FMT_XRGB555, MEDIA_BUS_FMT_ARGB8888_1X32,
 	  VI6_FMT_XRGB_1555, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 	  VI6_RPF_DSWAP_P_WDS,
-	  1, { 16, 0, 0 }, false, false, 1, 1, false },
+	  1, { 16, 0, 0 }, false, false, 1, 1, false, RCAR_FCP_UNCOMPRESSED },
 	{ V4L2_PIX_FMT_RGB565, MEDIA_BUS_FMT_ARGB8888_1X32,
 	  VI6_FMT_RGB_565, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 	  VI6_RPF_DSWAP_P_WDS,
-	  1, { 16, 0, 0 }, false, false, 1, 1, false },
+	  1, { 16, 0, 0 }, false, false, 1, 1, false, RCAR_FCP_UNCOMPRESSED },
 	{ V4L2_PIX_FMT_BGR24, MEDIA_BUS_FMT_ARGB8888_1X32,
 	  VI6_FMT_BGR_888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
-	  1, { 24, 0, 0 }, false, false, 1, 1, false },
+	  1, { 24, 0, 0 }, false, false, 1, 1, false, RCAR_FCP_UNCOMPRESSED },
 	{ V4L2_PIX_FMT_RGB24, MEDIA_BUS_FMT_ARGB8888_1X32,
 	  VI6_FMT_RGB_888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
-	  1, { 24, 0, 0 }, false, false, 1, 1, false },
+	  1, { 24, 0, 0 }, false, false, 1, 1, false, RCAR_FCP_UNCOMPRESSED },
 	{ V4L2_PIX_FMT_ABGR32, MEDIA_BUS_FMT_ARGB8888_1X32,
 	  VI6_FMT_ARGB_8888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS,
-	  1, { 32, 0, 0 }, false, false, 1, 1, true },
+	  1, { 32, 0, 0 }, false, false, 1, 1, true, RCAR_FCP_UNCOMPRESSED },
 	{ V4L2_PIX_FMT_XBGR32, MEDIA_BUS_FMT_ARGB8888_1X32,
 	  VI6_FMT_ARGB_8888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS,
-	  1, { 32, 0, 0 }, false, false, 1, 1, false },
+	  1, { 32, 0, 0 }, false, false, 1, 1, false, RCAR_FCP_UNCOMPRESSED },
 	{ V4L2_PIX_FMT_ARGB32, MEDIA_BUS_FMT_ARGB8888_1X32,
 	  VI6_FMT_ARGB_8888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
-	  1, { 32, 0, 0 }, false, false, 1, 1, true },
+	  1, { 32, 0, 0 }, false, false, 1, 1, true, RCAR_FCP_FCNL_RGB },
 	{ V4L2_PIX_FMT_XRGB32, MEDIA_BUS_FMT_ARGB8888_1X32,
 	  VI6_FMT_ARGB_8888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
-	  1, { 32, 0, 0 }, false, false, 1, 1, false },
+	  1, { 32, 0, 0 }, false, false, 1, 1, false, RCAR_FCP_FCNL_RGB },
 	{ V4L2_PIX_FMT_HSV24, MEDIA_BUS_FMT_AHSV8888_1X32,
 	  VI6_FMT_RGB_888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
-	  1, { 24, 0, 0 }, false, false, 1, 1, false },
+	  1, { 24, 0, 0 }, false, false, 1, 1, false, RCAR_FCP_UNCOMPRESSED },
 	{ V4L2_PIX_FMT_HSV32, MEDIA_BUS_FMT_AHSV8888_1X32,
 	  VI6_FMT_ARGB_8888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
-	  1, { 32, 0, 0 }, false, false, 1, 1, false },
+	  1, { 32, 0, 0 }, false, false, 1, 1, false, RCAR_FCP_UNCOMPRESSED },
 	{ V4L2_PIX_FMT_UYVY, MEDIA_BUS_FMT_AYUV8_1X32,
 	  VI6_FMT_YUYV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
-	  1, { 16, 0, 0 }, false, false, 2, 1, false },
+	  1, { 16, 0, 0 }, false, false, 2, 1, false, RCAR_FCP_UNCOMPRESSED },
 	{ V4L2_PIX_FMT_VYUY, MEDIA_BUS_FMT_AYUV8_1X32,
 	  VI6_FMT_YUYV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
-	  1, { 16, 0, 0 }, false, true, 2, 1, false },
+	  1, { 16, 0, 0 }, false, true, 2, 1, false, RCAR_FCP_UNCOMPRESSED },
 	{ V4L2_PIX_FMT_YUYV, MEDIA_BUS_FMT_AYUV8_1X32,
 	  VI6_FMT_YUYV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
-	  1, { 16, 0, 0 }, true, false, 2, 1, false },
+	  1, { 16, 0, 0 }, true, false, 2, 1, false, RCAR_FCP_FCNL_YUV_PACKED },
 	{ V4L2_PIX_FMT_YVYU, MEDIA_BUS_FMT_AYUV8_1X32,
 	  VI6_FMT_YUYV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
-	  1, { 16, 0, 0 }, true, true, 2, 1, false },
+	  1, { 16, 0, 0 }, true, true, 2, 1, false, RCAR_FCP_UNCOMPRESSED },
 	{ V4L2_PIX_FMT_NV12M, MEDIA_BUS_FMT_AYUV8_1X32,
 	  VI6_FMT_Y_UV_420, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
-	  2, { 8, 16, 0 }, false, false, 2, 2, false },
+	  2, { 8, 16, 0 }, false, false, 2, 2, false, RCAR_FCP_UNCOMPRESSED },
 	{ V4L2_PIX_FMT_NV21M, MEDIA_BUS_FMT_AYUV8_1X32,
 	  VI6_FMT_Y_UV_420, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
-	  2, { 8, 16, 0 }, false, true, 2, 2, false },
+	  2, { 8, 16, 0 }, false, true, 2, 2, false, RCAR_FCP_UNCOMPRESSED },
 	{ V4L2_PIX_FMT_NV16M, MEDIA_BUS_FMT_AYUV8_1X32,
 	  VI6_FMT_Y_UV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
-	  2, { 8, 16, 0 }, false, false, 2, 1, false },
+	  2, { 8, 16, 0 }, false, false, 2, 1, false, RCAR_FCP_UNCOMPRESSED },
 	{ V4L2_PIX_FMT_NV61M, MEDIA_BUS_FMT_AYUV8_1X32,
 	  VI6_FMT_Y_UV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
-	  2, { 8, 16, 0 }, false, true, 2, 1, false },
+	  2, { 8, 16, 0 }, false, true, 2, 1, false, RCAR_FCP_UNCOMPRESSED },
 	{ V4L2_PIX_FMT_YUV420M, MEDIA_BUS_FMT_AYUV8_1X32,
 	  VI6_FMT_Y_U_V_420, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
-	  3, { 8, 8, 8 }, false, false, 2, 2, false },
+	  3, { 8, 8, 8 }, false, false, 2, 2, false, RCAR_FCP_FCNL_YUV_PLANAR },
 	{ V4L2_PIX_FMT_YVU420M, MEDIA_BUS_FMT_AYUV8_1X32,
 	  VI6_FMT_Y_U_V_420, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
-	  3, { 8, 8, 8 }, false, true, 2, 2, false },
+	  3, { 8, 8, 8 }, false, true, 2, 2, false, RCAR_FCP_FCNL_YUV_PLANAR },
 	{ V4L2_PIX_FMT_YUV422M, MEDIA_BUS_FMT_AYUV8_1X32,
 	  VI6_FMT_Y_U_V_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
-	  3, { 8, 8, 8 }, false, false, 2, 1, false },
+	  3, { 8, 8, 8 }, false, false, 2, 1, false, RCAR_FCP_FCNL_YUV_PLANAR },
 	{ V4L2_PIX_FMT_YVU422M, MEDIA_BUS_FMT_AYUV8_1X32,
 	  VI6_FMT_Y_U_V_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
-	  3, { 8, 8, 8 }, false, true, 2, 1, false },
+	  3, { 8, 8, 8 }, false, true, 2, 1, false, RCAR_FCP_FCNL_YUV_PLANAR },
 	{ V4L2_PIX_FMT_YUV444M, MEDIA_BUS_FMT_AYUV8_1X32,
 	  VI6_FMT_Y_U_V_444, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
-	  3, { 8, 8, 8 }, false, false, 1, 1, false },
+	  3, { 8, 8, 8 }, false, false, 1, 1, false, RCAR_FCP_FCNL_YUV_PLANAR },
 	{ V4L2_PIX_FMT_YVU444M, MEDIA_BUS_FMT_AYUV8_1X32,
 	  VI6_FMT_Y_U_V_444, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
-	  3, { 8, 8, 8 }, false, true, 1, 1, false },
+	  3, { 8, 8, 8 }, false, true, 1, 1, false, RCAR_FCP_FCNL_YUV_PLANAR },
 };
 
 /**
diff --git a/drivers/media/platform/vsp1/vsp1_pipe.h b/drivers/media/platform/vsp1/vsp1_pipe.h
index dfff9b5685fe..2665579a70d3 100644
--- a/drivers/media/platform/vsp1/vsp1_pipe.h
+++ b/drivers/media/platform/vsp1/vsp1_pipe.h
@@ -36,6 +36,7 @@ struct vsp1_rwpf;
  * @hsub: horizontal subsampling factor
  * @vsub: vertical subsampling factor
  * @alpha: has an alpha channel
+ * @fcnl: the FCNL compression method, UNCOMPRESSED if not supported
  */
 struct vsp1_format_info {
 	u32 fourcc;
@@ -49,6 +50,7 @@ struct vsp1_format_info {
 	unsigned int hsub;
 	unsigned int vsub;
 	bool alpha;
+	unsigned int fcnl;
 };
 
 enum vsp1_pipeline_state {
diff --git a/drivers/media/platform/vsp1/vsp1_regs.h b/drivers/media/platform/vsp1/vsp1_regs.h
index 26c4ffad2f46..4fd01d6ae813 100644
--- a/drivers/media/platform/vsp1/vsp1_regs.h
+++ b/drivers/media/platform/vsp1/vsp1_regs.h
@@ -260,6 +260,7 @@
 #define VI6_WPF_OUTFMT_PDV_MASK		(0xff << 24)
 #define VI6_WPF_OUTFMT_PDV_SHIFT	24
 #define VI6_WPF_OUTFMT_PXA		(1 << 23)
+#define VI6_WPF_OUTFMT_FCNL		(1 << 20)
 #define VI6_WPF_OUTFMT_ROT		(1 << 18)
 #define VI6_WPF_OUTFMT_HFLP		(1 << 17)
 #define VI6_WPF_OUTFMT_FLP		(1 << 16)
diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.h b/drivers/media/platform/vsp1/vsp1_rwpf.h
index 58215a7ab631..c6cbb731c036 100644
--- a/drivers/media/platform/vsp1/vsp1_rwpf.h
+++ b/drivers/media/platform/vsp1/vsp1_rwpf.h
@@ -50,6 +50,7 @@ struct vsp1_rwpf {
 	unsigned int bru_input;
 
 	unsigned int alpha;
+	bool fcnl;
 
 	u32 mult_alpha;
 	u32 outfmt;
diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c
index f7f3b4b2c2de..fafb11ceaf3f 100644
--- a/drivers/media/platform/vsp1/vsp1_wpf.c
+++ b/drivers/media/platform/vsp1/vsp1_wpf.c
@@ -40,23 +40,53 @@ static inline void vsp1_wpf_write(struct vsp1_rwpf *wpf,
  * Controls
  */
 
+#define V4L2_CID_VSP1_FCNL			(V4L2_CID_USER_BASE | 0x1001)
+
 enum wpf_flip_ctrl {
 	WPF_CTRL_VFLIP = 0,
 	WPF_CTRL_HFLIP = 1,
 };
 
-static int vsp1_wpf_set_rotation(struct vsp1_rwpf *wpf, unsigned int rotation)
+static int vsp1_wpf_set_compression(struct vsp1_rwpf *wpf, bool fcnl)
+{
+	struct vsp1_video *video = wpf->video;
+	int ret = 0;
+
+	if (fcnl == wpf->fcnl)
+		return 0;
+
+	/* FCNL can't be changed when buffers are allocated. */
+	mutex_lock(&video->lock);
+
+	if (vb2_is_busy(&video->queue)) {
+		ret = -EBUSY;
+		goto done;
+	}
+
+	mutex_lock(&wpf->entity.lock);
+	wpf->fcnl = fcnl;
+	mutex_unlock(&wpf->entity.lock);
+
+done:
+	mutex_unlock(&video->lock);
+	return ret;
+}
+
+static int vsp1_wpf_set_rotation(struct vsp1_rwpf *wpf)
 {
 	struct vsp1_video *video = wpf->video;
 	struct v4l2_mbus_framefmt *sink_format;
 	struct v4l2_mbus_framefmt *source_format;
+	unsigned int rotation;
 	bool rotate;
-	int ret = 0;
+	u32 flip = 0;
 
 	/*
-	 * Only consider the 0°/180° from/to 90°/270° modifications, the rest
-	 * is taken care of by the flipping configuration.
+	 * Update the rotation. Only consider the 0°/180° from/to 90°/270°
+	 * modifications, the rest is taken care of by the flipping
+	 * configuration.
 	 */
+	rotation = wpf->flip.ctrls.rotate ? wpf->flip.ctrls.rotate->val : 0;
 	rotate = rotation == 90 || rotation == 270;
 	if (rotate == wpf->flip.rotate)
 		return 0;
@@ -65,8 +95,8 @@ static int vsp1_wpf_set_rotation(struct vsp1_rwpf *wpf, unsigned int rotation)
 	mutex_lock(&video->lock);
 
 	if (vb2_is_busy(&video->queue)) {
-		ret = -EBUSY;
-		goto done;
+		mutex_unlock(&video->lock);
+		return -EBUSY;
 	}
 
 	sink_format = vsp1_entity_get_pad_format(&wpf->entity,
@@ -89,25 +119,7 @@ static int vsp1_wpf_set_rotation(struct vsp1_rwpf *wpf, unsigned int rotation)
 	wpf->flip.rotate = rotate;
 
 	mutex_unlock(&wpf->entity.lock);
-
-done:
 	mutex_unlock(&video->lock);
-	return ret;
-}
-
-static int vsp1_wpf_s_ctrl(struct v4l2_ctrl *ctrl)
-{
-	struct vsp1_rwpf *wpf =
-		container_of(ctrl->handler, struct vsp1_rwpf, ctrls);
-	unsigned int rotation;
-	u32 flip = 0;
-	int ret;
-
-	/* Update the rotation. */
-	rotation = wpf->flip.ctrls.rotate ? wpf->flip.ctrls.rotate->val : 0;
-	ret = vsp1_wpf_set_rotation(wpf, rotation);
-	if (ret < 0)
-		return ret;
 
 	/*
 	 * Compute the flip value resulting from all three controls, with
@@ -131,46 +143,86 @@ static int vsp1_wpf_s_ctrl(struct v4l2_ctrl *ctrl)
 	return 0;
 }
 
+static int vsp1_wpf_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct vsp1_rwpf *wpf =
+		container_of(ctrl->handler, struct vsp1_rwpf, ctrls);
+
+	/*
+	 * TODO: Handle the interactions between rotation and FCNL, when FCNL
+	 * and rotation are both enabled the output format is restricted to
+	 * ARGB888.
+	 */
+	switch (ctrl->id) {
+	case V4L2_CID_VSP1_FCNL:
+		return vsp1_wpf_set_compression(wpf, ctrl->val);
+
+	case V4L2_CID_VFLIP:
+	case V4L2_CID_HFLIP:
+	case V4L2_CID_ROTATE:
+	default:
+		return vsp1_wpf_set_rotation(wpf);
+	}
+}
+
 static const struct v4l2_ctrl_ops vsp1_wpf_ctrl_ops = {
 	.s_ctrl = vsp1_wpf_s_ctrl,
 };
 
+static const struct v4l2_ctrl_config vsp1_wpf_fcnl_ctrl = {
+	.ops = &vsp1_wpf_ctrl_ops,
+	.id = V4L2_CID_VSP1_FCNL,
+	.name = "Near-Lossless Compression",
+	.type = V4L2_CTRL_TYPE_BOOLEAN,
+	.min = 0,
+	.max = 1,
+	.step = 1,
+	.def = 0,
+};
+
 static int wpf_init_controls(struct vsp1_rwpf *wpf)
 {
 	struct vsp1_device *vsp1 = wpf->entity.vsp1;
-	unsigned int num_flip_ctrls;
+	unsigned int num_ctrls = 0;
+	bool vflip = false;
+	bool hflip = false;
 
 	spin_lock_init(&wpf->flip.lock);
 
-	if (wpf->entity.index != 0) {
+	if (wpf->entity.index == 0) {
 		/* Only WPF0 supports flipping. */
-		num_flip_ctrls = 0;
-	} else if (vsp1->info->features & VSP1_HAS_WPF_HFLIP) {
-		/*
-		 * When horizontal flip is supported the WPF implements three
-		 * controls (horizontal flip, vertical flip and rotation).
-		 */
-		num_flip_ctrls = 3;
-	} else if (vsp1->info->features & VSP1_HAS_WPF_VFLIP) {
-		/*
-		 * When only vertical flip is supported the WPF implements a
-		 * single control (vertical flip).
-		 */
-		num_flip_ctrls = 1;
-	} else {
-		/* Otherwise flipping is not supported. */
-		num_flip_ctrls = 0;
+		if (vsp1->info->features & VSP1_HAS_WPF_HFLIP) {
+			/*
+			 * When horizontal flip is supported the WPF implements
+			 * three controls (horizontal flip, vertical flip and
+			 * rotation).
+			 */
+			vflip = true;
+			hflip = true;
+			num_ctrls += 3;
+		} else if (vsp1->info->features & VSP1_HAS_WPF_VFLIP) {
+			/*
+			 * When only vertical flip is supported the WPF
+			 * implements a single control (vertical flip).
+			 */
+			vflip = true;
+			hflip = false;
+			num_ctrls += 1;
+		}
 	}
 
-	vsp1_rwpf_init_ctrls(wpf, num_flip_ctrls);
+	if (vsp1->info->features & VSP1_HAS_FCNL)
+		num_ctrls++;
+
+	vsp1_rwpf_init_ctrls(wpf, num_ctrls);
 
-	if (num_flip_ctrls >= 1) {
+	if (vflip) {
 		wpf->flip.ctrls.vflip =
 			v4l2_ctrl_new_std(&wpf->ctrls, &vsp1_wpf_ctrl_ops,
 					  V4L2_CID_VFLIP, 0, 1, 1, 0);
 	}
 
-	if (num_flip_ctrls == 3) {
+	if (hflip) {
 		wpf->flip.ctrls.hflip =
 			v4l2_ctrl_new_std(&wpf->ctrls, &vsp1_wpf_ctrl_ops,
 					  V4L2_CID_HFLIP, 0, 1, 1, 0);
@@ -180,6 +232,9 @@ static int wpf_init_controls(struct vsp1_rwpf *wpf)
 		v4l2_ctrl_cluster(3, &wpf->flip.ctrls.vflip);
 	}
 
+	if (vsp1->info->features & VSP1_HAS_FCNL)
+		v4l2_ctrl_new_custom(&wpf->ctrls, &vsp1_wpf_fcnl_ctrl, NULL);
+
 	if (wpf->ctrls.error) {
 		dev_err(vsp1->dev, "wpf%u: failed to initialize controls\n",
 			wpf->entity.index);
@@ -402,6 +457,9 @@ static void wpf_configure(struct vsp1_entity *entity,
 		if (wpf->flip.rotate)
 			outfmt |= VI6_WPF_OUTFMT_ROT;
 
+		if (wpf->fcnl && fmtinfo->fcnl)
+			outfmt |= VI6_WPF_OUTFMT_FCNL;
+
 		if (fmtinfo->alpha)
 			outfmt |= VI6_WPF_OUTFMT_PXA;
 		if (fmtinfo->swap_yc)
@@ -409,14 +467,19 @@ static void wpf_configure(struct vsp1_entity *entity,
 		if (fmtinfo->swap_uv)
 			outfmt |= VI6_WPF_OUTFMT_SPUVS;
 
-		/* Destination stride and byte swapping. */
+		/*
+		 * Destination stride and byte swapping. When FCNL is enabled
+		 * data swapping must be hardcoded to VI6_RPF_DSWAP_P_LLS.
+		 */
 		vsp1_wpf_write(wpf, dl, VI6_WPF_DSTM_STRIDE_Y,
 			       format->plane_fmt[0].bytesperline);
 		if (format->num_planes > 1)
 			vsp1_wpf_write(wpf, dl, VI6_WPF_DSTM_STRIDE_C,
 				       format->plane_fmt[1].bytesperline);
 
-		vsp1_wpf_write(wpf, dl, VI6_WPF_DSWAP, fmtinfo->swap);
+		vsp1_wpf_write(wpf, dl, VI6_WPF_DSWAP,
+			       wpf->fcnl && fmtinfo->fcnl ?
+			       VI6_RPF_DSWAP_P_LLS : fmtinfo->swap);
 
 		if (vsp1->info->features & VSP1_HAS_WPF_HFLIP &&
 		    wpf->entity.index == 0)
-- 
Regards,

Laurent Pinchart

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

* [RFC 13/13] v4l: vsp1: Add support for near-lossless compression (FCNL) in the RPF
  2017-09-26 10:05 [RFC 00/13] R-Car: Enable lossy compression in VSP video pipelines Laurent Pinchart
                   ` (13 preceding siblings ...)
  2017-09-26 10:06 ` [RFC 12/13] v4l: vsp1: Add support for near-lossless compression (FCNL) in the WPF Laurent Pinchart
@ 2017-09-26 10:06 ` Laurent Pinchart
  14 siblings, 0 replies; 23+ messages in thread
From: Laurent Pinchart @ 2017-09-26 10:06 UTC (permalink / raw)
  To: linux-renesas-soc

Visual near-lossless compression is a technique used to lower the memory
bandwidth consumption by transparently (de)compressing frames when
reading them from or writing them to memory.

When reading frames from memory the DDR controller can transparently
decompress them using FCNL. Implement support for it on the read side of
the VSP.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/platform/vsp1/vsp1_rwpf.c  |  50 +++++++++++
 drivers/media/platform/vsp1/vsp1_video.c |  22 ++++-
 drivers/media/platform/vsp1/vsp1_wpf.c   | 150 +++++++++++--------------------
 3 files changed, 121 insertions(+), 101 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.c b/drivers/media/platform/vsp1/vsp1_rwpf.c
index cfd8f1904fa6..e71399761eed 100644
--- a/drivers/media/platform/vsp1/vsp1_rwpf.c
+++ b/drivers/media/platform/vsp1/vsp1_rwpf.c
@@ -257,12 +257,42 @@ const struct v4l2_subdev_pad_ops vsp1_rwpf_pad_ops = {
  * Controls
  */
 
+#define V4L2_CID_VSP1_FCNL			(V4L2_CID_USER_BASE | 0x1001)
+
+static int vsp1_rwpf_set_compression(struct vsp1_rwpf *rwpf, bool fcnl)
+{
+	struct vsp1_video *video = rwpf->video;
+	int ret = 0;
+
+	if (fcnl == rwpf->fcnl)
+		return 0;
+
+	/* FCNL can't be changed when buffers are allocated. */
+	mutex_lock(&video->lock);
+
+	if (vb2_is_busy(&video->queue)) {
+		ret = -EBUSY;
+		goto done;
+	}
+
+	mutex_lock(&rwpf->entity.lock);
+	rwpf->fcnl = fcnl;
+	mutex_unlock(&rwpf->entity.lock);
+
+done:
+	mutex_unlock(&video->lock);
+	return ret;
+}
+
 static int vsp1_rwpf_s_ctrl(struct v4l2_ctrl *ctrl)
 {
 	struct vsp1_rwpf *rwpf =
 		container_of(ctrl->handler, struct vsp1_rwpf, ctrls);
 
 	switch (ctrl->id) {
+	case V4L2_CID_VSP1_FCNL:
+		return vsp1_rwpf_set_compression(rwpf, ctrl->val);
+
 	case V4L2_CID_ALPHA_COMPONENT:
 		rwpf->alpha = ctrl->val;
 		break;
@@ -275,12 +305,32 @@ static const struct v4l2_ctrl_ops vsp1_rwpf_ctrl_ops = {
 	.s_ctrl = vsp1_rwpf_s_ctrl,
 };
 
+static const struct v4l2_ctrl_config vsp1_rwpf_fcnl_ctrl = {
+	.ops = &vsp1_rwpf_ctrl_ops,
+	.id = V4L2_CID_VSP1_FCNL,
+	.name = "Near-Lossless Compression",
+	.type = V4L2_CTRL_TYPE_BOOLEAN,
+	.min = 0,
+	.max = 1,
+	.step = 1,
+	.def = 0,
+};
+
 int vsp1_rwpf_init_ctrls(struct vsp1_rwpf *rwpf, unsigned int ncontrols)
 {
+	struct vsp1_device *vsp1 = rwpf->entity.vsp1;
+
+	if (vsp1->info->features & VSP1_HAS_FCNL)
+		ncontrols++;
+
 	v4l2_ctrl_handler_init(&rwpf->ctrls, ncontrols + 1);
+
 	v4l2_ctrl_new_std(&rwpf->ctrls, &vsp1_rwpf_ctrl_ops,
 			  V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 255);
 
+	if (vsp1->info->features & VSP1_HAS_FCNL)
+		v4l2_ctrl_new_custom(&rwpf->ctrls, &vsp1_rwpf_fcnl_ctrl, NULL);
+
 	rwpf->entity.subdev.ctrl_handler = &rwpf->ctrls;
 
 	return rwpf->ctrls.error;
diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
index c2d3b8f0f487..b188780dfc69 100644
--- a/drivers/media/platform/vsp1/vsp1_video.c
+++ b/drivers/media/platform/vsp1/vsp1_video.c
@@ -20,6 +20,7 @@
 #include <linux/wait.h>
 
 #include <media/media-entity.h>
+#include <media/rcar-fcp.h>
 #include <media/v4l2-dev.h>
 #include <media/v4l2-fh.h>
 #include <media/v4l2-ioctl.h>
@@ -728,7 +729,10 @@ vsp1_video_queue_setup(struct vb2_queue *vq,
 		       unsigned int sizes[], struct device *alloc_devs[])
 {
 	struct vsp1_video *video = vb2_get_drv_priv(vq);
+	struct vsp1_device *vsp1 = video->vsp1;
 	const struct v4l2_pix_format_mplane *format = &video->rwpf->format;
+	const struct vsp1_format_info *fmtinfo = video->rwpf->fmtinfo;
+	struct device *alloc_dev;
 	unsigned int i;
 
 	if (*nplanes) {
@@ -741,10 +745,26 @@ vsp1_video_queue_setup(struct vb2_queue *vq,
 		return 0;
 	}
 
+	/*
+	 * Select the appropriate allocation device. Perform FCNL decompression
+	 * on the RPF if requested by the user, supported by the format, and
+	 * supported by the FCP.
+	 */
+	if (video->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
+	    video->rwpf->fcnl && fmtinfo->fcnl) {
+		alloc_dev = rcar_fcp_get_bus_master(vsp1->fcp, fmtinfo->fcnl);
+		if (!alloc_dev)
+			return -EINVAL;
+	} else {
+		alloc_dev = video->vsp1->bus_master;
+	}
+
 	*nplanes = format->num_planes;
 
-	for (i = 0; i < format->num_planes; ++i)
+	for (i = 0; i < format->num_planes; ++i) {
 		sizes[i] = format->plane_fmt[i].sizeimage;
+		alloc_devs[i] = alloc_dev;
+	}
 
 	return 0;
 }
diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c
index fafb11ceaf3f..c0e50eb7eca2 100644
--- a/drivers/media/platform/vsp1/vsp1_wpf.c
+++ b/drivers/media/platform/vsp1/vsp1_wpf.c
@@ -40,53 +40,23 @@ static inline void vsp1_wpf_write(struct vsp1_rwpf *wpf,
  * Controls
  */
 
-#define V4L2_CID_VSP1_FCNL			(V4L2_CID_USER_BASE | 0x1001)
-
 enum wpf_flip_ctrl {
 	WPF_CTRL_VFLIP = 0,
 	WPF_CTRL_HFLIP = 1,
 };
 
-static int vsp1_wpf_set_compression(struct vsp1_rwpf *wpf, bool fcnl)
-{
-	struct vsp1_video *video = wpf->video;
-	int ret = 0;
-
-	if (fcnl == wpf->fcnl)
-		return 0;
-
-	/* FCNL can't be changed when buffers are allocated. */
-	mutex_lock(&video->lock);
-
-	if (vb2_is_busy(&video->queue)) {
-		ret = -EBUSY;
-		goto done;
-	}
-
-	mutex_lock(&wpf->entity.lock);
-	wpf->fcnl = fcnl;
-	mutex_unlock(&wpf->entity.lock);
-
-done:
-	mutex_unlock(&video->lock);
-	return ret;
-}
-
-static int vsp1_wpf_set_rotation(struct vsp1_rwpf *wpf)
+static int vsp1_wpf_set_rotation(struct vsp1_rwpf *wpf, unsigned int rotation)
 {
 	struct vsp1_video *video = wpf->video;
 	struct v4l2_mbus_framefmt *sink_format;
 	struct v4l2_mbus_framefmt *source_format;
-	unsigned int rotation;
 	bool rotate;
-	u32 flip = 0;
+	int ret = 0;
 
 	/*
-	 * Update the rotation. Only consider the 0°/180° from/to 90°/270°
-	 * modifications, the rest is taken care of by the flipping
-	 * configuration.
+	 * Only consider the 0°/180° from/to 90°/270° modifications, the rest
+	 * is taken care of by the flipping configuration.
 	 */
-	rotation = wpf->flip.ctrls.rotate ? wpf->flip.ctrls.rotate->val : 0;
 	rotate = rotation == 90 || rotation == 270;
 	if (rotate == wpf->flip.rotate)
 		return 0;
@@ -95,8 +65,8 @@ static int vsp1_wpf_set_rotation(struct vsp1_rwpf *wpf)
 	mutex_lock(&video->lock);
 
 	if (vb2_is_busy(&video->queue)) {
-		mutex_unlock(&video->lock);
-		return -EBUSY;
+		ret = -EBUSY;
+		goto done;
 	}
 
 	sink_format = vsp1_entity_get_pad_format(&wpf->entity,
@@ -119,7 +89,25 @@ static int vsp1_wpf_set_rotation(struct vsp1_rwpf *wpf)
 	wpf->flip.rotate = rotate;
 
 	mutex_unlock(&wpf->entity.lock);
+
+done:
 	mutex_unlock(&video->lock);
+	return ret;
+}
+
+static int vsp1_wpf_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct vsp1_rwpf *wpf =
+		container_of(ctrl->handler, struct vsp1_rwpf, ctrls);
+	unsigned int rotation;
+	u32 flip = 0;
+	int ret;
+
+	/* Update the rotation. */
+	rotation = wpf->flip.ctrls.rotate ? wpf->flip.ctrls.rotate->val : 0;
+	ret = vsp1_wpf_set_rotation(wpf, rotation);
+	if (ret < 0)
+		return ret;
 
 	/*
 	 * Compute the flip value resulting from all three controls, with
@@ -143,86 +131,46 @@ static int vsp1_wpf_set_rotation(struct vsp1_rwpf *wpf)
 	return 0;
 }
 
-static int vsp1_wpf_s_ctrl(struct v4l2_ctrl *ctrl)
-{
-	struct vsp1_rwpf *wpf =
-		container_of(ctrl->handler, struct vsp1_rwpf, ctrls);
-
-	/*
-	 * TODO: Handle the interactions between rotation and FCNL, when FCNL
-	 * and rotation are both enabled the output format is restricted to
-	 * ARGB888.
-	 */
-	switch (ctrl->id) {
-	case V4L2_CID_VSP1_FCNL:
-		return vsp1_wpf_set_compression(wpf, ctrl->val);
-
-	case V4L2_CID_VFLIP:
-	case V4L2_CID_HFLIP:
-	case V4L2_CID_ROTATE:
-	default:
-		return vsp1_wpf_set_rotation(wpf);
-	}
-}
-
 static const struct v4l2_ctrl_ops vsp1_wpf_ctrl_ops = {
 	.s_ctrl = vsp1_wpf_s_ctrl,
 };
 
-static const struct v4l2_ctrl_config vsp1_wpf_fcnl_ctrl = {
-	.ops = &vsp1_wpf_ctrl_ops,
-	.id = V4L2_CID_VSP1_FCNL,
-	.name = "Near-Lossless Compression",
-	.type = V4L2_CTRL_TYPE_BOOLEAN,
-	.min = 0,
-	.max = 1,
-	.step = 1,
-	.def = 0,
-};
-
 static int wpf_init_controls(struct vsp1_rwpf *wpf)
 {
 	struct vsp1_device *vsp1 = wpf->entity.vsp1;
-	unsigned int num_ctrls = 0;
-	bool vflip = false;
-	bool hflip = false;
+	unsigned int num_flip_ctrls;
 
 	spin_lock_init(&wpf->flip.lock);
 
-	if (wpf->entity.index == 0) {
+	if (wpf->entity.index != 0) {
 		/* Only WPF0 supports flipping. */
-		if (vsp1->info->features & VSP1_HAS_WPF_HFLIP) {
-			/*
-			 * When horizontal flip is supported the WPF implements
-			 * three controls (horizontal flip, vertical flip and
-			 * rotation).
-			 */
-			vflip = true;
-			hflip = true;
-			num_ctrls += 3;
-		} else if (vsp1->info->features & VSP1_HAS_WPF_VFLIP) {
-			/*
-			 * When only vertical flip is supported the WPF
-			 * implements a single control (vertical flip).
-			 */
-			vflip = true;
-			hflip = false;
-			num_ctrls += 1;
-		}
+		num_flip_ctrls = 0;
+	} else if (vsp1->info->features & VSP1_HAS_WPF_HFLIP) {
+		/*
+		 * When horizontal flip is supported the WPF implements three
+		 * controls (horizontal flip, vertical flip and rotation).
+		 */
+		num_flip_ctrls = 3;
+	} else if (vsp1->info->features & VSP1_HAS_WPF_VFLIP) {
+		/*
+		 * When only vertical flip is supported the WPF implements a
+		 * single control (vertical flip).
+		 */
+		num_flip_ctrls = 1;
+	} else {
+		/* Otherwise flipping is not supported. */
+		num_flip_ctrls = 0;
 	}
 
-	if (vsp1->info->features & VSP1_HAS_FCNL)
-		num_ctrls++;
+	vsp1_rwpf_init_ctrls(wpf, num_flip_ctrls);
 
-	vsp1_rwpf_init_ctrls(wpf, num_ctrls);
-
-	if (vflip) {
+	if (num_flip_ctrls >= 1) {
 		wpf->flip.ctrls.vflip =
 			v4l2_ctrl_new_std(&wpf->ctrls, &vsp1_wpf_ctrl_ops,
 					  V4L2_CID_VFLIP, 0, 1, 1, 0);
 	}
 
-	if (hflip) {
+	if (num_flip_ctrls == 3) {
 		wpf->flip.ctrls.hflip =
 			v4l2_ctrl_new_std(&wpf->ctrls, &vsp1_wpf_ctrl_ops,
 					  V4L2_CID_HFLIP, 0, 1, 1, 0);
@@ -232,9 +180,6 @@ static int wpf_init_controls(struct vsp1_rwpf *wpf)
 		v4l2_ctrl_cluster(3, &wpf->flip.ctrls.vflip);
 	}
 
-	if (vsp1->info->features & VSP1_HAS_FCNL)
-		v4l2_ctrl_new_custom(&wpf->ctrls, &vsp1_wpf_fcnl_ctrl, NULL);
-
 	if (wpf->ctrls.error) {
 		dev_err(vsp1->dev, "wpf%u: failed to initialize controls\n",
 			wpf->entity.index);
@@ -454,6 +399,11 @@ static void wpf_configure(struct vsp1_entity *entity,
 
 		outfmt = fmtinfo->hwfmt << VI6_WPF_OUTFMT_WRFMT_SHIFT;
 
+		/*
+		 * TODO: Handle the interactions between rotation and FCNL, when
+		 * FCNL and rotation are both enabled the output format is
+		 * restricted to ARGB888.
+		 */
 		if (wpf->flip.rotate)
 			outfmt |= VI6_WPF_OUTFMT_ROT;
 
-- 
Regards,

Laurent Pinchart

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

* Re: [RFC 02/13] dt-bindings: media: renesas-fcp: Add a compatible string for VSPI FCP
  2017-09-26 10:05 ` [RFC 02/13] dt-bindings: media: renesas-fcp: Add a compatible string for VSPI FCP Laurent Pinchart
@ 2017-09-26 11:47   ` Geert Uytterhoeven
  2017-09-26 12:39     ` Laurent Pinchart
  0 siblings, 1 reply; 23+ messages in thread
From: Geert Uytterhoeven @ 2017-09-26 11:47 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: Linux-Renesas

Hi Laurent,

On Tue, Sep 26, 2017 at 12:05 PM, Laurent Pinchart
<laurent.pinchart+renesas@ideasonboard.com> wrote:
> The FCP instances associated with a VSPI must be treated differently
> than the ones associated with another type of VSP. Add a new compatible
> string to allow telling them apart.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>  Documentation/devicetree/bindings/media/renesas,fcp.txt | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/devicetree/bindings/media/renesas,fcp.txt b/Documentation/devicetree/bindings/media/renesas,fcp.txt
> index 3ec91803ba58..c1f28736e2d6 100644
> --- a/Documentation/devicetree/bindings/media/renesas,fcp.txt
> +++ b/Documentation/devicetree/bindings/media/renesas,fcp.txt
> @@ -11,7 +11,8 @@ are paired with. These DT bindings currently support the FCPV and FCPF.
>
>   - compatible: Must be one or more of the following
>
> -   - "renesas,fcpv" for generic compatible 'FCP for VSP'
> +   - "renesas,fcpvi" for generic compatible 'FCP for VSPI'
> +   - "renesas,fcpv" for generic compatible 'FCP for VSP' (all other VSPs)
>     - "renesas,fcpf" for generic compatible 'FCP for FDP'

You may want to update the paragraph before that, referring to three types of
FCP. It seems there's also a similar split for FCPC? So that makes (at least)
5 types.

Just wondering: as FCPVI vs. FCPV is programmable through the FCPVSEL
bit, can you deduce the type using the renesas,fcp link in the corresponding
VSP node in DT?

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

* Re: [RFC 09/13] v4l: rcar-fcp: Configure the number of outstanding read transactions
  2017-09-26 10:06 ` [RFC 09/13] v4l: rcar-fcp: Configure the number of outstanding read transactions Laurent Pinchart
@ 2017-09-26 11:50   ` Geert Uytterhoeven
  2017-09-26 13:01     ` Laurent Pinchart
  0 siblings, 1 reply; 23+ messages in thread
From: Geert Uytterhoeven @ 2017-09-26 11:50 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: Linux-Renesas

Hi Laurent,

On Tue, Sep 26, 2017 at 12:06 PM, Laurent Pinchart
<laurent.pinchart+renesas@ideasonboard.com> wrote:
> The FCPV has a selectable number of outstanding read transactions.
> According to the documentation the value must be set based on the type
> of the VSP the FCPV is connected to. Set the register accordingly at
> probe time.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

> @@ -228,12 +236,29 @@ static int rcar_fcp_setup(struct rcar_fcp_device *fcp)
>         dev_dbg(fcp->dev, "%s %s device found\n", models[fcp->type],
>                 versions[i].name);
>
> +       /* Set the processing mode (needed for FCPV only). */
> +       switch (fcp->type) {
> +       case RCAR_FCPV:
> +               /* 64 outstanding read transactions */
> +               rcar_fcp_write(fcp, FCP_CFG0, 0);
> +               break;
> +
> +       case RCAR_FCPVI:
> +               /* 16 outstanding read transactions */
> +               rcar_fcp_write(fcp, FCP_CFG0, FCP_CFG0_FCPVSEL);
> +               break;
> +
> +       default:
> +               break;
> +       }
> +
>         return 0;
>  }
>
>  static const struct of_device_id rcar_fcp_of_match[] = {
>         { .compatible = "renesas,fcpf", .data = (void *)RCAR_FCPF },
>         { .compatible = "renesas,fcpv", .data = (void *)RCAR_FCPV },
> +       { .compatible = "renesas,fcpvi", .data = (void *)RCAR_FCPVI },
>         { },

As you use "renesas,fcpv" as a fallback value, you may want to insert
the new and more specific "renesas,fvpci" handling above it, for clarity.

I believe it will return the RCAR_FCPVI match data anyway, based on
a higher match score for the more specific compatible value?

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

* Re: [RFC 02/13] dt-bindings: media: renesas-fcp: Add a compatible string for VSPI FCP
  2017-09-26 11:47   ` Geert Uytterhoeven
@ 2017-09-26 12:39     ` Laurent Pinchart
  2017-09-26 12:46       ` Geert Uytterhoeven
  0 siblings, 1 reply; 23+ messages in thread
From: Laurent Pinchart @ 2017-09-26 12:39 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: Laurent Pinchart, Linux-Renesas

Hi Geert,

On Tuesday, 26 September 2017 14:47:35 EEST Geert Uytterhoeven wrote:
> On Tue, Sep 26, 2017 at 12:05 PM, Laurent Pinchart wrote:
> > The FCP instances associated with a VSPI must be treated differently
> > than the ones associated with another type of VSP. Add a new compatible
> > string to allow telling them apart.
> > 
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com>
> > ---
> > 
> >  Documentation/devicetree/bindings/media/renesas,fcp.txt | 3 ++-
> >  1 file changed, 2 insertions(+), 1 deletion(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/media/renesas,fcp.txt
> > b/Documentation/devicetree/bindings/media/renesas,fcp.txt index
> > 3ec91803ba58..c1f28736e2d6 100644
> > --- a/Documentation/devicetree/bindings/media/renesas,fcp.txt
> > +++ b/Documentation/devicetree/bindings/media/renesas,fcp.txt
> > @@ -11,7 +11,8 @@ are paired with. These DT bindings currently support the
> > FCPV and FCPF.> 
> >   - compatible: Must be one or more of the following
> > 
> > -   - "renesas,fcpv" for generic compatible 'FCP for VSP'
> > +   - "renesas,fcpvi" for generic compatible 'FCP for VSPI'
> > +   - "renesas,fcpv" for generic compatible 'FCP for VSP' (all other VSPs)
> > 
> >     - "renesas,fcpf" for generic compatible 'FCP for FDP'
> 
> You may want to update the paragraph before that, referring to three types
> of FCP.

As far as I know the FCP-VSPI and FCP-VSP[^I] are the same type of device, 
with different SoC integration.

> It seems there's also a similar split for FCPC? So that makes (at
> least) 5 types.

There's little documentation on the FCPC unfortunately, so I'm not sure how we 
should handle it.

> Just wondering: as FCPVI vs. FCPV is programmable through the FCPVSEL
> bit, can you deduce the type using the renesas,fcp link in the corresponding
> VSP node in DT?

You could possibly, if you had a link from the FCP to the VSP in DT. As 
there's none, the type can't be currently inferred from DT at probe time. We 
could pass the type from the VSP driver to the FCP driver, but I'm not sure I 
want to go that way. If the FCP-VSPI and VSP[^I] are identicaly and need 
different software configuration due to being used by different types of VSPs 
it would make sense, but if there are hardware differences between the FCPs 
then I think they should be described in DT.

-- 
Regards,

Laurent Pinchart

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

* Re: [RFC 02/13] dt-bindings: media: renesas-fcp: Add a compatible string for VSPI FCP
  2017-09-26 12:39     ` Laurent Pinchart
@ 2017-09-26 12:46       ` Geert Uytterhoeven
  2017-09-26 12:53         ` Laurent Pinchart
  0 siblings, 1 reply; 23+ messages in thread
From: Geert Uytterhoeven @ 2017-09-26 12:46 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: Laurent Pinchart, Linux-Renesas

Hi Laurent,

On Tue, Sep 26, 2017 at 2:39 PM, Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
> On Tuesday, 26 September 2017 14:47:35 EEST Geert Uytterhoeven wrote:
>> On Tue, Sep 26, 2017 at 12:05 PM, Laurent Pinchart wrote:
>> > The FCP instances associated with a VSPI must be treated differently
>> > than the ones associated with another type of VSP. Add a new compatible
>> > string to allow telling them apart.
>> >
>> > Signed-off-by: Laurent Pinchart
>> > <laurent.pinchart+renesas@ideasonboard.com>
>> > ---
>> >
>> >  Documentation/devicetree/bindings/media/renesas,fcp.txt | 3 ++-
>> >  1 file changed, 2 insertions(+), 1 deletion(-)
>> >
>> > diff --git a/Documentation/devicetree/bindings/media/renesas,fcp.txt
>> > b/Documentation/devicetree/bindings/media/renesas,fcp.txt index
>> > 3ec91803ba58..c1f28736e2d6 100644
>> > --- a/Documentation/devicetree/bindings/media/renesas,fcp.txt
>> > +++ b/Documentation/devicetree/bindings/media/renesas,fcp.txt
>> > @@ -11,7 +11,8 @@ are paired with. These DT bindings currently support the
>> > FCPV and FCPF.>
>> >   - compatible: Must be one or more of the following
>> >
>> > -   - "renesas,fcpv" for generic compatible 'FCP for VSP'
>> > +   - "renesas,fcpvi" for generic compatible 'FCP for VSPI'
>> > +   - "renesas,fcpv" for generic compatible 'FCP for VSP' (all other VSPs)
>> >
>> >     - "renesas,fcpf" for generic compatible 'FCP for FDP'
>>
>> You may want to update the paragraph before that, referring to three types
>> of FCP.
>
> As far as I know the FCP-VSPI and FCP-VSP[^I] are the same type of device,
> with different SoC integration.

OK. So they should use the same compatible value?

>> Just wondering: as FCPVI vs. FCPV is programmable through the FCPVSEL
>> bit, can you deduce the type using the renesas,fcp link in the corresponding
>> VSP node in DT?
>
> You could possibly, if you had a link from the FCP to the VSP in DT. As
> there's none, the type can't be currently inferred from DT at probe time. We
> could pass the type from the VSP driver to the FCP driver, but I'm not sure I
> want to go that way. If the FCP-VSPI and VSP[^I] are identicaly and need
> different software configuration due to being used by different types of VSPs
> it would make sense, but if there are hardware differences between the FCPs
> then I think they should be described in DT.

Given the FCPVSEL bit, it looks like there's no difference, and software is
supposed to specify configuration.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

* Re: [RFC 02/13] dt-bindings: media: renesas-fcp: Add a compatible string for VSPI FCP
  2017-09-26 12:46       ` Geert Uytterhoeven
@ 2017-09-26 12:53         ` Laurent Pinchart
  0 siblings, 0 replies; 23+ messages in thread
From: Laurent Pinchart @ 2017-09-26 12:53 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: Laurent Pinchart, Linux-Renesas

Hi Geert,

On Tuesday, 26 September 2017 15:46:59 EEST Geert Uytterhoeven wrote:
> On Tue, Sep 26, 2017 at 2:39 PM, Laurent Pinchart wrote:
> > On Tuesday, 26 September 2017 14:47:35 EEST Geert Uytterhoeven wrote:
> >> On Tue, Sep 26, 2017 at 12:05 PM, Laurent Pinchart wrote:
> >> > The FCP instances associated with a VSPI must be treated differently
> >> > than the ones associated with another type of VSP. Add a new compatible
> >> > string to allow telling them apart.
> >> > 
> >> > Signed-off-by: Laurent Pinchart
> >> > <laurent.pinchart+renesas@ideasonboard.com>
> >> > ---
> >> > 
> >> >  Documentation/devicetree/bindings/media/renesas,fcp.txt | 3 ++-
> >> >  1 file changed, 2 insertions(+), 1 deletion(-)
> >> > 
> >> > diff --git a/Documentation/devicetree/bindings/media/renesas,fcp.txt
> >> > b/Documentation/devicetree/bindings/media/renesas,fcp.txt index
> >> > 3ec91803ba58..c1f28736e2d6 100644
> >> > --- a/Documentation/devicetree/bindings/media/renesas,fcp.txt
> >> > +++ b/Documentation/devicetree/bindings/media/renesas,fcp.txt
> >> > @@ -11,7 +11,8 @@ are paired with. These DT bindings currently support
> >> > the FCPV and FCPF.
> >> > 
> >> >     - compatible: Must be one or more of the following
> >> > -   - "renesas,fcpv" for generic compatible 'FCP for VSP'
> >> > +   - "renesas,fcpvi" for generic compatible 'FCP for VSPI'
> >> > +   - "renesas,fcpv" for generic compatible 'FCP for VSP' (all other
> >> > VSPs)
> >> >     - "renesas,fcpf" for generic compatible 'FCP for FDP'
> >> 
> >> You may want to update the paragraph before that, referring to three
> >> types of FCP.
> > 
> > As far as I know the FCP-VSPI and FCP-VSP[^I] are the same type of device,
> > with different SoC integration.
> 
> OK. So they should use the same compatible value?
> 
> >> Just wondering: as FCPVI vs. FCPV is programmable through the FCPVSEL
> >> bit, can you deduce the type using the renesas,fcp link in the
> >> corresponding VSP node in DT?
> > 
> > You could possibly, if you had a link from the FCP to the VSP in DT. As
> > there's none, the type can't be currently inferred from DT at probe time.
> > We could pass the type from the VSP driver to the FCP driver, but I'm not
> > sure I want to go that way. If the FCP-VSPI and VSP[^I] are identicaly
> > and need different software configuration due to being used by different
> > types of VSPs it would make sense, but if there are hardware differences
> > between the FCPs then I think they should be described in DT.
> 
> Given the FCPVSEL bit, it looks like there's no difference, and software is
> supposed to specify configuration.

That's hard to tell for sure, it could be that there are hardware differences 
that require a different software configuration. I'll keep your comment in 
mind for the next version though, and will try to get more information from 
Renesas.

-- 
Regards,

Laurent Pinchart

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

* Re: [RFC 09/13] v4l: rcar-fcp: Configure the number of outstanding read transactions
  2017-09-26 11:50   ` Geert Uytterhoeven
@ 2017-09-26 13:01     ` Laurent Pinchart
  2017-09-26 13:07       ` Geert Uytterhoeven
  0 siblings, 1 reply; 23+ messages in thread
From: Laurent Pinchart @ 2017-09-26 13:01 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: Laurent Pinchart, Linux-Renesas

Hi Geert,

On Tuesday, 26 September 2017 14:50:46 EEST Geert Uytterhoeven wrote:
> On Tue, Sep 26, 2017 at 12:06 PM, Laurent Pinchart wrote:
> > The FCPV has a selectable number of outstanding read transactions.
> > According to the documentation the value must be set based on the type
> > of the VSP the FCPV is connected to. Set the register accordingly at
> > probe time.
> > 
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com>
> > 
> > @@ -228,12 +236,29 @@ static int rcar_fcp_setup(struct rcar_fcp_device
> > *fcp)
> >         dev_dbg(fcp->dev, "%s %s device found\n", models[fcp->type],
> >                 versions[i].name);
> > 
> > +       /* Set the processing mode (needed for FCPV only). */
> > +       switch (fcp->type) {
> > +       case RCAR_FCPV:
> > +               /* 64 outstanding read transactions */
> > +               rcar_fcp_write(fcp, FCP_CFG0, 0);
> > +               break;
> > +
> > +       case RCAR_FCPVI:
> > +               /* 16 outstanding read transactions */
> > +               rcar_fcp_write(fcp, FCP_CFG0, FCP_CFG0_FCPVSEL);
> > +               break;
> > +
> > +       default:
> > +               break;
> > +       }
> > +
> >         return 0;
> >  }
> >  
> >  static const struct of_device_id rcar_fcp_of_match[] = {
> >         { .compatible = "renesas,fcpf", .data = (void *)RCAR_FCPF },
> >         { .compatible = "renesas,fcpv", .data = (void *)RCAR_FCPV },
> > +       { .compatible = "renesas,fcpvi", .data = (void *)RCAR_FCPVI },
> >         { },
> 
> As you use "renesas,fcpv" as a fallback value, you may want to insert
> the new and more specific "renesas,fvpci" handling above it, for clarity.

Good point, I'll do that.

> I believe it will return the RCAR_FCPVI match data anyway, based on
> a higher match score for the more specific compatible value?

I don't think this is related to a match score, but to the fact the compatible 
strings from DT are tried in the left to right direction.

-- 
Regards,

Laurent Pinchart

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

* Re: [RFC 09/13] v4l: rcar-fcp: Configure the number of outstanding read transactions
  2017-09-26 13:01     ` Laurent Pinchart
@ 2017-09-26 13:07       ` Geert Uytterhoeven
  0 siblings, 0 replies; 23+ messages in thread
From: Geert Uytterhoeven @ 2017-09-26 13:07 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: Laurent Pinchart, Linux-Renesas

Hi Laurent,

On Tue, Sep 26, 2017 at 3:01 PM, Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
> On Tuesday, 26 September 2017 14:50:46 EEST Geert Uytterhoeven wrote:
>> On Tue, Sep 26, 2017 at 12:06 PM, Laurent Pinchart wrote:
>> >  static const struct of_device_id rcar_fcp_of_match[] = {
>> >         { .compatible = "renesas,fcpf", .data = (void *)RCAR_FCPF },
>> >         { .compatible = "renesas,fcpv", .data = (void *)RCAR_FCPV },
>> > +       { .compatible = "renesas,fcpvi", .data = (void *)RCAR_FCPVI },
>> >         { },
>>
>> As you use "renesas,fcpv" as a fallback value, you may want to insert
>> the new and more specific "renesas,fvpci" handling above it, for clarity.
>
> Good point, I'll do that.
>
>> I believe it will return the RCAR_FCPVI match data anyway, based on
>> a higher match score for the more specific compatible value?
>
> I don't think this is related to a match score, but to the fact the compatible
> strings from DT are tried in the left to right direction.

JTR, see the use scores in __of_match_node() and __of_device_is_compatible().

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

end of thread, other threads:[~2017-09-26 13:07 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-09-26 10:05 [RFC 00/13] R-Car: Enable lossy compression in VSP video pipelines Laurent Pinchart
2017-09-26 10:05 ` [RFC] [FW] bl2: plat: renesas: rcar: Enable all lossy decompression areas Laurent Pinchart
2017-09-26 10:05 ` [RFC] [U-BOOT] board: salvator-x: Add reserved lossy decompression areas to DT Laurent Pinchart
2017-09-26 10:05 ` [RFC 01/13] dt-bindings: reserved-memory: Add binding for the Renesas lossy decompression area Laurent Pinchart
2017-09-26 10:05 ` [RFC 02/13] dt-bindings: media: renesas-fcp: Add a compatible string for VSPI FCP Laurent Pinchart
2017-09-26 11:47   ` Geert Uytterhoeven
2017-09-26 12:39     ` Laurent Pinchart
2017-09-26 12:46       ` Geert Uytterhoeven
2017-09-26 12:53         ` Laurent Pinchart
2017-09-26 10:05 ` [RFC 03/13] dt-bindings: media: renesas-fcp: Add memory-region property Laurent Pinchart
2017-09-26 10:05 ` [RFC 04/13] arm64: dts: renesas: Use renesas,fcpvi compatible string Laurent Pinchart
2017-09-26 10:05 ` [RFC 05/13] arm64: dts: r8a7795: Add lossy decompression reserved memory nodes Laurent Pinchart
2017-09-26 10:05 ` [RFC 06/13] arm64: dts: r8a7795: Reference the lossy memory region from the FCPss Laurent Pinchart
2017-09-26 10:05 ` [RFC 07/13] arm64: dts: r8a7795: Add dma-ranges property in the /soc node Laurent Pinchart
2017-09-26 10:06 ` [RFC 08/13] v4l: rcar-fcp: Check device revision at probe time Laurent Pinchart
2017-09-26 10:06 ` [RFC 09/13] v4l: rcar-fcp: Configure the number of outstanding read transactions Laurent Pinchart
2017-09-26 11:50   ` Geert Uytterhoeven
2017-09-26 13:01     ` Laurent Pinchart
2017-09-26 13:07       ` Geert Uytterhoeven
2017-09-26 10:06 ` [RFC 10/13] v4l: rcar-fcp: Prepare driver API for FCNL support Laurent Pinchart
2017-09-26 10:06 ` [RFC 11/13] v4l: rcar-fcp: Support FCNL decompression Laurent Pinchart
2017-09-26 10:06 ` [RFC 12/13] v4l: vsp1: Add support for near-lossless compression (FCNL) in the WPF Laurent Pinchart
2017-09-26 10:06 ` [RFC 13/13] v4l: vsp1: Add support for near-lossless compression (FCNL) in the RPF Laurent Pinchart

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.