Commit 46f28427 authored by Daniel Vetter's avatar Daniel Vetter
Browse files

Merge tag 'drm-rcar-next-20230325' of...

Merge tag 'drm-rcar-next-20230325' of git://git.kernel.org/pub/scm/linux/kernel/git/pinchartl/linux

 into drm-next

Miscellaneous fixes and improvements for rcar-du

Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230325204922.GD19335@pendragon.ideasonboard.com
parents 7ed34927 40f43730
Loading
Loading
Loading
Loading
+26 −12
Original line number Diff line number Diff line
@@ -298,13 +298,26 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
		escr = params.escr;
	}

	if (rcdu->info->gen < 4) {
	/*
	 * The ESCR register only exists in DU channels that can output to an
	 * LVDS or DPAT, and the OTAR register in DU channels that can output
	 * to a DPAD.
	 */
	if ((rcdu->info->routes[RCAR_DU_OUTPUT_DPAD0].possible_crtcs |
	     rcdu->info->routes[RCAR_DU_OUTPUT_DPAD1].possible_crtcs |
	     rcdu->info->routes[RCAR_DU_OUTPUT_LVDS0].possible_crtcs |
	     rcdu->info->routes[RCAR_DU_OUTPUT_LVDS1].possible_crtcs) &
	    BIT(rcrtc->index)) {
		dev_dbg(rcrtc->dev->dev, "%s: ESCR 0x%08x\n", __func__, escr);

		rcar_du_crtc_write(rcrtc, rcrtc->index % 2 ? ESCR13 : ESCR02, escr);
		rcar_du_crtc_write(rcrtc, rcrtc->index % 2 ? OTAR13 : OTAR02, 0);
	}

	if ((rcdu->info->routes[RCAR_DU_OUTPUT_DPAD0].possible_crtcs |
	     rcdu->info->routes[RCAR_DU_OUTPUT_DPAD1].possible_crtcs) &
	    BIT(rcrtc->index))
		rcar_du_crtc_write(rcrtc, rcrtc->index % 2 ? OTAR13 : OTAR02, 0);

	/* Signal polarities */
	dsmr = ((mode->flags & DRM_MODE_FLAG_PVSYNC) ? DSMR_VSL : 0)
	     | ((mode->flags & DRM_MODE_FLAG_PHSYNC) ? DSMR_HSL : 0)
@@ -749,16 +762,17 @@ static void rcar_du_crtc_atomic_enable(struct drm_crtc *crtc,

	/*
	 * On D3/E3 the dot clock is provided by the LVDS encoder attached to
	 * the DU channel. We need to enable its clock output explicitly if
	 * the LVDS output is disabled.
	 * the DU channel. We need to enable its clock output explicitly before
	 * starting the CRTC, as the bridge hasn't been enabled by the atomic
	 * helpers yet.
	 */
	if (rcdu->info->lvds_clk_mask & BIT(rcrtc->index) &&
	    rstate->outputs == BIT(RCAR_DU_OUTPUT_DPAD0)) {
	if (rcdu->info->lvds_clk_mask & BIT(rcrtc->index)) {
		bool dot_clk_only = rstate->outputs == BIT(RCAR_DU_OUTPUT_DPAD0);
		struct drm_bridge *bridge = rcdu->lvds[rcrtc->index];
		const struct drm_display_mode *mode =
			&crtc->state->adjusted_mode;

		rcar_lvds_pclk_enable(bridge, mode->clock * 1000);
		rcar_lvds_pclk_enable(bridge, mode->clock * 1000, dot_clk_only);
	}

	/*
@@ -795,15 +809,16 @@ static void rcar_du_crtc_atomic_disable(struct drm_crtc *crtc,
	rcar_du_crtc_stop(rcrtc);
	rcar_du_crtc_put(rcrtc);

	if (rcdu->info->lvds_clk_mask & BIT(rcrtc->index) &&
	    rstate->outputs == BIT(RCAR_DU_OUTPUT_DPAD0)) {
	if (rcdu->info->lvds_clk_mask & BIT(rcrtc->index)) {
		bool dot_clk_only = rstate->outputs == BIT(RCAR_DU_OUTPUT_DPAD0);
		struct drm_bridge *bridge = rcdu->lvds[rcrtc->index];

		/*
		 * Disable the LVDS clock output, see
		 * rcar_du_crtc_atomic_enable().
		 * rcar_du_crtc_atomic_enable(). When the LVDS output is used,
		 * this also disables the LVDS encoder.
		 */
		rcar_lvds_pclk_disable(bridge);
		rcar_lvds_pclk_disable(bridge, dot_clk_only);
	}

	if ((rcdu->info->dsi_clk_mask & BIT(rcrtc->index)) &&
@@ -815,7 +830,6 @@ static void rcar_du_crtc_atomic_disable(struct drm_crtc *crtc,
		 * Disable the DSI clock output, see
		 * rcar_du_crtc_atomic_enable().
		 */

		rcar_mipi_dsi_pclk_disable(bridge);
	}

+2 −2
Original line number Diff line number Diff line
@@ -109,8 +109,8 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu,
	renc = drmm_encoder_alloc(&rcdu->ddev, struct rcar_du_encoder, base,
				  &rcar_du_encoder_funcs, DRM_MODE_ENCODER_NONE,
				  NULL);
	if (!renc)
		return -ENOMEM;
	if (IS_ERR(renc))
		return PTR_ERR(renc);

	renc->output = output;

+12 −4
Original line number Diff line number Diff line
@@ -138,6 +138,7 @@ static void rcar_du_group_setup(struct rcar_du_group *rgrp)
{
	struct rcar_du_device *rcdu = rgrp->dev;
	u32 defr7 = DEFR7_CODE;
	u32 dorcr;

	/* Enable extended features */
	rcar_du_group_write(rgrp, DEFR, DEFR_CODE | DEFR_DEFE);
@@ -174,8 +175,15 @@ static void rcar_du_group_setup(struct rcar_du_group *rgrp)
	/*
	 * Use DS1PR and DS2PR to configure planes priorities and connects the
	 * superposition 0 to DU0 pins. DU1 pins will be configured dynamically.
	 *
	 * Groups that have a single channel have a hardcoded configuration. On
	 * Gen3 and newer, the documentation requires PG1T, DK1S and PG1D_DS1 to
	 * always be set in this case.
	 */
	rcar_du_group_write(rgrp, DORCR, DORCR_PG1D_DS1 | DORCR_DPRS);
	dorcr = DORCR_PG0D_DS0 | DORCR_DPRS;
	if (rcdu->info->gen >= 3 && rgrp->num_crtcs == 1)
		dorcr |= DORCR_PG1T | DORCR_DK1S | DORCR_PG1D_DS1;
	rcar_du_group_write(rgrp, DORCR, dorcr);

	/* Apply planes to CRTCs association. */
	mutex_lock(&rgrp->lock);
@@ -349,7 +357,7 @@ int rcar_du_group_set_routing(struct rcar_du_group *rgrp)
	struct rcar_du_device *rcdu = rgrp->dev;
	u32 dorcr = rcar_du_group_read(rgrp, DORCR);

	dorcr &= ~(DORCR_PG2T | DORCR_DK2S | DORCR_PG2D_MASK);
	dorcr &= ~(DORCR_PG1T | DORCR_DK1S | DORCR_PG1D_MASK);

	/*
	 * Set the DPAD1 pins sources. Select CRTC 0 if explicitly requested and
@@ -357,9 +365,9 @@ int rcar_du_group_set_routing(struct rcar_du_group *rgrp)
	 * by default.
	 */
	if (rcdu->dpad1_source == rgrp->index * 2)
		dorcr |= DORCR_PG2D_DS1;
		dorcr |= DORCR_PG1D_DS0;
	else
		dorcr |= DORCR_PG2T | DORCR_DK2S | DORCR_PG2D_DS2;
		dorcr |= DORCR_PG1T | DORCR_DK1S | DORCR_PG1D_DS1;

	rcar_du_group_write(rgrp, DORCR, dorcr);

+13 −13
Original line number Diff line number Diff line
@@ -511,19 +511,19 @@
 */

#define DORCR			0x11000
#define DORCR_PG2T		(1 << 30)
#define DORCR_DK2S		(1 << 28)
#define DORCR_PG2D_DS1		(0 << 24)
#define DORCR_PG2D_DS2		(1 << 24)
#define DORCR_PG2D_FIX0		(2 << 24)
#define DORCR_PG2D_DOOR		(3 << 24)
#define DORCR_PG2D_MASK		(3 << 24)
#define DORCR_DR1D		(1 << 21)
#define DORCR_PG1D_DS1		(0 << 16)
#define DORCR_PG1D_DS2		(1 << 16)
#define DORCR_PG1D_FIX0		(2 << 16)
#define DORCR_PG1D_DOOR		(3 << 16)
#define DORCR_PG1D_MASK		(3 << 16)
#define DORCR_PG1T		(1 << 30)
#define DORCR_DK1S		(1 << 28)
#define DORCR_PG1D_DS0		(0 << 24)
#define DORCR_PG1D_DS1		(1 << 24)
#define DORCR_PG1D_FIX0		(2 << 24)
#define DORCR_PG1D_DOOR		(3 << 24)
#define DORCR_PG1D_MASK		(3 << 24)
#define DORCR_DR0D		(1 << 21)
#define DORCR_PG0D_DS0		(0 << 16)
#define DORCR_PG0D_DS1		(1 << 16)
#define DORCR_PG0D_FIX0		(2 << 16)
#define DORCR_PG0D_DOOR		(3 << 16)
#define DORCR_PG0D_MASK		(3 << 16)
#define DORCR_RGPV		(1 << 4)
#define DORCR_DPRS		(1 << 0)

+1 −1
Original line number Diff line number Diff line
@@ -73,7 +73,7 @@ void rcar_du_vsp_enable(struct rcar_du_crtc *crtc)
			.src.y2 = mode->vdisplay << 16,
			.zpos = 0,
		},
		.format = rcar_du_format_info(DRM_FORMAT_ARGB8888),
		.format = rcar_du_format_info(DRM_FORMAT_XRGB8888),
		.source = RCAR_DU_PLANE_VSPD1,
		.colorkey = 0,
	};
Loading