summaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorChen-Yu Tsai <wens@csie.org>2017-10-17 20:17:58 +0800
committerMaxime Ripard <maxime.ripard@free-electrons.com>2017-10-17 19:49:15 +0200
commitf55c83d37b85de411db74c6700808d08684522aa (patch)
tree56d08de2b199c48b2274f3e3094e176368c779c3 /drivers/gpu
parentba19c53704d8bc503dd20011819d1d3251899c56 (diff)
downloadlinux-f55c83d37b85de411db74c6700808d08684522aa.tar.gz
linux-f55c83d37b85de411db74c6700808d08684522aa.tar.bz2
linux-f55c83d37b85de411db74c6700808d08684522aa.zip
drm/sun4i: backend: Support output muxing
The backend has a mux to select the destination of the data to output to. It can select the TCON or the frontends. On the A20, it includes an option to output to the second TCON. This is not documented in the user manual, but the vendor kernel uses it nevertheless, so the second backend outputs to the second TCON. Although the muxing can be changed on the fly, DRM needs to be able to group a bunch of layers such that they get switched to another crtc together. This is because the display backend does the layer compositing, while the TCON generates the display timings. This constraint is not supported by DRM. Here we simply pair up backends and TCONs with the same ID. Signed-off-by: Chen-Yu Tsai <wens@csie.org> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> Link: https://patchwork.freedesktop.org/patch/msgid/20171017121807.2994-2-wens@csie.org
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_backend.c52
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_backend.h3
2 files changed, 51 insertions, 4 deletions
diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c
index d18d7e88d511..e8477321f978 100644
--- a/drivers/gpu/drm/sun4i/sun4i_backend.c
+++ b/drivers/gpu/drm/sun4i/sun4i_backend.c
@@ -20,6 +20,7 @@
#include <linux/component.h>
#include <linux/list.h>
+#include <linux/of_device.h>
#include <linux/of_graph.h>
#include <linux/reset.h>
@@ -28,6 +29,11 @@
#include "sun4i_layer.h"
#include "sunxi_engine.h"
+struct sun4i_backend_quirks {
+ /* backend <-> TCON muxing selection done in backend */
+ bool needs_output_muxing;
+};
+
static const u32 sunxi_rgb2yuv_coef[12] = {
0x00000107, 0x00000204, 0x00000064, 0x00000108,
0x00003f69, 0x00003ed6, 0x000001c1, 0x00000808,
@@ -345,6 +351,7 @@ static int sun4i_backend_bind(struct device *dev, struct device *master,
struct drm_device *drm = data;
struct sun4i_drv *drv = drm->dev_private;
struct sun4i_backend *backend;
+ const struct sun4i_backend_quirks *quirks;
struct resource *res;
void __iomem *regs;
int i, ret;
@@ -439,6 +446,27 @@ static int sun4i_backend_bind(struct device *dev, struct device *master,
SUN4I_BACKEND_MODCTL_DEBE_EN |
SUN4I_BACKEND_MODCTL_START_CTL);
+ /* Set output selection if needed */
+ quirks = of_device_get_match_data(dev);
+ if (quirks->needs_output_muxing) {
+ /*
+ * We assume there is no dynamic muxing of backends
+ * and TCONs, so we select the backend with same ID.
+ *
+ * While dynamic selection might be interesting, since
+ * the CRTC is tied to the TCON, while the layers are
+ * tied to the backends, this means, we will need to
+ * switch between groups of layers. There might not be
+ * a way to represent this constraint in DRM.
+ */
+ regmap_update_bits(backend->engine.regs,
+ SUN4I_BACKEND_MODCTL_REG,
+ SUN4I_BACKEND_MODCTL_OUT_SEL,
+ (backend->engine.id
+ ? SUN4I_BACKEND_MODCTL_OUT_LCD1
+ : SUN4I_BACKEND_MODCTL_OUT_LCD0));
+ }
+
return 0;
err_disable_ram_clk:
@@ -486,10 +514,28 @@ static int sun4i_backend_remove(struct platform_device *pdev)
return 0;
}
+static const struct sun4i_backend_quirks sun5i_backend_quirks = {
+};
+
+static const struct sun4i_backend_quirks sun6i_backend_quirks = {
+};
+
+static const struct sun4i_backend_quirks sun8i_a33_backend_quirks = {
+};
+
static const struct of_device_id sun4i_backend_of_table[] = {
- { .compatible = "allwinner,sun5i-a13-display-backend" },
- { .compatible = "allwinner,sun6i-a31-display-backend" },
- { .compatible = "allwinner,sun8i-a33-display-backend" },
+ {
+ .compatible = "allwinner,sun5i-a13-display-backend",
+ .data = &sun5i_backend_quirks,
+ },
+ {
+ .compatible = "allwinner,sun6i-a31-display-backend",
+ .data = &sun6i_backend_quirks,
+ },
+ {
+ .compatible = "allwinner,sun8i-a33-display-backend",
+ .data = &sun8i_a33_backend_quirks,
+ },
{ }
};
MODULE_DEVICE_TABLE(of, sun4i_backend_of_table);
diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.h b/drivers/gpu/drm/sun4i/sun4i_backend.h
index 21945af67a9d..ac3cc029f5cd 100644
--- a/drivers/gpu/drm/sun4i/sun4i_backend.h
+++ b/drivers/gpu/drm/sun4i/sun4i_backend.h
@@ -25,7 +25,8 @@
#define SUN4I_BACKEND_MODCTL_LINE_SEL BIT(29)
#define SUN4I_BACKEND_MODCTL_ITLMOD_EN BIT(28)
#define SUN4I_BACKEND_MODCTL_OUT_SEL GENMASK(22, 20)
-#define SUN4I_BACKEND_MODCTL_OUT_LCD (0 << 20)
+#define SUN4I_BACKEND_MODCTL_OUT_LCD0 (0 << 20)
+#define SUN4I_BACKEND_MODCTL_OUT_LCD1 (1 << 20)
#define SUN4I_BACKEND_MODCTL_OUT_FE0 (6 << 20)
#define SUN4I_BACKEND_MODCTL_OUT_FE1 (7 << 20)
#define SUN4I_BACKEND_MODCTL_HWC_EN BIT(16)