devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 00/15] drm/sun4i: Add A83t LVDS support
@ 2017-12-05 15:10 Maxime Ripard
  2017-12-05 15:10 ` [PATCH v3 01/15] dt-bindings: panel: lvds: Document power-supply property Maxime Ripard
                   ` (12 more replies)
  0 siblings, 13 replies; 33+ messages in thread
From: Maxime Ripard @ 2017-12-05 15:10 UTC (permalink / raw)
  To: Daniel Vetter, David Airlie, Chen-Yu Tsai, Maxime Ripard
  Cc: Mark Rutland, Thomas Petazzoni, jernej.skrabec, plaes,
	devicetree, linux-kernel, dri-devel, Rob Herring,
	linux-arm-kernel, icenowy

Hi,

Here is an attempt at supporting the LVDS output in our DRM driver. This
has been tested on the A83T (with DE2), but since everything is basically
in the TCON, it should also be usable on the older SoCs with minor
modifications.

This was the occasion to refactor a bunch of things. The most notable ones
would be the documentation, and split of the UI layers in the mixer code,
and the switch to kfifo for our endpoint parsing code in the driver that
fixes an issue introduced by the switch to BFS.

Let me know what you think,
Maxime

Changes from v2:
  - Move the module clock rate to the mixer structure
  - Adjusted the simple-panel documentation for power-supply
  - Changed the compatible for the first A83t mixer to mixer 0
  - Rebased on top of current drm-misc
  - Split out the A83t bindings in its separate patch

Changes from v1:
  - Added a fix for the error path handling in the TCON
  - Enable the TCON by default
  - Removed the patch that changes the channels offset but kept most of the
    modifications as a cleanup
  - Deal with the LVDS clock being able to have another PLL parent on some
    SoCs
  - Renamed the TCON compatible to TCON-TV, following the convention used
    on newer SoCs
  - Removed the hardcoded timings
  - Moved LVDS enable quirks to a separate function
  - Used clock indices define in the DT
  - Removed the hardcoded clock rate in the DT and moved it to the driver
  - Changed sun8i_mixer_planes to sun8i_mixer_ui_planes to be consistent
  - Added the various tags collected
  - Rebased on top of 4.15

Maxime Ripard (15):
  dt-bindings: panel: lvds: Document power-supply property
  drm/panel: lvds: Add support for the power-supply property
  dt-bindings: display: sun4i-drm: Add LVDS properties
  dt-bindings: display: sun4i-drm: Add A83T pipeline
  drm/sun4i: Fix error path handling
  drm/sun4i: Force the mixer rate at 150MHz
  drm/sun4i: Create minimal multipliers and dividers
  drm/sun4i: Add LVDS support
  drm/sun4i: Add A83T support
  ARM: dts: sun8i: a83t: Add display pipeline
  ARM: dts: sun8i: a83t: Enable the PWM
  ARM: dts: sun8i: a83t: Add LVDS pins group
  ARM: dts: sun8i: a83t: Add the PWM pin group
  ARM: dts: sun8i: a711: Reinstate the PMIC compatible
  ARM: dts: sun8i: a711: Enable the LCD

 Documentation/devicetree/bindings/display/panel/panel-common.txt |   6 ++-
 Documentation/devicetree/bindings/display/panel/panel-lvds.txt   |   1 +-
 Documentation/devicetree/bindings/display/panel/simple-panel.txt |   2 +-
 Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt    |  11 +++-
 arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts                        |  62 ++++++++++++++++++-
 arch/arm/boot/dts/sun8i-a83t.dtsi                                |  99 +++++++++++++++++++++++++++++-
 drivers/gpu/drm/panel/panel-lvds.c                               |  23 +++++++-
 drivers/gpu/drm/sun4i/Makefile                                   |   1 +-
 drivers/gpu/drm/sun4i/sun4i_dotclock.c                           |  10 ++-
 drivers/gpu/drm/sun4i/sun4i_drv.c                                |   1 +-
 drivers/gpu/drm/sun4i/sun4i_lvds.c                               | 183 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 drivers/gpu/drm/sun4i/sun4i_lvds.h                               |  18 +++++-
 drivers/gpu/drm/sun4i/sun4i_tcon.c                               | 247 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 drivers/gpu/drm/sun4i/sun4i_tcon.h                               |  31 +++++++++-
 drivers/gpu/drm/sun4i/sun8i_mixer.c                              |  18 +++++-
 drivers/gpu/drm/sun4i/sun8i_mixer.h                              |   3 +-
 16 files changed, 709 insertions(+), 7 deletions(-)
 create mode 100644 drivers/gpu/drm/sun4i/sun4i_lvds.c
 create mode 100644 drivers/gpu/drm/sun4i/sun4i_lvds.h

base-commit: 3b71239181e5429702387666f1ac70a9e6856cce
-- 
git-series 0.9.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 33+ messages in thread

* [PATCH v3 01/15] dt-bindings: panel: lvds: Document power-supply property
  2017-12-05 15:10 [PATCH v3 00/15] drm/sun4i: Add A83t LVDS support Maxime Ripard
@ 2017-12-05 15:10 ` Maxime Ripard
       [not found]   ` <97ebf0615821d79e8d7718594fe3a542a743a05f.1512486553.git-series.maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
  2017-12-05 15:10 ` [PATCH v3 03/15] dt-bindings: display: sun4i-drm: Add LVDS properties Maxime Ripard
                   ` (11 subsequent siblings)
  12 siblings, 1 reply; 33+ messages in thread
From: Maxime Ripard @ 2017-12-05 15:10 UTC (permalink / raw)
  To: Daniel Vetter, David Airlie, Chen-Yu Tsai, Maxime Ripard
  Cc: Mark Rutland, Thomas Petazzoni, jernej.skrabec, plaes,
	devicetree, linux-kernel, dri-devel, Rob Herring,
	linux-arm-kernel, icenowy

The power-supply property is used by a vast majority of panels, including
panel-simple. Let's document it as a common property

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 Documentation/devicetree/bindings/display/panel/panel-common.txt | 6 ++++++
 Documentation/devicetree/bindings/display/panel/panel-lvds.txt   | 1 +
 Documentation/devicetree/bindings/display/panel/simple-panel.txt | 2 +-
 3 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/display/panel/panel-common.txt b/Documentation/devicetree/bindings/display/panel/panel-common.txt
index ec52c472c845..125ea68052af 100644
--- a/Documentation/devicetree/bindings/display/panel/panel-common.txt
+++ b/Documentation/devicetree/bindings/display/panel/panel-common.txt
@@ -78,6 +78,12 @@ used for panels that implement compatible control signals.
   while active. Active high reset signals can be supported by inverting the
   GPIO specifier polarity flag.
 
+Power
+-----
+
+- power-supply: many display panels need an additional power supply in
+  order to be fully powered-up. For such panels, power-supply contains
+  a phandle to the regulator powering the panel.
 
 Backlight
 ---------
diff --git a/Documentation/devicetree/bindings/display/panel/panel-lvds.txt b/Documentation/devicetree/bindings/display/panel/panel-lvds.txt
index b938269f841e..250850a2150b 100644
--- a/Documentation/devicetree/bindings/display/panel/panel-lvds.txt
+++ b/Documentation/devicetree/bindings/display/panel/panel-lvds.txt
@@ -32,6 +32,7 @@ Optional properties:
 - label: See panel-common.txt.
 - gpios: See panel-common.txt.
 - backlight: See panel-common.txt.
+- power-supply: See panel-common.txt.
 - data-mirror: If set, reverse the bit order described in the data mappings
   below on all data lanes, transmitting bits for slots 6 to 0 instead of
   0 to 6.
diff --git a/Documentation/devicetree/bindings/display/panel/simple-panel.txt b/Documentation/devicetree/bindings/display/panel/simple-panel.txt
index 1341bbf4aa3d..16d8ff088b7d 100644
--- a/Documentation/devicetree/bindings/display/panel/simple-panel.txt
+++ b/Documentation/devicetree/bindings/display/panel/simple-panel.txt
@@ -1,7 +1,7 @@
 Simple display panel
 
 Required properties:
-- power-supply: regulator to provide the supply voltage
+- power-supply: See panel-common.txt
 
 Optional properties:
 - ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
-- 
git-series 0.9.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v3 02/15] drm/panel: lvds: Add support for the power-supply property
       [not found] ` <cover.825a49a4c1c565a548f3de0375e7537e7e8fd3a4.1512486553.git-series.maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
@ 2017-12-05 15:10   ` Maxime Ripard
  2017-12-05 15:10   ` [PATCH v3 08/15] drm/sun4i: Add LVDS support Maxime Ripard
  2017-12-05 15:10   ` [PATCH v3 14/15] ARM: dts: sun8i: a711: Reinstate the PMIC compatible Maxime Ripard
  2 siblings, 0 replies; 33+ messages in thread
From: Maxime Ripard @ 2017-12-05 15:10 UTC (permalink / raw)
  To: Daniel Vetter, David Airlie, Chen-Yu Tsai, Maxime Ripard
  Cc: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Mark Rutland, Rob Herring,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	plaes-q/aMd4JkU83YtjvyW6yDsg, icenowy-h8G6r0blFSE,
	Thomas Petazzoni, jernej.skrabec-gGgVlfcn5nU,
	devicetree-u79uwXL29TY76Z2rM5mHXA

A significant number of panels need to power up a regulator in order to
operate properly. Add support for the power-supply property to enable and
disable such a regulator whenever needed.

Reviewed-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
Signed-off-by: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
---
 drivers/gpu/drm/panel/panel-lvds.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/drivers/gpu/drm/panel/panel-lvds.c b/drivers/gpu/drm/panel/panel-lvds.c
index e2d57c01200b..57e38a9e7ab4 100644
--- a/drivers/gpu/drm/panel/panel-lvds.c
+++ b/drivers/gpu/drm/panel/panel-lvds.c
@@ -17,6 +17,7 @@
 #include <linux/module.h>
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 
 #include <drm/drmP.h>
@@ -39,6 +40,7 @@ struct panel_lvds {
 	bool data_mirror;
 
 	struct backlight_device *backlight;
+	struct regulator *supply;
 
 	struct gpio_desc *enable_gpio;
 	struct gpio_desc *reset_gpio;
@@ -69,6 +71,9 @@ static int panel_lvds_unprepare(struct drm_panel *panel)
 	if (lvds->enable_gpio)
 		gpiod_set_value_cansleep(lvds->enable_gpio, 0);
 
+	if (lvds->supply)
+		regulator_disable(lvds->supply);
+
 	return 0;
 }
 
@@ -76,6 +81,17 @@ static int panel_lvds_prepare(struct drm_panel *panel)
 {
 	struct panel_lvds *lvds = to_panel_lvds(panel);
 
+	if (lvds->supply) {
+		int err;
+
+		err = regulator_enable(lvds->supply);
+		if (err < 0) {
+			dev_err(lvds->dev, "failed to enable supply: %d\n",
+				err);
+			return err;
+		}
+	}
+
 	if (lvds->enable_gpio)
 		gpiod_set_value_cansleep(lvds->enable_gpio, 1);
 
@@ -196,6 +212,13 @@ static int panel_lvds_probe(struct platform_device *pdev)
 	if (ret < 0)
 		return ret;
 
+	lvds->supply = devm_regulator_get_optional(lvds->dev, "power");
+	if (IS_ERR(lvds->supply)) {
+		ret = PTR_ERR(lvds->supply);
+		dev_err(lvds->dev, "failed to request regulator: %d\n", ret);
+		return ret;
+	}
+
 	/* Get GPIOs and backlight controller. */
 	lvds->enable_gpio = devm_gpiod_get_optional(lvds->dev, "enable",
 						     GPIOD_OUT_LOW);
-- 
git-series 0.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v3 03/15] dt-bindings: display: sun4i-drm: Add LVDS properties
  2017-12-05 15:10 [PATCH v3 00/15] drm/sun4i: Add A83t LVDS support Maxime Ripard
  2017-12-05 15:10 ` [PATCH v3 01/15] dt-bindings: panel: lvds: Document power-supply property Maxime Ripard
@ 2017-12-05 15:10 ` Maxime Ripard
       [not found]   ` <17851ba6277b69aa9cd81de5eead62bfed271661.1512486553.git-series.maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
  2017-12-05 15:10 ` [PATCH v3 04/15] dt-bindings: display: sun4i-drm: Add A83T pipeline Maxime Ripard
                   ` (10 subsequent siblings)
  12 siblings, 1 reply; 33+ messages in thread
From: Maxime Ripard @ 2017-12-05 15:10 UTC (permalink / raw)
  To: Daniel Vetter, David Airlie, Chen-Yu Tsai, Maxime Ripard
  Cc: Mark Rutland, Thomas Petazzoni, jernej.skrabec, plaes,
	devicetree, linux-kernel, dri-devel, Rob Herring,
	linux-arm-kernel, icenowy

Some clocks and resets supposed to drive the LVDS logic in the display
engine have been overlooked when the driver was first introduced.

Add those additional resources to the binding, and we'll deal with the ABI
stability in the code.

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt | 8 +++++++-
 1 file changed, 8 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
index 50cc72ee1168..d4259a4f5171 100644
--- a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
+++ b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
@@ -121,6 +121,14 @@ Required properties:
 On SoCs other than the A33 and V3s, there is one more clock required:
    - 'tcon-ch1': The clock driving the TCON channel 1
 
+On SoCs that support LVDS (all SoCs but the A13, H3, H5 and V3s), you
+need one more reset line:
+   - 'lvds': The reset line driving the LVDS logic
+
+And on the SoCs newer than the A31 (sun6i and sun8i families), you
+need one more clock line:
+   - 'lvds-pll': The PLL that can be used to drive the LVDS clock
+
 DRC
 ---
 
-- 
git-series 0.9.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v3 04/15] dt-bindings: display: sun4i-drm: Add A83T pipeline
  2017-12-05 15:10 [PATCH v3 00/15] drm/sun4i: Add A83t LVDS support Maxime Ripard
  2017-12-05 15:10 ` [PATCH v3 01/15] dt-bindings: panel: lvds: Document power-supply property Maxime Ripard
  2017-12-05 15:10 ` [PATCH v3 03/15] dt-bindings: display: sun4i-drm: Add LVDS properties Maxime Ripard
@ 2017-12-05 15:10 ` Maxime Ripard
       [not found]   ` <3762a8428aaf207e80ae86d4db2e50473576bb6d.1512486553.git-series.maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
  2017-12-05 15:10 ` [PATCH v3 05/15] drm/sun4i: Fix error path handling Maxime Ripard
                   ` (9 subsequent siblings)
  12 siblings, 1 reply; 33+ messages in thread
From: Maxime Ripard @ 2017-12-05 15:10 UTC (permalink / raw)
  To: Daniel Vetter, David Airlie, Chen-Yu Tsai, Maxime Ripard
  Cc: Mark Rutland, Thomas Petazzoni, jernej.skrabec, plaes,
	devicetree, linux-kernel, dri-devel, Rob Herring,
	linux-arm-kernel, icenowy

The A83T has two video pipelines in parallel that looks quite similar to
the other SoCs.

The video planes are handled through a controller called the mixer, and the
video signal is then passed to the timing controller (TCON).

And while there is two instances of the mixers and TCONs, they have a
significant number of differences. The TCONs are quite easy to deal with,
one is supposed to generate TV (in the broader term, so including things
like HDMI) signals, the other one LCD (so RGB, LVDS, DSI) signals. And
while they are called TCON0 and TCON1 in the A83t datasheet, newer SoCs
call them TCON-TV and TCON-LCD, which seems more appropriate.

However, the mixers differ mostly by their capabilities, with some features
being available only in the first one, or the number of planes they expose,
but also through their register layout. And while the capabilities could be
represented as properties, the register layout differences would need to
express all the registers offsets as properties, which is usually quite
bad. Especially since documentation on that hardware block is close to
non-existant and we don't even have the list of all those registers in the
first place.

So let's call them mixer 0 and 1 in our compatibles, even though the name
is pretty bad...

At the moment, we only have tested the code on a board that has a single
display output, so we're leaving the tcon-tv and mixer1 out.

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
index d4259a4f5171..338cb6bbf25c 100644
--- a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
+++ b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
@@ -93,6 +93,7 @@ Required properties:
    * allwinner,sun6i-a31s-tcon
    * allwinner,sun7i-a20-tcon
    * allwinner,sun8i-a33-tcon
+   * allwinner,sun8i-a83t-tcon-lcd
    * allwinner,sun8i-v3s-tcon
  - reg: base address and size of memory-mapped region
  - interrupts: interrupt associated to this IP
@@ -224,6 +225,7 @@ supported.
 
 Required properties:
   - compatible: value must be one of:
+    * allwinner,sun8i-a83t-de2-mixer-0
     * allwinner,sun8i-v3s-de2-mixer
   - reg: base address and size of the memory-mapped region.
   - clocks: phandles to the clocks feeding the mixer
@@ -253,6 +255,7 @@ Required properties:
     * allwinner,sun6i-a31s-display-engine
     * allwinner,sun7i-a20-display-engine
     * allwinner,sun8i-a33-display-engine
+    * allwinner,sun8i-a83t-display-engine
     * allwinner,sun8i-v3s-display-engine
 
   - allwinner,pipelines: list of phandle to the display engine
-- 
git-series 0.9.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v3 05/15] drm/sun4i: Fix error path handling
  2017-12-05 15:10 [PATCH v3 00/15] drm/sun4i: Add A83t LVDS support Maxime Ripard
                   ` (2 preceding siblings ...)
  2017-12-05 15:10 ` [PATCH v3 04/15] dt-bindings: display: sun4i-drm: Add A83T pipeline Maxime Ripard
@ 2017-12-05 15:10 ` Maxime Ripard
       [not found]   ` <1f2443c41082fc6e086570da38d20744c52fe636.1512486553.git-series.maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
  2017-12-05 15:10 ` [PATCH v3 06/15] drm/sun4i: Force the mixer rate at 150MHz Maxime Ripard
                   ` (8 subsequent siblings)
  12 siblings, 1 reply; 33+ messages in thread
From: Maxime Ripard @ 2017-12-05 15:10 UTC (permalink / raw)
  To: Daniel Vetter, David Airlie, Chen-Yu Tsai, Maxime Ripard
  Cc: Mark Rutland, Thomas Petazzoni, jernej.skrabec, plaes,
	devicetree, linux-kernel, dri-devel, Rob Herring, stable,
	linux-arm-kernel, icenowy

The commit 4c7f16d14a33 ("drm/sun4i: Fix TCON clock and regmap
initialization sequence") moved a bunch of logic around, but forgot to
update the gotos after the introduction of the err_free_dotclock label.

It means that if we fail later that the one introduced in that commit,
we'll just to the old label which isn't free the clock we created. This
will result in a breakage as soon as someone tries to do something with
that clock, since its resources will have been long reclaimed.

Cc: <stable@vger.kernel.org>
Fixes: 4c7f16d14a33 ("drm/sun4i: Fix TCON clock and regmap initialization sequence")
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 drivers/gpu/drm/sun4i/sun4i_tcon.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index a1ed462c2430..ea056a3d2131 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -724,12 +724,12 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
 	if (IS_ERR(tcon->crtc)) {
 		dev_err(dev, "Couldn't create our CRTC\n");
 		ret = PTR_ERR(tcon->crtc);
-		goto err_free_clocks;
+		goto err_free_dotclock;
 	}
 
 	ret = sun4i_rgb_init(drm, tcon);
 	if (ret < 0)
-		goto err_free_clocks;
+		goto err_free_dotclock;
 
 	if (tcon->quirks->needs_de_be_mux) {
 		/*
-- 
git-series 0.9.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v3 06/15] drm/sun4i: Force the mixer rate at 150MHz
  2017-12-05 15:10 [PATCH v3 00/15] drm/sun4i: Add A83t LVDS support Maxime Ripard
                   ` (3 preceding siblings ...)
  2017-12-05 15:10 ` [PATCH v3 05/15] drm/sun4i: Fix error path handling Maxime Ripard
@ 2017-12-05 15:10 ` Maxime Ripard
  2017-12-05 15:10 ` [PATCH v3 07/15] drm/sun4i: Create minimal multipliers and dividers Maxime Ripard
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 33+ messages in thread
From: Maxime Ripard @ 2017-12-05 15:10 UTC (permalink / raw)
  To: Daniel Vetter, David Airlie, Chen-Yu Tsai, Maxime Ripard
  Cc: Mark Rutland, Thomas Petazzoni, jernej.skrabec, plaes,
	devicetree, linux-kernel, dri-devel, Rob Herring,
	linux-arm-kernel, icenowy

It seems like the mixer can only run properly when clocked at 150MHz. In
order to have something more robust than simply a fire-and-forget
assigned-clocks-rate, let's put that in the code.

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 drivers/gpu/drm/sun4i/sun8i_mixer.c |  9 +++++++++
 drivers/gpu/drm/sun4i/sun8i_mixer.h |  3 +++
 2 files changed, 12 insertions(+)

diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c
index 29ceeb016d72..ff235e3228ce 100644
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
@@ -400,6 +400,14 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master,
 	}
 	clk_prepare_enable(mixer->mod_clk);
 
+	/*
+	 * It seems that we need to enforce that rate for whatever
+	 * reason for the mixer to be functional. Make sure it's the
+	 * case.
+	 */
+	if (mixer->cfg->mod_rate)
+		clk_set_rate(mixer->mod_clk, mixer->cfg->mod_rate);
+
 	list_add_tail(&mixer->engine.list, &drv->engine_list);
 
 	/* Reset the registers */
@@ -474,6 +482,7 @@ static const struct sun8i_mixer_cfg sun8i_v3s_mixer_cfg = {
 	.ui_num = 1,
 	.scaler_mask = 0x3,
 	.ccsc = 0,
+	.mod_rate = 150000000,
 };
 
 static const struct of_device_id sun8i_mixer_of_table[] = {
diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h b/drivers/gpu/drm/sun4i/sun8i_mixer.h
index bc58040a88f9..f34e70c42adf 100644
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.h
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h
@@ -121,12 +121,15 @@ struct de2_fmt_info {
  *	Set value to 0 if this is first mixer or second mixer with VEP support.
  *	Set value to 1 if this is second mixer without VEP support. Other values
  *	are invalid.
+ * @mod_rate: module clock rate that needs to be set in order to have
+ *	a functional block.
  */
 struct sun8i_mixer_cfg {
 	int		vi_num;
 	int		ui_num;
 	int		scaler_mask;
 	int		ccsc;
+	unsigned long	mod_rate;
 };
 
 struct sun8i_mixer {
-- 
git-series 0.9.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v3 07/15] drm/sun4i: Create minimal multipliers and dividers
  2017-12-05 15:10 [PATCH v3 00/15] drm/sun4i: Add A83t LVDS support Maxime Ripard
                   ` (4 preceding siblings ...)
  2017-12-05 15:10 ` [PATCH v3 06/15] drm/sun4i: Force the mixer rate at 150MHz Maxime Ripard
@ 2017-12-05 15:10 ` Maxime Ripard
       [not found] ` <cover.825a49a4c1c565a548f3de0375e7537e7e8fd3a4.1512486553.git-series.maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 33+ messages in thread
From: Maxime Ripard @ 2017-12-05 15:10 UTC (permalink / raw)
  To: Daniel Vetter, David Airlie, Chen-Yu Tsai, Maxime Ripard
  Cc: Mark Rutland, Thomas Petazzoni, jernej.skrabec, plaes,
	devicetree, linux-kernel, dri-devel, Rob Herring,
	linux-arm-kernel, icenowy

The various outputs the TCON can provide have different constraints on the
dotclock divider. Let's make them configurable by the various mode_set
functions.

Reviewed-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 drivers/gpu/drm/sun4i/sun4i_dotclock.c | 10 +++++++---
 drivers/gpu/drm/sun4i/sun4i_tcon.c     |  2 ++
 drivers/gpu/drm/sun4i/sun4i_tcon.h     |  2 ++
 3 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_dotclock.c b/drivers/gpu/drm/sun4i/sun4i_dotclock.c
index d401156490f3..023f39bda633 100644
--- a/drivers/gpu/drm/sun4i/sun4i_dotclock.c
+++ b/drivers/gpu/drm/sun4i/sun4i_dotclock.c
@@ -17,8 +17,9 @@
 #include "sun4i_dotclock.h"
 
 struct sun4i_dclk {
-	struct clk_hw	hw;
-	struct regmap	*regmap;
+	struct clk_hw		hw;
+	struct regmap		*regmap;
+	struct sun4i_tcon	*tcon;
 };
 
 static inline struct sun4i_dclk *hw_to_dclk(struct clk_hw *hw)
@@ -73,11 +74,13 @@ static unsigned long sun4i_dclk_recalc_rate(struct clk_hw *hw,
 static long sun4i_dclk_round_rate(struct clk_hw *hw, unsigned long rate,
 				  unsigned long *parent_rate)
 {
+	struct sun4i_dclk *dclk = hw_to_dclk(hw);
+	struct sun4i_tcon *tcon = dclk->tcon;
 	unsigned long best_parent = 0;
 	u8 best_div = 1;
 	int i;
 
-	for (i = 6; i <= 127; i++) {
+	for (i = tcon->dclk_min_div; i <= tcon->dclk_max_div; i++) {
 		unsigned long ideal = rate * i;
 		unsigned long rounded;
 
@@ -167,6 +170,7 @@ int sun4i_dclk_create(struct device *dev, struct sun4i_tcon *tcon)
 	dclk = devm_kzalloc(dev, sizeof(*dclk), GFP_KERNEL);
 	if (!dclk)
 		return -ENOMEM;
+	dclk->tcon = tcon;
 
 	init.name = clk_name;
 	init.ops = &sun4i_dclk_ops;
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index ea056a3d2131..46e28ca1f676 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -177,6 +177,8 @@ static void sun4i_tcon0_mode_set_rgb(struct sun4i_tcon *tcon,
 	u8 clk_delay;
 	u32 val = 0;
 
+	tcon->dclk_min_div = 6;
+	tcon->dclk_max_div = 127;
 	sun4i_tcon0_mode_set_common(tcon, mode);
 
 	/* Adjust clock delay */
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.h b/drivers/gpu/drm/sun4i/sun4i_tcon.h
index 839266a38505..bd3ad7684870 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.h
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.h
@@ -169,6 +169,8 @@ struct sun4i_tcon {
 
 	/* Pixel clock */
 	struct clk			*dclk;
+	u8				dclk_max_div;
+	u8				dclk_min_div;
 
 	/* Reset control */
 	struct reset_control		*lcd_rst;
-- 
git-series 0.9.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v3 08/15] drm/sun4i: Add LVDS support
       [not found] ` <cover.825a49a4c1c565a548f3de0375e7537e7e8fd3a4.1512486553.git-series.maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
  2017-12-05 15:10   ` [PATCH v3 02/15] drm/panel: lvds: Add support for the power-supply property Maxime Ripard
@ 2017-12-05 15:10   ` Maxime Ripard
       [not found]     ` <b900e5963180c94ca02bde178b6674622a127787.1512486553.git-series.maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
  2017-12-07 10:14     ` Philippe Ombredanne
  2017-12-05 15:10   ` [PATCH v3 14/15] ARM: dts: sun8i: a711: Reinstate the PMIC compatible Maxime Ripard
  2 siblings, 2 replies; 33+ messages in thread
From: Maxime Ripard @ 2017-12-05 15:10 UTC (permalink / raw)
  To: Daniel Vetter, David Airlie, Chen-Yu Tsai, Maxime Ripard
  Cc: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Mark Rutland, Rob Herring,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	plaes-q/aMd4JkU83YtjvyW6yDsg, icenowy-h8G6r0blFSE,
	Thomas Petazzoni, jernej.skrabec-gGgVlfcn5nU,
	devicetree-u79uwXL29TY76Z2rM5mHXA

The TCON supports the LVDS interface to output to a panel or a bridge.
Let's add support for it.

Signed-off-by: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
---
 drivers/gpu/drm/sun4i/Makefile     |   1 +-
 drivers/gpu/drm/sun4i/sun4i_lvds.c | 183 +++++++++++++++++++++++-
 drivers/gpu/drm/sun4i/sun4i_lvds.h |  18 ++-
 drivers/gpu/drm/sun4i/sun4i_tcon.c | 238 +++++++++++++++++++++++++++++-
 drivers/gpu/drm/sun4i/sun4i_tcon.h |  29 ++++-
 5 files changed, 467 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/sun4i/sun4i_lvds.c
 create mode 100644 drivers/gpu/drm/sun4i/sun4i_lvds.h

diff --git a/drivers/gpu/drm/sun4i/Makefile b/drivers/gpu/drm/sun4i/Makefile
index 82a6ac57fbe3..2b37a6abbb1d 100644
--- a/drivers/gpu/drm/sun4i/Makefile
+++ b/drivers/gpu/drm/sun4i/Makefile
@@ -15,6 +15,7 @@ sun8i-mixer-y			+= sun8i_mixer.o sun8i_ui_layer.o \
 
 sun4i-tcon-y			+= sun4i_crtc.o
 sun4i-tcon-y			+= sun4i_dotclock.o
+sun4i-tcon-y			+= sun4i_lvds.o
 sun4i-tcon-y			+= sun4i_tcon.o
 sun4i-tcon-y			+= sun4i_rgb.o
 
diff --git a/drivers/gpu/drm/sun4i/sun4i_lvds.c b/drivers/gpu/drm/sun4i/sun4i_lvds.c
new file mode 100644
index 000000000000..635a3f505ecb
--- /dev/null
+++ b/drivers/gpu/drm/sun4i/sun4i_lvds.c
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2015 NextThing Co
+ * Copyright (C) 2015-2017 Free Electrons
+ *
+ * Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
+ *
+ * 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 <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_of.h>
+#include <drm/drm_panel.h>
+
+#include "sun4i_crtc.h"
+#include "sun4i_tcon.h"
+#include "sun4i_lvds.h"
+
+struct sun4i_lvds {
+	struct drm_connector	connector;
+	struct drm_encoder	encoder;
+
+	struct sun4i_tcon	*tcon;
+};
+
+static inline struct sun4i_lvds *
+drm_connector_to_sun4i_lvds(struct drm_connector *connector)
+{
+	return container_of(connector, struct sun4i_lvds,
+			    connector);
+}
+
+static inline struct sun4i_lvds *
+drm_encoder_to_sun4i_lvds(struct drm_encoder *encoder)
+{
+	return container_of(encoder, struct sun4i_lvds,
+			    encoder);
+}
+
+static int sun4i_lvds_get_modes(struct drm_connector *connector)
+{
+	struct sun4i_lvds *lvds =
+		drm_connector_to_sun4i_lvds(connector);
+	struct sun4i_tcon *tcon = lvds->tcon;
+
+	return drm_panel_get_modes(tcon->panel);
+}
+
+static struct drm_connector_helper_funcs sun4i_lvds_con_helper_funcs = {
+	.get_modes	= sun4i_lvds_get_modes,
+};
+
+static void
+sun4i_lvds_connector_destroy(struct drm_connector *connector)
+{
+	struct sun4i_lvds *lvds = drm_connector_to_sun4i_lvds(connector);
+	struct sun4i_tcon *tcon = lvds->tcon;
+
+	drm_panel_detach(tcon->panel);
+	drm_connector_cleanup(connector);
+}
+
+static const struct drm_connector_funcs sun4i_lvds_con_funcs = {
+	.fill_modes		= drm_helper_probe_single_connector_modes,
+	.destroy		= sun4i_lvds_connector_destroy,
+	.reset			= drm_atomic_helper_connector_reset,
+	.atomic_duplicate_state	= drm_atomic_helper_connector_duplicate_state,
+	.atomic_destroy_state	= drm_atomic_helper_connector_destroy_state,
+};
+
+static void sun4i_lvds_encoder_enable(struct drm_encoder *encoder)
+{
+	struct sun4i_lvds *lvds = drm_encoder_to_sun4i_lvds(encoder);
+	struct sun4i_tcon *tcon = lvds->tcon;
+
+	DRM_DEBUG_DRIVER("Enabling LVDS output\n");
+
+	if (!IS_ERR(tcon->panel)) {
+		drm_panel_prepare(tcon->panel);
+		drm_panel_enable(tcon->panel);
+	}
+}
+
+static void sun4i_lvds_encoder_disable(struct drm_encoder *encoder)
+{
+	struct sun4i_lvds *lvds = drm_encoder_to_sun4i_lvds(encoder);
+	struct sun4i_tcon *tcon = lvds->tcon;
+
+	DRM_DEBUG_DRIVER("Disabling LVDS output\n");
+
+	if (!IS_ERR(tcon->panel)) {
+		drm_panel_disable(tcon->panel);
+		drm_panel_unprepare(tcon->panel);
+	}
+}
+
+static const struct drm_encoder_helper_funcs sun4i_lvds_enc_helper_funcs = {
+	.disable	= sun4i_lvds_encoder_disable,
+	.enable		= sun4i_lvds_encoder_enable,
+};
+
+static const struct drm_encoder_funcs sun4i_lvds_enc_funcs = {
+	.destroy	= drm_encoder_cleanup,
+};
+
+int sun4i_lvds_init(struct drm_device *drm, struct sun4i_tcon *tcon)
+{
+	struct drm_encoder *encoder;
+	struct drm_bridge *bridge;
+	struct sun4i_lvds *lvds;
+	int ret;
+
+	lvds = devm_kzalloc(drm->dev, sizeof(*lvds), GFP_KERNEL);
+	if (!lvds)
+		return -ENOMEM;
+	lvds->tcon = tcon;
+	encoder = &lvds->encoder;
+
+	ret = drm_of_find_panel_or_bridge(tcon->dev->of_node, 1, 0,
+					  &tcon->panel, &bridge);
+	if (ret) {
+		dev_info(drm->dev, "No panel or bridge found... LVDS output disabled\n");
+		return 0;
+	}
+
+	drm_encoder_helper_add(&lvds->encoder,
+			       &sun4i_lvds_enc_helper_funcs);
+	ret = drm_encoder_init(drm,
+			       &lvds->encoder,
+			       &sun4i_lvds_enc_funcs,
+			       DRM_MODE_ENCODER_LVDS,
+			       NULL);
+	if (ret) {
+		dev_err(drm->dev, "Couldn't initialise the lvds encoder\n");
+		goto err_out;
+	}
+
+	/* The LVDS encoder can only work with the TCON channel 0 */
+	lvds->encoder.possible_crtcs = BIT(drm_crtc_index(&tcon->crtc->crtc));
+
+	if (tcon->panel) {
+		drm_connector_helper_add(&lvds->connector,
+					 &sun4i_lvds_con_helper_funcs);
+		ret = drm_connector_init(drm, &lvds->connector,
+					 &sun4i_lvds_con_funcs,
+					 DRM_MODE_CONNECTOR_LVDS);
+		if (ret) {
+			dev_err(drm->dev, "Couldn't initialise the lvds connector\n");
+			goto err_cleanup_connector;
+		}
+
+		drm_mode_connector_attach_encoder(&lvds->connector,
+						  &lvds->encoder);
+
+		ret = drm_panel_attach(tcon->panel, &lvds->connector);
+		if (ret) {
+			dev_err(drm->dev, "Couldn't attach our panel\n");
+			goto err_cleanup_connector;
+		}
+	}
+
+	if (bridge) {
+		ret = drm_bridge_attach(encoder, bridge, NULL);
+		if (ret) {
+			dev_err(drm->dev, "Couldn't attach our bridge\n");
+			goto err_cleanup_connector;
+		}
+	}
+
+	return 0;
+
+err_cleanup_connector:
+	drm_encoder_cleanup(&lvds->encoder);
+err_out:
+	return ret;
+}
+EXPORT_SYMBOL(sun4i_lvds_init);
diff --git a/drivers/gpu/drm/sun4i/sun4i_lvds.h b/drivers/gpu/drm/sun4i/sun4i_lvds.h
new file mode 100644
index 000000000000..1b8fad4b82c3
--- /dev/null
+++ b/drivers/gpu/drm/sun4i/sun4i_lvds.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2015 NextThing Co
+ * Copyright (C) 2015-2017 Free Electrons
+ *
+ * Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
+ *
+ * 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.
+ */
+
+#ifndef _SUN4I_LVDS_H_
+#define _SUN4I_LVDS_H_
+
+int sun4i_lvds_init(struct drm_device *drm, struct sun4i_tcon *tcon);
+
+#endif /* _SUN4I_LVDS_H_ */
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index 46e28ca1f676..92f4738101e6 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -31,10 +31,52 @@
 #include "sun4i_crtc.h"
 #include "sun4i_dotclock.h"
 #include "sun4i_drv.h"
+#include "sun4i_lvds.h"
 #include "sun4i_rgb.h"
 #include "sun4i_tcon.h"
 #include "sunxi_engine.h"
 
+static struct drm_connector *sun4i_tcon_get_connector(const struct drm_encoder *encoder)
+{
+	struct drm_connector *connector;
+	struct drm_connector_list_iter iter;
+
+	drm_connector_list_iter_begin(encoder->dev, &iter);
+	drm_for_each_connector_iter(connector, &iter)
+		if (connector->encoder == encoder) {
+			drm_connector_list_iter_end(&iter);
+			return connector;
+		}
+	drm_connector_list_iter_end(&iter);
+
+	return NULL;
+}
+
+static int sun4i_tcon_get_pixel_depth(const struct drm_encoder *encoder)
+{
+	struct drm_connector *connector;
+	struct drm_display_info *info;
+
+	connector = sun4i_tcon_get_connector(encoder);
+	if (!connector)
+		return -EINVAL;
+
+	info = &connector->display_info;
+	if (info->num_bus_formats != 1)
+		return -EINVAL;
+
+	switch (info->bus_formats[0]) {
+	case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG:
+		return 18;
+
+	case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA:
+	case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG:
+		return 24;
+	}
+
+	return -EINVAL;
+}
+
 static void sun4i_tcon_channel_set_status(struct sun4i_tcon *tcon, int channel,
 					  bool enabled)
 {
@@ -65,13 +107,58 @@ static void sun4i_tcon_channel_set_status(struct sun4i_tcon *tcon, int channel,
 		clk_disable_unprepare(clk);
 }
 
+static void sun4i_tcon_lvds_set_status(struct sun4i_tcon *tcon,
+				       const struct drm_encoder *encoder,
+				       bool enabled)
+{
+	if (enabled) {
+		u8 val;
+
+		regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_IF_REG,
+				   SUN4I_TCON0_LVDS_IF_EN,
+				   SUN4I_TCON0_LVDS_IF_EN);
+
+		regmap_write(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
+			     SUN4I_TCON0_LVDS_ANA0_C(2) |
+			     SUN4I_TCON0_LVDS_ANA0_V(3) |
+			     SUN4I_TCON0_LVDS_ANA0_PD(2) |
+			     SUN4I_TCON0_LVDS_ANA0_EN_LDO);
+		udelay(2);
+
+		regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
+				   SUN4I_TCON0_LVDS_ANA0_EN_MB,
+				   SUN4I_TCON0_LVDS_ANA0_EN_MB);
+		udelay(2);
+
+		regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
+				   SUN4I_TCON0_LVDS_ANA0_EN_DRVC,
+				   SUN4I_TCON0_LVDS_ANA0_EN_DRVC);
+
+		if (sun4i_tcon_get_pixel_depth(encoder) == 18)
+			val = 7;
+		else
+			val = 0xf;
+
+		regmap_write_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
+				  SUN4I_TCON0_LVDS_ANA0_EN_DRVD(0xf),
+				  SUN4I_TCON0_LVDS_ANA0_EN_DRVD(val));
+	} else {
+		regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_IF_REG,
+				   SUN4I_TCON0_LVDS_IF_EN, 0);
+	}
+}
+
 void sun4i_tcon_set_status(struct sun4i_tcon *tcon,
 			   const struct drm_encoder *encoder,
 			   bool enabled)
 {
+	bool is_lvds = false;
 	int channel;
 
 	switch (encoder->encoder_type) {
+	case DRM_MODE_ENCODER_LVDS:
+		is_lvds = true;
+		/* Fallthrough */
 	case DRM_MODE_ENCODER_NONE:
 		channel = 0;
 		break;
@@ -84,10 +171,16 @@ void sun4i_tcon_set_status(struct sun4i_tcon *tcon,
 		return;
 	}
 
+	if (is_lvds && !enabled)
+		sun4i_tcon_lvds_set_status(tcon, encoder, false);
+
 	regmap_update_bits(tcon->regs, SUN4I_TCON_GCTL_REG,
 			   SUN4I_TCON_GCTL_TCON_ENABLE,
 			   enabled ? SUN4I_TCON_GCTL_TCON_ENABLE : 0);
 
+	if (is_lvds && enabled)
+		sun4i_tcon_lvds_set_status(tcon, encoder, true);
+
 	sun4i_tcon_channel_set_status(tcon, channel, enabled);
 }
 
@@ -170,6 +263,78 @@ static void sun4i_tcon0_mode_set_common(struct sun4i_tcon *tcon,
 		     SUN4I_TCON0_BASIC0_Y(mode->crtc_vdisplay));
 }
 
+static void sun4i_tcon0_mode_set_lvds(struct sun4i_tcon *tcon,
+				      const struct drm_encoder *encoder,
+				      const struct drm_display_mode *mode)
+{
+	unsigned int bp;
+	u8 clk_delay;
+	u32 reg, val = 0;
+
+	tcon->dclk_min_div = 7;
+	tcon->dclk_max_div = 7;
+	sun4i_tcon0_mode_set_common(tcon, mode);
+
+	/* Adjust clock delay */
+	clk_delay = sun4i_tcon_get_clk_delay(mode, 0);
+	regmap_update_bits(tcon->regs, SUN4I_TCON0_CTL_REG,
+			   SUN4I_TCON0_CTL_CLK_DELAY_MASK,
+			   SUN4I_TCON0_CTL_CLK_DELAY(clk_delay));
+
+	/*
+	 * This is called a backporch in the register documentation,
+	 * but it really is the back porch + hsync
+	 */
+	bp = mode->crtc_htotal - mode->crtc_hsync_start;
+	DRM_DEBUG_DRIVER("Setting horizontal total %d, backporch %d\n",
+			 mode->crtc_htotal, bp);
+
+	/* Set horizontal display timings */
+	regmap_write(tcon->regs, SUN4I_TCON0_BASIC1_REG,
+		     SUN4I_TCON0_BASIC1_H_TOTAL(mode->htotal) |
+		     SUN4I_TCON0_BASIC1_H_BACKPORCH(bp));
+
+	/*
+	 * This is called a backporch in the register documentation,
+	 * but it really is the back porch + hsync
+	 */
+	bp = mode->crtc_vtotal - mode->crtc_vsync_start;
+	DRM_DEBUG_DRIVER("Setting vertical total %d, backporch %d\n",
+			 mode->crtc_vtotal, bp);
+
+	/* Set vertical display timings */
+	regmap_write(tcon->regs, SUN4I_TCON0_BASIC2_REG,
+		     SUN4I_TCON0_BASIC2_V_TOTAL(mode->crtc_vtotal * 2) |
+		     SUN4I_TCON0_BASIC2_V_BACKPORCH(bp));
+
+	reg = SUN4I_TCON0_LVDS_IF_CLK_SEL_TCON0 |
+		SUN4I_TCON0_LVDS_IF_DATA_POL_NORMAL |
+		SUN4I_TCON0_LVDS_IF_CLK_POL_NORMAL;
+	if (sun4i_tcon_get_pixel_depth(encoder) == 24)
+		reg |= SUN4I_TCON0_LVDS_IF_BITWIDTH_24BITS;
+	else
+		reg |= SUN4I_TCON0_LVDS_IF_BITWIDTH_18BITS;
+
+	regmap_write(tcon->regs, SUN4I_TCON0_LVDS_IF_REG, reg);
+
+	/* Setup the polarity of the various signals */
+	if (!(mode->flags & DRM_MODE_FLAG_PHSYNC))
+		val |= SUN4I_TCON0_IO_POL_HSYNC_POSITIVE;
+
+	if (!(mode->flags & DRM_MODE_FLAG_PVSYNC))
+		val |= SUN4I_TCON0_IO_POL_VSYNC_POSITIVE;
+
+	regmap_write(tcon->regs, SUN4I_TCON0_IO_POL_REG, val);
+
+	/* Map output pins to channel 0 */
+	regmap_update_bits(tcon->regs, SUN4I_TCON_GCTL_REG,
+			   SUN4I_TCON_GCTL_IOMAP_MASK,
+			   SUN4I_TCON_GCTL_IOMAP_TCON0);
+
+	/* Enable the output on the pins */
+	regmap_write(tcon->regs, SUN4I_TCON0_IO_TRI_REG, 0xe0000000);
+}
+
 static void sun4i_tcon0_mode_set_rgb(struct sun4i_tcon *tcon,
 				     const struct drm_display_mode *mode)
 {
@@ -336,6 +501,9 @@ void sun4i_tcon_mode_set(struct sun4i_tcon *tcon,
 			 const struct drm_display_mode *mode)
 {
 	switch (encoder->encoder_type) {
+	case DRM_MODE_ENCODER_LVDS:
+		sun4i_tcon0_mode_set_lvds(tcon, encoder, mode);
+		break;
 	case DRM_MODE_ENCODER_NONE:
 		sun4i_tcon0_mode_set_rgb(tcon, mode);
 		sun4i_tcon_set_mux(tcon, 0, encoder);
@@ -667,7 +835,9 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
 	struct drm_device *drm = data;
 	struct sun4i_drv *drv = drm->dev_private;
 	struct sunxi_engine *engine;
+	struct device_node *remote;
 	struct sun4i_tcon *tcon;
+	bool has_lvds_rst, has_lvds_pll, can_lvds;
 	int ret;
 
 	engine = sun4i_tcon_find_engine(drv, dev->of_node);
@@ -698,6 +868,54 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
 		return ret;
 	}
 
+	/*
+	 * This can only be made optional since we've had DT nodes
+	 * without the LVDS reset properties.
+	 *
+	 * If the property is missing, just disable LVDS, and print a
+	 * warning.
+	 */
+	tcon->lvds_rst = devm_reset_control_get_optional(dev, "lvds");
+	if (IS_ERR(tcon->lvds_rst)) {
+		dev_err(dev, "Couldn't get our reset line\n");
+		return PTR_ERR(tcon->lvds_rst);
+	} else if (tcon->lvds_rst) {
+		has_lvds_rst = true;
+		reset_control_reset(tcon->lvds_rst);
+	} else {
+		has_lvds_rst = false;
+	}
+
+	/*
+	 * This can only be made optional since we've had DT nodes
+	 * without the LVDS reset properties.
+	 *
+	 * If the property is missing, just disable LVDS, and print a
+	 * warning.
+	 */
+	if (tcon->quirks->has_lvds_pll) {
+		tcon->lvds_pll = devm_clk_get(dev, "pll-lvds");
+		if (IS_ERR(tcon->lvds_pll)) {
+			if (PTR_ERR(tcon->lvds_pll) == -ENOENT) {
+				has_lvds_pll = false;
+			} else {
+				dev_err(dev, "Couldn't get the LVDS PLL\n");
+				return PTR_ERR(tcon->lvds_rst);
+			}
+		} else {
+			has_lvds_pll = true;
+		}
+	}
+
+	if (!has_lvds_rst || (tcon->quirks->has_lvds_pll && !has_lvds_pll)) {
+		dev_warn(dev,
+			 "Missing LVDS properties, Please upgrade your DT\n");
+		dev_warn(dev, "LVDS output disabled\n");
+		can_lvds = false;
+	} else {
+		can_lvds = true;
+	}
+
 	ret = sun4i_tcon_init_clocks(dev, tcon);
 	if (ret) {
 		dev_err(dev, "Couldn't init our TCON clocks\n");
@@ -729,7 +947,21 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
 		goto err_free_dotclock;
 	}
 
-	ret = sun4i_rgb_init(drm, tcon);
+	/*
+	 * If we have an LVDS panel connected to the TCON, we should
+	 * just probe the LVDS connector. Otherwise, just probe RGB as
+	 * we used to.
+	 */
+	remote = of_graph_get_remote_node(dev->of_node, 1, 0);
+	if (of_device_is_compatible(remote, "panel-lvds"))
+		if (can_lvds)
+			ret = sun4i_lvds_init(drm, tcon);
+		else
+			ret = -EINVAL;
+	else
+		ret = sun4i_rgb_init(drm, tcon);
+	of_node_put(remote);
+
 	if (ret < 0)
 		goto err_free_dotclock;
 
@@ -879,12 +1111,14 @@ static const struct sun4i_tcon_quirks sun5i_a13_quirks = {
 
 static const struct sun4i_tcon_quirks sun6i_a31_quirks = {
 	.has_channel_1		= true,
+	.has_lvds_pll		= true,
 	.needs_de_be_mux	= true,
 	.set_mux		= sun6i_tcon_set_mux,
 };
 
 static const struct sun4i_tcon_quirks sun6i_a31s_quirks = {
 	.has_channel_1		= true,
+	.has_lvds_pll		= true,
 	.needs_de_be_mux	= true,
 };
 
@@ -895,7 +1129,7 @@ static const struct sun4i_tcon_quirks sun7i_a20_quirks = {
 };
 
 static const struct sun4i_tcon_quirks sun8i_a33_quirks = {
-	/* nothing is supported */
+	.has_lvds_pll		= true,
 };
 
 static const struct sun4i_tcon_quirks sun8i_v3s_quirks = {
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.h b/drivers/gpu/drm/sun4i/sun4i_tcon.h
index bd3ad7684870..6e801a6325a1 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.h
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.h
@@ -70,7 +70,21 @@
 #define SUN4I_TCON0_TTL2_REG			0x78
 #define SUN4I_TCON0_TTL3_REG			0x7c
 #define SUN4I_TCON0_TTL4_REG			0x80
+
 #define SUN4I_TCON0_LVDS_IF_REG			0x84
+#define SUN4I_TCON0_LVDS_IF_EN				BIT(31)
+#define SUN4I_TCON0_LVDS_IF_BITWIDTH_MASK		BIT(26)
+#define SUN4I_TCON0_LVDS_IF_BITWIDTH_18BITS		(1 << 26)
+#define SUN4I_TCON0_LVDS_IF_BITWIDTH_24BITS		(0 << 26)
+#define SUN4I_TCON0_LVDS_IF_CLK_SEL_MASK		BIT(20)
+#define SUN4I_TCON0_LVDS_IF_CLK_SEL_TCON0		(1 << 20)
+#define SUN4I_TCON0_LVDS_IF_CLK_POL_MASK		BIT(4)
+#define SUN4I_TCON0_LVDS_IF_CLK_POL_NORMAL		(1 << 4)
+#define SUN4I_TCON0_LVDS_IF_CLK_POL_INV			(0 << 4)
+#define SUN4I_TCON0_LVDS_IF_DATA_POL_MASK		GENMASK(3, 0)
+#define SUN4I_TCON0_LVDS_IF_DATA_POL_NORMAL		(0xf)
+#define SUN4I_TCON0_LVDS_IF_DATA_POL_INV		(0)
+
 #define SUN4I_TCON0_IO_POL_REG			0x88
 #define SUN4I_TCON0_IO_POL_DCLK_PHASE(phase)		((phase & 3) << 28)
 #define SUN4I_TCON0_IO_POL_HSYNC_POSITIVE		BIT(25)
@@ -131,6 +145,16 @@
 #define SUN4I_TCON_CEU_RANGE_G_REG		0x144
 #define SUN4I_TCON_CEU_RANGE_B_REG		0x148
 #define SUN4I_TCON_MUX_CTRL_REG			0x200
+
+#define SUN4I_TCON0_LVDS_ANA0_REG		0x220
+#define SUN4I_TCON0_LVDS_ANA0_EN_MB			BIT(31)
+#define SUN4I_TCON0_LVDS_ANA0_EN_LDO			BIT(30)
+#define SUN4I_TCON0_LVDS_ANA0_EN_DRVC			BIT(24)
+#define SUN4I_TCON0_LVDS_ANA0_EN_DRVD(x)		(((x) & 0xf) << 20)
+#define SUN4I_TCON0_LVDS_ANA0_C(x)			(((x) & 3) << 17)
+#define SUN4I_TCON0_LVDS_ANA0_V(x)			(((x) & 3) << 8)
+#define SUN4I_TCON0_LVDS_ANA0_PD(x)			(((x) & 3) << 4)
+
 #define SUN4I_TCON1_FILL_CTL_REG		0x300
 #define SUN4I_TCON1_FILL_BEG0_REG		0x304
 #define SUN4I_TCON1_FILL_END0_REG		0x308
@@ -149,6 +173,7 @@ struct sun4i_tcon;
 
 struct sun4i_tcon_quirks {
 	bool	has_channel_1;	/* a33 does not have channel 1 */
+	bool	has_lvds_pll;	/* Can we mux the LVDS clock to a PLL? */
 	bool	needs_de_be_mux; /* sun6i needs mux to select backend */
 
 	/* callback to handle tcon muxing options */
@@ -167,6 +192,9 @@ struct sun4i_tcon {
 	struct clk			*sclk0;
 	struct clk			*sclk1;
 
+	/* Possible mux for the LVDS clock */
+	struct clk			*lvds_pll;
+
 	/* Pixel clock */
 	struct clk			*dclk;
 	u8				dclk_max_div;
@@ -174,6 +202,7 @@ struct sun4i_tcon {
 
 	/* Reset control */
 	struct reset_control		*lcd_rst;
+	struct reset_control		*lvds_rst;
 
 	struct drm_panel		*panel;
 
-- 
git-series 0.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v3 09/15] drm/sun4i: Add A83T support
  2017-12-05 15:10 [PATCH v3 00/15] drm/sun4i: Add A83t LVDS support Maxime Ripard
                   ` (6 preceding siblings ...)
       [not found] ` <cover.825a49a4c1c565a548f3de0375e7537e7e8fd3a4.1512486553.git-series.maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
@ 2017-12-05 15:10 ` Maxime Ripard
  2017-12-05 15:42   ` Jernej Škrabec
  2017-12-05 15:10 ` [PATCH v3 10/15] ARM: dts: sun8i: a83t: Add display pipeline Maxime Ripard
                   ` (4 subsequent siblings)
  12 siblings, 1 reply; 33+ messages in thread
From: Maxime Ripard @ 2017-12-05 15:10 UTC (permalink / raw)
  To: Daniel Vetter, David Airlie, Chen-Yu Tsai, Maxime Ripard
  Cc: Mark Rutland, Thomas Petazzoni, jernej.skrabec, plaes,
	devicetree, linux-kernel, dri-devel, Rob Herring,
	linux-arm-kernel, icenowy

Add support for the A83T display pipeline.

Reviewed-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 drivers/gpu/drm/sun4i/sun4i_drv.c   |  1 +
 drivers/gpu/drm/sun4i/sun4i_tcon.c  |  5 +++++
 drivers/gpu/drm/sun4i/sun8i_mixer.c |  9 +++++++++
 3 files changed, 15 insertions(+)

diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c
index 49215d91c853..6f5e721b545e 100644
--- a/drivers/gpu/drm/sun4i/sun4i_drv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
@@ -347,6 +347,7 @@ static const struct of_device_id sun4i_drv_of_table[] = {
 	{ .compatible = "allwinner,sun6i-a31s-display-engine" },
 	{ .compatible = "allwinner,sun7i-a20-display-engine" },
 	{ .compatible = "allwinner,sun8i-a33-display-engine" },
+	{ .compatible = "allwinner,sun8i-a83t-display-engine" },
 	{ .compatible = "allwinner,sun8i-v3s-display-engine" },
 	{ }
 };
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index 92f4738101e6..9b757450555f 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -1132,6 +1132,10 @@ static const struct sun4i_tcon_quirks sun8i_a33_quirks = {
 	.has_lvds_pll		= true,
 };
 
+static const struct sun4i_tcon_quirks sun8i_a83t_lcd_quirks = {
+	/* nothing is supported */
+};
+
 static const struct sun4i_tcon_quirks sun8i_v3s_quirks = {
 	/* nothing is supported */
 };
@@ -1144,6 +1148,7 @@ const struct of_device_id sun4i_tcon_of_table[] = {
 	{ .compatible = "allwinner,sun6i-a31s-tcon", .data = &sun6i_a31s_quirks },
 	{ .compatible = "allwinner,sun7i-a20-tcon", .data = &sun7i_a20_quirks },
 	{ .compatible = "allwinner,sun8i-a33-tcon", .data = &sun8i_a33_quirks },
+	{ .compatible = "allwinner,sun8i-a83t-tcon-lcd", .data = &sun8i_a83t_lcd_quirks },
 	{ .compatible = "allwinner,sun8i-v3s-tcon", .data = &sun8i_v3s_quirks },
 	{ }
 };
diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c
index ff235e3228ce..6829bec4ba68 100644
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
@@ -477,6 +477,11 @@ static int sun8i_mixer_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct sun8i_mixer_cfg sun8i_a83t_mixer_cfg = {
+	.vi_num = 1,
+	.ui_num = 3,
+};
+
 static const struct sun8i_mixer_cfg sun8i_v3s_mixer_cfg = {
 	.vi_num = 2,
 	.ui_num = 1,
@@ -487,6 +492,10 @@ static const struct sun8i_mixer_cfg sun8i_v3s_mixer_cfg = {
 
 static const struct of_device_id sun8i_mixer_of_table[] = {
 	{
+		.compatible = "allwinner,sun8i-a83t-de2-mixer-0",
+		.data = &sun8i_a83t_mixer_cfg,
+	},
+	{
 		.compatible = "allwinner,sun8i-v3s-de2-mixer",
 		.data = &sun8i_v3s_mixer_cfg,
 	},
-- 
git-series 0.9.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v3 10/15] ARM: dts: sun8i: a83t: Add display pipeline
  2017-12-05 15:10 [PATCH v3 00/15] drm/sun4i: Add A83t LVDS support Maxime Ripard
                   ` (7 preceding siblings ...)
  2017-12-05 15:10 ` [PATCH v3 09/15] drm/sun4i: Add A83T support Maxime Ripard
@ 2017-12-05 15:10 ` Maxime Ripard
       [not found]   ` <97d3cee9d0d7a92893f646d72643bac520de5f05.1512486553.git-series.maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
  2017-12-05 15:10 ` [PATCH v3 11/15] ARM: dts: sun8i: a83t: Enable the PWM Maxime Ripard
                   ` (3 subsequent siblings)
  12 siblings, 1 reply; 33+ messages in thread
From: Maxime Ripard @ 2017-12-05 15:10 UTC (permalink / raw)
  To: Daniel Vetter, David Airlie, Chen-Yu Tsai, Maxime Ripard
  Cc: Mark Rutland, Thomas Petazzoni, jernej.skrabec, plaes,
	devicetree, linux-kernel, dri-devel, Rob Herring,
	linux-arm-kernel, icenowy

The display pipeline on the A83T is mainly composed of the mixers and
TCONs, plus various encoders.

Let's add the first mixer and TCON to the DTSI since the only board I have
can use only the LVDS output on the first TCON. The other parts will be
added eventually.

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 arch/arm/boot/dts/sun8i-a83t.dtsi | 79 ++++++++++++++++++++++++++++++++-
 1 file changed, 79 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi
index 19acae1b4089..e4db38c717d9 100644
--- a/arch/arm/boot/dts/sun8i-a83t.dtsi
+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi
@@ -45,8 +45,10 @@
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 
 #include <dt-bindings/clock/sun8i-a83t-ccu.h>
+#include <dt-bindings/clock/sun8i-de2.h>
 #include <dt-bindings/clock/sun8i-r-ccu.h>
 #include <dt-bindings/reset/sun8i-a83t-ccu.h>
+#include <dt-bindings/reset/sun8i-de2.h>
 #include <dt-bindings/reset/sun8i-r-ccu.h>
 
 / {
@@ -151,6 +153,12 @@
 		};
 	};
 
+	de: display-engine {
+		compatible = "allwinner,sun8i-a83t-display-engine";
+		allwinner,pipelines = <&mixer0>;
+		status = "disabled";
+	};
+
 	memory {
 		reg = <0x40000000 0x80000000>;
 		device_type = "memory";
@@ -162,6 +170,44 @@
 		#size-cells = <1>;
 		ranges;
 
+		display_clocks: clock@1000000 {
+			compatible = "allwinner,sun8i-a83t-de2-clk";
+			reg = <0x01000000 0x100000>;
+			clocks = <&ccu CLK_PLL_DE>,
+				 <&ccu CLK_BUS_DE>;
+			clock-names = "mod",
+				      "bus";
+			resets = <&ccu RST_BUS_DE>;
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+		};
+
+		mixer0: mixer@1100000 {
+			compatible = "allwinner,sun8i-a83t-de2-mixer-0";
+			reg = <0x01100000 0x100000>;
+			clocks = <&display_clocks CLK_BUS_MIXER0>,
+				 <&display_clocks CLK_MIXER0>;
+			clock-names = "bus",
+				      "mod";
+			resets = <&display_clocks RST_MIXER0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				mixer0_out: port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+
+					mixer0_out_tcon0: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&tcon0_in_mixer0>;
+					};
+				};
+			};
+		};
+
 		syscon: syscon@1c00000 {
 			compatible = "allwinner,sun8i-a83t-system-controller",
 				"syscon";
@@ -177,6 +223,39 @@
 			#dma-cells = <1>;
 		};
 
+		tcon0: lcd-controller@1c0c000 {
+			compatible = "allwinner,sun8i-a83t-tcon-lcd";
+			reg = <0x01c0c000 0x1000>;
+			interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_TCON0>, <&ccu CLK_TCON0>;
+			clock-names = "ahb", "tcon-ch0";
+			clock-output-names = "tcon-pixel-clock";
+			resets = <&ccu RST_BUS_TCON0>, <&ccu RST_BUS_LVDS>;
+			reset-names = "lcd", "lvds";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				tcon0_in: port@0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+
+					tcon0_in_mixer0: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&mixer0_out_tcon0>;
+					};
+				};
+
+				tcon0_out: port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+				};
+			};
+		};
+
 		mmc0: mmc@1c0f000 {
 			compatible = "allwinner,sun8i-a83t-mmc",
 				     "allwinner,sun7i-a20-mmc";
-- 
git-series 0.9.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v3 11/15] ARM: dts: sun8i: a83t: Enable the PWM
  2017-12-05 15:10 [PATCH v3 00/15] drm/sun4i: Add A83t LVDS support Maxime Ripard
                   ` (8 preceding siblings ...)
  2017-12-05 15:10 ` [PATCH v3 10/15] ARM: dts: sun8i: a83t: Add display pipeline Maxime Ripard
@ 2017-12-05 15:10 ` Maxime Ripard
  2017-12-05 15:10 ` [PATCH v3 12/15] ARM: dts: sun8i: a83t: Add LVDS pins group Maxime Ripard
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 33+ messages in thread
From: Maxime Ripard @ 2017-12-05 15:10 UTC (permalink / raw)
  To: Daniel Vetter, David Airlie, Chen-Yu Tsai, Maxime Ripard
  Cc: Mark Rutland, Thomas Petazzoni, jernej.skrabec, plaes,
	devicetree, linux-kernel, dri-devel, Rob Herring,
	linux-arm-kernel, icenowy

The A83T has the same PWM block than the H3. Add it to our DT.

Reviewed-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 arch/arm/boot/dts/sun8i-a83t.dtsi |  9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi
index e4db38c717d9..7a49b9f085eb 100644
--- a/arch/arm/boot/dts/sun8i-a83t.dtsi
+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi
@@ -497,6 +497,15 @@
 			status = "disabled";
 		};
 
+		pwm: pwm@1c21400 {
+			compatible = "allwinner,sun8i-a83t-pwm",
+				     "allwinner,sun8i-h3-pwm";
+			reg = <0x01c21400 0x400>;
+			clocks = <&osc24M>;
+			#pwm-cells = <3>;
+			status = "disabled";
+		};
+
 		uart0: serial@1c28000 {
 			compatible = "snps,dw-apb-uart";
 			reg = <0x01c28000 0x400>;
-- 
git-series 0.9.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v3 12/15] ARM: dts: sun8i: a83t: Add LVDS pins group
  2017-12-05 15:10 [PATCH v3 00/15] drm/sun4i: Add A83t LVDS support Maxime Ripard
                   ` (9 preceding siblings ...)
  2017-12-05 15:10 ` [PATCH v3 11/15] ARM: dts: sun8i: a83t: Enable the PWM Maxime Ripard
@ 2017-12-05 15:10 ` Maxime Ripard
  2017-12-05 15:10 ` [PATCH v3 13/15] ARM: dts: sun8i: a83t: Add the PWM pin group Maxime Ripard
  2017-12-05 15:10 ` [PATCH v3 15/15] ARM: dts: sun8i: a711: Enable the LCD Maxime Ripard
  12 siblings, 0 replies; 33+ messages in thread
From: Maxime Ripard @ 2017-12-05 15:10 UTC (permalink / raw)
  To: Daniel Vetter, David Airlie, Chen-Yu Tsai, Maxime Ripard
  Cc: Mark Rutland, Thomas Petazzoni, jernej.skrabec, plaes,
	devicetree, linux-kernel, dri-devel, Rob Herring,
	linux-arm-kernel, icenowy

The A83T has an LVDS bus that can be connected to a panel or a bridge. Add
the pinctrl group for it.

Reviewed-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 arch/arm/boot/dts/sun8i-a83t.dtsi | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi
index 7a49b9f085eb..e200df5a9058 100644
--- a/arch/arm/boot/dts/sun8i-a83t.dtsi
+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi
@@ -415,6 +415,12 @@
 			#interrupt-cells = <3>;
 			#gpio-cells = <3>;
 
+			lcd_lvds_pins: lcd-lvds-pins {
+				pins = "PD18", "PD19", "PD20", "PD21", "PD22",
+				       "PD23", "PD24", "PD25", "PD26", "PD27";
+				function = "lvds0";
+			};
+
 			mmc0_pins: mmc0-pins {
 				pins = "PF0", "PF1", "PF2",
 				       "PF3", "PF4", "PF5";
-- 
git-series 0.9.1

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v3 13/15] ARM: dts: sun8i: a83t: Add the PWM pin group
  2017-12-05 15:10 [PATCH v3 00/15] drm/sun4i: Add A83t LVDS support Maxime Ripard
                   ` (10 preceding siblings ...)
  2017-12-05 15:10 ` [PATCH v3 12/15] ARM: dts: sun8i: a83t: Add LVDS pins group Maxime Ripard
@ 2017-12-05 15:10 ` Maxime Ripard
  2017-12-05 15:10 ` [PATCH v3 15/15] ARM: dts: sun8i: a711: Enable the LCD Maxime Ripard
  12 siblings, 0 replies; 33+ messages in thread
From: Maxime Ripard @ 2017-12-05 15:10 UTC (permalink / raw)
  To: Daniel Vetter, David Airlie, Chen-Yu Tsai, Maxime Ripard
  Cc: Mark Rutland, Thomas Petazzoni, jernej.skrabec, plaes,
	devicetree, linux-kernel, dri-devel, Rob Herring,
	linux-arm-kernel, icenowy

The A83T has a PWM that can be output from the SoC. Let's add a pinctrl
group for it.

Reviewed-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 arch/arm/boot/dts/sun8i-a83t.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi
index e200df5a9058..a37517d4472a 100644
--- a/arch/arm/boot/dts/sun8i-a83t.dtsi
+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi
@@ -446,6 +446,11 @@
 				bias-pull-up;
 			};
 
+			pwm_pin: pwm-pin {
+				pins = "PD28";
+				function = "pwm";
+			};
+
 			spdif_tx_pin: spdif-tx-pin {
 				pins = "PE18";
 				function = "spdif";
-- 
git-series 0.9.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v3 14/15] ARM: dts: sun8i: a711: Reinstate the PMIC compatible
       [not found] ` <cover.825a49a4c1c565a548f3de0375e7537e7e8fd3a4.1512486553.git-series.maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
  2017-12-05 15:10   ` [PATCH v3 02/15] drm/panel: lvds: Add support for the power-supply property Maxime Ripard
  2017-12-05 15:10   ` [PATCH v3 08/15] drm/sun4i: Add LVDS support Maxime Ripard
@ 2017-12-05 15:10   ` Maxime Ripard
       [not found]     ` <25b482f19587ff195582995c11ee9d07f5bf42d2.1512486553.git-series.maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
  2 siblings, 1 reply; 33+ messages in thread
From: Maxime Ripard @ 2017-12-05 15:10 UTC (permalink / raw)
  To: Daniel Vetter, David Airlie, Chen-Yu Tsai, Maxime Ripard
  Cc: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Mark Rutland, Rob Herring,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	plaes-q/aMd4JkU83YtjvyW6yDsg, icenowy-h8G6r0blFSE,
	Thomas Petazzoni, jernej.skrabec-gGgVlfcn5nU,
	devicetree-u79uwXL29TY76Z2rM5mHXA

When we added the regulator support in commit 90c5d7cdae64 ("ARM: dts:
sun8i: a711: Add regulator support"), we also dropped the PMIC's
compatible. Since it's not in the PMIC DTSI, unlike most other PMIC
DTSI, it obviously wasn't probing anymore.

Re-add it so that everything works again.

Fixes: 90c5d7cdae64 ("ARM: dts: sun8i: a711: Add regulator support")
Signed-off-by: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
---
 arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
index 98715538932f..a021ee6da396 100644
--- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
+++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
@@ -146,6 +146,7 @@
 	status = "okay";
 
 	axp81x: pmic@3a3 {
+		compatible = "x-powers,axp813";
 		reg = <0x3a3>;
 		interrupt-parent = <&r_intc>;
 		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
-- 
git-series 0.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v3 15/15] ARM: dts: sun8i: a711: Enable the LCD
  2017-12-05 15:10 [PATCH v3 00/15] drm/sun4i: Add A83t LVDS support Maxime Ripard
                   ` (11 preceding siblings ...)
  2017-12-05 15:10 ` [PATCH v3 13/15] ARM: dts: sun8i: a83t: Add the PWM pin group Maxime Ripard
@ 2017-12-05 15:10 ` Maxime Ripard
  12 siblings, 0 replies; 33+ messages in thread
From: Maxime Ripard @ 2017-12-05 15:10 UTC (permalink / raw)
  To: Daniel Vetter, David Airlie, Chen-Yu Tsai, Maxime Ripard
  Cc: Mark Rutland, Thomas Petazzoni, jernej.skrabec, plaes,
	devicetree, linux-kernel, dri-devel, Rob Herring,
	linux-arm-kernel, icenowy

The A711 has 1024x600 LVDS panel, with a PWM-based backlight. Add it to our
DT.

Reviewed-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts | 61 ++++++++++++++++++++++++-
 1 file changed, 61 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
index a021ee6da396..511fca491fe8 100644
--- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
+++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
@@ -45,6 +45,7 @@
 #include "sun8i-a83t.dtsi"
 
 #include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pwm/pwm.h>
 
 / {
 	model = "TBS A711 Tablet";
@@ -59,6 +60,44 @@
 		stdout-path = "serial0:115200n8";
 	};
 
+	backlight: backlight {
+		compatible = "pwm-backlight";
+		pwms = <&pwm 0 50000 PWM_POLARITY_INVERTED>;
+		enable-gpios = <&pio 3 29 GPIO_ACTIVE_HIGH>;
+
+		brightness-levels = <0 1 2 4 8 16 32 64 128 255>;
+		default-brightness-level = <9>;
+	};
+
+	panel {
+		compatible = "tbs,a711-panel", "panel-lvds";
+		backlight = <&backlight>;
+		power-supply = <&reg_sw>;
+
+		width-mm = <153>;
+		height-mm = <90>;
+		data-mapping = "vesa-24";
+
+		panel-timing {
+			/* 1024x600 @60Hz */
+			clock-frequency = <52000000>;
+			hactive = <1024>;
+			vactive = <600>;
+			hsync-len = <20>;
+			hfront-porch = <180>;
+			hback-porch = <160>;
+			vfront-porch = <12>;
+			vback-porch = <23>;
+			vsync-len = <5>;
+		};
+
+		port {
+			panel_input: endpoint {
+				remote-endpoint = <&tcon0_out_lcd>;
+			};
+		};
+	};
+
 	reg_vbat: reg-vbat {
 		compatible = "regulator-fixed";
 		regulator-name = "vbat";
@@ -89,6 +128,10 @@
 	};
 };
 
+&de {
+	status = "okay";
+};
+
 /*
  * An USB-2 hub is connected here, which also means we don't need to
  * enable the OHCI controller.
@@ -142,6 +185,12 @@
 	status = "okay";
 };
 
+&pwm {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pwm_pin>;
+	status = "okay";
+};
+
 &r_rsb {
 	status = "okay";
 
@@ -323,6 +372,18 @@
 	regulator-name = "vcc-lcd";
 };
 
+&tcon0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&lcd_lvds_pins>;
+};
+
+&tcon0_out {
+	tcon0_out_lcd: endpoint@0 {
+		reg = <0>;
+		remote-endpoint = <&panel_input>;
+	};
+};
+
 &uart0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart0_pb_pins>;
-- 
git-series 0.9.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* Re: [PATCH v3 05/15] drm/sun4i: Fix error path handling
       [not found]   ` <1f2443c41082fc6e086570da38d20744c52fe636.1512486553.git-series.maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
@ 2017-12-05 15:42     ` Chen-Yu Tsai
  0 siblings, 0 replies; 33+ messages in thread
From: Chen-Yu Tsai @ 2017-12-05 15:42 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Daniel Vetter, David Airlie, Chen-Yu Tsai, dri-devel,
	linux-kernel, Mark Rutland, Rob Herring, linux-arm-kernel,
	Priit Laes, Icenowy Zheng, Thomas Petazzoni, Jernej Skrabec,
	devicetree, stable

On Tue, Dec 5, 2017 at 11:10 PM, Maxime Ripard
<maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org> wrote:
> The commit 4c7f16d14a33 ("drm/sun4i: Fix TCON clock and regmap
> initialization sequence") moved a bunch of logic around, but forgot to
> update the gotos after the introduction of the err_free_dotclock label.
>
> It means that if we fail later that the one introduced in that commit,
> we'll just to the old label which isn't free the clock we created. This
> will result in a breakage as soon as someone tries to do something with
> that clock, since its resources will have been long reclaimed.
>
> Cc: <stable-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>
> Fixes: 4c7f16d14a33 ("drm/sun4i: Fix TCON clock and regmap initialization sequence")
> Signed-off-by: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>

Thanks.

I think this was reported, or I noticed it after the patch was merged,
but then I got busy with other stuff.

Reviewed-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v3 09/15] drm/sun4i: Add A83T support
  2017-12-05 15:10 ` [PATCH v3 09/15] drm/sun4i: Add A83T support Maxime Ripard
@ 2017-12-05 15:42   ` Jernej Škrabec
  2017-12-06 16:37     ` Jernej Škrabec
  0 siblings, 1 reply; 33+ messages in thread
From: Jernej Škrabec @ 2017-12-05 15:42 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Daniel Vetter, David Airlie, Chen-Yu Tsai, dri-devel,
	linux-kernel, Mark Rutland, Rob Herring, linux-arm-kernel, plaes,
	icenowy, Thomas Petazzoni, devicetree

Hi Maxime,

Dne torek, 05. december 2017 ob 16:10:21 CET je Maxime Ripard napisal(a):
> Add support for the A83T display pipeline.
> 
> Reviewed-by: Chen-Yu Tsai <wens@csie.org>
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> ---
>  drivers/gpu/drm/sun4i/sun4i_drv.c   |  1 +
>  drivers/gpu/drm/sun4i/sun4i_tcon.c  |  5 +++++
>  drivers/gpu/drm/sun4i/sun8i_mixer.c |  9 +++++++++
>  3 files changed, 15 insertions(+)
> 
> diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c
> b/drivers/gpu/drm/sun4i/sun4i_drv.c index 49215d91c853..6f5e721b545e 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_drv.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
> @@ -347,6 +347,7 @@ static const struct of_device_id sun4i_drv_of_table[] =
> { { .compatible = "allwinner,sun6i-a31s-display-engine" },
>  	{ .compatible = "allwinner,sun7i-a20-display-engine" },
>  	{ .compatible = "allwinner,sun8i-a33-display-engine" },
> +	{ .compatible = "allwinner,sun8i-a83t-display-engine" },
>  	{ .compatible = "allwinner,sun8i-v3s-display-engine" },
>  	{ }
>  };
> diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> b/drivers/gpu/drm/sun4i/sun4i_tcon.c index 92f4738101e6..9b757450555f
> 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> @@ -1132,6 +1132,10 @@ static const struct sun4i_tcon_quirks
> sun8i_a33_quirks = { .has_lvds_pll		= true,
>  };
> 
> +static const struct sun4i_tcon_quirks sun8i_a83t_lcd_quirks = {
> +	/* nothing is supported */
> +};
> +
>  static const struct sun4i_tcon_quirks sun8i_v3s_quirks = {
>  	/* nothing is supported */
>  };
> @@ -1144,6 +1148,7 @@ const struct of_device_id sun4i_tcon_of_table[] = {
>  	{ .compatible = "allwinner,sun6i-a31s-tcon", .data = &sun6i_a31s_quirks },
> { .compatible = "allwinner,sun7i-a20-tcon", .data = &sun7i_a20_quirks }, {
> .compatible = "allwinner,sun8i-a33-tcon", .data = &sun8i_a33_quirks }, +	{
> .compatible = "allwinner,sun8i-a83t-tcon-lcd", .data =
> &sun8i_a83t_lcd_quirks }, { .compatible = "allwinner,sun8i-v3s-tcon", .data
> = &sun8i_v3s_quirks }, { }
>  };
> diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c
> b/drivers/gpu/drm/sun4i/sun8i_mixer.c index ff235e3228ce..6829bec4ba68
> 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
> +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
> @@ -477,6 +477,11 @@ static int sun8i_mixer_remove(struct platform_device
> *pdev) return 0;
>  }
> 
> +static const struct sun8i_mixer_cfg sun8i_a83t_mixer_cfg = {
> +	.vi_num = 1,
> +	.ui_num = 3,
> +};
> +

I think you should expand that structure with:
.ccsc = 0,
.scaler_mask = 0xf,
.mod_rate = 150000000,

Best regards,
Jernej

>  static const struct sun8i_mixer_cfg sun8i_v3s_mixer_cfg = {
>  	.vi_num = 2,
>  	.ui_num = 1,
> @@ -487,6 +492,10 @@ static const struct sun8i_mixer_cfg sun8i_v3s_mixer_cfg
> = {
> 
>  static const struct of_device_id sun8i_mixer_of_table[] = {
>  	{
> +		.compatible = "allwinner,sun8i-a83t-de2-mixer-0",
> +		.data = &sun8i_a83t_mixer_cfg,
> +	},
> +	{
>  		.compatible = "allwinner,sun8i-v3s-de2-mixer",
>  		.data = &sun8i_v3s_mixer_cfg,
>  	},
> --
> git-series 0.9.1

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v3 09/15] drm/sun4i: Add A83T support
  2017-12-05 15:42   ` Jernej Škrabec
@ 2017-12-06 16:37     ` Jernej Škrabec
  2017-12-07 10:55       ` Maxime Ripard
  0 siblings, 1 reply; 33+ messages in thread
From: Jernej Škrabec @ 2017-12-06 16:37 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Daniel Vetter, David Airlie, Chen-Yu Tsai, dri-devel,
	linux-kernel, Mark Rutland, Rob Herring, linux-arm-kernel, plaes,
	icenowy, Thomas Petazzoni, devicetree

Hi,

Dne torek, 05. december 2017 ob 16:42:55 CET je Jernej Škrabec napisal(a):
> Hi Maxime,
> 
> Dne torek, 05. december 2017 ob 16:10:21 CET je Maxime Ripard napisal(a):
> > Add support for the A83T display pipeline.
> > 
> > Reviewed-by: Chen-Yu Tsai <wens@csie.org>
> > Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> > ---
> > 
> >  drivers/gpu/drm/sun4i/sun4i_drv.c   |  1 +
> >  drivers/gpu/drm/sun4i/sun4i_tcon.c  |  5 +++++
> >  drivers/gpu/drm/sun4i/sun8i_mixer.c |  9 +++++++++
> >  3 files changed, 15 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c
> > b/drivers/gpu/drm/sun4i/sun4i_drv.c index 49215d91c853..6f5e721b545e
> > 100644
> > --- a/drivers/gpu/drm/sun4i/sun4i_drv.c
> > +++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
> > @@ -347,6 +347,7 @@ static const struct of_device_id sun4i_drv_of_table[]
> > =
> > { { .compatible = "allwinner,sun6i-a31s-display-engine" },
> > 
> >  	{ .compatible = "allwinner,sun7i-a20-display-engine" },
> >  	{ .compatible = "allwinner,sun8i-a33-display-engine" },
> > 
> > +	{ .compatible = "allwinner,sun8i-a83t-display-engine" },
> > 
> >  	{ .compatible = "allwinner,sun8i-v3s-display-engine" },
> >  	{ }
> >  
> >  };
> > 
> > diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > b/drivers/gpu/drm/sun4i/sun4i_tcon.c index 92f4738101e6..9b757450555f
> > 100644
> > --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > @@ -1132,6 +1132,10 @@ static const struct sun4i_tcon_quirks
> > sun8i_a33_quirks = { .has_lvds_pll		= true,
> > 
> >  };
> > 
> > +static const struct sun4i_tcon_quirks sun8i_a83t_lcd_quirks = {
> > +	/* nothing is supported */
> > +};
> > +
> > 
> >  static const struct sun4i_tcon_quirks sun8i_v3s_quirks = {
> >  
> >  	/* nothing is supported */
> >  
> >  };
> > 
> > @@ -1144,6 +1148,7 @@ const struct of_device_id sun4i_tcon_of_table[] = {
> > 
> >  	{ .compatible = "allwinner,sun6i-a31s-tcon", .data = 
&sun6i_a31s_quirks
> >  	},
> > 
> > { .compatible = "allwinner,sun7i-a20-tcon", .data = &sun7i_a20_quirks }, {
> > .compatible = "allwinner,sun8i-a33-tcon", .data = &sun8i_a33_quirks }, +	
{
> > .compatible = "allwinner,sun8i-a83t-tcon-lcd", .data =
> > &sun8i_a83t_lcd_quirks }, { .compatible = "allwinner,sun8i-v3s-tcon",
> > .data
> > = &sun8i_v3s_quirks }, { }
> > 
> >  };
> > 
> > diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c
> > b/drivers/gpu/drm/sun4i/sun8i_mixer.c index ff235e3228ce..6829bec4ba68
> > 100644
> > --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
> > +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
> > @@ -477,6 +477,11 @@ static int sun8i_mixer_remove(struct platform_device
> > *pdev) return 0;
> > 
> >  }
> > 
> > +static const struct sun8i_mixer_cfg sun8i_a83t_mixer_cfg = {
> > +	.vi_num = 1,
> > +	.ui_num = 3,
> > +};
> > +
> 
> I think you should expand that structure with:
> .ccsc = 0,
> .scaler_mask = 0xf,
> .mod_rate = 150000000,

I guess you could set higher clock if CLK_SET_RATE_PARENT flag is set to de_clk 
in A83T CCU driver. BSP sets it to 500 MHz, which is a bit high...

Best regards,
Jernej

> 
> Best regards,
> Jernej
> 
> >  static const struct sun8i_mixer_cfg sun8i_v3s_mixer_cfg = {
> >  
> >  	.vi_num = 2,
> >  	.ui_num = 1,
> > 
> > @@ -487,6 +492,10 @@ static const struct sun8i_mixer_cfg
> > sun8i_v3s_mixer_cfg = {
> > 
> >  static const struct of_device_id sun8i_mixer_of_table[] = {
> >  
> >  	{
> > 
> > +		.compatible = "allwinner,sun8i-a83t-de2-mixer-0",
> > +		.data = &sun8i_a83t_mixer_cfg,
> > +	},
> > +	{
> > 
> >  		.compatible = "allwinner,sun8i-v3s-de2-mixer",
> >  		.data = &sun8i_v3s_mixer_cfg,
> >  	
> >  	},
> > 
> > --
> > git-series 0.9.1

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v3 01/15] dt-bindings: panel: lvds: Document power-supply property
       [not found]   ` <97ebf0615821d79e8d7718594fe3a542a743a05f.1512486553.git-series.maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
@ 2017-12-06 21:56     ` Rob Herring
  0 siblings, 0 replies; 33+ messages in thread
From: Rob Herring @ 2017-12-06 21:56 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Daniel Vetter, David Airlie, Chen-Yu Tsai,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Mark Rutland,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	plaes-q/aMd4JkU83YtjvyW6yDsg, icenowy-h8G6r0blFSE,
	Thomas Petazzoni, jernej.skrabec-gGgVlfcn5nU,
	devicetree-u79uwXL29TY76Z2rM5mHXA

On Tue, Dec 05, 2017 at 04:10:13PM +0100, Maxime Ripard wrote:
> The power-supply property is used by a vast majority of panels, including
> panel-simple. Let's document it as a common property
> 
> Signed-off-by: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
> ---
>  Documentation/devicetree/bindings/display/panel/panel-common.txt | 6 ++++++
>  Documentation/devicetree/bindings/display/panel/panel-lvds.txt   | 1 +
>  Documentation/devicetree/bindings/display/panel/simple-panel.txt | 2 +-
>  3 files changed, 8 insertions(+), 1 deletion(-)

Reviewed-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v3 03/15] dt-bindings: display: sun4i-drm: Add LVDS properties
       [not found]   ` <17851ba6277b69aa9cd81de5eead62bfed271661.1512486553.git-series.maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
@ 2017-12-06 21:57     ` Rob Herring
  2017-12-07  3:57     ` Chen-Yu Tsai
  1 sibling, 0 replies; 33+ messages in thread
From: Rob Herring @ 2017-12-06 21:57 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Daniel Vetter, David Airlie, Chen-Yu Tsai,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Mark Rutland,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	plaes-q/aMd4JkU83YtjvyW6yDsg, icenowy-h8G6r0blFSE,
	Thomas Petazzoni, jernej.skrabec-gGgVlfcn5nU,
	devicetree-u79uwXL29TY76Z2rM5mHXA

On Tue, Dec 05, 2017 at 04:10:15PM +0100, Maxime Ripard wrote:
> Some clocks and resets supposed to drive the LVDS logic in the display
> engine have been overlooked when the driver was first introduced.
> 
> Add those additional resources to the binding, and we'll deal with the ABI
> stability in the code.
> 
> Signed-off-by: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
> ---
>  Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt | 8 +++++++-
>  1 file changed, 8 insertions(+)

Reviewed-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v3 04/15] dt-bindings: display: sun4i-drm: Add A83T pipeline
       [not found]   ` <3762a8428aaf207e80ae86d4db2e50473576bb6d.1512486553.git-series.maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
@ 2017-12-06 21:59     ` Rob Herring
  2017-12-07  3:37       ` Chen-Yu Tsai
  0 siblings, 1 reply; 33+ messages in thread
From: Rob Herring @ 2017-12-06 21:59 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Daniel Vetter, David Airlie, Chen-Yu Tsai,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Mark Rutland,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	plaes-q/aMd4JkU83YtjvyW6yDsg, icenowy-h8G6r0blFSE,
	Thomas Petazzoni, jernej.skrabec-gGgVlfcn5nU,
	devicetree-u79uwXL29TY76Z2rM5mHXA

On Tue, Dec 05, 2017 at 04:10:16PM +0100, Maxime Ripard wrote:
> The A83T has two video pipelines in parallel that looks quite similar to
> the other SoCs.
> 
> The video planes are handled through a controller called the mixer, and the
> video signal is then passed to the timing controller (TCON).
> 
> And while there is two instances of the mixers and TCONs, they have a
> significant number of differences. The TCONs are quite easy to deal with,
> one is supposed to generate TV (in the broader term, so including things
> like HDMI) signals, the other one LCD (so RGB, LVDS, DSI) signals. And
> while they are called TCON0 and TCON1 in the A83t datasheet, newer SoCs
> call them TCON-TV and TCON-LCD, which seems more appropriate.
> 
> However, the mixers differ mostly by their capabilities, with some features
> being available only in the first one, or the number of planes they expose,
> but also through their register layout. And while the capabilities could be
> represented as properties, the register layout differences would need to
> express all the registers offsets as properties, which is usually quite
> bad. Especially since documentation on that hardware block is close to
> non-existant and we don't even have the list of all those registers in the
> first place.
> 
> So let's call them mixer 0 and 1 in our compatibles, even though the name
> is pretty bad...
> 
> At the moment, we only have tested the code on a board that has a single
> display output, so we're leaving the tcon-tv and mixer1 out.
> 
> Signed-off-by: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
> ---
>  Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt | 3 +++
>  1 file changed, 3 insertions(+)

Reviewed-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v3 14/15] ARM: dts: sun8i: a711: Reinstate the PMIC compatible
       [not found]     ` <25b482f19587ff195582995c11ee9d07f5bf42d2.1512486553.git-series.maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
@ 2017-12-07  3:34       ` Chen-Yu Tsai
  0 siblings, 0 replies; 33+ messages in thread
From: Chen-Yu Tsai @ 2017-12-07  3:34 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Daniel Vetter, David Airlie, Chen-Yu Tsai, dri-devel,
	linux-kernel, Mark Rutland, Rob Herring, linux-arm-kernel,
	Priit Laes, Icenowy Zheng, Thomas Petazzoni, Jernej Skrabec,
	devicetree

On Tue, Dec 5, 2017 at 11:10 PM, Maxime Ripard
<maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org> wrote:
> When we added the regulator support in commit 90c5d7cdae64 ("ARM: dts:
> sun8i: a711: Add regulator support"), we also dropped the PMIC's
> compatible. Since it's not in the PMIC DTSI, unlike most other PMIC
> DTSI, it obviously wasn't probing anymore.
>
> Re-add it so that everything works again.
>
> Fixes: 90c5d7cdae64 ("ARM: dts: sun8i: a711: Add regulator support")
> Signed-off-by: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>

Reviewed-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v3 04/15] dt-bindings: display: sun4i-drm: Add A83T pipeline
  2017-12-06 21:59     ` Rob Herring
@ 2017-12-07  3:37       ` Chen-Yu Tsai
  0 siblings, 0 replies; 33+ messages in thread
From: Chen-Yu Tsai @ 2017-12-07  3:37 UTC (permalink / raw)
  To: Rob Herring
  Cc: Maxime Ripard, Daniel Vetter, David Airlie, Chen-Yu Tsai,
	dri-devel, linux-kernel, Mark Rutland, linux-arm-kernel,
	Priit Laes, Icenowy Zheng, Thomas Petazzoni, Jernej Skrabec,
	devicetree

On Thu, Dec 7, 2017 at 5:59 AM, Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
> On Tue, Dec 05, 2017 at 04:10:16PM +0100, Maxime Ripard wrote:
>> The A83T has two video pipelines in parallel that looks quite similar to
>> the other SoCs.
>>
>> The video planes are handled through a controller called the mixer, and the
>> video signal is then passed to the timing controller (TCON).
>>
>> And while there is two instances of the mixers and TCONs, they have a
>> significant number of differences. The TCONs are quite easy to deal with,
>> one is supposed to generate TV (in the broader term, so including things
>> like HDMI) signals, the other one LCD (so RGB, LVDS, DSI) signals. And
>> while they are called TCON0 and TCON1 in the A83t datasheet, newer SoCs
>> call them TCON-TV and TCON-LCD, which seems more appropriate.
>>
>> However, the mixers differ mostly by their capabilities, with some features
>> being available only in the first one, or the number of planes they expose,
>> but also through their register layout. And while the capabilities could be
>> represented as properties, the register layout differences would need to
>> express all the registers offsets as properties, which is usually quite
>> bad. Especially since documentation on that hardware block is close to
>> non-existant and we don't even have the list of all those registers in the
>> first place.
>>
>> So let's call them mixer 0 and 1 in our compatibles, even though the name
>> is pretty bad...
>>
>> At the moment, we only have tested the code on a board that has a single
>> display output, so we're leaving the tcon-tv and mixer1 out.
>>
>> Signed-off-by: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
>> ---
>>  Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt | 3 +++
>>  1 file changed, 3 insertions(+)
>
> Reviewed-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>

Reviewed-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v3 03/15] dt-bindings: display: sun4i-drm: Add LVDS properties
       [not found]   ` <17851ba6277b69aa9cd81de5eead62bfed271661.1512486553.git-series.maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
  2017-12-06 21:57     ` Rob Herring
@ 2017-12-07  3:57     ` Chen-Yu Tsai
  1 sibling, 0 replies; 33+ messages in thread
From: Chen-Yu Tsai @ 2017-12-07  3:57 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Daniel Vetter, David Airlie, Chen-Yu Tsai, dri-devel,
	linux-kernel, Mark Rutland, Rob Herring, linux-arm-kernel,
	Priit Laes, Icenowy Zheng, Thomas Petazzoni, Jernej Skrabec,
	devicetree

On Tue, Dec 5, 2017 at 11:10 PM, Maxime Ripard
<maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org> wrote:
> Some clocks and resets supposed to drive the LVDS logic in the display
> engine have been overlooked when the driver was first introduced.
>
> Add those additional resources to the binding, and we'll deal with the ABI
> stability in the code.
>
> Signed-off-by: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
> ---
>  Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt | 8 +++++++-
>  1 file changed, 8 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
> index 50cc72ee1168..d4259a4f5171 100644
> --- a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
> +++ b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
> @@ -121,6 +121,14 @@ Required properties:
>  On SoCs other than the A33 and V3s, there is one more clock required:
>     - 'tcon-ch1': The clock driving the TCON channel 1
>
> +On SoCs that support LVDS (all SoCs but the A13, H3, H5 and V3s), you
> +need one more reset line:
> +   - 'lvds': The reset line driving the LVDS logic
> +
> +And on the SoCs newer than the A31 (sun6i and sun8i families), you
> +need one more clock line:
> +   - 'lvds-pll': The PLL that can be used to drive the LVDS clock

Is this referring to TCON0_LVDS_Clk_Sel, which can use the MIPI PLL
on the A33? Maybe the description should be more clear, like:

  - 'lvds-alt': An alternative clock separate from the TCON
                that can be used to drive the LVDS clock.

ChenYu

> +
>  DRC
>  ---
>
> --
> git-series 0.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v3 10/15] ARM: dts: sun8i: a83t: Add display pipeline
       [not found]   ` <97d3cee9d0d7a92893f646d72643bac520de5f05.1512486553.git-series.maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
@ 2017-12-07  4:02     ` Chen-Yu Tsai
  0 siblings, 0 replies; 33+ messages in thread
From: Chen-Yu Tsai @ 2017-12-07  4:02 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Daniel Vetter, David Airlie, Chen-Yu Tsai, dri-devel,
	linux-kernel, Mark Rutland, Rob Herring, linux-arm-kernel,
	Priit Laes, Icenowy Zheng, Thomas Petazzoni, Jernej Skrabec,
	devicetree

On Tue, Dec 5, 2017 at 11:10 PM, Maxime Ripard
<maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org> wrote:
> The display pipeline on the A83T is mainly composed of the mixers and
> TCONs, plus various encoders.
>
> Let's add the first mixer and TCON to the DTSI since the only board I have
> can use only the LVDS output on the first TCON. The other parts will be
> added eventually.
>
> Signed-off-by: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>

Reviewed-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v3 08/15] drm/sun4i: Add LVDS support
       [not found]     ` <b900e5963180c94ca02bde178b6674622a127787.1512486553.git-series.maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
@ 2017-12-07  6:05       ` Chen-Yu Tsai
  2017-12-07 12:25         ` Maxime Ripard
  0 siblings, 1 reply; 33+ messages in thread
From: Chen-Yu Tsai @ 2017-12-07  6:05 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Daniel Vetter, David Airlie, Chen-Yu Tsai, dri-devel,
	linux-kernel, Mark Rutland, Rob Herring, linux-arm-kernel,
	Priit Laes, Icenowy Zheng, Thomas Petazzoni, Jernej Skrabec,
	devicetree

On Tue, Dec 5, 2017 at 11:10 PM, Maxime Ripard
<maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org> wrote:
> The TCON supports the LVDS interface to output to a panel or a bridge.
> Let's add support for it.
>
> Signed-off-by: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
> ---
>  drivers/gpu/drm/sun4i/Makefile     |   1 +-
>  drivers/gpu/drm/sun4i/sun4i_lvds.c | 183 +++++++++++++++++++++++-
>  drivers/gpu/drm/sun4i/sun4i_lvds.h |  18 ++-
>  drivers/gpu/drm/sun4i/sun4i_tcon.c | 238 +++++++++++++++++++++++++++++-
>  drivers/gpu/drm/sun4i/sun4i_tcon.h |  29 ++++-
>  5 files changed, 467 insertions(+), 2 deletions(-)
>  create mode 100644 drivers/gpu/drm/sun4i/sun4i_lvds.c
>  create mode 100644 drivers/gpu/drm/sun4i/sun4i_lvds.h
>
> diff --git a/drivers/gpu/drm/sun4i/Makefile b/drivers/gpu/drm/sun4i/Makefile
> index 82a6ac57fbe3..2b37a6abbb1d 100644
> --- a/drivers/gpu/drm/sun4i/Makefile
> +++ b/drivers/gpu/drm/sun4i/Makefile
> @@ -15,6 +15,7 @@ sun8i-mixer-y                 += sun8i_mixer.o sun8i_ui_layer.o \
>
>  sun4i-tcon-y                   += sun4i_crtc.o
>  sun4i-tcon-y                   += sun4i_dotclock.o
> +sun4i-tcon-y                   += sun4i_lvds.o
>  sun4i-tcon-y                   += sun4i_tcon.o
>  sun4i-tcon-y                   += sun4i_rgb.o
>
> diff --git a/drivers/gpu/drm/sun4i/sun4i_lvds.c b/drivers/gpu/drm/sun4i/sun4i_lvds.c
> new file mode 100644
> index 000000000000..635a3f505ecb
> --- /dev/null
> +++ b/drivers/gpu/drm/sun4i/sun4i_lvds.c
> @@ -0,0 +1,183 @@
> +/*
> + * Copyright (C) 2015 NextThing Co
> + * Copyright (C) 2015-2017 Free Electrons
> + *
> + * Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
> + *
> + * 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 <drm/drmP.h>
> +#include <drm/drm_atomic_helper.h>
> +#include <drm/drm_crtc_helper.h>
> +#include <drm/drm_of.h>
> +#include <drm/drm_panel.h>
> +
> +#include "sun4i_crtc.h"
> +#include "sun4i_tcon.h"
> +#include "sun4i_lvds.h"
> +
> +struct sun4i_lvds {
> +       struct drm_connector    connector;
> +       struct drm_encoder      encoder;
> +
> +       struct sun4i_tcon       *tcon;
> +};
> +
> +static inline struct sun4i_lvds *
> +drm_connector_to_sun4i_lvds(struct drm_connector *connector)
> +{
> +       return container_of(connector, struct sun4i_lvds,
> +                           connector);
> +}
> +
> +static inline struct sun4i_lvds *
> +drm_encoder_to_sun4i_lvds(struct drm_encoder *encoder)
> +{
> +       return container_of(encoder, struct sun4i_lvds,
> +                           encoder);
> +}
> +
> +static int sun4i_lvds_get_modes(struct drm_connector *connector)
> +{
> +       struct sun4i_lvds *lvds =
> +               drm_connector_to_sun4i_lvds(connector);
> +       struct sun4i_tcon *tcon = lvds->tcon;
> +
> +       return drm_panel_get_modes(tcon->panel);
> +}
> +
> +static struct drm_connector_helper_funcs sun4i_lvds_con_helper_funcs = {
> +       .get_modes      = sun4i_lvds_get_modes,
> +};
> +
> +static void
> +sun4i_lvds_connector_destroy(struct drm_connector *connector)
> +{
> +       struct sun4i_lvds *lvds = drm_connector_to_sun4i_lvds(connector);
> +       struct sun4i_tcon *tcon = lvds->tcon;
> +
> +       drm_panel_detach(tcon->panel);
> +       drm_connector_cleanup(connector);
> +}
> +
> +static const struct drm_connector_funcs sun4i_lvds_con_funcs = {
> +       .fill_modes             = drm_helper_probe_single_connector_modes,
> +       .destroy                = sun4i_lvds_connector_destroy,
> +       .reset                  = drm_atomic_helper_connector_reset,
> +       .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
> +       .atomic_destroy_state   = drm_atomic_helper_connector_destroy_state,
> +};
> +
> +static void sun4i_lvds_encoder_enable(struct drm_encoder *encoder)
> +{
> +       struct sun4i_lvds *lvds = drm_encoder_to_sun4i_lvds(encoder);
> +       struct sun4i_tcon *tcon = lvds->tcon;
> +
> +       DRM_DEBUG_DRIVER("Enabling LVDS output\n");
> +
> +       if (!IS_ERR(tcon->panel)) {
> +               drm_panel_prepare(tcon->panel);
> +               drm_panel_enable(tcon->panel);
> +       }
> +}
> +
> +static void sun4i_lvds_encoder_disable(struct drm_encoder *encoder)
> +{
> +       struct sun4i_lvds *lvds = drm_encoder_to_sun4i_lvds(encoder);
> +       struct sun4i_tcon *tcon = lvds->tcon;
> +
> +       DRM_DEBUG_DRIVER("Disabling LVDS output\n");
> +
> +       if (!IS_ERR(tcon->panel)) {
> +               drm_panel_disable(tcon->panel);
> +               drm_panel_unprepare(tcon->panel);
> +       }
> +}
> +
> +static const struct drm_encoder_helper_funcs sun4i_lvds_enc_helper_funcs = {
> +       .disable        = sun4i_lvds_encoder_disable,
> +       .enable         = sun4i_lvds_encoder_enable,
> +};
> +
> +static const struct drm_encoder_funcs sun4i_lvds_enc_funcs = {
> +       .destroy        = drm_encoder_cleanup,
> +};
> +
> +int sun4i_lvds_init(struct drm_device *drm, struct sun4i_tcon *tcon)
> +{
> +       struct drm_encoder *encoder;
> +       struct drm_bridge *bridge;
> +       struct sun4i_lvds *lvds;
> +       int ret;
> +
> +       lvds = devm_kzalloc(drm->dev, sizeof(*lvds), GFP_KERNEL);
> +       if (!lvds)
> +               return -ENOMEM;
> +       lvds->tcon = tcon;
> +       encoder = &lvds->encoder;
> +
> +       ret = drm_of_find_panel_or_bridge(tcon->dev->of_node, 1, 0,
> +                                         &tcon->panel, &bridge);
> +       if (ret) {
> +               dev_info(drm->dev, "No panel or bridge found... LVDS output disabled\n");
> +               return 0;
> +       }
> +
> +       drm_encoder_helper_add(&lvds->encoder,
> +                              &sun4i_lvds_enc_helper_funcs);
> +       ret = drm_encoder_init(drm,
> +                              &lvds->encoder,
> +                              &sun4i_lvds_enc_funcs,
> +                              DRM_MODE_ENCODER_LVDS,
> +                              NULL);
> +       if (ret) {
> +               dev_err(drm->dev, "Couldn't initialise the lvds encoder\n");
> +               goto err_out;
> +       }
> +
> +       /* The LVDS encoder can only work with the TCON channel 0 */
> +       lvds->encoder.possible_crtcs = BIT(drm_crtc_index(&tcon->crtc->crtc));
> +
> +       if (tcon->panel) {
> +               drm_connector_helper_add(&lvds->connector,
> +                                        &sun4i_lvds_con_helper_funcs);
> +               ret = drm_connector_init(drm, &lvds->connector,
> +                                        &sun4i_lvds_con_funcs,
> +                                        DRM_MODE_CONNECTOR_LVDS);
> +               if (ret) {
> +                       dev_err(drm->dev, "Couldn't initialise the lvds connector\n");
> +                       goto err_cleanup_connector;
> +               }
> +
> +               drm_mode_connector_attach_encoder(&lvds->connector,
> +                                                 &lvds->encoder);
> +
> +               ret = drm_panel_attach(tcon->panel, &lvds->connector);
> +               if (ret) {
> +                       dev_err(drm->dev, "Couldn't attach our panel\n");
> +                       goto err_cleanup_connector;
> +               }
> +       }
> +
> +       if (bridge) {
> +               ret = drm_bridge_attach(encoder, bridge, NULL);
> +               if (ret) {
> +                       dev_err(drm->dev, "Couldn't attach our bridge\n");
> +                       goto err_cleanup_connector;
> +               }
> +       }
> +
> +       return 0;
> +
> +err_cleanup_connector:
> +       drm_encoder_cleanup(&lvds->encoder);
> +err_out:
> +       return ret;
> +}
> +EXPORT_SYMBOL(sun4i_lvds_init);
> diff --git a/drivers/gpu/drm/sun4i/sun4i_lvds.h b/drivers/gpu/drm/sun4i/sun4i_lvds.h
> new file mode 100644
> index 000000000000..1b8fad4b82c3
> --- /dev/null
> +++ b/drivers/gpu/drm/sun4i/sun4i_lvds.h
> @@ -0,0 +1,18 @@
> +/*
> + * Copyright (C) 2015 NextThing Co
> + * Copyright (C) 2015-2017 Free Electrons
> + *
> + * Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
> + *
> + * 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.
> + */
> +
> +#ifndef _SUN4I_LVDS_H_
> +#define _SUN4I_LVDS_H_
> +
> +int sun4i_lvds_init(struct drm_device *drm, struct sun4i_tcon *tcon);
> +
> +#endif /* _SUN4I_LVDS_H_ */
> diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> index 46e28ca1f676..92f4738101e6 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> @@ -31,10 +31,52 @@
>  #include "sun4i_crtc.h"
>  #include "sun4i_dotclock.h"
>  #include "sun4i_drv.h"
> +#include "sun4i_lvds.h"
>  #include "sun4i_rgb.h"
>  #include "sun4i_tcon.h"
>  #include "sunxi_engine.h"
>
> +static struct drm_connector *sun4i_tcon_get_connector(const struct drm_encoder *encoder)
> +{
> +       struct drm_connector *connector;
> +       struct drm_connector_list_iter iter;
> +
> +       drm_connector_list_iter_begin(encoder->dev, &iter);
> +       drm_for_each_connector_iter(connector, &iter)
> +               if (connector->encoder == encoder) {
> +                       drm_connector_list_iter_end(&iter);
> +                       return connector;
> +               }
> +       drm_connector_list_iter_end(&iter);
> +
> +       return NULL;
> +}
> +
> +static int sun4i_tcon_get_pixel_depth(const struct drm_encoder *encoder)
> +{
> +       struct drm_connector *connector;
> +       struct drm_display_info *info;
> +
> +       connector = sun4i_tcon_get_connector(encoder);
> +       if (!connector)
> +               return -EINVAL;
> +
> +       info = &connector->display_info;
> +       if (info->num_bus_formats != 1)
> +               return -EINVAL;
> +
> +       switch (info->bus_formats[0]) {
> +       case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG:
> +               return 18;
> +
> +       case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA:
> +       case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG:
> +               return 24;
> +       }
> +
> +       return -EINVAL;
> +}
> +
>  static void sun4i_tcon_channel_set_status(struct sun4i_tcon *tcon, int channel,
>                                           bool enabled)
>  {
> @@ -65,13 +107,58 @@ static void sun4i_tcon_channel_set_status(struct sun4i_tcon *tcon, int channel,
>                 clk_disable_unprepare(clk);
>  }
>
> +static void sun4i_tcon_lvds_set_status(struct sun4i_tcon *tcon,
> +                                      const struct drm_encoder *encoder,
> +                                      bool enabled)
> +{
> +       if (enabled) {
> +               u8 val;
> +
> +               regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_IF_REG,
> +                                  SUN4I_TCON0_LVDS_IF_EN,
> +                                  SUN4I_TCON0_LVDS_IF_EN);
> +
> +               regmap_write(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
> +                            SUN4I_TCON0_LVDS_ANA0_C(2) |
> +                            SUN4I_TCON0_LVDS_ANA0_V(3) |
> +                            SUN4I_TCON0_LVDS_ANA0_PD(2) |
> +                            SUN4I_TCON0_LVDS_ANA0_EN_LDO);
> +               udelay(2);
> +
> +               regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
> +                                  SUN4I_TCON0_LVDS_ANA0_EN_MB,
> +                                  SUN4I_TCON0_LVDS_ANA0_EN_MB);
> +               udelay(2);
> +
> +               regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
> +                                  SUN4I_TCON0_LVDS_ANA0_EN_DRVC,
> +                                  SUN4I_TCON0_LVDS_ANA0_EN_DRVC);
> +
> +               if (sun4i_tcon_get_pixel_depth(encoder) == 18)
> +                       val = 7;
> +               else
> +                       val = 0xf;
> +
> +               regmap_write_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
> +                                 SUN4I_TCON0_LVDS_ANA0_EN_DRVD(0xf),
> +                                 SUN4I_TCON0_LVDS_ANA0_EN_DRVD(val));

I suggest changing the prefix of the macros of the analog bits to
SUN6I_TCON0_*. The register definitions and sequence do not apply
to the A10/A20. Furthermore you should add a comment saying this
doesn't apply to the A10/A20. In the future we might want to move
this part into a separate function, referenced by a function pointer
from the quirks structure.

> +       } else {
> +               regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_IF_REG,
> +                                  SUN4I_TCON0_LVDS_IF_EN, 0);
> +       }
> +}
> +
>  void sun4i_tcon_set_status(struct sun4i_tcon *tcon,
>                            const struct drm_encoder *encoder,
>                            bool enabled)
>  {
> +       bool is_lvds = false;
>         int channel;
>
>         switch (encoder->encoder_type) {
> +       case DRM_MODE_ENCODER_LVDS:
> +               is_lvds = true;
> +               /* Fallthrough */
>         case DRM_MODE_ENCODER_NONE:
>                 channel = 0;
>                 break;
> @@ -84,10 +171,16 @@ void sun4i_tcon_set_status(struct sun4i_tcon *tcon,
>                 return;
>         }
>
> +       if (is_lvds && !enabled)
> +               sun4i_tcon_lvds_set_status(tcon, encoder, false);
> +
>         regmap_update_bits(tcon->regs, SUN4I_TCON_GCTL_REG,
>                            SUN4I_TCON_GCTL_TCON_ENABLE,
>                            enabled ? SUN4I_TCON_GCTL_TCON_ENABLE : 0);
>
> +       if (is_lvds && enabled)
> +               sun4i_tcon_lvds_set_status(tcon, encoder, true);
> +
>         sun4i_tcon_channel_set_status(tcon, channel, enabled);
>  }
>
> @@ -170,6 +263,78 @@ static void sun4i_tcon0_mode_set_common(struct sun4i_tcon *tcon,
>                      SUN4I_TCON0_BASIC0_Y(mode->crtc_vdisplay));
>  }
>
> +static void sun4i_tcon0_mode_set_lvds(struct sun4i_tcon *tcon,
> +                                     const struct drm_encoder *encoder,
> +                                     const struct drm_display_mode *mode)
> +{
> +       unsigned int bp;
> +       u8 clk_delay;
> +       u32 reg, val = 0;
> +
> +       tcon->dclk_min_div = 7;
> +       tcon->dclk_max_div = 7;
> +       sun4i_tcon0_mode_set_common(tcon, mode);
> +
> +       /* Adjust clock delay */
> +       clk_delay = sun4i_tcon_get_clk_delay(mode, 0);
> +       regmap_update_bits(tcon->regs, SUN4I_TCON0_CTL_REG,
> +                          SUN4I_TCON0_CTL_CLK_DELAY_MASK,
> +                          SUN4I_TCON0_CTL_CLK_DELAY(clk_delay));
> +
> +       /*
> +        * This is called a backporch in the register documentation,
> +        * but it really is the back porch + hsync
> +        */
> +       bp = mode->crtc_htotal - mode->crtc_hsync_start;
> +       DRM_DEBUG_DRIVER("Setting horizontal total %d, backporch %d\n",
> +                        mode->crtc_htotal, bp);
> +
> +       /* Set horizontal display timings */
> +       regmap_write(tcon->regs, SUN4I_TCON0_BASIC1_REG,
> +                    SUN4I_TCON0_BASIC1_H_TOTAL(mode->htotal) |
> +                    SUN4I_TCON0_BASIC1_H_BACKPORCH(bp));
> +
> +       /*
> +        * This is called a backporch in the register documentation,
> +        * but it really is the back porch + hsync
> +        */
> +       bp = mode->crtc_vtotal - mode->crtc_vsync_start;
> +       DRM_DEBUG_DRIVER("Setting vertical total %d, backporch %d\n",
> +                        mode->crtc_vtotal, bp);
> +
> +       /* Set vertical display timings */
> +       regmap_write(tcon->regs, SUN4I_TCON0_BASIC2_REG,
> +                    SUN4I_TCON0_BASIC2_V_TOTAL(mode->crtc_vtotal * 2) |
> +                    SUN4I_TCON0_BASIC2_V_BACKPORCH(bp));
> +

Can we move the above to a common function?

> +       reg = SUN4I_TCON0_LVDS_IF_CLK_SEL_TCON0 |
> +               SUN4I_TCON0_LVDS_IF_DATA_POL_NORMAL |
> +               SUN4I_TCON0_LVDS_IF_CLK_POL_NORMAL;
> +       if (sun4i_tcon_get_pixel_depth(encoder) == 24)
> +               reg |= SUN4I_TCON0_LVDS_IF_BITWIDTH_24BITS;
> +       else
> +               reg |= SUN4I_TCON0_LVDS_IF_BITWIDTH_18BITS;
> +
> +       regmap_write(tcon->regs, SUN4I_TCON0_LVDS_IF_REG, reg);
> +
> +       /* Setup the polarity of the various signals */
> +       if (!(mode->flags & DRM_MODE_FLAG_PHSYNC))
> +               val |= SUN4I_TCON0_IO_POL_HSYNC_POSITIVE;
> +
> +       if (!(mode->flags & DRM_MODE_FLAG_PVSYNC))
> +               val |= SUN4I_TCON0_IO_POL_VSYNC_POSITIVE;
> +
> +       regmap_write(tcon->regs, SUN4I_TCON0_IO_POL_REG, val);
> +
> +       /* Map output pins to channel 0 */
> +       regmap_update_bits(tcon->regs, SUN4I_TCON_GCTL_REG,
> +                          SUN4I_TCON_GCTL_IOMAP_MASK,
> +                          SUN4I_TCON_GCTL_IOMAP_TCON0);
> +
> +       /* Enable the output on the pins */
> +       regmap_write(tcon->regs, SUN4I_TCON0_IO_TRI_REG, 0xe0000000);

Is this still needed? You are no longer using the TCON LCD pins
with LVDS.

> +}
> +
>  static void sun4i_tcon0_mode_set_rgb(struct sun4i_tcon *tcon,
>                                      const struct drm_display_mode *mode)
>  {
> @@ -336,6 +501,9 @@ void sun4i_tcon_mode_set(struct sun4i_tcon *tcon,
>                          const struct drm_display_mode *mode)
>  {
>         switch (encoder->encoder_type) {
> +       case DRM_MODE_ENCODER_LVDS:
> +               sun4i_tcon0_mode_set_lvds(tcon, encoder, mode);
> +               break;
>         case DRM_MODE_ENCODER_NONE:
>                 sun4i_tcon0_mode_set_rgb(tcon, mode);
>                 sun4i_tcon_set_mux(tcon, 0, encoder);
> @@ -667,7 +835,9 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
>         struct drm_device *drm = data;
>         struct sun4i_drv *drv = drm->dev_private;
>         struct sunxi_engine *engine;
> +       struct device_node *remote;
>         struct sun4i_tcon *tcon;
> +       bool has_lvds_rst, has_lvds_pll, can_lvds;
>         int ret;
>
>         engine = sun4i_tcon_find_engine(drv, dev->of_node);
> @@ -698,6 +868,54 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
>                 return ret;
>         }
>
> +       /*
> +        * This can only be made optional since we've had DT nodes
> +        * without the LVDS reset properties.
> +        *
> +        * If the property is missing, just disable LVDS, and print a
> +        * warning.
> +        */
> +       tcon->lvds_rst = devm_reset_control_get_optional(dev, "lvds");
> +       if (IS_ERR(tcon->lvds_rst)) {
> +               dev_err(dev, "Couldn't get our reset line\n");
> +               return PTR_ERR(tcon->lvds_rst);
> +       } else if (tcon->lvds_rst) {
> +               has_lvds_rst = true;
> +               reset_control_reset(tcon->lvds_rst);
> +       } else {
> +               has_lvds_rst = false;
> +       }
> +
> +       /*
> +        * This can only be made optional since we've had DT nodes
> +        * without the LVDS reset properties.
> +        *
> +        * If the property is missing, just disable LVDS, and print a
> +        * warning.
> +        */
> +       if (tcon->quirks->has_lvds_pll) {
> +               tcon->lvds_pll = devm_clk_get(dev, "pll-lvds");
> +               if (IS_ERR(tcon->lvds_pll)) {
> +                       if (PTR_ERR(tcon->lvds_pll) == -ENOENT) {
> +                               has_lvds_pll = false;
> +                       } else {
> +                               dev_err(dev, "Couldn't get the LVDS PLL\n");
> +                               return PTR_ERR(tcon->lvds_rst);
> +                       }
> +               } else {
> +                       has_lvds_pll = true;
> +               }
> +       }
> +
> +       if (!has_lvds_rst || (tcon->quirks->has_lvds_pll && !has_lvds_pll)) {
> +               dev_warn(dev,
> +                        "Missing LVDS properties, Please upgrade your DT\n");
> +               dev_warn(dev, "LVDS output disabled\n");
> +               can_lvds = false;
> +       } else {
> +               can_lvds = true;
> +       }
> +
>         ret = sun4i_tcon_init_clocks(dev, tcon);
>         if (ret) {
>                 dev_err(dev, "Couldn't init our TCON clocks\n");
> @@ -729,7 +947,21 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
>                 goto err_free_dotclock;
>         }
>
> -       ret = sun4i_rgb_init(drm, tcon);
> +       /*
> +        * If we have an LVDS panel connected to the TCON, we should
> +        * just probe the LVDS connector. Otherwise, just probe RGB as
> +        * we used to.
> +        */
> +       remote = of_graph_get_remote_node(dev->of_node, 1, 0);
> +       if (of_device_is_compatible(remote, "panel-lvds"))
> +               if (can_lvds)
> +                       ret = sun4i_lvds_init(drm, tcon);
> +               else
> +                       ret = -EINVAL;
> +       else
> +               ret = sun4i_rgb_init(drm, tcon);
> +       of_node_put(remote);
> +
>         if (ret < 0)
>                 goto err_free_dotclock;
>
> @@ -879,12 +1111,14 @@ static const struct sun4i_tcon_quirks sun5i_a13_quirks = {
>
>  static const struct sun4i_tcon_quirks sun6i_a31_quirks = {
>         .has_channel_1          = true,
> +       .has_lvds_pll           = true,
>         .needs_de_be_mux        = true,
>         .set_mux                = sun6i_tcon_set_mux,
>  };
>
>  static const struct sun4i_tcon_quirks sun6i_a31s_quirks = {
>         .has_channel_1          = true,
> +       .has_lvds_pll           = true,

The A31s does not have MIPI.

>         .needs_de_be_mux        = true,
>  };
>
> @@ -895,7 +1129,7 @@ static const struct sun4i_tcon_quirks sun7i_a20_quirks = {
>  };
>
>  static const struct sun4i_tcon_quirks sun8i_a33_quirks = {
> -       /* nothing is supported */
> +       .has_lvds_pll           = true,
>  };
>
>  static const struct sun4i_tcon_quirks sun8i_v3s_quirks = {
> diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.h b/drivers/gpu/drm/sun4i/sun4i_tcon.h
> index bd3ad7684870..6e801a6325a1 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_tcon.h
> +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.h
> @@ -70,7 +70,21 @@
>  #define SUN4I_TCON0_TTL2_REG                   0x78
>  #define SUN4I_TCON0_TTL3_REG                   0x7c
>  #define SUN4I_TCON0_TTL4_REG                   0x80
> +
>  #define SUN4I_TCON0_LVDS_IF_REG                        0x84
> +#define SUN4I_TCON0_LVDS_IF_EN                         BIT(31)
> +#define SUN4I_TCON0_LVDS_IF_BITWIDTH_MASK              BIT(26)
> +#define SUN4I_TCON0_LVDS_IF_BITWIDTH_18BITS            (1 << 26)
> +#define SUN4I_TCON0_LVDS_IF_BITWIDTH_24BITS            (0 << 26)
> +#define SUN4I_TCON0_LVDS_IF_CLK_SEL_MASK               BIT(20)
> +#define SUN4I_TCON0_LVDS_IF_CLK_SEL_TCON0              (1 << 20)
> +#define SUN4I_TCON0_LVDS_IF_CLK_POL_MASK               BIT(4)
> +#define SUN4I_TCON0_LVDS_IF_CLK_POL_NORMAL             (1 << 4)
> +#define SUN4I_TCON0_LVDS_IF_CLK_POL_INV                        (0 << 4)
> +#define SUN4I_TCON0_LVDS_IF_DATA_POL_MASK              GENMASK(3, 0)
> +#define SUN4I_TCON0_LVDS_IF_DATA_POL_NORMAL            (0xf)
> +#define SUN4I_TCON0_LVDS_IF_DATA_POL_INV               (0)
> +
>  #define SUN4I_TCON0_IO_POL_REG                 0x88
>  #define SUN4I_TCON0_IO_POL_DCLK_PHASE(phase)           ((phase & 3) << 28)
>  #define SUN4I_TCON0_IO_POL_HSYNC_POSITIVE              BIT(25)
> @@ -131,6 +145,16 @@
>  #define SUN4I_TCON_CEU_RANGE_G_REG             0x144
>  #define SUN4I_TCON_CEU_RANGE_B_REG             0x148
>  #define SUN4I_TCON_MUX_CTRL_REG                        0x200
> +
> +#define SUN4I_TCON0_LVDS_ANA0_REG              0x220
> +#define SUN4I_TCON0_LVDS_ANA0_EN_MB                    BIT(31)
> +#define SUN4I_TCON0_LVDS_ANA0_EN_LDO                   BIT(30)
> +#define SUN4I_TCON0_LVDS_ANA0_EN_DRVC                  BIT(24)
> +#define SUN4I_TCON0_LVDS_ANA0_EN_DRVD(x)               (((x) & 0xf) << 20)
> +#define SUN4I_TCON0_LVDS_ANA0_C(x)                     (((x) & 3) << 17)
> +#define SUN4I_TCON0_LVDS_ANA0_V(x)                     (((x) & 3) << 8)
> +#define SUN4I_TCON0_LVDS_ANA0_PD(x)                    (((x) & 3) << 4)

See above about the analog bits.

ChenYu

> +
>  #define SUN4I_TCON1_FILL_CTL_REG               0x300
>  #define SUN4I_TCON1_FILL_BEG0_REG              0x304
>  #define SUN4I_TCON1_FILL_END0_REG              0x308
> @@ -149,6 +173,7 @@ struct sun4i_tcon;
>
>  struct sun4i_tcon_quirks {
>         bool    has_channel_1;  /* a33 does not have channel 1 */
> +       bool    has_lvds_pll;   /* Can we mux the LVDS clock to a PLL? */
>         bool    needs_de_be_mux; /* sun6i needs mux to select backend */
>
>         /* callback to handle tcon muxing options */
> @@ -167,6 +192,9 @@ struct sun4i_tcon {
>         struct clk                      *sclk0;
>         struct clk                      *sclk1;
>
> +       /* Possible mux for the LVDS clock */
> +       struct clk                      *lvds_pll;
> +
>         /* Pixel clock */
>         struct clk                      *dclk;
>         u8                              dclk_max_div;
> @@ -174,6 +202,7 @@ struct sun4i_tcon {
>
>         /* Reset control */
>         struct reset_control            *lcd_rst;
> +       struct reset_control            *lvds_rst;
>
>         struct drm_panel                *panel;
>
> --
> git-series 0.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v3 08/15] drm/sun4i: Add LVDS support
  2017-12-05 15:10   ` [PATCH v3 08/15] drm/sun4i: Add LVDS support Maxime Ripard
       [not found]     ` <b900e5963180c94ca02bde178b6674622a127787.1512486553.git-series.maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
@ 2017-12-07 10:14     ` Philippe Ombredanne
       [not found]       ` <CAOFm3uEpnBFUDBHK+SqQ-pGUPcWbGXNrWum4HRJ34tMtoX-2Qw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  1 sibling, 1 reply; 33+ messages in thread
From: Philippe Ombredanne @ 2017-12-07 10:14 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Daniel Vetter, David Airlie, Chen-Yu Tsai, dri-devel, LKML,
	Mark Rutland, Rob Herring,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE, plaes,
	Icenowy Zheng, Thomas Petazzoni, jernej.skrabec,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS

On Tue, Dec 5, 2017 at 4:10 PM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> The TCON supports the LVDS interface to output to a panel or a bridge.
> Let's add support for it.
>
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
[]
> --- /dev/null
> +++ b/drivers/gpu/drm/sun4i/sun4i_lvds.c
> @@ -0,0 +1,183 @@
> +/*
> + * Copyright (C) 2015 NextThing Co
> + * Copyright (C) 2015-2017 Free Electrons
> + *
> + * Maxime Ripard <maxime.ripard@free-electrons.com>
> + *
> + * 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.
> + */

Maxime,

Would you consider using the new SPDX ids instead of this fine legalese?
e.g. this as the top line:

// SPDX-License-Identifier: GPL-2.0+

-- 
Cordially
Philippe Ombredanne

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v3 08/15] drm/sun4i: Add LVDS support
       [not found]       ` <CAOFm3uEpnBFUDBHK+SqQ-pGUPcWbGXNrWum4HRJ34tMtoX-2Qw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2017-12-07 10:50         ` Maxime Ripard
  0 siblings, 0 replies; 33+ messages in thread
From: Maxime Ripard @ 2017-12-07 10:50 UTC (permalink / raw)
  To: Philippe Ombredanne
  Cc: Daniel Vetter, David Airlie, Chen-Yu Tsai,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, LKML, Mark Rutland,
	Rob Herring,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
	plaes-q/aMd4JkU83YtjvyW6yDsg, Icenowy Zheng, Thomas Petazzoni,
	jernej.skrabec-gGgVlfcn5nU,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS

[-- Attachment #1: Type: text/plain, Size: 1347 bytes --]

Hi,

On Thu, Dec 07, 2017 at 11:14:27AM +0100, Philippe Ombredanne wrote:
> On Tue, Dec 5, 2017 at 4:10 PM, Maxime Ripard
> <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org> wrote:
> > The TCON supports the LVDS interface to output to a panel or a bridge.
> > Let's add support for it.
> >
> > Signed-off-by: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
> []
> > --- /dev/null
> > +++ b/drivers/gpu/drm/sun4i/sun4i_lvds.c
> > @@ -0,0 +1,183 @@
> > +/*
> > + * Copyright (C) 2015 NextThing Co
> > + * Copyright (C) 2015-2017 Free Electrons
> > + *
> > + * Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
> > + *
> > + * 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.
> > + */
> 
> Would you consider using the new SPDX ids instead of this fine legalese?
> e.g. this as the top line:
> 
> // SPDX-License-Identifier: GPL-2.0+

I did, and then forgot about it.

This will be in my next iteration, thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v3 09/15] drm/sun4i: Add A83T support
  2017-12-06 16:37     ` Jernej Škrabec
@ 2017-12-07 10:55       ` Maxime Ripard
  0 siblings, 0 replies; 33+ messages in thread
From: Maxime Ripard @ 2017-12-07 10:55 UTC (permalink / raw)
  To: Jernej Škrabec
  Cc: Mark Rutland, Thomas Petazzoni, plaes, devicetree, David Airlie,
	linux-kernel, dri-devel, Chen-Yu Tsai, Rob Herring,
	Daniel Vetter, linux-arm-kernel, icenowy


[-- Attachment #1.1: Type: text/plain, Size: 3853 bytes --]

Hi,

On Wed, Dec 06, 2017 at 05:37:47PM +0100, Jernej Škrabec wrote:
> Hi,
> 
> Dne torek, 05. december 2017 ob 16:42:55 CET je Jernej Škrabec napisal(a):
> > Hi Maxime,
> > 
> > Dne torek, 05. december 2017 ob 16:10:21 CET je Maxime Ripard napisal(a):
> > > Add support for the A83T display pipeline.
> > > 
> > > Reviewed-by: Chen-Yu Tsai <wens@csie.org>
> > > Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> > > ---
> > > 
> > >  drivers/gpu/drm/sun4i/sun4i_drv.c   |  1 +
> > >  drivers/gpu/drm/sun4i/sun4i_tcon.c  |  5 +++++
> > >  drivers/gpu/drm/sun4i/sun8i_mixer.c |  9 +++++++++
> > >  3 files changed, 15 insertions(+)
> > > 
> > > diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c
> > > b/drivers/gpu/drm/sun4i/sun4i_drv.c index 49215d91c853..6f5e721b545e
> > > 100644
> > > --- a/drivers/gpu/drm/sun4i/sun4i_drv.c
> > > +++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
> > > @@ -347,6 +347,7 @@ static const struct of_device_id sun4i_drv_of_table[]
> > > =
> > > { { .compatible = "allwinner,sun6i-a31s-display-engine" },
> > > 
> > >  	{ .compatible = "allwinner,sun7i-a20-display-engine" },
> > >  	{ .compatible = "allwinner,sun8i-a33-display-engine" },
> > > 
> > > +	{ .compatible = "allwinner,sun8i-a83t-display-engine" },
> > > 
> > >  	{ .compatible = "allwinner,sun8i-v3s-display-engine" },
> > >  	{ }
> > >  
> > >  };
> > > 
> > > diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > b/drivers/gpu/drm/sun4i/sun4i_tcon.c index 92f4738101e6..9b757450555f
> > > 100644
> > > --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > @@ -1132,6 +1132,10 @@ static const struct sun4i_tcon_quirks
> > > sun8i_a33_quirks = { .has_lvds_pll		= true,
> > > 
> > >  };
> > > 
> > > +static const struct sun4i_tcon_quirks sun8i_a83t_lcd_quirks = {
> > > +	/* nothing is supported */
> > > +};
> > > +
> > > 
> > >  static const struct sun4i_tcon_quirks sun8i_v3s_quirks = {
> > >  
> > >  	/* nothing is supported */
> > >  
> > >  };
> > > 
> > > @@ -1144,6 +1148,7 @@ const struct of_device_id sun4i_tcon_of_table[] = {
> > > 
> > >  	{ .compatible = "allwinner,sun6i-a31s-tcon", .data = 
> &sun6i_a31s_quirks
> > >  	},
> > > 
> > > { .compatible = "allwinner,sun7i-a20-tcon", .data = &sun7i_a20_quirks }, {
> > > .compatible = "allwinner,sun8i-a33-tcon", .data = &sun8i_a33_quirks }, +	
> {
> > > .compatible = "allwinner,sun8i-a83t-tcon-lcd", .data =
> > > &sun8i_a83t_lcd_quirks }, { .compatible = "allwinner,sun8i-v3s-tcon",
> > > .data
> > > = &sun8i_v3s_quirks }, { }
> > > 
> > >  };
> > > 
> > > diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c
> > > b/drivers/gpu/drm/sun4i/sun8i_mixer.c index ff235e3228ce..6829bec4ba68
> > > 100644
> > > --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
> > > +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
> > > @@ -477,6 +477,11 @@ static int sun8i_mixer_remove(struct platform_device
> > > *pdev) return 0;
> > > 
> > >  }
> > > 
> > > +static const struct sun8i_mixer_cfg sun8i_a83t_mixer_cfg = {
> > > +	.vi_num = 1,
> > > +	.ui_num = 3,
> > > +};
> > > +
> > 
> > I think you should expand that structure with:
> > .ccsc = 0,
> > .scaler_mask = 0xf,
> > .mod_rate = 150000000,
> 
> I guess you could set higher clock if CLK_SET_RATE_PARENT flag is set to de_clk 
> in A83T CCU driver. BSP sets it to 500 MHz, which is a bit high...

Actually, I didn't have to change the rate used by default, so it's
not clear what it should be on the A83T.

And yeah, I'd like to avoid setting it at 500MHz without any
particular reason. The A83T draws way to much power already without
making it worse.

I'll add the CCSC and scaler_mask fields.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

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

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v3 08/15] drm/sun4i: Add LVDS support
  2017-12-07  6:05       ` Chen-Yu Tsai
@ 2017-12-07 12:25         ` Maxime Ripard
       [not found]           ` <20171207122521.frv5zgaay3sgol6f-ZC1Zs529Oq4@public.gmane.org>
  0 siblings, 1 reply; 33+ messages in thread
From: Maxime Ripard @ 2017-12-07 12:25 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Mark Rutland, Thomas Petazzoni, Jernej Skrabec, Priit Laes,
	devicetree, David Airlie, linux-kernel, dri-devel, Rob Herring,
	Daniel Vetter, linux-arm-kernel, Icenowy Zheng


[-- Attachment #1.1: Type: text/plain, Size: 6914 bytes --]

Hi,

On Thu, Dec 07, 2017 at 02:05:47PM +0800, Chen-Yu Tsai wrote:
> > +static void sun4i_tcon_lvds_set_status(struct sun4i_tcon *tcon,
> > +                                      const struct drm_encoder *encoder,
> > +                                      bool enabled)
> > +{
> > +       if (enabled) {
> > +               u8 val;
> > +
> > +               regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_IF_REG,
> > +                                  SUN4I_TCON0_LVDS_IF_EN,
> > +                                  SUN4I_TCON0_LVDS_IF_EN);
> > +
> > +               regmap_write(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
> > +                            SUN4I_TCON0_LVDS_ANA0_C(2) |
> > +                            SUN4I_TCON0_LVDS_ANA0_V(3) |
> > +                            SUN4I_TCON0_LVDS_ANA0_PD(2) |
> > +                            SUN4I_TCON0_LVDS_ANA0_EN_LDO);
> > +               udelay(2);
> > +
> > +               regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
> > +                                  SUN4I_TCON0_LVDS_ANA0_EN_MB,
> > +                                  SUN4I_TCON0_LVDS_ANA0_EN_MB);
> > +               udelay(2);
> > +
> > +               regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
> > +                                  SUN4I_TCON0_LVDS_ANA0_EN_DRVC,
> > +                                  SUN4I_TCON0_LVDS_ANA0_EN_DRVC);
> > +
> > +               if (sun4i_tcon_get_pixel_depth(encoder) == 18)
> > +                       val = 7;
> > +               else
> > +                       val = 0xf;
> > +
> > +               regmap_write_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
> > +                                 SUN4I_TCON0_LVDS_ANA0_EN_DRVD(0xf),
> > +                                 SUN4I_TCON0_LVDS_ANA0_EN_DRVD(val));
> 
> I suggest changing the prefix of the macros of the analog bits to
> SUN6I_TCON0_*. The register definitions and sequence do not apply
> to the A10/A20. Furthermore you should add a comment saying this
> doesn't apply to the A10/A20. In the future we might want to move
> this part into a separate function, referenced by a function pointer
> from the quirks structure.

I'll change the bit field names and add a comment like you suggested.

> > +       } else {
> > +               regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_IF_REG,
> > +                                  SUN4I_TCON0_LVDS_IF_EN, 0);
> > +       }
> > +}
> > +
> >  void sun4i_tcon_set_status(struct sun4i_tcon *tcon,
> >                            const struct drm_encoder *encoder,
> >                            bool enabled)
> >  {
> > +       bool is_lvds = false;
> >         int channel;
> >
> >         switch (encoder->encoder_type) {
> > +       case DRM_MODE_ENCODER_LVDS:
> > +               is_lvds = true;
> > +               /* Fallthrough */
> >         case DRM_MODE_ENCODER_NONE:
> >                 channel = 0;
> >                 break;
> > @@ -84,10 +171,16 @@ void sun4i_tcon_set_status(struct sun4i_tcon *tcon,
> >                 return;
> >         }
> >
> > +       if (is_lvds && !enabled)
> > +               sun4i_tcon_lvds_set_status(tcon, encoder, false);
> > +
> >         regmap_update_bits(tcon->regs, SUN4I_TCON_GCTL_REG,
> >                            SUN4I_TCON_GCTL_TCON_ENABLE,
> >                            enabled ? SUN4I_TCON_GCTL_TCON_ENABLE : 0);
> >
> > +       if (is_lvds && enabled)
> > +               sun4i_tcon_lvds_set_status(tcon, encoder, true);
> > +
> >         sun4i_tcon_channel_set_status(tcon, channel, enabled);
> >  }
> >
> > @@ -170,6 +263,78 @@ static void sun4i_tcon0_mode_set_common(struct sun4i_tcon *tcon,
> >                      SUN4I_TCON0_BASIC0_Y(mode->crtc_vdisplay));
> >  }
> >
> > +static void sun4i_tcon0_mode_set_lvds(struct sun4i_tcon *tcon,
> > +                                     const struct drm_encoder *encoder,
> > +                                     const struct drm_display_mode *mode)
> > +{
> > +       unsigned int bp;
> > +       u8 clk_delay;
> > +       u32 reg, val = 0;
> > +
> > +       tcon->dclk_min_div = 7;
> > +       tcon->dclk_max_div = 7;
> > +       sun4i_tcon0_mode_set_common(tcon, mode);
> > +
> > +       /* Adjust clock delay */
> > +       clk_delay = sun4i_tcon_get_clk_delay(mode, 0);
> > +       regmap_update_bits(tcon->regs, SUN4I_TCON0_CTL_REG,
> > +                          SUN4I_TCON0_CTL_CLK_DELAY_MASK,
> > +                          SUN4I_TCON0_CTL_CLK_DELAY(clk_delay));
> > +
> > +       /*
> > +        * This is called a backporch in the register documentation,
> > +        * but it really is the back porch + hsync
> > +        */
> > +       bp = mode->crtc_htotal - mode->crtc_hsync_start;
> > +       DRM_DEBUG_DRIVER("Setting horizontal total %d, backporch %d\n",
> > +                        mode->crtc_htotal, bp);
> > +
> > +       /* Set horizontal display timings */
> > +       regmap_write(tcon->regs, SUN4I_TCON0_BASIC1_REG,
> > +                    SUN4I_TCON0_BASIC1_H_TOTAL(mode->htotal) |
> > +                    SUN4I_TCON0_BASIC1_H_BACKPORCH(bp));
> > +
> > +       /*
> > +        * This is called a backporch in the register documentation,
> > +        * but it really is the back porch + hsync
> > +        */
> > +       bp = mode->crtc_vtotal - mode->crtc_vsync_start;
> > +       DRM_DEBUG_DRIVER("Setting vertical total %d, backporch %d\n",
> > +                        mode->crtc_vtotal, bp);
> > +
> > +       /* Set vertical display timings */
> > +       regmap_write(tcon->regs, SUN4I_TCON0_BASIC2_REG,
> > +                    SUN4I_TCON0_BASIC2_V_TOTAL(mode->crtc_vtotal * 2) |
> > +                    SUN4I_TCON0_BASIC2_V_BACKPORCH(bp));
> 
> Can we move the above to a common function?

Until we have DSI support figured out I'd rather not do too much of
consolidation. We know already a few things are going to change there
(like the clk_delay), but it's not clear yet how much.

> > +       /* Map output pins to channel 0 */
> > +       regmap_update_bits(tcon->regs, SUN4I_TCON_GCTL_REG,
> > +                          SUN4I_TCON_GCTL_IOMAP_MASK,
> > +                          SUN4I_TCON_GCTL_IOMAP_TCON0);
> > +
> > +       /* Enable the output on the pins */
> > +       regmap_write(tcon->regs, SUN4I_TCON0_IO_TRI_REG, 0xe0000000);
> 
> Is this still needed? You are no longer using the TCON LCD pins
> with LVDS.

We do. It's a separate function of the pins, but it's the same pins.

> >  static const struct sun4i_tcon_quirks sun6i_a31s_quirks = {
> >         .has_channel_1          = true,
> > +       .has_lvds_pll           = true,
> 
> The A31s does not have MIPI.

I'll change that.

Thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

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

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v3 08/15] drm/sun4i: Add LVDS support
       [not found]           ` <20171207122521.frv5zgaay3sgol6f-ZC1Zs529Oq4@public.gmane.org>
@ 2017-12-14  3:30             ` Chen-Yu Tsai
  2017-12-14  9:37               ` Maxime Ripard
  0 siblings, 1 reply; 33+ messages in thread
From: Chen-Yu Tsai @ 2017-12-14  3:30 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Chen-Yu Tsai, Daniel Vetter, David Airlie, dri-devel,
	linux-kernel, Mark Rutland, Rob Herring, linux-arm-kernel,
	Priit Laes, Icenowy Zheng, Thomas Petazzoni, Jernej Skrabec,
	devicetree

On Thu, Dec 7, 2017 at 8:25 PM, Maxime Ripard
<maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org> wrote:
> Hi,
>
> On Thu, Dec 07, 2017 at 02:05:47PM +0800, Chen-Yu Tsai wrote:
>> > +static void sun4i_tcon_lvds_set_status(struct sun4i_tcon *tcon,
>> > +                                      const struct drm_encoder *encoder,
>> > +                                      bool enabled)
>> > +{
>> > +       if (enabled) {
>> > +               u8 val;
>> > +
>> > +               regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_IF_REG,
>> > +                                  SUN4I_TCON0_LVDS_IF_EN,
>> > +                                  SUN4I_TCON0_LVDS_IF_EN);
>> > +
>> > +               regmap_write(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
>> > +                            SUN4I_TCON0_LVDS_ANA0_C(2) |
>> > +                            SUN4I_TCON0_LVDS_ANA0_V(3) |
>> > +                            SUN4I_TCON0_LVDS_ANA0_PD(2) |
>> > +                            SUN4I_TCON0_LVDS_ANA0_EN_LDO);
>> > +               udelay(2);
>> > +
>> > +               regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
>> > +                                  SUN4I_TCON0_LVDS_ANA0_EN_MB,
>> > +                                  SUN4I_TCON0_LVDS_ANA0_EN_MB);
>> > +               udelay(2);
>> > +
>> > +               regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
>> > +                                  SUN4I_TCON0_LVDS_ANA0_EN_DRVC,
>> > +                                  SUN4I_TCON0_LVDS_ANA0_EN_DRVC);
>> > +
>> > +               if (sun4i_tcon_get_pixel_depth(encoder) == 18)
>> > +                       val = 7;
>> > +               else
>> > +                       val = 0xf;
>> > +
>> > +               regmap_write_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
>> > +                                 SUN4I_TCON0_LVDS_ANA0_EN_DRVD(0xf),
>> > +                                 SUN4I_TCON0_LVDS_ANA0_EN_DRVD(val));
>>
>> I suggest changing the prefix of the macros of the analog bits to
>> SUN6I_TCON0_*. The register definitions and sequence do not apply
>> to the A10/A20. Furthermore you should add a comment saying this
>> doesn't apply to the A10/A20. In the future we might want to move
>> this part into a separate function, referenced by a function pointer
>> from the quirks structure.
>
> I'll change the bit field names and add a comment like you suggested.
>
>> > +       } else {
>> > +               regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_IF_REG,
>> > +                                  SUN4I_TCON0_LVDS_IF_EN, 0);
>> > +       }
>> > +}
>> > +
>> >  void sun4i_tcon_set_status(struct sun4i_tcon *tcon,
>> >                            const struct drm_encoder *encoder,
>> >                            bool enabled)
>> >  {
>> > +       bool is_lvds = false;
>> >         int channel;
>> >
>> >         switch (encoder->encoder_type) {
>> > +       case DRM_MODE_ENCODER_LVDS:
>> > +               is_lvds = true;
>> > +               /* Fallthrough */
>> >         case DRM_MODE_ENCODER_NONE:
>> >                 channel = 0;
>> >                 break;
>> > @@ -84,10 +171,16 @@ void sun4i_tcon_set_status(struct sun4i_tcon *tcon,
>> >                 return;
>> >         }
>> >
>> > +       if (is_lvds && !enabled)
>> > +               sun4i_tcon_lvds_set_status(tcon, encoder, false);
>> > +
>> >         regmap_update_bits(tcon->regs, SUN4I_TCON_GCTL_REG,
>> >                            SUN4I_TCON_GCTL_TCON_ENABLE,
>> >                            enabled ? SUN4I_TCON_GCTL_TCON_ENABLE : 0);
>> >
>> > +       if (is_lvds && enabled)
>> > +               sun4i_tcon_lvds_set_status(tcon, encoder, true);
>> > +
>> >         sun4i_tcon_channel_set_status(tcon, channel, enabled);
>> >  }
>> >
>> > @@ -170,6 +263,78 @@ static void sun4i_tcon0_mode_set_common(struct sun4i_tcon *tcon,
>> >                      SUN4I_TCON0_BASIC0_Y(mode->crtc_vdisplay));
>> >  }
>> >
>> > +static void sun4i_tcon0_mode_set_lvds(struct sun4i_tcon *tcon,
>> > +                                     const struct drm_encoder *encoder,
>> > +                                     const struct drm_display_mode *mode)
>> > +{
>> > +       unsigned int bp;
>> > +       u8 clk_delay;
>> > +       u32 reg, val = 0;
>> > +
>> > +       tcon->dclk_min_div = 7;
>> > +       tcon->dclk_max_div = 7;
>> > +       sun4i_tcon0_mode_set_common(tcon, mode);
>> > +
>> > +       /* Adjust clock delay */
>> > +       clk_delay = sun4i_tcon_get_clk_delay(mode, 0);
>> > +       regmap_update_bits(tcon->regs, SUN4I_TCON0_CTL_REG,
>> > +                          SUN4I_TCON0_CTL_CLK_DELAY_MASK,
>> > +                          SUN4I_TCON0_CTL_CLK_DELAY(clk_delay));
>> > +
>> > +       /*
>> > +        * This is called a backporch in the register documentation,
>> > +        * but it really is the back porch + hsync
>> > +        */
>> > +       bp = mode->crtc_htotal - mode->crtc_hsync_start;
>> > +       DRM_DEBUG_DRIVER("Setting horizontal total %d, backporch %d\n",
>> > +                        mode->crtc_htotal, bp);
>> > +
>> > +       /* Set horizontal display timings */
>> > +       regmap_write(tcon->regs, SUN4I_TCON0_BASIC1_REG,
>> > +                    SUN4I_TCON0_BASIC1_H_TOTAL(mode->htotal) |
>> > +                    SUN4I_TCON0_BASIC1_H_BACKPORCH(bp));
>> > +
>> > +       /*
>> > +        * This is called a backporch in the register documentation,
>> > +        * but it really is the back porch + hsync
>> > +        */
>> > +       bp = mode->crtc_vtotal - mode->crtc_vsync_start;
>> > +       DRM_DEBUG_DRIVER("Setting vertical total %d, backporch %d\n",
>> > +                        mode->crtc_vtotal, bp);
>> > +
>> > +       /* Set vertical display timings */
>> > +       regmap_write(tcon->regs, SUN4I_TCON0_BASIC2_REG,
>> > +                    SUN4I_TCON0_BASIC2_V_TOTAL(mode->crtc_vtotal * 2) |
>> > +                    SUN4I_TCON0_BASIC2_V_BACKPORCH(bp));
>>
>> Can we move the above to a common function?
>
> Until we have DSI support figured out I'd rather not do too much of
> consolidation. We know already a few things are going to change there
> (like the clk_delay), but it's not clear yet how much.
>
>> > +       /* Map output pins to channel 0 */
>> > +       regmap_update_bits(tcon->regs, SUN4I_TCON_GCTL_REG,
>> > +                          SUN4I_TCON_GCTL_IOMAP_MASK,
>> > +                          SUN4I_TCON_GCTL_IOMAP_TCON0);
>> > +
>> > +       /* Enable the output on the pins */
>> > +       regmap_write(tcon->regs, SUN4I_TCON0_IO_TRI_REG, 0xe0000000);
>>
>> Is this still needed? You are no longer using the TCON LCD pins
>> with LVDS.
>
> We do. It's a separate function of the pins, but it's the same pins.

OK. I assume you've tried it without setting it and it failed?
I just assume that these refer to the TCON LCD output, whereas
LVDS looks like a separate module and function, and shouldn't
need it.

ChenYu

>> >  static const struct sun4i_tcon_quirks sun6i_a31s_quirks = {
>> >         .has_channel_1          = true,
>> > +       .has_lvds_pll           = true,
>>
>> The A31s does not have MIPI.
>
> I'll change that.
>
> Thanks!
> Maxime
>
> --
> Maxime Ripard, Free Electrons
> Embedded Linux and Kernel engineering
> http://free-electrons.com
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v3 08/15] drm/sun4i: Add LVDS support
  2017-12-14  3:30             ` Chen-Yu Tsai
@ 2017-12-14  9:37               ` Maxime Ripard
  0 siblings, 0 replies; 33+ messages in thread
From: Maxime Ripard @ 2017-12-14  9:37 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Daniel Vetter, David Airlie, dri-devel, linux-kernel,
	Mark Rutland, Rob Herring, linux-arm-kernel, Priit Laes,
	Icenowy Zheng, Thomas Petazzoni, Jernej Skrabec, devicetree

[-- Attachment #1: Type: text/plain, Size: 1085 bytes --]

On Thu, Dec 14, 2017 at 11:30:21AM +0800, Chen-Yu Tsai wrote:
> >> > +       /* Map output pins to channel 0 */
> >> > +       regmap_update_bits(tcon->regs, SUN4I_TCON_GCTL_REG,
> >> > +                          SUN4I_TCON_GCTL_IOMAP_MASK,
> >> > +                          SUN4I_TCON_GCTL_IOMAP_TCON0);
> >> > +
> >> > +       /* Enable the output on the pins */
> >> > +       regmap_write(tcon->regs, SUN4I_TCON0_IO_TRI_REG, 0xe0000000);
> >>
> >> Is this still needed? You are no longer using the TCON LCD pins
> >> with LVDS.
> >
> > We do. It's a separate function of the pins, but it's the same pins.
> 
> OK. I assume you've tried it without setting it and it failed?
> I just assume that these refer to the TCON LCD output, whereas
> LVDS looks like a separate module and function, and shouldn't
> need it.

Argh, I forgot to test that. I'll test it for real this time and will
update that part with a comment if that's needed.

Sorry :/

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 33+ messages in thread

end of thread, other threads:[~2017-12-14  9:37 UTC | newest]

Thread overview: 33+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-12-05 15:10 [PATCH v3 00/15] drm/sun4i: Add A83t LVDS support Maxime Ripard
2017-12-05 15:10 ` [PATCH v3 01/15] dt-bindings: panel: lvds: Document power-supply property Maxime Ripard
     [not found]   ` <97ebf0615821d79e8d7718594fe3a542a743a05f.1512486553.git-series.maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
2017-12-06 21:56     ` Rob Herring
2017-12-05 15:10 ` [PATCH v3 03/15] dt-bindings: display: sun4i-drm: Add LVDS properties Maxime Ripard
     [not found]   ` <17851ba6277b69aa9cd81de5eead62bfed271661.1512486553.git-series.maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
2017-12-06 21:57     ` Rob Herring
2017-12-07  3:57     ` Chen-Yu Tsai
2017-12-05 15:10 ` [PATCH v3 04/15] dt-bindings: display: sun4i-drm: Add A83T pipeline Maxime Ripard
     [not found]   ` <3762a8428aaf207e80ae86d4db2e50473576bb6d.1512486553.git-series.maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
2017-12-06 21:59     ` Rob Herring
2017-12-07  3:37       ` Chen-Yu Tsai
2017-12-05 15:10 ` [PATCH v3 05/15] drm/sun4i: Fix error path handling Maxime Ripard
     [not found]   ` <1f2443c41082fc6e086570da38d20744c52fe636.1512486553.git-series.maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
2017-12-05 15:42     ` Chen-Yu Tsai
2017-12-05 15:10 ` [PATCH v3 06/15] drm/sun4i: Force the mixer rate at 150MHz Maxime Ripard
2017-12-05 15:10 ` [PATCH v3 07/15] drm/sun4i: Create minimal multipliers and dividers Maxime Ripard
     [not found] ` <cover.825a49a4c1c565a548f3de0375e7537e7e8fd3a4.1512486553.git-series.maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
2017-12-05 15:10   ` [PATCH v3 02/15] drm/panel: lvds: Add support for the power-supply property Maxime Ripard
2017-12-05 15:10   ` [PATCH v3 08/15] drm/sun4i: Add LVDS support Maxime Ripard
     [not found]     ` <b900e5963180c94ca02bde178b6674622a127787.1512486553.git-series.maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
2017-12-07  6:05       ` Chen-Yu Tsai
2017-12-07 12:25         ` Maxime Ripard
     [not found]           ` <20171207122521.frv5zgaay3sgol6f-ZC1Zs529Oq4@public.gmane.org>
2017-12-14  3:30             ` Chen-Yu Tsai
2017-12-14  9:37               ` Maxime Ripard
2017-12-07 10:14     ` Philippe Ombredanne
     [not found]       ` <CAOFm3uEpnBFUDBHK+SqQ-pGUPcWbGXNrWum4HRJ34tMtoX-2Qw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-12-07 10:50         ` Maxime Ripard
2017-12-05 15:10   ` [PATCH v3 14/15] ARM: dts: sun8i: a711: Reinstate the PMIC compatible Maxime Ripard
     [not found]     ` <25b482f19587ff195582995c11ee9d07f5bf42d2.1512486553.git-series.maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
2017-12-07  3:34       ` Chen-Yu Tsai
2017-12-05 15:10 ` [PATCH v3 09/15] drm/sun4i: Add A83T support Maxime Ripard
2017-12-05 15:42   ` Jernej Škrabec
2017-12-06 16:37     ` Jernej Škrabec
2017-12-07 10:55       ` Maxime Ripard
2017-12-05 15:10 ` [PATCH v3 10/15] ARM: dts: sun8i: a83t: Add display pipeline Maxime Ripard
     [not found]   ` <97d3cee9d0d7a92893f646d72643bac520de5f05.1512486553.git-series.maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
2017-12-07  4:02     ` Chen-Yu Tsai
2017-12-05 15:10 ` [PATCH v3 11/15] ARM: dts: sun8i: a83t: Enable the PWM Maxime Ripard
2017-12-05 15:10 ` [PATCH v3 12/15] ARM: dts: sun8i: a83t: Add LVDS pins group Maxime Ripard
2017-12-05 15:10 ` [PATCH v3 13/15] ARM: dts: sun8i: a83t: Add the PWM pin group Maxime Ripard
2017-12-05 15:10 ` [PATCH v3 15/15] ARM: dts: sun8i: a711: Enable the LCD Maxime Ripard

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).