Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6d62ef3a authored by Laurent Pinchart's avatar Laurent Pinchart
Browse files

drm: rcar-du: Expose the VSP1 compositor through KMS planes



On R-Car Gen3 SoCs the DU lost its ability to access memory directly and
needs to work in conjunction with the VSP to do so. This commit handles
the VSP internally to hide it from the user.

Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
parent ab334e13
Loading
Loading
Loading
Loading
+7 −0
Original line number Original line Diff line number Diff line
@@ -25,3 +25,10 @@ config DRM_RCAR_LVDS
	help
	help
	  Enable support for the R-Car Display Unit embedded LVDS encoders
	  Enable support for the R-Car Display Unit embedded LVDS encoders
	  (currently only on R8A7790 and R8A7791).
	  (currently only on R8A7790 and R8A7791).

config DRM_RCAR_VSP
	bool "R-Car DU VSP Compositor Support"
	depends on DRM_RCAR_DU
	depends on VIDEO_RENESAS_VSP1
	help
	  Enable support to expose the R-Car VSP Compositor as KMS planes.
+2 −0
Original line number Original line Diff line number Diff line
@@ -11,4 +11,6 @@ rcar-du-drm-$(CONFIG_DRM_RCAR_HDMI) += rcar_du_hdmicon.o \
					   rcar_du_hdmienc.o
					   rcar_du_hdmienc.o
rcar-du-drm-$(CONFIG_DRM_RCAR_LVDS)	+= rcar_du_lvdsenc.o
rcar-du-drm-$(CONFIG_DRM_RCAR_LVDS)	+= rcar_du_lvdsenc.o


rcar-du-drm-$(CONFIG_DRM_RCAR_VSP)	+= rcar_du_vsp.o

obj-$(CONFIG_DRM_RCAR_DU)		+= rcar-du-drm.o
obj-$(CONFIG_DRM_RCAR_DU)		+= rcar-du-drm.o
+41 −7
Original line number Original line Diff line number Diff line
@@ -28,6 +28,7 @@
#include "rcar_du_kms.h"
#include "rcar_du_kms.h"
#include "rcar_du_plane.h"
#include "rcar_du_plane.h"
#include "rcar_du_regs.h"
#include "rcar_du_regs.h"
#include "rcar_du_vsp.h"


static u32 rcar_du_crtc_read(struct rcar_du_crtc *rcrtc, u32 reg)
static u32 rcar_du_crtc_read(struct rcar_du_crtc *rcrtc, u32 reg)
{
{
@@ -207,6 +208,7 @@ plane_format(struct rcar_du_plane *plane)
static void rcar_du_crtc_update_planes(struct rcar_du_crtc *rcrtc)
static void rcar_du_crtc_update_planes(struct rcar_du_crtc *rcrtc)
{
{
	struct rcar_du_plane *planes[RCAR_DU_NUM_HW_PLANES];
	struct rcar_du_plane *planes[RCAR_DU_NUM_HW_PLANES];
	struct rcar_du_device *rcdu = rcrtc->group->dev;
	unsigned int num_planes = 0;
	unsigned int num_planes = 0;
	unsigned int dptsr_planes;
	unsigned int dptsr_planes;
	unsigned int hwplanes = 0;
	unsigned int hwplanes = 0;
@@ -250,6 +252,12 @@ static void rcar_du_crtc_update_planes(struct rcar_du_crtc *rcrtc)
		}
		}
	}
	}


	/* If VSP+DU integration is enabled the plane assignment is fixed. */
	if (rcar_du_has(rcdu, RCAR_DU_FEATURE_VSP1_SOURCE)) {
		dspr = (rcrtc->index % 2) + 1;
		hwplanes = 1 << (rcrtc->index % 2);
	}

	/* Update the planes to display timing and dot clock generator
	/* Update the planes to display timing and dot clock generator
	 * associations.
	 * associations.
	 *
	 *
@@ -369,6 +377,10 @@ static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc)


	rcar_du_group_start_stop(rcrtc->group, true);
	rcar_du_group_start_stop(rcrtc->group, true);


	/* Enable the VSP compositor. */
	if (rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_VSP1_SOURCE))
		rcar_du_vsp_enable(rcrtc);

	/* Turn vertical blanking interrupt reporting back on. */
	/* Turn vertical blanking interrupt reporting back on. */
	drm_crtc_vblank_on(crtc);
	drm_crtc_vblank_on(crtc);


@@ -402,6 +414,10 @@ static void rcar_du_crtc_stop(struct rcar_du_crtc *rcrtc)
	rcar_du_crtc_wait_page_flip(rcrtc);
	rcar_du_crtc_wait_page_flip(rcrtc);
	drm_crtc_vblank_off(crtc);
	drm_crtc_vblank_off(crtc);


	/* Disable the VSP compositor. */
	if (rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_VSP1_SOURCE))
		rcar_du_vsp_disable(rcrtc);

	/* Select switch sync mode. This stops display operation and configures
	/* Select switch sync mode. This stops display operation and configures
	 * the HSYNC and VSYNC signals as inputs.
	 * the HSYNC and VSYNC signals as inputs.
	 */
	 */
@@ -414,6 +430,9 @@ static void rcar_du_crtc_stop(struct rcar_du_crtc *rcrtc)


void rcar_du_crtc_suspend(struct rcar_du_crtc *rcrtc)
void rcar_du_crtc_suspend(struct rcar_du_crtc *rcrtc)
{
{
	if (rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_VSP1_SOURCE))
		rcar_du_vsp_disable(rcrtc);

	rcar_du_crtc_stop(rcrtc);
	rcar_du_crtc_stop(rcrtc);
	rcar_du_crtc_put(rcrtc);
	rcar_du_crtc_put(rcrtc);
}
}
@@ -429,6 +448,9 @@ void rcar_du_crtc_resume(struct rcar_du_crtc *rcrtc)
	rcar_du_crtc_start(rcrtc);
	rcar_du_crtc_start(rcrtc);


	/* Commit the planes state. */
	/* Commit the planes state. */
	if (rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_VSP1_SOURCE)) {
		rcar_du_vsp_enable(rcrtc);
	} else {
		for (i = 0; i < rcrtc->group->num_planes; ++i) {
		for (i = 0; i < rcrtc->group->num_planes; ++i) {
			struct rcar_du_plane *plane = &rcrtc->group->planes[i];
			struct rcar_du_plane *plane = &rcrtc->group->planes[i];


@@ -437,6 +459,7 @@ void rcar_du_crtc_resume(struct rcar_du_crtc *rcrtc)


			rcar_du_plane_setup(plane);
			rcar_du_plane_setup(plane);
		}
		}
	}


	rcar_du_crtc_update_planes(rcrtc);
	rcar_du_crtc_update_planes(rcrtc);
}
}
@@ -486,6 +509,9 @@ static void rcar_du_crtc_atomic_begin(struct drm_crtc *crtc,
		rcrtc->event = event;
		rcrtc->event = event;
		spin_unlock_irqrestore(&dev->event_lock, flags);
		spin_unlock_irqrestore(&dev->event_lock, flags);
	}
	}

	if (rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_VSP1_SOURCE))
		rcar_du_vsp_atomic_begin(rcrtc);
}
}


static void rcar_du_crtc_atomic_flush(struct drm_crtc *crtc,
static void rcar_du_crtc_atomic_flush(struct drm_crtc *crtc,
@@ -494,6 +520,9 @@ static void rcar_du_crtc_atomic_flush(struct drm_crtc *crtc,
	struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
	struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);


	rcar_du_crtc_update_planes(rcrtc);
	rcar_du_crtc_update_planes(rcrtc);

	if (rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_VSP1_SOURCE))
		rcar_du_vsp_atomic_flush(rcrtc);
}
}


static const struct drm_crtc_helper_funcs crtc_helper_funcs = {
static const struct drm_crtc_helper_funcs crtc_helper_funcs = {
@@ -549,6 +578,7 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index)
	struct platform_device *pdev = to_platform_device(rcdu->dev);
	struct platform_device *pdev = to_platform_device(rcdu->dev);
	struct rcar_du_crtc *rcrtc = &rcdu->crtcs[index];
	struct rcar_du_crtc *rcrtc = &rcdu->crtcs[index];
	struct drm_crtc *crtc = &rcrtc->crtc;
	struct drm_crtc *crtc = &rcrtc->crtc;
	struct drm_plane *primary;
	unsigned int irqflags;
	unsigned int irqflags;
	struct clk *clk;
	struct clk *clk;
	char clk_name[9];
	char clk_name[9];
@@ -585,8 +615,12 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index)
	rcrtc->mmio_offset = mmio_offsets[index];
	rcrtc->mmio_offset = mmio_offsets[index];
	rcrtc->index = index;
	rcrtc->index = index;


	ret = drm_crtc_init_with_planes(rcdu->ddev, crtc,
	if (rcar_du_has(rcdu, RCAR_DU_FEATURE_VSP1_SOURCE))
					&rgrp->planes[index % 2].plane,
		primary = &rcrtc->vsp->planes[0].plane;
	else
		primary = &rgrp->planes[index % 2].plane;

	ret = drm_crtc_init_with_planes(rcdu->ddev, crtc, primary,
					NULL, &crtc_funcs, NULL);
					NULL, &crtc_funcs, NULL);
	if (ret < 0)
	if (ret < 0)
		return ret;
		return ret;
+2 −0
Original line number Original line Diff line number Diff line
@@ -21,6 +21,7 @@
#include <drm/drm_crtc.h>
#include <drm/drm_crtc.h>


struct rcar_du_group;
struct rcar_du_group;
struct rcar_du_vsp;


/**
/**
 * struct rcar_du_crtc - the CRTC, representing a DU superposition processor
 * struct rcar_du_crtc - the CRTC, representing a DU superposition processor
@@ -50,6 +51,7 @@ struct rcar_du_crtc {
	unsigned int outputs;
	unsigned int outputs;


	struct rcar_du_group *group;
	struct rcar_du_group *group;
	struct rcar_du_vsp *vsp;
};
};


#define to_rcar_crtc(c)	container_of(c, struct rcar_du_crtc, crtc)
#define to_rcar_crtc(c)	container_of(c, struct rcar_du_crtc, crtc)
+4 −0
Original line number Original line Diff line number Diff line
@@ -19,6 +19,7 @@


#include "rcar_du_crtc.h"
#include "rcar_du_crtc.h"
#include "rcar_du_group.h"
#include "rcar_du_group.h"
#include "rcar_du_vsp.h"


struct clk;
struct clk;
struct device;
struct device;
@@ -29,6 +30,7 @@ struct rcar_du_lvdsenc;


#define RCAR_DU_FEATURE_CRTC_IRQ_CLOCK	(1 << 0)	/* Per-CRTC IRQ and clock */
#define RCAR_DU_FEATURE_CRTC_IRQ_CLOCK	(1 << 0)	/* Per-CRTC IRQ and clock */
#define RCAR_DU_FEATURE_EXT_CTRL_REGS	(1 << 1)	/* Has extended control registers */
#define RCAR_DU_FEATURE_EXT_CTRL_REGS	(1 << 1)	/* Has extended control registers */
#define RCAR_DU_FEATURE_VSP1_SOURCE	(1 << 2)	/* Has inputs from VSP1 */


#define RCAR_DU_QUIRK_ALIGN_128B	(1 << 0)	/* Align pitches to 128 bytes */
#define RCAR_DU_QUIRK_ALIGN_128B	(1 << 0)	/* Align pitches to 128 bytes */
#define RCAR_DU_QUIRK_LVDS_LANES	(1 << 1)	/* LVDS lanes 1 and 3 inverted */
#define RCAR_DU_QUIRK_LVDS_LANES	(1 << 1)	/* LVDS lanes 1 and 3 inverted */
@@ -68,6 +70,7 @@ struct rcar_du_device_info {
#define RCAR_DU_MAX_CRTCS		3
#define RCAR_DU_MAX_CRTCS		3
#define RCAR_DU_MAX_GROUPS		DIV_ROUND_UP(RCAR_DU_MAX_CRTCS, 2)
#define RCAR_DU_MAX_GROUPS		DIV_ROUND_UP(RCAR_DU_MAX_CRTCS, 2)
#define RCAR_DU_MAX_LVDS		2
#define RCAR_DU_MAX_LVDS		2
#define RCAR_DU_MAX_VSPS		4


struct rcar_du_device {
struct rcar_du_device {
	struct device *dev;
	struct device *dev;
@@ -82,6 +85,7 @@ struct rcar_du_device {
	unsigned int num_crtcs;
	unsigned int num_crtcs;


	struct rcar_du_group groups[RCAR_DU_MAX_GROUPS];
	struct rcar_du_group groups[RCAR_DU_MAX_GROUPS];
	struct rcar_du_vsp vsps[RCAR_DU_MAX_VSPS];


	struct {
	struct {
		struct drm_property *alpha;
		struct drm_property *alpha;
Loading