dri-devel.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/19] drm/sun4i: hdmi: Support HDMI controller on A31
@ 2017-06-02 10:10 Chen-Yu Tsai
  2017-06-02 10:10 ` [PATCH 02/19] drm/sun4i: add components in two passes with encoders added in second pass Chen-Yu Tsai
                   ` (2 more replies)
  0 siblings, 3 replies; 38+ messages in thread
From: Chen-Yu Tsai @ 2017-06-02 10:10 UTC (permalink / raw)
  To: Maxime Ripard, David Airlie, Rob Herring, Michael Turquette,
	Stephen Boyd
  Cc: Chen-Yu Tsai, dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

Hi everyone,

This series adds support for the HDMI controller found on Allwinner
A31/A31s SoCs. It builds upon Maxime's work that added support for
the HDMI controller on the Allwinner A10s SoC.

The HDMI controllers in the older generation Allwinner SoCs is very
similar. The A10/A10s/A20 all have the same hardware block, with the
A10 having slightly different initial configuration values. The A31's
variant splits out the DDC parent clock, has different formulas for
the DDC and TMDS clocks, and a different register layout for the DDC
block. Also, it does not expose the CEC pins outside of the SoC, which
is unfortunate.

The first 2 patches allow the sun4i-drm driver to work correctly with
2 display pipelines.

Patch 3 adds support for the TCON demuxing feature on the A31. This is
needed if the user wants to output through HDMI from the second display
pipeline.

Patch 4 adds proper error path cleanup to the HDMI driver.

Patch 5 allows the HDMI TMDS clock to use the second PLL as its parent,
in case the first PLL is driving an incompatible dot clock.

Patch 6 adds the A31 HDMI controller variant to the device tree binding.

Patch 7 adds support for different variants of the TMDS clock, with the
different being an offset value for the divider.

Patch 8 adds support for the A31's TMDS clock variant.

Patch 9 adds support for different variants of the DDC clock, with the
differences being a different register offset, different divider offset,
different pre-divider, and different clock parent.

Patch 10 renames the HDMI block's DDC clock, so that it doesn't conflict
with the A31's SoC level HDMI DDC clock.

Patch 11 adds defines for the A31 specific DDC register offsets.

Patch 12 adds support for the A31's DDC clock variant.

Patch 13 adds support for different variants of the HDMI controller
hardware, with the differences mentioned in the beginning of this
letter.

Patch 14 adds support for the A31's HDMI controller variant.

Patch 15 exports the 2x outputs of the two video PLLs. These feed the
TMDS clock directly.

Patch 16 adds a device node for the HDMI controller on the A31.

Patches 17~19 enable HDMI video output on three boards that I have.


Patches 13 & 14 are somewhat complicated. If the DDC block were factored
out into a proper I2C controller, it might be cleaner. Other than that
this series should be quite straightforward.

I also had simultaneous output on both display pipelines on the SinA31s,
one with an LCD panel and the other using HDMI. After boot, both screens
showed a proper console. The HDMI screen had higher resolution, so the
console was limited to the upper left corner.


Regards
ChenYu

Chen-Yu Tsai (19):
  drm/sun4i: call drm_vblank_init with correct number of crtcs
  drm/sun4i: add components in two passes with encoders added in second
    pass
  drm/sun4i: tcon: Add support for demuxing TCON output on A31
  drm/sun4i: hdmi: Disable clks in bind function error path and unbind
    function
  drm/sun4i: hdmi: Allow using second PLL as TMDS clk parent
  dt-bindings: display: sun4i: Add binding for A31 HDMI controller
  drm/sun4i: hdmi: Support different variants of the TMDS clock
  drm/sun4i: hdmi: Support the TMDS clock in the A31's HDMI controller
  drm/sun4i: hdmi: Support different variants of the DDC clock
  drm/sun4i: hdmi: Rename internal DDC clock to avoid name collision
  drm/sun4i: hdmi: Add A31 specific DDC register definitions
  drm/sun4i: hdmi: Support the DDC clock in the A31's HDMI controller
  drm/sun4i: hdmi: Add support for controller hardware variants
  drm/sun4i: hdmi: Add support for A31's HDMI controller
  clk: sunxi-ng: sun6i: Export video PLLs
  ARM: sun6i: a31: Add device node for HDMI controller
  ARM: sun6i: a31: Enable HDMI support on the A31 Hummingbird
  ARM: sun6i: a31s: Enable HDMI display output on the Sinlinx SinA31s
  ARM: sun6i: a31s: Enable HDMI display output on the MSI Primo81 tablet

 .../bindings/display/sunxi/sun4i-drm.txt           |   3 +
 arch/arm/boot/dts/sun6i-a31-hummingbird.dts        |  21 ++
 arch/arm/boot/dts/sun6i-a31.dtsi                   |  55 ++++
 arch/arm/boot/dts/sun6i-a31s-primo81.dts           |  25 ++
 arch/arm/boot/dts/sun6i-a31s-sina31s.dts           |  25 ++
 drivers/clk/sunxi-ng/ccu-sun6i-a31.c               |   2 +-
 drivers/clk/sunxi-ng/ccu-sun6i-a31.h               |   8 +-
 drivers/gpu/drm/sun4i/sun4i_drv.c                  |  34 ++-
 drivers/gpu/drm/sun4i/sun4i_hdmi.h                 |  39 +++
 drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c         |  55 +++-
 drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c             | 280 ++++++++++++++++++---
 drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c        |  82 +++---
 drivers/gpu/drm/sun4i/sun4i_tcon.c                 |  61 +++++
 include/dt-bindings/clock/sun6i-a31-ccu.h          |   4 +
 14 files changed, 613 insertions(+), 81 deletions(-)

-- 
2.11.0

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

* [PATCH 01/19] drm/sun4i: call drm_vblank_init with correct number of crtcs
       [not found] ` <20170602101024.18940-1-wens-jdAy2FN1RRM@public.gmane.org>
@ 2017-06-02 10:10   ` Chen-Yu Tsai
  2017-06-02 10:10   ` [PATCH 03/19] drm/sun4i: tcon: Add support for demuxing TCON output on A31 Chen-Yu Tsai
                     ` (15 subsequent siblings)
  16 siblings, 0 replies; 38+ messages in thread
From: Chen-Yu Tsai @ 2017-06-02 10:10 UTC (permalink / raw)
  To: Maxime Ripard, David Airlie, Rob Herring, Michael Turquette,
	Stephen Boyd
  Cc: Chen-Yu Tsai, dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

If we want to have vblank on both pipelines at the same time, we need
to call drm_vblank_init with num_crtcs = 2.

Instead, since the crtc init calls correctly set mode_config.num_crtc,
we can move the drm_vblank_init call to after the crtc init code is
called, which is the component bind part. Then we can just pass
mode_config.num_crtc in.

Signed-off-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
---
 drivers/gpu/drm/sun4i/sun4i_drv.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c
index f19100c91c2b..ed75a779ae4b 100644
--- a/drivers/gpu/drm/sun4i/sun4i_drv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
@@ -100,11 +100,6 @@ static int sun4i_drv_bind(struct device *dev)
 		goto free_drm;
 	}
 
-	/* drm_vblank_init calls kcalloc, which can fail */
-	ret = drm_vblank_init(drm, 1);
-	if (ret)
-		goto free_mem_region;
-
 	drm_mode_config_init(drm);
 
 	ret = component_bind_all(drm->dev, drm);
@@ -113,6 +108,11 @@ static int sun4i_drv_bind(struct device *dev)
 		goto cleanup_mode_config;
 	}
 
+	/* drm_vblank_init calls kcalloc, which can fail */
+	ret = drm_vblank_init(drm, drm->mode_config.num_crtc);
+	if (ret)
+		goto free_mem_region;
+
 	drm->irq_enabled = true;
 
 	/* Remove early framebuffers (ie. simplefb) */
-- 
2.11.0

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

* [PATCH 02/19] drm/sun4i: add components in two passes with encoders added in second pass
  2017-06-02 10:10 [PATCH 00/19] drm/sun4i: hdmi: Support HDMI controller on A31 Chen-Yu Tsai
@ 2017-06-02 10:10 ` Chen-Yu Tsai
  2017-06-02 19:18   ` Maxime Ripard
  2017-06-02 10:10 ` [PATCH 07/19] drm/sun4i: hdmi: Support different variants of the TMDS clock Chen-Yu Tsai
       [not found] ` <20170602101024.18940-1-wens-jdAy2FN1RRM@public.gmane.org>
  2 siblings, 1 reply; 38+ messages in thread
From: Chen-Yu Tsai @ 2017-06-02 10:10 UTC (permalink / raw)
  To: Maxime Ripard, David Airlie, Rob Herring, Michael Turquette,
	Stephen Boyd
  Cc: Chen-Yu Tsai, dri-devel, linux-arm-kernel, devicetree, linux-clk,
	linux-sunxi

The encoder drivers use drm_of_find_possible_crtcs to get upstream
crtcs from the device tree using of_graph. For the results to be
correct, encoders must be probed/bound after _all_ crtcs have been
created. The existing code uses a depth first recursive traversal
of the of_graph, which means the encoders downstream of the TCON
get add right after the first TCON. The second TCON or CRTC will
never be properly associated with encoders connected to it.

Other platforms, such as Rockchip, deal with this by probing all
crtcs first, then all subsequent components. This is easy to do
since the crtcs correspond to just one device node, and are the
first nodes in the pipeline.

However with Allwinner SoCs, the function of the CRTC is split between
the display backend (DE 1.0) or mixer (DE 2.0), which does scan-out
and compositing, and the TCON, which generating the display timing
signals. Further complicating the process, there may be a Dynamic Range
Controller between the backend and the TCON. Also, the backend is
preceded by the frontend, with a Display Enhancement Unit possibly
in between.

One solution would be, instead of a depth first traversal of the
component of_graph, we do a breadth first traversal, so that components
at the same depth are grouped together. This however requires us to
implement extra code for a queue structure that is only used here.

Instead, since we can identify TCON device nodes, and since the
component system can gracefully deal with duplicate entries, we can add
components in two passes, using the existing recursive depth code. The
first pass stops right after the TCON is added. The second pass will
re-add all components up to the TCON, but these will be skipped since
they will have already been bound with the entries from the first pass.
The encoders added in the second pass will be the last entries in the
list.

Signed-off-by: Chen-Yu Tsai <wens@csie.org>
---
 drivers/gpu/drm/sun4i/sun4i_drv.c | 24 ++++++++++++++++++++----
 1 file changed, 20 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c
index ed75a779ae4b..bc13dcf06783 100644
--- a/drivers/gpu/drm/sun4i/sun4i_drv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
@@ -198,7 +198,8 @@ static int compare_of(struct device *dev, void *data)
 
 static int sun4i_drv_add_endpoints(struct device *dev,
 				   struct component_match **match,
-				   struct device_node *node)
+				   struct device_node *node,
+				   bool add_encoders)
 {
 	struct device_node *port, *ep, *remote;
 	int count = 0;
@@ -227,13 +228,16 @@ static int sun4i_drv_add_endpoints(struct device *dev,
 		count++;
 	}
 
+	/* Skip downstream encoders during the first pass */
+	if (sun4i_drv_node_is_tcon(node) && !add_encoders)
+		return count;
+
 	/* Inputs are listed first, then outputs */
 	port = of_graph_get_port_by_id(node, 1);
 	if (!port) {
 		DRM_DEBUG_DRIVER("No output to bind\n");
 		return count;
 	}
-
 	for_each_available_child_of_node(port, ep) {
 		remote = of_graph_get_remote_port_parent(ep);
 		if (!remote) {
@@ -262,7 +266,8 @@ static int sun4i_drv_add_endpoints(struct device *dev,
 		}
 
 		/* Walk down our tree */
-		count += sun4i_drv_add_endpoints(dev, match, remote);
+		count += sun4i_drv_add_endpoints(dev, match, remote,
+						 add_encoders);
 
 		of_node_put(remote);
 	}
@@ -283,8 +288,19 @@ static int sun4i_drv_probe(struct platform_device *pdev)
 		if (!pipeline)
 			break;
 
+		sun4i_drv_add_endpoints(&pdev->dev, &match, pipeline, false);
+		of_node_put(pipeline);
+	}
+
+	for (i = 0;; i++) {
+		struct device_node *pipeline = of_parse_phandle(np,
+								"allwinner,pipelines",
+								i);
+		if (!pipeline)
+			break;
+
 		count += sun4i_drv_add_endpoints(&pdev->dev, &match,
-						pipeline);
+						 pipeline, true);
 		of_node_put(pipeline);
 
 		DRM_DEBUG_DRIVER("Queued %d outputs on pipeline %d\n",
-- 
2.11.0


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

* [PATCH 03/19] drm/sun4i: tcon: Add support for demuxing TCON output on A31
       [not found] ` <20170602101024.18940-1-wens-jdAy2FN1RRM@public.gmane.org>
  2017-06-02 10:10   ` [PATCH 01/19] drm/sun4i: call drm_vblank_init with correct number of crtcs Chen-Yu Tsai
@ 2017-06-02 10:10   ` Chen-Yu Tsai
  2017-06-02 10:10   ` [PATCH 04/19] drm/sun4i: hdmi: Disable clks in bind function error path and unbind function Chen-Yu Tsai
                     ` (14 subsequent siblings)
  16 siblings, 0 replies; 38+ messages in thread
From: Chen-Yu Tsai @ 2017-06-02 10:10 UTC (permalink / raw)
  To: Maxime Ripard, David Airlie, Rob Herring, Michael Turquette,
	Stephen Boyd
  Cc: Chen-Yu Tsai, dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

On systems with 2 TCONs such as the A31, it is possible to demux the
output of the TCONs to one encoder.

Add support for this for the A31.

Signed-off-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
---
 drivers/gpu/drm/sun4i/sun4i_tcon.c | 61 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 61 insertions(+)

diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index d9791292553e..21bd7fab7aaa 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -14,9 +14,12 @@
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_crtc_helper.h>
+#include <drm/drm_encoder.h>
 #include <drm/drm_modes.h>
 #include <drm/drm_of.h>
 
+#include <uapi/drm/drm_mode.h>
+
 #include <linux/component.h>
 #include <linux/ioport.h>
 #include <linux/of_address.h>
@@ -109,11 +112,69 @@ void sun4i_tcon_enable_vblank(struct sun4i_tcon *tcon, bool enable)
 }
 EXPORT_SYMBOL(sun4i_tcon_enable_vblank);
 
+static struct sun4i_tcon *sun4i_get_first_tcon(struct drm_device *drm)
+{
+	struct sun4i_drv *drv = drm->dev_private;
+	struct sun4i_tcon *tcon;
+
+	list_for_each_entry(tcon, &drv->tcon_list, list)
+		if (tcon->id == 0)
+			return tcon;
+
+	dev_warn(drm->dev,
+		 "TCON0 not found, display output muxing may not work\n");
+
+	return tcon;
+}
+
+static int _sun6i_tcon_set_mux(struct drm_encoder *encoder)
+{
+	struct sun4i_tcon *tcon = sun4i_get_first_tcon(encoder->dev);
+	int tcon_id = drm_crtc_to_sun4i_crtc(encoder->crtc)->tcon->id;
+	u32 shift;
+
+	DRM_DEBUG_DRIVER("Muxing encoder %s to CRTC %s (TCON %d)\n",
+			 encoder->name, encoder->crtc->name, tcon_id);
+
+	/* Only 2 TCONs */
+	if (tcon_id >= 2)
+		return -EINVAL;
+
+	switch (encoder->encoder_type) {
+	case DRM_MODE_ENCODER_TMDS:
+		/* HDMI */
+		shift = 8;
+		break;
+	case DRM_MODE_ENCODER_DSI:
+		/* No MIPI DSI on A31s */
+		if (of_device_is_compatible(tcon->dev->of_node,
+					    "allwinner,sun6i-a31s-tcon"))
+			return -EINVAL;
+		shift = 0;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	regmap_update_bits(tcon->regs, SUN4I_TCON_MUX_CTRL_REG,
+			   0x3 << shift, tcon_id << shift);
+
+	return 0;
+}
+
 void sun4i_tcon_set_mux(struct sun4i_tcon *tcon, int channel,
 			struct drm_encoder *encoder)
 {
+	/* Get the device node of the display engine */
+	struct device_node *node = encoder->dev->dev->of_node;
 	u32 val;
 
+	if (of_device_is_compatible(node, "allwinner,sun6i-a31-display-engine") ||
+	    of_device_is_compatible(node, "allwinner,sun6i-a31s-display-engine")) {
+		_sun6i_tcon_set_mux(encoder);
+		return;
+	}
+
 	if (!tcon->quirks->has_unknown_mux)
 		return;
 
-- 
2.11.0

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

* [PATCH 04/19] drm/sun4i: hdmi: Disable clks in bind function error path and unbind function
       [not found] ` <20170602101024.18940-1-wens-jdAy2FN1RRM@public.gmane.org>
  2017-06-02 10:10   ` [PATCH 01/19] drm/sun4i: call drm_vblank_init with correct number of crtcs Chen-Yu Tsai
  2017-06-02 10:10   ` [PATCH 03/19] drm/sun4i: tcon: Add support for demuxing TCON output on A31 Chen-Yu Tsai
@ 2017-06-02 10:10   ` Chen-Yu Tsai
  2017-06-02 10:10   ` [PATCH 05/19] drm/sun4i: hdmi: Allow using second PLL as TMDS clk parent Chen-Yu Tsai
                     ` (13 subsequent siblings)
  16 siblings, 0 replies; 38+ messages in thread
From: Chen-Yu Tsai @ 2017-06-02 10:10 UTC (permalink / raw)
  To: Maxime Ripard, David Airlie, Rob Herring, Michael Turquette,
	Stephen Boyd
  Cc: Chen-Yu Tsai, dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

The HDMI driver enables the bus and mod clocks in the bind function, but
does not disable them if it then bails our due to any errors. Neither
does it disable the clocks in the unbind function.

Fix this by adding a proper error path to the bind function, and
clk_disable_unprepare calls to the unbind function.

Also rename the err_cleanup_connector label to err_cleanup_encoder,
since it is the encoder that gets cleaned up.

Signed-off-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
---
 drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 25 +++++++++++++++++--------
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
index d3398f6250ef..457614073501 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
@@ -350,26 +350,29 @@ static int sun4i_hdmi_bind(struct device *dev, struct device *master,
 	hdmi->mod_clk = devm_clk_get(dev, "mod");
 	if (IS_ERR(hdmi->mod_clk)) {
 		dev_err(dev, "Couldn't get the HDMI mod clock\n");
-		return PTR_ERR(hdmi->mod_clk);
+		ret = PTR_ERR(hdmi->mod_clk);
+		goto err_disable_bus_clk;
 	}
 	clk_prepare_enable(hdmi->mod_clk);
 
 	hdmi->pll0_clk = devm_clk_get(dev, "pll-0");
 	if (IS_ERR(hdmi->pll0_clk)) {
 		dev_err(dev, "Couldn't get the HDMI PLL 0 clock\n");
-		return PTR_ERR(hdmi->pll0_clk);
+		ret = PTR_ERR(hdmi->pll0_clk);
+		goto err_disable_mod_clk;
 	}
 
 	hdmi->pll1_clk = devm_clk_get(dev, "pll-1");
 	if (IS_ERR(hdmi->pll1_clk)) {
 		dev_err(dev, "Couldn't get the HDMI PLL 1 clock\n");
-		return PTR_ERR(hdmi->pll1_clk);
+		ret = PTR_ERR(hdmi->pll1_clk);
+		goto err_disable_mod_clk;
 	}
 
 	ret = sun4i_tmds_create(hdmi);
 	if (ret) {
 		dev_err(dev, "Couldn't create the TMDS clock\n");
-		return ret;
+		goto err_disable_mod_clk;
 	}
 
 	writel(SUN4I_HDMI_CTRL_ENABLE, hdmi->base + SUN4I_HDMI_CTRL_REG);
@@ -410,7 +413,7 @@ static int sun4i_hdmi_bind(struct device *dev, struct device *master,
 	ret = sun4i_ddc_create(hdmi, hdmi->tmds_clk);
 	if (ret) {
 		dev_err(dev, "Couldn't create the DDC clock\n");
-		return ret;
+		goto err_disable_mod_clk;
 	}
 
 	drm_encoder_helper_add(&hdmi->encoder,
@@ -428,7 +431,7 @@ static int sun4i_hdmi_bind(struct device *dev, struct device *master,
 	hdmi->encoder.possible_crtcs = drm_of_find_possible_crtcs(drm,
 								  dev->of_node);
 	if (!hdmi->encoder.possible_crtcs)
-		return -EPROBE_DEFER;
+		goto err_disable_mod_clk;
 
 	drm_connector_helper_add(&hdmi->connector,
 				 &sun4i_hdmi_connector_helper_funcs);
@@ -438,7 +441,7 @@ static int sun4i_hdmi_bind(struct device *dev, struct device *master,
 	if (ret) {
 		dev_err(dev,
 			"Couldn't initialise the HDMI connector\n");
-		goto err_cleanup_connector;
+		goto err_cleanup_encoder;
 	}
 
 	/* There is no HPD interrupt, so we need to poll the controller */
@@ -449,8 +452,12 @@ static int sun4i_hdmi_bind(struct device *dev, struct device *master,
 
 	return 0;
 
-err_cleanup_connector:
+err_cleanup_encoder:
 	drm_encoder_cleanup(&hdmi->encoder);
+err_disable_mod_clk:
+	clk_disable_unprepare(hdmi->mod_clk);
+err_disable_bus_clk:
+	clk_disable_unprepare(hdmi->bus_clk);
 	return ret;
 }
 
@@ -461,6 +468,8 @@ static void sun4i_hdmi_unbind(struct device *dev, struct device *master,
 
 	drm_connector_cleanup(&hdmi->connector);
 	drm_encoder_cleanup(&hdmi->encoder);
+	clk_disable_unprepare(hdmi->mod_clk);
+	clk_disable_unprepare(hdmi->bus_clk);
 }
 
 static const struct component_ops sun4i_hdmi_ops = {
-- 
2.11.0

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

* [PATCH 05/19] drm/sun4i: hdmi: Allow using second PLL as TMDS clk parent
       [not found] ` <20170602101024.18940-1-wens-jdAy2FN1RRM@public.gmane.org>
                     ` (2 preceding siblings ...)
  2017-06-02 10:10   ` [PATCH 04/19] drm/sun4i: hdmi: Disable clks in bind function error path and unbind function Chen-Yu Tsai
@ 2017-06-02 10:10   ` Chen-Yu Tsai
  2017-06-02 10:10   ` [PATCH 06/19] dt-bindings: display: sun4i: Add binding for A31 HDMI controller Chen-Yu Tsai
                     ` (12 subsequent siblings)
  16 siblings, 0 replies; 38+ messages in thread
From: Chen-Yu Tsai @ 2017-06-02 10:10 UTC (permalink / raw)
  To: Maxime Ripard, David Airlie, Rob Herring, Michael Turquette,
	Stephen Boyd
  Cc: Chen-Yu Tsai, dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

On SoCs with two display pipelines, it is possible that the two
pipelines are active at the same time, with potentially incompatible
dot clocks.

Let the HDMI encoder's TMDS clock go through all of its parents when
calculating possible clock rates. This allows usage of the second video
PLL as its parent.

Signed-off-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
---
 drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c | 51 ++++++++++++++++-------------
 1 file changed, 28 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c
index 5cf2527bffc8..5692e41833ae 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c
@@ -71,7 +71,7 @@ static int sun4i_tmds_determine_rate(struct clk_hw *hw,
 	unsigned long best_parent = 0;
 	unsigned long rate = req->rate;
 	int best_div = 1, best_half = 1;
-	int i, j;
+	int i, j, p;
 
 	/*
 	 * We only consider PLL3, since the TCON is very likely to be
@@ -79,32 +79,37 @@ static int sun4i_tmds_determine_rate(struct clk_hw *hw,
 	 * clock, so we should not need to do anything.
 	 */
 
-	parent = clk_hw_get_parent_by_index(hw, 0);
-	if (!parent)
-		return -EINVAL;
-
-	for (i = 1; i < 3; i++) {
-		for (j = 1; j < 16; j++) {
-			unsigned long ideal = rate * i * j;
-			unsigned long rounded;
-
-			rounded = clk_hw_round_rate(parent, ideal);
-
-			if (rounded == ideal) {
-				best_parent = rounded;
-				best_half = i;
-				best_div = j;
-				goto out;
-			}
-
-			if (abs(rate - rounded / i) <
-			    abs(rate - best_parent / best_div)) {
-				best_parent = rounded;
-				best_div = i;
+	for (p = 0; p < clk_hw_get_num_parents(hw); p++) {
+		parent = clk_hw_get_parent_by_index(hw, p);
+		if (!parent)
+			continue;
+
+		for (i = 1; i < 3; i++) {
+			for (j = 1; j < 16; j++) {
+				unsigned long ideal = rate * i * j;
+				unsigned long rounded;
+
+				rounded = clk_hw_round_rate(parent, ideal);
+
+				if (rounded == ideal) {
+					best_parent = rounded;
+					best_half = i;
+					best_div = j;
+					goto out;
+				}
+
+				if (abs(rate - rounded / i) <
+				    abs(rate - best_parent / best_div)) {
+					best_parent = rounded;
+					best_div = i;
+				}
 			}
 		}
 	}
 
+	if (!parent)
+		return -EINVAL;
+
 out:
 	req->rate = best_parent / best_half / best_div;
 	req->best_parent_rate = best_parent;
-- 
2.11.0

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

* [PATCH 06/19] dt-bindings: display: sun4i: Add binding for A31 HDMI controller
       [not found] ` <20170602101024.18940-1-wens-jdAy2FN1RRM@public.gmane.org>
                     ` (3 preceding siblings ...)
  2017-06-02 10:10   ` [PATCH 05/19] drm/sun4i: hdmi: Allow using second PLL as TMDS clk parent Chen-Yu Tsai
@ 2017-06-02 10:10   ` Chen-Yu Tsai
       [not found]     ` <20170602101024.18940-7-wens-jdAy2FN1RRM@public.gmane.org>
  2017-06-02 10:10   ` [PATCH 08/19] drm/sun4i: hdmi: Support the TMDS clock in the A31's " Chen-Yu Tsai
                     ` (11 subsequent siblings)
  16 siblings, 1 reply; 38+ messages in thread
From: Chen-Yu Tsai @ 2017-06-02 10:10 UTC (permalink / raw)
  To: Maxime Ripard, David Airlie, Rob Herring, Michael Turquette,
	Stephen Boyd
  Cc: Chen-Yu Tsai, dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

The HDMI controller in the A31 SoC is slightly different from the
earlier version. In addition to the TMDS clock and DDC controls,
this version now takes a second DDC clock input.

Add a compatible string for it, and add the DDC clock input to the
list of clocks required.

Signed-off-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
---
 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 b83e6018041d..d23e7cad19d0 100644
--- a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
+++ b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
@@ -23,14 +23,17 @@ CEC. It is one end of the pipeline.
 Required properties:
   - compatible: value must be one of:
     * allwinner,sun5i-a10s-hdmi
+    * allwinner,sun6i-a31-hdmi
   - reg: base address and size of memory-mapped region
   - interrupts: interrupt associated to this IP
   - clocks: phandles to the clocks feeding the HDMI encoder
     * ahb: the HDMI interface clock
     * mod: the HDMI module clock
+    * ddc: the HDMI ddc clock (A31 only)
     * pll-0: the first video PLL
     * pll-1: the second video PLL
   - clock-names: the clock names mentioned above
+  - resets: phandle to the reset control for the HDMI encoder (A31 only)
   - dmas: phandles to the DMA channels used by the HDMI encoder
     * ddc-tx: The channel for DDC transmission
     * ddc-rx: The channel for DDC reception
-- 
2.11.0

--
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] 38+ messages in thread

* [PATCH 07/19] drm/sun4i: hdmi: Support different variants of the TMDS clock
  2017-06-02 10:10 [PATCH 00/19] drm/sun4i: hdmi: Support HDMI controller on A31 Chen-Yu Tsai
  2017-06-02 10:10 ` [PATCH 02/19] drm/sun4i: add components in two passes with encoders added in second pass Chen-Yu Tsai
@ 2017-06-02 10:10 ` Chen-Yu Tsai
       [not found] ` <20170602101024.18940-1-wens-jdAy2FN1RRM@public.gmane.org>
  2 siblings, 0 replies; 38+ messages in thread
From: Chen-Yu Tsai @ 2017-06-02 10:10 UTC (permalink / raw)
  To: Maxime Ripard, David Airlie, Rob Herring, Michael Turquette,
	Stephen Boyd
  Cc: Chen-Yu Tsai, dri-devel, linux-arm-kernel, devicetree, linux-clk,
	linux-sunxi

On the A31, the HDMI TMDS clock has a different value offset for the
divider.

This patch adds support for custom offsets to the TMDS clock.

Signed-off-by: Chen-Yu Tsai <wens@csie.org>
---
 drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c | 26 +++++++++++++++++++-------
 1 file changed, 19 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c
index 5692e41833ae..3c304e1fbe3b 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c
@@ -18,6 +18,8 @@
 struct sun4i_tmds {
 	struct clk_hw		hw;
 	struct sun4i_hdmi	*hdmi;
+
+	u8			div_offset;
 };
 
 static inline struct sun4i_tmds *hw_to_tmds(struct clk_hw *hw)
@@ -28,6 +30,7 @@ static inline struct sun4i_tmds *hw_to_tmds(struct clk_hw *hw)
 
 static unsigned long sun4i_tmds_calc_divider(unsigned long rate,
 					     unsigned long parent_rate,
+					     u8 div_offset,
 					     u8 *div,
 					     bool *half)
 {
@@ -35,7 +38,7 @@ static unsigned long sun4i_tmds_calc_divider(unsigned long rate,
 	u8 best_m = 0, m;
 	bool is_double;
 
-	for (m = 1; m < 16; m++) {
+	for (m = div_offset ?: 1; m < (16 + div_offset); m++) {
 		u8 d;
 
 		for (d = 1; d < 3; d++) {
@@ -67,7 +70,8 @@ static unsigned long sun4i_tmds_calc_divider(unsigned long rate,
 static int sun4i_tmds_determine_rate(struct clk_hw *hw,
 				     struct clk_rate_request *req)
 {
-	struct clk_hw *parent;
+	struct sun4i_tmds *tmds = hw_to_tmds(hw);
+	struct clk_hw *parent = NULL;
 	unsigned long best_parent = 0;
 	unsigned long rate = req->rate;
 	int best_div = 1, best_half = 1;
@@ -85,7 +89,8 @@ static int sun4i_tmds_determine_rate(struct clk_hw *hw,
 			continue;
 
 		for (i = 1; i < 3; i++) {
-			for (j = 1; j < 16; j++) {
+			for (j = tmds->div_offset ?: 1;
+			     j < (16 + tmds->div_offset); j++) {
 				unsigned long ideal = rate * i * j;
 				unsigned long rounded;
 
@@ -129,7 +134,7 @@ static unsigned long sun4i_tmds_recalc_rate(struct clk_hw *hw,
 		parent_rate /= 2;
 
 	reg = readl(tmds->hdmi->base + SUN4I_HDMI_PLL_CTRL_REG);
-	reg = (reg >> 4) & 0xf;
+	reg = ((reg >> 4) & 0xf) + tmds->div_offset;
 	if (!reg)
 		reg = 1;
 
@@ -144,7 +149,8 @@ static int sun4i_tmds_set_rate(struct clk_hw *hw, unsigned long rate,
 	u32 reg;
 	u8 div;
 
-	sun4i_tmds_calc_divider(rate, parent_rate, &div, &half);
+	sun4i_tmds_calc_divider(rate, parent_rate, tmds->div_offset,
+				&div, &half);
 
 	reg = readl(tmds->hdmi->base + SUN4I_HDMI_PAD_CTRL1_REG);
 	reg &= ~SUN4I_HDMI_PAD_CTRL1_HALVE_CLK;
@@ -154,7 +160,7 @@ static int sun4i_tmds_set_rate(struct clk_hw *hw, unsigned long rate,
 
 	reg = readl(tmds->hdmi->base + SUN4I_HDMI_PLL_CTRL_REG);
 	reg &= ~SUN4I_HDMI_PLL_CTRL_DIV_MASK;
-	writel(reg | SUN4I_HDMI_PLL_CTRL_DIV(div),
+	writel(reg | SUN4I_HDMI_PLL_CTRL_DIV(div - tmds->div_offset),
 	       tmds->hdmi->base + SUN4I_HDMI_PLL_CTRL_REG);
 
 	return 0;
@@ -195,7 +201,7 @@ static const struct clk_ops sun4i_tmds_ops = {
 	.set_parent	= sun4i_tmds_set_parent,
 };
 
-int sun4i_tmds_create(struct sun4i_hdmi *hdmi)
+static int _sun4i_tmds_create(struct sun4i_hdmi *hdmi, u8 div_offset)
 {
 	struct clk_init_data init;
 	struct sun4i_tmds *tmds;
@@ -221,6 +227,7 @@ int sun4i_tmds_create(struct sun4i_hdmi *hdmi)
 
 	tmds->hdmi = hdmi;
 	tmds->hw.init = &init;
+	tmds->div_offset = div_offset;
 
 	hdmi->tmds_clk = devm_clk_register(hdmi->dev, &tmds->hw);
 	if (IS_ERR(hdmi->tmds_clk))
@@ -228,3 +235,8 @@ int sun4i_tmds_create(struct sun4i_hdmi *hdmi)
 
 	return 0;
 }
+
+int sun4i_tmds_create(struct sun4i_hdmi *hdmi)
+{
+	return _sun4i_tmds_create(hdmi, 0);
+}
-- 
2.11.0


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

* [PATCH 08/19] drm/sun4i: hdmi: Support the TMDS clock in the A31's HDMI controller
       [not found] ` <20170602101024.18940-1-wens-jdAy2FN1RRM@public.gmane.org>
                     ` (4 preceding siblings ...)
  2017-06-02 10:10   ` [PATCH 06/19] dt-bindings: display: sun4i: Add binding for A31 HDMI controller Chen-Yu Tsai
@ 2017-06-02 10:10   ` Chen-Yu Tsai
  2017-06-02 10:10   ` [PATCH 09/19] drm/sun4i: hdmi: Support different variants of the DDC clock Chen-Yu Tsai
                     ` (10 subsequent siblings)
  16 siblings, 0 replies; 38+ messages in thread
From: Chen-Yu Tsai @ 2017-06-02 10:10 UTC (permalink / raw)
  To: Maxime Ripard, David Airlie, Rob Herring, Michael Turquette,
	Stephen Boyd
  Cc: Chen-Yu Tsai, dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

The A31's HDMI controller's TMDS clock is slightly different.
There is an offset of 1 between the divider value and the actual
value programmed into the registers.

Signed-off-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
---
 drivers/gpu/drm/sun4i/sun4i_hdmi.h          | 1 +
 drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c | 7 +++++++
 2 files changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi.h b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
index 2f2f2ff1ea63..3a4987ab8da8 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi.h
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
@@ -153,5 +153,6 @@ struct sun4i_hdmi {
 
 int sun4i_ddc_create(struct sun4i_hdmi *hdmi, struct clk *clk);
 int sun4i_tmds_create(struct sun4i_hdmi *hdmi);
+int sun6i_tmds_create(struct sun4i_hdmi *hdmi);
 
 #endif /* _SUN4I_HDMI_H_ */
diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c
index 3c304e1fbe3b..6f25c7bd887e 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c
@@ -240,3 +240,10 @@ int sun4i_tmds_create(struct sun4i_hdmi *hdmi)
 {
 	return _sun4i_tmds_create(hdmi, 0);
 }
+
+/* sun6i variant has a different value offset for the divider */
+
+int sun6i_tmds_create(struct sun4i_hdmi *hdmi)
+{
+	return _sun4i_tmds_create(hdmi, 1);
+}
-- 
2.11.0

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

* [PATCH 09/19] drm/sun4i: hdmi: Support different variants of the DDC clock
       [not found] ` <20170602101024.18940-1-wens-jdAy2FN1RRM@public.gmane.org>
                     ` (5 preceding siblings ...)
  2017-06-02 10:10   ` [PATCH 08/19] drm/sun4i: hdmi: Support the TMDS clock in the A31's " Chen-Yu Tsai
@ 2017-06-02 10:10   ` Chen-Yu Tsai
  2017-06-02 10:10   ` [PATCH 10/19] drm/sun4i: hdmi: Rename internal DDC clock to avoid name collision Chen-Yu Tsai
                     ` (9 subsequent siblings)
  16 siblings, 0 replies; 38+ messages in thread
From: Chen-Yu Tsai @ 2017-06-02 10:10 UTC (permalink / raw)
  To: Maxime Ripard, David Airlie, Rob Herring, Michael Turquette,
	Stephen Boyd
  Cc: Chen-Yu Tsai, dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

On the A31, the HDMI DDC block is different from the one in the
other SoCs. As far as the DDC clock goes, it has no pre-divider,
as it is clocked from a slower parent clock, not the TMDS clock.
The divider offset from the register value is different. And the
clock control register is at a different offset.

This patch adds support for different variants of the DDC clock.

Signed-off-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
---
 drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c | 42 ++++++++++++++++++++++++------
 1 file changed, 34 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c
index 4692e8c345ed..e1071838f487 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c
@@ -15,9 +15,16 @@
 #include "sun4i_tcon.h"
 #include "sun4i_hdmi.h"
 
+struct sun4i_ddc_variant {
+	u32	reg_offset;
+	u8	pre_divider;
+	u8	m_offset;
+};
+
 struct sun4i_ddc {
 	struct clk_hw		hw;
 	struct sun4i_hdmi	*hdmi;
+	const struct sun4i_ddc_variant	*variant;
 };
 
 static inline struct sun4i_ddc *hw_to_ddc(struct clk_hw *hw)
@@ -27,6 +34,7 @@ static inline struct sun4i_ddc *hw_to_ddc(struct clk_hw *hw)
 
 static unsigned long sun4i_ddc_calc_divider(unsigned long rate,
 					    unsigned long parent_rate,
+					    const struct sun4i_ddc_variant *variant,
 					    u8 *m, u8 *n)
 {
 	unsigned long best_rate = 0;
@@ -36,7 +44,8 @@ static unsigned long sun4i_ddc_calc_divider(unsigned long rate,
 		for (_n = 0; _n < 8; _n++) {
 			unsigned long tmp_rate;
 
-			tmp_rate = (((parent_rate / 2) / 10) >> _n) / (_m + 1);
+			tmp_rate = (((parent_rate / variant->pre_divider) /
+				     10) >> _n) / (_m + variant->m_offset);
 
 			if (tmp_rate > rate)
 				continue;
@@ -60,7 +69,9 @@ static unsigned long sun4i_ddc_calc_divider(unsigned long rate,
 static long sun4i_ddc_round_rate(struct clk_hw *hw, unsigned long rate,
 				 unsigned long *prate)
 {
-	return sun4i_ddc_calc_divider(rate, *prate, NULL, NULL);
+	struct sun4i_ddc *ddc = hw_to_ddc(hw);
+
+	return sun4i_ddc_calc_divider(rate, *prate, ddc->variant, NULL, NULL);
 }
 
 static unsigned long sun4i_ddc_recalc_rate(struct clk_hw *hw,
@@ -70,11 +81,12 @@ static unsigned long sun4i_ddc_recalc_rate(struct clk_hw *hw,
 	u32 reg;
 	u8 m, n;
 
-	reg = readl(ddc->hdmi->base + SUN4I_HDMI_DDC_CLK_REG);
-	m = (reg >> 3) & 0x7;
+	reg = readl(ddc->hdmi->base + ddc->variant->reg_offset);
+	m = (reg >> 3) & 0xf;
 	n = reg & 0x7;
 
-	return (((parent_rate / 2) / 10) >> n) / (m + 1);
+	return (((parent_rate / ddc->variant->pre_divider) / 10) >> n) /
+	       (m + ddc->variant->m_offset);
 }
 
 static int sun4i_ddc_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -83,10 +95,11 @@ static int sun4i_ddc_set_rate(struct clk_hw *hw, unsigned long rate,
 	struct sun4i_ddc *ddc = hw_to_ddc(hw);
 	u8 div_m, div_n;
 
-	sun4i_ddc_calc_divider(rate, parent_rate, &div_m, &div_n);
+	sun4i_ddc_calc_divider(rate, parent_rate, ddc->variant,
+			       &div_m, &div_n);
 
 	writel(SUN4I_HDMI_DDC_CLK_M(div_m) | SUN4I_HDMI_DDC_CLK_N(div_n),
-	       ddc->hdmi->base + SUN4I_HDMI_DDC_CLK_REG);
+	       ddc->hdmi->base + ddc->variant->reg_offset);
 
 	return 0;
 }
@@ -97,7 +110,8 @@ static const struct clk_ops sun4i_ddc_ops = {
 	.set_rate	= sun4i_ddc_set_rate,
 };
 
-int sun4i_ddc_create(struct sun4i_hdmi *hdmi, struct clk *parent)
+static int _sun4i_ddc_create(struct sun4i_hdmi *hdmi, struct clk *parent,
+			     const struct sun4i_ddc_variant *variant)
 {
 	struct clk_init_data init;
 	struct sun4i_ddc *ddc;
@@ -117,6 +131,7 @@ int sun4i_ddc_create(struct sun4i_hdmi *hdmi, struct clk *parent)
 	init.num_parents = 1;
 
 	ddc->hdmi = hdmi;
+	ddc->variant = variant;
 	ddc->hw.init = &init;
 
 	hdmi->ddc_clk = devm_clk_register(hdmi->dev, &ddc->hw);
@@ -125,3 +140,14 @@ int sun4i_ddc_create(struct sun4i_hdmi *hdmi, struct clk *parent)
 
 	return 0;
 }
+
+static const struct sun4i_ddc_variant sun4i_variant = {
+	.reg_offset	= SUN4I_HDMI_DDC_CLK_REG,
+	.pre_divider	= 2,
+	.m_offset	= 1,
+};
+
+int sun4i_ddc_create(struct sun4i_hdmi *hdmi, struct clk *parent)
+{
+	return _sun4i_ddc_create(hdmi, parent, &sun4i_variant);
+}
-- 
2.11.0

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

* [PATCH 10/19] drm/sun4i: hdmi: Rename internal DDC clock to avoid name collision
       [not found] ` <20170602101024.18940-1-wens-jdAy2FN1RRM@public.gmane.org>
                     ` (6 preceding siblings ...)
  2017-06-02 10:10   ` [PATCH 09/19] drm/sun4i: hdmi: Support different variants of the DDC clock Chen-Yu Tsai
@ 2017-06-02 10:10   ` Chen-Yu Tsai
  2017-06-02 19:30     ` Maxime Ripard
  2017-06-02 10:10   ` [PATCH 11/19] drm/sun4i: hdmi: Add A31 specific DDC register definitions Chen-Yu Tsai
                     ` (8 subsequent siblings)
  16 siblings, 1 reply; 38+ messages in thread
From: Chen-Yu Tsai @ 2017-06-02 10:10 UTC (permalink / raw)
  To: Maxime Ripard, David Airlie, Rob Herring, Michael Turquette,
	Stephen Boyd
  Cc: Chen-Yu Tsai, dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

The DDC parent clock on the A31 SoC is also conveniently named
"hdmi-ddc", which results in a name collision when the hdmi driver
registers its internal DDC divider clock.

Rename the internal clock to "hdmi-ddc-divider".

Signed-off-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
---
 drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c
index e1071838f487..9a6b6243e977 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c
@@ -125,7 +125,7 @@ static int _sun4i_ddc_create(struct sun4i_hdmi *hdmi, struct clk *parent,
 	if (!ddc)
 		return -ENOMEM;
 
-	init.name = "hdmi-ddc";
+	init.name = "hdmi-ddc-divider";
 	init.ops = &sun4i_ddc_ops;
 	init.parent_names = &parent_name;
 	init.num_parents = 1;
-- 
2.11.0

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

* [PATCH 11/19] drm/sun4i: hdmi: Add A31 specific DDC register definitions
       [not found] ` <20170602101024.18940-1-wens-jdAy2FN1RRM@public.gmane.org>
                     ` (7 preceding siblings ...)
  2017-06-02 10:10   ` [PATCH 10/19] drm/sun4i: hdmi: Rename internal DDC clock to avoid name collision Chen-Yu Tsai
@ 2017-06-02 10:10   ` Chen-Yu Tsai
  2017-06-02 10:10   ` [PATCH 12/19] drm/sun4i: hdmi: Support the DDC clock in the A31's HDMI controller Chen-Yu Tsai
                     ` (7 subsequent siblings)
  16 siblings, 0 replies; 38+ messages in thread
From: Chen-Yu Tsai @ 2017-06-02 10:10 UTC (permalink / raw)
  To: Maxime Ripard, David Airlie, Rob Herring, Michael Turquette,
	Stephen Boyd
  Cc: Chen-Yu Tsai, dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

The DDC block for the HDMI controller is different on the A31.

This patch adds the register definitions.

Signed-off-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
---
 drivers/gpu/drm/sun4i/sun4i_hdmi.h | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi.h b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
index 3a4987ab8da8..08c514672fd3 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi.h
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
@@ -124,6 +124,32 @@
 
 #define SUN4I_HDMI_DDC_FIFO_SIZE	16
 
+/* A31 specific */
+#define SUN6I_HDMI_DDC_CTRL_REG		0x500
+#define SUN6I_HDMI_DDC_CTRL_RESET		BIT(31)
+#define SUN6I_HDMI_DDC_CTRL_START_CMD		BIT(27)
+#define SUN6I_HDMI_DDC_CTRL_SDA_ENABLE		BIT(6)
+#define SUN6I_HDMI_DDC_CTRL_SCL_ENABLE		BIT(4)
+#define SUN6I_HDMI_DDC_CTRL_ENABLE		BIT(0)
+
+#define SUN6I_HDMI_DDC_CMD_REG		0x508
+#define SUN6I_HDMI_DDC_CMD_EXPLICIT_EDDC_READ	6
+#define SUN6I_HDMI_DDC_CMD_BYTE_COUNT(count)	((count) << 16)
+
+#define SUN6I_HDMI_DDC_ADDR_REG		0x50c
+#define SUN6I_HDMI_DDC_ADDR_SEGMENT(seg)	(((seg) & 0xff) << 24)
+#define SUN6I_HDMI_DDC_ADDR_EDDC(addr)		(((addr) & 0xff) << 16)
+#define SUN6I_HDMI_DDC_ADDR_OFFSET(off)		(((off) & 0xff) << 8)
+#define SUN6I_HDMI_DDC_ADDR_SLAVE(addr)		(((addr) & 0xff) << 1)
+
+#define SUN6I_HDMI_DDC_FIFO_CTRL_REG	0x518
+#define SUN6I_HDMI_DDC_FIFO_CTRL_CLEAR		BIT(15)
+
+#define SUN6I_HDMI_DDC_CLK_REG		0x520
+/* DDC CLK bit fields are the same, but the formula is not */
+
+#define SUN6I_HDMI_DDC_FIFO_DATA_REG	0x580
+
 enum sun4i_hdmi_pkt_type {
 	SUN4I_HDMI_PKT_AVI = 2,
 	SUN4I_HDMI_PKT_END = 15,
-- 
2.11.0

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

* [PATCH 12/19] drm/sun4i: hdmi: Support the DDC clock in the A31's HDMI controller
       [not found] ` <20170602101024.18940-1-wens-jdAy2FN1RRM@public.gmane.org>
                     ` (8 preceding siblings ...)
  2017-06-02 10:10   ` [PATCH 11/19] drm/sun4i: hdmi: Add A31 specific DDC register definitions Chen-Yu Tsai
@ 2017-06-02 10:10   ` Chen-Yu Tsai
       [not found]     ` <20170602101024.18940-13-wens-jdAy2FN1RRM@public.gmane.org>
  2017-06-02 10:10   ` [PATCH 13/19] drm/sun4i: hdmi: Add support for controller hardware variants Chen-Yu Tsai
                     ` (6 subsequent siblings)
  16 siblings, 1 reply; 38+ messages in thread
From: Chen-Yu Tsai @ 2017-06-02 10:10 UTC (permalink / raw)
  To: Maxime Ripard, David Airlie, Rob Herring, Michael Turquette,
	Stephen Boyd
  Cc: Chen-Yu Tsai, dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

On the A31, the HDMI DDC block is different from the one in the
other SoCs. As far as the DDC clock goes, it has no pre-divider,
as it is clocked from a slower parent clock, not the TMDS clock.
The divider offset from the register value is different. And the
clock control register is at a different offset.

This patch adds support for this variant.

Signed-off-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
---
 drivers/gpu/drm/sun4i/sun4i_hdmi.h         |  1 +
 drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c | 11 +++++++++++
 2 files changed, 12 insertions(+)

diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi.h b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
index 08c514672fd3..c39c2a245339 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi.h
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
@@ -178,6 +178,7 @@ struct sun4i_hdmi {
 };
 
 int sun4i_ddc_create(struct sun4i_hdmi *hdmi, struct clk *clk);
+int sun6i_ddc_create(struct sun4i_hdmi *hdmi, struct clk *clk);
 int sun4i_tmds_create(struct sun4i_hdmi *hdmi);
 int sun6i_tmds_create(struct sun4i_hdmi *hdmi);
 
diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c
index 9a6b6243e977..b1395e7b242c 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c
@@ -151,3 +151,14 @@ int sun4i_ddc_create(struct sun4i_hdmi *hdmi, struct clk *parent)
 {
 	return _sun4i_ddc_create(hdmi, parent, &sun4i_variant);
 }
+
+static const struct sun4i_ddc_variant sun6i_variant = {
+	.reg_offset	= SUN6I_HDMI_DDC_CLK_REG,
+	.pre_divider	= 1,
+	.m_offset	= 2,
+};
+
+int sun6i_ddc_create(struct sun4i_hdmi *hdmi, struct clk *parent)
+{
+	return _sun4i_ddc_create(hdmi, parent, &sun6i_variant);
+}
-- 
2.11.0

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

* [PATCH 13/19] drm/sun4i: hdmi: Add support for controller hardware variants
       [not found] ` <20170602101024.18940-1-wens-jdAy2FN1RRM@public.gmane.org>
                     ` (9 preceding siblings ...)
  2017-06-02 10:10   ` [PATCH 12/19] drm/sun4i: hdmi: Support the DDC clock in the A31's HDMI controller Chen-Yu Tsai
@ 2017-06-02 10:10   ` Chen-Yu Tsai
  2017-06-02 19:38     ` Maxime Ripard
  2017-06-02 10:10   ` [PATCH 14/19] drm/sun4i: hdmi: Add support for A31's HDMI controller Chen-Yu Tsai
                     ` (5 subsequent siblings)
  16 siblings, 1 reply; 38+ messages in thread
From: Chen-Yu Tsai @ 2017-06-02 10:10 UTC (permalink / raw)
  To: Maxime Ripard, David Airlie, Rob Herring, Michael Turquette,
	Stephen Boyd
  Cc: Chen-Yu Tsai, dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

The HDMI controller found in earlier Allwinner SoCs have slight
differences:

  - Need different initial values for the PLL related registers

  - Different behavior of the DDC and TMDS clocks

  - Different register layout for the DDC portion

  - Separate DDC parent clock on the A31

  - Explicit reset control

The clock variants are supported within their implementations,
which only expose a create function for each variant.

The different layout of the DDC registers necessitates a separate
version of struct drm_connector_helper_funcs.

A new variant data structure is created to store pointers to the
above functions, structures, and the different initial values.
Another flag notates whether there is a separate DDC parent clock.
If not, the TMDS clock is passed to the DDC clock create function,
as before.

Signed-off-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
---
 drivers/clk/sunxi-ng/ccu-sun6i-a31.c   |   2 +-
 drivers/gpu/drm/sun4i/sun4i_hdmi.h     |   8 +++
 drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 114 ++++++++++++++++++++++++++-------
 3 files changed, 100 insertions(+), 24 deletions(-)

diff --git a/drivers/clk/sunxi-ng/ccu-sun6i-a31.c b/drivers/clk/sunxi-ng/ccu-sun6i-a31.c
index 4d6078fca9ac..e48186985a51 100644
--- a/drivers/clk/sunxi-ng/ccu-sun6i-a31.c
+++ b/drivers/clk/sunxi-ng/ccu-sun6i-a31.c
@@ -610,7 +610,7 @@ static SUNXI_CCU_M_WITH_MUX_GATE(hdmi_clk, "hdmi", lcd_ch1_parents,
 
 static SUNXI_CCU_GATE(hdmi_ddc_clk, "hdmi-ddc", "osc24M", 0x150, BIT(30), 0);
 
-static SUNXI_CCU_GATE(ps_clk, "ps", "lcd1-ch1", 0x140, BIT(31), 0);
+static SUNXI_CCU_GATE(ps_clk, "ps", "lcd1-ch1", 0x154, BIT(31), 0);
 
 static const char * const mbus_parents[] = { "osc24M", "pll-periph",
 					     "pll-ddr" };
diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi.h b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
index c39c2a245339..c63d0bd95963 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi.h
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
@@ -155,6 +155,8 @@ enum sun4i_hdmi_pkt_type {
 	SUN4I_HDMI_PKT_END = 15,
 };
 
+struct sun4i_hdmi_variant;
+
 struct sun4i_hdmi {
 	struct drm_connector	connector;
 	struct drm_encoder	encoder;
@@ -162,9 +164,13 @@ struct sun4i_hdmi {
 
 	void __iomem		*base;
 
+	/* Reset control */
+	struct reset_control	*reset;
+
 	/* Parent clocks */
 	struct clk		*bus_clk;
 	struct clk		*mod_clk;
+	struct clk		*ddc_parent_clk;
 	struct clk		*pll0_clk;
 	struct clk		*pll1_clk;
 
@@ -175,6 +181,8 @@ struct sun4i_hdmi {
 	struct sun4i_drv	*drv;
 
 	bool			hdmi_monitor;
+
+	const struct sun4i_hdmi_variant	*variant;
 };
 
 int sun4i_ddc_create(struct sun4i_hdmi *hdmi, struct clk *clk);
diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
index 457614073501..9ded40aaed32 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
@@ -20,8 +20,10 @@
 #include <linux/clk.h>
 #include <linux/component.h>
 #include <linux/iopoll.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
+#include <linux/reset.h>
 
 #include "sun4i_backend.h"
 #include "sun4i_crtc.h"
@@ -315,6 +317,56 @@ static const struct drm_connector_funcs sun4i_hdmi_connector_funcs = {
 	.atomic_destroy_state	= drm_atomic_helper_connector_destroy_state,
 };
 
+struct sun4i_hdmi_variant {
+	const struct drm_connector_helper_funcs *connector_helpers;
+	int (*ddc_create)(struct sun4i_hdmi *hdmi, struct clk *clk);
+	int (*tmds_create)(struct sun4i_hdmi *hdmi);
+	bool has_ddc_parent_clk;
+	bool has_reset_control;
+
+	u32 pad_ctrl0_init_val;
+	u32 pad_ctrl1_init_val;
+	u32 pll_ctrl_init_val;
+};
+
+#define SUN4I_HDMI_PAD_CTRL1_MASK	(GENMASK(24, 7) | GENMASK(5, 0))
+#define SUN4I_HDMI_PLL_CTRL_MASK	(GENMASK(31, 8) | GENMASK(3, 0))
+
+static const struct sun4i_hdmi_variant sun5i_variant = {
+	.connector_helpers	= &sun4i_hdmi_connector_helper_funcs,
+	.ddc_create		= sun4i_ddc_create,
+	.tmds_create		= sun4i_tmds_create,
+	.has_ddc_parent_clk	= false,
+	.has_reset_control	= false,
+	.pad_ctrl0_init_val	= SUN4I_HDMI_PAD_CTRL0_TXEN |
+				  SUN4I_HDMI_PAD_CTRL0_CKEN |
+				  SUN4I_HDMI_PAD_CTRL0_PWENG |
+				  SUN4I_HDMI_PAD_CTRL0_PWEND |
+				  SUN4I_HDMI_PAD_CTRL0_PWENC |
+				  SUN4I_HDMI_PAD_CTRL0_LDODEN |
+				  SUN4I_HDMI_PAD_CTRL0_LDOCEN |
+				  SUN4I_HDMI_PAD_CTRL0_BIASEN,
+	.pad_ctrl1_init_val	= SUN4I_HDMI_PAD_CTRL1_REG_AMP(6) |
+				  SUN4I_HDMI_PAD_CTRL1_REG_EMP(2) |
+				  SUN4I_HDMI_PAD_CTRL1_REG_DENCK |
+				  SUN4I_HDMI_PAD_CTRL1_REG_DEN |
+				  SUN4I_HDMI_PAD_CTRL1_EMPCK_OPT |
+				  SUN4I_HDMI_PAD_CTRL1_EMP_OPT |
+				  SUN4I_HDMI_PAD_CTRL1_AMPCK_OPT |
+				  SUN4I_HDMI_PAD_CTRL1_AMP_OPT,
+	.pll_ctrl_init_val	= SUN4I_HDMI_PLL_CTRL_VCO_S(8) |
+				  SUN4I_HDMI_PLL_CTRL_CS(7) |
+				  SUN4I_HDMI_PLL_CTRL_CP_S(15) |
+				  SUN4I_HDMI_PLL_CTRL_S(7) |
+				  SUN4I_HDMI_PLL_CTRL_VCO_GAIN(4) |
+				  SUN4I_HDMI_PLL_CTRL_SDIV2 |
+				  SUN4I_HDMI_PLL_CTRL_LDO2_EN |
+				  SUN4I_HDMI_PLL_CTRL_LDO1_EN |
+				  SUN4I_HDMI_PLL_CTRL_HV_IS_33 |
+				  SUN4I_HDMI_PLL_CTRL_BWS |
+				  SUN4I_HDMI_PLL_CTRL_PLL_EN,
+};
+
 static int sun4i_hdmi_bind(struct device *dev, struct device *master,
 			   void *data)
 {
@@ -333,6 +385,10 @@ static int sun4i_hdmi_bind(struct device *dev, struct device *master,
 	hdmi->dev = dev;
 	hdmi->drv = drv;
 
+	hdmi->variant = of_device_get_match_data(&pdev->dev);
+	if (!hdmi->variant)
+		return -EINVAL;
+
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	hdmi->base = devm_ioremap_resource(dev, res);
 	if (IS_ERR(hdmi->base)) {
@@ -340,10 +396,25 @@ static int sun4i_hdmi_bind(struct device *dev, struct device *master,
 		return PTR_ERR(hdmi->base);
 	}
 
+	if (hdmi->variant->has_reset_control) {
+		hdmi->reset = devm_reset_control_get(dev, NULL);
+		if (IS_ERR(hdmi->reset)) {
+			dev_err(dev, "Couldn't get the HDMI reset control\n");
+			return PTR_ERR(hdmi->reset);
+		}
+
+		ret = reset_control_deassert(hdmi->reset);
+		if (ret) {
+			dev_err(dev, "Couldn't deassert HDMI reset\n");
+			return ret;
+		}
+	}
+
 	hdmi->bus_clk = devm_clk_get(dev, "ahb");
 	if (IS_ERR(hdmi->bus_clk)) {
 		dev_err(dev, "Couldn't get the HDMI bus clock\n");
-		return PTR_ERR(hdmi->bus_clk);
+		ret = PTR_ERR(hdmi->bus_clk);
+		goto err_assert_reset;
 	}
 	clk_prepare_enable(hdmi->bus_clk);
 
@@ -369,18 +440,25 @@ static int sun4i_hdmi_bind(struct device *dev, struct device *master,
 		goto err_disable_mod_clk;
 	}
 
-	ret = sun4i_tmds_create(hdmi);
+	ret = hdmi->variant->tmds_create(hdmi);
 	if (ret) {
 		dev_err(dev, "Couldn't create the TMDS clock\n");
 		goto err_disable_mod_clk;
 	}
 
+	if (hdmi->variant->has_ddc_parent_clk) {
+		hdmi->ddc_parent_clk = devm_clk_get(dev, "ddc");
+		if (IS_ERR(hdmi->ddc_parent_clk)) {
+			dev_err(dev, "Couldn't get the HDMI DDC clock\n");
+			return PTR_ERR(hdmi->ddc_parent_clk);
+		}
+	} else {
+		hdmi->ddc_parent_clk = hdmi->tmds_clk;
+	}
+
 	writel(SUN4I_HDMI_CTRL_ENABLE, hdmi->base + SUN4I_HDMI_CTRL_REG);
 
-	writel(SUN4I_HDMI_PAD_CTRL0_TXEN | SUN4I_HDMI_PAD_CTRL0_CKEN |
-	       SUN4I_HDMI_PAD_CTRL0_PWENG | SUN4I_HDMI_PAD_CTRL0_PWEND |
-	       SUN4I_HDMI_PAD_CTRL0_PWENC | SUN4I_HDMI_PAD_CTRL0_LDODEN |
-	       SUN4I_HDMI_PAD_CTRL0_LDOCEN | SUN4I_HDMI_PAD_CTRL0_BIASEN,
+	writel(hdmi->variant->pad_ctrl0_init_val,
 	       hdmi->base + SUN4I_HDMI_PAD_CTRL0_REG);
 
 	/*
@@ -390,27 +468,15 @@ static int sun4i_hdmi_bind(struct device *dev, struct device *master,
 	 */
 	reg = readl(hdmi->base + SUN4I_HDMI_PAD_CTRL1_REG);
 	reg &= SUN4I_HDMI_PAD_CTRL1_HALVE_CLK;
-	reg |= SUN4I_HDMI_PAD_CTRL1_REG_AMP(6) |
-		SUN4I_HDMI_PAD_CTRL1_REG_EMP(2) |
-		SUN4I_HDMI_PAD_CTRL1_REG_DENCK |
-		SUN4I_HDMI_PAD_CTRL1_REG_DEN |
-		SUN4I_HDMI_PAD_CTRL1_EMPCK_OPT |
-		SUN4I_HDMI_PAD_CTRL1_EMP_OPT |
-		SUN4I_HDMI_PAD_CTRL1_AMPCK_OPT |
-		SUN4I_HDMI_PAD_CTRL1_AMP_OPT;
+	reg |= hdmi->variant->pad_ctrl1_init_val;
 	writel(reg, hdmi->base + SUN4I_HDMI_PAD_CTRL1_REG);
 
 	reg = readl(hdmi->base + SUN4I_HDMI_PLL_CTRL_REG);
 	reg &= SUN4I_HDMI_PLL_CTRL_DIV_MASK;
-	reg |= SUN4I_HDMI_PLL_CTRL_VCO_S(8) | SUN4I_HDMI_PLL_CTRL_CS(7) |
-		SUN4I_HDMI_PLL_CTRL_CP_S(15) | SUN4I_HDMI_PLL_CTRL_S(7) |
-		SUN4I_HDMI_PLL_CTRL_VCO_GAIN(4) | SUN4I_HDMI_PLL_CTRL_SDIV2 |
-		SUN4I_HDMI_PLL_CTRL_LDO2_EN | SUN4I_HDMI_PLL_CTRL_LDO1_EN |
-		SUN4I_HDMI_PLL_CTRL_HV_IS_33 | SUN4I_HDMI_PLL_CTRL_BWS |
-		SUN4I_HDMI_PLL_CTRL_PLL_EN;
+	reg |= hdmi->variant->pll_ctrl_init_val;
 	writel(reg, hdmi->base + SUN4I_HDMI_PLL_CTRL_REG);
 
-	ret = sun4i_ddc_create(hdmi, hdmi->tmds_clk);
+	ret = hdmi->variant->ddc_create(hdmi, hdmi->ddc_parent_clk);
 	if (ret) {
 		dev_err(dev, "Couldn't create the DDC clock\n");
 		goto err_disable_mod_clk;
@@ -434,7 +500,7 @@ static int sun4i_hdmi_bind(struct device *dev, struct device *master,
 		goto err_disable_mod_clk;
 
 	drm_connector_helper_add(&hdmi->connector,
-				 &sun4i_hdmi_connector_helper_funcs);
+				 hdmi->variant->connector_helpers);
 	ret = drm_connector_init(drm, &hdmi->connector,
 				 &sun4i_hdmi_connector_funcs,
 				 DRM_MODE_CONNECTOR_HDMIA);
@@ -458,6 +524,8 @@ static int sun4i_hdmi_bind(struct device *dev, struct device *master,
 	clk_disable_unprepare(hdmi->mod_clk);
 err_disable_bus_clk:
 	clk_disable_unprepare(hdmi->bus_clk);
+err_assert_reset:
+	reset_control_assert(hdmi->reset);
 	return ret;
 }
 
@@ -490,7 +558,7 @@ static int sun4i_hdmi_remove(struct platform_device *pdev)
 }
 
 static const struct of_device_id sun4i_hdmi_of_table[] = {
-	{ .compatible = "allwinner,sun5i-a10s-hdmi" },
+	{ .compatible = "allwinner,sun5i-a10s-hdmi", .data = &sun5i_variant, },
 	{ }
 };
 MODULE_DEVICE_TABLE(of, sun4i_hdmi_of_table);
-- 
2.11.0

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

* [PATCH 14/19] drm/sun4i: hdmi: Add support for A31's HDMI controller
       [not found] ` <20170602101024.18940-1-wens-jdAy2FN1RRM@public.gmane.org>
                     ` (10 preceding siblings ...)
  2017-06-02 10:10   ` [PATCH 13/19] drm/sun4i: hdmi: Add support for controller hardware variants Chen-Yu Tsai
@ 2017-06-02 10:10   ` Chen-Yu Tsai
  2017-06-02 19:41     ` Maxime Ripard
  2017-06-02 10:10   ` [PATCH 15/19] clk: sunxi-ng: sun6i: Export video PLLs Chen-Yu Tsai
                     ` (4 subsequent siblings)
  16 siblings, 1 reply; 38+ messages in thread
From: Chen-Yu Tsai @ 2017-06-02 10:10 UTC (permalink / raw)
  To: Maxime Ripard, David Airlie, Rob Herring, Michael Turquette,
	Stephen Boyd
  Cc: Chen-Yu Tsai, dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

The HDMI controller found in the A31 SoCs is slightly different
from the one already supported, which is found in the A10s:

  - Need different initial values for the PLL related registers

  - Different behavior of the DDC and TMDS clocks

  - Different register layout for the DDC portion

  - Separate DDC parent clock

This patch adds support for it.

Signed-off-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
---
 drivers/gpu/drm/sun4i/sun4i_hdmi.h     |   3 +
 drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 141 +++++++++++++++++++++++++++++++++
 2 files changed, 144 insertions(+)

diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi.h b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
index c63d0bd95963..2589bc92be59 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi.h
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
@@ -56,10 +56,13 @@
 #define SUN4I_HDMI_PAD_CTRL0_TXEN		BIT(23)
 
 #define SUN4I_HDMI_PAD_CTRL1_REG	0x204
+#define SUN4I_HDMI_PAD_CTRL1_UNKNOWN		BIT(24)	/* set on A31 */
 #define SUN4I_HDMI_PAD_CTRL1_AMP_OPT		BIT(23)
 #define SUN4I_HDMI_PAD_CTRL1_AMPCK_OPT		BIT(22)
 #define SUN4I_HDMI_PAD_CTRL1_EMP_OPT		BIT(20)
 #define SUN4I_HDMI_PAD_CTRL1_EMPCK_OPT		BIT(19)
+#define SUN4I_HDMI_PAD_CTRL1_PWSCK		BIT(18)
+#define SUN4I_HDMI_PAD_CTRL1_PWSDT		BIT(17)
 #define SUN4I_HDMI_PAD_CTRL1_REG_DEN		BIT(15)
 #define SUN4I_HDMI_PAD_CTRL1_REG_DENCK		BIT(14)
 #define SUN4I_HDMI_PAD_CTRL1_REG_EMP(n)		(((n) & 7) << 10)
diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
index 9ded40aaed32..e9abf93eb41c 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
@@ -293,6 +293,109 @@ static const struct drm_connector_helper_funcs sun4i_hdmi_connector_helper_funcs
 	.get_modes	= sun4i_hdmi_get_modes,
 };
 
+static int sun6i_hdmi_read_sub_block(struct sun4i_hdmi *hdmi,
+				     unsigned int blk, unsigned int offset,
+				     u8 *buf, unsigned int count)
+{
+	unsigned long reg;
+	int i;
+
+	reg = readl(hdmi->base + SUN6I_HDMI_DDC_FIFO_CTRL_REG);
+	writel(reg | SUN6I_HDMI_DDC_FIFO_CTRL_CLEAR,
+	       hdmi->base + SUN6I_HDMI_DDC_FIFO_CTRL_REG);
+	writel(SUN6I_HDMI_DDC_ADDR_SEGMENT(offset >> 8) |
+	       SUN6I_HDMI_DDC_ADDR_EDDC(DDC_SEGMENT_ADDR << 1) |
+	       SUN6I_HDMI_DDC_ADDR_OFFSET(offset) |
+	       SUN6I_HDMI_DDC_ADDR_SLAVE(DDC_ADDR),
+	       hdmi->base + SUN6I_HDMI_DDC_ADDR_REG);
+
+	writel(SUN6I_HDMI_DDC_CMD_EXPLICIT_EDDC_READ |
+	       SUN6I_HDMI_DDC_CMD_BYTE_COUNT(count),
+	       hdmi->base + SUN6I_HDMI_DDC_CMD_REG);
+
+	reg = readl(hdmi->base + SUN6I_HDMI_DDC_CTRL_REG);
+	writel(reg | SUN6I_HDMI_DDC_CTRL_START_CMD,
+	       hdmi->base + SUN6I_HDMI_DDC_CTRL_REG);
+
+	if (readl_poll_timeout(hdmi->base + SUN6I_HDMI_DDC_CTRL_REG, reg,
+			       !(reg & SUN6I_HDMI_DDC_CTRL_START_CMD),
+			       100, 100000))
+		return -EIO;
+
+	for (i = 0; i < count; i++)
+		buf[i] = readb(hdmi->base + SUN6I_HDMI_DDC_FIFO_DATA_REG);
+
+	return 0;
+}
+
+static int sun6i_hdmi_read_edid_block(void *data, u8 *buf, unsigned int blk,
+				      size_t length)
+{
+	struct sun4i_hdmi *hdmi = data;
+	int retry = 2, i;
+
+	do {
+		for (i = 0; i < length; i += SUN4I_HDMI_DDC_FIFO_SIZE) {
+			unsigned char offset = blk * EDID_LENGTH + i;
+			unsigned int count = min((unsigned int)SUN4I_HDMI_DDC_FIFO_SIZE,
+						 length - i);
+			int ret;
+
+			ret = sun6i_hdmi_read_sub_block(hdmi, blk, offset,
+							buf + i, count);
+			if (ret)
+				return ret;
+		}
+	} while (!drm_edid_block_valid(buf, blk, true, NULL) && (retry--));
+
+	return 0;
+}
+
+static int sun6i_hdmi_get_modes(struct drm_connector *connector)
+{
+	struct sun4i_hdmi *hdmi = drm_connector_to_sun4i_hdmi(connector);
+	u32 reg;
+	struct edid *edid;
+	int ret;
+
+	clk_set_rate(hdmi->ddc_clk, 100000);
+	clk_prepare_enable(hdmi->ddc_clk);
+
+	/* Reset i2c controller */
+	writel(SUN6I_HDMI_DDC_CTRL_ENABLE | SUN6I_HDMI_DDC_CTRL_RESET |
+	       SUN6I_HDMI_DDC_CTRL_SDA_ENABLE |
+	       SUN6I_HDMI_DDC_CTRL_SCL_ENABLE,
+	       hdmi->base + SUN6I_HDMI_DDC_CTRL_REG);
+	if (readl_poll_timeout(hdmi->base + SUN6I_HDMI_DDC_CTRL_REG, reg,
+			       !(reg & SUN6I_HDMI_DDC_CTRL_RESET),
+			       100, 2000)) {
+		dev_err(hdmi->dev, "DDC reset timeout: %08x\n", reg);
+		clk_disable_unprepare(hdmi->ddc_clk);
+		return -EIO;
+	}
+
+	edid = drm_do_get_edid(connector, sun6i_hdmi_read_edid_block, hdmi);
+
+	clk_disable_unprepare(hdmi->ddc_clk);
+
+	if (!edid)
+		return 0;
+
+	hdmi->hdmi_monitor = drm_detect_hdmi_monitor(edid);
+	DRM_DEBUG_DRIVER("Monitor is %s monitor\n",
+			 hdmi->hdmi_monitor ? "an HDMI" : "a DVI");
+
+	drm_mode_connector_update_edid_property(connector, edid);
+	ret = drm_add_edid_modes(connector, edid);
+	kfree(edid);
+
+	return ret;
+}
+
+static const struct drm_connector_helper_funcs sun6i_hdmi_connector_helper_funcs = {
+	.get_modes	= sun6i_hdmi_get_modes,
+};
+
 static enum drm_connector_status
 sun4i_hdmi_connector_detect(struct drm_connector *connector, bool force)
 {
@@ -367,6 +470,43 @@ static const struct sun4i_hdmi_variant sun5i_variant = {
 				  SUN4I_HDMI_PLL_CTRL_PLL_EN,
 };
 
+static const struct sun4i_hdmi_variant sun6i_variant = {
+	.connector_helpers	= &sun6i_hdmi_connector_helper_funcs,
+	.ddc_create		= sun6i_ddc_create,
+	.tmds_create		= sun6i_tmds_create,
+	.has_ddc_parent_clk	= true,
+	.has_reset_control	= true,
+	.pad_ctrl0_init_val	= 0xff |
+				  SUN4I_HDMI_PAD_CTRL0_TXEN |
+				  SUN4I_HDMI_PAD_CTRL0_CKEN |
+				  SUN4I_HDMI_PAD_CTRL0_PWENG |
+				  SUN4I_HDMI_PAD_CTRL0_PWEND |
+				  SUN4I_HDMI_PAD_CTRL0_PWENC |
+				  SUN4I_HDMI_PAD_CTRL0_LDODEN |
+				  SUN4I_HDMI_PAD_CTRL0_LDOCEN,
+	.pad_ctrl1_init_val	= SUN4I_HDMI_PAD_CTRL1_REG_AMP(6) |
+				  SUN4I_HDMI_PAD_CTRL1_REG_EMP(4) |
+				  SUN4I_HDMI_PAD_CTRL1_REG_DENCK |
+				  SUN4I_HDMI_PAD_CTRL1_REG_DEN |
+				  SUN4I_HDMI_PAD_CTRL1_EMPCK_OPT |
+				  SUN4I_HDMI_PAD_CTRL1_EMP_OPT |
+				  SUN4I_HDMI_PAD_CTRL1_PWSDT |
+				  SUN4I_HDMI_PAD_CTRL1_PWSCK |
+				  SUN4I_HDMI_PAD_CTRL1_AMPCK_OPT |
+				  SUN4I_HDMI_PAD_CTRL1_AMP_OPT |
+				  SUN4I_HDMI_PAD_CTRL1_UNKNOWN,
+	.pll_ctrl_init_val	= SUN4I_HDMI_PLL_CTRL_VCO_S(8) |
+				  SUN4I_HDMI_PLL_CTRL_CS(3) |
+				  SUN4I_HDMI_PLL_CTRL_CP_S(10) |
+				  SUN4I_HDMI_PLL_CTRL_S(4) |
+				  SUN4I_HDMI_PLL_CTRL_VCO_GAIN(4) |
+				  SUN4I_HDMI_PLL_CTRL_SDIV2 |
+				  SUN4I_HDMI_PLL_CTRL_LDO2_EN |
+				  SUN4I_HDMI_PLL_CTRL_LDO1_EN |
+				  SUN4I_HDMI_PLL_CTRL_HV_IS_33 |
+				  SUN4I_HDMI_PLL_CTRL_PLL_EN,
+};
+
 static int sun4i_hdmi_bind(struct device *dev, struct device *master,
 			   void *data)
 {
@@ -559,6 +699,7 @@ static int sun4i_hdmi_remove(struct platform_device *pdev)
 
 static const struct of_device_id sun4i_hdmi_of_table[] = {
 	{ .compatible = "allwinner,sun5i-a10s-hdmi", .data = &sun5i_variant, },
+	{ .compatible = "allwinner,sun6i-a31-hdmi", .data = &sun6i_variant, },
 	{ }
 };
 MODULE_DEVICE_TABLE(of, sun4i_hdmi_of_table);
-- 
2.11.0

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

* [PATCH 15/19] clk: sunxi-ng: sun6i: Export video PLLs
       [not found] ` <20170602101024.18940-1-wens-jdAy2FN1RRM@public.gmane.org>
                     ` (11 preceding siblings ...)
  2017-06-02 10:10   ` [PATCH 14/19] drm/sun4i: hdmi: Add support for A31's HDMI controller Chen-Yu Tsai
@ 2017-06-02 10:10   ` Chen-Yu Tsai
  2017-06-02 10:10   ` [PATCH 16/19] ARM: sun6i: a31: Add device node for HDMI controller Chen-Yu Tsai
                     ` (3 subsequent siblings)
  16 siblings, 0 replies; 38+ messages in thread
From: Chen-Yu Tsai @ 2017-06-02 10:10 UTC (permalink / raw)
  To: Maxime Ripard, David Airlie, Rob Herring, Michael Turquette,
	Stephen Boyd
  Cc: Chen-Yu Tsai, dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

The 2x outputs of the 2 video PLL clocks are directly used by the
HDMI controller block.

Export them so they can be referenced in the device tree.

Signed-off-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
---
 drivers/clk/sunxi-ng/ccu-sun6i-a31.h      | 8 ++++++--
 include/dt-bindings/clock/sun6i-a31-ccu.h | 4 ++++
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/sunxi-ng/ccu-sun6i-a31.h b/drivers/clk/sunxi-ng/ccu-sun6i-a31.h
index 4e434011e9e7..27e6ad4133ab 100644
--- a/drivers/clk/sunxi-ng/ccu-sun6i-a31.h
+++ b/drivers/clk/sunxi-ng/ccu-sun6i-a31.h
@@ -27,7 +27,9 @@
 #define CLK_PLL_AUDIO_4X	4
 #define CLK_PLL_AUDIO_8X	5
 #define CLK_PLL_VIDEO0		6
-#define CLK_PLL_VIDEO0_2X	7
+
+/* The PLL_VIDEO0_2X clock is exported */
+
 #define CLK_PLL_VE		8
 #define CLK_PLL_DDR		9
 
@@ -35,7 +37,9 @@
 
 #define CLK_PLL_PERIPH_2X	11
 #define CLK_PLL_VIDEO1		12
-#define CLK_PLL_VIDEO1_2X	13
+
+/* The PLL_VIDEO1_2X clock is exported */
+
 #define CLK_PLL_GPU		14
 #define CLK_PLL_MIPI		15
 #define CLK_PLL9		16
diff --git a/include/dt-bindings/clock/sun6i-a31-ccu.h b/include/dt-bindings/clock/sun6i-a31-ccu.h
index 4482530fb6f5..c5d13340184a 100644
--- a/include/dt-bindings/clock/sun6i-a31-ccu.h
+++ b/include/dt-bindings/clock/sun6i-a31-ccu.h
@@ -43,8 +43,12 @@
 #ifndef _DT_BINDINGS_CLK_SUN6I_A31_H_
 #define _DT_BINDINGS_CLK_SUN6I_A31_H_
 
+#define CLK_PLL_VIDEO0_2X	7
+
 #define CLK_PLL_PERIPH		10
 
+#define CLK_PLL_VIDEO1_2X	13
+
 #define CLK_CPU			18
 
 #define CLK_AHB1_MIPIDSI	23
-- 
2.11.0

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

* [PATCH 16/19] ARM: sun6i: a31: Add device node for HDMI controller
       [not found] ` <20170602101024.18940-1-wens-jdAy2FN1RRM@public.gmane.org>
                     ` (12 preceding siblings ...)
  2017-06-02 10:10   ` [PATCH 15/19] clk: sunxi-ng: sun6i: Export video PLLs Chen-Yu Tsai
@ 2017-06-02 10:10   ` Chen-Yu Tsai
  2017-06-02 10:10   ` [PATCH 17/19] ARM: sun6i: a31: Enable HDMI support on the A31 Hummingbird Chen-Yu Tsai
                     ` (2 subsequent siblings)
  16 siblings, 0 replies; 38+ messages in thread
From: Chen-Yu Tsai @ 2017-06-02 10:10 UTC (permalink / raw)
  To: Maxime Ripard, David Airlie, Rob Herring, Michael Turquette,
	Stephen Boyd
  Cc: Chen-Yu Tsai, dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

Now that we support the HDMI controller on the A31 SoC, we can add it
to the device tree.

This adds a device node for the HDMI controller, and the of_graph nodes
connecting it to the 2 TCONs.

Signed-off-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
---
 arch/arm/boot/dts/sun6i-a31.dtsi | 55 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 55 insertions(+)

diff --git a/arch/arm/boot/dts/sun6i-a31.dtsi b/arch/arm/boot/dts/sun6i-a31.dtsi
index d0cede5aaeb5..36bfb6ad6578 100644
--- a/arch/arm/boot/dts/sun6i-a31.dtsi
+++ b/arch/arm/boot/dts/sun6i-a31.dtsi
@@ -284,6 +284,12 @@
 					#address-cells = <1>;
 					#size-cells = <0>;
 					reg = <1>;
+
+					tcon0_out_hdmi: endpoint@1 {
+						reg = <1>;
+						remote-endpoint = <&hdmi_in_tcon0>;
+						allwinner,tcon-channel = <1>;
+					};
 				};
 			};
 		};
@@ -321,6 +327,12 @@
 					#address-cells = <1>;
 					#size-cells = <0>;
 					reg = <1>;
+
+					tcon1_out_hdmi: endpoint@1 {
+						reg = <1>;
+						remote-endpoint = <&hdmi_in_tcon1>;
+						allwinner,tcon-channel = <1>;
+					};
 				};
 			};
 		};
@@ -401,6 +413,49 @@
 			#size-cells = <0>;
 		};
 
+		hdmi: hdmi@01c16000 {
+			compatible = "allwinner,sun6i-a31-hdmi";
+			reg = <0x01c16000 0x1000>;
+			interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_AHB1_HDMI>, <&ccu CLK_HDMI>,
+				 <&ccu CLK_HDMI_DDC>,
+				 <&ccu CLK_PLL_VIDEO0_2X>,
+				 <&ccu CLK_PLL_VIDEO1_2X>;
+			clock-names = "ahb", "mod", "ddc", "pll-0", "pll-1";
+			resets = <&ccu RST_AHB1_HDMI>;
+			reset-names = "ahb";
+			dma-names = "ddc-tx", "ddc-rx", "audio-tx";
+			dmas = <&dma 13>, <&dma 13>, <&dma 14>;
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				hdmi_in: port@0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+
+					hdmi_in_tcon0: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&tcon0_out_hdmi>;
+					};
+
+					hdmi_in_tcon1: endpoint@1 {
+						reg = <1>;
+						remote-endpoint = <&tcon1_out_hdmi>;
+					};
+				};
+
+				hdmi_out: port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+				};
+			};
+		};
+
 		usb_otg: usb@01c19000 {
 			compatible = "allwinner,sun6i-a31-musb";
 			reg = <0x01c19000 0x0400>;
-- 
2.11.0

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

* [PATCH 17/19] ARM: sun6i: a31: Enable HDMI support on the A31 Hummingbird
       [not found] ` <20170602101024.18940-1-wens-jdAy2FN1RRM@public.gmane.org>
                     ` (13 preceding siblings ...)
  2017-06-02 10:10   ` [PATCH 16/19] ARM: sun6i: a31: Add device node for HDMI controller Chen-Yu Tsai
@ 2017-06-02 10:10   ` Chen-Yu Tsai
  2017-06-02 10:10   ` [PATCH 18/19] ARM: sun6i: a31s: Enable HDMI display output on the Sinlinx SinA31s Chen-Yu Tsai
  2017-06-02 10:10   ` [PATCH 19/19] ARM: sun6i: a31s: Enable HDMI display output on the MSI Primo81 tablet Chen-Yu Tsai
  16 siblings, 0 replies; 38+ messages in thread
From: Chen-Yu Tsai @ 2017-06-02 10:10 UTC (permalink / raw)
  To: Maxime Ripard, David Airlie, Rob Herring, Michael Turquette,
	Stephen Boyd
  Cc: Chen-Yu Tsai, dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

The A31 Humminbird has an HDMI connector wired to the HDMI pins
on the SoC. Enable HDMI support for this board.

Signed-off-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
---
 arch/arm/boot/dts/sun6i-a31-hummingbird.dts | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/arch/arm/boot/dts/sun6i-a31-hummingbird.dts b/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
index 9ecb5f0b3f83..19e382a11297 100644
--- a/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
+++ b/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
@@ -62,6 +62,17 @@
 		stdout-path = "serial0:115200n8";
 	};
 
+	hdmi-connector {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con_in: endpoint {
+				remote-endpoint = <&hdmi_out_con>;
+			};
+		};
+	};
+
 	vga-connector {
 		compatible = "vga-connector";
 
@@ -162,6 +173,16 @@
 	};
 };
 
+&hdmi {
+	status = "okay";
+};
+
+&hdmi_out {
+	hdmi_out_con: endpoint {
+		remote-endpoint = <&hdmi_con_in>;
+	};
+};
+
 &i2c0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&i2c0_pins_a>;
-- 
2.11.0

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

* [PATCH 18/19] ARM: sun6i: a31s: Enable HDMI display output on the Sinlinx SinA31s
       [not found] ` <20170602101024.18940-1-wens-jdAy2FN1RRM@public.gmane.org>
                     ` (14 preceding siblings ...)
  2017-06-02 10:10   ` [PATCH 17/19] ARM: sun6i: a31: Enable HDMI support on the A31 Hummingbird Chen-Yu Tsai
@ 2017-06-02 10:10   ` Chen-Yu Tsai
  2017-06-02 10:10   ` [PATCH 19/19] ARM: sun6i: a31s: Enable HDMI display output on the MSI Primo81 tablet Chen-Yu Tsai
  16 siblings, 0 replies; 38+ messages in thread
From: Chen-Yu Tsai @ 2017-06-02 10:10 UTC (permalink / raw)
  To: Maxime Ripard, David Airlie, Rob Herring, Michael Turquette,
	Stephen Boyd
  Cc: Chen-Yu Tsai, dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

The Sinlinx SinA31s has an HDMI connector wired to the HDMI pins
from the SoC.

Enable the display pipeline and the HDMI output.

Signed-off-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
---
 arch/arm/boot/dts/sun6i-a31s-sina31s.dts | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/arch/arm/boot/dts/sun6i-a31s-sina31s.dts b/arch/arm/boot/dts/sun6i-a31s-sina31s.dts
index b3d98222bd81..298476485bb4 100644
--- a/arch/arm/boot/dts/sun6i-a31s-sina31s.dts
+++ b/arch/arm/boot/dts/sun6i-a31s-sina31s.dts
@@ -53,6 +53,17 @@
 		stdout-path = "serial0:115200n8";
 	};
 
+	hdmi-connector {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con_in: endpoint {
+				remote-endpoint = <&hdmi_out_con>;
+			};
+		};
+	};
+
 	leds {
 		compatible = "gpio-leds";
 		pinctrl-names = "default";
@@ -90,6 +101,10 @@
 	status = "okay";
 };
 
+&de {
+	status = "okay";
+};
+
 &ehci0 {
 	/* USB 2.0 4 port hub IC */
 	status = "okay";
@@ -112,6 +127,16 @@
 	};
 };
 
+&hdmi {
+	status = "okay";
+};
+
+&hdmi_out {
+	hdmi_out_con: endpoint {
+		remote-endpoint = <&hdmi_con_in>;
+	};
+};
+
 &ir {
 	pinctrl-names = "default";
 	pinctrl-0 = <&ir_pins_a>;
-- 
2.11.0

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

* [PATCH 19/19] ARM: sun6i: a31s: Enable HDMI display output on the MSI Primo81 tablet
       [not found] ` <20170602101024.18940-1-wens-jdAy2FN1RRM@public.gmane.org>
                     ` (15 preceding siblings ...)
  2017-06-02 10:10   ` [PATCH 18/19] ARM: sun6i: a31s: Enable HDMI display output on the Sinlinx SinA31s Chen-Yu Tsai
@ 2017-06-02 10:10   ` Chen-Yu Tsai
       [not found]     ` <20170602101024.18940-20-wens-jdAy2FN1RRM@public.gmane.org>
  16 siblings, 1 reply; 38+ messages in thread
From: Chen-Yu Tsai @ 2017-06-02 10:10 UTC (permalink / raw)
  To: Maxime Ripard, David Airlie, Rob Herring, Michael Turquette,
	Stephen Boyd
  Cc: Chen-Yu Tsai, dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

The MSI Primo81 tablet has a micro HDMI connector at the bottom.
This is connected to the SoCs HDMI output.

Enable the display pipeline and the HDMI output.

Signed-off-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
---
 arch/arm/boot/dts/sun6i-a31s-primo81.dts | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/arch/arm/boot/dts/sun6i-a31s-primo81.dts b/arch/arm/boot/dts/sun6i-a31s-primo81.dts
index f3712753fa42..26154b2f87a3 100644
--- a/arch/arm/boot/dts/sun6i-a31s-primo81.dts
+++ b/arch/arm/boot/dts/sun6i-a31s-primo81.dts
@@ -52,17 +52,42 @@
 / {
 	model = "MSI Primo81 tablet";
 	compatible = "msi,primo81", "allwinner,sun6i-a31s";
+
+	hdmi-connector {
+		compatible = "hdmi-connector";
+		type = "c";
+
+		port {
+			hdmi_con_in: endpoint {
+				remote-endpoint = <&hdmi_out_con>;
+			};
+		};
+	};
 };
 
 &cpu0 {
 	cpu-supply = <&reg_dcdc3>;
 };
 
+&de {
+	status = "okay";
+};
+
 &ehci0 {
 	/* rtl8188etv wifi is connected here */
 	status = "okay";
 };
 
+&hdmi {
+	status = "okay";
+};
+
+&hdmi_out {
+	hdmi_out_con: endpoint {
+		remote-endpoint = <&hdmi_con_in>;
+	};
+};
+
 &i2c0 {
 	/* pull-ups and device VDDIO use AXP221 DLDO3 */
 	pinctrl-names = "default";
-- 
2.11.0

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

* Re: [PATCH 02/19] drm/sun4i: add components in two passes with encoders added in second pass
  2017-06-02 10:10 ` [PATCH 02/19] drm/sun4i: add components in two passes with encoders added in second pass Chen-Yu Tsai
@ 2017-06-02 19:18   ` Maxime Ripard
  0 siblings, 0 replies; 38+ messages in thread
From: Maxime Ripard @ 2017-06-02 19:18 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: David Airlie, Rob Herring, Michael Turquette, Stephen Boyd,
	dri-devel, linux-arm-kernel, devicetree, linux-clk, linux-sunxi

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

On Fri, Jun 02, 2017 at 06:10:07PM +0800, Chen-Yu Tsai wrote:
> The encoder drivers use drm_of_find_possible_crtcs to get upstream
> crtcs from the device tree using of_graph. For the results to be
> correct, encoders must be probed/bound after _all_ crtcs have been
> created. The existing code uses a depth first recursive traversal
> of the of_graph, which means the encoders downstream of the TCON
> get add right after the first TCON. The second TCON or CRTC will
> never be properly associated with encoders connected to it.
> 
> Other platforms, such as Rockchip, deal with this by probing all
> crtcs first, then all subsequent components. This is easy to do
> since the crtcs correspond to just one device node, and are the
> first nodes in the pipeline.
> 
> However with Allwinner SoCs, the function of the CRTC is split between
> the display backend (DE 1.0) or mixer (DE 2.0), which does scan-out
> and compositing, and the TCON, which generating the display timing
> signals. Further complicating the process, there may be a Dynamic Range
> Controller between the backend and the TCON. Also, the backend is
> preceded by the frontend, with a Display Enhancement Unit possibly
> in between.
> 
> One solution would be, instead of a depth first traversal of the
> component of_graph, we do a breadth first traversal, so that components
> at the same depth are grouped together. This however requires us to
> implement extra code for a queue structure that is only used here.
> 
> Instead, since we can identify TCON device nodes, and since the
> component system can gracefully deal with duplicate entries, we can add
> components in two passes, using the existing recursive depth code. The
> first pass stops right after the TCON is added. The second pass will
> re-add all components up to the TCON, but these will be skipped since
> they will have already been bound with the entries from the first pass.
> The encoders added in the second pass will be the last entries in the
> list.
> 
> Signed-off-by: Chen-Yu Tsai <wens@csie.org>

This commit log is great. So great actually that it should be a
comment in the code ;)

Maxime

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

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

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

* Re: [PATCH 10/19] drm/sun4i: hdmi: Rename internal DDC clock to avoid name collision
  2017-06-02 10:10   ` [PATCH 10/19] drm/sun4i: hdmi: Rename internal DDC clock to avoid name collision Chen-Yu Tsai
@ 2017-06-02 19:30     ` Maxime Ripard
  2017-06-03 14:33       ` Chen-Yu Tsai
  0 siblings, 1 reply; 38+ messages in thread
From: Maxime Ripard @ 2017-06-02 19:30 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: David Airlie, Rob Herring, Michael Turquette, Stephen Boyd,
	dri-devel, linux-arm-kernel, devicetree, linux-clk, linux-sunxi

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

On Fri, Jun 02, 2017 at 06:10:15PM +0800, Chen-Yu Tsai wrote:
> The DDC parent clock on the A31 SoC is also conveniently named
> "hdmi-ddc", which results in a name collision when the hdmi driver
> registers its internal DDC divider clock.
> 
> Rename the internal clock to "hdmi-ddc-divider".
> 
> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
> ---
>  drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c
> index e1071838f487..9a6b6243e977 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c
> @@ -125,7 +125,7 @@ static int _sun4i_ddc_create(struct sun4i_hdmi *hdmi, struct clk *parent,
>  	if (!ddc)
>  		return -ENOMEM;
>  
> -	init.name = "hdmi-ddc";
> +	init.name = "hdmi-ddc-divider";

Can't we rename the CCU clock instead? Having the clock called
hdmi-ddc being the actual clock output on the DDC bus feels more
natural.

Maxime

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

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

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

* Re: [PATCH 12/19] drm/sun4i: hdmi: Support the DDC clock in the A31's HDMI controller
       [not found]     ` <20170602101024.18940-13-wens-jdAy2FN1RRM@public.gmane.org>
@ 2017-06-02 19:31       ` Maxime Ripard
  0 siblings, 0 replies; 38+ messages in thread
From: Maxime Ripard @ 2017-06-02 19:31 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: David Airlie, Rob Herring, Michael Turquette, Stephen Boyd,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

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

On Fri, Jun 02, 2017 at 06:10:17PM +0800, Chen-Yu Tsai wrote:
> On the A31, the HDMI DDC block is different from the one in the
> other SoCs. As far as the DDC clock goes, it has no pre-divider,
> as it is clocked from a slower parent clock, not the TMDS clock.
> The divider offset from the register value is different. And the
> clock control register is at a different offset.
> 
> This patch adds support for this variant.
> 
> Signed-off-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
> ---
>  drivers/gpu/drm/sun4i/sun4i_hdmi.h         |  1 +
>  drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c | 11 +++++++++++
>  2 files changed, 12 insertions(+)
> 
> diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi.h b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
> index 08c514672fd3..c39c2a245339 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_hdmi.h
> +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
> @@ -178,6 +178,7 @@ struct sun4i_hdmi {
>  };
>  
>  int sun4i_ddc_create(struct sun4i_hdmi *hdmi, struct clk *clk);
> +int sun6i_ddc_create(struct sun4i_hdmi *hdmi, struct clk *clk);
>  int sun4i_tmds_create(struct sun4i_hdmi *hdmi);
>  int sun6i_tmds_create(struct sun4i_hdmi *hdmi);
>  
> diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c
> index 9a6b6243e977..b1395e7b242c 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c
> @@ -151,3 +151,14 @@ int sun4i_ddc_create(struct sun4i_hdmi *hdmi, struct clk *parent)
>  {
>  	return _sun4i_ddc_create(hdmi, parent, &sun4i_variant);
>  }
> +
> +static const struct sun4i_ddc_variant sun6i_variant = {
> +	.reg_offset	= SUN6I_HDMI_DDC_CLK_REG,

This one should be handled through a regmap_field.

Maxime

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

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

* Re: [PATCH 13/19] drm/sun4i: hdmi: Add support for controller hardware variants
  2017-06-02 10:10   ` [PATCH 13/19] drm/sun4i: hdmi: Add support for controller hardware variants Chen-Yu Tsai
@ 2017-06-02 19:38     ` Maxime Ripard
       [not found]       ` <20170602193827.rnjum6x5ra4x5wef-ZC1Zs529Oq4@public.gmane.org>
  0 siblings, 1 reply; 38+ messages in thread
From: Maxime Ripard @ 2017-06-02 19:38 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: David Airlie, Rob Herring, Michael Turquette, Stephen Boyd,
	dri-devel, linux-arm-kernel, devicetree, linux-clk, linux-sunxi

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

On Fri, Jun 02, 2017 at 06:10:18PM +0800, Chen-Yu Tsai wrote:
> The HDMI controller found in earlier Allwinner SoCs have slight
> differences:
> 
>   - Need different initial values for the PLL related registers
> 
>   - Different behavior of the DDC and TMDS clocks
> 
>   - Different register layout for the DDC portion
> 
>   - Separate DDC parent clock on the A31
> 
>   - Explicit reset control
> 
> The clock variants are supported within their implementations,
> which only expose a create function for each variant.
> 
> The different layout of the DDC registers necessitates a separate
> version of struct drm_connector_helper_funcs.
> 
> A new variant data structure is created to store pointers to the
> above functions, structures, and the different initial values.
> Another flag notates whether there is a separate DDC parent clock.
> If not, the TMDS clock is passed to the DDC clock create function,
> as before.
> 
> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
> ---
>  drivers/clk/sunxi-ng/ccu-sun6i-a31.c   |   2 +-
>  drivers/gpu/drm/sun4i/sun4i_hdmi.h     |   8 +++
>  drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 114 ++++++++++++++++++++++++++-------
>  3 files changed, 100 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/clk/sunxi-ng/ccu-sun6i-a31.c b/drivers/clk/sunxi-ng/ccu-sun6i-a31.c
> index 4d6078fca9ac..e48186985a51 100644
> --- a/drivers/clk/sunxi-ng/ccu-sun6i-a31.c
> +++ b/drivers/clk/sunxi-ng/ccu-sun6i-a31.c
> @@ -610,7 +610,7 @@ static SUNXI_CCU_M_WITH_MUX_GATE(hdmi_clk, "hdmi", lcd_ch1_parents,
>  
>  static SUNXI_CCU_GATE(hdmi_ddc_clk, "hdmi-ddc", "osc24M", 0x150, BIT(30), 0);
>  
> -static SUNXI_CCU_GATE(ps_clk, "ps", "lcd1-ch1", 0x140, BIT(31), 0);
> +static SUNXI_CCU_GATE(ps_clk, "ps", "lcd1-ch1", 0x154, BIT(31), 0);

Unrelated change?

>  
>  static const char * const mbus_parents[] = { "osc24M", "pll-periph",
>  					     "pll-ddr" };
> diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi.h b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
> index c39c2a245339..c63d0bd95963 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_hdmi.h
> +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
> @@ -155,6 +155,8 @@ enum sun4i_hdmi_pkt_type {
>  	SUN4I_HDMI_PKT_END = 15,
>  };
>  
> +struct sun4i_hdmi_variant;
> +
>  struct sun4i_hdmi {
>  	struct drm_connector	connector;
>  	struct drm_encoder	encoder;
> @@ -162,9 +164,13 @@ struct sun4i_hdmi {
>  
>  	void __iomem		*base;
>  
> +	/* Reset control */
> +	struct reset_control	*reset;
> +
>  	/* Parent clocks */
>  	struct clk		*bus_clk;
>  	struct clk		*mod_clk;
> +	struct clk		*ddc_parent_clk;
>  	struct clk		*pll0_clk;
>  	struct clk		*pll1_clk;
>  
> @@ -175,6 +181,8 @@ struct sun4i_hdmi {
>  	struct sun4i_drv	*drv;
>  
>  	bool			hdmi_monitor;
> +
> +	const struct sun4i_hdmi_variant	*variant;
>  };
>  
>  int sun4i_ddc_create(struct sun4i_hdmi *hdmi, struct clk *clk);
> diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
> index 457614073501..9ded40aaed32 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
> @@ -20,8 +20,10 @@
>  #include <linux/clk.h>
>  #include <linux/component.h>
>  #include <linux/iopoll.h>
> +#include <linux/of_device.h>
>  #include <linux/platform_device.h>
>  #include <linux/pm_runtime.h>
> +#include <linux/reset.h>
>  
>  #include "sun4i_backend.h"
>  #include "sun4i_crtc.h"
> @@ -315,6 +317,56 @@ static const struct drm_connector_funcs sun4i_hdmi_connector_funcs = {
>  	.atomic_destroy_state	= drm_atomic_helper_connector_destroy_state,
>  };
>  
> +struct sun4i_hdmi_variant {
> +	const struct drm_connector_helper_funcs *connector_helpers;
> +	int (*ddc_create)(struct sun4i_hdmi *hdmi, struct clk *clk);
> +	int (*tmds_create)(struct sun4i_hdmi *hdmi);
> +	bool has_ddc_parent_clk;
> +	bool has_reset_control;
> +
> +	u32 pad_ctrl0_init_val;
> +	u32 pad_ctrl1_init_val;
> +	u32 pll_ctrl_init_val;
> +};
> +
> +#define SUN4I_HDMI_PAD_CTRL1_MASK	(GENMASK(24, 7) | GENMASK(5, 0))
> +#define SUN4I_HDMI_PLL_CTRL_MASK	(GENMASK(31, 8) | GENMASK(3, 0))
> +
> +static const struct sun4i_hdmi_variant sun5i_variant = {
> +	.connector_helpers	= &sun4i_hdmi_connector_helper_funcs,
> +	.ddc_create		= sun4i_ddc_create,
> +	.tmds_create		= sun4i_tmds_create,

If we store the variants info for those clocks in that structure, we
don't need those functions anymore. This would be cleaner imho.

> +	.has_ddc_parent_clk	= false,
> +	.has_reset_control	= false,

Those two are the default values


Maxime

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

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

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

* Re: [PATCH 14/19] drm/sun4i: hdmi: Add support for A31's HDMI controller
  2017-06-02 10:10   ` [PATCH 14/19] drm/sun4i: hdmi: Add support for A31's HDMI controller Chen-Yu Tsai
@ 2017-06-02 19:41     ` Maxime Ripard
  2017-06-03 15:19       ` Chen-Yu Tsai
  0 siblings, 1 reply; 38+ messages in thread
From: Maxime Ripard @ 2017-06-02 19:41 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: David Airlie, Rob Herring, Michael Turquette, Stephen Boyd,
	dri-devel, linux-arm-kernel, devicetree, linux-clk, linux-sunxi

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

On Fri, Jun 02, 2017 at 06:10:19PM +0800, Chen-Yu Tsai wrote:
> The HDMI controller found in the A31 SoCs is slightly different
> from the one already supported, which is found in the A10s:
> 
>   - Need different initial values for the PLL related registers
> 
>   - Different behavior of the DDC and TMDS clocks
> 
>   - Different register layout for the DDC portion
> 
>   - Separate DDC parent clock
> 
> This patch adds support for it.
> 
> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
> ---
>  drivers/gpu/drm/sun4i/sun4i_hdmi.h     |   3 +
>  drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 141 +++++++++++++++++++++++++++++++++
>  2 files changed, 144 insertions(+)
> 
> diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi.h b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
> index c63d0bd95963..2589bc92be59 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_hdmi.h
> +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
> @@ -56,10 +56,13 @@
>  #define SUN4I_HDMI_PAD_CTRL0_TXEN		BIT(23)
>  
>  #define SUN4I_HDMI_PAD_CTRL1_REG	0x204
> +#define SUN4I_HDMI_PAD_CTRL1_UNKNOWN		BIT(24)	/* set on A31 */
>  #define SUN4I_HDMI_PAD_CTRL1_AMP_OPT		BIT(23)
>  #define SUN4I_HDMI_PAD_CTRL1_AMPCK_OPT		BIT(22)
>  #define SUN4I_HDMI_PAD_CTRL1_EMP_OPT		BIT(20)
>  #define SUN4I_HDMI_PAD_CTRL1_EMPCK_OPT		BIT(19)
> +#define SUN4I_HDMI_PAD_CTRL1_PWSCK		BIT(18)
> +#define SUN4I_HDMI_PAD_CTRL1_PWSDT		BIT(17)
>  #define SUN4I_HDMI_PAD_CTRL1_REG_DEN		BIT(15)
>  #define SUN4I_HDMI_PAD_CTRL1_REG_DENCK		BIT(14)
>  #define SUN4I_HDMI_PAD_CTRL1_REG_EMP(n)		(((n) & 7) << 10)
> diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
> index 9ded40aaed32..e9abf93eb41c 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
> @@ -293,6 +293,109 @@ static const struct drm_connector_helper_funcs sun4i_hdmi_connector_helper_funcs
>  	.get_modes	= sun4i_hdmi_get_modes,
>  };
>  
> +static int sun6i_hdmi_read_sub_block(struct sun4i_hdmi *hdmi,
> +				     unsigned int blk, unsigned int offset,
> +				     u8 *buf, unsigned int count)
> +{
> +	unsigned long reg;
> +	int i;
> +
> +	reg = readl(hdmi->base + SUN6I_HDMI_DDC_FIFO_CTRL_REG);
> +	writel(reg | SUN6I_HDMI_DDC_FIFO_CTRL_CLEAR,
> +	       hdmi->base + SUN6I_HDMI_DDC_FIFO_CTRL_REG);
> +	writel(SUN6I_HDMI_DDC_ADDR_SEGMENT(offset >> 8) |
> +	       SUN6I_HDMI_DDC_ADDR_EDDC(DDC_SEGMENT_ADDR << 1) |
> +	       SUN6I_HDMI_DDC_ADDR_OFFSET(offset) |
> +	       SUN6I_HDMI_DDC_ADDR_SLAVE(DDC_ADDR),
> +	       hdmi->base + SUN6I_HDMI_DDC_ADDR_REG);
> +
> +	writel(SUN6I_HDMI_DDC_CMD_EXPLICIT_EDDC_READ |
> +	       SUN6I_HDMI_DDC_CMD_BYTE_COUNT(count),
> +	       hdmi->base + SUN6I_HDMI_DDC_CMD_REG);
> +
> +	reg = readl(hdmi->base + SUN6I_HDMI_DDC_CTRL_REG);
> +	writel(reg | SUN6I_HDMI_DDC_CTRL_START_CMD,
> +	       hdmi->base + SUN6I_HDMI_DDC_CTRL_REG);
> +
> +	if (readl_poll_timeout(hdmi->base + SUN6I_HDMI_DDC_CTRL_REG, reg,
> +			       !(reg & SUN6I_HDMI_DDC_CTRL_START_CMD),
> +			       100, 100000))
> +		return -EIO;
> +
> +	for (i = 0; i < count; i++)
> +		buf[i] = readb(hdmi->base + SUN6I_HDMI_DDC_FIFO_DATA_REG);
> +
> +	return 0;
> +}
> +
> +static int sun6i_hdmi_read_edid_block(void *data, u8 *buf, unsigned int blk,
> +				      size_t length)
> +{
> +	struct sun4i_hdmi *hdmi = data;
> +	int retry = 2, i;
> +
> +	do {
> +		for (i = 0; i < length; i += SUN4I_HDMI_DDC_FIFO_SIZE) {
> +			unsigned char offset = blk * EDID_LENGTH + i;
> +			unsigned int count = min((unsigned int)SUN4I_HDMI_DDC_FIFO_SIZE,
> +						 length - i);
> +			int ret;
> +
> +			ret = sun6i_hdmi_read_sub_block(hdmi, blk, offset,
> +							buf + i, count);
> +			if (ret)
> +				return ret;
> +		}
> +	} while (!drm_edid_block_valid(buf, blk, true, NULL) && (retry--));
> +
> +	return 0;
> +}
> +
> +static int sun6i_hdmi_get_modes(struct drm_connector *connector)
> +{
> +	struct sun4i_hdmi *hdmi = drm_connector_to_sun4i_hdmi(connector);
> +	u32 reg;
> +	struct edid *edid;
> +	int ret;
> +
> +	clk_set_rate(hdmi->ddc_clk, 100000);
> +	clk_prepare_enable(hdmi->ddc_clk);
> +
> +	/* Reset i2c controller */
> +	writel(SUN6I_HDMI_DDC_CTRL_ENABLE | SUN6I_HDMI_DDC_CTRL_RESET |
> +	       SUN6I_HDMI_DDC_CTRL_SDA_ENABLE |
> +	       SUN6I_HDMI_DDC_CTRL_SCL_ENABLE,
> +	       hdmi->base + SUN6I_HDMI_DDC_CTRL_REG);
> +	if (readl_poll_timeout(hdmi->base + SUN6I_HDMI_DDC_CTRL_REG, reg,
> +			       !(reg & SUN6I_HDMI_DDC_CTRL_RESET),
> +			       100, 2000)) {
> +		dev_err(hdmi->dev, "DDC reset timeout: %08x\n", reg);
> +		clk_disable_unprepare(hdmi->ddc_clk);
> +		return -EIO;
> +	}
> +
> +	edid = drm_do_get_edid(connector, sun6i_hdmi_read_edid_block, hdmi);
> +
> +	clk_disable_unprepare(hdmi->ddc_clk);
> +
> +	if (!edid)
> +		return 0;
> +
> +	hdmi->hdmi_monitor = drm_detect_hdmi_monitor(edid);
> +	DRM_DEBUG_DRIVER("Monitor is %s monitor\n",
> +			 hdmi->hdmi_monitor ? "an HDMI" : "a DVI");
> +
> +	drm_mode_connector_update_edid_property(connector, edid);
> +	ret = drm_add_edid_modes(connector, edid);
> +	kfree(edid);
> +
> +	return ret;
> +}
> +
> +static const struct drm_connector_helper_funcs sun6i_hdmi_connector_helper_funcs = {
> +	.get_modes	= sun6i_hdmi_get_modes,
> +};
> +

Every thing here can be handled through regfield without having to
duplicate the logic.

>  static enum drm_connector_status
>  sun4i_hdmi_connector_detect(struct drm_connector *connector, bool force)
>  {
> @@ -367,6 +470,43 @@ static const struct sun4i_hdmi_variant sun5i_variant = {
>  				  SUN4I_HDMI_PLL_CTRL_PLL_EN,
>  };
>  
> +static const struct sun4i_hdmi_variant sun6i_variant = {
> +	.connector_helpers	= &sun6i_hdmi_connector_helper_funcs,
> +	.ddc_create		= sun6i_ddc_create,
> +	.tmds_create		= sun6i_tmds_create,
> +	.has_ddc_parent_clk	= true,
> +	.has_reset_control	= true,
> +	.pad_ctrl0_init_val	= 0xff |

What is this 0xff for?

Maxime

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

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

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

* Re: [PATCH 19/19] ARM: sun6i: a31s: Enable HDMI display output on the MSI Primo81 tablet
       [not found]     ` <20170602101024.18940-20-wens-jdAy2FN1RRM@public.gmane.org>
@ 2017-06-02 19:42       ` Maxime Ripard
       [not found]         ` <20170602194219.hiajr7dt2oikm52q-ZC1Zs529Oq4@public.gmane.org>
  0 siblings, 1 reply; 38+ messages in thread
From: Maxime Ripard @ 2017-06-02 19:42 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: David Airlie, Rob Herring, Michael Turquette, Stephen Boyd,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

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

On Fri, Jun 02, 2017 at 06:10:24PM +0800, Chen-Yu Tsai wrote:
> The MSI Primo81 tablet has a micro HDMI connector at the bottom.
> This is connected to the SoCs HDMI output.
> 
> Enable the display pipeline and the HDMI output.
> 
> Signed-off-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
> ---
>  arch/arm/boot/dts/sun6i-a31s-primo81.dts | 25 +++++++++++++++++++++++++
>  1 file changed, 25 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/sun6i-a31s-primo81.dts b/arch/arm/boot/dts/sun6i-a31s-primo81.dts
> index f3712753fa42..26154b2f87a3 100644
> --- a/arch/arm/boot/dts/sun6i-a31s-primo81.dts
> +++ b/arch/arm/boot/dts/sun6i-a31s-primo81.dts
> @@ -52,17 +52,42 @@
>  / {
>  	model = "MSI Primo81 tablet";
>  	compatible = "msi,primo81", "allwinner,sun6i-a31s";
> +
> +	hdmi-connector {
> +		compatible = "hdmi-connector";
> +		type = "c";

Should we add a connector type for this one?

Maxime

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

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

* Re: [PATCH 10/19] drm/sun4i: hdmi: Rename internal DDC clock to avoid name collision
  2017-06-02 19:30     ` Maxime Ripard
@ 2017-06-03 14:33       ` Chen-Yu Tsai
       [not found]         ` <CAGb2v64Vgdjm1MAwn+L0PVc0CA0QOCn=0RONKoGDWLpzVBzvmQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 38+ messages in thread
From: Chen-Yu Tsai @ 2017-06-03 14:33 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Chen-Yu Tsai, David Airlie, Rob Herring, Michael Turquette,
	Stephen Boyd, dri-devel, linux-arm-kernel, devicetree, linux-clk,
	linux-sunxi

On Sat, Jun 3, 2017 at 3:30 AM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> On Fri, Jun 02, 2017 at 06:10:15PM +0800, Chen-Yu Tsai wrote:
>> The DDC parent clock on the A31 SoC is also conveniently named
>> "hdmi-ddc", which results in a name collision when the hdmi driver
>> registers its internal DDC divider clock.
>>
>> Rename the internal clock to "hdmi-ddc-divider".
>>
>> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
>> ---
>>  drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c
>> index e1071838f487..9a6b6243e977 100644
>> --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c
>> +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c
>> @@ -125,7 +125,7 @@ static int _sun4i_ddc_create(struct sun4i_hdmi *hdmi, struct clk *parent,
>>       if (!ddc)
>>               return -ENOMEM;
>>
>> -     init.name = "hdmi-ddc";
>> +     init.name = "hdmi-ddc-divider";
>
> Can't we rename the CCU clock instead? Having the clock called
> hdmi-ddc being the actual clock output on the DDC bus feels more
> natural.

Do you have any suggestions? The manual labels the conflicting one
in the CCU as "HDMI_DDC"...

ChenYu

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

* Re: [PATCH 13/19] drm/sun4i: hdmi: Add support for controller hardware variants
       [not found]       ` <20170602193827.rnjum6x5ra4x5wef-ZC1Zs529Oq4@public.gmane.org>
@ 2017-06-03 14:58         ` Chen-Yu Tsai
  0 siblings, 0 replies; 38+ messages in thread
From: Chen-Yu Tsai @ 2017-06-03 14:58 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Chen-Yu Tsai, David Airlie, Rob Herring, Michael Turquette,
	Stephen Boyd, dri-devel, linux-arm-kernel, devicetree, linux-clk,
	linux-sunxi

On Sat, Jun 3, 2017 at 3:38 AM, Maxime Ripard
<maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org> wrote:
> On Fri, Jun 02, 2017 at 06:10:18PM +0800, Chen-Yu Tsai wrote:
>> The HDMI controller found in earlier Allwinner SoCs have slight
>> differences:
>>
>>   - Need different initial values for the PLL related registers
>>
>>   - Different behavior of the DDC and TMDS clocks
>>
>>   - Different register layout for the DDC portion
>>
>>   - Separate DDC parent clock on the A31
>>
>>   - Explicit reset control
>>
>> The clock variants are supported within their implementations,
>> which only expose a create function for each variant.
>>
>> The different layout of the DDC registers necessitates a separate
>> version of struct drm_connector_helper_funcs.
>>
>> A new variant data structure is created to store pointers to the
>> above functions, structures, and the different initial values.
>> Another flag notates whether there is a separate DDC parent clock.
>> If not, the TMDS clock is passed to the DDC clock create function,
>> as before.
>>
>> Signed-off-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
>> ---
>>  drivers/clk/sunxi-ng/ccu-sun6i-a31.c   |   2 +-
>>  drivers/gpu/drm/sun4i/sun4i_hdmi.h     |   8 +++
>>  drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 114 ++++++++++++++++++++++++++-------
>>  3 files changed, 100 insertions(+), 24 deletions(-)
>>
>> diff --git a/drivers/clk/sunxi-ng/ccu-sun6i-a31.c b/drivers/clk/sunxi-ng/ccu-sun6i-a31.c
>> index 4d6078fca9ac..e48186985a51 100644
>> --- a/drivers/clk/sunxi-ng/ccu-sun6i-a31.c
>> +++ b/drivers/clk/sunxi-ng/ccu-sun6i-a31.c
>> @@ -610,7 +610,7 @@ static SUNXI_CCU_M_WITH_MUX_GATE(hdmi_clk, "hdmi", lcd_ch1_parents,
>>
>>  static SUNXI_CCU_GATE(hdmi_ddc_clk, "hdmi-ddc", "osc24M", 0x150, BIT(30), 0);
>>
>> -static SUNXI_CCU_GATE(ps_clk, "ps", "lcd1-ch1", 0x140, BIT(31), 0);
>> +static SUNXI_CCU_GATE(ps_clk, "ps", "lcd1-ch1", 0x154, BIT(31), 0);
>
> Unrelated change?

Indeed. :(

>>
>>  static const char * const mbus_parents[] = { "osc24M", "pll-periph",
>>                                            "pll-ddr" };
>> diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi.h b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
>> index c39c2a245339..c63d0bd95963 100644
>> --- a/drivers/gpu/drm/sun4i/sun4i_hdmi.h
>> +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
>> @@ -155,6 +155,8 @@ enum sun4i_hdmi_pkt_type {
>>       SUN4I_HDMI_PKT_END = 15,
>>  };
>>
>> +struct sun4i_hdmi_variant;
>> +
>>  struct sun4i_hdmi {
>>       struct drm_connector    connector;
>>       struct drm_encoder      encoder;
>> @@ -162,9 +164,13 @@ struct sun4i_hdmi {
>>
>>       void __iomem            *base;
>>
>> +     /* Reset control */
>> +     struct reset_control    *reset;
>> +
>>       /* Parent clocks */
>>       struct clk              *bus_clk;
>>       struct clk              *mod_clk;
>> +     struct clk              *ddc_parent_clk;
>>       struct clk              *pll0_clk;
>>       struct clk              *pll1_clk;
>>
>> @@ -175,6 +181,8 @@ struct sun4i_hdmi {
>>       struct sun4i_drv        *drv;
>>
>>       bool                    hdmi_monitor;
>> +
>> +     const struct sun4i_hdmi_variant *variant;
>>  };
>>
>>  int sun4i_ddc_create(struct sun4i_hdmi *hdmi, struct clk *clk);
>> diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
>> index 457614073501..9ded40aaed32 100644
>> --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
>> +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
>> @@ -20,8 +20,10 @@
>>  #include <linux/clk.h>
>>  #include <linux/component.h>
>>  #include <linux/iopoll.h>
>> +#include <linux/of_device.h>
>>  #include <linux/platform_device.h>
>>  #include <linux/pm_runtime.h>
>> +#include <linux/reset.h>
>>
>>  #include "sun4i_backend.h"
>>  #include "sun4i_crtc.h"
>> @@ -315,6 +317,56 @@ static const struct drm_connector_funcs sun4i_hdmi_connector_funcs = {
>>       .atomic_destroy_state   = drm_atomic_helper_connector_destroy_state,
>>  };
>>
>> +struct sun4i_hdmi_variant {
>> +     const struct drm_connector_helper_funcs *connector_helpers;
>> +     int (*ddc_create)(struct sun4i_hdmi *hdmi, struct clk *clk);
>> +     int (*tmds_create)(struct sun4i_hdmi *hdmi);
>> +     bool has_ddc_parent_clk;
>> +     bool has_reset_control;
>> +
>> +     u32 pad_ctrl0_init_val;
>> +     u32 pad_ctrl1_init_val;
>> +     u32 pll_ctrl_init_val;
>> +};
>> +
>> +#define SUN4I_HDMI_PAD_CTRL1_MASK    (GENMASK(24, 7) | GENMASK(5, 0))
>> +#define SUN4I_HDMI_PLL_CTRL_MASK     (GENMASK(31, 8) | GENMASK(3, 0))
>> +
>> +static const struct sun4i_hdmi_variant sun5i_variant = {
>> +     .connector_helpers      = &sun4i_hdmi_connector_helper_funcs,
>> +     .ddc_create             = sun4i_ddc_create,
>> +     .tmds_create            = sun4i_tmds_create,
>
> If we store the variants info for those clocks in that structure, we
> don't need those functions anymore. This would be cleaner imho.

I'll see what I can do.

>> +     .has_ddc_parent_clk     = false,
>> +     .has_reset_control      = false,
>
> Those two are the default values

Right. I wanted them to be explicitly labeled.

ChenYu

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

* Re: [PATCH 14/19] drm/sun4i: hdmi: Add support for A31's HDMI controller
  2017-06-02 19:41     ` Maxime Ripard
@ 2017-06-03 15:19       ` Chen-Yu Tsai
       [not found]         ` <CAGb2v65eFAmAybmHkQcKjF+ZKxh+_G6q9i2GPzMs5854X8bQug-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 38+ messages in thread
From: Chen-Yu Tsai @ 2017-06-03 15:19 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Chen-Yu Tsai, David Airlie, Rob Herring, Michael Turquette,
	Stephen Boyd, dri-devel, linux-arm-kernel, devicetree, linux-clk,
	linux-sunxi

On Sat, Jun 3, 2017 at 3:41 AM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> On Fri, Jun 02, 2017 at 06:10:19PM +0800, Chen-Yu Tsai wrote:
>> The HDMI controller found in the A31 SoCs is slightly different
>> from the one already supported, which is found in the A10s:
>>
>>   - Need different initial values for the PLL related registers
>>
>>   - Different behavior of the DDC and TMDS clocks
>>
>>   - Different register layout for the DDC portion
>>
>>   - Separate DDC parent clock
>>
>> This patch adds support for it.
>>
>> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
>> ---
>>  drivers/gpu/drm/sun4i/sun4i_hdmi.h     |   3 +
>>  drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 141 +++++++++++++++++++++++++++++++++
>>  2 files changed, 144 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi.h b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
>> index c63d0bd95963..2589bc92be59 100644
>> --- a/drivers/gpu/drm/sun4i/sun4i_hdmi.h
>> +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
>> @@ -56,10 +56,13 @@
>>  #define SUN4I_HDMI_PAD_CTRL0_TXEN            BIT(23)
>>
>>  #define SUN4I_HDMI_PAD_CTRL1_REG     0x204
>> +#define SUN4I_HDMI_PAD_CTRL1_UNKNOWN         BIT(24) /* set on A31 */
>>  #define SUN4I_HDMI_PAD_CTRL1_AMP_OPT         BIT(23)
>>  #define SUN4I_HDMI_PAD_CTRL1_AMPCK_OPT               BIT(22)
>>  #define SUN4I_HDMI_PAD_CTRL1_EMP_OPT         BIT(20)
>>  #define SUN4I_HDMI_PAD_CTRL1_EMPCK_OPT               BIT(19)
>> +#define SUN4I_HDMI_PAD_CTRL1_PWSCK           BIT(18)
>> +#define SUN4I_HDMI_PAD_CTRL1_PWSDT           BIT(17)
>>  #define SUN4I_HDMI_PAD_CTRL1_REG_DEN         BIT(15)
>>  #define SUN4I_HDMI_PAD_CTRL1_REG_DENCK               BIT(14)
>>  #define SUN4I_HDMI_PAD_CTRL1_REG_EMP(n)              (((n) & 7) << 10)
>> diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
>> index 9ded40aaed32..e9abf93eb41c 100644
>> --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
>> +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
>> @@ -293,6 +293,109 @@ static const struct drm_connector_helper_funcs sun4i_hdmi_connector_helper_funcs
>>       .get_modes      = sun4i_hdmi_get_modes,
>>  };
>>
>> +static int sun6i_hdmi_read_sub_block(struct sun4i_hdmi *hdmi,
>> +                                  unsigned int blk, unsigned int offset,
>> +                                  u8 *buf, unsigned int count)
>> +{
>> +     unsigned long reg;
>> +     int i;
>> +
>> +     reg = readl(hdmi->base + SUN6I_HDMI_DDC_FIFO_CTRL_REG);
>> +     writel(reg | SUN6I_HDMI_DDC_FIFO_CTRL_CLEAR,
>> +            hdmi->base + SUN6I_HDMI_DDC_FIFO_CTRL_REG);
>> +     writel(SUN6I_HDMI_DDC_ADDR_SEGMENT(offset >> 8) |
>> +            SUN6I_HDMI_DDC_ADDR_EDDC(DDC_SEGMENT_ADDR << 1) |
>> +            SUN6I_HDMI_DDC_ADDR_OFFSET(offset) |
>> +            SUN6I_HDMI_DDC_ADDR_SLAVE(DDC_ADDR),
>> +            hdmi->base + SUN6I_HDMI_DDC_ADDR_REG);
>> +
>> +     writel(SUN6I_HDMI_DDC_CMD_EXPLICIT_EDDC_READ |
>> +            SUN6I_HDMI_DDC_CMD_BYTE_COUNT(count),
>> +            hdmi->base + SUN6I_HDMI_DDC_CMD_REG);
>> +
>> +     reg = readl(hdmi->base + SUN6I_HDMI_DDC_CTRL_REG);
>> +     writel(reg | SUN6I_HDMI_DDC_CTRL_START_CMD,
>> +            hdmi->base + SUN6I_HDMI_DDC_CTRL_REG);
>> +
>> +     if (readl_poll_timeout(hdmi->base + SUN6I_HDMI_DDC_CTRL_REG, reg,
>> +                            !(reg & SUN6I_HDMI_DDC_CTRL_START_CMD),
>> +                            100, 100000))
>> +             return -EIO;
>> +
>> +     for (i = 0; i < count; i++)
>> +             buf[i] = readb(hdmi->base + SUN6I_HDMI_DDC_FIFO_DATA_REG);
>> +
>> +     return 0;
>> +}
>> +
>> +static int sun6i_hdmi_read_edid_block(void *data, u8 *buf, unsigned int blk,
>> +                                   size_t length)
>> +{
>> +     struct sun4i_hdmi *hdmi = data;
>> +     int retry = 2, i;
>> +
>> +     do {
>> +             for (i = 0; i < length; i += SUN4I_HDMI_DDC_FIFO_SIZE) {
>> +                     unsigned char offset = blk * EDID_LENGTH + i;
>> +                     unsigned int count = min((unsigned int)SUN4I_HDMI_DDC_FIFO_SIZE,
>> +                                              length - i);
>> +                     int ret;
>> +
>> +                     ret = sun6i_hdmi_read_sub_block(hdmi, blk, offset,
>> +                                                     buf + i, count);
>> +                     if (ret)
>> +                             return ret;
>> +             }
>> +     } while (!drm_edid_block_valid(buf, blk, true, NULL) && (retry--));
>> +
>> +     return 0;
>> +}
>> +
>> +static int sun6i_hdmi_get_modes(struct drm_connector *connector)
>> +{
>> +     struct sun4i_hdmi *hdmi = drm_connector_to_sun4i_hdmi(connector);
>> +     u32 reg;
>> +     struct edid *edid;
>> +     int ret;
>> +
>> +     clk_set_rate(hdmi->ddc_clk, 100000);
>> +     clk_prepare_enable(hdmi->ddc_clk);
>> +
>> +     /* Reset i2c controller */
>> +     writel(SUN6I_HDMI_DDC_CTRL_ENABLE | SUN6I_HDMI_DDC_CTRL_RESET |
>> +            SUN6I_HDMI_DDC_CTRL_SDA_ENABLE |
>> +            SUN6I_HDMI_DDC_CTRL_SCL_ENABLE,
>> +            hdmi->base + SUN6I_HDMI_DDC_CTRL_REG);
>> +     if (readl_poll_timeout(hdmi->base + SUN6I_HDMI_DDC_CTRL_REG, reg,
>> +                            !(reg & SUN6I_HDMI_DDC_CTRL_RESET),
>> +                            100, 2000)) {
>> +             dev_err(hdmi->dev, "DDC reset timeout: %08x\n", reg);
>> +             clk_disable_unprepare(hdmi->ddc_clk);
>> +             return -EIO;
>> +     }
>> +
>> +     edid = drm_do_get_edid(connector, sun6i_hdmi_read_edid_block, hdmi);
>> +
>> +     clk_disable_unprepare(hdmi->ddc_clk);
>> +
>> +     if (!edid)
>> +             return 0;
>> +
>> +     hdmi->hdmi_monitor = drm_detect_hdmi_monitor(edid);
>> +     DRM_DEBUG_DRIVER("Monitor is %s monitor\n",
>> +                      hdmi->hdmi_monitor ? "an HDMI" : "a DVI");
>> +
>> +     drm_mode_connector_update_edid_property(connector, edid);
>> +     ret = drm_add_edid_modes(connector, edid);
>> +     kfree(edid);
>> +
>> +     return ret;
>> +}
>> +
>> +static const struct drm_connector_helper_funcs sun6i_hdmi_connector_helper_funcs = {
>> +     .get_modes      = sun6i_hdmi_get_modes,
>> +};
>> +
>
> Every thing here can be handled through regfield without having to
> duplicate the logic.

Hmm... You're right. Does that mean we should convert the entire driver to
using regmap? Or just the DDC bits here, since they won't conflict with
any other access patterns in the whole HDMI driver?

>
>>  static enum drm_connector_status
>>  sun4i_hdmi_connector_detect(struct drm_connector *connector, bool force)
>>  {
>> @@ -367,6 +470,43 @@ static const struct sun4i_hdmi_variant sun5i_variant = {
>>                                 SUN4I_HDMI_PLL_CTRL_PLL_EN,
>>  };
>>
>> +static const struct sun4i_hdmi_variant sun6i_variant = {
>> +     .connector_helpers      = &sun6i_hdmi_connector_helper_funcs,
>> +     .ddc_create             = sun6i_ddc_create,
>> +     .tmds_create            = sun6i_tmds_create,
>> +     .has_ddc_parent_clk     = true,
>> +     .has_reset_control      = true,
>> +     .pad_ctrl0_init_val     = 0xff |
>
> What is this 0xff for?

Unknown. It is set in the mainline U-boot driver.

Looking at an old 3.3 kernel from the BSP, it seems the higher 4 bits
control the transmitter. But the lower 4 bits are still unknown.

ChenYu

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

* Re: [PATCH 19/19] ARM: sun6i: a31s: Enable HDMI display output on the MSI Primo81 tablet
       [not found]         ` <20170602194219.hiajr7dt2oikm52q-ZC1Zs529Oq4@public.gmane.org>
@ 2017-06-03 15:31           ` Chen-Yu Tsai
  2017-06-07 22:36           ` Rob Herring
  1 sibling, 0 replies; 38+ messages in thread
From: Chen-Yu Tsai @ 2017-06-03 15:31 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Chen-Yu Tsai, David Airlie, Rob Herring, Michael Turquette,
	Stephen Boyd, dri-devel, linux-arm-kernel, devicetree, linux-clk,
	linux-sunxi

On Sat, Jun 3, 2017 at 3:42 AM, Maxime Ripard
<maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org> wrote:
> On Fri, Jun 02, 2017 at 06:10:24PM +0800, Chen-Yu Tsai wrote:
>> The MSI Primo81 tablet has a micro HDMI connector at the bottom.
>> This is connected to the SoCs HDMI output.
>>
>> Enable the display pipeline and the HDMI output.
>>
>> Signed-off-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
>> ---
>>  arch/arm/boot/dts/sun6i-a31s-primo81.dts | 25 +++++++++++++++++++++++++
>>  1 file changed, 25 insertions(+)
>>
>> diff --git a/arch/arm/boot/dts/sun6i-a31s-primo81.dts b/arch/arm/boot/dts/sun6i-a31s-primo81.dts
>> index f3712753fa42..26154b2f87a3 100644
>> --- a/arch/arm/boot/dts/sun6i-a31s-primo81.dts
>> +++ b/arch/arm/boot/dts/sun6i-a31s-primo81.dts
>> @@ -52,17 +52,42 @@
>>  / {
>>       model = "MSI Primo81 tablet";
>>       compatible = "msi,primo81", "allwinner,sun6i-a31s";
>> +
>> +     hdmi-connector {
>> +             compatible = "hdmi-connector";
>> +             type = "c";
>
> Should we add a connector type for this one?

To be honest I don't know. DRM has HDMI-B to differentiate dual-link
connections, but that is only used by Intel and AMD GPU drivers.
AMD driver has "/* HDMI-B is basically DL-DVI; analog works fine */",
which makes sense since actual HDMI B-type connectors only exist on
paper. None of the other drivers seem to care.

ChenYu
--
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] 38+ messages in thread

* Re: [PATCH 10/19] drm/sun4i: hdmi: Rename internal DDC clock to avoid name collision
       [not found]         ` <CAGb2v64Vgdjm1MAwn+L0PVc0CA0QOCn=0RONKoGDWLpzVBzvmQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2017-06-05 14:00           ` Maxime Ripard
       [not found]             ` <20170605140012.rlx7rm7xhriwqaza-ZC1Zs529Oq4@public.gmane.org>
  0 siblings, 1 reply; 38+ messages in thread
From: Maxime Ripard @ 2017-06-05 14:00 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: David Airlie, Rob Herring, Michael Turquette, Stephen Boyd,
	dri-devel, linux-arm-kernel, devicetree, linux-clk, linux-sunxi

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

On Sat, Jun 03, 2017 at 10:33:25PM +0800, Chen-Yu Tsai wrote:
> On Sat, Jun 3, 2017 at 3:30 AM, Maxime Ripard
> <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org> wrote:
> > On Fri, Jun 02, 2017 at 06:10:15PM +0800, Chen-Yu Tsai wrote:
> >> The DDC parent clock on the A31 SoC is also conveniently named
> >> "hdmi-ddc", which results in a name collision when the hdmi driver
> >> registers its internal DDC divider clock.
> >>
> >> Rename the internal clock to "hdmi-ddc-divider".
> >>
> >> Signed-off-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
> >> ---
> >>  drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c | 2 +-
> >>  1 file changed, 1 insertion(+), 1 deletion(-)
> >>
> >> diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c
> >> index e1071838f487..9a6b6243e977 100644
> >> --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c
> >> +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c
> >> @@ -125,7 +125,7 @@ static int _sun4i_ddc_create(struct sun4i_hdmi *hdmi, struct clk *parent,
> >>       if (!ddc)
> >>               return -ENOMEM;
> >>
> >> -     init.name = "hdmi-ddc";
> >> +     init.name = "hdmi-ddc-divider";
> >
> > Can't we rename the CCU clock instead? Having the clock called
> > hdmi-ddc being the actual clock output on the DDC bus feels more
> > natural.
> 
> Do you have any suggestions? The manual labels the conflicting one
> in the CCU as "HDMI_DDC"...

DDC as the main CCU clock, and hdmi-ddc as the one actually generated
by the HDMI controller?

Maxime

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

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

* Re: [PATCH 14/19] drm/sun4i: hdmi: Add support for A31's HDMI controller
       [not found]         ` <CAGb2v65eFAmAybmHkQcKjF+ZKxh+_G6q9i2GPzMs5854X8bQug-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2017-06-06 19:27           ` Maxime Ripard
  0 siblings, 0 replies; 38+ messages in thread
From: Maxime Ripard @ 2017-06-06 19:27 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: David Airlie, Rob Herring, Michael Turquette, Stephen Boyd,
	dri-devel, linux-arm-kernel, devicetree, linux-clk, linux-sunxi

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

On Sat, Jun 03, 2017 at 11:19:09PM +0800, Chen-Yu Tsai wrote:
> On Sat, Jun 3, 2017 at 3:41 AM, Maxime Ripard
> <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org> wrote:
> > On Fri, Jun 02, 2017 at 06:10:19PM +0800, Chen-Yu Tsai wrote:
> >> The HDMI controller found in the A31 SoCs is slightly different
> >> from the one already supported, which is found in the A10s:
> >>
> >>   - Need different initial values for the PLL related registers
> >>
> >>   - Different behavior of the DDC and TMDS clocks
> >>
> >>   - Different register layout for the DDC portion
> >>
> >>   - Separate DDC parent clock
> >>
> >> This patch adds support for it.
> >>
> >> Signed-off-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
> >> ---
> >>  drivers/gpu/drm/sun4i/sun4i_hdmi.h     |   3 +
> >>  drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 141 +++++++++++++++++++++++++++++++++
> >>  2 files changed, 144 insertions(+)
> >>
> >> diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi.h b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
> >> index c63d0bd95963..2589bc92be59 100644
> >> --- a/drivers/gpu/drm/sun4i/sun4i_hdmi.h
> >> +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
> >> @@ -56,10 +56,13 @@
> >>  #define SUN4I_HDMI_PAD_CTRL0_TXEN            BIT(23)
> >>
> >>  #define SUN4I_HDMI_PAD_CTRL1_REG     0x204
> >> +#define SUN4I_HDMI_PAD_CTRL1_UNKNOWN         BIT(24) /* set on A31 */
> >>  #define SUN4I_HDMI_PAD_CTRL1_AMP_OPT         BIT(23)
> >>  #define SUN4I_HDMI_PAD_CTRL1_AMPCK_OPT               BIT(22)
> >>  #define SUN4I_HDMI_PAD_CTRL1_EMP_OPT         BIT(20)
> >>  #define SUN4I_HDMI_PAD_CTRL1_EMPCK_OPT               BIT(19)
> >> +#define SUN4I_HDMI_PAD_CTRL1_PWSCK           BIT(18)
> >> +#define SUN4I_HDMI_PAD_CTRL1_PWSDT           BIT(17)
> >>  #define SUN4I_HDMI_PAD_CTRL1_REG_DEN         BIT(15)
> >>  #define SUN4I_HDMI_PAD_CTRL1_REG_DENCK               BIT(14)
> >>  #define SUN4I_HDMI_PAD_CTRL1_REG_EMP(n)              (((n) & 7) << 10)
> >> diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
> >> index 9ded40aaed32..e9abf93eb41c 100644
> >> --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
> >> +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
> >> @@ -293,6 +293,109 @@ static const struct drm_connector_helper_funcs sun4i_hdmi_connector_helper_funcs
> >>       .get_modes      = sun4i_hdmi_get_modes,
> >>  };
> >>
> >> +static int sun6i_hdmi_read_sub_block(struct sun4i_hdmi *hdmi,
> >> +                                  unsigned int blk, unsigned int offset,
> >> +                                  u8 *buf, unsigned int count)
> >> +{
> >> +     unsigned long reg;
> >> +     int i;
> >> +
> >> +     reg = readl(hdmi->base + SUN6I_HDMI_DDC_FIFO_CTRL_REG);
> >> +     writel(reg | SUN6I_HDMI_DDC_FIFO_CTRL_CLEAR,
> >> +            hdmi->base + SUN6I_HDMI_DDC_FIFO_CTRL_REG);
> >> +     writel(SUN6I_HDMI_DDC_ADDR_SEGMENT(offset >> 8) |
> >> +            SUN6I_HDMI_DDC_ADDR_EDDC(DDC_SEGMENT_ADDR << 1) |
> >> +            SUN6I_HDMI_DDC_ADDR_OFFSET(offset) |
> >> +            SUN6I_HDMI_DDC_ADDR_SLAVE(DDC_ADDR),
> >> +            hdmi->base + SUN6I_HDMI_DDC_ADDR_REG);
> >> +
> >> +     writel(SUN6I_HDMI_DDC_CMD_EXPLICIT_EDDC_READ |
> >> +            SUN6I_HDMI_DDC_CMD_BYTE_COUNT(count),
> >> +            hdmi->base + SUN6I_HDMI_DDC_CMD_REG);
> >> +
> >> +     reg = readl(hdmi->base + SUN6I_HDMI_DDC_CTRL_REG);
> >> +     writel(reg | SUN6I_HDMI_DDC_CTRL_START_CMD,
> >> +            hdmi->base + SUN6I_HDMI_DDC_CTRL_REG);
> >> +
> >> +     if (readl_poll_timeout(hdmi->base + SUN6I_HDMI_DDC_CTRL_REG, reg,
> >> +                            !(reg & SUN6I_HDMI_DDC_CTRL_START_CMD),
> >> +                            100, 100000))
> >> +             return -EIO;
> >> +
> >> +     for (i = 0; i < count; i++)
> >> +             buf[i] = readb(hdmi->base + SUN6I_HDMI_DDC_FIFO_DATA_REG);
> >> +
> >> +     return 0;
> >> +}
> >> +
> >> +static int sun6i_hdmi_read_edid_block(void *data, u8 *buf, unsigned int blk,
> >> +                                   size_t length)
> >> +{
> >> +     struct sun4i_hdmi *hdmi = data;
> >> +     int retry = 2, i;
> >> +
> >> +     do {
> >> +             for (i = 0; i < length; i += SUN4I_HDMI_DDC_FIFO_SIZE) {
> >> +                     unsigned char offset = blk * EDID_LENGTH + i;
> >> +                     unsigned int count = min((unsigned int)SUN4I_HDMI_DDC_FIFO_SIZE,
> >> +                                              length - i);
> >> +                     int ret;
> >> +
> >> +                     ret = sun6i_hdmi_read_sub_block(hdmi, blk, offset,
> >> +                                                     buf + i, count);
> >> +                     if (ret)
> >> +                             return ret;
> >> +             }
> >> +     } while (!drm_edid_block_valid(buf, blk, true, NULL) && (retry--));
> >> +
> >> +     return 0;
> >> +}
> >> +
> >> +static int sun6i_hdmi_get_modes(struct drm_connector *connector)
> >> +{
> >> +     struct sun4i_hdmi *hdmi = drm_connector_to_sun4i_hdmi(connector);
> >> +     u32 reg;
> >> +     struct edid *edid;
> >> +     int ret;
> >> +
> >> +     clk_set_rate(hdmi->ddc_clk, 100000);
> >> +     clk_prepare_enable(hdmi->ddc_clk);
> >> +
> >> +     /* Reset i2c controller */
> >> +     writel(SUN6I_HDMI_DDC_CTRL_ENABLE | SUN6I_HDMI_DDC_CTRL_RESET |
> >> +            SUN6I_HDMI_DDC_CTRL_SDA_ENABLE |
> >> +            SUN6I_HDMI_DDC_CTRL_SCL_ENABLE,
> >> +            hdmi->base + SUN6I_HDMI_DDC_CTRL_REG);
> >> +     if (readl_poll_timeout(hdmi->base + SUN6I_HDMI_DDC_CTRL_REG, reg,
> >> +                            !(reg & SUN6I_HDMI_DDC_CTRL_RESET),
> >> +                            100, 2000)) {
> >> +             dev_err(hdmi->dev, "DDC reset timeout: %08x\n", reg);
> >> +             clk_disable_unprepare(hdmi->ddc_clk);
> >> +             return -EIO;
> >> +     }
> >> +
> >> +     edid = drm_do_get_edid(connector, sun6i_hdmi_read_edid_block, hdmi);
> >> +
> >> +     clk_disable_unprepare(hdmi->ddc_clk);
> >> +
> >> +     if (!edid)
> >> +             return 0;
> >> +
> >> +     hdmi->hdmi_monitor = drm_detect_hdmi_monitor(edid);
> >> +     DRM_DEBUG_DRIVER("Monitor is %s monitor\n",
> >> +                      hdmi->hdmi_monitor ? "an HDMI" : "a DVI");
> >> +
> >> +     drm_mode_connector_update_edid_property(connector, edid);
> >> +     ret = drm_add_edid_modes(connector, edid);
> >> +     kfree(edid);
> >> +
> >> +     return ret;
> >> +}
> >> +
> >> +static const struct drm_connector_helper_funcs sun6i_hdmi_connector_helper_funcs = {
> >> +     .get_modes      = sun6i_hdmi_get_modes,
> >> +};
> >> +
> >
> > Every thing here can be handled through regfield without having to
> > duplicate the logic.
> 
> Hmm... You're right. Does that mean we should convert the entire driver to
> using regmap? Or just the DDC bits here, since they won't conflict with
> any other access patterns in the whole HDMI driver?

I guess we could just convert everything (and I wish I would have done
it before...)

> >>  static enum drm_connector_status
> >>  sun4i_hdmi_connector_detect(struct drm_connector *connector, bool force)
> >>  {
> >> @@ -367,6 +470,43 @@ static const struct sun4i_hdmi_variant sun5i_variant = {
> >>                                 SUN4I_HDMI_PLL_CTRL_PLL_EN,
> >>  };
> >>
> >> +static const struct sun4i_hdmi_variant sun6i_variant = {
> >> +     .connector_helpers      = &sun6i_hdmi_connector_helper_funcs,
> >> +     .ddc_create             = sun6i_ddc_create,
> >> +     .tmds_create            = sun6i_tmds_create,
> >> +     .has_ddc_parent_clk     = true,
> >> +     .has_reset_control      = true,
> >> +     .pad_ctrl0_init_val     = 0xff |
> >
> > What is this 0xff for?
> 
> Unknown. It is set in the mainline U-boot driver.
> 
> Looking at an old 3.3 kernel from the BSP, it seems the higher 4 bits
> control the transmitter. But the lower 4 bits are still unknown.

Can you add a comment for that?

Maxime

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

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

* Re: [PATCH 19/19] ARM: sun6i: a31s: Enable HDMI display output on the MSI Primo81 tablet
       [not found]         ` <20170602194219.hiajr7dt2oikm52q-ZC1Zs529Oq4@public.gmane.org>
  2017-06-03 15:31           ` Chen-Yu Tsai
@ 2017-06-07 22:36           ` Rob Herring
  2017-06-07 22:47             ` Ilia Mirkin
  1 sibling, 1 reply; 38+ messages in thread
From: Rob Herring @ 2017-06-07 22:36 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Chen-Yu Tsai, David Airlie, Michael Turquette, Stephen Boyd,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

On Fri, Jun 02, 2017 at 09:42:19PM +0200, Maxime Ripard wrote:
> On Fri, Jun 02, 2017 at 06:10:24PM +0800, Chen-Yu Tsai wrote:
> > The MSI Primo81 tablet has a micro HDMI connector at the bottom.
> > This is connected to the SoCs HDMI output.
> > 
> > Enable the display pipeline and the HDMI output.
> > 
> > Signed-off-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
> > ---
> >  arch/arm/boot/dts/sun6i-a31s-primo81.dts | 25 +++++++++++++++++++++++++
> >  1 file changed, 25 insertions(+)
> > 
> > diff --git a/arch/arm/boot/dts/sun6i-a31s-primo81.dts b/arch/arm/boot/dts/sun6i-a31s-primo81.dts
> > index f3712753fa42..26154b2f87a3 100644
> > --- a/arch/arm/boot/dts/sun6i-a31s-primo81.dts
> > +++ b/arch/arm/boot/dts/sun6i-a31s-primo81.dts
> > @@ -52,17 +52,42 @@
> >  / {
> >  	model = "MSI Primo81 tablet";
> >  	compatible = "msi,primo81", "allwinner,sun6i-a31s";
> > +
> > +	hdmi-connector {
> > +		compatible = "hdmi-connector";
> > +		type = "c";
> 
> Should we add a connector type for this one?

c as in USB Type C? I'd prefer to see a new compatible string. Is type 
even documented?

Rob

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

* Re: [PATCH 06/19] dt-bindings: display: sun4i: Add binding for A31 HDMI controller
       [not found]     ` <20170602101024.18940-7-wens-jdAy2FN1RRM@public.gmane.org>
@ 2017-06-07 22:37       ` Rob Herring
  0 siblings, 0 replies; 38+ messages in thread
From: Rob Herring @ 2017-06-07 22:37 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Maxime Ripard, David Airlie, Michael Turquette, Stephen Boyd,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

On Fri, Jun 02, 2017 at 06:10:11PM +0800, Chen-Yu Tsai wrote:
> The HDMI controller in the A31 SoC is slightly different from the
> earlier version. In addition to the TMDS clock and DDC controls,
> this version now takes a second DDC clock input.
> 
> Add a compatible string for it, and add the DDC clock input to the
> list of clocks required.
> 
> Signed-off-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
> ---
>  Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt | 3 +++
>  1 file changed, 3 insertions(+)

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

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

* Re: [PATCH 19/19] ARM: sun6i: a31s: Enable HDMI display output on the MSI Primo81 tablet
  2017-06-07 22:36           ` Rob Herring
@ 2017-06-07 22:47             ` Ilia Mirkin
       [not found]               ` <CAKb7UvgKhgCpeNzUX1ecFPuF6j+KvAWW3vprZ9nnVMBBJFi_zQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 38+ messages in thread
From: Ilia Mirkin @ 2017-06-07 22:47 UTC (permalink / raw)
  To: Rob Herring
  Cc: Maxime Ripard, devicetree, Michael Turquette, Stephen Boyd,
	linux-sunxi, dri-devel, Chen-Yu Tsai, linux-clk,
	linux-arm-kernel

On Wed, Jun 7, 2017 at 6:36 PM, Rob Herring <robh@kernel.org> wrote:
> On Fri, Jun 02, 2017 at 09:42:19PM +0200, Maxime Ripard wrote:
>> On Fri, Jun 02, 2017 at 06:10:24PM +0800, Chen-Yu Tsai wrote:
>> > The MSI Primo81 tablet has a micro HDMI connector at the bottom.
>> > This is connected to the SoCs HDMI output.
>> >
>> > Enable the display pipeline and the HDMI output.
>> >
>> > Signed-off-by: Chen-Yu Tsai <wens@csie.org>
>> > ---
>> >  arch/arm/boot/dts/sun6i-a31s-primo81.dts | 25 +++++++++++++++++++++++++
>> >  1 file changed, 25 insertions(+)
>> >
>> > diff --git a/arch/arm/boot/dts/sun6i-a31s-primo81.dts b/arch/arm/boot/dts/sun6i-a31s-primo81.dts
>> > index f3712753fa42..26154b2f87a3 100644
>> > --- a/arch/arm/boot/dts/sun6i-a31s-primo81.dts
>> > +++ b/arch/arm/boot/dts/sun6i-a31s-primo81.dts
>> > @@ -52,17 +52,42 @@
>> >  / {
>> >     model = "MSI Primo81 tablet";
>> >     compatible = "msi,primo81", "allwinner,sun6i-a31s";
>> > +
>> > +   hdmi-connector {
>> > +           compatible = "hdmi-connector";
>> > +           type = "c";
>>
>> Should we add a connector type for this one?
>
> c as in USB Type C? I'd prefer to see a new compatible string. Is type
> even documented?

Probably as in HDMI Type C (there are Type A, C, and D connectors, aka
"regular", "mini", and "micro").

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

* Re: [PATCH 19/19] ARM: sun6i: a31s: Enable HDMI display output on the MSI Primo81 tablet
       [not found]               ` <CAKb7UvgKhgCpeNzUX1ecFPuF6j+KvAWW3vprZ9nnVMBBJFi_zQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2017-06-09 16:08                 ` Chen-Yu Tsai
  2017-06-09 16:49                   ` Rob Herring
  0 siblings, 1 reply; 38+ messages in thread
From: Chen-Yu Tsai @ 2017-06-09 16:08 UTC (permalink / raw)
  To: Rob Herring
  Cc: Ilia Mirkin, Maxime Ripard, devicetree, Michael Turquette,
	Stephen Boyd, linux-sunxi,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Chen-Yu Tsai,
	linux-clk, linux-arm-kernel

On Thu, Jun 8, 2017 at 6:47 AM, Ilia Mirkin <imirkin-FrUbXkNCsVf2fBVCVOL8/A@public.gmane.org> wrote:
> On Wed, Jun 7, 2017 at 6:36 PM, Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
>> On Fri, Jun 02, 2017 at 09:42:19PM +0200, Maxime Ripard wrote:
>>> On Fri, Jun 02, 2017 at 06:10:24PM +0800, Chen-Yu Tsai wrote:
>>> > The MSI Primo81 tablet has a micro HDMI connector at the bottom.
>>> > This is connected to the SoCs HDMI output.
>>> >
>>> > Enable the display pipeline and the HDMI output.
>>> >
>>> > Signed-off-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
>>> > ---
>>> >  arch/arm/boot/dts/sun6i-a31s-primo81.dts | 25 +++++++++++++++++++++++++
>>> >  1 file changed, 25 insertions(+)
>>> >
>>> > diff --git a/arch/arm/boot/dts/sun6i-a31s-primo81.dts b/arch/arm/boot/dts/sun6i-a31s-primo81.dts
>>> > index f3712753fa42..26154b2f87a3 100644
>>> > --- a/arch/arm/boot/dts/sun6i-a31s-primo81.dts
>>> > +++ b/arch/arm/boot/dts/sun6i-a31s-primo81.dts
>>> > @@ -52,17 +52,42 @@
>>> >  / {
>>> >     model = "MSI Primo81 tablet";
>>> >     compatible = "msi,primo81", "allwinner,sun6i-a31s";
>>> > +
>>> > +   hdmi-connector {
>>> > +           compatible = "hdmi-connector";
>>> > +           type = "c";
>>>
>>> Should we add a connector type for this one?
>>
>> c as in USB Type C? I'd prefer to see a new compatible string. Is type
>> even documented?

Indeed it is:

http://elixir.free-electrons.com/linux/latest/source/Documentation/devicetree/bindings/display/connector/hdmi-connector.txt#L6

> Probably as in HDMI Type C (there are Type A, C, and D connectors, aka
> "regular", "mini", and "micro").

Correct.

ChenYu

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

* Re: [PATCH 19/19] ARM: sun6i: a31s: Enable HDMI display output on the MSI Primo81 tablet
  2017-06-09 16:08                 ` Chen-Yu Tsai
@ 2017-06-09 16:49                   ` Rob Herring
  0 siblings, 0 replies; 38+ messages in thread
From: Rob Herring @ 2017-06-09 16:49 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: devicetree, Michael Turquette, Stephen Boyd, dri-devel,
	linux-sunxi, linux-arm-kernel, Maxime Ripard, linux-clk

On Fri, Jun 9, 2017 at 11:08 AM, Chen-Yu Tsai <wens@csie.org> wrote:
> On Thu, Jun 8, 2017 at 6:47 AM, Ilia Mirkin <imirkin@alum.mit.edu> wrote:
>> On Wed, Jun 7, 2017 at 6:36 PM, Rob Herring <robh@kernel.org> wrote:
>>> On Fri, Jun 02, 2017 at 09:42:19PM +0200, Maxime Ripard wrote:
>>>> On Fri, Jun 02, 2017 at 06:10:24PM +0800, Chen-Yu Tsai wrote:
>>>> > The MSI Primo81 tablet has a micro HDMI connector at the bottom.
>>>> > This is connected to the SoCs HDMI output.
>>>> >
>>>> > Enable the display pipeline and the HDMI output.
>>>> >
>>>> > Signed-off-by: Chen-Yu Tsai <wens@csie.org>
>>>> > ---
>>>> >  arch/arm/boot/dts/sun6i-a31s-primo81.dts | 25 +++++++++++++++++++++++++
>>>> >  1 file changed, 25 insertions(+)
>>>> >
>>>> > diff --git a/arch/arm/boot/dts/sun6i-a31s-primo81.dts b/arch/arm/boot/dts/sun6i-a31s-primo81.dts
>>>> > index f3712753fa42..26154b2f87a3 100644
>>>> > --- a/arch/arm/boot/dts/sun6i-a31s-primo81.dts
>>>> > +++ b/arch/arm/boot/dts/sun6i-a31s-primo81.dts
>>>> > @@ -52,17 +52,42 @@
>>>> >  / {
>>>> >     model = "MSI Primo81 tablet";
>>>> >     compatible = "msi,primo81", "allwinner,sun6i-a31s";
>>>> > +
>>>> > +   hdmi-connector {
>>>> > +           compatible = "hdmi-connector";
>>>> > +           type = "c";
>>>>
>>>> Should we add a connector type for this one?
>>>
>>> c as in USB Type C? I'd prefer to see a new compatible string. Is type
>>> even documented?
>
> Indeed it is:
>
> http://elixir.free-electrons.com/linux/latest/source/Documentation/devicetree/bindings/display/connector/hdmi-connector.txt#L6

-ETOOMANYBINDINGS

I guess I don't understand the original question then. This looks fine to me.

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

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

* Re: [PATCH 10/19] drm/sun4i: hdmi: Rename internal DDC clock to avoid name collision
       [not found]             ` <20170605140012.rlx7rm7xhriwqaza-ZC1Zs529Oq4@public.gmane.org>
@ 2017-06-23  9:37               ` Chen-Yu Tsai
  0 siblings, 0 replies; 38+ messages in thread
From: Chen-Yu Tsai @ 2017-06-23  9:37 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Chen-Yu Tsai, David Airlie, Rob Herring, Michael Turquette,
	Stephen Boyd, dri-devel, linux-arm-kernel, devicetree, linux-clk,
	linux-sunxi

On Mon, Jun 5, 2017 at 10:00 PM, Maxime Ripard
<maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org> wrote:
> On Sat, Jun 03, 2017 at 10:33:25PM +0800, Chen-Yu Tsai wrote:
>> On Sat, Jun 3, 2017 at 3:30 AM, Maxime Ripard
>> <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org> wrote:
>> > On Fri, Jun 02, 2017 at 06:10:15PM +0800, Chen-Yu Tsai wrote:
>> >> The DDC parent clock on the A31 SoC is also conveniently named
>> >> "hdmi-ddc", which results in a name collision when the hdmi driver
>> >> registers its internal DDC divider clock.
>> >>
>> >> Rename the internal clock to "hdmi-ddc-divider".
>> >>
>> >> Signed-off-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
>> >> ---
>> >>  drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c | 2 +-
>> >>  1 file changed, 1 insertion(+), 1 deletion(-)
>> >>
>> >> diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c
>> >> index e1071838f487..9a6b6243e977 100644
>> >> --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c
>> >> +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c
>> >> @@ -125,7 +125,7 @@ static int _sun4i_ddc_create(struct sun4i_hdmi *hdmi, struct clk *parent,
>> >>       if (!ddc)
>> >>               return -ENOMEM;
>> >>
>> >> -     init.name = "hdmi-ddc";
>> >> +     init.name = "hdmi-ddc-divider";
>> >
>> > Can't we rename the CCU clock instead? Having the clock called
>> > hdmi-ddc being the actual clock output on the DDC bus feels more
>> > natural.
>>
>> Do you have any suggestions? The manual labels the conflicting one
>> in the CCU as "HDMI_DDC"...
>
> DDC as the main CCU clock, and hdmi-ddc as the one actually generated
> by the HDMI controller?

I think I'll just name it hdmi-ddc-parent. Who knows if some other module
comes in and has a clock named ddc.

ChenYu

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

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

Thread overview: 38+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-06-02 10:10 [PATCH 00/19] drm/sun4i: hdmi: Support HDMI controller on A31 Chen-Yu Tsai
2017-06-02 10:10 ` [PATCH 02/19] drm/sun4i: add components in two passes with encoders added in second pass Chen-Yu Tsai
2017-06-02 19:18   ` Maxime Ripard
2017-06-02 10:10 ` [PATCH 07/19] drm/sun4i: hdmi: Support different variants of the TMDS clock Chen-Yu Tsai
     [not found] ` <20170602101024.18940-1-wens-jdAy2FN1RRM@public.gmane.org>
2017-06-02 10:10   ` [PATCH 01/19] drm/sun4i: call drm_vblank_init with correct number of crtcs Chen-Yu Tsai
2017-06-02 10:10   ` [PATCH 03/19] drm/sun4i: tcon: Add support for demuxing TCON output on A31 Chen-Yu Tsai
2017-06-02 10:10   ` [PATCH 04/19] drm/sun4i: hdmi: Disable clks in bind function error path and unbind function Chen-Yu Tsai
2017-06-02 10:10   ` [PATCH 05/19] drm/sun4i: hdmi: Allow using second PLL as TMDS clk parent Chen-Yu Tsai
2017-06-02 10:10   ` [PATCH 06/19] dt-bindings: display: sun4i: Add binding for A31 HDMI controller Chen-Yu Tsai
     [not found]     ` <20170602101024.18940-7-wens-jdAy2FN1RRM@public.gmane.org>
2017-06-07 22:37       ` Rob Herring
2017-06-02 10:10   ` [PATCH 08/19] drm/sun4i: hdmi: Support the TMDS clock in the A31's " Chen-Yu Tsai
2017-06-02 10:10   ` [PATCH 09/19] drm/sun4i: hdmi: Support different variants of the DDC clock Chen-Yu Tsai
2017-06-02 10:10   ` [PATCH 10/19] drm/sun4i: hdmi: Rename internal DDC clock to avoid name collision Chen-Yu Tsai
2017-06-02 19:30     ` Maxime Ripard
2017-06-03 14:33       ` Chen-Yu Tsai
     [not found]         ` <CAGb2v64Vgdjm1MAwn+L0PVc0CA0QOCn=0RONKoGDWLpzVBzvmQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-06-05 14:00           ` Maxime Ripard
     [not found]             ` <20170605140012.rlx7rm7xhriwqaza-ZC1Zs529Oq4@public.gmane.org>
2017-06-23  9:37               ` Chen-Yu Tsai
2017-06-02 10:10   ` [PATCH 11/19] drm/sun4i: hdmi: Add A31 specific DDC register definitions Chen-Yu Tsai
2017-06-02 10:10   ` [PATCH 12/19] drm/sun4i: hdmi: Support the DDC clock in the A31's HDMI controller Chen-Yu Tsai
     [not found]     ` <20170602101024.18940-13-wens-jdAy2FN1RRM@public.gmane.org>
2017-06-02 19:31       ` Maxime Ripard
2017-06-02 10:10   ` [PATCH 13/19] drm/sun4i: hdmi: Add support for controller hardware variants Chen-Yu Tsai
2017-06-02 19:38     ` Maxime Ripard
     [not found]       ` <20170602193827.rnjum6x5ra4x5wef-ZC1Zs529Oq4@public.gmane.org>
2017-06-03 14:58         ` Chen-Yu Tsai
2017-06-02 10:10   ` [PATCH 14/19] drm/sun4i: hdmi: Add support for A31's HDMI controller Chen-Yu Tsai
2017-06-02 19:41     ` Maxime Ripard
2017-06-03 15:19       ` Chen-Yu Tsai
     [not found]         ` <CAGb2v65eFAmAybmHkQcKjF+ZKxh+_G6q9i2GPzMs5854X8bQug-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-06-06 19:27           ` Maxime Ripard
2017-06-02 10:10   ` [PATCH 15/19] clk: sunxi-ng: sun6i: Export video PLLs Chen-Yu Tsai
2017-06-02 10:10   ` [PATCH 16/19] ARM: sun6i: a31: Add device node for HDMI controller Chen-Yu Tsai
2017-06-02 10:10   ` [PATCH 17/19] ARM: sun6i: a31: Enable HDMI support on the A31 Hummingbird Chen-Yu Tsai
2017-06-02 10:10   ` [PATCH 18/19] ARM: sun6i: a31s: Enable HDMI display output on the Sinlinx SinA31s Chen-Yu Tsai
2017-06-02 10:10   ` [PATCH 19/19] ARM: sun6i: a31s: Enable HDMI display output on the MSI Primo81 tablet Chen-Yu Tsai
     [not found]     ` <20170602101024.18940-20-wens-jdAy2FN1RRM@public.gmane.org>
2017-06-02 19:42       ` Maxime Ripard
     [not found]         ` <20170602194219.hiajr7dt2oikm52q-ZC1Zs529Oq4@public.gmane.org>
2017-06-03 15:31           ` Chen-Yu Tsai
2017-06-07 22:36           ` Rob Herring
2017-06-07 22:47             ` Ilia Mirkin
     [not found]               ` <CAKb7UvgKhgCpeNzUX1ecFPuF6j+KvAWW3vprZ9nnVMBBJFi_zQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-06-09 16:08                 ` Chen-Yu Tsai
2017-06-09 16:49                   ` Rob Herring

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