All of lore.kernel.org
 help / color / mirror / Atom feed
From: Heiko Stuebner <heiko@sntech.de>
To: dri-devel@lists.freedesktop.org
Cc: mark.rutland@arm.com, devicetree@vger.kernel.org,
	briannorris@chromium.org, hoegsberg@gmail.com,
	philippe.cornu@st.com, yannick.fertre@st.com,
	linux-rockchip@lists.infradead.org, nickey.yang@rock-chips.com,
	robh+dt@kernel.org, thierry.reding@gmail.com,
	laurent.pinchart@ideasonboard.com, mka@chromium.org
Subject: [PATCH v2 8/8] drm/rockchip: dsi: add dual mipi support
Date: Mon, 18 Jun 2018 12:28:06 +0200	[thread overview]
Message-ID: <20180618102806.15650-9-heiko@sntech.de> (raw)
In-Reply-To: <20180618102806.15650-1-heiko@sntech.de>

Add the Rockchip-sepcific dual-dsi setup and hook it into the VOP as well.
As described in the general dual-dsi devicetree binding, the panel should
define two input ports and point each of them to one of the used dsi-
controllers, as well as declare one of them as clock-master.
This is used to determine the dual-dsi state and get access to both
controller instances.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 .../gpu/drm/rockchip/dw-mipi-dsi-rockchip.c   | 67 ++++++++++++++++++-
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h   |  1 +
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c   |  3 +
 drivers/gpu/drm/rockchip/rockchip_drm_vop.h   |  4 ++
 drivers/gpu/drm/rockchip/rockchip_vop_reg.c   |  1 +
 5 files changed, 75 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
index 12e4dacc7970..3382ad5a1b0d 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
@@ -218,6 +218,10 @@ struct dw_mipi_dsi_rockchip {
 	struct clk *grf_clk;
 	struct clk *phy_cfg_clk;
 
+	/* dual-channel */
+	bool is_slave;
+	struct dw_mipi_dsi_rockchip *slave;
+
 	unsigned int lane_mbps; /* per lane */
 	u16 input_div;
 	u16 feedback_div;
@@ -604,6 +608,8 @@ static void dw_mipi_dsi_encoder_mode_set(struct drm_encoder *encoder,
 	}
 
 	dw_mipi_dsi_rockchip_config(dsi, mux);
+	if (dsi->slave)
+		dw_mipi_dsi_rockchip_config(dsi->slave, mux);
 
 	clk_disable_unprepare(dsi->grf_clk);
 }
@@ -632,6 +638,8 @@ dw_mipi_dsi_encoder_atomic_check(struct drm_encoder *encoder,
 	}
 
 	s->output_type = DRM_MODE_CONNECTOR_DSI;
+	if (dsi->slave)
+		s->output_flags = ROCKCHIP_OUTPUT_DSI_DUAL;
 
 	return 0;
 }
@@ -641,6 +649,8 @@ static void dw_mipi_dsi_encoder_disable(struct drm_encoder *encoder)
 	struct dw_mipi_dsi_rockchip *dsi = to_dsi(encoder);
 
 	pm_runtime_put(dsi->dev);
+	if (dsi->slave)
+		pm_runtime_put(dsi->slave->dev);
 }
 
 static const struct drm_encoder_helper_funcs
@@ -681,18 +691,70 @@ static int dw_mipi_dsi_rockchip_bind(struct device *dev,
 {
 	struct dw_mipi_dsi_rockchip *dsi = dev_get_drvdata(dev);
 	struct drm_device *drm_dev = data;
+	struct device_node *second_np;
 	struct drm_bridge *bridge;
 	struct drm_panel *panel;
+	bool master1, master2;
 	int ret;
 
 	/*
-	 * Handle probe-deferrals due to missing display.
+	 * At this point both DSIs (if in use) should have probed and found
+	 * any connected displays or bridges.
+	 * This also takes care of handling possible probe-deferrals.
 	 */
 	ret = drm_of_find_panel_or_bridge(dsi->dev->of_node, 1, 0,
 					  &panel, &bridge);
 	if (ret)
 		return ret;
 
+	second_np = of_mipi_dsi_find_second_host(dsi->dev->of_node, 1, 0);
+	if (IS_ERR(second_np))
+		return PTR_ERR(second_np);
+
+	if (second_np) {
+		struct platform_device *pdev;
+
+		master1 = of_property_read_bool(dsi->dev->of_node,
+						"clock-master");
+		master2 = of_property_read_bool(second_np, "clock-master");
+
+		if (master1 && master2) {
+			DRM_DEV_ERROR(dsi->dev, "only one clock-master allowed\n");
+			of_node_put(second_np);
+			return -EINVAL;
+		}
+
+		if (!master1 && !master2) {
+			DRM_DEV_ERROR(dsi->dev, "no clock-master defined\n");
+			of_node_put(second_np);
+			return -EINVAL;
+		}
+
+		/* we are the slave in dual-DSI */
+		if (!master1) {
+			dsi->is_slave = true;
+			of_node_put(second_np);
+			return 0;
+		}
+
+		pdev = of_find_device_by_node(second_np);
+		if (!pdev) {
+			DRM_DEV_ERROR(dev, "could not find slave controller\n");
+			return -ENODEV;
+		}
+
+		dsi->slave = platform_get_drvdata(pdev);
+		if (!dsi->slave) {
+			DRM_DEV_ERROR(dev, "could not get slaves platform-data\n");
+			return -ENODEV;
+		}
+
+		dsi->slave->is_slave = true;
+		dw_mipi_dsi_set_slave(dsi->dmd, dsi->slave->dmd);
+
+		of_node_put(second_np);
+	}
+
 	ret = rockchip_dsi_drm_create_encoder(dsi, drm_dev);
 	if (ret) {
 		DRM_DEV_ERROR(dev, "Failed to create drm encoder\n");
@@ -714,6 +776,9 @@ static void dw_mipi_dsi_rockchip_unbind(struct device *dev,
 {
 	struct dw_mipi_dsi_rockchip *dsi = dev_get_drvdata(dev);
 
+	if (dsi->is_slave)
+		return;
+
 	dw_mipi_dsi_unbind(dsi->dmd);
 }
 
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index 96bb4ca8febf..2e6d2d4d1b65 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -37,6 +37,7 @@ struct rockchip_crtc_state {
 	int output_type;
 	int output_mode;
 	int output_bpc;
+	int output_flags;
 };
 #define to_rockchip_crtc_state(s) \
 		container_of(s, struct rockchip_crtc_state, base)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index d105e984cf09..9b2fa5e0eade 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -916,6 +916,7 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc,
 	pin_pol |= (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) ?
 		   BIT(VSYNC_POSITIVE) : 0;
 	VOP_REG_SET(vop, output, pin_pol, pin_pol);
+	VOP_REG_SET(vop, output, mipi_dual_channel_en, 0);
 
 	switch (s->output_type) {
 	case DRM_MODE_CONNECTOR_LVDS:
@@ -933,6 +934,8 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc,
 	case DRM_MODE_CONNECTOR_DSI:
 		VOP_REG_SET(vop, output, mipi_pin_pol, pin_pol);
 		VOP_REG_SET(vop, output, mipi_en, 1);
+		VOP_REG_SET(vop, output, mipi_dual_channel_en,
+			    !!(s->output_flags & ROCKCHIP_OUTPUT_DSI_DUAL));
 		break;
 	case DRM_MODE_CONNECTOR_DisplayPort:
 		pin_pol &= ~BIT(DCLK_INVERT);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
index 084acdd0019a..63c815edeaac 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
@@ -60,6 +60,7 @@ struct vop_output {
 	struct vop_reg edp_en;
 	struct vop_reg hdmi_en;
 	struct vop_reg mipi_en;
+	struct vop_reg mipi_dual_channel_en;
 	struct vop_reg rgb_en;
 };
 
@@ -213,6 +214,9 @@ struct vop_data {
 /* for use special outface */
 #define ROCKCHIP_OUT_MODE_AAAA	15
 
+/* output flags */
+#define ROCKCHIP_OUTPUT_DSI_DUAL	BIT(0)
+
 enum alpha_mode {
 	ALPHA_STRAIGHT,
 	ALPHA_INVERSE,
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
index 08023d3ecb76..56d83f1c2599 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
@@ -421,6 +421,7 @@ static const struct vop_output rk3399_output = {
 	.hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
 	.edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14),
 	.mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15),
+	.mipi_dual_channel_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 3),
 };
 
 static const struct vop_data rk3399_vop_big = {
-- 
2.17.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

  parent reply	other threads:[~2018-06-18 10:28 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-06-18 10:27 [PATCH v2 0/8] drm/rockchip: migrate to common dw-mipi-dsi bridge and dual-dsi Heiko Stuebner
2018-06-18 10:27 ` [PATCH v2 1/8] drm/bridge/synopsys: dsi: move mipi_dsi_host_unregister to __dw_mipi_dsi_remove Heiko Stuebner
2018-07-03 10:40   ` Andrzej Hajda
2018-07-03 11:58   ` Philippe CORNU
2018-06-18 10:28 ` [PATCH v2 2/8] drm/bridge/synopsys: dsi: don't call __dw_mipi_dsi_probe from dw_mipi_dsi_bind Heiko Stuebner
2018-07-03 12:16   ` Andrzej Hajda
2018-07-03 12:32     ` Heiko Stübner
2018-07-04 12:23     ` Heiko Stuebner
2018-06-18 10:28 ` [PATCH v2 3/8] drm/bridge/synopsys: dsi: defer probing if panel not available in bridge-attach Heiko Stuebner
2018-07-03 11:57   ` Philippe CORNU
2018-07-03 12:42   ` Andrzej Hajda
2018-07-04 10:36     ` Heiko Stuebner
2018-06-18 10:28 ` [PATCH v2 4/8] dt-bindings: display: rockchip: update DSI controller Heiko Stuebner
2018-06-18 10:30   ` Heiko Stuebner
2018-06-18 10:28 ` [PATCH v2 5/8] drm/rockchip: dsi: migrate to use dw-mipi-dsi bridge driver Heiko Stuebner
2018-07-03 13:06   ` Andrzej Hajda
2018-06-18 10:28 ` [PATCH v2 6/8] drm/dsi: add helper function to find the second host in a dual-dsi setup Heiko Stuebner
2018-07-03 15:06   ` Andrzej Hajda
2018-07-04 10:47     ` Heiko Stuebner
2018-06-18 10:28 ` [PATCH v2 7/8] drm/bridge/synopsys: dsi: add dual-dsi support Heiko Stuebner
2018-07-03 11:57   ` Philippe CORNU
2018-07-03 17:07   ` Andrzej Hajda
2018-07-09 13:45     ` Heiko Stuebner
2018-07-09 16:02       ` Andrzej Hajda
2018-06-18 10:28 ` Heiko Stuebner [this message]
2018-07-03 12:05 ` [PATCH v2 0/8] drm/rockchip: migrate to common dw-mipi-dsi bridge and dual-dsi Philippe CORNU

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180618102806.15650-9-heiko@sntech.de \
    --to=heiko@sntech.de \
    --cc=briannorris@chromium.org \
    --cc=devicetree@vger.kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=hoegsberg@gmail.com \
    --cc=laurent.pinchart@ideasonboard.com \
    --cc=linux-rockchip@lists.infradead.org \
    --cc=mark.rutland@arm.com \
    --cc=mka@chromium.org \
    --cc=nickey.yang@rock-chips.com \
    --cc=philippe.cornu@st.com \
    --cc=robh+dt@kernel.org \
    --cc=thierry.reding@gmail.com \
    --cc=yannick.fertre@st.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.