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 8/8] drm/rockchip: dsi: add dual mipi support
Date: Mon, 11 Jun 2018 15:35:02 +0200 [thread overview]
Message-ID: <20180611133502.1292-9-heiko@sntech.de> (raw)
In-Reply-To: <20180611133502.1292-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 93b019482276..cc47610d5bdf 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
@@ -227,6 +227,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;
@@ -613,6 +617,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);
}
@@ -641,6 +647,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;
}
@@ -650,6 +658,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
@@ -690,18 +700,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");
@@ -723,6 +785,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 3013992d088d..f8861ba3c025 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -36,6 +36,7 @@ struct rockchip_crtc_state {
struct drm_crtc_state base;
int output_type;
int output_mode;
+ 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 7192e101bb44..2f6eac7ed510 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -905,6 +905,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:
@@ -922,6 +923,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 56bbd2e2a8ef..a4627d2343a3 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;
};
@@ -212,6 +213,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 2e4eea3459fe..7d294290ef11 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
@@ -420,6 +420,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
prev parent reply other threads:[~2018-06-11 13:35 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-06-11 13:34 [RFC PATCH 0/8] drm/rockchip: migrate to common dw-mipi-dsi bridge and dual-dsi Heiko Stuebner
2018-06-11 13:34 ` [PATCH 1/8] drm/bridge/synopsys: dsi: move mipi_dsi_host_unregister to __dw_mipi_dsi_remove Heiko Stuebner
2018-06-11 13:34 ` [PATCH 2/8] drm/bridge/synopsys: dsi: don't call __dw_mipi_dsi_probe from dw_mipi_dsi_bind Heiko Stuebner
2018-06-11 13:34 ` [PATCH 3/8] drm/bridge/synopsys: dsi: defer probing if panel not available in bridge-attach Heiko Stuebner
2018-06-11 13:34 ` [PATCH 4/8] dt-bindings: display: rockchip: update DSI controller Heiko Stuebner
[not found] ` <20180611133502.1292-5-heiko-4mtYJXux2i+zQB+pC5nmwQ@public.gmane.org>
2018-06-12 22:08 ` Rob Herring
2018-06-11 13:34 ` [PATCH v8 5/8] drm/rockchip: dsi: migrate to use dw-mipi-dsi bridge driver Heiko Stuebner
[not found] ` <20180611133502.1292-1-heiko-4mtYJXux2i+zQB+pC5nmwQ@public.gmane.org>
2018-06-11 13:35 ` [PATCH 6/8] drm/dsi: add helper function to find the second host in a dual-dsi setup Heiko Stuebner
2018-06-11 13:35 ` [PATCH 7/8] drm/bridge/synopsys: dsi: add dual-dsi support Heiko Stuebner
2018-06-11 13:35 ` Heiko Stuebner [this message]
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=20180611133502.1292-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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox