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

Commit 34c8a892 authored by Daniel Vetter's avatar Daniel Vetter
Browse files

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



R-Car DU changes for v5.3:

- R8A774A1 SoC support
- LVDS dual-link mode support
- Support for additional formats
- Misc fixes

Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190608134652.GE4786@pendragon.ideasonboard.com
parents 396f9aca cb5f15b7
Loading
Loading
Loading
Loading
+15 −4
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@ Required properties:
- compatible : Shall contain one of
  - "renesas,r8a7743-lvds" for R8A7743 (RZ/G1M) compatible LVDS encoders
  - "renesas,r8a7744-lvds" for R8A7744 (RZ/G1N) compatible LVDS encoders
  - "renesas,r8a774a1-lvds" for R8A774A1 (RZ/G2M) compatible LVDS encoders
  - "renesas,r8a774c0-lvds" for R8A774C0 (RZ/G2E) compatible LVDS encoders
  - "renesas,r8a7790-lvds" for R8A7790 (R-Car H2) compatible LVDS encoders
  - "renesas,r8a7791-lvds" for R8A7791 (R-Car M2-W) compatible LVDS encoders
@@ -45,14 +46,24 @@ OF graph bindings specified in Documentation/devicetree/bindings/graph.txt.

Each port shall have a single endpoint.

Optional properties:

- renesas,companion : phandle to the companion LVDS encoder. This property is
  mandatory for the first LVDS encoder on D3 and E3 SoCs, and shall point to
  the second encoder to be used as a companion in dual-link mode. It shall not
  be set for any other LVDS encoder.


Example:

	lvds0: lvds@feb90000 {
		compatible = "renesas,r8a7790-lvds";
		reg = <0 0xfeb90000 0 0x1c>;
		clocks = <&cpg CPG_MOD 726>;
		resets = <&cpg 726>;
		compatible = "renesas,r8a77990-lvds";
		reg = <0 0xfeb90000 0 0x20>;
		clocks = <&cpg CPG_MOD 727>;
		power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
		resets = <&cpg 727>;

		renesas,companion = <&lvds1>;

		ports {
			#address-cells = <1>;
+6 −0
Original line number Diff line number Diff line
@@ -28,6 +28,12 @@ Optional video port nodes:
- port@1: Second LVDS input port
- port@3: Second digital CMOS/TTL parallel output

The device can operate in single-link mode or dual-link mode. In single-link
mode, all pixels are received on port@0, and port@1 shall not contain any
endpoint. In dual-link mode, even-numbered pixels are received on port@0 and
odd-numbered pixels on port@1, and both port@0 and port@1 shall contain
endpoints.

Example:
--------

+2 −0
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@ Required Properties:
    - "renesas,du-r8a7744" for R8A7744 (RZ/G1N) compatible DU
    - "renesas,du-r8a7745" for R8A7745 (RZ/G1E) compatible DU
    - "renesas,du-r8a77470" for R8A77470 (RZ/G1C) compatible DU
    - "renesas,du-r8a774a1" for R8A774A1 (RZ/G2M) compatible DU
    - "renesas,du-r8a774c0" for R8A774C0 (RZ/G2E) compatible DU
    - "renesas,du-r8a7779" for R8A7779 (R-Car H1) compatible DU
    - "renesas,du-r8a7790" for R8A7790 (R-Car H2) compatible DU
@@ -58,6 +59,7 @@ corresponding to each DU output.
 R8A7744 (RZ/G1N)       DPAD 0         LVDS 0         -              -
 R8A7745 (RZ/G1E)       DPAD 0         DPAD 1         -              -
 R8A77470 (RZ/G1C)      DPAD 0         DPAD 1         LVDS 0         -
 R8A774A1 (RZ/G2M)      DPAD 0         HDMI 0         LVDS 0         -
 R8A774C0 (RZ/G2E)      DPAD 0         LVDS 0         LVDS 1         -
 R8A7779 (R-Car H1)     DPAD 0         DPAD 1         -              -
 R8A7790 (R-Car H2)     DPAD 0         LVDS 0         LVDS 1         -
+43 −11
Original line number Diff line number Diff line
@@ -33,6 +33,8 @@ struct thc63_dev {

	struct drm_bridge bridge;
	struct drm_bridge *next;

	struct drm_bridge_timings timings;
};

static inline struct thc63_dev *to_thc63(struct drm_bridge *bridge)
@@ -50,15 +52,28 @@ static int thc63_attach(struct drm_bridge *bridge)
static enum drm_mode_status thc63_mode_valid(struct drm_bridge *bridge,
					const struct drm_display_mode *mode)
{
	struct thc63_dev *thc63 = to_thc63(bridge);
	unsigned int min_freq;
	unsigned int max_freq;

	/*
	 * The THC63LVD1024 clock frequency range is 8 to 135 MHz in single-in
	 * mode. Note that the limits are different in dual-in, single-out mode,
	 * and will need to be adjusted accordingly.
	 * The THC63LVD1024 pixel rate range is 8 to 135 MHz in all modes but
	 * dual-in, single-out where it is 40 to 150 MHz. As dual-in, dual-out
	 * isn't supported by the driver yet, simply derive the limits from the
	 * input mode.
	 */
	if (mode->clock < 8000)
	if (thc63->timings.dual_link) {
		min_freq = 40000;
		max_freq = 150000;
	} else {
		min_freq = 8000;
		max_freq = 135000;
	}

	if (mode->clock < min_freq)
		return MODE_CLOCK_LOW;

	if (mode->clock > 135000)
	if (mode->clock > max_freq)
		return MODE_CLOCK_HIGH;

	return MODE_OK;
@@ -103,19 +118,19 @@ static const struct drm_bridge_funcs thc63_bridge_func = {

static int thc63_parse_dt(struct thc63_dev *thc63)
{
	struct device_node *thc63_out;
	struct device_node *endpoint;
	struct device_node *remote;

	thc63_out = of_graph_get_endpoint_by_regs(thc63->dev->of_node,
	endpoint = of_graph_get_endpoint_by_regs(thc63->dev->of_node,
						 THC63_RGB_OUT0, -1);
	if (!thc63_out) {
	if (!endpoint) {
		dev_err(thc63->dev, "Missing endpoint in port@%u\n",
			THC63_RGB_OUT0);
		return -ENODEV;
	}

	remote = of_graph_get_remote_port_parent(thc63_out);
	of_node_put(thc63_out);
	remote = of_graph_get_remote_port_parent(endpoint);
	of_node_put(endpoint);
	if (!remote) {
		dev_err(thc63->dev, "Endpoint in port@%u unconnected\n",
			THC63_RGB_OUT0);
@@ -134,6 +149,22 @@ static int thc63_parse_dt(struct thc63_dev *thc63)
	if (!thc63->next)
		return -EPROBE_DEFER;

	endpoint = of_graph_get_endpoint_by_regs(thc63->dev->of_node,
						 THC63_LVDS_IN1, -1);
	if (endpoint) {
		remote = of_graph_get_remote_port_parent(endpoint);
		of_node_put(endpoint);

		if (remote) {
			if (of_device_is_available(remote))
				thc63->timings.dual_link = true;
			of_node_put(remote);
		}
	}

	dev_dbg(thc63->dev, "operating in %s-link mode\n",
		thc63->timings.dual_link ? "dual" : "single");

	return 0;
}

@@ -190,6 +221,7 @@ static int thc63_probe(struct platform_device *pdev)
	thc63->bridge.driver_private = thc63;
	thc63->bridge.of_node = pdev->dev.of_node;
	thc63->bridge.funcs = &thc63_bridge_func;
	thc63->bridge.timings = &thc63->timings;

	drm_bridge_add(&thc63->bridge);

+30 −0
Original line number Diff line number Diff line
@@ -102,6 +102,35 @@ static const struct rcar_du_device_info rzg1_du_r8a77470_info = {
	},
};

static const struct rcar_du_device_info rcar_du_r8a774a1_info = {
	.gen = 3,
	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
		  | RCAR_DU_FEATURE_VSP1_SOURCE
		  | RCAR_DU_FEATURE_INTERLACED
		  | RCAR_DU_FEATURE_TVM_SYNC,
	.channels_mask = BIT(2) | BIT(1) | BIT(0),
	.routes = {
		/*
		 * R8A774A1 has one RGB output, one LVDS output and one HDMI
		 * output.
		 */
		[RCAR_DU_OUTPUT_DPAD0] = {
			.possible_crtcs = BIT(2),
			.port = 0,
		},
		[RCAR_DU_OUTPUT_HDMI0] = {
			.possible_crtcs = BIT(1),
			.port = 1,
		},
		[RCAR_DU_OUTPUT_LVDS0] = {
			.possible_crtcs = BIT(0),
			.port = 2,
		},
	},
	.num_lvds = 1,
	.dpll_mask =  BIT(1),
};

static const struct rcar_du_device_info rcar_du_r8a774c0_info = {
	.gen = 3,
	.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
@@ -386,6 +415,7 @@ static const struct of_device_id rcar_du_of_table[] = {
	{ .compatible = "renesas,du-r8a7744", .data = &rzg1_du_r8a7743_info },
	{ .compatible = "renesas,du-r8a7745", .data = &rzg1_du_r8a7745_info },
	{ .compatible = "renesas,du-r8a77470", .data = &rzg1_du_r8a77470_info },
	{ .compatible = "renesas,du-r8a774a1", .data = &rcar_du_r8a774a1_info },
	{ .compatible = "renesas,du-r8a774c0", .data = &rcar_du_r8a774c0_info },
	{ .compatible = "renesas,du-r8a7779", .data = &rcar_du_r8a7779_info },
	{ .compatible = "renesas,du-r8a7790", .data = &rcar_du_r8a7790_info },
Loading