linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Chen-Yu Tsai <wens@csie.org>
To: Maxime Ripard <maxime.ripard@free-electrons.com>,
	David Airlie <airlied@linux.ie>
Cc: Chen-Yu Tsai <wens@csie.org>,
	dri-devel@lists.freedesktop.org, linux-sunxi@googlegroups.com,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org
Subject: [PATCH 09/11] drm/sun4i: Support two display pipelines
Date: Thu,  9 Mar 2017 18:05:32 +0800	[thread overview]
Message-ID: <20170309100534.14023-10-wens@csie.org> (raw)
In-Reply-To: <20170309100534.14023-1-wens@csie.org>

Some Allwinner SoCs have two display pipelines (frontend -> backend ->
tcon).

Previously we only supported one pipeline. This patch extends the
current driver to support two. It extends the tcon and backend pointers
in sun4i_drv into arrays, and makes the related bind functions store
the pointer into said arrays based on the id fetched from the device
tree. In the case of the tcons, it falls back to a first come order
if no encoders that can be used for differentiating the tcons are
defined. The driver's depth-first traversal of the of graph, coupled
with the increasing address ordering of the of graph endpoints, and
the fact that tcon0 should always be enabled for the tcon/encoder
mux to be accessible, means that tcon1 would always come after tcon0.

Assignment of the device structure into sun4i_drv is moved to the end
of the bind function, when all possible error checks have passed.

This patch also drops a trailing 0 in one of the backend probe messages.

Signed-off-by: Chen-Yu Tsai <wens@csie.org>
---
 drivers/gpu/drm/sun4i/sun4i_backend.c |  9 +++++++--
 drivers/gpu/drm/sun4i/sun4i_drv.c     |  2 +-
 drivers/gpu/drm/sun4i/sun4i_drv.h     |  6 ++++--
 drivers/gpu/drm/sun4i/sun4i_tcon.c    | 25 +++++++++++++++++--------
 4 files changed, 29 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c
index f3c92d54c8e4..8d22efd5a9cc 100644
--- a/drivers/gpu/drm/sun4i/sun4i_backend.c
+++ b/drivers/gpu/drm/sun4i/sun4i_backend.c
@@ -350,12 +350,15 @@ static int sun4i_backend_bind(struct device *dev, struct device *master,
 	if (!backend)
 		return -ENOMEM;
 	dev_set_drvdata(dev, backend);
-	drv->backend = backend;
 
 	backend->id = sun4i_backend_of_get_id(dev->of_node);
 	if (backend->id < 0)
 		return backend->id;
 
+	/* We only support SUN4I_DRM_MAX_PIPELINES number of backends */
+	if (backend->id >= SUN4I_DRM_MAX_PIPELINES)
+		return -EINVAL;
+
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	regs = devm_ioremap_resource(dev, res);
 	if (IS_ERR(regs))
@@ -364,7 +367,7 @@ static int sun4i_backend_bind(struct device *dev, struct device *master,
 	backend->regs = devm_regmap_init_mmio(dev, regs,
 					      &sun4i_backend_regmap_config);
 	if (IS_ERR(backend->regs)) {
-		dev_err(dev, "Couldn't create the backend0 regmap\n");
+		dev_err(dev, "Couldn't create the backend regmap\n");
 		return PTR_ERR(backend->regs);
 	}
 
@@ -413,6 +416,8 @@ static int sun4i_backend_bind(struct device *dev, struct device *master,
 		}
 	}
 
+	drv->backend[backend->id] = backend;
+
 	/* Reset the registers */
 	for (i = 0x800; i < 0x1000; i += 4)
 		regmap_write(backend->regs, i, 0);
diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c
index 767bbadcc85d..c15ecb8343d7 100644
--- a/drivers/gpu/drm/sun4i/sun4i_drv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
@@ -271,7 +271,7 @@ static int sun4i_drv_probe(struct platform_device *pdev)
 	struct device_node *np = pdev->dev.of_node;
 	int i, count = 0;
 
-	for (i = 0;; i++) {
+	for (i = 0; i < SUN4I_DRM_MAX_PIPELINES; i++) {
 		struct device_node *pipeline = of_parse_phandle(np,
 								"allwinner,pipelines",
 								i);
diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.h b/drivers/gpu/drm/sun4i/sun4i_drv.h
index 5df50126ff52..ec1c08af47e1 100644
--- a/drivers/gpu/drm/sun4i/sun4i_drv.h
+++ b/drivers/gpu/drm/sun4i/sun4i_drv.h
@@ -16,9 +16,11 @@
 #include <linux/clk.h>
 #include <linux/regmap.h>
 
+#define SUN4I_DRM_MAX_PIPELINES		2
+
 struct sun4i_drv {
-	struct sun4i_backend	*backend;
-	struct sun4i_tcon	*tcon;
+	struct sun4i_backend	*backend[SUN4I_DRM_MAX_PIPELINES];
+	struct sun4i_tcon	*tcon[SUN4I_DRM_MAX_PIPELINES];
 
 	struct drm_fbdev_cma	*fbdev;
 };
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index b774c9a50c55..7749c3133f38 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -532,7 +532,6 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
 	if (!tcon)
 		return -ENOMEM;
 	dev_set_drvdata(dev, tcon);
-	drv->tcon = tcon;
 	tcon->drm = drm;
 	tcon->dev = dev;
 	tcon->quirks = of_device_get_match_data(dev);
@@ -540,14 +539,22 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
 	/* This can fail if the DT does not have any downstream encoders. */
 	tcon->id = sun4i_tcon_of_get_id(dev->of_node);
 	if (tcon->id < 0) {
-		/*
-		 * TODO We currently support only 1 TCON, so we can
-		 * safely set this to 0. This should be revisited
-		 * when we add support for multiple pipelines.
-		 */
-		tcon->id = 0;
+		int i;
+
+		/* find the first empty tcon in sun4i_drv */
+		for (i = 0; i < SUN4I_DRM_MAX_PIPELINES; i++)
+			if (!drv->tcon[i])
+				tcon->id = i;
+
+		/* bail out if that failed */
+		if (tcon->id < 0)
+			return tcon->id;
 	}
 
+	/* We only support SUN4I_DRM_MAX_PIPELINES number of tcons */
+	if (tcon->id >= SUN4I_DRM_MAX_PIPELINES)
+		return -EINVAL;
+
 	tcon->lcd_rst = devm_reset_control_get(dev, "lcd");
 	if (IS_ERR(tcon->lcd_rst)) {
 		dev_err(dev, "Couldn't get our reset line\n");
@@ -588,7 +595,7 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
 		goto err_free_dotclock;
 	}
 
-	tcon->crtc = sun4i_crtc_init(drm, drv->backend, tcon);
+	tcon->crtc = sun4i_crtc_init(drm, drv->backend[tcon->id], tcon);
 	if (IS_ERR(tcon->crtc)) {
 		dev_err(dev, "Couldn't create our CRTC\n");
 		ret = PTR_ERR(tcon->crtc);
@@ -599,6 +606,8 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
 	if (ret < 0)
 		goto err_free_clocks;
 
+	drv->tcon[tcon->id] = tcon;
+
 	return 0;
 
 err_free_dotclock:
-- 
2.11.0

  parent reply	other threads:[~2017-03-09 10:06 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-03-09 10:05 [PATCH 00/11] drm/sun4i: Support two display pipelines Chen-Yu Tsai
2017-03-09 10:05 ` [PATCH 01/11] drm/sun4i: Fix TCON clock and regmap initialization sequence Chen-Yu Tsai
2017-03-09 10:05 ` [PATCH 02/11] drm/sun4i: Fix tcon channel 0 comment about backporch = backporch + hsync Chen-Yu Tsai
2017-03-09 10:05 ` [PATCH 03/11] drm/sun4i: Use embedded tcon pointer to get the tcon's output port node Chen-Yu Tsai
2017-03-09 10:05 ` [PATCH 04/11] drm/sun4i: tv: Get tcon and backend pointers from associated crtc Chen-Yu Tsai
2017-03-09 10:05 ` [PATCH 05/11] drm/sun4i: Pass pointers for associated backend and tcon into crtc init Chen-Yu Tsai
2017-03-09 10:05 ` [PATCH 06/11] drm/sun4i: Pass pointer for underlying backend into layer init Chen-Yu Tsai
2017-03-09 10:05 ` [PATCH 07/11] drm/sun4i: Fetch backend ID from device tree Chen-Yu Tsai
2017-03-09 10:05 ` [PATCH 08/11] drm/sun4i: Fetch TCON " Chen-Yu Tsai
2017-03-09 10:05 ` Chen-Yu Tsai [this message]
2017-03-09 10:36   ` [PATCH 09/11] drm/sun4i: Support two display pipelines Maxime Ripard
2017-03-09 11:20     ` Chen-Yu Tsai
2017-03-09 14:40       ` Maxime Ripard
2017-04-07 17:30         ` Chen-Yu Tsai
2017-04-18  9:57           ` Maxime Ripard
2017-04-18 10:10             ` Chen-Yu Tsai
2017-04-20  7:36               ` Maxime Ripard
2017-03-09 10:05 ` [PATCH 10/11] ARM: dts: sun6i: Add second display pipeline device nodes Chen-Yu Tsai
2017-03-09 10:05 ` [PATCH 11/11] ARM: dts: sun6i: Enable tcon0 by default Chen-Yu Tsai
2017-03-09 10:29 ` [PATCH 00/11] drm/sun4i: Support two display pipelines Maxime Ripard

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=20170309100534.14023-10-wens@csie.org \
    --to=wens@csie.org \
    --cc=airlied@linux.ie \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-sunxi@googlegroups.com \
    --cc=maxime.ripard@free-electrons.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;
as well as URLs for NNTP newsgroup(s).