Skip to contentSkip to conversation

Add a DRM display driver to the Allwinner H3

PATCH In review Jean-Francois Moine 4 participants 9 messages Feb 2, 2016 – Feb 6, 2016

Subsystems (6)
lore
Share & tools
lore
#0 lore raw

v4 cover Add a DRM display driver to the Allwinner H3

The proposed DRM driver works on a Orange PI 2 with a kernel 4.5.0-rc1 and some H3 patches found in Hans de Goede's GIT repository.

As there is no documentation about the HDMI of the H3, the associated encoder/connector driver has not been included in this patch series.
For test purpose, it may be built as a out-of-tree driver from the tarball:

	http://moinejf.free.fr/opi2/h3-hdmi.tar.gz
and the DT files:
	http://moinejf.free.fr/opi2/sun8i-h3.dtsi
	http://moinejf.free.fr/opi2/sun8i-h3-orangepi-plus.dts

Jean-Francois Moine (2):
clk: sunxi: Add sun6i/8i video support
drm: sunxi: Add a basic DRM driver for Allwinner DE2

---
v4:
- drivers/clk/sunxi/Makefile was missing (Emil Velikov)
v3:
- add the hardware cursor
- simplify and fix the DE2 init sequences
- generation for all SUNXI SoCs (Andre Przywara)
v2:
- remarks from Chen-Yu Tsai and Russell King
- DT documentation added
---

 Documentation/devicetree/bindings/clock/sunxi.txt  |   2 +
 .../devicetree/bindings/display/sunxi.txt          |  81 ++++
 drivers/clk/sunxi/Makefile                         |   2 +
 drivers/clk/sunxi/clk-sun6i-display.c              | 106 +++++
 drivers/clk/sunxi/clk-sun6i-pll3.c                 | 174 +++++++
 drivers/gpu/drm/Kconfig                            |   2 +
 drivers/gpu/drm/Makefile                           |   1 +
 drivers/gpu/drm/sunxi/Kconfig                      |  20 +
 drivers/gpu/drm/sunxi/Makefile                     |   7 +
 drivers/gpu/drm/sunxi/de2_crtc.c                   | 421 +++++++++++++++++
 drivers/gpu/drm/sunxi/de2_crtc.h                   |  61 +++
 drivers/gpu/drm/sunxi/de2_de.c                     | 505 +++++++++++++++++++++
 drivers/gpu/drm/sunxi/de2_drm.h                    |  40 ++
 drivers/gpu/drm/sunxi/de2_drv.c                    | 377 +++++++++++++++
 drivers/gpu/drm/sunxi/de2_plane.c                  |  91 ++++
 15 files changed, 1890 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/sunxi.txt
 create mode 100644 drivers/clk/sunxi/clk-sun6i-display.c
 create mode 100644 drivers/clk/sunxi/clk-sun6i-pll3.c
 create mode 100644 drivers/gpu/drm/sunxi/Kconfig
 create mode 100644 drivers/gpu/drm/sunxi/Makefile
 create mode 100644 drivers/gpu/drm/sunxi/de2_crtc.c
 create mode 100644 drivers/gpu/drm/sunxi/de2_crtc.h
 create mode 100644 drivers/gpu/drm/sunxi/de2_de.c
 create mode 100644 drivers/gpu/drm/sunxi/de2_drm.h
 create mode 100644 drivers/gpu/drm/sunxi/de2_drv.c
 create mode 100644 drivers/gpu/drm/sunxi/de2_plane.c
Signature · 1 line
2.7.0
#1 lore raw

PATCH v4 1/2 clk: sunxi: Add sun6i/8i video support

Add the clock types which are used by the sun6i/8i families for video.

---
v4:
- drivers/clk/sunxi/Makefile was missing (Emil Velikov)
v3: (no change)
v2:
- remarks from Chen-Yu Tsai
- DT documentation added

---
 Documentation/devicetree/bindings/clock/sunxi.txt |   2 +
 drivers/clk/sunxi/Makefile                        |   2 +
 drivers/clk/sunxi/clk-sun6i-display.c             | 106 +++++++++++++
 drivers/clk/sunxi/clk-sun6i-pll3.c                | 174 ++++++++++++++++++++++
 4 files changed, 284 insertions(+)
 create mode 100644 drivers/clk/sunxi/clk-sun6i-display.c
 create mode 100644 drivers/clk/sunxi/clk-sun6i-pll3.c
Documentation/devicetree/bindings/clock/sunxi.txt +2 -0
index e59f57b..a22b92f 100644
@@ -11,6 +11,7 @@ Required properties:
 	"allwinner,sun6i-a31-pll1-clk" - for the main PLL clock on A31
 	"allwinner,sun8i-a23-pll1-clk" - for the main PLL clock on A23
 	"allwinner,sun9i-a80-pll4-clk" - for the peripheral PLLs on A80
+	"allwinner,sun6i-pll3-clk" - for the video PLLs clock
 	"allwinner,sun4i-a10-pll5-clk" - for the PLL5 clock
 	"allwinner,sun4i-a10-pll6-clk" - for the PLL6 clock
 	"allwinner,sun6i-a31-pll6-clk" - for the PLL6 clock on A31
@@ -77,6 +78,7 @@ Required properties:
 	"allwinner,sun9i-a80-usb-mod-clk" - for usb gates + resets on A80
 	"allwinner,sun9i-a80-usb-phy-clk" - for usb phy gates + resets on A80
 	"allwinner,sun4i-a10-ve-clk" - for the Video Engine clock
+	"allwinner,sun6i-display-clk" - for the display clocks
 
 Required properties for all clocks:
 - reg : shall be the control register address for the clock.
drivers/clk/sunxi/Makefile +2 -0
index 3fd7901..6fe336f 100644
@@ -11,6 +11,8 @@ obj-y += clk-a10-ve.o
 obj-y += clk-a20-gmac.o
 obj-y += clk-mod0.o
 obj-y += clk-simple-gates.o
+obj-y += clk-sun6i-display.o
+obj-y += clk-sun6i-pll3.o
 obj-y += clk-sun8i-bus-gates.o
 obj-y += clk-sun8i-mbus.o
 obj-y += clk-sun9i-core.o
drivers/clk/sunxi/clk-sun6i-display.c new file +106 -0

106 lines not on this page · raw message

drivers/clk/sunxi/clk-sun6i-pll3.c new file +174 -0

174 lines not on this page · raw message

Signature · 1 line
2.7.0
maintainer Acked-by on v4 1/2
#2 lore raw

Re: [PATCH v4 1/2] clk: sunxi: Add sun6i/8i video support

Quoted 10 lines · Jean-Francois Moine

Add the clock types which are used by the sun6i/8i families for video.

---
v4:
- drivers/clk/sunxi/Makefile was missing (Emil Velikov)
v3: (no change)
v2:
- remarks from Chen-Yu Tsai
- DT documentation added

Quoted 2 lines
---
 Documentation/devicetree/bindings/clock/sunxi.txt |   2 +
Quoted 6 lines
 drivers/clk/sunxi/Makefile                        |   2 +
 drivers/clk/sunxi/clk-sun6i-display.c             | 106 +++++++++++++
 drivers/clk/sunxi/clk-sun6i-pll3.c                | 174 ++++++++++++++++++++++
 4 files changed, 284 insertions(+)
 create mode 100644 drivers/clk/sunxi/clk-sun6i-display.c
 create mode 100644 drivers/clk/sunxi/clk-sun6i-pll3.c
#3 lore raw

Re: [PATCH v4 1/2] clk: sunxi: Add sun6i/8i video support

In reply to Jean-Francois Moine

Hi,

Quoted 24 lines · Jean-Francois Moine

Add the clock types which are used by the sun6i/8i families for video.

---
v4:
- drivers/clk/sunxi/Makefile was missing (Emil Velikov)
v3: (no change)
v2:
- remarks from Chen-Yu Tsai
- DT documentation added

---
 Documentation/devicetree/bindings/clock/sunxi.txt |   2 +
 drivers/clk/sunxi/Makefile                        |   2 +
 drivers/clk/sunxi/clk-sun6i-display.c             | 106 +++++++++++++
 drivers/clk/sunxi/clk-sun6i-pll3.c                | 174 ++++++++++++++++++++++
 4 files changed, 284 insertions(+)
 create mode 100644 drivers/clk/sunxi/clk-sun6i-display.c
 create mode 100644 drivers/clk/sunxi/clk-sun6i-pll3.c
Documentation/devicetree/bindings/clock/sunxi.txt +0 -0
index e59f57b..a22b92f 100644

Documentation/devicetree/bindings/clock/sunxi.txt Required properties: · line 14

Quoted 4 lines
Documentation/devicetree/bindings/clock/sunxi.txt +1 -0
@@ -11,6 +11,7 @@ Required properties:
 	"allwinner,sun6i-a31-pll1-clk" - for the main PLL clock on A31
 	"allwinner,sun8i-a23-pll1-clk" - for the main PLL clock on A23
 	"allwinner,sun9i-a80-pll4-clk" - for the peripheral PLLs on A80
+	"allwinner,sun6i-pll3-clk" - for the video PLLs clock

sun6i-a31

Documentation/devicetree/bindings/clock/sunxi.txt Required properties: · line 81

Quoted 8 lines
Documentation/devicetree/bindings/clock/sunxi.txt +1 -0
 	"allwinner,sun4i-a10-pll5-clk" - for the PLL5 clock
 	"allwinner,sun4i-a10-pll6-clk" - for the PLL6 clock
 	"allwinner,sun6i-a31-pll6-clk" - for the PLL6 clock on A31
@@ -77,6 +78,7 @@ Required properties:
 	"allwinner,sun9i-a80-usb-mod-clk" - for usb gates + resets on A80
 	"allwinner,sun9i-a80-usb-phy-clk" - for usb phy gates + resets on A80
 	"allwinner,sun4i-a10-ve-clk" - for the Video Engine clock
+	"allwinner,sun6i-display-clk" - for the display clocks

Ditto

Quoted 117 lines
Documentation/devicetree/bindings/clock/sunxi.txt +0 -0
 Required properties for all clocks:
 - reg : shall be the control register address for the clock.
drivers/clk/sunxi/Makefile +2 -0
index 3fd7901..6fe336f 100644
@@ -11,6 +11,8 @@ obj-y += clk-a10-ve.o
 obj-y += clk-a20-gmac.o
 obj-y += clk-mod0.o
 obj-y += clk-simple-gates.o
+obj-y += clk-sun6i-display.o
+obj-y += clk-sun6i-pll3.o
 obj-y += clk-sun8i-bus-gates.o
 obj-y += clk-sun8i-mbus.o
 obj-y += clk-sun9i-core.o
drivers/clk/sunxi/clk-sun6i-display.c new file +96 -0
new file mode 100644
index 0000000..48356e3
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2016 Jean-Francois Moine <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/rational.h>
+#include <linux/delay.h>
+
+static DEFINE_SPINLOCK(sun6i_display_lock);
+
+#define SUN6I_DISPLAY_GATE_BIT	31
+#define SUN6I_DISPLAY_SEL_SHIFT	24
+#define SUN6I_DISPLAY_SEL_MASK	GENMASK(2, 0)
+#define SUN6I_DISPLAY_MSHIFT	0
+#define SUN6I_DISPLAY_MWIDTH	4
+
+static void __init sun6i_display_setup(struct device_node *node)
+{
+	const char *clk_name = node->name;
+	const char *parents[8];
+	struct clk_mux *mux = NULL;
+	struct clk_divider *div;
+	struct clk_gate *gate;
+	struct resource res;
+	void __iomem *mmio;
+	struct clk *clk;
+	int n;
+
+	of_property_read_string(node, "clock-output-names", &clk_name);
+
+	mmio = of_io_request_and_map(node, 0, of_node_full_name(node));
+	if (IS_ERR(mmio)) {
+		pr_err("%s: Could not map the clock registers\n", clk_name);
+		return;
+	}
+
+	n = of_clk_parent_fill(node, parents, ARRAY_SIZE(parents));
+
+	if (n > 1) {				/* many possible sources */
+		mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+		if (!mux)
+			goto free_io;
+		mux->reg = mmio;
+		mux->shift = SUN6I_DISPLAY_SEL_SHIFT;
+		mux->mask = SUN6I_DISPLAY_SEL_MASK;
+		mux->lock = &sun6i_display_lock;
+	}
+
+	gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+	if (!gate)
+		goto free_mux;
+
+	gate->reg = mmio;
+	gate->bit_idx = SUN6I_DISPLAY_GATE_BIT;
+	gate->lock = &sun6i_display_lock;
+
+	div = kzalloc(sizeof(*div), GFP_KERNEL);
+	if (!div)
+		goto free_gate;
+
+	div->reg = mmio;
+	div->shift = SUN6I_DISPLAY_MSHIFT;
+	div->width = SUN6I_DISPLAY_MWIDTH;
+	div->lock = &sun6i_display_lock;
+
+	clk = clk_register_composite(NULL, clk_name,
+				     parents, n,
+				     mux ? &mux->hw : NULL, &clk_mux_ops,
+				     &div->hw, &clk_divider_ops,
+				     &gate->hw, &clk_gate_ops,
+				     0);
+	if (IS_ERR(clk)) {
+		pr_err("%s: Couldn't register the clock\n", clk_name);
+		goto free_div;
+	}
+
+	of_clk_add_provider(node, of_clk_src_simple_get, clk);
+
+	return;
+
+free_div:
+	kfree(div);
+free_gate:

drivers/clk/sunxi/clk-sun6i-display.c line 106

Quoted 10 lines
drivers/clk/sunxi/clk-sun6i-display.c new file +10 -0
+	kfree(gate);
+free_mux:
+	kfree(mux);
+free_io:
+	iounmap(mmio);
+	of_address_to_resource(node, 0, &res);
+	release_mem_region(res.start, resource_size(&res));
+}
+
+CLK_OF_DECLARE(sun6i_display, "allwinner,sun6i-display-clk", sun6i_display_setup);

Please use the display driver from my DRM serie, it covers everything you need here.

Quoted 170 lines
drivers/clk/sunxi/clk-sun6i-pll3.c new file +164 -0
new file mode 100644
index 0000000..3c128a4
@@ -0,0 +1,174 @@
+/*
+ * Allwinner video PLL clocks
+ *
+ * Copyright 2016 Jean-Francois Moine <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/rational.h>
+#include <linux/iopoll.h>
+
+static DEFINE_SPINLOCK(sun6i_pll3_lock);
+
+struct clk_fact {
+	struct clk_hw hw;
+	void __iomem *reg;
+};
+#define to_clk_fact(_hw) container_of(_hw, struct clk_fact, hw)
+
+#define SUN6I_PLL3_MSHIFT	0
+#define SUN6I_PLL3_MMASK	GENMASK(3, 0)
+#define SUN6I_PLL3_NSHIFT	8
+#define SUN6I_PLL3_NMASK	GENMASK(7, 0)
+#define SUN6I_PLL3_MODE_SEL	BIT(24)
+#define SUN6I_PLL3_FRAC_CLK	BIT(25)
+#define SUN6I_PLL3_LOCK_BIT	28
+#define SUN6I_PLL3_GATE_BIT	31
+
+static u32 sun6i_pll3_get_fact(unsigned long rate,
+			unsigned long parent_rate,
+			unsigned long *n, unsigned long *m)
+{
+	if (rate == 297000000)
+		return SUN6I_PLL3_FRAC_CLK;
+	if (rate == 270000000)
+		return 0;
+	rational_best_approximation(rate, parent_rate,
+				SUN6I_PLL3_NMASK + 1, SUN6I_PLL3_MMASK + 1,
+				n, m);
+	return SUN6I_PLL3_MODE_SEL;
+}
+
+static unsigned long sun6i_pll3_recalc_rate(struct clk_hw *hw,
+					unsigned long parent_rate)
+{
+	struct clk_fact *fact = to_clk_fact(hw);
+	u32 reg;
+	u32 n, m;
+
+	reg = readl(fact->reg);
+	if (reg & SUN6I_PLL3_MODE_SEL) {
+		n = (reg >> SUN6I_PLL3_NSHIFT) & SUN6I_PLL3_NMASK;
+		m = (reg >> SUN6I_PLL3_MSHIFT) & SUN6I_PLL3_MMASK;
+		return parent_rate / (m + 1) * (n + 1);
+	}
+	if (reg & SUN6I_PLL3_FRAC_CLK)
+		return 297000000;
+	return 270000000;
+}
+
+static long sun6i_pll3_round_rate(struct clk_hw *hw, unsigned long rate,
+				unsigned long *parent_rate)
+{
+	u32 frac;
+	unsigned long n, m;
+
+	frac = sun6i_pll3_get_fact(rate, *parent_rate, &n, &m);
+	if (frac & SUN6I_PLL3_MODE_SEL)
+		return *parent_rate / m * n;
+	if (frac & SUN6I_PLL3_FRAC_CLK)
+		return 297000000;
+	return 270000000;
+}
+
+static int sun6i_pll3_set_rate(struct clk_hw *hw, unsigned long rate,
+			unsigned long parent_rate)
+{
+	struct clk_fact *fact = to_clk_fact(hw);
+	u32 reg;
+	unsigned long n, m;
+
+	reg = readl(fact->reg) &
+			~(SUN6I_PLL3_MODE_SEL |
+			  SUN6I_PLL3_FRAC_CLK |
+			  (SUN6I_PLL3_NMASK << SUN6I_PLL3_NSHIFT) |
+			  (SUN6I_PLL3_MMASK << SUN6I_PLL3_MSHIFT));
+
+	reg |= sun6i_pll3_get_fact(rate, parent_rate, &n, &m);
+	if (reg & SUN6I_PLL3_MODE_SEL)
+		reg |= ((n - 1) << SUN6I_PLL3_NSHIFT) |
+			((m - 1) << SUN6I_PLL3_MSHIFT);
+
+	writel(reg, fact->reg);
+
+	readl_poll_timeout(fact->reg, reg, reg & SUN6I_PLL3_LOCK_BIT, 10, 500);
+
+	return 0;
+}
+
+static const struct clk_ops clk_sun6i_pll3_fact_ops = {
+	.recalc_rate = sun6i_pll3_recalc_rate,
+	.round_rate = sun6i_pll3_round_rate,
+	.set_rate = sun6i_pll3_set_rate,
+};
+
+static void __init sun6i_pll3_setup(struct device_node *node)
+{
+	const char *clk_name, *parent;
+	void __iomem *mmio;
+	struct clk_fact *fact;
+	struct clk_gate *gate;
+	struct resource res;
+	struct clk *clk;
+
+	mmio = of_io_request_and_map(node, 0, of_node_full_name(node));
+	if (IS_ERR(mmio)) {
+		pr_err("%s: Could not map the clock registers\n", clk_name);
+		return;
+	}
+
+	gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+	if (!gate)
+		goto free_mmio;
+	gate->reg = mmio;
+	gate->bit_idx = SUN6I_PLL3_GATE_BIT;
+	gate->lock = &sun6i_pll3_lock;
+
+	fact = kzalloc(sizeof(*fact), GFP_KERNEL);
+	if (!fact)
+		goto free_gate;
+	fact->reg = mmio;
+
+	parent = of_clk_get_parent_name(node, 0);
+
+	of_property_read_string(node, "clock-output-names", &clk_name);
+
+	clk = clk_register_composite(NULL, clk_name,
+				     &parent, 1,
+				     NULL, NULL,
+				     &fact->hw, &clk_sun6i_pll3_fact_ops,
+				     &gate->hw, &clk_gate_ops,
+				     0);
+	if (IS_ERR(clk)) {
+		pr_err("%s: Couldn't register the clock\n", clk_name);
+		goto free_fact;
+	}
+
+	of_clk_add_provider(node, of_clk_src_simple_get, clk);
+
+	return;
+
+free_fact:

drivers/clk/sunxi/clk-sun6i-pll3.c line 174

Quoted 10 lines
drivers/clk/sunxi/clk-sun6i-pll3.c new file +10 -0
+	kfree(fact);
+free_gate:
+	kfree(gate);
+free_mmio:
+	iounmap(mmio);
+	of_address_to_resource(node, 0, &res);
+	release_mem_region(res.start, resource_size(&res));
+}
+
+CLK_OF_DECLARE(sun6i_pll3, "allwinner,sun6i-pll3-clk", sun6i_pll3_setup);

And please use the clk-factors code here.

Maxime

Signature · 10 lines
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160205/067edc6a/attachment.sig>
#4 lore raw

Re: [PATCH v4 1/2] clk: sunxi: Add sun6i/8i video support

Quoted 4 lines · On Fri, 5 Feb 2016 10:39:15 +0100 Maxime Ripard…
Quoted 1 line

+CLK_OF_DECLARE(sun6i_display, "allwinner,sun6i-display-clk", sun6i_display_setup);

Please use the display driver from my DRM serie, it covers everything you need here.

If you give me a pointer, I will have a look.

Quoted 3 lines
Quoted 1 line

+CLK_OF_DECLARE(sun6i_pll3, "allwinner,sun6i-pll3-clk", sun6i_pll3_setup);

And please use the clk-factors code here.

I don't see how I can get direct 297MHz and 270MHz in fractional mode with that code.

Signature · 2 lines
Ken ar c'henta?	|	      ** Breizh ha Linux atav! **
Jef		|		http://moinejf.free.fr/
#5 lore raw

Re: [PATCH v4 1/2] clk: sunxi: Add sun6i/8i video support

Quoted 8 lines · Jean-Francois Moine
Quoted 4 lines · On Fri, 5 Feb 2016 10:39:15 +0100 Maxime Ripard…
Quoted 1 line

+CLK_OF_DECLARE(sun6i_display, "allwinner,sun6i-display-clk", sun6i_display_setup);

Please use the display driver from my DRM serie, it covers everything you need here.

Quoted 8 lines

If you give me a pointer, I will have a look.

Quoted 3 lines
Quoted 1 line

+CLK_OF_DECLARE(sun6i_pll3, "allwinner,sun6i-pll3-clk", sun6i_pll3_setup);

And please use the clk-factors code here.

I don't see how I can get direct 297MHz and 270MHz in fractional mode with that code.

clk-factors now supports a custom .recalc callback. Along with get_factors, you can support pretty much any clock that has four variables, not including the mux and clock gate.

So for this you'd have the div as factor m, and the integer mode bit as p, and the fraction bit as n, and recalc would be somewhat like this:

if (p) {
        rate = parent_rate / (m + 1);
} else if (n) {
        rate = 297000000;
} else {
        rate = 270000000;
}

get_factors should be easy enough to figure out.

Regards
ChenYu

#6 lore raw

PATCH v4 2/2 drm: sunxi: Add a basic DRM driver for Allwinner DE2

In reply to Jean-Francois Moine

In recent SoCs, as the H3, Allwinner uses a new display interface, DE2. This patch adds a DRM video driver for this interface.

---
v4: (no change)
v3:
- add the hardware cursor
- simplify and fix the DE2 init sequences
- generation for all SUNXI SoCs (Andre Przywara)
v2:
- remarks from Russell King
- DT documentation added
- working resolution change with xrandr
- removal of the HDMI driver

---
 .../devicetree/bindings/display/sunxi.txt          |  81 ++++
 drivers/gpu/drm/Kconfig                            |   2 +
 drivers/gpu/drm/Makefile                           |   1 +
 drivers/gpu/drm/sunxi/Kconfig                      |  20 +
 drivers/gpu/drm/sunxi/Makefile                     |   7 +
 drivers/gpu/drm/sunxi/de2_crtc.c                   | 421 +++++++++++++++++
 drivers/gpu/drm/sunxi/de2_crtc.h                   |  61 +++
 drivers/gpu/drm/sunxi/de2_de.c                     | 505 +++++++++++++++++++++
 drivers/gpu/drm/sunxi/de2_drm.h                    |  40 ++
 drivers/gpu/drm/sunxi/de2_drv.c                    | 377 +++++++++++++++
 drivers/gpu/drm/sunxi/de2_plane.c                  |  91 ++++
 11 files changed, 1606 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/sunxi.txt
 create mode 100644 drivers/gpu/drm/sunxi/Kconfig
 create mode 100644 drivers/gpu/drm/sunxi/Makefile
 create mode 100644 drivers/gpu/drm/sunxi/de2_crtc.c
 create mode 100644 drivers/gpu/drm/sunxi/de2_crtc.h
 create mode 100644 drivers/gpu/drm/sunxi/de2_de.c
 create mode 100644 drivers/gpu/drm/sunxi/de2_drm.h
 create mode 100644 drivers/gpu/drm/sunxi/de2_drv.c
 create mode 100644 drivers/gpu/drm/sunxi/de2_plane.c
Documentation/devicetree/bindings/display/sunxi.txt new file +81 -0
new file mode 100644
index 0000000..35f9763
@@ -0,0 +1,81 @@
+Allwinner sunxi display subsystem
+=================================
+
+The sunxi display subsystems contain a display controller (DE),
+one or two LCD controllers (TCON) and their external interfaces.
+
+Display controller
+==================
+
+Required properties:
+
+- compatible: value should be one of the following
+		"allwinner,sun8i-h3-display-engine"
+
+- clocks: must include clock specifiers corresponding to entries in the
+		clock-names property.
+
+- clock-names: must contain
+		gate: for DE activation
+		clock: DE clock
+
+- resets: phandle to the reset of the device
+
+- ports: phandle's to the LCD ports
+
+LCD controller
+==============
+
+Required properties:
+
+- compatible: value should be one of the following
+		"allwinner,sun8i-h3-lcd"
+
+- clocks: must include clock specifiers corresponding to entries in the
+		clock-names property.
+
+- clock-names: must contain
+		gate: for LCD activation
+		clock: pixel clock
+
+- resets: phandle to the reset of the device
+
+- port: port node with endpoint definitions as defined in
+	Documentation/devicetree/bindings/media/video-interfaces.txt
+
+Example:
+
+	de: de-controller@01000000 {
+		compatible = "allwinner,sun8i-h3-display-engine";
+		...
+		clocks = <&bus_gates 44>, <&de_clk>;
+		clock-names = "gate", "clock";
+		resets = <&ahb_rst 44>;
+		ports = <&lcd0_p>;
+	};
+
+	lcd0: lcd-controller@01c0c000 {
+		compatible = "allwinner,sun8i-h3-lcd";
+		...
+		clocks = <&bus_gates 35>, <&tcon0_clk>;
+		clock-names = "gate", "clock";
+		resets = <&ahb_rst 35>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		lcd0_p: port {
+			lcd0_ep: endpoint {
+				remote-endpoint = <&hdmi_ep>;
+			};
+		};
+	};
+
+	hdmi: hdmi@01ee0000 {
+		...
+		#address-cells = <1>;
+		#size-cells = <0>;
+		port {
+			hdmi_ep: endpoint {
+				remote-endpoint = <&lcd0_ep>;
+			};
+		};
+	};
drivers/gpu/drm/Kconfig +2 -0
index 8ae7ab6..0cec9a1 100644
@@ -269,3 +269,5 @@ source "drivers/gpu/drm/imx/Kconfig"
 source "drivers/gpu/drm/vc4/Kconfig"
 
 source "drivers/gpu/drm/etnaviv/Kconfig"
+
+source "drivers/gpu/drm/sunxi/Kconfig"
drivers/gpu/drm/Makefile +1 -0
index 61766de..eef53f2 100644
@@ -74,3 +74,4 @@ obj-y			+= panel/
 obj-y			+= bridge/
 obj-$(CONFIG_DRM_FSL_DCU) += fsl-dcu/
 obj-$(CONFIG_DRM_ETNAVIV) += etnaviv/
+obj-$(CONFIG_DRM_SUNXI) += sunxi/
drivers/gpu/drm/sunxi/Kconfig new file +20 -0
new file mode 100644
index 0000000..e452930
@@ -0,0 +1,20 @@
+#
+# Allwinner Video configuration
+#
+
+config DRM_SUNXI
+	tristate "DRM Support for Allwinner Video"
+	depends on DRM && ARCH_SUNXI
+	depends on OF
+	select DRM_KMS_HELPER
+	select DRM_KMS_CMA_HELPER
+	select DRM_GEM_CMA_HELPER
+	help
+	  Choose this option if you have a Allwinner chipset.
+
+config DRM_SUNXI_DE2
+	tristate "Support for Allwinner Video with DE2 interface"
+	depends on DRM_SUNXI
+	help
+	  Choose this option if your Allwinner chipset has the DE2 interface
+	  as the H3.
drivers/gpu/drm/sunxi/Makefile new file +7 -0
new file mode 100644
index 0000000..3778877
@@ -0,0 +1,7 @@
+#
+# Makefile for Allwinner's DRM device driver
+#
+
+sunxi-de2-drm-objs := de2_drv.o de2_de.o de2_crtc.o de2_plane.o
+
+obj-$(CONFIG_DRM_SUNXI_DE2) += sunxi-de2-drm.o
drivers/gpu/drm/sunxi/de2_crtc.c new file +421 -0

421 lines not on this page · raw message

drivers/gpu/drm/sunxi/de2_crtc.h new file +61 -0

61 lines not on this page · raw message

drivers/gpu/drm/sunxi/de2_de.c new file +505 -0

505 lines not on this page · raw message

drivers/gpu/drm/sunxi/de2_drm.h new file +40 -0
new file mode 100644
index 0000000..1e6cf6d
@@ -0,0 +1,40 @@
+#ifndef __DE2_DRM_H__
+#define __DE2_DRM_H__
+/*
+ * Copyright (C) 2016 Jean-François Moine
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+#include <linux/clk.h>
+#include <linux/reset.h>
+#include <drm/drmP.h>
+#include <drm/drm_fb_cma_helper.h>
+
+struct lcd;
+
+#define N_LCDS 2
+struct priv {
+	void __iomem *mmio;
+	struct clk *clk;
+	struct clk *gate;
+	struct reset_control *rstc;
+
+	struct drm_fbdev_cma *fbdev;
+
+	struct lcd *lcds[N_LCDS];
+};
+
+/* in de2_crtc.c */
+int de2_enable_vblank(struct drm_device *drm, unsigned crtc);
+void de2_disable_vblank(struct drm_device *drm, unsigned crtc);
+extern struct platform_driver de2_lcd_platform_driver;
+
+/* in de2_de.c */
+int de2_de_init(struct priv *priv, struct device *dev);
+void de2_de_cleanup(struct priv *priv);
+
+#endif /* __DE2_DRM_H__ */
drivers/gpu/drm/sunxi/de2_drv.c new file +377 -0

377 lines not on this page · raw message

drivers/gpu/drm/sunxi/de2_plane.c new file +91 -0

91 lines not on this page · raw message

Signature · 1 line
2.7.0
maintainer
#7 lore raw

Re: [PATCH v4 2/2] drm: sunxi: Add a basic DRM driver for Allwinner DE2

Quoted 78 lines · Jean-Francois Moine

In recent SoCs, as the H3, Allwinner uses a new display interface, DE2. This patch adds a DRM video driver for this interface.

---
v4: (no change)
v3:
- add the hardware cursor
- simplify and fix the DE2 init sequences
- generation for all SUNXI SoCs (Andre Przywara)
v2:
- remarks from Russell King
- DT documentation added
- working resolution change with xrandr
- removal of the HDMI driver

---
 .../devicetree/bindings/display/sunxi.txt          |  81 ++++
 drivers/gpu/drm/Kconfig                            |   2 +
 drivers/gpu/drm/Makefile                           |   1 +
 drivers/gpu/drm/sunxi/Kconfig                      |  20 +
 drivers/gpu/drm/sunxi/Makefile                     |   7 +
 drivers/gpu/drm/sunxi/de2_crtc.c                   | 421 +++++++++++++++++
 drivers/gpu/drm/sunxi/de2_crtc.h                   |  61 +++
 drivers/gpu/drm/sunxi/de2_de.c                     | 505 +++++++++++++++++++++
 drivers/gpu/drm/sunxi/de2_drm.h                    |  40 ++
 drivers/gpu/drm/sunxi/de2_drv.c                    | 377 +++++++++++++++
 drivers/gpu/drm/sunxi/de2_plane.c                  |  91 ++++
 11 files changed, 1606 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/sunxi.txt
 create mode 100644 drivers/gpu/drm/sunxi/Kconfig
 create mode 100644 drivers/gpu/drm/sunxi/Makefile
 create mode 100644 drivers/gpu/drm/sunxi/de2_crtc.c
 create mode 100644 drivers/gpu/drm/sunxi/de2_crtc.h
 create mode 100644 drivers/gpu/drm/sunxi/de2_de.c
 create mode 100644 drivers/gpu/drm/sunxi/de2_drm.h
 create mode 100644 drivers/gpu/drm/sunxi/de2_drv.c
 create mode 100644 drivers/gpu/drm/sunxi/de2_plane.c
Documentation/devicetree/bindings/display/sunxi.txt new file +34 -0
new file mode 100644
index 0000000..35f9763
@@ -0,0 +1,81 @@
+Allwinner sunxi display subsystem
+=================================
+
+The sunxi display subsystems contain a display controller (DE),
+one or two LCD controllers (TCON) and their external interfaces.
+
+Display controller
+==================
+
+Required properties:
+
+- compatible: value should be one of the following
+		"allwinner,sun8i-h3-display-engine"
+
+- clocks: must include clock specifiers corresponding to entries in the
+		clock-names property.
+
+- clock-names: must contain
+		gate: for DE activation
+		clock: DE clock
+
+- resets: phandle to the reset of the device
+
+- ports: phandle's to the LCD ports
+
+LCD controller
+==============
+
+Required properties:
+
+- compatible: value should be one of the following
+		"allwinner,sun8i-h3-lcd"
+
+- clocks: must include clock specifiers corresponding to entries in the

Documentation/devicetree/bindings/display/sunxi.txt line 44

Quoted 10 lines
Documentation/devicetree/bindings/display/sunxi.txt new file +10 -0
+		clock-names property.
+
+- clock-names: must contain
+		gate: for LCD activation
+		clock: pixel clock
+
+- resets: phandle to the reset of the device
+
+- port: port node with endpoint definitions as defined in
+	Documentation/devicetree/bindings/media/video-interfaces.txt

Define how many ports and endpoints.

Documentation/devicetree/bindings/display/sunxi.txt line 54

Quoted 10 lines
Documentation/devicetree/bindings/display/sunxi.txt new file +10 -0
+
+Example:
+
+	de: de-controller@01000000 {
+		compatible = "allwinner,sun8i-h3-display-engine";
+		...
+		clocks = <&bus_gates 44>, <&de_clk>;
+		clock-names = "gate", "clock";
+		resets = <&ahb_rst 44>;
+		ports = <&lcd0_p>;

This is pointless if you only have one item in ports. Is this really a separate h/w block? Can't you move all this into the node below?

Quoted 27 lines
Documentation/devicetree/bindings/display/sunxi.txt new file +27 -0
+	};
+
+	lcd0: lcd-controller@01c0c000 {
+		compatible = "allwinner,sun8i-h3-lcd";
+		...
+		clocks = <&bus_gates 35>, <&tcon0_clk>;
+		clock-names = "gate", "clock";
+		resets = <&ahb_rst 35>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		lcd0_p: port {
+			lcd0_ep: endpoint {
+				remote-endpoint = <&hdmi_ep>;
+			};
+		};
+	};
+
+	hdmi: hdmi@01ee0000 {
+		...
+		#address-cells = <1>;
+		#size-cells = <0>;
+		port {
+			hdmi_ep: endpoint {
+				remote-endpoint = <&lcd0_ep>;
+			};
+		};
+	};
#8 lore raw

Re: [PATCH v4 2/2] drm: sunxi: Add a basic DRM driver for Allwinner DE2

Quoted 44 lines · On Tue, 2 Feb 2016 15:50:36 -0600 Rob Herring <[email protected]> wrote:
Quoted 44 lines
Documentation/devicetree/bindings/display/sunxi.txt new file +38 -0
new file mode 100644
index 0000000..35f9763
@@ -0,0 +1,81 @@
+Allwinner sunxi display subsystem
+=================================
+
+The sunxi display subsystems contain a display controller (DE),
+one or two LCD controllers (TCON) and their external interfaces.
+
+Display controller
+==================
+
+Required properties:
+
+- compatible: value should be one of the following
+		"allwinner,sun8i-h3-display-engine"
+
+- clocks: must include clock specifiers corresponding to entries in the
+		clock-names property.
+
+- clock-names: must contain
+		gate: for DE activation
+		clock: DE clock
+
+- resets: phandle to the reset of the device
+
+- ports: phandle's to the LCD ports
+
+LCD controller
+==============
+
+Required properties:
+
+- compatible: value should be one of the following
+		"allwinner,sun8i-h3-lcd"
+
+- clocks: must include clock specifiers corresponding to entries in the
+		clock-names property.
+
+- clock-names: must contain
+		gate: for LCD activation
Quoted 8 lines

Documentation/devicetree/bindings/display/sunxi.txt line 44

Quoted 6 lines
Documentation/devicetree/bindings/display/sunxi.txt new file +6 -0
+		clock: pixel clock
+
+- resets: phandle to the reset of the device
+
+- port: port node with endpoint definitions as defined in
+	Documentation/devicetree/bindings/media/video-interfaces.txt

Define how many ports and endpoints.

As told in some other mail, such a video binding should be generic. The number of ports depends on the hardware. Most SoCs have only one port per LCD, but some other have many ports as the A83T (3 ports from the LCD0).

Quoted 5 lines
Quoted 5 lines
Documentation/devicetree/bindings/display/sunxi.txt new file +5 -0
+
+Example:
+
+	de: de-controller@01000000 {
+		compatible = "allwinner,sun8i-h3-display-engine";
Quoted 8 lines

Documentation/devicetree/bindings/display/sunxi.txt line 54

Quoted 5 lines
Documentation/devicetree/bindings/display/sunxi.txt new file +5 -0
+		...
+		clocks = <&bus_gates 44>, <&de_clk>;
+		clock-names = "gate", "clock";
+		resets = <&ahb_rst 44>;
+		ports = <&lcd0_p>;

This is pointless if you only have one item in ports. Is this really a separate h/w block? Can't you move all this into the node below?

Well, this example is extracted from the H3 where the DE and LCDs have different clocks, I/O resources and functions (the DE builds the video frames while the LCDs - TCONs - convert them to video flows).

The example is not complete because there are 2 LCDs in the H3:

		ports = <&lcd0_p>,		/* HDMI */
			<&lcd1_p>;		/* TV (CVBS) */

But, for SoCs with only one LCD, the description would be the same.

Quoted 16 lines
Quoted 16 lines
Documentation/devicetree/bindings/display/sunxi.txt new file +16 -0
+	};
+
+	lcd0: lcd-controller@01c0c000 {
+		compatible = "allwinner,sun8i-h3-lcd";
+		...
+		clocks = <&bus_gates 35>, <&tcon0_clk>;
+		clock-names = "gate", "clock";
+		resets = <&ahb_rst 35>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		lcd0_p: port {
+			lcd0_ep: endpoint {
+				remote-endpoint = <&hdmi_ep>;
+			};
+		};
+	};
Signature · 2 lines
Ken ar c'hentañ	|	      ** Breizh ha Linux atav! **
Jef		|		http://moinejf.free.fr/