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

Commit 1a3865d6 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge branch 'drm/next/du' of git://linuxtv.org/pinchartl/media into drm-next

rcar-du -next branch.

* 'drm/next/du' of git://linuxtv.org/pinchartl/media:
  drm: rcar-du: Fix LVDS start sequence on Gen3
  drm: rcar-du: Fix H/V sync signal polarity configuration
  drm: rcar-du: Fix display timing controller parameter
  drm: rcar-du: Fix dot clock routing configuration
  drm: rcar-du: Add R8A7796 support
  drm: rcar-du: Add R8A7792 support
  drm: rcar-du: Simplify and fix probe error handling
  drm: rcar-du: Fix crash in encoder failure error path
  drm: rcar-du: Remove memory allocation error message
  drm: rcar-du: Remove test for impossible error condition
  drm: rcar-du: Bring HDMI encoder comments in line with the driver
  drm: rcar-du: Constify node argument to rcar_du_lvds_connector_init()
  video: of: Constify node argument to display timing functions
parents d8c1abd9 85e8f8d1
Loading
Loading
Loading
Loading
+8 −4
Original line number Diff line number Diff line
@@ -6,9 +6,11 @@ Required Properties:
    - "renesas,du-r8a7779" for R8A7779 (R-Car H1) compatible DU
    - "renesas,du-r8a7790" for R8A7790 (R-Car H2) compatible DU
    - "renesas,du-r8a7791" for R8A7791 (R-Car M2-W) compatible DU
    - "renesas,du-r8a7792" for R8A7792 (R-Car V2H) compatible DU
    - "renesas,du-r8a7793" for R8A7793 (R-Car M2-N) compatible DU
    - "renesas,du-r8a7794" for R8A7794 (R-Car E2) compatible DU
    - "renesas,du-r8a7795" for R8A7795 (R-Car H3) compatible DU
    - "renesas,du-r8a7796" for R8A7796 (R-Car M3-W) compatible DU

  - reg: A list of base address and length of each memory resource, one for
    each entry in the reg-names property.
@@ -25,10 +27,10 @@ Required Properties:
  - clock-names: Name of the clocks. This property is model-dependent.
    - R8A7779 uses a single functional clock. The clock doesn't need to be
      named.
    - R8A779[01345] use one functional clock per channel and one clock per LVDS
      encoder (if available). The functional clocks must be named "du.x" with
      "x" being the channel numerical index. The LVDS clocks must be named
      "lvds.x" with "x" being the LVDS encoder numerical index.
    - R8A779[0123456] use one functional clock per channel and one clock per
      LVDS encoder (if available). The functional clocks must be named "du.x"
      with "x" being the channel numerical index. The LVDS clocks must be
      named "lvds.x" with "x" being the LVDS encoder numerical index.
    - In addition to the functional and encoder clocks, all DU versions also
      support externally supplied pixel clocks. Those clocks are optional.
      When supplied they must be named "dclkin.x" with "x" being the input
@@ -47,9 +49,11 @@ corresponding to each DU output.
 R8A7779 (H1)	DPAD 0		DPAD 1		-		-
 R8A7790 (H2)	DPAD		LVDS 0		LVDS 1		-
 R8A7791 (M2-W)	DPAD		LVDS 0		-		-
 R8A7792 (V2H)	DPAD 0		DPAD 1		-		-
 R8A7793 (M2-N)	DPAD		LVDS 0		-		-
 R8A7794 (E2)	DPAD 0		DPAD 1		-		-
 R8A7795 (H3)	DPAD		HDMI 0		HDMI 1		LVDS
 R8A7796 (M3-W)	DPAD		HDMI		LVDS		-


Example: R8A7790 (R-Car H2) DU
+3 −3
Original line number Diff line number Diff line
@@ -149,8 +149,8 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
	rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? OTAR2 : OTAR, 0);

	/* Signal polarities */
	value = ((mode->flags & DRM_MODE_FLAG_PVSYNC) ? 0 : DSMR_VSL)
	      | ((mode->flags & DRM_MODE_FLAG_PHSYNC) ? 0 : DSMR_HSL)
	value = ((mode->flags & DRM_MODE_FLAG_PVSYNC) ? DSMR_VSL : 0)
	      | ((mode->flags & DRM_MODE_FLAG_PHSYNC) ? DSMR_HSL : 0)
	      | DSMR_DIPM_DISP | DSMR_CSPM;
	rcar_du_crtc_write(rcrtc, DSMR, value);

@@ -172,7 +172,7 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
					mode->crtc_vsync_start - 1);
	rcar_du_crtc_write(rcrtc, VCR,  mode->crtc_vtotal - 1);

	rcar_du_crtc_write(rcrtc, DESR,  mode->htotal - mode->hsync_start);
	rcar_du_crtc_write(rcrtc, DESR,  mode->htotal - mode->hsync_start - 1);
	rcar_du_crtc_write(rcrtc, DEWR,  mode->hdisplay);
}

+57 −26
Original line number Diff line number Diff line
@@ -110,6 +110,27 @@ static const struct rcar_du_device_info rcar_du_r8a7791_info = {
	.num_lvds = 1,
};

static const struct rcar_du_device_info rcar_du_r8a7792_info = {
	.gen = 2,
	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
		  | RCAR_DU_FEATURE_EXT_CTRL_REGS,
	.num_crtcs = 2,
	.routes = {
		/* R8A7792 has two RGB outputs. */
		[RCAR_DU_OUTPUT_DPAD0] = {
			.possible_crtcs = BIT(0),
			.encoder_type = DRM_MODE_ENCODER_NONE,
			.port = 0,
		},
		[RCAR_DU_OUTPUT_DPAD1] = {
			.possible_crtcs = BIT(1),
			.encoder_type = DRM_MODE_ENCODER_NONE,
			.port = 1,
		},
	},
	.num_lvds = 0,
};

static const struct rcar_du_device_info rcar_du_r8a7794_info = {
	.gen = 2,
	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
@@ -157,13 +178,39 @@ static const struct rcar_du_device_info rcar_du_r8a7795_info = {
	.num_lvds = 1,
};

static const struct rcar_du_device_info rcar_du_r8a7796_info = {
	.gen = 3,
	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
		  | RCAR_DU_FEATURE_EXT_CTRL_REGS
		  | RCAR_DU_FEATURE_VSP1_SOURCE,
	.num_crtcs = 3,
	.routes = {
		/* R8A7796 has one RGB output, one LVDS output and one
		 * (currently unsupported) HDMI output.
		 */
		[RCAR_DU_OUTPUT_DPAD0] = {
			.possible_crtcs = BIT(2),
			.encoder_type = DRM_MODE_ENCODER_NONE,
			.port = 0,
		},
		[RCAR_DU_OUTPUT_LVDS0] = {
			.possible_crtcs = BIT(0),
			.encoder_type = DRM_MODE_ENCODER_LVDS,
			.port = 2,
		},
	},
	.num_lvds = 1,
};

static const struct of_device_id rcar_du_of_table[] = {
	{ .compatible = "renesas,du-r8a7779", .data = &rcar_du_r8a7779_info },
	{ .compatible = "renesas,du-r8a7790", .data = &rcar_du_r8a7790_info },
	{ .compatible = "renesas,du-r8a7791", .data = &rcar_du_r8a7791_info },
	{ .compatible = "renesas,du-r8a7792", .data = &rcar_du_r8a7792_info },
	{ .compatible = "renesas,du-r8a7793", .data = &rcar_du_r8a7791_info },
	{ .compatible = "renesas,du-r8a7794", .data = &rcar_du_r8a7794_info },
	{ .compatible = "renesas,du-r8a7795", .data = &rcar_du_r8a7795_info },
	{ .compatible = "renesas,du-r8a7796", .data = &rcar_du_r8a7796_info },
	{ }
};

@@ -283,7 +330,6 @@ static int rcar_du_remove(struct platform_device *pdev)

	drm_kms_helper_poll_fini(ddev);
	drm_mode_config_cleanup(ddev);
	drm_vblank_cleanup(ddev);

	drm_dev_unref(ddev);

@@ -292,18 +338,12 @@ static int rcar_du_remove(struct platform_device *pdev)

static int rcar_du_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct rcar_du_device *rcdu;
	struct drm_device *ddev;
	struct resource *mem;
	int ret;

	if (np == NULL) {
		dev_err(&pdev->dev, "no device tree node\n");
		return -ENODEV;
	}

	/* Allocate and initialize the DRM and R-Car device structures. */
	/* Allocate and initialize the R-Car device structure. */
	rcdu = devm_kzalloc(&pdev->dev, sizeof(*rcdu), GFP_KERNEL);
	if (rcdu == NULL)
		return -ENOMEM;
@@ -313,31 +353,22 @@ static int rcar_du_probe(struct platform_device *pdev)
	rcdu->dev = &pdev->dev;
	rcdu->info = of_match_device(rcar_du_of_table, rcdu->dev)->data;

	ddev = drm_dev_alloc(&rcar_du_driver, &pdev->dev);
	if (IS_ERR(ddev))
		return PTR_ERR(ddev);

	rcdu->ddev = ddev;
	ddev->dev_private = rcdu;

	platform_set_drvdata(pdev, rcdu);

	/* I/O resources */
	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	rcdu->mmio = devm_ioremap_resource(&pdev->dev, mem);
	if (IS_ERR(rcdu->mmio)) {
		ret = PTR_ERR(rcdu->mmio);
		goto error;
	}

	/* Initialize vertical blanking interrupts handling. Start with vblank
	 * disabled for all CRTCs.
	 */
	ret = drm_vblank_init(ddev, (1 << rcdu->info->num_crtcs) - 1);
	if (ret < 0)
		goto error;
	if (IS_ERR(rcdu->mmio))
		return PTR_ERR(rcdu->mmio);

	/* DRM/KMS objects */
	ddev = drm_dev_alloc(&rcar_du_driver, &pdev->dev);
	if (IS_ERR(ddev))
		return PTR_ERR(ddev);

	rcdu->ddev = ddev;
	ddev->dev_private = rcdu;

	ret = rcar_du_modeset_init(rcdu);
	if (ret < 0) {
		if (ret != -EPROBE_DEFER)
+13 −9
Original line number Diff line number Diff line
@@ -105,16 +105,20 @@ static void rcar_du_group_setup(struct rcar_du_group *rgrp)
	if (rcar_du_has(rgrp->dev, RCAR_DU_FEATURE_EXT_CTRL_REGS)) {
		rcar_du_group_setup_defr8(rgrp);

		/* Configure input dot clock routing. We currently hardcode the
		 * configuration to routing DOTCLKINn to DUn.
		/*
		 * Configure input dot clock routing. We currently hardcode the
		 * configuration to routing DOTCLKINn to DUn. Register fields
		 * depend on the DU generation, but the resulting value is 0 in
		 * all cases.
		 *
		 * On Gen2 a single register in the first group controls dot
		 * clock selection for all channels, while on Gen3 dot clocks
		 * are setup through per-group registers, only available when
		 * the group has two channels.
		 */
		rcar_du_group_write(rgrp, DIDSR, DIDSR_CODE |
				    DIDSR_LCDS_DCLKIN(2) |
				    DIDSR_LCDS_DCLKIN(1) |
				    DIDSR_LCDS_DCLKIN(0) |
				    DIDSR_PDCS_CLK(2, 0) |
				    DIDSR_PDCS_CLK(1, 0) |
				    DIDSR_PDCS_CLK(0, 0));
		if ((rcdu->info->gen < 3 && rgrp->index == 0) ||
		    (rcdu->info->gen == 3 &&  rgrp->num_crtcs > 1))
			rcar_du_group_write(rgrp, DIDSR, DIDSR_CODE);
	}

	if (rcdu->info->gen >= 3)
+2 −2
Original line number Diff line number Diff line
@@ -108,7 +108,7 @@ int rcar_du_hdmienc_init(struct rcar_du_device *rcdu,
	if (hdmienc == NULL)
		return -ENOMEM;

	/* Locate drm bridge from the hdmi encoder DT node */
	/* Locate the DRM bridge from the HDMI encoder DT node. */
	bridge = of_drm_find_bridge(np);
	if (!bridge)
		return -EPROBE_DEFER;
@@ -123,7 +123,7 @@ int rcar_du_hdmienc_init(struct rcar_du_device *rcdu,
	renc->hdmi = hdmienc;
	hdmienc->renc = renc;

	/* Link drm_bridge to encoder */
	/* Link the bridge to the encoder. */
	bridge->encoder = encoder;
	encoder->bridge = bridge;

Loading