Linux-Clk Archive on lore.kernel.org
 help / Atom feed
* [PATCH v3 00/28] Allwinner H6 DE3 and HDMI support
@ 2018-11-04 18:26 Jernej Skrabec
  2018-11-04 18:26 ` [PATCH v3 01/28] dt-bindings: bus: add H6 DE3 bus binding Jernej Skrabec
                   ` (28 more replies)
  0 siblings, 29 replies; 41+ messages in thread
From: Jernej Skrabec @ 2018-11-04 18:26 UTC (permalink / raw)
  To: maxime.ripard, wens
  Cc: robh+dt, mturquette, sboyd, airlied, architt, a.hajda,
	Laurent.pinchart, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi, jernej.skrabec

This series adds support for Display Engine 3.0 and HDMI 2.0a, which
can be found on H6 SoC.

Display Engine 3.0 in comparison to 2.0 mostly adds features needed for
displaying and processing 10-bit and AFBC formats, which are not yet
supported by this series.

H6 is also the first SoC which supports IOMMU, but support for it is
not yet added.

This series is based on linux-next at next-20181102.

I suggest all patches go through allwinner tree, except DRM patches,
which should go through drm-misc tree.

Last detail, PineH64 model A schematic has DDC_EN signal, which enables
DDC voltage level shifter. TL Lim, PINE64 founder, said that this
signal is not actually present on PineH64 model A board. It is, however
present on PineH64 model B engineering samples, but it will be removed
in production version. Because of that, I didn't include any code for
it.

Please take a look.

Best regards,
Jernej

Changes from v2:
- Collected tags
- Removed patch which renames all DE2 macros
- Converted bool struct members in header files to unsigned int bitfield.
  This issue was reported by checkpatch.pl --strict.
- Fixed code style in tcon top driver and removed unnecessary initialization
- Moved set_rate quirk check in dw-hdmi driver to more appropriate place
- Fixed compatible for H6 DE3 bus compatible

Changes from v1:
- Collected tags
- Reworked some commit messages and titles
- Remove two patches which were already merged
- Added new patches (10, 11, 12, 21)
- Lowered max. supported HDMI pixel clock to 594 MHz
- Reordered compatibles and quirks by family name
- Fixed kbuild test robot warnings
- renamed CLK_NUMBER to CLK_NUMBER_WITHOUT_ROT and introduced
  CLK_NUMBER_WITH_ROT
- removed "inline" from functions in c file
- used regmap_bulk_write() for writing DE3 CSC table
- DE3 specific macros have "DE3_" prefix now
- reworked DE2/3 mixer registers initialization
- removed writing to edge detection registers because
  functionality is not used

Icenowy Zheng (5):
  dt-bindings: bus: add H6 DE3 bus binding
  dt-bindings: display: sunxi: add DT binding for Allwinner H6 DW HDMI
  drm: sun4i: add quirks for TCON TOP
  dt-bindings: display: sun4i-drm: document H6 TCON TOP
  drm: sun4i: add support for H6 TCON TOP

Jernej Skrabec (23):
  clk: sunxi-ng: Adjust MP clock parent rate when allowed
  clk: sunxi-ng: Use u64 for calculation of NM rate
  clk: sunxi-ng: h6: Set video PLLs limits
  dt-bindings: clock: sun8i-de2: Add H6 DE3 clock description
  clk: sunxi-ng: Add support for H6 DE3 clocks
  dt-bindings: display: sun4i-drm: Add H6 display engine compatibles
  drm/sun4i: Add compatible for H6 display engine
  drm/sun4i: Rework DE2 register defines
  drm/sun4i: Fix DE2 mixer size
  drm/sun4i: Disable unused DE2 sub-engines
  drm/sun4i: Add basic support for DE3
  drm/sun4i: Add support for H6 DE3 mixer 0
  drm/bridge/synopsys: dw-hdmi: Enable workaround for v2.12a
  drm/sun4i: Not all DW HDMI controllers has scrambled addresses
  drm/sun4i: dw-hdmi: Make mode_valid function configurable
  drm/sun4i: dw-hdmi: Add quirk for setting TMDS clock
  drm/sun4i: Add support for H6 DW HDMI controller
  drm/sun4i: dw-hdmi-phy: Reorder quirks by family
  drm/sun4i: Add support for Synopsys HDMI PHY
  drm/sun4i: Add support for H6 HDMI PHY
  drm/sun4i: Initialize registers in tcon-top driver
  arm64: dts: allwinner: h6: Add HDMI pipeline
  arm64: dts: allwinner: h6: Enable HDMI output on Pine H64 board

 .../bindings/bus/sun50i-de2-bus.txt           |   9 +-
 .../devicetree/bindings/clock/sun8i-de2.txt   |   5 +-
 .../bindings/display/sunxi/sun4i-drm.txt      |  30 ++-
 .../boot/dts/allwinner/sun50i-h6-pine-h64.dts |  25 +++
 arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi  | 201 ++++++++++++++++++
 drivers/clk/sunxi-ng/ccu-sun50i-h6.c          |   4 +
 drivers/clk/sunxi-ng/ccu-sun8i-de2.c          |  71 ++++++-
 drivers/clk/sunxi-ng/ccu-sun8i-de2.h          |   4 +-
 drivers/clk/sunxi-ng/ccu_mp.c                 |  64 +++++-
 drivers/clk/sunxi-ng/ccu_nm.c                 |  18 +-
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c     |   1 +
 drivers/gpu/drm/sun4i/sun4i_drv.c             |   1 +
 drivers/gpu/drm/sun4i/sun8i_csc.c             |  83 ++++++++
 drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c         |  45 +++-
 drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h         |  14 +-
 drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c        | 201 ++++++++++++++++--
 drivers/gpu/drm/sun4i/sun8i_mixer.c           |  57 ++++-
 drivers/gpu/drm/sun4i/sun8i_mixer.h           |  80 +++++--
 drivers/gpu/drm/sun4i/sun8i_tcon_top.c        |  52 ++++-
 drivers/gpu/drm/sun4i/sun8i_ui_layer.c        |  47 ++--
 drivers/gpu/drm/sun4i/sun8i_ui_layer.h        |  37 ++--
 drivers/gpu/drm/sun4i/sun8i_ui_scaler.c       |  47 ++--
 drivers/gpu/drm/sun4i/sun8i_ui_scaler.h       |  28 +--
 drivers/gpu/drm/sun4i/sun8i_vi_layer.c        |  55 +++--
 drivers/gpu/drm/sun4i/sun8i_vi_layer.h        |  25 ++-
 drivers/gpu/drm/sun4i/sun8i_vi_scaler.c       |  70 ++++--
 drivers/gpu/drm/sun4i/sun8i_vi_scaler.h       |  68 +++---
 include/dt-bindings/clock/sun8i-de2.h         |   3 +
 include/dt-bindings/reset/sun8i-de2.h         |   1 +
 29 files changed, 1120 insertions(+), 226 deletions(-)

-- 
2.19.1


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

* [PATCH v3 01/28] dt-bindings: bus: add H6 DE3 bus binding
  2018-11-04 18:26 [PATCH v3 00/28] Allwinner H6 DE3 and HDMI support Jernej Skrabec
@ 2018-11-04 18:26 ` Jernej Skrabec
  2018-11-04 18:26 ` [PATCH v3 02/28] clk: sunxi-ng: Adjust MP clock parent rate when allowed Jernej Skrabec
                   ` (27 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Jernej Skrabec @ 2018-11-04 18:26 UTC (permalink / raw)
  To: maxime.ripard, wens
  Cc: robh+dt, mturquette, sboyd, airlied, architt, a.hajda,
	Laurent.pinchart, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi, jernej.skrabec, Icenowy Zheng

From: Icenowy Zheng <icenowy@aosc.io>

The Allwinner H6 DE3 bus is similar to the A64 DE2 one.

Add its compatible string with the A64 string as fallback to the
binding.

Some description of the binding is modified to make it more generic.

Reviewed-by: Rob Herring <robh@kernel.org>
Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
[Fixed compatible name]
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 Documentation/devicetree/bindings/bus/sun50i-de2-bus.txt | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/bus/sun50i-de2-bus.txt b/Documentation/devicetree/bindings/bus/sun50i-de2-bus.txt
index 87dfb33fb3be..b9d533717dff 100644
--- a/Documentation/devicetree/bindings/bus/sun50i-de2-bus.txt
+++ b/Documentation/devicetree/bindings/bus/sun50i-de2-bus.txt
@@ -1,11 +1,14 @@
-Device tree bindings for Allwinner A64 DE2 bus
+Device tree bindings for Allwinner DE2/3 bus
 
 The Allwinner A64 DE2 is on a special bus, which needs a SRAM region (SRAM C)
-to be claimed for enabling the access.
+to be claimed for enabling the access. The DE3 on Allwinner H6 is at the same
+situation, and the binding also applies.
 
 Required properties:
 
- - compatible:		Should contain "allwinner,sun50i-a64-de2"
+ - compatible:		Should be one of:
+				- "allwinner,sun50i-a64-de2"
+				- "allwinner,sun50i-h6-de3", "allwinner,sun50i-a64-de2"
  - reg:			A resource specifier for the register space
  - #address-cells:	Must be set to 1
  - #size-cells:		Must be set to 1
-- 
2.19.1


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

* [PATCH v3 02/28] clk: sunxi-ng: Adjust MP clock parent rate when allowed
  2018-11-04 18:26 [PATCH v3 00/28] Allwinner H6 DE3 and HDMI support Jernej Skrabec
  2018-11-04 18:26 ` [PATCH v3 01/28] dt-bindings: bus: add H6 DE3 bus binding Jernej Skrabec
@ 2018-11-04 18:26 ` Jernej Skrabec
  2019-01-10  9:15   ` [linux-sunxi] " Priit Laes
  2018-11-04 18:26 ` [PATCH v3 03/28] clk: sunxi-ng: Use u64 for calculation of NM rate Jernej Skrabec
                   ` (26 subsequent siblings)
  28 siblings, 1 reply; 41+ messages in thread
From: Jernej Skrabec @ 2018-11-04 18:26 UTC (permalink / raw)
  To: maxime.ripard, wens
  Cc: robh+dt, mturquette, sboyd, airlied, architt, a.hajda,
	Laurent.pinchart, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi, jernej.skrabec

Currently MP clocks don't consider adjusting parent rate even if they
are allowed to do so. Such behaviour considerably lowers amount of
possible rates, which is very inconvenient when such clock is used for
pixel clock, for example.

In order to improve the situation, adjusting parent rate is considered
when allowed.

This code is inspired by clk_divider_bestdiv() function, which does
basically the same thing for different clock type.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/clk/sunxi-ng/ccu_mp.c | 64 +++++++++++++++++++++++++++++++++--
 1 file changed, 62 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/sunxi-ng/ccu_mp.c b/drivers/clk/sunxi-ng/ccu_mp.c
index 5d0af4051737..0357349eb767 100644
--- a/drivers/clk/sunxi-ng/ccu_mp.c
+++ b/drivers/clk/sunxi-ng/ccu_mp.c
@@ -40,6 +40,61 @@ static void ccu_mp_find_best(unsigned long parent, unsigned long rate,
 	*p = best_p;
 }
 
+static unsigned long ccu_mp_find_best_with_parent_adj(struct clk_hw *hw,
+						      unsigned long *parent,
+						      unsigned long rate,
+						      unsigned int max_m,
+						      unsigned int max_p)
+{
+	unsigned long parent_rate_saved;
+	unsigned long parent_rate, now;
+	unsigned long best_rate = 0;
+	unsigned int _m, _p, div;
+	unsigned long maxdiv;
+
+	parent_rate_saved = *parent;
+
+	/*
+	 * The maximum divider we can use without overflowing
+	 * unsigned long in rate * m * p below
+	 */
+	maxdiv = max_m * max_p;
+	maxdiv = min(ULONG_MAX / rate, maxdiv);
+
+	for (_p = 1; _p <= max_p; _p <<= 1) {
+		for (_m = 1; _m <= max_m; _m++) {
+			div = _m * _p;
+
+			if (div > maxdiv)
+				break;
+
+			if (rate * div == parent_rate_saved) {
+				/*
+				 * It's the most ideal case if the requested
+				 * rate can be divided from parent clock without
+				 * needing to change parent rate, so return the
+				 * divider immediately.
+				 */
+				*parent = parent_rate_saved;
+				return rate;
+			}
+
+			parent_rate = clk_hw_round_rate(hw, rate * div);
+			now = parent_rate / div;
+
+			if (now <= rate && now > best_rate) {
+				best_rate = now;
+				*parent = parent_rate;
+
+				if (now == rate)
+					return rate;
+			}
+		}
+	}
+
+	return best_rate;
+}
+
 static unsigned long ccu_mp_round_rate(struct ccu_mux_internal *mux,
 				       struct clk_hw *hw,
 				       unsigned long *parent_rate,
@@ -56,8 +111,13 @@ static unsigned long ccu_mp_round_rate(struct ccu_mux_internal *mux,
 	max_m = cmp->m.max ?: 1 << cmp->m.width;
 	max_p = cmp->p.max ?: 1 << ((1 << cmp->p.width) - 1);
 
-	ccu_mp_find_best(*parent_rate, rate, max_m, max_p, &m, &p);
-	rate = *parent_rate / p / m;
+	if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) {
+		ccu_mp_find_best(*parent_rate, rate, max_m, max_p, &m, &p);
+		rate = *parent_rate / p / m;
+	} else {
+		rate = ccu_mp_find_best_with_parent_adj(hw, parent_rate, rate,
+							max_m, max_p);
+	}
 
 	if (cmp->common.features & CCU_FEATURE_FIXED_POSTDIV)
 		rate /= cmp->fixed_post_div;
-- 
2.19.1


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

* [PATCH v3 03/28] clk: sunxi-ng: Use u64 for calculation of NM rate
  2018-11-04 18:26 [PATCH v3 00/28] Allwinner H6 DE3 and HDMI support Jernej Skrabec
  2018-11-04 18:26 ` [PATCH v3 01/28] dt-bindings: bus: add H6 DE3 bus binding Jernej Skrabec
  2018-11-04 18:26 ` [PATCH v3 02/28] clk: sunxi-ng: Adjust MP clock parent rate when allowed Jernej Skrabec
@ 2018-11-04 18:26 ` Jernej Skrabec
  2018-11-04 18:26 ` [PATCH v3 04/28] clk: sunxi-ng: h6: Set video PLLs limits Jernej Skrabec
                   ` (25 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Jernej Skrabec @ 2018-11-04 18:26 UTC (permalink / raw)
  To: maxime.ripard, wens
  Cc: robh+dt, mturquette, sboyd, airlied, architt, a.hajda,
	Laurent.pinchart, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi, jernej.skrabec, stable

Allwinner H6 SoC has multiplier N range between 1 and 254. Since parent
rate is 24MHz, intermediate result when calculating final rate easily
overflows 32 bit variable.

Because of that, introduce function for calculating clock rate which
uses 64 bit variable for intermediate result.

Fixes: 6174a1e24b0d ("clk: sunxi-ng: Add N-M-factor clock support")
Fixes: ee28648cb2b4 ("clk: sunxi-ng: Remove the use of rational computations")

CC: <stable@vger.kernel.org>
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/clk/sunxi-ng/ccu_nm.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/sunxi-ng/ccu_nm.c b/drivers/clk/sunxi-ng/ccu_nm.c
index 6fe3c14f7b2d..424d8635b053 100644
--- a/drivers/clk/sunxi-ng/ccu_nm.c
+++ b/drivers/clk/sunxi-ng/ccu_nm.c
@@ -19,6 +19,17 @@ struct _ccu_nm {
 	unsigned long	m, min_m, max_m;
 };
 
+static unsigned long ccu_nm_calc_rate(unsigned long parent,
+				      unsigned long n, unsigned long m)
+{
+	u64 rate = parent;
+
+	rate *= n;
+	do_div(rate, m);
+
+	return rate;
+}
+
 static void ccu_nm_find_best(unsigned long parent, unsigned long rate,
 			     struct _ccu_nm *nm)
 {
@@ -28,7 +39,8 @@ static void ccu_nm_find_best(unsigned long parent, unsigned long rate,
 
 	for (_n = nm->min_n; _n <= nm->max_n; _n++) {
 		for (_m = nm->min_m; _m <= nm->max_m; _m++) {
-			unsigned long tmp_rate = parent * _n  / _m;
+			unsigned long tmp_rate = ccu_nm_calc_rate(parent,
+								  _n, _m);
 
 			if (tmp_rate > rate)
 				continue;
@@ -100,7 +112,7 @@ static unsigned long ccu_nm_recalc_rate(struct clk_hw *hw,
 	if (ccu_sdm_helper_is_enabled(&nm->common, &nm->sdm))
 		rate = ccu_sdm_helper_read_rate(&nm->common, &nm->sdm, m, n);
 	else
-		rate = parent_rate * n / m;
+		rate = ccu_nm_calc_rate(parent_rate, n, m);
 
 	if (nm->common.features & CCU_FEATURE_FIXED_POSTDIV)
 		rate /= nm->fixed_post_div;
@@ -149,7 +161,7 @@ static long ccu_nm_round_rate(struct clk_hw *hw, unsigned long rate,
 	_nm.max_m = nm->m.max ?: 1 << nm->m.width;
 
 	ccu_nm_find_best(*parent_rate, rate, &_nm);
-	rate = *parent_rate * _nm.n / _nm.m;
+	rate = ccu_nm_calc_rate(*parent_rate, _nm.n, _nm.m);
 
 	if (nm->common.features & CCU_FEATURE_FIXED_POSTDIV)
 		rate /= nm->fixed_post_div;
-- 
2.19.1


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

* [PATCH v3 04/28] clk: sunxi-ng: h6: Set video PLLs limits
  2018-11-04 18:26 [PATCH v3 00/28] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (2 preceding siblings ...)
  2018-11-04 18:26 ` [PATCH v3 03/28] clk: sunxi-ng: Use u64 for calculation of NM rate Jernej Skrabec
@ 2018-11-04 18:26 ` Jernej Skrabec
  2018-11-04 18:26 ` [PATCH v3 05/28] dt-bindings: clock: sun8i-de2: Add H6 DE3 clock description Jernej Skrabec
                   ` (24 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Jernej Skrabec @ 2018-11-04 18:26 UTC (permalink / raw)
  To: maxime.ripard, wens
  Cc: robh+dt, mturquette, sboyd, airlied, architt, a.hajda,
	Laurent.pinchart, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi, jernej.skrabec

Video PLL factors can be set in a way that final PLL rate is outside
stable range. H6 user manual specifically says that N factor should not
be below 12. While it doesn't says anything about maximum stable rate, it
is clear that PLL doesn't work at 6.096 GHz (254 * 24 MHz).

Set minimum allowed PLL video rate to 288 MHz (12 * 24 MHz) and maximum
to 2.4 GHz, which is maximum in BSP driver.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/clk/sunxi-ng/ccu-sun50i-h6.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
index 2193e1495086..19ff09f610e4 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
@@ -120,6 +120,8 @@ static struct ccu_nm pll_video0_clk = {
 	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
 	.m		= _SUNXI_CCU_DIV(1, 1), /* input divider */
 	.fixed_post_div	= 4,
+	.min_rate	= 288000000,
+	.max_rate	= 2400000000UL,
 	.common		= {
 		.reg		= 0x040,
 		.features	= CCU_FEATURE_FIXED_POSTDIV,
@@ -136,6 +138,8 @@ static struct ccu_nm pll_video1_clk = {
 	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
 	.m		= _SUNXI_CCU_DIV(1, 1), /* input divider */
 	.fixed_post_div	= 4,
+	.min_rate	= 288000000,
+	.max_rate	= 2400000000UL,
 	.common		= {
 		.reg		= 0x048,
 		.features	= CCU_FEATURE_FIXED_POSTDIV,
-- 
2.19.1


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

* [PATCH v3 05/28] dt-bindings: clock: sun8i-de2: Add H6 DE3 clock description
  2018-11-04 18:26 [PATCH v3 00/28] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (3 preceding siblings ...)
  2018-11-04 18:26 ` [PATCH v3 04/28] clk: sunxi-ng: h6: Set video PLLs limits Jernej Skrabec
@ 2018-11-04 18:26 ` Jernej Skrabec
  2018-11-04 18:26 ` [PATCH v3 06/28] clk: sunxi-ng: Add support for H6 DE3 clocks Jernej Skrabec
                   ` (23 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Jernej Skrabec @ 2018-11-04 18:26 UTC (permalink / raw)
  To: maxime.ripard, wens
  Cc: robh+dt, mturquette, sboyd, airlied, architt, a.hajda,
	Laurent.pinchart, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi, jernej.skrabec

This commit adds necessary description and dt includes for H6 DE3 clock.
It is very similar to others, but memory region has some additional
registers not found in DE2.

Reviewed-by: Rob Herring <robh@kernel.org>
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 Documentation/devicetree/bindings/clock/sun8i-de2.txt | 5 +++--
 include/dt-bindings/clock/sun8i-de2.h                 | 3 +++
 include/dt-bindings/reset/sun8i-de2.h                 | 1 +
 3 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/clock/sun8i-de2.txt b/Documentation/devicetree/bindings/clock/sun8i-de2.txt
index e94582e8b8a9..41a52c2acffd 100644
--- a/Documentation/devicetree/bindings/clock/sun8i-de2.txt
+++ b/Documentation/devicetree/bindings/clock/sun8i-de2.txt
@@ -1,5 +1,5 @@
-Allwinner Display Engine 2.0 Clock Control Binding
---------------------------------------------------
+Allwinner Display Engine 2.0/3.0 Clock Control Binding
+------------------------------------------------------
 
 Required properties :
 - compatible: must contain one of the following compatibles:
@@ -8,6 +8,7 @@ Required properties :
 		- "allwinner,sun8i-v3s-de2-clk"
 		- "allwinner,sun50i-a64-de2-clk"
 		- "allwinner,sun50i-h5-de2-clk"
+		- "allwinner,sun50i-h6-de3-clk"
 
 - reg: Must contain the registers base address and length
 - clocks: phandle to the clocks feeding the display engine subsystem.
diff --git a/include/dt-bindings/clock/sun8i-de2.h b/include/dt-bindings/clock/sun8i-de2.h
index 3bed63b524aa..7768f73b051e 100644
--- a/include/dt-bindings/clock/sun8i-de2.h
+++ b/include/dt-bindings/clock/sun8i-de2.h
@@ -15,4 +15,7 @@
 #define CLK_MIXER1		7
 #define CLK_WB			8
 
+#define CLK_BUS_ROT		9
+#define CLK_ROT			10
+
 #endif /* _DT_BINDINGS_CLOCK_SUN8I_DE2_H_ */
diff --git a/include/dt-bindings/reset/sun8i-de2.h b/include/dt-bindings/reset/sun8i-de2.h
index 9526017432f0..1c36a6ac86d6 100644
--- a/include/dt-bindings/reset/sun8i-de2.h
+++ b/include/dt-bindings/reset/sun8i-de2.h
@@ -10,5 +10,6 @@
 #define RST_MIXER0	0
 #define RST_MIXER1	1
 #define RST_WB		2
+#define RST_ROT		3
 
 #endif /* _DT_BINDINGS_RESET_SUN8I_DE2_H_ */
-- 
2.19.1


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

* [PATCH v3 06/28] clk: sunxi-ng: Add support for H6 DE3 clocks
  2018-11-04 18:26 [PATCH v3 00/28] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (4 preceding siblings ...)
  2018-11-04 18:26 ` [PATCH v3 05/28] dt-bindings: clock: sun8i-de2: Add H6 DE3 clock description Jernej Skrabec
@ 2018-11-04 18:26 ` Jernej Skrabec
  2018-11-04 18:26 ` [PATCH v3 07/28] dt-bindings: display: sun4i-drm: Add H6 display engine compatibles Jernej Skrabec
                   ` (22 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Jernej Skrabec @ 2018-11-04 18:26 UTC (permalink / raw)
  To: maxime.ripard, wens
  Cc: robh+dt, mturquette, sboyd, airlied, architt, a.hajda,
	Laurent.pinchart, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi, jernej.skrabec, Icenowy Zheng

Support for mixer0, mixer1, writeback and rotation units is added.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
---
 drivers/clk/sunxi-ng/ccu-sun8i-de2.c | 71 ++++++++++++++++++++++++++--
 drivers/clk/sunxi-ng/ccu-sun8i-de2.h |  4 +-
 2 files changed, 71 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-de2.c b/drivers/clk/sunxi-ng/ccu-sun8i-de2.c
index bae5ee67a797..1c9ae0a319c1 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-de2.c
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-de2.c
@@ -31,6 +31,8 @@ static SUNXI_CCU_GATE(bus_mixer1_clk,	"bus-mixer1",	"bus-de",
 		      0x04, BIT(1), 0);
 static SUNXI_CCU_GATE(bus_wb_clk,	"bus-wb",	"bus-de",
 		      0x04, BIT(2), 0);
+static SUNXI_CCU_GATE(bus_rot_clk,	"bus-rot",	"bus-de",
+		      0x04, BIT(3), 0);
 
 static SUNXI_CCU_GATE(mixer0_clk,	"mixer0",	"mixer0-div",
 		      0x00, BIT(0), CLK_SET_RATE_PARENT);
@@ -38,6 +40,8 @@ static SUNXI_CCU_GATE(mixer1_clk,	"mixer1",	"mixer1-div",
 		      0x00, BIT(1), CLK_SET_RATE_PARENT);
 static SUNXI_CCU_GATE(wb_clk,		"wb",		"wb-div",
 		      0x00, BIT(2), CLK_SET_RATE_PARENT);
+static SUNXI_CCU_GATE(rot_clk,		"rot",		"rot-div",
+		      0x00, BIT(3), CLK_SET_RATE_PARENT);
 
 static SUNXI_CCU_M(mixer0_div_clk, "mixer0-div", "de", 0x0c, 0, 4,
 		   CLK_SET_RATE_PARENT);
@@ -45,6 +49,8 @@ static SUNXI_CCU_M(mixer1_div_clk, "mixer1-div", "de", 0x0c, 4, 4,
 		   CLK_SET_RATE_PARENT);
 static SUNXI_CCU_M(wb_div_clk, "wb-div", "de", 0x0c, 8, 4,
 		   CLK_SET_RATE_PARENT);
+static SUNXI_CCU_M(rot_div_clk, "rot-div", "de", 0x0c, 0x0c, 4,
+		   CLK_SET_RATE_PARENT);
 
 static SUNXI_CCU_M(mixer0_div_a83_clk, "mixer0-div", "pll-de", 0x0c, 0, 4,
 		   CLK_SET_RATE_PARENT);
@@ -53,6 +59,24 @@ static SUNXI_CCU_M(mixer1_div_a83_clk, "mixer1-div", "pll-de", 0x0c, 4, 4,
 static SUNXI_CCU_M(wb_div_a83_clk, "wb-div", "pll-de", 0x0c, 8, 4,
 		   CLK_SET_RATE_PARENT);
 
+static struct ccu_common *sun50i_h6_de3_clks[] = {
+	&mixer0_clk.common,
+	&mixer1_clk.common,
+	&wb_clk.common,
+
+	&bus_mixer0_clk.common,
+	&bus_mixer1_clk.common,
+	&bus_wb_clk.common,
+
+	&mixer0_div_clk.common,
+	&mixer1_div_clk.common,
+	&wb_div_clk.common,
+
+	&bus_rot_clk.common,
+	&rot_clk.common,
+	&rot_div_clk.common,
+};
+
 static struct ccu_common *sun8i_a83t_de2_clks[] = {
 	&mixer0_clk.common,
 	&mixer1_clk.common,
@@ -106,7 +130,7 @@ static struct clk_hw_onecell_data sun8i_a83t_de2_hw_clks = {
 		[CLK_MIXER1_DIV]	= &mixer1_div_a83_clk.common.hw,
 		[CLK_WB_DIV]		= &wb_div_a83_clk.common.hw,
 	},
-	.num	= CLK_NUMBER,
+	.num	= CLK_NUMBER_WITHOUT_ROT,
 };
 
 static struct clk_hw_onecell_data sun8i_h3_de2_hw_clks = {
@@ -123,7 +147,7 @@ static struct clk_hw_onecell_data sun8i_h3_de2_hw_clks = {
 		[CLK_MIXER1_DIV]	= &mixer1_div_clk.common.hw,
 		[CLK_WB_DIV]		= &wb_div_clk.common.hw,
 	},
-	.num	= CLK_NUMBER,
+	.num	= CLK_NUMBER_WITHOUT_ROT,
 };
 
 static struct clk_hw_onecell_data sun8i_v3s_de2_hw_clks = {
@@ -137,7 +161,27 @@ static struct clk_hw_onecell_data sun8i_v3s_de2_hw_clks = {
 		[CLK_MIXER0_DIV]	= &mixer0_div_clk.common.hw,
 		[CLK_WB_DIV]		= &wb_div_clk.common.hw,
 	},
-	.num	= CLK_NUMBER,
+	.num	= CLK_NUMBER_WITHOUT_ROT,
+};
+
+static struct clk_hw_onecell_data sun50i_h6_de3_hw_clks = {
+	.hws	= {
+		[CLK_MIXER0]		= &mixer0_clk.common.hw,
+		[CLK_MIXER1]		= &mixer1_clk.common.hw,
+		[CLK_WB]		= &wb_clk.common.hw,
+		[CLK_ROT]		= &rot_clk.common.hw,
+
+		[CLK_BUS_MIXER0]	= &bus_mixer0_clk.common.hw,
+		[CLK_BUS_MIXER1]	= &bus_mixer1_clk.common.hw,
+		[CLK_BUS_WB]		= &bus_wb_clk.common.hw,
+		[CLK_BUS_ROT]		= &bus_rot_clk.common.hw,
+
+		[CLK_MIXER0_DIV]	= &mixer0_div_clk.common.hw,
+		[CLK_MIXER1_DIV]	= &mixer1_div_clk.common.hw,
+		[CLK_WB_DIV]		= &wb_div_clk.common.hw,
+		[CLK_ROT_DIV]		= &rot_div_clk.common.hw,
+	},
+	.num	= CLK_NUMBER_WITH_ROT,
 };
 
 static struct ccu_reset_map sun8i_a83t_de2_resets[] = {
@@ -156,6 +200,13 @@ static struct ccu_reset_map sun50i_a64_de2_resets[] = {
 	[RST_WB]	= { 0x08, BIT(2) },
 };
 
+static struct ccu_reset_map sun50i_h6_de3_resets[] = {
+	[RST_MIXER0]	= { 0x08, BIT(0) },
+	[RST_MIXER1]	= { 0x08, BIT(1) },
+	[RST_WB]	= { 0x08, BIT(2) },
+	[RST_ROT]	= { 0x08, BIT(3) },
+};
+
 static const struct sunxi_ccu_desc sun8i_a83t_de2_clk_desc = {
 	.ccu_clks	= sun8i_a83t_de2_clks,
 	.num_ccu_clks	= ARRAY_SIZE(sun8i_a83t_de2_clks),
@@ -186,6 +237,16 @@ static const struct sunxi_ccu_desc sun50i_a64_de2_clk_desc = {
 	.num_resets	= ARRAY_SIZE(sun50i_a64_de2_resets),
 };
 
+static const struct sunxi_ccu_desc sun50i_h6_de3_clk_desc = {
+	.ccu_clks	= sun50i_h6_de3_clks,
+	.num_ccu_clks	= ARRAY_SIZE(sun50i_h6_de3_clks),
+
+	.hw_clks	= &sun50i_h6_de3_hw_clks,
+
+	.resets		= sun50i_h6_de3_resets,
+	.num_resets	= ARRAY_SIZE(sun50i_h6_de3_resets),
+};
+
 static const struct sunxi_ccu_desc sun8i_v3s_de2_clk_desc = {
 	.ccu_clks	= sun8i_v3s_de2_clks,
 	.num_ccu_clks	= ARRAY_SIZE(sun8i_v3s_de2_clks),
@@ -296,6 +357,10 @@ static const struct of_device_id sunxi_de2_clk_ids[] = {
 		.compatible = "allwinner,sun50i-h5-de2-clk",
 		.data = &sun50i_a64_de2_clk_desc,
 	},
+	{
+		.compatible = "allwinner,sun50i-h6-de3-clk",
+		.data = &sun50i_h6_de3_clk_desc,
+	},
 	{ }
 };
 
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-de2.h b/drivers/clk/sunxi-ng/ccu-sun8i-de2.h
index 530c006e0ae9..fc9c6b4c89a8 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-de2.h
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-de2.h
@@ -22,7 +22,9 @@
 #define CLK_MIXER0_DIV	3
 #define CLK_MIXER1_DIV	4
 #define CLK_WB_DIV	5
+#define CLK_ROT_DIV	11
 
-#define CLK_NUMBER	(CLK_WB + 1)
+#define CLK_NUMBER_WITH_ROT	(CLK_ROT_DIV + 1)
+#define CLK_NUMBER_WITHOUT_ROT	(CLK_WB + 1)
 
 #endif /* _CCU_SUN8I_DE2_H_ */
-- 
2.19.1


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

* [PATCH v3 07/28] dt-bindings: display: sun4i-drm: Add H6 display engine compatibles
  2018-11-04 18:26 [PATCH v3 00/28] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (5 preceding siblings ...)
  2018-11-04 18:26 ` [PATCH v3 06/28] clk: sunxi-ng: Add support for H6 DE3 clocks Jernej Skrabec
@ 2018-11-04 18:26 ` Jernej Skrabec
  2018-11-04 18:26 ` [PATCH v3 08/28] drm/sun4i: Add compatible for H6 display engine Jernej Skrabec
                   ` (21 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Jernej Skrabec @ 2018-11-04 18:26 UTC (permalink / raw)
  To: maxime.ripard, wens
  Cc: robh+dt, mturquette, sboyd, airlied, architt, a.hajda,
	Laurent.pinchart, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi, jernej.skrabec

This commit adds compatibles used in H6 display pipeline, namely for
display engine, mixer and TV TCON.

H6 display engine is somewhat similar to R40, just less TCONs and
mixer support more features.

Reviewed-by: Rob Herring <robh@kernel.org>
Reviewed-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 .../devicetree/bindings/display/sunxi/sun4i-drm.txt          | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
index 7854fff4fc16..62c83b351344 100644
--- a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
+++ b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
@@ -158,6 +158,7 @@ Required properties:
    * allwinner,sun9i-a80-tcon-tv
    * "allwinner,sun50i-a64-tcon-lcd", "allwinner,sun8i-a83t-tcon-lcd"
    * "allwinner,sun50i-a64-tcon-tv", "allwinner,sun8i-a83t-tcon-tv"
+   * allwinner,sun50i-h6-tcon-tv, allwinner,sun8i-r40-tcon-tv
  - reg: base address and size of memory-mapped region
  - interrupts: interrupt associated to this IP
  - clocks: phandles to the clocks feeding the TCON.
@@ -381,6 +382,7 @@ Required properties:
     * allwinner,sun8i-v3s-de2-mixer
     * allwinner,sun50i-a64-de2-mixer-0
     * allwinner,sun50i-a64-de2-mixer-1
+    * allwinner,sun50i-h6-de3-mixer-0
   - reg: base address and size of the memory-mapped region.
   - clocks: phandles to the clocks feeding the mixer
     * bus: the mixer interface clock
@@ -415,9 +417,10 @@ Required properties:
     * allwinner,sun8i-v3s-display-engine
     * allwinner,sun9i-a80-display-engine
     * allwinner,sun50i-a64-display-engine
+    * allwinner,sun50i-h6-display-engine
 
   - allwinner,pipelines: list of phandle to the display engine
-    frontends (DE 1.0) or mixers (DE 2.0) available.
+    frontends (DE 1.0) or mixers (DE 2.0/3.0) available.
 
 Example:
 
-- 
2.19.1


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

* [PATCH v3 08/28] drm/sun4i: Add compatible for H6 display engine
  2018-11-04 18:26 [PATCH v3 00/28] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (6 preceding siblings ...)
  2018-11-04 18:26 ` [PATCH v3 07/28] dt-bindings: display: sun4i-drm: Add H6 display engine compatibles Jernej Skrabec
@ 2018-11-04 18:26 ` Jernej Skrabec
  2018-11-04 18:26 ` [PATCH v3 09/28] drm/sun4i: Rework DE2 register defines Jernej Skrabec
                   ` (20 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Jernej Skrabec @ 2018-11-04 18:26 UTC (permalink / raw)
  To: maxime.ripard, wens
  Cc: robh+dt, mturquette, sboyd, airlied, architt, a.hajda,
	Laurent.pinchart, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi, jernej.skrabec

H6 is first Allwinner SoC which supports 10 bit colors, HDR and AFBC.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/gpu/drm/sun4i/sun4i_drv.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c
index 1e41c3f5fd6d..1ca7b70cbbfa 100644
--- a/drivers/gpu/drm/sun4i/sun4i_drv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
@@ -406,6 +406,7 @@ static const struct of_device_id sun4i_drv_of_table[] = {
 	{ .compatible = "allwinner,sun8i-v3s-display-engine" },
 	{ .compatible = "allwinner,sun9i-a80-display-engine" },
 	{ .compatible = "allwinner,sun50i-a64-display-engine" },
+	{ .compatible = "allwinner,sun50i-h6-display-engine" },
 	{ }
 };
 MODULE_DEVICE_TABLE(of, sun4i_drv_of_table);
-- 
2.19.1


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

* [PATCH v3 09/28] drm/sun4i: Rework DE2 register defines
  2018-11-04 18:26 [PATCH v3 00/28] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (7 preceding siblings ...)
  2018-11-04 18:26 ` [PATCH v3 08/28] drm/sun4i: Add compatible for H6 display engine Jernej Skrabec
@ 2018-11-04 18:26 ` Jernej Skrabec
  2018-11-04 18:26 ` [PATCH v3 10/28] drm/sun4i: Fix DE2 mixer size Jernej Skrabec
                   ` (19 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Jernej Skrabec @ 2018-11-04 18:26 UTC (permalink / raw)
  To: maxime.ripard, wens
  Cc: robh+dt, mturquette, sboyd, airlied, architt, a.hajda,
	Laurent.pinchart, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi, jernej.skrabec, Icenowy Zheng

Most, if not all, registers found in DE2 still exists in DE3. However,
units are on different base addresses.

To prepare for addition of DE3 support, registers macros are reworked so
they take base address as parameter.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
[rebased]
Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
---
 drivers/gpu/drm/sun4i/sun8i_mixer.c     | 14 ++++---
 drivers/gpu/drm/sun4i/sun8i_mixer.h     | 44 +++++++++++++-------
 drivers/gpu/drm/sun4i/sun8i_ui_layer.c  | 47 ++++++++++++++--------
 drivers/gpu/drm/sun4i/sun8i_ui_layer.h  | 37 +++++++++--------
 drivers/gpu/drm/sun4i/sun8i_ui_scaler.c | 41 +++++++++++--------
 drivers/gpu/drm/sun4i/sun8i_ui_scaler.h | 27 +++++--------
 drivers/gpu/drm/sun4i/sun8i_vi_layer.c  | 47 ++++++++++++++--------
 drivers/gpu/drm/sun4i/sun8i_vi_layer.h  | 23 ++++++-----
 drivers/gpu/drm/sun4i/sun8i_vi_scaler.c | 53 +++++++++++++++----------
 drivers/gpu/drm/sun4i/sun8i_vi_scaler.h | 45 ++++++++++-----------
 10 files changed, 219 insertions(+), 159 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c
index 8b3d02b146b7..6129c350f7bd 100644
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
@@ -368,6 +368,7 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master,
 	struct sun8i_mixer *mixer;
 	struct resource *res;
 	void __iomem *regs;
+	unsigned int base;
 	int plane_cnt;
 	int i, ret;
 
@@ -456,6 +457,8 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master,
 
 	list_add_tail(&mixer->engine.list, &drv->engine_list);
 
+	base = sun8i_blender_base(mixer);
+
 	/* Reset the registers */
 	for (i = 0x0; i < 0x20000; i += 4)
 		regmap_write(mixer->engine.regs, i, 0);
@@ -465,24 +468,25 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master,
 		     SUN8I_MIXER_GLOBAL_CTL_RT_EN);
 
 	/* Set background color to black */
-	regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_BKCOLOR,
+	regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_BKCOLOR(base),
 		     SUN8I_MIXER_BLEND_COLOR_BLACK);
 
 	/*
 	 * Set fill color of bottom plane to black. Generally not needed
 	 * except when VI plane is at bottom (zpos = 0) and enabled.
 	 */
-	regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL,
+	regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL(base),
 		     SUN8I_MIXER_BLEND_PIPE_CTL_FC_EN(0));
-	regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_ATTR_FCOLOR(0),
+	regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_ATTR_FCOLOR(base, 0),
 		     SUN8I_MIXER_BLEND_COLOR_BLACK);
 
 	plane_cnt = mixer->cfg->vi_num + mixer->cfg->ui_num;
 	for (i = 0; i < plane_cnt; i++)
-		regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_MODE(i),
+		regmap_write(mixer->engine.regs,
+			     SUN8I_MIXER_BLEND_MODE(base, i),
 			     SUN8I_MIXER_BLEND_MODE_DEF);
 
-	regmap_update_bits(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL,
+	regmap_update_bits(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL(base),
 			   SUN8I_MIXER_BLEND_PIPE_CTL_EN_MSK, 0);
 
 	return 0;
diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h b/drivers/gpu/drm/sun4i/sun8i_mixer.h
index 406c42e752d7..025550a1f539 100644
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.h
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h
@@ -29,20 +29,24 @@
 
 #define SUN8I_MIXER_GLOBAL_DBUFF_ENABLE		BIT(0)
 
-#define SUN8I_MIXER_BLEND_PIPE_CTL		0x1000
-#define SUN8I_MIXER_BLEND_ATTR_FCOLOR(x)	(0x1004 + 0x10 * (x) + 0x0)
-#define SUN8I_MIXER_BLEND_ATTR_INSIZE(x)	(0x1004 + 0x10 * (x) + 0x4)
-#define SUN8I_MIXER_BLEND_ATTR_COORD(x)		(0x1004 + 0x10 * (x) + 0x8)
-#define SUN8I_MIXER_BLEND_ROUTE			0x1080
-#define SUN8I_MIXER_BLEND_PREMULTIPLY		0x1084
-#define SUN8I_MIXER_BLEND_BKCOLOR		0x1088
-#define SUN8I_MIXER_BLEND_OUTSIZE		0x108c
-#define SUN8I_MIXER_BLEND_MODE(x)		(0x1090 + 0x04 * (x))
-#define SUN8I_MIXER_BLEND_CK_CTL		0x10b0
-#define SUN8I_MIXER_BLEND_CK_CFG		0x10b4
-#define SUN8I_MIXER_BLEND_CK_MAX(x)		(0x10c0 + 0x04 * (x))
-#define SUN8I_MIXER_BLEND_CK_MIN(x)		(0x10e0 + 0x04 * (x))
-#define SUN8I_MIXER_BLEND_OUTCTL		0x10fc
+#define DE2_BLD_BASE				0x1000
+#define DE2_CH_BASE				0x2000
+#define DE2_CH_SIZE				0x1000
+
+#define SUN8I_MIXER_BLEND_PIPE_CTL(base)	((base) + 0)
+#define SUN8I_MIXER_BLEND_ATTR_FCOLOR(base, x)	((base) + 0x4 + 0x10 * (x))
+#define SUN8I_MIXER_BLEND_ATTR_INSIZE(base, x)	((base) + 0x8 + 0x10 * (x))
+#define SUN8I_MIXER_BLEND_ATTR_COORD(base, x)	((base) + 0xc + 0x10 * (x))
+#define SUN8I_MIXER_BLEND_ROUTE(base)		((base) + 0x80)
+#define SUN8I_MIXER_BLEND_PREMULTIPLY(base)	((base) + 0x84)
+#define SUN8I_MIXER_BLEND_BKCOLOR(base)		((base) + 0x88)
+#define SUN8I_MIXER_BLEND_OUTSIZE(base)		((base) + 0x8c)
+#define SUN8I_MIXER_BLEND_MODE(base, x)		((base) + 0x90 + 0x04 * (x))
+#define SUN8I_MIXER_BLEND_CK_CTL(base)		((base) + 0xb0)
+#define SUN8I_MIXER_BLEND_CK_CFG(base)		((base) + 0xb4)
+#define SUN8I_MIXER_BLEND_CK_MAX(base, x)	((base) + 0xc0 + 0x04 * (x))
+#define SUN8I_MIXER_BLEND_CK_MIN(base, x)	((base) + 0xe0 + 0x04 * (x))
+#define SUN8I_MIXER_BLEND_OUTCTL(base)		((base) + 0xfc)
 
 #define SUN8I_MIXER_BLEND_PIPE_CTL_EN_MSK	GENMASK(12, 8)
 #define SUN8I_MIXER_BLEND_PIPE_CTL_EN(pipe)	BIT(8 + pipe)
@@ -153,5 +157,17 @@ engine_to_sun8i_mixer(struct sunxi_engine *engine)
 	return container_of(engine, struct sun8i_mixer, engine);
 }
 
+static inline u32
+sun8i_blender_base(struct sun8i_mixer *mixer)
+{
+	return DE2_BLD_BASE;
+}
+
+static inline u32
+sun8i_channel_base(struct sun8i_mixer *mixer, int channel)
+{
+	return DE2_CH_BASE + channel * DE2_CH_SIZE;
+}
+
 const struct de2_fmt_info *sun8i_mixer_format_info(u32 format);
 #endif /* _SUN8I_MIXER_H_ */
diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
index 28c15c6ef1ef..e3fc8fa920fb 100644
--- a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
@@ -30,7 +30,10 @@ static void sun8i_ui_layer_enable(struct sun8i_mixer *mixer, int channel,
 				  int overlay, bool enable, unsigned int zpos,
 				  unsigned int old_zpos)
 {
-	u32 val;
+	u32 val, bld_base, ch_base;
+
+	bld_base = sun8i_blender_base(mixer);
+	ch_base = sun8i_channel_base(mixer, channel);
 
 	DRM_DEBUG_DRIVER("%sabling channel %d overlay %d\n",
 			 enable ? "En" : "Dis", channel, overlay);
@@ -41,17 +44,17 @@ static void sun8i_ui_layer_enable(struct sun8i_mixer *mixer, int channel,
 		val = 0;
 
 	regmap_update_bits(mixer->engine.regs,
-			   SUN8I_MIXER_CHAN_UI_LAYER_ATTR(channel, overlay),
+			   SUN8I_MIXER_CHAN_UI_LAYER_ATTR(ch_base, overlay),
 			   SUN8I_MIXER_CHAN_UI_LAYER_ATTR_EN, val);
 
 	if (!enable || zpos != old_zpos) {
 		regmap_update_bits(mixer->engine.regs,
-				   SUN8I_MIXER_BLEND_PIPE_CTL,
+				   SUN8I_MIXER_BLEND_PIPE_CTL(bld_base),
 				   SUN8I_MIXER_BLEND_PIPE_CTL_EN(old_zpos),
 				   0);
 
 		regmap_update_bits(mixer->engine.regs,
-				   SUN8I_MIXER_BLEND_ROUTE,
+				   SUN8I_MIXER_BLEND_ROUTE(bld_base),
 				   SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(old_zpos),
 				   0);
 	}
@@ -60,12 +63,13 @@ static void sun8i_ui_layer_enable(struct sun8i_mixer *mixer, int channel,
 		val = SUN8I_MIXER_BLEND_PIPE_CTL_EN(zpos);
 
 		regmap_update_bits(mixer->engine.regs,
-				   SUN8I_MIXER_BLEND_PIPE_CTL, val, val);
+				   SUN8I_MIXER_BLEND_PIPE_CTL(bld_base),
+				   val, val);
 
 		val = channel << SUN8I_MIXER_BLEND_ROUTE_PIPE_SHIFT(zpos);
 
 		regmap_update_bits(mixer->engine.regs,
-				   SUN8I_MIXER_BLEND_ROUTE,
+				   SUN8I_MIXER_BLEND_ROUTE(bld_base),
 				   SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(zpos),
 				   val);
 	}
@@ -77,12 +81,16 @@ static int sun8i_ui_layer_update_coord(struct sun8i_mixer *mixer, int channel,
 {
 	struct drm_plane_state *state = plane->state;
 	u32 src_w, src_h, dst_w, dst_h;
+	u32 bld_base, ch_base;
 	u32 outsize, insize;
 	u32 hphase, vphase;
 
 	DRM_DEBUG_DRIVER("Updating UI channel %d overlay %d\n",
 			 channel, overlay);
 
+	bld_base = sun8i_blender_base(mixer);
+	ch_base = sun8i_channel_base(mixer, channel);
+
 	src_w = drm_rect_width(&state->src) >> 16;
 	src_h = drm_rect_height(&state->src) >> 16;
 	dst_w = drm_rect_width(&state->dst);
@@ -103,8 +111,8 @@ static int sun8i_ui_layer_update_coord(struct sun8i_mixer *mixer, int channel,
 		regmap_write(mixer->engine.regs,
 			     SUN8I_MIXER_GLOBAL_SIZE,
 			     outsize);
-		regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_OUTSIZE,
-			     outsize);
+		regmap_write(mixer->engine.regs,
+			     SUN8I_MIXER_BLEND_OUTSIZE(bld_base), outsize);
 
 		if (state->crtc)
 			interlaced = state->crtc->state->adjusted_mode.flags
@@ -116,7 +124,7 @@ static int sun8i_ui_layer_update_coord(struct sun8i_mixer *mixer, int channel,
 			val = 0;
 
 		regmap_update_bits(mixer->engine.regs,
-				   SUN8I_MIXER_BLEND_OUTCTL,
+				   SUN8I_MIXER_BLEND_OUTCTL(bld_base),
 				   SUN8I_MIXER_BLEND_OUTCTL_INTERLACED,
 				   val);
 
@@ -129,10 +137,10 @@ static int sun8i_ui_layer_update_coord(struct sun8i_mixer *mixer, int channel,
 			 state->src.x1 >> 16, state->src.y1 >> 16);
 	DRM_DEBUG_DRIVER("Layer source size W: %d H: %d\n", src_w, src_h);
 	regmap_write(mixer->engine.regs,
-		     SUN8I_MIXER_CHAN_UI_LAYER_SIZE(channel, overlay),
+		     SUN8I_MIXER_CHAN_UI_LAYER_SIZE(ch_base, overlay),
 		     insize);
 	regmap_write(mixer->engine.regs,
-		     SUN8I_MIXER_CHAN_UI_OVL_SIZE(channel),
+		     SUN8I_MIXER_CHAN_UI_OVL_SIZE(ch_base),
 		     insize);
 
 	if (insize != outsize || hphase || vphase) {
@@ -156,10 +164,10 @@ static int sun8i_ui_layer_update_coord(struct sun8i_mixer *mixer, int channel,
 			 state->dst.x1, state->dst.y1);
 	DRM_DEBUG_DRIVER("Layer destination size W: %d H: %d\n", dst_w, dst_h);
 	regmap_write(mixer->engine.regs,
-		     SUN8I_MIXER_BLEND_ATTR_COORD(zpos),
+		     SUN8I_MIXER_BLEND_ATTR_COORD(bld_base, zpos),
 		     SUN8I_MIXER_COORD(state->dst.x1, state->dst.y1));
 	regmap_write(mixer->engine.regs,
-		     SUN8I_MIXER_BLEND_ATTR_INSIZE(zpos),
+		     SUN8I_MIXER_BLEND_ATTR_INSIZE(bld_base, zpos),
 		     outsize);
 
 	return 0;
@@ -170,7 +178,9 @@ static int sun8i_ui_layer_update_formats(struct sun8i_mixer *mixer, int channel,
 {
 	struct drm_plane_state *state = plane->state;
 	const struct de2_fmt_info *fmt_info;
-	u32 val;
+	u32 val, ch_base;
+
+	ch_base = sun8i_channel_base(mixer, channel);
 
 	fmt_info = sun8i_mixer_format_info(state->fb->format->format);
 	if (!fmt_info || !fmt_info->rgb) {
@@ -180,7 +190,7 @@ static int sun8i_ui_layer_update_formats(struct sun8i_mixer *mixer, int channel,
 
 	val = fmt_info->de2_fmt << SUN8I_MIXER_CHAN_UI_LAYER_ATTR_FBFMT_OFFSET;
 	regmap_update_bits(mixer->engine.regs,
-			   SUN8I_MIXER_CHAN_UI_LAYER_ATTR(channel, overlay),
+			   SUN8I_MIXER_CHAN_UI_LAYER_ATTR(ch_base, overlay),
 			   SUN8I_MIXER_CHAN_UI_LAYER_ATTR_FBFMT_MASK, val);
 
 	return 0;
@@ -193,8 +203,11 @@ static int sun8i_ui_layer_update_buffer(struct sun8i_mixer *mixer, int channel,
 	struct drm_framebuffer *fb = state->fb;
 	struct drm_gem_cma_object *gem;
 	dma_addr_t paddr;
+	u32 ch_base;
 	int bpp;
 
+	ch_base = sun8i_channel_base(mixer, channel);
+
 	/* Get the physical address of the buffer in memory */
 	gem = drm_fb_cma_get_gem_obj(fb, 0);
 
@@ -211,13 +224,13 @@ static int sun8i_ui_layer_update_buffer(struct sun8i_mixer *mixer, int channel,
 	/* Set the line width */
 	DRM_DEBUG_DRIVER("Layer line width: %d bytes\n", fb->pitches[0]);
 	regmap_write(mixer->engine.regs,
-		     SUN8I_MIXER_CHAN_UI_LAYER_PITCH(channel, overlay),
+		     SUN8I_MIXER_CHAN_UI_LAYER_PITCH(ch_base, overlay),
 		     fb->pitches[0]);
 
 	DRM_DEBUG_DRIVER("Setting buffer address to %pad\n", &paddr);
 
 	regmap_write(mixer->engine.regs,
-		     SUN8I_MIXER_CHAN_UI_LAYER_TOP_LADDR(channel, overlay),
+		     SUN8I_MIXER_CHAN_UI_LAYER_TOP_LADDR(ch_base, overlay),
 		     lower_32_bits(paddr));
 
 	return 0;
diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_layer.h b/drivers/gpu/drm/sun4i/sun8i_ui_layer.h
index 123b15ea9918..f4389cf0ba20 100644
--- a/drivers/gpu/drm/sun4i/sun8i_ui_layer.h
+++ b/drivers/gpu/drm/sun4i/sun8i_ui_layer.h
@@ -18,23 +18,26 @@
 
 #include <drm/drm_plane.h>
 
-#define SUN8I_MIXER_CHAN_UI_LAYER_ATTR(ch, layer) \
-			(0x2000 + 0x1000 * (ch) + 0x20 * (layer) + 0x0)
-#define SUN8I_MIXER_CHAN_UI_LAYER_SIZE(ch, layer) \
-			(0x2000 + 0x1000 * (ch) + 0x20 * (layer) + 0x4)
-#define SUN8I_MIXER_CHAN_UI_LAYER_COORD(ch, layer) \
-			(0x2000 + 0x1000 * (ch) + 0x20 * (layer) + 0x8)
-#define SUN8I_MIXER_CHAN_UI_LAYER_PITCH(ch, layer) \
-			(0x2000 + 0x1000 * (ch) + 0x20 * (layer) + 0xc)
-#define SUN8I_MIXER_CHAN_UI_LAYER_TOP_LADDR(ch, layer) \
-			(0x2000 + 0x1000 * (ch) + 0x20 * (layer) + 0x10)
-#define SUN8I_MIXER_CHAN_UI_LAYER_BOT_LADDR(ch, layer) \
-			(0x2000 + 0x1000 * (ch) + 0x20 * (layer) + 0x14)
-#define SUN8I_MIXER_CHAN_UI_LAYER_FCOLOR(ch, layer) \
-			(0x2000 + 0x1000 * (ch) + 0x20 * (layer) + 0x18)
-#define SUN8I_MIXER_CHAN_UI_TOP_HADDR(ch)	(0x2000 + 0x1000 * (ch) + 0x80)
-#define SUN8I_MIXER_CHAN_UI_BOT_HADDR(ch)	(0x2000 + 0x1000 * (ch) + 0x84)
-#define SUN8I_MIXER_CHAN_UI_OVL_SIZE(ch)	(0x2000 + 0x1000 * (ch) + 0x88)
+#define SUN8I_MIXER_CHAN_UI_LAYER_ATTR(base, layer) \
+			((base) + 0x20 * (layer) + 0x0)
+#define SUN8I_MIXER_CHAN_UI_LAYER_SIZE(base, layer) \
+			((base) + 0x20 * (layer) + 0x4)
+#define SUN8I_MIXER_CHAN_UI_LAYER_COORD(base, layer) \
+			((base) + 0x20 * (layer) + 0x8)
+#define SUN8I_MIXER_CHAN_UI_LAYER_PITCH(base, layer) \
+			((base) + 0x20 * (layer) + 0xc)
+#define SUN8I_MIXER_CHAN_UI_LAYER_TOP_LADDR(base, layer) \
+			((base) + 0x20 * (layer) + 0x10)
+#define SUN8I_MIXER_CHAN_UI_LAYER_BOT_LADDR(base, layer) \
+			((base) + 0x20 * (layer) + 0x14)
+#define SUN8I_MIXER_CHAN_UI_LAYER_FCOLOR(base, layer) \
+			((base) + 0x20 * (layer) + 0x18)
+#define SUN8I_MIXER_CHAN_UI_TOP_HADDR(base) \
+			((base) + 0x80)
+#define SUN8I_MIXER_CHAN_UI_BOT_HADDR(base) \
+			((base) + 0x84)
+#define SUN8I_MIXER_CHAN_UI_OVL_SIZE(base) \
+			((base) + 0x88)
 
 #define SUN8I_MIXER_CHAN_UI_LAYER_ATTR_EN		BIT(0)
 #define SUN8I_MIXER_CHAN_UI_LAYER_ATTR_ALPHA_MODE_MASK	GENMASK(2, 1)
diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_scaler.c b/drivers/gpu/drm/sun4i/sun8i_ui_scaler.c
index 6bb2aa164c8e..698401ecb53d 100644
--- a/drivers/gpu/drm/sun4i/sun8i_ui_scaler.c
+++ b/drivers/gpu/drm/sun4i/sun8i_ui_scaler.c
@@ -10,6 +10,7 @@
  */
 
 #include "sun8i_ui_scaler.h"
+#include "sun8i_vi_scaler.h"
 
 static const u32 lan2coefftab16[240] = {
 	0x00004000, 0x00033ffe, 0x00063efc, 0x000a3bfb,
@@ -88,6 +89,14 @@ static const u32 lan2coefftab16[240] = {
 	0x0b1c1603, 0x0d1c1502, 0x0e1d1401, 0x0f1d1301,
 };
 
+static u32 sun8i_ui_scaler_base(struct sun8i_mixer *mixer, int channel)
+{
+	int vi_num = mixer->cfg->vi_num;
+
+	return DE2_VI_SCALER_UNIT_BASE + DE2_VI_SCALER_UNIT_SIZE * vi_num +
+	       DE2_UI_SCALER_UNIT_SIZE * (channel - vi_num);
+}
+
 static int sun8i_ui_scaler_coef_index(unsigned int step)
 {
 	unsigned int scale, int_part, float_part;
@@ -114,33 +123,35 @@ static int sun8i_ui_scaler_coef_index(unsigned int step)
 
 void sun8i_ui_scaler_enable(struct sun8i_mixer *mixer, int layer, bool enable)
 {
-	int vi_cnt = mixer->cfg->vi_num;
-	u32 val;
+	u32 val, base;
 
-	if (WARN_ON(layer < vi_cnt))
+	if (WARN_ON(layer < mixer->cfg->vi_num))
 		return;
 
+	base = sun8i_ui_scaler_base(mixer, layer);
+
 	if (enable)
 		val = SUN8I_SCALER_GSU_CTRL_EN |
 		      SUN8I_SCALER_GSU_CTRL_COEFF_RDY;
 	else
 		val = 0;
 
-	regmap_write(mixer->engine.regs,
-		     SUN8I_SCALER_GSU_CTRL(vi_cnt, layer - vi_cnt), val);
+	regmap_write(mixer->engine.regs, SUN8I_SCALER_GSU_CTRL(base), val);
 }
 
 void sun8i_ui_scaler_setup(struct sun8i_mixer *mixer, int layer,
 			   u32 src_w, u32 src_h, u32 dst_w, u32 dst_h,
 			   u32 hscale, u32 vscale, u32 hphase, u32 vphase)
 {
-	int vi_cnt = mixer->cfg->vi_num;
 	u32 insize, outsize;
 	int i, offset;
+	u32 base;
 
-	if (WARN_ON(layer < vi_cnt))
+	if (WARN_ON(layer < mixer->cfg->vi_num))
 		return;
 
+	base = sun8i_ui_scaler_base(mixer, layer);
+
 	hphase <<= SUN8I_UI_SCALER_PHASE_FRAC - 16;
 	vphase <<= SUN8I_UI_SCALER_PHASE_FRAC - 16;
 	hscale <<= SUN8I_UI_SCALER_SCALE_FRAC - 16;
@@ -149,24 +160,22 @@ void sun8i_ui_scaler_setup(struct sun8i_mixer *mixer, int layer,
 	insize = SUN8I_UI_SCALER_SIZE(src_w, src_h);
 	outsize = SUN8I_UI_SCALER_SIZE(dst_w, dst_h);
 
-	layer -= vi_cnt;
-
 	regmap_write(mixer->engine.regs,
-		     SUN8I_SCALER_GSU_OUTSIZE(vi_cnt, layer), outsize);
+		     SUN8I_SCALER_GSU_OUTSIZE(base), outsize);
 	regmap_write(mixer->engine.regs,
-		     SUN8I_SCALER_GSU_INSIZE(vi_cnt, layer), insize);
+		     SUN8I_SCALER_GSU_INSIZE(base), insize);
 	regmap_write(mixer->engine.regs,
-		     SUN8I_SCALER_GSU_HSTEP(vi_cnt, layer), hscale);
+		     SUN8I_SCALER_GSU_HSTEP(base), hscale);
 	regmap_write(mixer->engine.regs,
-		     SUN8I_SCALER_GSU_VSTEP(vi_cnt, layer), vscale);
+		     SUN8I_SCALER_GSU_VSTEP(base), vscale);
 	regmap_write(mixer->engine.regs,
-		     SUN8I_SCALER_GSU_HPHASE(vi_cnt, layer), hphase);
+		     SUN8I_SCALER_GSU_HPHASE(base), hphase);
 	regmap_write(mixer->engine.regs,
-		     SUN8I_SCALER_GSU_VPHASE(vi_cnt, layer), vphase);
+		     SUN8I_SCALER_GSU_VPHASE(base), vphase);
 	offset = sun8i_ui_scaler_coef_index(hscale) *
 			SUN8I_UI_SCALER_COEFF_COUNT;
 	for (i = 0; i < SUN8I_UI_SCALER_COEFF_COUNT; i++)
 		regmap_write(mixer->engine.regs,
-			     SUN8I_SCALER_GSU_HCOEFF(vi_cnt, layer, i),
+			     SUN8I_SCALER_GSU_HCOEFF(base, i),
 			     lan2coefftab16[offset + i]);
 }
diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_scaler.h b/drivers/gpu/drm/sun4i/sun8i_ui_scaler.h
index 86295be8be78..6b4bc1ff3e2c 100644
--- a/drivers/gpu/drm/sun4i/sun8i_ui_scaler.h
+++ b/drivers/gpu/drm/sun4i/sun8i_ui_scaler.h
@@ -11,6 +11,8 @@
 
 #include "sun8i_mixer.h"
 
+#define DE2_UI_SCALER_UNIT_SIZE 0x10000
+
 /* this two macros assumes 16 fractional bits which is standard in DRM */
 #define SUN8I_UI_SCALER_SCALE_MIN		1
 #define SUN8I_UI_SCALER_SCALE_MAX		((1UL << 20) - 1)
@@ -20,23 +22,14 @@
 #define SUN8I_UI_SCALER_COEFF_COUNT		16
 #define SUN8I_UI_SCALER_SIZE(w, h)		(((h) - 1) << 16 | ((w) - 1))
 
-#define SUN8I_SCALER_GSU_CTRL(vi_cnt, ui_idx) \
-	(0x20000 + 0x20000 * (vi_cnt) + 0x10000 * (ui_idx) + 0x0)
-#define SUN8I_SCALER_GSU_OUTSIZE(vi_cnt, ui_idx) \
-	(0x20000 + 0x20000 * (vi_cnt) + 0x10000 * (ui_idx) + 0x40)
-#define SUN8I_SCALER_GSU_INSIZE(vi_cnt, ui_idx) \
-	(0x20000 + 0x20000 * (vi_cnt) + 0x10000 * (ui_idx) + 0x80)
-#define SUN8I_SCALER_GSU_HSTEP(vi_cnt, ui_idx) \
-	(0x20000 + 0x20000 * (vi_cnt) + 0x10000 * (ui_idx) + 0x88)
-#define SUN8I_SCALER_GSU_VSTEP(vi_cnt, ui_idx) \
-	(0x20000 + 0x20000 * (vi_cnt) + 0x10000 * (ui_idx) + 0x8c)
-#define SUN8I_SCALER_GSU_HPHASE(vi_cnt, ui_idx) \
-	(0x20000 + 0x20000 * (vi_cnt) + 0x10000 * (ui_idx) + 0x90)
-#define SUN8I_SCALER_GSU_VPHASE(vi_cnt, ui_idx) \
-	(0x20000 + 0x20000 * (vi_cnt) + 0x10000 * (ui_idx) + 0x98)
-#define SUN8I_SCALER_GSU_HCOEFF(vi_cnt, ui_idx, index) \
-	(0x20000 + 0x20000 * (vi_cnt) + 0x10000 * (ui_idx) + 0x200 + \
-	0x4 * (index))
+#define SUN8I_SCALER_GSU_CTRL(base)		((base) + 0x0)
+#define SUN8I_SCALER_GSU_OUTSIZE(base)		((base) + 0x40)
+#define SUN8I_SCALER_GSU_INSIZE(base)		((base) + 0x80)
+#define SUN8I_SCALER_GSU_HSTEP(base)		((base) + 0x88)
+#define SUN8I_SCALER_GSU_VSTEP(base)		((base) + 0x8c)
+#define SUN8I_SCALER_GSU_HPHASE(base)		((base) + 0x90)
+#define SUN8I_SCALER_GSU_VPHASE(base)		((base) + 0x98)
+#define SUN8I_SCALER_GSU_HCOEFF(base, index)	((base) + 0x200 + 0x4 * (index))
 
 #define SUN8I_SCALER_GSU_CTRL_EN		BIT(0)
 #define SUN8I_SCALER_GSU_CTRL_COEFF_RDY		BIT(4)
diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
index f4fe97813f94..79811eae3735 100644
--- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
@@ -24,7 +24,10 @@ static void sun8i_vi_layer_enable(struct sun8i_mixer *mixer, int channel,
 				  int overlay, bool enable, unsigned int zpos,
 				  unsigned int old_zpos)
 {
-	u32 val;
+	u32 val, bld_base, ch_base;
+
+	bld_base = sun8i_blender_base(mixer);
+	ch_base = sun8i_channel_base(mixer, channel);
 
 	DRM_DEBUG_DRIVER("%sabling VI channel %d overlay %d\n",
 			 enable ? "En" : "Dis", channel, overlay);
@@ -35,17 +38,17 @@ static void sun8i_vi_layer_enable(struct sun8i_mixer *mixer, int channel,
 		val = 0;
 
 	regmap_update_bits(mixer->engine.regs,
-			   SUN8I_MIXER_CHAN_VI_LAYER_ATTR(channel, overlay),
+			   SUN8I_MIXER_CHAN_VI_LAYER_ATTR(ch_base, overlay),
 			   SUN8I_MIXER_CHAN_VI_LAYER_ATTR_EN, val);
 
 	if (!enable || zpos != old_zpos) {
 		regmap_update_bits(mixer->engine.regs,
-				   SUN8I_MIXER_BLEND_PIPE_CTL,
+				   SUN8I_MIXER_BLEND_PIPE_CTL(bld_base),
 				   SUN8I_MIXER_BLEND_PIPE_CTL_EN(old_zpos),
 				   0);
 
 		regmap_update_bits(mixer->engine.regs,
-				   SUN8I_MIXER_BLEND_ROUTE,
+				   SUN8I_MIXER_BLEND_ROUTE(bld_base),
 				   SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(old_zpos),
 				   0);
 	}
@@ -54,12 +57,13 @@ static void sun8i_vi_layer_enable(struct sun8i_mixer *mixer, int channel,
 		val = SUN8I_MIXER_BLEND_PIPE_CTL_EN(zpos);
 
 		regmap_update_bits(mixer->engine.regs,
-				   SUN8I_MIXER_BLEND_PIPE_CTL, val, val);
+				   SUN8I_MIXER_BLEND_PIPE_CTL(bld_base),
+				   val, val);
 
 		val = channel << SUN8I_MIXER_BLEND_ROUTE_PIPE_SHIFT(zpos);
 
 		regmap_update_bits(mixer->engine.regs,
-				   SUN8I_MIXER_BLEND_ROUTE,
+				   SUN8I_MIXER_BLEND_ROUTE(bld_base),
 				   SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(zpos),
 				   val);
 	}
@@ -72,6 +76,7 @@ static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel,
 	struct drm_plane_state *state = plane->state;
 	const struct drm_format_info *format = state->fb->format;
 	u32 src_w, src_h, dst_w, dst_h;
+	u32 bld_base, ch_base;
 	u32 outsize, insize;
 	u32 hphase, vphase;
 	bool subsampled;
@@ -79,6 +84,9 @@ static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel,
 	DRM_DEBUG_DRIVER("Updating VI channel %d overlay %d\n",
 			 channel, overlay);
 
+	bld_base = sun8i_blender_base(mixer);
+	ch_base = sun8i_channel_base(mixer, channel);
+
 	src_w = drm_rect_width(&state->src) >> 16;
 	src_h = drm_rect_height(&state->src) >> 16;
 	dst_w = drm_rect_width(&state->dst);
@@ -115,10 +123,10 @@ static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel,
 			 (state->src.y1 >> 16) & ~(format->vsub - 1));
 	DRM_DEBUG_DRIVER("Layer source size W: %d H: %d\n", src_w, src_h);
 	regmap_write(mixer->engine.regs,
-		     SUN8I_MIXER_CHAN_VI_LAYER_SIZE(channel, overlay),
+		     SUN8I_MIXER_CHAN_VI_LAYER_SIZE(ch_base, overlay),
 		     insize);
 	regmap_write(mixer->engine.regs,
-		     SUN8I_MIXER_CHAN_VI_OVL_SIZE(channel),
+		     SUN8I_MIXER_CHAN_VI_OVL_SIZE(ch_base),
 		     insize);
 
 	/*
@@ -149,10 +157,10 @@ static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel,
 			 state->dst.x1, state->dst.y1);
 	DRM_DEBUG_DRIVER("Layer destination size W: %d H: %d\n", dst_w, dst_h);
 	regmap_write(mixer->engine.regs,
-		     SUN8I_MIXER_BLEND_ATTR_COORD(zpos),
+		     SUN8I_MIXER_BLEND_ATTR_COORD(bld_base, zpos),
 		     SUN8I_MIXER_COORD(state->dst.x1, state->dst.y1));
 	regmap_write(mixer->engine.regs,
-		     SUN8I_MIXER_BLEND_ATTR_INSIZE(zpos),
+		     SUN8I_MIXER_BLEND_ATTR_INSIZE(bld_base, zpos),
 		     outsize);
 
 	return 0;
@@ -163,7 +171,9 @@ static int sun8i_vi_layer_update_formats(struct sun8i_mixer *mixer, int channel,
 {
 	struct drm_plane_state *state = plane->state;
 	const struct de2_fmt_info *fmt_info;
-	u32 val;
+	u32 val, ch_base;
+
+	ch_base = sun8i_channel_base(mixer, channel);
 
 	fmt_info = sun8i_mixer_format_info(state->fb->format->format);
 	if (!fmt_info) {
@@ -173,7 +183,7 @@ static int sun8i_vi_layer_update_formats(struct sun8i_mixer *mixer, int channel,
 
 	val = fmt_info->de2_fmt << SUN8I_MIXER_CHAN_VI_LAYER_ATTR_FBFMT_OFFSET;
 	regmap_update_bits(mixer->engine.regs,
-			   SUN8I_MIXER_CHAN_VI_LAYER_ATTR(channel, overlay),
+			   SUN8I_MIXER_CHAN_VI_LAYER_ATTR(ch_base, overlay),
 			   SUN8I_MIXER_CHAN_VI_LAYER_ATTR_FBFMT_MASK, val);
 
 	if (fmt_info->csc != SUN8I_CSC_MODE_OFF) {
@@ -189,7 +199,7 @@ static int sun8i_vi_layer_update_formats(struct sun8i_mixer *mixer, int channel,
 		val = 0;
 
 	regmap_update_bits(mixer->engine.regs,
-			   SUN8I_MIXER_CHAN_VI_LAYER_ATTR(channel, overlay),
+			   SUN8I_MIXER_CHAN_VI_LAYER_ATTR(ch_base, overlay),
 			   SUN8I_MIXER_CHAN_VI_LAYER_ATTR_RGB_MODE, val);
 
 	return 0;
@@ -204,8 +214,11 @@ static int sun8i_vi_layer_update_buffer(struct sun8i_mixer *mixer, int channel,
 	struct drm_gem_cma_object *gem;
 	u32 dx, dy, src_x, src_y;
 	dma_addr_t paddr;
+	u32 ch_base;
 	int i;
 
+	ch_base = sun8i_channel_base(mixer, channel);
+
 	/* Adjust x and y to be dividable by subsampling factor */
 	src_x = (state->src.x1 >> 16) & ~(format->hsub - 1);
 	src_y = (state->src.y1 >> 16) & ~(format->vsub - 1);
@@ -235,17 +248,17 @@ static int sun8i_vi_layer_update_buffer(struct sun8i_mixer *mixer, int channel,
 		DRM_DEBUG_DRIVER("Layer %d. line width: %d bytes\n",
 				 i + 1, fb->pitches[i]);
 		regmap_write(mixer->engine.regs,
-			     SUN8I_MIXER_CHAN_VI_LAYER_PITCH(channel,
+			     SUN8I_MIXER_CHAN_VI_LAYER_PITCH(ch_base,
 							     overlay, i),
-	       fb->pitches[i]);
+			     fb->pitches[i]);
 
 		DRM_DEBUG_DRIVER("Setting %d. buffer address to %pad\n",
 				 i + 1, &paddr);
 
 		regmap_write(mixer->engine.regs,
-			     SUN8I_MIXER_CHAN_VI_LAYER_TOP_LADDR(channel,
+			     SUN8I_MIXER_CHAN_VI_LAYER_TOP_LADDR(ch_base,
 								 overlay, i),
-	       lower_32_bits(paddr));
+			     lower_32_bits(paddr));
 	}
 
 	return 0;
diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.h b/drivers/gpu/drm/sun4i/sun8i_vi_layer.h
index 6996627a0a76..46f0237c17bb 100644
--- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.h
+++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.h
@@ -12,17 +12,18 @@
 
 #include <drm/drm_plane.h>
 
-#define SUN8I_MIXER_CHAN_VI_LAYER_ATTR(ch, layer) \
-		(0x2000 + 0x1000 * (ch) + 0x30 * (layer) + 0x0)
-#define SUN8I_MIXER_CHAN_VI_LAYER_SIZE(ch, layer) \
-		(0x2000 + 0x1000 * (ch) + 0x30 * (layer) + 0x4)
-#define SUN8I_MIXER_CHAN_VI_LAYER_COORD(ch, layer) \
-		(0x2000 + 0x1000 * (ch) + 0x30 * (layer) + 0x8)
-#define SUN8I_MIXER_CHAN_VI_LAYER_PITCH(ch, layer, plane) \
-		(0x2000 + 0x1000 * (ch) + 0x30 * (layer) + 0xc + 4 * (plane))
-#define SUN8I_MIXER_CHAN_VI_LAYER_TOP_LADDR(ch, layer, plane) \
-		(0x2000 + 0x1000 * (ch) + 0x30 * (layer) + 0x18 + 4 * (plane))
-#define SUN8I_MIXER_CHAN_VI_OVL_SIZE(ch)	(0x2000 + 0x1000 * (ch) + 0xe8)
+#define SUN8I_MIXER_CHAN_VI_LAYER_ATTR(base, layer) \
+		((base) + 0x30 * (layer) + 0x0)
+#define SUN8I_MIXER_CHAN_VI_LAYER_SIZE(base, layer) \
+		((base) + 0x30 * (layer) + 0x4)
+#define SUN8I_MIXER_CHAN_VI_LAYER_COORD(base, layer) \
+		((base) + 0x30 * (layer) + 0x8)
+#define SUN8I_MIXER_CHAN_VI_LAYER_PITCH(base, layer, plane) \
+		((base) + 0x30 * (layer) + 0xc + 4 * (plane))
+#define SUN8I_MIXER_CHAN_VI_LAYER_TOP_LADDR(base, layer, plane) \
+		((base) + 0x30 * (layer) + 0x18 + 4 * (plane))
+#define SUN8I_MIXER_CHAN_VI_OVL_SIZE(base) \
+		((base) + 0xe8)
 
 #define SUN8I_MIXER_CHAN_VI_LAYER_ATTR_EN		BIT(0)
 /* RGB mode should be set for RGB formats and cleared for YCbCr */
diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c
index d3f1acb234b7..9f6834c143d7 100644
--- a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c
+++ b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c
@@ -833,6 +833,11 @@ static const u32 bicubic4coefftab32[480] = {
 	0x1012110d, 0x1012110d, 0x1013110c, 0x1013110c,
 };
 
+static u32 sun8i_vi_scaler_base(struct sun8i_mixer *mixer, int channel)
+{
+	return DE2_VI_SCALER_UNIT_BASE + DE2_VI_SCALER_UNIT_SIZE * channel;
+}
+
 static int sun8i_vi_scaler_coef_index(unsigned int step)
 {
 	unsigned int scale, int_part, float_part;
@@ -857,7 +862,7 @@ static int sun8i_vi_scaler_coef_index(unsigned int step)
 	}
 }
 
-static void sun8i_vi_scaler_set_coeff(struct regmap *map, int layer,
+static void sun8i_vi_scaler_set_coeff(struct regmap *map, u32 base,
 				      u32 hstep, u32 vstep,
 				      const struct drm_format_info *format)
 {
@@ -877,29 +882,31 @@ static void sun8i_vi_scaler_set_coeff(struct regmap *map, int layer,
 	offset = sun8i_vi_scaler_coef_index(hstep) *
 			SUN8I_VI_SCALER_COEFF_COUNT;
 	for (i = 0; i < SUN8I_VI_SCALER_COEFF_COUNT; i++) {
-		regmap_write(map, SUN8I_SCALER_VSU_YHCOEFF0(layer, i),
+		regmap_write(map, SUN8I_SCALER_VSU_YHCOEFF0(base, i),
 			     lan3coefftab32_left[offset + i]);
-		regmap_write(map, SUN8I_SCALER_VSU_YHCOEFF1(layer, i),
+		regmap_write(map, SUN8I_SCALER_VSU_YHCOEFF1(base, i),
 			     lan3coefftab32_right[offset + i]);
-		regmap_write(map, SUN8I_SCALER_VSU_CHCOEFF0(layer, i),
+		regmap_write(map, SUN8I_SCALER_VSU_CHCOEFF0(base, i),
 			     ch_left[offset + i]);
-		regmap_write(map, SUN8I_SCALER_VSU_CHCOEFF1(layer, i),
+		regmap_write(map, SUN8I_SCALER_VSU_CHCOEFF1(base, i),
 			     ch_right[offset + i]);
 	}
 
 	offset = sun8i_vi_scaler_coef_index(hstep) *
 			SUN8I_VI_SCALER_COEFF_COUNT;
 	for (i = 0; i < SUN8I_VI_SCALER_COEFF_COUNT; i++) {
-		regmap_write(map, SUN8I_SCALER_VSU_YVCOEFF(layer, i),
+		regmap_write(map, SUN8I_SCALER_VSU_YVCOEFF(base, i),
 			     lan2coefftab32[offset + i]);
-		regmap_write(map, SUN8I_SCALER_VSU_CVCOEFF(layer, i),
+		regmap_write(map, SUN8I_SCALER_VSU_CVCOEFF(base, i),
 			     cy[offset + i]);
 	}
 }
 
 void sun8i_vi_scaler_enable(struct sun8i_mixer *mixer, int layer, bool enable)
 {
-	u32 val;
+	u32 val, base;
+
+	base = sun8i_vi_scaler_base(mixer, layer);
 
 	if (enable)
 		val = SUN8I_SCALER_VSU_CTRL_EN |
@@ -907,7 +914,8 @@ void sun8i_vi_scaler_enable(struct sun8i_mixer *mixer, int layer, bool enable)
 	else
 		val = 0;
 
-	regmap_write(mixer->engine.regs, SUN8I_SCALER_VSU_CTRL(layer), val);
+	regmap_write(mixer->engine.regs,
+		     SUN8I_SCALER_VSU_CTRL(base), val);
 }
 
 void sun8i_vi_scaler_setup(struct sun8i_mixer *mixer, int layer,
@@ -917,6 +925,9 @@ void sun8i_vi_scaler_setup(struct sun8i_mixer *mixer, int layer,
 {
 	u32 chphase, cvphase;
 	u32 insize, outsize;
+	u32 base;
+
+	base = sun8i_vi_scaler_base(mixer, layer);
 
 	hphase <<= SUN8I_VI_SCALER_PHASE_FRAC - 16;
 	vphase <<= SUN8I_VI_SCALER_PHASE_FRAC - 16;
@@ -941,31 +952,31 @@ void sun8i_vi_scaler_setup(struct sun8i_mixer *mixer, int layer,
 	}
 
 	regmap_write(mixer->engine.regs,
-		     SUN8I_SCALER_VSU_OUTSIZE(layer), outsize);
+		     SUN8I_SCALER_VSU_OUTSIZE(base), outsize);
 	regmap_write(mixer->engine.regs,
-		     SUN8I_SCALER_VSU_YINSIZE(layer), insize);
+		     SUN8I_SCALER_VSU_YINSIZE(base), insize);
 	regmap_write(mixer->engine.regs,
-		     SUN8I_SCALER_VSU_YHSTEP(layer), hscale);
+		     SUN8I_SCALER_VSU_YHSTEP(base), hscale);
 	regmap_write(mixer->engine.regs,
-		     SUN8I_SCALER_VSU_YVSTEP(layer), vscale);
+		     SUN8I_SCALER_VSU_YVSTEP(base), vscale);
 	regmap_write(mixer->engine.regs,
-		     SUN8I_SCALER_VSU_YHPHASE(layer), hphase);
+		     SUN8I_SCALER_VSU_YHPHASE(base), hphase);
 	regmap_write(mixer->engine.regs,
-		     SUN8I_SCALER_VSU_YVPHASE(layer), vphase);
+		     SUN8I_SCALER_VSU_YVPHASE(base), vphase);
 	regmap_write(mixer->engine.regs,
-		     SUN8I_SCALER_VSU_CINSIZE(layer),
+		     SUN8I_SCALER_VSU_CINSIZE(base),
 		     SUN8I_VI_SCALER_SIZE(src_w / format->hsub,
 					  src_h / format->vsub));
 	regmap_write(mixer->engine.regs,
-		     SUN8I_SCALER_VSU_CHSTEP(layer),
+		     SUN8I_SCALER_VSU_CHSTEP(base),
 		     hscale / format->hsub);
 	regmap_write(mixer->engine.regs,
-		     SUN8I_SCALER_VSU_CVSTEP(layer),
+		     SUN8I_SCALER_VSU_CVSTEP(base),
 		     vscale / format->vsub);
 	regmap_write(mixer->engine.regs,
-		     SUN8I_SCALER_VSU_CHPHASE(layer), chphase);
+		     SUN8I_SCALER_VSU_CHPHASE(base), chphase);
 	regmap_write(mixer->engine.regs,
-		     SUN8I_SCALER_VSU_CVPHASE(layer), cvphase);
-	sun8i_vi_scaler_set_coeff(mixer->engine.regs, layer,
+		     SUN8I_SCALER_VSU_CVPHASE(base), cvphase);
+	sun8i_vi_scaler_set_coeff(mixer->engine.regs, base,
 				  hscale, vscale, format);
 }
diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h
index a595ab643a5a..f3de87122f07 100644
--- a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h
+++ b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h
@@ -12,6 +12,9 @@
 #include <drm/drm_fourcc.h>
 #include "sun8i_mixer.h"
 
+#define DE2_VI_SCALER_UNIT_BASE 0x20000
+#define DE2_VI_SCALER_UNIT_SIZE 0x20000
+
 /* this two macros assumes 16 fractional bits which is standard in DRM */
 #define SUN8I_VI_SCALER_SCALE_MIN		1
 #define SUN8I_VI_SCALER_SCALE_MAX		((1UL << 20) - 1)
@@ -21,30 +24,24 @@
 #define SUN8I_VI_SCALER_COEFF_COUNT		32
 #define SUN8I_VI_SCALER_SIZE(w, h)		(((h) - 1) << 16 | ((w) - 1))
 
-#define SUN8I_SCALER_VSU_CTRL(ch)	(0x20000 + 0x20000 * (ch) + 0x0)
-#define SUN8I_SCALER_VSU_OUTSIZE(ch)	(0x20000 + 0x20000 * (ch) + 0x40)
-#define SUN8I_SCALER_VSU_YINSIZE(ch)	(0x20000 + 0x20000 * (ch) + 0x80)
-#define SUN8I_SCALER_VSU_YHSTEP(ch)	(0x20000 + 0x20000 * (ch) + 0x88)
-#define SUN8I_SCALER_VSU_YVSTEP(ch)	(0x20000 + 0x20000 * (ch) + 0x8c)
-#define SUN8I_SCALER_VSU_YHPHASE(ch)	(0x20000 + 0x20000 * (ch) + 0x90)
-#define SUN8I_SCALER_VSU_YVPHASE(ch)	(0x20000 + 0x20000 * (ch) + 0x98)
-#define SUN8I_SCALER_VSU_CINSIZE(ch)	(0x20000 + 0x20000 * (ch) + 0xc0)
-#define SUN8I_SCALER_VSU_CHSTEP(ch)	(0x20000 + 0x20000 * (ch) + 0xc8)
-#define SUN8I_SCALER_VSU_CVSTEP(ch)	(0x20000 + 0x20000 * (ch) + 0xcc)
-#define SUN8I_SCALER_VSU_CHPHASE(ch)	(0x20000 + 0x20000 * (ch) + 0xd0)
-#define SUN8I_SCALER_VSU_CVPHASE(ch)	(0x20000 + 0x20000 * (ch) + 0xd8)
-#define SUN8I_SCALER_VSU_YHCOEFF0(ch, i) \
-	(0x20000 + 0x20000 * (ch) + 0x200 + 0x4 * (i))
-#define SUN8I_SCALER_VSU_YHCOEFF1(ch, i) \
-	(0x20000 + 0x20000 * (ch) + 0x300 + 0x4 * (i))
-#define SUN8I_SCALER_VSU_YVCOEFF(ch, i) \
-	(0x20000 + 0x20000 * (ch) + 0x400 + 0x4 * (i))
-#define SUN8I_SCALER_VSU_CHCOEFF0(ch, i) \
-	(0x20000 + 0x20000 * (ch) + 0x600 + 0x4 * (i))
-#define SUN8I_SCALER_VSU_CHCOEFF1(ch, i) \
-	(0x20000 + 0x20000 * (ch) + 0x700 + 0x4 * (i))
-#define SUN8I_SCALER_VSU_CVCOEFF(ch, i) \
-	(0x20000 + 0x20000 * (ch) + 0x800 + 0x4 * (i))
+#define SUN8I_SCALER_VSU_CTRL(base)		((base) + 0x0)
+#define SUN8I_SCALER_VSU_OUTSIZE(base)		((base) + 0x40)
+#define SUN8I_SCALER_VSU_YINSIZE(base)		((base) + 0x80)
+#define SUN8I_SCALER_VSU_YHSTEP(base)		((base) + 0x88)
+#define SUN8I_SCALER_VSU_YVSTEP(base)		((base) + 0x8c)
+#define SUN8I_SCALER_VSU_YHPHASE(base)		((base) + 0x90)
+#define SUN8I_SCALER_VSU_YVPHASE(base)		((base) + 0x98)
+#define SUN8I_SCALER_VSU_CINSIZE(base)		((base) + 0xc0)
+#define SUN8I_SCALER_VSU_CHSTEP(base)		((base) + 0xc8)
+#define SUN8I_SCALER_VSU_CVSTEP(base)		((base) + 0xcc)
+#define SUN8I_SCALER_VSU_CHPHASE(base)		((base) + 0xd0)
+#define SUN8I_SCALER_VSU_CVPHASE(base)		((base) + 0xd8)
+#define SUN8I_SCALER_VSU_YHCOEFF0(base, i)	((base) + 0x200 + 0x4 * (i))
+#define SUN8I_SCALER_VSU_YHCOEFF1(base, i)	((base) + 0x300 + 0x4 * (i))
+#define SUN8I_SCALER_VSU_YVCOEFF(base, i)	((base) + 0x400 + 0x4 * (i))
+#define SUN8I_SCALER_VSU_CHCOEFF0(base, i)	((base) + 0x600 + 0x4 * (i))
+#define SUN8I_SCALER_VSU_CHCOEFF1(base, i)	((base) + 0x700 + 0x4 * (i))
+#define SUN8I_SCALER_VSU_CVCOEFF(base, i)	((base) + 0x800 + 0x4 * (i))
 
 #define SUN8I_SCALER_VSU_CTRL_EN		BIT(0)
 #define SUN8I_SCALER_VSU_CTRL_COEFF_RDY		BIT(4)
-- 
2.19.1


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

* [PATCH v3 10/28] drm/sun4i: Fix DE2 mixer size
  2018-11-04 18:26 [PATCH v3 00/28] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (8 preceding siblings ...)
  2018-11-04 18:26 ` [PATCH v3 09/28] drm/sun4i: Rework DE2 register defines Jernej Skrabec
@ 2018-11-04 18:26 ` Jernej Skrabec
  2018-11-04 18:26 ` [PATCH v3 11/28] drm/sun4i: Disable unused DE2 sub-engines Jernej Skrabec
                   ` (18 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Jernej Skrabec @ 2018-11-04 18:26 UTC (permalink / raw)
  To: maxime.ripard, wens
  Cc: robh+dt, mturquette, sboyd, airlied, architt, a.hajda,
	Laurent.pinchart, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi, jernej.skrabec

DE2 mixer is always 0x6000 bytes in size on all known SoCs.

While at it, introduce a macro for that.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/gpu/drm/sun4i/sun8i_mixer.c | 2 +-
 drivers/gpu/drm/sun4i/sun8i_mixer.h | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c
index 6129c350f7bd..6769ec08c0d3 100644
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
@@ -460,7 +460,7 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master,
 	base = sun8i_blender_base(mixer);
 
 	/* Reset the registers */
-	for (i = 0x0; i < 0x20000; i += 4)
+	for (i = 0; i < DE2_MIXER_UNIT_SIZE; i += 4)
 		regmap_write(mixer->engine.regs, i, 0);
 
 	/* Enable the mixer */
diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h b/drivers/gpu/drm/sun4i/sun8i_mixer.h
index 025550a1f539..09e0f4428c1e 100644
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.h
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h
@@ -29,6 +29,8 @@
 
 #define SUN8I_MIXER_GLOBAL_DBUFF_ENABLE		BIT(0)
 
+#define DE2_MIXER_UNIT_SIZE			0x6000
+
 #define DE2_BLD_BASE				0x1000
 #define DE2_CH_BASE				0x2000
 #define DE2_CH_SIZE				0x1000
-- 
2.19.1


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

* [PATCH v3 11/28] drm/sun4i: Disable unused DE2 sub-engines
  2018-11-04 18:26 [PATCH v3 00/28] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (9 preceding siblings ...)
  2018-11-04 18:26 ` [PATCH v3 10/28] drm/sun4i: Fix DE2 mixer size Jernej Skrabec
@ 2018-11-04 18:26 ` Jernej Skrabec
  2018-11-04 18:26 ` [PATCH v3 12/28] drm/sun4i: Add basic support for DE3 Jernej Skrabec
                   ` (17 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Jernej Skrabec @ 2018-11-04 18:26 UTC (permalink / raw)
  To: maxime.ripard, wens
  Cc: robh+dt, mturquette, sboyd, airlied, architt, a.hajda,
	Laurent.pinchart, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi, jernej.skrabec

Some sub-engines are unused. Disable them explicitly.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/gpu/drm/sun4i/sun8i_mixer.c | 8 ++++++++
 drivers/gpu/drm/sun4i/sun8i_mixer.h | 4 ++--
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c
index 6769ec08c0d3..ec2c264f9481 100644
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
@@ -462,6 +462,14 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master,
 	/* Reset the registers */
 	for (i = 0; i < DE2_MIXER_UNIT_SIZE; i += 4)
 		regmap_write(mixer->engine.regs, i, 0);
+	/* Disable unused sub-engines */
+	regmap_write(mixer->engine.regs, SUN8I_MIXER_FCE_EN, 0);
+	regmap_write(mixer->engine.regs, SUN8I_MIXER_BWS_EN, 0);
+	regmap_write(mixer->engine.regs, SUN8I_MIXER_LTI_EN, 0);
+	regmap_write(mixer->engine.regs, SUN8I_MIXER_PEAK_EN, 0);
+	regmap_write(mixer->engine.regs, SUN8I_MIXER_ASE_EN, 0);
+	regmap_write(mixer->engine.regs, SUN8I_MIXER_FCC_EN, 0);
+	regmap_write(mixer->engine.regs, SUN8I_MIXER_DCSC_EN, 0);
 
 	/* Enable the mixer */
 	regmap_write(mixer->engine.regs, SUN8I_MIXER_GLOBAL_CTL,
diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h b/drivers/gpu/drm/sun4i/sun8i_mixer.h
index 09e0f4428c1e..a4175b993e0d 100644
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.h
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h
@@ -101,8 +101,8 @@
 #define SUN8I_MIXER_FBFMT_YUV411	14
 
 /*
- * These sub-engines are still unknown now, the EN registers are here only to
- * be used to disable these sub-engines.
+ * Sub-engines listed bellow are unused for now. The EN registers are here only
+ * to be used to disable these sub-engines.
  */
 #define SUN8I_MIXER_FCE_EN			0xa0000
 #define SUN8I_MIXER_BWS_EN			0xa2000
-- 
2.19.1


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

* [PATCH v3 12/28] drm/sun4i: Add basic support for DE3
  2018-11-04 18:26 [PATCH v3 00/28] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (10 preceding siblings ...)
  2018-11-04 18:26 ` [PATCH v3 11/28] drm/sun4i: Disable unused DE2 sub-engines Jernej Skrabec
@ 2018-11-04 18:26 ` Jernej Skrabec
  2018-11-04 18:26 ` [PATCH v3 13/28] drm/sun4i: Add support for H6 DE3 mixer 0 Jernej Skrabec
                   ` (16 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Jernej Skrabec @ 2018-11-04 18:26 UTC (permalink / raw)
  To: maxime.ripard, wens
  Cc: robh+dt, mturquette, sboyd, airlied, architt, a.hajda,
	Laurent.pinchart, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi, jernej.skrabec

Display Engine 3 is an upgrade of DE2 with new features like support for
10 bit color formats and support for AFBC.

Most of DE2 code works with DE3, except some small details.

Implement basic support for DE3. Support for 10 bit colort formats and
AFBC, among others missing features, will be added later.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/gpu/drm/sun4i/sun8i_csc.c       | 83 +++++++++++++++++++++++++
 drivers/gpu/drm/sun4i/sun8i_mixer.c     | 38 +++++++----
 drivers/gpu/drm/sun4i/sun8i_mixer.h     | 34 +++++++++-
 drivers/gpu/drm/sun4i/sun8i_ui_scaler.c | 10 ++-
 drivers/gpu/drm/sun4i/sun8i_ui_scaler.h |  1 +
 drivers/gpu/drm/sun4i/sun8i_vi_layer.c  |  8 +++
 drivers/gpu/drm/sun4i/sun8i_vi_layer.h  |  2 +
 drivers/gpu/drm/sun4i/sun8i_vi_scaler.c | 19 +++++-
 drivers/gpu/drm/sun4i/sun8i_vi_scaler.h | 23 +++++++
 9 files changed, 202 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.c b/drivers/gpu/drm/sun4i/sun8i_csc.c
index b14925b40ccf..e7608a72f26f 100644
--- a/drivers/gpu/drm/sun4i/sun8i_csc.c
+++ b/drivers/gpu/drm/sun4i/sun8i_csc.c
@@ -34,6 +34,41 @@ static const u32 yvu2rgb[] = {
 	0x000004A8, 0x00000000, 0x00000813, 0xFFFBAC4A,
 };
 
+/*
+ * DE3 has a bit different CSC units. Factors are in two's complement format.
+ * First three factors in a row are multiplication factors which have 17 bits
+ * for fractional part. Fourth value in a row is comprised of two factors.
+ * Upper 16 bits represents difference, which is subtracted from the input
+ * value before multiplication and lower 16 bits represents constant, which
+ * is addes at the end.
+ *
+ * x' = c00 * (x + d0) + c01 * (y + d1) + c02 * (z + d2) + const0
+ * y' = c10 * (x + d0) + c11 * (y + d1) + c12 * (z + d2) + const1
+ * z' = c20 * (x + d0) + c21 * (y + d1) + c22 * (z + d2) + const2
+ *
+ * Please note that above formula is true only for Blender CSC. Other DE3 CSC
+ * units takes only positive value for difference. From what can be deducted
+ * from BSP driver code, those units probably automatically assume that
+ * difference has to be subtracted.
+ *
+ * Layout of factors in table:
+ * c00 c01 c02 [d0 const0]
+ * c10 c11 c12 [d1 const1]
+ * c20 c21 c22 [d2 const2]
+ */
+
+static const u32 yuv2rgb_de3[] = {
+	0x0002542a, 0x00000000, 0x0003312a, 0xffc00000,
+	0x0002542a, 0xffff376b, 0xfffe5fc3, 0xfe000000,
+	0x0002542a, 0x000408d3, 0x00000000, 0xfe000000,
+};
+
+static const u32 yvu2rgb_de3[] = {
+	0x0002542a, 0x0003312a, 0x00000000, 0xffc00000,
+	0x0002542a, 0xfffe5fc3, 0xffff376b, 0xfe000000,
+	0x0002542a, 0x00000000, 0x000408d3, 0xfe000000,
+};
+
 static void sun8i_csc_set_coefficients(struct regmap *map, u32 base,
 				       enum sun8i_csc_mode mode)
 {
@@ -61,6 +96,28 @@ static void sun8i_csc_set_coefficients(struct regmap *map, u32 base,
 	}
 }
 
+static void sun8i_de3_ccsc_set_coefficients(struct regmap *map, int layer,
+					    enum sun8i_csc_mode mode)
+{
+	const u32 *table;
+	u32 base_reg;
+
+	switch (mode) {
+	case SUN8I_CSC_MODE_YUV2RGB:
+		table = yuv2rgb_de3;
+		break;
+	case SUN8I_CSC_MODE_YVU2RGB:
+		table = yvu2rgb_de3;
+		break;
+	default:
+		DRM_WARN("Wrong CSC mode specified.\n");
+		return;
+	}
+
+	base_reg = SUN50I_MIXER_BLEND_CSC_COEFF(DE3_BLD_BASE, layer, 0, 0);
+	regmap_bulk_write(map, base_reg, table, 12);
+}
+
 static void sun8i_csc_enable(struct regmap *map, u32 base, bool enable)
 {
 	u32 val;
@@ -73,11 +130,32 @@ static void sun8i_csc_enable(struct regmap *map, u32 base, bool enable)
 	regmap_update_bits(map, SUN8I_CSC_CTRL(base), SUN8I_CSC_CTRL_EN, val);
 }
 
+static void sun8i_de3_ccsc_enable(struct regmap *map, int layer, bool enable)
+{
+	u32 val, mask;
+
+	mask = SUN50I_MIXER_BLEND_CSC_CTL_EN(layer);
+
+	if (enable)
+		val = mask;
+	else
+		val = 0;
+
+	regmap_update_bits(map, SUN50I_MIXER_BLEND_CSC_CTL(DE3_BLD_BASE),
+			   mask, val);
+}
+
 void sun8i_csc_set_ccsc_coefficients(struct sun8i_mixer *mixer, int layer,
 				     enum sun8i_csc_mode mode)
 {
 	u32 base;
 
+	if (mixer->cfg->is_de3) {
+		sun8i_de3_ccsc_set_coefficients(mixer->engine.regs,
+						layer, mode);
+		return;
+	}
+
 	base = ccsc_base[mixer->cfg->ccsc][layer];
 
 	sun8i_csc_set_coefficients(mixer->engine.regs, base, mode);
@@ -87,6 +165,11 @@ void sun8i_csc_enable_ccsc(struct sun8i_mixer *mixer, int layer, bool enable)
 {
 	u32 base;
 
+	if (mixer->cfg->is_de3) {
+		sun8i_de3_ccsc_enable(mixer->engine.regs, layer, enable);
+		return;
+	}
+
 	base = ccsc_base[mixer->cfg->ccsc][layer];
 
 	sun8i_csc_enable(mixer->engine.regs, base, enable);
diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c
index ec2c264f9481..ca402cf0f5ba 100644
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
@@ -459,17 +459,33 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master,
 
 	base = sun8i_blender_base(mixer);
 
-	/* Reset the registers */
-	for (i = 0; i < DE2_MIXER_UNIT_SIZE; i += 4)
-		regmap_write(mixer->engine.regs, i, 0);
-	/* Disable unused sub-engines */
-	regmap_write(mixer->engine.regs, SUN8I_MIXER_FCE_EN, 0);
-	regmap_write(mixer->engine.regs, SUN8I_MIXER_BWS_EN, 0);
-	regmap_write(mixer->engine.regs, SUN8I_MIXER_LTI_EN, 0);
-	regmap_write(mixer->engine.regs, SUN8I_MIXER_PEAK_EN, 0);
-	regmap_write(mixer->engine.regs, SUN8I_MIXER_ASE_EN, 0);
-	regmap_write(mixer->engine.regs, SUN8I_MIXER_FCC_EN, 0);
-	regmap_write(mixer->engine.regs, SUN8I_MIXER_DCSC_EN, 0);
+	/* Reset registers and disable unused sub-engines */
+	if (mixer->cfg->is_de3) {
+		for (i = 0; i < DE3_MIXER_UNIT_SIZE; i += 4)
+			regmap_write(mixer->engine.regs, i, 0);
+
+		regmap_write(mixer->engine.regs, SUN50I_MIXER_FCE_EN, 0);
+		regmap_write(mixer->engine.regs, SUN50I_MIXER_PEAK_EN, 0);
+		regmap_write(mixer->engine.regs, SUN50I_MIXER_LCTI_EN, 0);
+		regmap_write(mixer->engine.regs, SUN50I_MIXER_BLS_EN, 0);
+		regmap_write(mixer->engine.regs, SUN50I_MIXER_FCC_EN, 0);
+		regmap_write(mixer->engine.regs, SUN50I_MIXER_DNS_EN, 0);
+		regmap_write(mixer->engine.regs, SUN50I_MIXER_DRC_EN, 0);
+		regmap_write(mixer->engine.regs, SUN50I_MIXER_FMT_EN, 0);
+		regmap_write(mixer->engine.regs, SUN50I_MIXER_CDC0_EN, 0);
+		regmap_write(mixer->engine.regs, SUN50I_MIXER_CDC1_EN, 0);
+	} else {
+		for (i = 0; i < DE2_MIXER_UNIT_SIZE; i += 4)
+			regmap_write(mixer->engine.regs, i, 0);
+
+		regmap_write(mixer->engine.regs, SUN8I_MIXER_FCE_EN, 0);
+		regmap_write(mixer->engine.regs, SUN8I_MIXER_BWS_EN, 0);
+		regmap_write(mixer->engine.regs, SUN8I_MIXER_LTI_EN, 0);
+		regmap_write(mixer->engine.regs, SUN8I_MIXER_PEAK_EN, 0);
+		regmap_write(mixer->engine.regs, SUN8I_MIXER_ASE_EN, 0);
+		regmap_write(mixer->engine.regs, SUN8I_MIXER_FCC_EN, 0);
+		regmap_write(mixer->engine.regs, SUN8I_MIXER_DCSC_EN, 0);
+	}
 
 	/* Enable the mixer */
 	regmap_write(mixer->engine.regs, SUN8I_MIXER_GLOBAL_CTL,
diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h b/drivers/gpu/drm/sun4i/sun8i_mixer.h
index a4175b993e0d..913d14ce68b0 100644
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.h
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h
@@ -30,11 +30,16 @@
 #define SUN8I_MIXER_GLOBAL_DBUFF_ENABLE		BIT(0)
 
 #define DE2_MIXER_UNIT_SIZE			0x6000
+#define DE3_MIXER_UNIT_SIZE			0x3000
 
 #define DE2_BLD_BASE				0x1000
 #define DE2_CH_BASE				0x2000
 #define DE2_CH_SIZE				0x1000
 
+#define DE3_BLD_BASE				0x0800
+#define DE3_CH_BASE				0x1000
+#define DE3_CH_SIZE				0x0800
+
 #define SUN8I_MIXER_BLEND_PIPE_CTL(base)	((base) + 0)
 #define SUN8I_MIXER_BLEND_ATTR_FCOLOR(base, x)	((base) + 0x4 + 0x10 * (x))
 #define SUN8I_MIXER_BLEND_ATTR_INSIZE(base, x)	((base) + 0x8 + 0x10 * (x))
@@ -49,10 +54,16 @@
 #define SUN8I_MIXER_BLEND_CK_MAX(base, x)	((base) + 0xc0 + 0x04 * (x))
 #define SUN8I_MIXER_BLEND_CK_MIN(base, x)	((base) + 0xe0 + 0x04 * (x))
 #define SUN8I_MIXER_BLEND_OUTCTL(base)		((base) + 0xfc)
+#define SUN50I_MIXER_BLEND_CSC_CTL(base)	((base) + 0x100)
+#define SUN50I_MIXER_BLEND_CSC_COEFF(base, layer, x, y) \
+	((base) + 0x110 + (layer) * 0x30 +  (x) * 0x10 + 4 * (y))
+#define SUN50I_MIXER_BLEND_CSC_CONST(base, layer, i) \
+	((base) + 0x110 + (layer) * 0x30 +  (i) * 0x10 + 0x0c)
 
 #define SUN8I_MIXER_BLEND_PIPE_CTL_EN_MSK	GENMASK(12, 8)
 #define SUN8I_MIXER_BLEND_PIPE_CTL_EN(pipe)	BIT(8 + pipe)
 #define SUN8I_MIXER_BLEND_PIPE_CTL_FC_EN(pipe)	BIT(pipe)
+
 /* colors are always in AARRGGBB format */
 #define SUN8I_MIXER_BLEND_COLOR_BLACK		0xff000000
 /* The following numbers are some still unknown magic numbers */
@@ -63,6 +74,9 @@
 
 #define SUN8I_MIXER_BLEND_OUTCTL_INTERLACED	BIT(1)
 
+#define SUN50I_MIXER_BLEND_CSC_CTL_EN(ch)	BIT(ch)
+#define SUN50I_MIXER_BLEND_CSC_CONST_VAL(d, c)	(((d) << 16) | ((c) & 0xffff))
+
 #define SUN8I_MIXER_FBFMT_ARGB8888	0
 #define SUN8I_MIXER_FBFMT_ABGR8888	1
 #define SUN8I_MIXER_FBFMT_RGBA8888	2
@@ -112,6 +126,17 @@
 #define SUN8I_MIXER_FCC_EN			0xaa000
 #define SUN8I_MIXER_DCSC_EN			0xb0000
 
+#define SUN50I_MIXER_FCE_EN			0x70000
+#define SUN50I_MIXER_PEAK_EN			0x70800
+#define SUN50I_MIXER_LCTI_EN			0x71000
+#define SUN50I_MIXER_BLS_EN			0x71800
+#define SUN50I_MIXER_FCC_EN			0x72000
+#define SUN50I_MIXER_DNS_EN			0x80000
+#define SUN50I_MIXER_DRC_EN			0xa0000
+#define SUN50I_MIXER_FMT_EN			0xa8000
+#define SUN50I_MIXER_CDC0_EN			0xd0000
+#define SUN50I_MIXER_CDC1_EN			0xd8000
+
 struct de2_fmt_info {
 	u32			drm_fmt;
 	u32			de2_fmt;
@@ -133,6 +158,7 @@ struct de2_fmt_info {
  *	are invalid.
  * @mod_rate: module clock rate that needs to be set in order to have
  *	a functional block.
+ * @is_de3: true, if this is next gen display engine 3.0, false otherwise.
  */
 struct sun8i_mixer_cfg {
 	int		vi_num;
@@ -140,6 +166,7 @@ struct sun8i_mixer_cfg {
 	int		scaler_mask;
 	int		ccsc;
 	unsigned long	mod_rate;
+	unsigned int	is_de3 : 1;
 };
 
 struct sun8i_mixer {
@@ -162,13 +189,16 @@ engine_to_sun8i_mixer(struct sunxi_engine *engine)
 static inline u32
 sun8i_blender_base(struct sun8i_mixer *mixer)
 {
-	return DE2_BLD_BASE;
+	return mixer->cfg->is_de3 ? DE3_BLD_BASE : DE2_BLD_BASE;
 }
 
 static inline u32
 sun8i_channel_base(struct sun8i_mixer *mixer, int channel)
 {
-	return DE2_CH_BASE + channel * DE2_CH_SIZE;
+	if (mixer->cfg->is_de3)
+		return DE3_CH_BASE + channel * DE3_CH_SIZE;
+	else
+		return DE2_CH_BASE + channel * DE2_CH_SIZE;
 }
 
 const struct de2_fmt_info *sun8i_mixer_format_info(u32 format);
diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_scaler.c b/drivers/gpu/drm/sun4i/sun8i_ui_scaler.c
index 698401ecb53d..ae0806bccac7 100644
--- a/drivers/gpu/drm/sun4i/sun8i_ui_scaler.c
+++ b/drivers/gpu/drm/sun4i/sun8i_ui_scaler.c
@@ -93,8 +93,14 @@ static u32 sun8i_ui_scaler_base(struct sun8i_mixer *mixer, int channel)
 {
 	int vi_num = mixer->cfg->vi_num;
 
-	return DE2_VI_SCALER_UNIT_BASE + DE2_VI_SCALER_UNIT_SIZE * vi_num +
-	       DE2_UI_SCALER_UNIT_SIZE * (channel - vi_num);
+	if (mixer->cfg->is_de3)
+		return DE3_VI_SCALER_UNIT_BASE +
+		       DE3_VI_SCALER_UNIT_SIZE * vi_num +
+		       DE3_UI_SCALER_UNIT_SIZE * (channel - vi_num);
+	else
+		return DE2_VI_SCALER_UNIT_BASE +
+		       DE2_VI_SCALER_UNIT_SIZE * vi_num +
+		       DE2_UI_SCALER_UNIT_SIZE * (channel - vi_num);
 }
 
 static int sun8i_ui_scaler_coef_index(unsigned int step)
diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_scaler.h b/drivers/gpu/drm/sun4i/sun8i_ui_scaler.h
index 6b4bc1ff3e2c..1ef4bd6f2718 100644
--- a/drivers/gpu/drm/sun4i/sun8i_ui_scaler.h
+++ b/drivers/gpu/drm/sun4i/sun8i_ui_scaler.h
@@ -12,6 +12,7 @@
 #include "sun8i_mixer.h"
 
 #define DE2_UI_SCALER_UNIT_SIZE 0x10000
+#define DE3_UI_SCALER_UNIT_SIZE 0x08000
 
 /* this two macros assumes 16 fractional bits which is standard in DRM */
 #define SUN8I_UI_SCALER_SCALE_MIN		1
diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
index 79811eae3735..4249edfb47ed 100644
--- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
@@ -202,6 +202,14 @@ static int sun8i_vi_layer_update_formats(struct sun8i_mixer *mixer, int channel,
 			   SUN8I_MIXER_CHAN_VI_LAYER_ATTR(ch_base, overlay),
 			   SUN8I_MIXER_CHAN_VI_LAYER_ATTR_RGB_MODE, val);
 
+	/* It seems that YUV formats use global alpha setting. */
+	if (mixer->cfg->is_de3)
+		regmap_update_bits(mixer->engine.regs,
+				   SUN8I_MIXER_CHAN_VI_LAYER_ATTR(ch_base,
+								  overlay),
+				   SUN50I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA_MASK,
+				   SUN50I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA(0xff));
+
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.h b/drivers/gpu/drm/sun4i/sun8i_vi_layer.h
index 46f0237c17bb..8a5e6d01c85d 100644
--- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.h
+++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.h
@@ -30,6 +30,8 @@
 #define SUN8I_MIXER_CHAN_VI_LAYER_ATTR_RGB_MODE		BIT(15)
 #define SUN8I_MIXER_CHAN_VI_LAYER_ATTR_FBFMT_OFFSET	8
 #define SUN8I_MIXER_CHAN_VI_LAYER_ATTR_FBFMT_MASK	GENMASK(12, 8)
+#define SUN50I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA_MASK	GENMASK(31, 24)
+#define SUN50I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA(x)	((x) << 24)
 
 struct sun8i_mixer;
 
diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c
index 9f6834c143d7..7ba75011adf9 100644
--- a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c
+++ b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c
@@ -835,7 +835,12 @@ static const u32 bicubic4coefftab32[480] = {
 
 static u32 sun8i_vi_scaler_base(struct sun8i_mixer *mixer, int channel)
 {
-	return DE2_VI_SCALER_UNIT_BASE + DE2_VI_SCALER_UNIT_SIZE * channel;
+	if (mixer->cfg->is_de3)
+		return DE3_VI_SCALER_UNIT_BASE +
+		       DE3_VI_SCALER_UNIT_SIZE * channel;
+	else
+		return DE2_VI_SCALER_UNIT_BASE +
+		       DE2_VI_SCALER_UNIT_SIZE * channel;
 }
 
 static int sun8i_vi_scaler_coef_index(unsigned int step)
@@ -951,6 +956,18 @@ void sun8i_vi_scaler_setup(struct sun8i_mixer *mixer, int layer,
 		cvphase = vphase;
 	}
 
+	if (mixer->cfg->is_de3) {
+		u32 val;
+
+		if (format->hsub == 1 && format->vsub == 1)
+			val = SUN50I_SCALER_VSU_SCALE_MODE_UI;
+		else
+			val = SUN50I_SCALER_VSU_SCALE_MODE_NORMAL;
+
+		regmap_write(mixer->engine.regs,
+			     SUN50I_SCALER_VSU_SCALE_MODE(base), val);
+	}
+
 	regmap_write(mixer->engine.regs,
 		     SUN8I_SCALER_VSU_OUTSIZE(base), outsize);
 	regmap_write(mixer->engine.regs,
diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h
index f3de87122f07..68f6593b369a 100644
--- a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h
+++ b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h
@@ -15,6 +15,9 @@
 #define DE2_VI_SCALER_UNIT_BASE 0x20000
 #define DE2_VI_SCALER_UNIT_SIZE 0x20000
 
+#define DE3_VI_SCALER_UNIT_BASE 0x20000
+#define DE3_VI_SCALER_UNIT_SIZE 0x08000
+
 /* this two macros assumes 16 fractional bits which is standard in DRM */
 #define SUN8I_VI_SCALER_SCALE_MIN		1
 #define SUN8I_VI_SCALER_SCALE_MAX		((1UL << 20) - 1)
@@ -25,6 +28,11 @@
 #define SUN8I_VI_SCALER_SIZE(w, h)		(((h) - 1) << 16 | ((w) - 1))
 
 #define SUN8I_SCALER_VSU_CTRL(base)		((base) + 0x0)
+#define SUN50I_SCALER_VSU_SCALE_MODE(base)		((base) + 0x10)
+#define SUN50I_SCALER_VSU_DIR_THR(base)		((base) + 0x20)
+#define SUN50I_SCALER_VSU_EDGE_THR(base)		((base) + 0x24)
+#define SUN50I_SCALER_VSU_EDSCL_CTRL(base)		((base) + 0x28)
+#define SUN50I_SCALER_VSU_ANGLE_THR(base)		((base) + 0x2c)
 #define SUN8I_SCALER_VSU_OUTSIZE(base)		((base) + 0x40)
 #define SUN8I_SCALER_VSU_YINSIZE(base)		((base) + 0x80)
 #define SUN8I_SCALER_VSU_YHSTEP(base)		((base) + 0x88)
@@ -46,6 +54,21 @@
 #define SUN8I_SCALER_VSU_CTRL_EN		BIT(0)
 #define SUN8I_SCALER_VSU_CTRL_COEFF_RDY		BIT(4)
 
+#define SUN50I_SCALER_VSU_SUB_ZERO_DIR_THR(x)	(((x) << 24) & 0xFF)
+#define SUN50I_SCALER_VSU_ZERO_DIR_THR(x)		(((x) << 16) & 0xFF)
+#define SUN50I_SCALER_VSU_HORZ_DIR_THR(x)		(((x) << 8) & 0xFF)
+#define SUN50I_SCALER_VSU_VERT_DIR_THR(x)		((x) & 0xFF)
+
+#define SUN50I_SCALER_VSU_SCALE_MODE_UI		0
+#define SUN50I_SCALER_VSU_SCALE_MODE_NORMAL	1
+#define SUN50I_SCALER_VSU_SCALE_MODE_ED_SCALE	2
+
+#define SUN50I_SCALER_VSU_EDGE_SHIFT(x)		(((x) << 16) & 0xF)
+#define SUN50I_SCALER_VSU_EDGE_OFFSET(x)		((x) & 0xFF)
+
+#define SUN50I_SCALER_VSU_ANGLE_SHIFT(x)		(((x) << 16) & 0xF)
+#define SUN50I_SCALER_VSU_ANGLE_OFFSET(x)		((x) & 0xFF)
+
 void sun8i_vi_scaler_enable(struct sun8i_mixer *mixer, int layer, bool enable);
 void sun8i_vi_scaler_setup(struct sun8i_mixer *mixer, int layer,
 			   u32 src_w, u32 src_h, u32 dst_w, u32 dst_h,
-- 
2.19.1


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

* [PATCH v3 13/28] drm/sun4i: Add support for H6 DE3 mixer 0
  2018-11-04 18:26 [PATCH v3 00/28] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (11 preceding siblings ...)
  2018-11-04 18:26 ` [PATCH v3 12/28] drm/sun4i: Add basic support for DE3 Jernej Skrabec
@ 2018-11-04 18:26 ` Jernej Skrabec
  2018-11-04 18:26 ` [PATCH v3 14/28] drm/bridge/synopsys: dw-hdmi: Enable workaround for v2.12a Jernej Skrabec
                   ` (15 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Jernej Skrabec @ 2018-11-04 18:26 UTC (permalink / raw)
  To: maxime.ripard, wens
  Cc: robh+dt, mturquette, sboyd, airlied, architt, a.hajda,
	Laurent.pinchart, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi, jernej.skrabec

Mixer 0 has 1 VI and 3 UI planes, scaler on all planes and can output
4K image @60Hz. It also support 10 bit colors, which are not yet
implemented.

Reviewed-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/gpu/drm/sun4i/sun8i_mixer.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c
index ca402cf0f5ba..44a9ba7d8433 100644
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
@@ -613,6 +613,15 @@ static const struct sun8i_mixer_cfg sun50i_a64_mixer1_cfg = {
 	.vi_num		= 1,
 };
 
+static const struct sun8i_mixer_cfg sun50i_h6_mixer0_cfg = {
+	.ccsc		= 0,
+	.is_de3		= true,
+	.mod_rate	= 600000000,
+	.scaler_mask	= 0xf,
+	.ui_num		= 3,
+	.vi_num		= 1,
+};
+
 static const struct of_device_id sun8i_mixer_of_table[] = {
 	{
 		.compatible = "allwinner,sun8i-a83t-de2-mixer-0",
@@ -646,6 +655,10 @@ static const struct of_device_id sun8i_mixer_of_table[] = {
 		.compatible = "allwinner,sun50i-a64-de2-mixer-1",
 		.data = &sun50i_a64_mixer1_cfg,
 	},
+	{
+		.compatible = "allwinner,sun50i-h6-de3-mixer-0",
+		.data = &sun50i_h6_mixer0_cfg,
+	},
 	{ }
 };
 MODULE_DEVICE_TABLE(of, sun8i_mixer_of_table);
-- 
2.19.1


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

* [PATCH v3 14/28] drm/bridge/synopsys: dw-hdmi: Enable workaround for v2.12a
  2018-11-04 18:26 [PATCH v3 00/28] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (12 preceding siblings ...)
  2018-11-04 18:26 ` [PATCH v3 13/28] drm/sun4i: Add support for H6 DE3 mixer 0 Jernej Skrabec
@ 2018-11-04 18:26 ` Jernej Skrabec
  2018-11-04 18:26 ` [PATCH v3 15/28] drm/sun4i: Not all DW HDMI controllers has scrambled addresses Jernej Skrabec
                   ` (14 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Jernej Skrabec @ 2018-11-04 18:26 UTC (permalink / raw)
  To: maxime.ripard, wens
  Cc: robh+dt, mturquette, sboyd, airlied, architt, a.hajda,
	Laurent.pinchart, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi, jernej.skrabec

It turns out that even new DW HDMI controllers exhibits same magenta
line issues as older versions.

Enable workaround for v2.12a.

Reviewed-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 5971976284bf..df1c7a2d6961 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -1664,6 +1664,7 @@ static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi)
 	case 0x131a:
 	case 0x132a:
 	case 0x201a:
+	case 0x212a:
 		count = 1;
 		break;
 	default:
-- 
2.19.1


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

* [PATCH v3 15/28] drm/sun4i: Not all DW HDMI controllers has scrambled addresses
  2018-11-04 18:26 [PATCH v3 00/28] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (13 preceding siblings ...)
  2018-11-04 18:26 ` [PATCH v3 14/28] drm/bridge/synopsys: dw-hdmi: Enable workaround for v2.12a Jernej Skrabec
@ 2018-11-04 18:26 ` Jernej Skrabec
  2018-11-04 18:26 ` [PATCH v3 16/28] drm/sun4i: dw-hdmi: Make mode_valid function configurable Jernej Skrabec
                   ` (13 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Jernej Skrabec @ 2018-11-04 18:26 UTC (permalink / raw)
  To: maxime.ripard, wens
  Cc: robh+dt, mturquette, sboyd, airlied, architt, a.hajda,
	Laurent.pinchart, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi, jernej.skrabec

Currently supported Allwinner SoCs with DW HDMI controller have
scrambled addresses and read lock. However, that is not true in general.
For example, A80 and H6 have normal addresses and normal read access.

Move code for unscrambling addresses and unlocking read access to it's
own function and call it from init function.

Reviewed-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c | 23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
index 471993097ced..365cb5a9fb77 100644
--- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
+++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
@@ -279,8 +279,21 @@ static const struct dw_hdmi_phy_ops sun8i_hdmi_phy_ops = {
 	.setup_hpd = &dw_hdmi_phy_setup_hpd,
 };
 
+static void sun8i_hdmi_phy_unlock(struct sun8i_hdmi_phy *phy)
+{
+	/* enable read access to HDMI controller */
+	regmap_write(phy->regs, SUN8I_HDMI_PHY_READ_EN_REG,
+		     SUN8I_HDMI_PHY_READ_EN_MAGIC);
+
+	/* unscramble register offsets */
+	regmap_write(phy->regs, SUN8I_HDMI_PHY_UNSCRAMBLE_REG,
+		     SUN8I_HDMI_PHY_UNSCRAMBLE_MAGIC);
+}
+
 static void sun8i_hdmi_phy_init_a83t(struct sun8i_hdmi_phy *phy)
 {
+	sun8i_hdmi_phy_unlock(phy);
+
 	regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_DBG_CTRL_REG,
 			   SUN8I_HDMI_PHY_DBG_CTRL_PX_LOCK,
 			   SUN8I_HDMI_PHY_DBG_CTRL_PX_LOCK);
@@ -298,6 +311,8 @@ static void sun8i_hdmi_phy_init_h3(struct sun8i_hdmi_phy *phy)
 {
 	unsigned int val;
 
+	sun8i_hdmi_phy_unlock(phy);
+
 	regmap_write(phy->regs, SUN8I_HDMI_PHY_ANA_CFG1_REG, 0);
 	regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_ANA_CFG1_REG,
 			   SUN8I_HDMI_PHY_ANA_CFG1_ENBI,
@@ -372,14 +387,6 @@ static void sun8i_hdmi_phy_init_h3(struct sun8i_hdmi_phy *phy)
 
 void sun8i_hdmi_phy_init(struct sun8i_hdmi_phy *phy)
 {
-	/* enable read access to HDMI controller */
-	regmap_write(phy->regs, SUN8I_HDMI_PHY_READ_EN_REG,
-		     SUN8I_HDMI_PHY_READ_EN_MAGIC);
-
-	/* unscramble register offsets */
-	regmap_write(phy->regs, SUN8I_HDMI_PHY_UNSCRAMBLE_REG,
-		     SUN8I_HDMI_PHY_UNSCRAMBLE_MAGIC);
-
 	phy->variant->phy_init(phy);
 }
 
-- 
2.19.1


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

* [PATCH v3 16/28] drm/sun4i: dw-hdmi: Make mode_valid function configurable
  2018-11-04 18:26 [PATCH v3 00/28] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (14 preceding siblings ...)
  2018-11-04 18:26 ` [PATCH v3 15/28] drm/sun4i: Not all DW HDMI controllers has scrambled addresses Jernej Skrabec
@ 2018-11-04 18:26 ` Jernej Skrabec
  2018-11-04 18:26 ` [PATCH v3 17/28] drm/sun4i: dw-hdmi: Add quirk for setting TMDS clock Jernej Skrabec
                   ` (12 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Jernej Skrabec @ 2018-11-04 18:26 UTC (permalink / raw)
  To: maxime.ripard, wens
  Cc: robh+dt, mturquette, sboyd, airlied, architt, a.hajda,
	Laurent.pinchart, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi, jernej.skrabec

Since it is not possible to access sun8i-dw-hdmi driver private data
inside mode_valid function, make it configurable. That way different
versions of HDMI controllers can set different function, depending on
it's limitations.

Reviewed-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c | 18 ++++++++++++++----
 drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h |  6 ++++++
 2 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
index ed2983770e9c..ec122136ee9d 100644
--- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
+++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
@@ -5,6 +5,7 @@
 
 #include <linux/component.h>
 #include <linux/module.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
 
 #include <drm/drm_of.h>
@@ -33,8 +34,8 @@ static const struct drm_encoder_funcs sun8i_dw_hdmi_encoder_funcs = {
 };
 
 static enum drm_mode_status
-sun8i_dw_hdmi_mode_valid(struct drm_connector *connector,
-			 const struct drm_display_mode *mode)
+sun8i_dw_hdmi_mode_valid_a83t(struct drm_connector *connector,
+			      const struct drm_display_mode *mode)
 {
 	if (mode->clock > 297000)
 		return MODE_CLOCK_HIGH;
@@ -102,6 +103,8 @@ static int sun8i_dw_hdmi_bind(struct device *dev, struct device *master,
 	hdmi->dev = &pdev->dev;
 	encoder = &hdmi->encoder;
 
+	hdmi->quirks = of_device_get_match_data(dev);
+
 	encoder->possible_crtcs =
 		sun8i_dw_hdmi_find_possible_crtcs(drm, dev->of_node);
 	/*
@@ -168,7 +171,7 @@ static int sun8i_dw_hdmi_bind(struct device *dev, struct device *master,
 
 	sun8i_hdmi_phy_init(hdmi->phy);
 
-	plat_data->mode_valid = &sun8i_dw_hdmi_mode_valid;
+	plat_data->mode_valid = hdmi->quirks->mode_valid;
 	plat_data->phy_ops = sun8i_hdmi_phy_get_ops();
 	plat_data->phy_name = "sun8i_dw_hdmi_phy";
 	plat_data->phy_data = hdmi->phy;
@@ -230,8 +233,15 @@ static int sun8i_dw_hdmi_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct sun8i_dw_hdmi_quirks sun8i_a83t_quirks = {
+	.mode_valid = sun8i_dw_hdmi_mode_valid_a83t,
+};
+
 static const struct of_device_id sun8i_dw_hdmi_dt_ids[] = {
-	{ .compatible = "allwinner,sun8i-a83t-dw-hdmi" },
+	{
+		.compatible = "allwinner,sun8i-a83t-dw-hdmi",
+		.data = &sun8i_a83t_quirks,
+	},
 	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, sun8i_dw_hdmi_dt_ids);
diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
index 7fdc1ecd2892..a645b8bc9f58 100644
--- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
+++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
@@ -170,6 +170,11 @@ struct sun8i_hdmi_phy {
 	struct sun8i_hdmi_phy_variant	*variant;
 };
 
+struct sun8i_dw_hdmi_quirks {
+	enum drm_mode_status (*mode_valid)(struct drm_connector *connector,
+					   const struct drm_display_mode *mode);
+};
+
 struct sun8i_dw_hdmi {
 	struct clk			*clk_tmds;
 	struct device			*dev;
@@ -178,6 +183,7 @@ struct sun8i_dw_hdmi {
 	struct sun8i_hdmi_phy		*phy;
 	struct dw_hdmi_plat_data	plat_data;
 	struct regulator		*regulator;
+	const struct sun8i_dw_hdmi_quirks *quirks;
 	struct reset_control		*rst_ctrl;
 };
 
-- 
2.19.1


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

* [PATCH v3 17/28] drm/sun4i: dw-hdmi: Add quirk for setting TMDS clock
  2018-11-04 18:26 [PATCH v3 00/28] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (15 preceding siblings ...)
  2018-11-04 18:26 ` [PATCH v3 16/28] drm/sun4i: dw-hdmi: Make mode_valid function configurable Jernej Skrabec
@ 2018-11-04 18:26 ` Jernej Skrabec
  2018-11-04 18:26 ` [PATCH v3 18/28] dt-bindings: display: sunxi: add DT binding for Allwinner H6 DW HDMI Jernej Skrabec
                   ` (11 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Jernej Skrabec @ 2018-11-04 18:26 UTC (permalink / raw)
  To: maxime.ripard, wens
  Cc: robh+dt, mturquette, sboyd, airlied, architt, a.hajda,
	Laurent.pinchart, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi, jernej.skrabec

It turns out that H6 HDMI BSP kernel driver doesn't change TMDS rate at
all. At this point it is not clear whether it is just not necessary or
it would cause some kind of issues.

Add a quirk for it.

Acked-by: Maxime Ripard <maxime.ripard@bootlin.com>
Reviewed-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c | 4 +++-
 drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h | 1 +
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
index ec122136ee9d..99b878e380e1 100644
--- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
+++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
@@ -21,7 +21,8 @@ static void sun8i_dw_hdmi_encoder_mode_set(struct drm_encoder *encoder,
 {
 	struct sun8i_dw_hdmi *hdmi = encoder_to_sun8i_dw_hdmi(encoder);
 
-	clk_set_rate(hdmi->clk_tmds, mode->crtc_clock * 1000);
+	if (hdmi->quirks->set_rate)
+		clk_set_rate(hdmi->clk_tmds, mode->crtc_clock * 1000);
 }
 
 static const struct drm_encoder_helper_funcs
@@ -235,6 +236,7 @@ static int sun8i_dw_hdmi_remove(struct platform_device *pdev)
 
 static const struct sun8i_dw_hdmi_quirks sun8i_a83t_quirks = {
 	.mode_valid = sun8i_dw_hdmi_mode_valid_a83t,
+	.set_rate = true,
 };
 
 static const struct of_device_id sun8i_dw_hdmi_dt_ids[] = {
diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
index a645b8bc9f58..49c9e80c46ea 100644
--- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
+++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
@@ -173,6 +173,7 @@ struct sun8i_hdmi_phy {
 struct sun8i_dw_hdmi_quirks {
 	enum drm_mode_status (*mode_valid)(struct drm_connector *connector,
 					   const struct drm_display_mode *mode);
+	unsigned int set_rate : 1;
 };
 
 struct sun8i_dw_hdmi {
-- 
2.19.1


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

* [PATCH v3 18/28] dt-bindings: display: sunxi: add DT binding for Allwinner H6 DW HDMI
  2018-11-04 18:26 [PATCH v3 00/28] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (16 preceding siblings ...)
  2018-11-04 18:26 ` [PATCH v3 17/28] drm/sun4i: dw-hdmi: Add quirk for setting TMDS clock Jernej Skrabec
@ 2018-11-04 18:26 ` Jernej Skrabec
  2018-11-04 18:26 ` [PATCH v3 19/28] drm/sun4i: Add support for H6 DW HDMI controller Jernej Skrabec
                   ` (10 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Jernej Skrabec @ 2018-11-04 18:26 UTC (permalink / raw)
  To: maxime.ripard, wens
  Cc: robh+dt, mturquette, sboyd, airlied, architt, a.hajda,
	Laurent.pinchart, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi, jernej.skrabec, Icenowy Zheng

From: Icenowy Zheng <icenowy@aosc.io>

The Allwinner H6 SoC uses a v2.12a DesignWare HDMI controller, with
dedicated CEC and HDCP clocks added; the PHY connected is a standard
DesignWare HDMI PHY.

Add binding for it.

Reviewed-by: Rob Herring <robh@kernel.org>
Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
[added HDCP clock and reset]
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 .../devicetree/bindings/display/sunxi/sun4i-drm.txt   | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
index 62c83b351344..478b288eebd9 100644
--- a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
+++ b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
@@ -79,6 +79,7 @@ Required properties:
   - compatible: value must be one of:
     * "allwinner,sun8i-a83t-dw-hdmi"
     * "allwinner,sun50i-a64-dw-hdmi", "allwinner,sun8i-a83t-dw-hdmi"
+    * "allwinner,sun50i-h6-dw-hdmi"
   - reg: base address and size of memory-mapped region
   - reg-io-width: See dw_hdmi.txt. Shall be 1.
   - interrupts: HDMI interrupt number
@@ -86,9 +87,14 @@ Required properties:
     * iahb: the HDMI bus clock
     * isfr: the HDMI register clock
     * tmds: TMDS clock
+    * cec: HDMI CEC clock (H6 only)
+    * hdcp: HDCP clock (H6 only)
+    * hdcp-bus: HDCP bus clock (H6 only)
   - clock-names: the clock names mentioned above
-  - resets: phandle to the reset controller
-  - reset-names: must be "ctrl"
+  - resets:
+    * ctrl: HDMI controller reset
+    * hdcp: HDCP reset (H6 only)
+  - reset-names: reset names mentioned above
   - phys: phandle to the DWC HDMI PHY
   - phy-names: must be "phy"
 
@@ -109,6 +115,7 @@ Required properties:
     * allwinner,sun8i-h3-hdmi-phy
     * allwinner,sun8i-r40-hdmi-phy
     * allwinner,sun50i-a64-hdmi-phy
+    * allwinner,sun50i-h6-hdmi-phy
   - reg: base address and size of memory-mapped region
   - clocks: phandles to the clocks feeding the HDMI PHY
     * bus: the HDMI PHY interface clock
-- 
2.19.1


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

* [PATCH v3 19/28] drm/sun4i: Add support for H6 DW HDMI controller
  2018-11-04 18:26 [PATCH v3 00/28] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (17 preceding siblings ...)
  2018-11-04 18:26 ` [PATCH v3 18/28] dt-bindings: display: sunxi: add DT binding for Allwinner H6 DW HDMI Jernej Skrabec
@ 2018-11-04 18:26 ` Jernej Skrabec
  2018-11-04 18:26 ` [PATCH v3 20/28] drm/sun4i: dw-hdmi-phy: Reorder quirks by family Jernej Skrabec
                   ` (9 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Jernej Skrabec @ 2018-11-04 18:26 UTC (permalink / raw)
  To: maxime.ripard, wens
  Cc: robh+dt, mturquette, sboyd, airlied, architt, a.hajda,
	Laurent.pinchart, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi, jernej.skrabec

H6 has DW HDMI 2.0b controller v2.12a.

It supports 4K at 60 Hz and HDCP 2.2.

Reviewed-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
index 99b878e380e1..445cca8d9a26 100644
--- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
+++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
@@ -44,6 +44,17 @@ sun8i_dw_hdmi_mode_valid_a83t(struct drm_connector *connector,
 	return MODE_OK;
 }
 
+static enum drm_mode_status
+sun8i_dw_hdmi_mode_valid_h6(struct drm_connector *connector,
+			    const struct drm_display_mode *mode)
+{
+	/* This is max for HDMI 2.0b (4K@60Hz) */
+	if (mode->clock > 594000)
+		return MODE_CLOCK_HIGH;
+
+	return MODE_OK;
+}
+
 static bool sun8i_dw_hdmi_node_is_tcon_top(struct device_node *node)
 {
 	return IS_ENABLED(CONFIG_DRM_SUN8I_TCON_TOP) &&
@@ -239,11 +250,19 @@ static const struct sun8i_dw_hdmi_quirks sun8i_a83t_quirks = {
 	.set_rate = true,
 };
 
+static const struct sun8i_dw_hdmi_quirks sun50i_h6_quirks = {
+	.mode_valid = sun8i_dw_hdmi_mode_valid_h6,
+};
+
 static const struct of_device_id sun8i_dw_hdmi_dt_ids[] = {
 	{
 		.compatible = "allwinner,sun8i-a83t-dw-hdmi",
 		.data = &sun8i_a83t_quirks,
 	},
+	{
+		.compatible = "allwinner,sun50i-h6-dw-hdmi",
+		.data = &sun50i_h6_quirks,
+	},
 	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, sun8i_dw_hdmi_dt_ids);
-- 
2.19.1


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

* [PATCH v3 20/28] drm/sun4i: dw-hdmi-phy: Reorder quirks by family
  2018-11-04 18:26 [PATCH v3 00/28] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (18 preceding siblings ...)
  2018-11-04 18:26 ` [PATCH v3 19/28] drm/sun4i: Add support for H6 DW HDMI controller Jernej Skrabec
@ 2018-11-04 18:26 ` Jernej Skrabec
  2018-11-04 18:26 ` [PATCH v3 21/28] drm/sun4i: Add support for Synopsys HDMI PHY Jernej Skrabec
                   ` (8 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Jernej Skrabec @ 2018-11-04 18:26 UTC (permalink / raw)
  To: maxime.ripard, wens
  Cc: robh+dt, mturquette, sboyd, airlied, architt, a.hajda,
	Laurent.pinchart, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi, jernej.skrabec

Currently, quirks and compatibles are sorted alphabetically. However,
they should be sorted by family release date and then alphabetically.

Fix that by moving A64 quirks and compatible to bottom. No functional
change is made.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
index 365cb5a9fb77..adc3ba7df7e3 100644
--- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
+++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
@@ -403,13 +403,6 @@ static struct regmap_config sun8i_hdmi_phy_regmap_config = {
 	.name		= "phy"
 };
 
-static const struct sun8i_hdmi_phy_variant sun50i_a64_hdmi_phy = {
-	.has_phy_clk = true,
-	.phy_init = &sun8i_hdmi_phy_init_h3,
-	.phy_disable = &sun8i_hdmi_phy_disable_h3,
-	.phy_config = &sun8i_hdmi_phy_config_h3,
-};
-
 static const struct sun8i_hdmi_phy_variant sun8i_a83t_hdmi_phy = {
 	.phy_init = &sun8i_hdmi_phy_init_a83t,
 	.phy_disable = &sun8i_hdmi_phy_disable_a83t,
@@ -431,11 +424,14 @@ static const struct sun8i_hdmi_phy_variant sun8i_r40_hdmi_phy = {
 	.phy_config = &sun8i_hdmi_phy_config_h3,
 };
 
+static const struct sun8i_hdmi_phy_variant sun50i_a64_hdmi_phy = {
+	.has_phy_clk = true,
+	.phy_init = &sun8i_hdmi_phy_init_h3,
+	.phy_disable = &sun8i_hdmi_phy_disable_h3,
+	.phy_config = &sun8i_hdmi_phy_config_h3,
+};
+
 static const struct of_device_id sun8i_hdmi_phy_of_table[] = {
-	{
-		.compatible = "allwinner,sun50i-a64-hdmi-phy",
-		.data = &sun50i_a64_hdmi_phy,
-	},
 	{
 		.compatible = "allwinner,sun8i-a83t-hdmi-phy",
 		.data = &sun8i_a83t_hdmi_phy,
@@ -448,6 +444,10 @@ static const struct of_device_id sun8i_hdmi_phy_of_table[] = {
 		.compatible = "allwinner,sun8i-r40-hdmi-phy",
 		.data = &sun8i_r40_hdmi_phy,
 	},
+	{
+		.compatible = "allwinner,sun50i-a64-hdmi-phy",
+		.data = &sun50i_a64_hdmi_phy,
+	},
 	{ /* sentinel */ }
 };
 
-- 
2.19.1


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

* [PATCH v3 21/28] drm/sun4i: Add support for Synopsys HDMI PHY
  2018-11-04 18:26 [PATCH v3 00/28] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (19 preceding siblings ...)
  2018-11-04 18:26 ` [PATCH v3 20/28] drm/sun4i: dw-hdmi-phy: Reorder quirks by family Jernej Skrabec
@ 2018-11-04 18:26 ` Jernej Skrabec
  2018-11-04 18:26 ` [PATCH v3 22/28] drm/sun4i: Add support for H6 " Jernej Skrabec
                   ` (7 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Jernej Skrabec @ 2018-11-04 18:26 UTC (permalink / raw)
  To: maxime.ripard, wens
  Cc: robh+dt, mturquette, sboyd, airlied, architt, a.hajda,
	Laurent.pinchart, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi, jernej.skrabec

Currently sun8i-hdmi-phy driver supports only custom PHYs connected to
DW HDMI controller. Since newest Allwinner SoCs have unmodified Synopsys
PHY, driver has to be reorganized to support them.

Variant structure is expanded to allow differentiation between custom
and Sysnopsys PHYs and to hold Synopsys PHY settings.

Since DW HDMI bridge platform data has different fields for custom and
Sysnopsys PHY, function sun8i_hdmi_phy_get_ops() is replaced with
sun8i_hdmi_phy_set_ops().

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c  |  4 +---
 drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h  |  7 ++++++-
 drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c | 19 +++++++++++++++++--
 3 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
index 445cca8d9a26..dc47720c99ba 100644
--- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
+++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
@@ -184,9 +184,7 @@ static int sun8i_dw_hdmi_bind(struct device *dev, struct device *master,
 	sun8i_hdmi_phy_init(hdmi->phy);
 
 	plat_data->mode_valid = hdmi->quirks->mode_valid;
-	plat_data->phy_ops = sun8i_hdmi_phy_get_ops();
-	plat_data->phy_name = "sun8i_dw_hdmi_phy";
-	plat_data->phy_data = hdmi->phy;
+	sun8i_hdmi_phy_set_ops(hdmi->phy, plat_data);
 
 	platform_set_drvdata(pdev, hdmi);
 
diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
index 49c9e80c46ea..720c5aa8adc1 100644
--- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
+++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
@@ -150,6 +150,10 @@ struct sun8i_hdmi_phy;
 struct sun8i_hdmi_phy_variant {
 	bool has_phy_clk;
 	bool has_second_pll;
+	unsigned int is_custom_phy : 1;
+	const struct dw_hdmi_curr_ctrl *cur_ctr;
+	const struct dw_hdmi_mpll_config *mpll_cfg;
+	const struct dw_hdmi_phy_config *phy_cfg;
 	void (*phy_init)(struct sun8i_hdmi_phy *phy);
 	void (*phy_disable)(struct dw_hdmi *hdmi,
 			    struct sun8i_hdmi_phy *phy);
@@ -198,7 +202,8 @@ int sun8i_hdmi_phy_probe(struct sun8i_dw_hdmi *hdmi, struct device_node *node);
 void sun8i_hdmi_phy_remove(struct sun8i_dw_hdmi *hdmi);
 
 void sun8i_hdmi_phy_init(struct sun8i_hdmi_phy *phy);
-const struct dw_hdmi_phy_ops *sun8i_hdmi_phy_get_ops(void);
+void sun8i_hdmi_phy_set_ops(struct sun8i_hdmi_phy *phy,
+			    struct dw_hdmi_plat_data *plat_data);
 
 int sun8i_phy_clk_create(struct sun8i_hdmi_phy *phy, struct device *dev,
 			 bool second_parent);
diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
index adc3ba7df7e3..635825b55648 100644
--- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
+++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
@@ -390,9 +390,20 @@ void sun8i_hdmi_phy_init(struct sun8i_hdmi_phy *phy)
 	phy->variant->phy_init(phy);
 }
 
-const struct dw_hdmi_phy_ops *sun8i_hdmi_phy_get_ops(void)
+void sun8i_hdmi_phy_set_ops(struct sun8i_hdmi_phy *phy,
+			    struct dw_hdmi_plat_data *plat_data)
 {
-	return &sun8i_hdmi_phy_ops;
+	struct sun8i_hdmi_phy_variant *variant = phy->variant;
+
+	if (variant->is_custom_phy) {
+		plat_data->phy_ops = &sun8i_hdmi_phy_ops;
+		plat_data->phy_name = "sun8i_dw_hdmi_phy";
+		plat_data->phy_data = phy;
+	} else {
+		plat_data->mpll_cfg = variant->mpll_cfg;
+		plat_data->cur_ctr = variant->cur_ctr;
+		plat_data->phy_config = variant->phy_cfg;
+	}
 }
 
 static struct regmap_config sun8i_hdmi_phy_regmap_config = {
@@ -404,6 +415,7 @@ static struct regmap_config sun8i_hdmi_phy_regmap_config = {
 };
 
 static const struct sun8i_hdmi_phy_variant sun8i_a83t_hdmi_phy = {
+	.is_custom_phy = true,
 	.phy_init = &sun8i_hdmi_phy_init_a83t,
 	.phy_disable = &sun8i_hdmi_phy_disable_a83t,
 	.phy_config = &sun8i_hdmi_phy_config_a83t,
@@ -411,6 +423,7 @@ static const struct sun8i_hdmi_phy_variant sun8i_a83t_hdmi_phy = {
 
 static const struct sun8i_hdmi_phy_variant sun8i_h3_hdmi_phy = {
 	.has_phy_clk = true,
+	.is_custom_phy = true,
 	.phy_init = &sun8i_hdmi_phy_init_h3,
 	.phy_disable = &sun8i_hdmi_phy_disable_h3,
 	.phy_config = &sun8i_hdmi_phy_config_h3,
@@ -419,6 +432,7 @@ static const struct sun8i_hdmi_phy_variant sun8i_h3_hdmi_phy = {
 static const struct sun8i_hdmi_phy_variant sun8i_r40_hdmi_phy = {
 	.has_phy_clk = true,
 	.has_second_pll = true,
+	.is_custom_phy = true,
 	.phy_init = &sun8i_hdmi_phy_init_h3,
 	.phy_disable = &sun8i_hdmi_phy_disable_h3,
 	.phy_config = &sun8i_hdmi_phy_config_h3,
@@ -426,6 +440,7 @@ static const struct sun8i_hdmi_phy_variant sun8i_r40_hdmi_phy = {
 
 static const struct sun8i_hdmi_phy_variant sun50i_a64_hdmi_phy = {
 	.has_phy_clk = true,
+	.is_custom_phy = true,
 	.phy_init = &sun8i_hdmi_phy_init_h3,
 	.phy_disable = &sun8i_hdmi_phy_disable_h3,
 	.phy_config = &sun8i_hdmi_phy_config_h3,
-- 
2.19.1


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

* [PATCH v3 22/28] drm/sun4i: Add support for H6 HDMI PHY
  2018-11-04 18:26 [PATCH v3 00/28] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (20 preceding siblings ...)
  2018-11-04 18:26 ` [PATCH v3 21/28] drm/sun4i: Add support for Synopsys HDMI PHY Jernej Skrabec
@ 2018-11-04 18:26 ` " Jernej Skrabec
  2018-11-04 18:27 ` [PATCH v3 23/28] drm/sun4i: Initialize registers in tcon-top driver Jernej Skrabec
                   ` (6 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Jernej Skrabec @ 2018-11-04 18:26 UTC (permalink / raw)
  To: maxime.ripard, wens
  Cc: robh+dt, mturquette, sboyd, airlied, architt, a.hajda,
	Laurent.pinchart, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi, jernej.skrabec

H6 has Synopsys DWC HDMI 2.0 TX PHY.

There is no freely available documentation for it, only code found in
BSP kernel. However, judging by the code, PHY is very similar to older
Synopsys HDMI PHY described in i.MX6 documentation. Most registers seem
to be the same.

According to i.MX6 documentation, mpll settings are based on pixel clock
and are not specific to each SoC. Because of that, mpll table in this
commit is based on that documentation and not on BSP code. Other PHY
settings were derived from BSP PHY driver code.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c | 137 +++++++++++++++++++++++++
 1 file changed, 137 insertions(+)

diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
index 635825b55648..66ea3a902e36 100644
--- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
+++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
@@ -14,6 +14,122 @@
  */
 #define I2C_ADDR	0x69
 
+static const struct dw_hdmi_mpll_config sun50i_h6_mpll_cfg[] = {
+	{
+		30666000, {
+			{ 0x00b3, 0x0000 },
+			{ 0x2153, 0x0000 },
+			{ 0x40f3, 0x0000 },
+		},
+	},  {
+		36800000, {
+			{ 0x00b3, 0x0000 },
+			{ 0x2153, 0x0000 },
+			{ 0x40a2, 0x0001 },
+		},
+	},  {
+		46000000, {
+			{ 0x00b3, 0x0000 },
+			{ 0x2142, 0x0001 },
+			{ 0x40a2, 0x0001 },
+		},
+	},  {
+		61333000, {
+			{ 0x0072, 0x0001 },
+			{ 0x2142, 0x0001 },
+			{ 0x40a2, 0x0001 },
+		},
+	},  {
+		73600000, {
+			{ 0x0072, 0x0001 },
+			{ 0x2142, 0x0001 },
+			{ 0x4061, 0x0002 },
+		},
+	},  {
+		92000000, {
+			{ 0x0072, 0x0001 },
+			{ 0x2145, 0x0002 },
+			{ 0x4061, 0x0002 },
+		},
+	},  {
+		122666000, {
+			{ 0x0051, 0x0002 },
+			{ 0x2145, 0x0002 },
+			{ 0x4061, 0x0002 },
+		},
+	},  {
+		147200000, {
+			{ 0x0051, 0x0002 },
+			{ 0x2145, 0x0002 },
+			{ 0x4064, 0x0003 },
+		},
+	},  {
+		184000000, {
+			{ 0x0051, 0x0002 },
+			{ 0x214c, 0x0003 },
+			{ 0x4064, 0x0003 },
+		},
+	},  {
+		226666000, {
+			{ 0x0040, 0x0003 },
+			{ 0x214c, 0x0003 },
+			{ 0x4064, 0x0003 },
+		},
+	},  {
+		272000000, {
+			{ 0x0040, 0x0003 },
+			{ 0x214c, 0x0003 },
+			{ 0x5a64, 0x0003 },
+		},
+	},  {
+		340000000, {
+			{ 0x0040, 0x0003 },
+			{ 0x3b4c, 0x0003 },
+			{ 0x5a64, 0x0003 },
+		},
+	},  {
+		594000000, {
+			{ 0x1a40, 0x0003 },
+			{ 0x3b4c, 0x0003 },
+			{ 0x5a64, 0x0003 },
+		},
+	}, {
+		~0UL, {
+			{ 0x0000, 0x0000 },
+			{ 0x0000, 0x0000 },
+			{ 0x0000, 0x0000 },
+		},
+	}
+};
+
+static const struct dw_hdmi_curr_ctrl sun50i_h6_cur_ctr[] = {
+	/* pixelclk    bpp8    bpp10   bpp12 */
+	{ 25175000,  { 0x0000, 0x0000, 0x0000 }, },
+	{ 27000000,  { 0x0012, 0x0000, 0x0000 }, },
+	{ 59400000,  { 0x0008, 0x0008, 0x0008 }, },
+	{ 72000000,  { 0x0008, 0x0008, 0x001b }, },
+	{ 74250000,  { 0x0013, 0x0013, 0x0013 }, },
+	{ 90000000,  { 0x0008, 0x001a, 0x001b }, },
+	{ 118800000, { 0x001b, 0x001a, 0x001b }, },
+	{ 144000000, { 0x001b, 0x001a, 0x0034 }, },
+	{ 180000000, { 0x001b, 0x0033, 0x0034 }, },
+	{ 216000000, { 0x0036, 0x0033, 0x0034 }, },
+	{ 237600000, { 0x0036, 0x0033, 0x001b }, },
+	{ 288000000, { 0x0036, 0x001b, 0x001b }, },
+	{ 297000000, { 0x0019, 0x001b, 0x0019 }, },
+	{ 330000000, { 0x0036, 0x001b, 0x001b }, },
+	{ 594000000, { 0x003f, 0x001b, 0x001b }, },
+	{ ~0UL,      { 0x0000, 0x0000, 0x0000 }, }
+};
+
+static const struct dw_hdmi_phy_config sun50i_h6_phy_config[] = {
+	/*pixelclk   symbol   term   vlev*/
+	{ 74250000,  0x8009, 0x0004, 0x0232},
+	{ 148500000, 0x8029, 0x0004, 0x0273},
+	{ 594000000, 0x8039, 0x0004, 0x014a},
+	{ ~0UL,	     0x0000, 0x0000, 0x0000}
+};
+
 static int sun8i_hdmi_phy_config_a83t(struct dw_hdmi *hdmi,
 				      struct sun8i_hdmi_phy *phy,
 				      unsigned int clk_rate)
@@ -290,6 +406,16 @@ static void sun8i_hdmi_phy_unlock(struct sun8i_hdmi_phy *phy)
 		     SUN8I_HDMI_PHY_UNSCRAMBLE_MAGIC);
 }
 
+static void sun50i_hdmi_phy_init_h6(struct sun8i_hdmi_phy *phy)
+{
+	regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_REXT_CTRL_REG,
+			   SUN8I_HDMI_PHY_REXT_CTRL_REXT_EN,
+			   SUN8I_HDMI_PHY_REXT_CTRL_REXT_EN);
+
+	regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_REXT_CTRL_REG,
+			   0xffff0000, 0x80c00000);
+}
+
 static void sun8i_hdmi_phy_init_a83t(struct sun8i_hdmi_phy *phy)
 {
 	sun8i_hdmi_phy_unlock(phy);
@@ -446,6 +572,13 @@ static const struct sun8i_hdmi_phy_variant sun50i_a64_hdmi_phy = {
 	.phy_config = &sun8i_hdmi_phy_config_h3,
 };
 
+static const struct sun8i_hdmi_phy_variant sun50i_h6_hdmi_phy = {
+	.cur_ctr  = sun50i_h6_cur_ctr,
+	.mpll_cfg = sun50i_h6_mpll_cfg,
+	.phy_cfg  = sun50i_h6_phy_config,
+	.phy_init = &sun50i_hdmi_phy_init_h6,
+};
+
 static const struct of_device_id sun8i_hdmi_phy_of_table[] = {
 	{
 		.compatible = "allwinner,sun8i-a83t-hdmi-phy",
@@ -463,6 +596,10 @@ static const struct of_device_id sun8i_hdmi_phy_of_table[] = {
 		.compatible = "allwinner,sun50i-a64-hdmi-phy",
 		.data = &sun50i_a64_hdmi_phy,
 	},
+	{
+		.compatible = "allwinner,sun50i-h6-hdmi-phy",
+		.data = &sun50i_h6_hdmi_phy,
+	},
 	{ /* sentinel */ }
 };
 
-- 
2.19.1


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

* [PATCH v3 23/28] drm/sun4i: Initialize registers in tcon-top driver
  2018-11-04 18:26 [PATCH v3 00/28] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (21 preceding siblings ...)
  2018-11-04 18:26 ` [PATCH v3 22/28] drm/sun4i: Add support for H6 " Jernej Skrabec
@ 2018-11-04 18:27 ` Jernej Skrabec
  2018-11-04 18:27 ` [PATCH v3 24/28] drm: sun4i: add quirks for TCON TOP Jernej Skrabec
                   ` (5 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Jernej Skrabec @ 2018-11-04 18:27 UTC (permalink / raw)
  To: maxime.ripard, wens
  Cc: robh+dt, mturquette, sboyd, airlied, architt, a.hajda,
	Laurent.pinchart, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi, jernej.skrabec

It turns out that TCON TOP registers in H6 SoC have non-zero reset
value. This may cause issues if bits are not changed during
configuration.

To prevent that, initialize registers to 0.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/gpu/drm/sun4i/sun8i_tcon_top.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/sun4i/sun8i_tcon_top.c b/drivers/gpu/drm/sun4i/sun8i_tcon_top.c
index 3040a79f298f..37158548b447 100644
--- a/drivers/gpu/drm/sun4i/sun8i_tcon_top.c
+++ b/drivers/gpu/drm/sun4i/sun8i_tcon_top.c
@@ -167,6 +167,13 @@ static int sun8i_tcon_top_bind(struct device *dev, struct device *master,
 		goto err_assert_reset;
 	}
 
+	/*
+	 * At least on H6, some registers have some bits set by default
+	 * which may cause issues. Clear them here.
+	 */
+	writel(0, regs + TCON_TOP_PORT_SEL_REG);
+	writel(0, regs + TCON_TOP_GATE_SRC_REG);
+
 	/*
 	 * TCON TOP has two muxes, which select parent clock for each TCON TV
 	 * channel clock. Parent could be either TCON TV or TVE clock. For now
-- 
2.19.1


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

* [PATCH v3 24/28] drm: sun4i: add quirks for TCON TOP
  2018-11-04 18:26 [PATCH v3 00/28] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (22 preceding siblings ...)
  2018-11-04 18:27 ` [PATCH v3 23/28] drm/sun4i: Initialize registers in tcon-top driver Jernej Skrabec
@ 2018-11-04 18:27 ` Jernej Skrabec
  2018-11-04 18:27 ` [PATCH v3 25/28] dt-bindings: display: sun4i-drm: document H6 " Jernej Skrabec
                   ` (4 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Jernej Skrabec @ 2018-11-04 18:27 UTC (permalink / raw)
  To: maxime.ripard, wens
  Cc: robh+dt, mturquette, sboyd, airlied, architt, a.hajda,
	Laurent.pinchart, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi, jernej.skrabec, Icenowy Zheng

From: Icenowy Zheng <icenowy@aosc.io>

Some SoCs, such as H6, doesn't have a full-featured TCON TOP.

Add quirks support for TCON TOP.

Currently the presence of TCON_TV1 and DSI is controlled via the quirks
structure.

Acked-by: Maxime Ripard <maxime.ripard@bootlin.com>
Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
[Fixed code style and removed unnecessary initialization]
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/gpu/drm/sun4i/sun8i_tcon_top.c | 37 +++++++++++++++++++-------
 1 file changed, 28 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun8i_tcon_top.c b/drivers/gpu/drm/sun4i/sun8i_tcon_top.c
index 37158548b447..e94e3fb1736b 100644
--- a/drivers/gpu/drm/sun4i/sun8i_tcon_top.c
+++ b/drivers/gpu/drm/sun4i/sun8i_tcon_top.c
@@ -9,11 +9,17 @@
 #include <linux/component.h>
 #include <linux/device.h>
 #include <linux/module.h>
+#include <linux/of_device.h>
 #include <linux/of_graph.h>
 #include <linux/platform_device.h>
 
 #include "sun8i_tcon_top.h"
 
+struct sun8i_tcon_top_quirks {
+	bool has_tcon_tv1;
+	bool has_dsi;
+};
+
 static bool sun8i_tcon_top_node_is_tcon_top(struct device_node *node)
 {
 	return !!of_match_node(sun8i_tcon_top_of_table, node);
@@ -121,10 +127,13 @@ static int sun8i_tcon_top_bind(struct device *dev, struct device *master,
 	struct platform_device *pdev = to_platform_device(dev);
 	struct clk_hw_onecell_data *clk_data;
 	struct sun8i_tcon_top *tcon_top;
+	const struct sun8i_tcon_top_quirks *quirks;
 	struct resource *res;
 	void __iomem *regs;
 	int ret, i;
 
+	quirks = of_device_get_match_data(&pdev->dev);
+
 	tcon_top = devm_kzalloc(dev, sizeof(*tcon_top), GFP_KERNEL);
 	if (!tcon_top)
 		return -ENOMEM;
@@ -187,15 +196,17 @@ static int sun8i_tcon_top_bind(struct device *dev, struct device *master,
 					     &tcon_top->reg_lock,
 					     TCON_TOP_TCON_TV0_GATE, 0);
 
-	clk_data->hws[CLK_TCON_TOP_TV1] =
-		sun8i_tcon_top_register_gate(dev, "tcon-tv1", regs,
-					     &tcon_top->reg_lock,
-					     TCON_TOP_TCON_TV1_GATE, 1);
+	if (quirks->has_tcon_tv1)
+		clk_data->hws[CLK_TCON_TOP_TV1] =
+			sun8i_tcon_top_register_gate(dev, "tcon-tv1", regs,
+						     &tcon_top->reg_lock,
+						     TCON_TOP_TCON_TV1_GATE, 1);
 
-	clk_data->hws[CLK_TCON_TOP_DSI] =
-		sun8i_tcon_top_register_gate(dev, "dsi", regs,
-					     &tcon_top->reg_lock,
-					     TCON_TOP_TCON_DSI_GATE, 2);
+	if (quirks->has_dsi)
+		clk_data->hws[CLK_TCON_TOP_DSI] =
+			sun8i_tcon_top_register_gate(dev, "dsi", regs,
+						     &tcon_top->reg_lock,
+						     TCON_TOP_TCON_DSI_GATE, 2);
 
 	for (i = 0; i < CLK_NUM; i++)
 		if (IS_ERR(clk_data->hws[i])) {
@@ -257,9 +268,17 @@ static int sun8i_tcon_top_remove(struct platform_device *pdev)
 	return 0;
 }
 
+const struct sun8i_tcon_top_quirks sun8i_r40_tcon_top_quirks = {
+	.has_tcon_tv1	= true,
+	.has_dsi	= true,
+};
+
 /* sun4i_drv uses this list to check if a device node is a TCON TOP */
 const struct of_device_id sun8i_tcon_top_of_table[] = {
-	{ .compatible = "allwinner,sun8i-r40-tcon-top" },
+	{
+		.compatible = "allwinner,sun8i-r40-tcon-top",
+		.data = &sun8i_r40_tcon_top_quirks
+	},
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, sun8i_tcon_top_of_table);
-- 
2.19.1


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

* [PATCH v3 25/28] dt-bindings: display: sun4i-drm: document H6 TCON TOP
  2018-11-04 18:26 [PATCH v3 00/28] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (23 preceding siblings ...)
  2018-11-04 18:27 ` [PATCH v3 24/28] drm: sun4i: add quirks for TCON TOP Jernej Skrabec
@ 2018-11-04 18:27 ` " Jernej Skrabec
  2018-11-04 18:27 ` [PATCH v3 26/28] drm: sun4i: add support for " Jernej Skrabec
                   ` (3 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Jernej Skrabec @ 2018-11-04 18:27 UTC (permalink / raw)
  To: maxime.ripard, wens
  Cc: robh+dt, mturquette, sboyd, airlied, architt, a.hajda,
	Laurent.pinchart, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi, jernej.skrabec, Icenowy Zheng

From: Icenowy Zheng <icenowy@aosc.io>

Allwinner H6 SoC has a cut down version of TCON TOP.

Add binding documentation for it.

Reviewed-by: Rob Herring <robh@kernel.org>
Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
[expanded description]
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 .../bindings/display/sunxi/sun4i-drm.txt           | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
index 478b288eebd9..f426bdb42f18 100644
--- a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
+++ b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
@@ -228,24 +228,26 @@ It allows display pipeline to be configured in very different ways:
                  \ [3] TCON-TV1 [1] - TVE1/RGB
 
 Note that both TCON TOP references same physical unit. Both mixers can be
-connected to any TCON.
+connected to any TCON. Not all TCON TOP variants support all features.
 
 Required properties:
   - compatible: value must be one of:
     * allwinner,sun8i-r40-tcon-top
+    * allwinner,sun50i-h6-tcon-top
   - reg: base address and size of the memory-mapped region.
   - clocks: phandle to the clocks feeding the TCON TOP
     * bus: TCON TOP interface clock
     * tcon-tv0: TCON TV0 clock
-    * tve0: TVE0 clock
-    * tcon-tv1: TCON TV1 clock
-    * tve1: TVE0 clock
-    * dsi: MIPI DSI clock
+    * tve0: TVE0 clock (R40 only)
+    * tcon-tv1: TCON TV1 clock (R40 only)
+    * tve1: TVE0 clock (R40 only)
+    * dsi: MIPI DSI clock (R40 only)
   - clock-names: clock name mentioned above
   - resets: phandle to the reset line driving the TCON TOP
   - #clock-cells : must contain 1
   - clock-output-names: Names of clocks created for TCON TV0 channel clock,
-    TCON TV1 channel clock and DSI channel clock, in that order.
+    TCON TV1 channel clock (R40 only) and DSI channel clock (R40 only), in
+    that order.
 
 - ports: A ports node with endpoint definitions as defined in
     Documentation/devicetree/bindings/media/video-interfaces.txt. 6 ports should
-- 
2.19.1


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

* [PATCH v3 26/28] drm: sun4i: add support for H6 TCON TOP
  2018-11-04 18:26 [PATCH v3 00/28] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (24 preceding siblings ...)
  2018-11-04 18:27 ` [PATCH v3 25/28] dt-bindings: display: sun4i-drm: document H6 " Jernej Skrabec
@ 2018-11-04 18:27 ` " Jernej Skrabec
  2018-11-04 18:27 ` [PATCH v3 27/28] arm64: dts: allwinner: h6: Add HDMI pipeline Jernej Skrabec
                   ` (2 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Jernej Skrabec @ 2018-11-04 18:27 UTC (permalink / raw)
  To: maxime.ripard, wens
  Cc: robh+dt, mturquette, sboyd, airlied, architt, a.hajda,
	Laurent.pinchart, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi, jernej.skrabec, Icenowy Zheng

From: Icenowy Zheng <icenowy@aosc.io>

The TCON TOP on Allwinner H6 SoC is a cut down version of the R40 TCON
TOP, which dropped TCON_TV1 and DSI (which do not exist on H6).

Add support for it.

Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
---
 drivers/gpu/drm/sun4i/sun8i_tcon_top.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/sun4i/sun8i_tcon_top.c b/drivers/gpu/drm/sun4i/sun8i_tcon_top.c
index e94e3fb1736b..fc36e0c10a37 100644
--- a/drivers/gpu/drm/sun4i/sun8i_tcon_top.c
+++ b/drivers/gpu/drm/sun4i/sun8i_tcon_top.c
@@ -273,12 +273,20 @@ const struct sun8i_tcon_top_quirks sun8i_r40_tcon_top_quirks = {
 	.has_dsi	= true,
 };
 
+const struct sun8i_tcon_top_quirks sun50i_h6_tcon_top_quirks = {
+	/* Nothing special */
+};
+
 /* sun4i_drv uses this list to check if a device node is a TCON TOP */
 const struct of_device_id sun8i_tcon_top_of_table[] = {
 	{
 		.compatible = "allwinner,sun8i-r40-tcon-top",
 		.data = &sun8i_r40_tcon_top_quirks
 	},
+	{
+		.compatible = "allwinner,sun50i-h6-tcon-top",
+		.data = &sun50i_h6_tcon_top_quirks
+	},
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, sun8i_tcon_top_of_table);
-- 
2.19.1


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

* [PATCH v3 27/28] arm64: dts: allwinner: h6: Add HDMI pipeline
  2018-11-04 18:26 [PATCH v3 00/28] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (25 preceding siblings ...)
  2018-11-04 18:27 ` [PATCH v3 26/28] drm: sun4i: add support for " Jernej Skrabec
@ 2018-11-04 18:27 ` Jernej Skrabec
  2018-11-04 18:27 ` [PATCH v3 28/28] arm64: dts: allwinner: h6: Enable HDMI output on Pine H64 board Jernej Skrabec
  2018-11-05  9:43 ` [PATCH v3 00/28] Allwinner H6 DE3 and HDMI support Maxime Ripard
  28 siblings, 0 replies; 41+ messages in thread
From: Jernej Skrabec @ 2018-11-04 18:27 UTC (permalink / raw)
  To: maxime.ripard, wens
  Cc: robh+dt, mturquette, sboyd, airlied, architt, a.hajda,
	Laurent.pinchart, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi, jernej.skrabec, Icenowy Zheng

This commit adds all entries needed for HDMI to function properly.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
[added DE3 bus]
Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
---
 arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 201 +++++++++++++++++++
 1 file changed, 201 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
index 040828d2e2c0..59dda8f89d23 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
@@ -6,8 +6,11 @@
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/clock/sun50i-h6-ccu.h>
 #include <dt-bindings/clock/sun50i-h6-r-ccu.h>
+#include <dt-bindings/clock/sun8i-de2.h>
+#include <dt-bindings/clock/sun8i-tcon-top.h>
 #include <dt-bindings/reset/sun50i-h6-ccu.h>
 #include <dt-bindings/reset/sun50i-h6-r-ccu.h>
+#include <dt-bindings/reset/sun8i-de2.h>
 
 / {
 	interrupt-parent = <&gic>;
@@ -86,12 +89,63 @@
 			(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
 	};
 
+	de: display-engine {
+		compatible = "allwinner,sun50i-h6-display-engine";
+		allwinner,pipelines = <&mixer0>;
+		status = "disabled";
+	};
+
 	soc {
 		compatible = "simple-bus";
 		#address-cells = <1>;
 		#size-cells = <1>;
 		ranges;
 
+		de3@1000000 {
+			compatible = "allwinner,sun50i-h6-de3",
+				     "allwinner,sun50i-a64-de2";
+			reg = <0x1000000 0x400000>;
+			allwinner,sram = <&de2_sram 1>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 0x1000000 0x400000>;
+
+			display_clocks: clock@0 {
+				compatible = "allwinner,sun50i-h6-de3-clk";
+				reg = <0x0 0x10000>;
+				clocks = <&ccu CLK_DE>,
+					 <&ccu CLK_BUS_DE>;
+				clock-names = "mod",
+					      "bus";
+				resets = <&ccu RST_BUS_DE>;
+				#clock-cells = <1>;
+				#reset-cells = <1>;
+			};
+
+			mixer0: mixer@100000 {
+				compatible = "allwinner,sun50i-h6-de3-mixer-0";
+				reg = <0x100000 0x100000>;
+				clocks = <&display_clocks CLK_BUS_MIXER0>,
+					 <&display_clocks CLK_MIXER0>;
+				clock-names = "bus",
+					      "mod";
+				resets = <&display_clocks RST_MIXER0>;
+
+				ports {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					mixer0_out: port@1 {
+						reg = <1>;
+
+						mixer0_out_tcon_top_mixer0: endpoint {
+							remote-endpoint = <&tcon_top_mixer0_in_mixer0>;
+						};
+					};
+				};
+			};
+		};
+
 		syscon: syscon@3000000 {
 			compatible = "allwinner,sun50i-h6-system-control",
 				     "allwinner,sun50i-a64-system-control";
@@ -149,6 +203,11 @@
 			interrupt-controller;
 			#interrupt-cells = <3>;
 
+			hdmi_pins: hdmi-pins {
+				pins = "PH8", "PH9", "PH10";
+				function = "hdmi";
+			};
+
 			mmc0_pins: mmc0-pins {
 				pins = "PF0", "PF1", "PF2", "PF3",
 				       "PF4", "PF5";
@@ -258,6 +317,148 @@
 			status = "disabled";
 		};
 
+		hdmi: hdmi@6000000 {
+			compatible = "allwinner,sun50i-h6-dw-hdmi";
+			reg = <0x06000000 0x10000>;
+			reg-io-width = <1>;
+			interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_HDMI>, <&ccu CLK_HDMI_SLOW>,
+				 <&ccu CLK_HDMI>, <&ccu CLK_HDMI_CEC>,
+				 <&ccu CLK_HDCP>, <&ccu CLK_BUS_HDCP>;
+			clock-names = "iahb", "isfr", "tmds", "cec", "hdcp",
+				      "hdcp-bus";
+			resets = <&ccu RST_BUS_HDMI_SUB>, <&ccu RST_BUS_HDCP>;
+			reset-names = "ctrl", "hdcp";
+			phys = <&hdmi_phy>;
+			phy-names = "hdmi-phy";
+			pinctrl-names = "default";
+			pinctrl-0 = <&hdmi_pins>;
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				hdmi_in: port@0 {
+					reg = <0>;
+
+					hdmi_in_tcon_top: endpoint {
+						remote-endpoint = <&tcon_top_hdmi_out_hdmi>;
+					};
+				};
+
+				hdmi_out: port@1 {
+					reg = <1>;
+				};
+			};
+		};
+
+		hdmi_phy: hdmi-phy@6010000 {
+			compatible = "allwinner,sun50i-h6-hdmi-phy";
+			reg = <0x06010000 0x10000>;
+			clocks = <&ccu CLK_BUS_HDMI>, <&ccu CLK_HDMI_SLOW>;
+			clock-names = "bus", "mod";
+			resets = <&ccu RST_BUS_HDMI>;
+			reset-names = "phy";
+			#phy-cells = <0>;
+		};
+
+		tcon_top: tcon-top@6510000 {
+			compatible = "allwinner,sun50i-h6-tcon-top";
+			reg = <0x06510000 0x1000>;
+			clocks = <&ccu CLK_BUS_TCON_TOP>,
+				 <&ccu CLK_TCON_TV0>;
+			clock-names = "bus",
+				      "tcon-tv0";
+			clock-output-names = "tcon-top-tv0";
+			resets = <&ccu RST_BUS_TCON_TOP>;
+			reset-names = "rst";
+			#clock-cells = <1>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				tcon_top_mixer0_in: port@0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+
+					tcon_top_mixer0_in_mixer0: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&mixer0_out_tcon_top_mixer0>;
+					};
+				};
+
+				tcon_top_mixer0_out: port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+
+					tcon_top_mixer0_out_tcon_tv: endpoint@2 {
+						reg = <2>;
+						remote-endpoint = <&tcon_tv_in_tcon_top_mixer0>;
+					};
+				};
+
+				tcon_top_hdmi_in: port@4 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <4>;
+
+					tcon_top_hdmi_in_tcon_tv: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&tcon_tv_out_tcon_top>;
+					};
+				};
+
+				tcon_top_hdmi_out: port@5 {
+					reg = <5>;
+
+					tcon_top_hdmi_out_hdmi: endpoint {
+						remote-endpoint = <&hdmi_in_tcon_top>;
+					};
+				};
+			};
+		};
+
+		tcon_tv: lcd-controller@6515000 {
+			compatible = "allwinner,sun50i-h6-tcon-tv",
+				     "allwinner,sun8i-r40-tcon-tv";
+			reg = <0x06515000 0x1000>;
+			interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_TCON_TV0>,
+				 <&tcon_top CLK_TCON_TOP_TV0>;
+			clock-names = "ahb",
+				      "tcon-ch1";
+			resets = <&ccu RST_BUS_TCON_TV0>;
+			reset-names = "lcd";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				tcon_tv_in: port@0 {
+					reg = <0>;
+
+					tcon_tv_in_tcon_top_mixer0: endpoint {
+						remote-endpoint = <&tcon_top_mixer0_out_tcon_tv>;
+					};
+				};
+
+				tcon_tv_out: port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+
+					tcon_tv_out_tcon_top: endpoint@1 {
+						reg = <1>;
+						remote-endpoint = <&tcon_top_hdmi_in_tcon_tv>;
+					};
+				};
+			};
+		};
+
 		r_ccu: clock@7010000 {
 			compatible = "allwinner,sun50i-h6-r-ccu";
 			reg = <0x07010000 0x400>;
-- 
2.19.1


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

* [PATCH v3 28/28] arm64: dts: allwinner: h6: Enable HDMI output on Pine H64 board
  2018-11-04 18:26 [PATCH v3 00/28] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (26 preceding siblings ...)
  2018-11-04 18:27 ` [PATCH v3 27/28] arm64: dts: allwinner: h6: Add HDMI pipeline Jernej Skrabec
@ 2018-11-04 18:27 ` Jernej Skrabec
  2018-11-05  9:43 ` [PATCH v3 00/28] Allwinner H6 DE3 and HDMI support Maxime Ripard
  28 siblings, 0 replies; 41+ messages in thread
From: Jernej Skrabec @ 2018-11-04 18:27 UTC (permalink / raw)
  To: maxime.ripard, wens
  Cc: robh+dt, mturquette, sboyd, airlied, architt, a.hajda,
	Laurent.pinchart, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi, jernej.skrabec

Pine H64 board has HDMI type A connector.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 .../boot/dts/allwinner/sun50i-h6-pine-h64.dts | 25 +++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts
index 48daec7f78ba..36db21314996 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts
@@ -21,6 +21,17 @@
 		stdout-path = "serial0:115200n8";
 	};
 
+	connector {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con_in: endpoint {
+				remote-endpoint = <&hdmi_out_con>;
+			};
+		};
+	};
+
 	leds {
 		compatible = "gpio-leds";
 
@@ -41,6 +52,20 @@
 	};
 };
 
+&de {
+	status = "okay";
+};
+
+&hdmi {
+	status = "okay";
+};
+
+&hdmi_out {
+	hdmi_out_con: endpoint {
+		remote-endpoint = <&hdmi_con_in>;
+	};
+};
+
 &mmc0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&mmc0_pins>;
-- 
2.19.1


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

* Re: [PATCH v3 00/28] Allwinner H6 DE3 and HDMI support
  2018-11-04 18:26 [PATCH v3 00/28] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (27 preceding siblings ...)
  2018-11-04 18:27 ` [PATCH v3 28/28] arm64: dts: allwinner: h6: Enable HDMI output on Pine H64 board Jernej Skrabec
@ 2018-11-05  9:43 ` Maxime Ripard
  2018-11-06 15:54   ` Jernej Škrabec
                     ` (2 more replies)
  28 siblings, 3 replies; 41+ messages in thread
From: Maxime Ripard @ 2018-11-05  9:43 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: wens, robh+dt, mturquette, sboyd, airlied, architt, a.hajda,
	Laurent.pinchart, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi

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

On Sun, Nov 04, 2018 at 07:26:37PM +0100, Jernej Skrabec wrote:
> This series adds support for Display Engine 3.0 and HDMI 2.0a, which
> can be found on H6 SoC.
> 
> Display Engine 3.0 in comparison to 2.0 mostly adds features needed for
> displaying and processing 10-bit and AFBC formats, which are not yet
> supported by this series.
> 
> H6 is also the first SoC which supports IOMMU, but support for it is
> not yet added.
> 
> This series is based on linux-next at next-20181102.
> 
> I suggest all patches go through allwinner tree, except DRM patches,
> which should go through drm-misc tree.

Applied all patches up to the 26. The two last one however should not
use the clk bindings define you added in the first clk patches, since
clk and dt patches are going through different tree.

Thanks!
Maxime

-- 
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

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

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

* Re: [PATCH v3 00/28] Allwinner H6 DE3 and HDMI support
  2018-11-05  9:43 ` [PATCH v3 00/28] Allwinner H6 DE3 and HDMI support Maxime Ripard
@ 2018-11-06 15:54   ` Jernej Škrabec
  2018-11-06 17:20   ` Jernej Škrabec
  2018-12-03 18:09   ` Jernej Škrabec
  2 siblings, 0 replies; 41+ messages in thread
From: Jernej Škrabec @ 2018-11-06 15:54 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: wens, robh+dt, mturquette, sboyd, airlied, architt, a.hajda,
	Laurent.pinchart, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi

Dne ponedeljek, 05. november 2018 ob 10:43:41 CET je Maxime Ripard napisal(a):
> On Sun, Nov 04, 2018 at 07:26:37PM +0100, Jernej Skrabec wrote:
> > This series adds support for Display Engine 3.0 and HDMI 2.0a, which
> > can be found on H6 SoC.
> > 
> > Display Engine 3.0 in comparison to 2.0 mostly adds features needed for
> > displaying and processing 10-bit and AFBC formats, which are not yet
> > supported by this series.
> > 
> > H6 is also the first SoC which supports IOMMU, but support for it is
> > not yet added.
> > 
> > This series is based on linux-next at next-20181102.
> > 
> > I suggest all patches go through allwinner tree, except DRM patches,
> > which should go through drm-misc tree.
> 
> Applied all patches up to the 26. The two last one however should not
> use the clk bindings define you added in the first clk patches, since
> clk and dt patches are going through different tree.

Thanks!

Should I send remaining 2 patches as v4 or can be send separately?

Best regards,
Jernej




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

* Re: [PATCH v3 00/28] Allwinner H6 DE3 and HDMI support
  2018-11-05  9:43 ` [PATCH v3 00/28] Allwinner H6 DE3 and HDMI support Maxime Ripard
  2018-11-06 15:54   ` Jernej Škrabec
@ 2018-11-06 17:20   ` Jernej Škrabec
  2018-11-07  9:44     ` Maxime Ripard
  2018-12-03 18:09   ` Jernej Škrabec
  2 siblings, 1 reply; 41+ messages in thread
From: Jernej Škrabec @ 2018-11-06 17:20 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: wens, robh+dt, mturquette, sboyd, airlied, architt, a.hajda,
	Laurent.pinchart, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi

Dne ponedeljek, 05. november 2018 ob 10:43:41 CET je Maxime Ripard napisal(a):
> On Sun, Nov 04, 2018 at 07:26:37PM +0100, Jernej Skrabec wrote:
> > This series adds support for Display Engine 3.0 and HDMI 2.0a, which
> > can be found on H6 SoC.
> > 
> > Display Engine 3.0 in comparison to 2.0 mostly adds features needed for
> > displaying and processing 10-bit and AFBC formats, which are not yet
> > supported by this series.
> > 
> > H6 is also the first SoC which supports IOMMU, but support for it is
> > not yet added.
> > 
> > This series is based on linux-next at next-20181102.
> > 
> > I suggest all patches go through allwinner tree, except DRM patches,
> > which should go through drm-misc tree.
> 
> Applied all patches up to the 26. The two last one however should not
> use the clk bindings define you added in the first clk patches, since
> clk and dt patches are going through different tree.

I went over clock defines again, but I don't think I use anything new. New 
defines are:

#define CLK_BUS_ROT            9
#define CLK_ROT                        10
#define RST_ROT                3

but none of them are actually used in DT.

Did I miss anything?

Best regards,
Jernej




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

* Re: [PATCH v3 00/28] Allwinner H6 DE3 and HDMI support
  2018-11-06 17:20   ` Jernej Škrabec
@ 2018-11-07  9:44     ` Maxime Ripard
  0 siblings, 0 replies; 41+ messages in thread
From: Maxime Ripard @ 2018-11-07  9:44 UTC (permalink / raw)
  To: Jernej Škrabec
  Cc: wens, robh+dt, mturquette, sboyd, airlied, architt, a.hajda,
	Laurent.pinchart, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi

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

On Tue, Nov 06, 2018 at 06:20:39PM +0100, Jernej Škrabec wrote:
> Dne ponedeljek, 05. november 2018 ob 10:43:41 CET je Maxime Ripard napisal(a):
> > On Sun, Nov 04, 2018 at 07:26:37PM +0100, Jernej Skrabec wrote:
> > > This series adds support for Display Engine 3.0 and HDMI 2.0a, which
> > > can be found on H6 SoC.
> > > 
> > > Display Engine 3.0 in comparison to 2.0 mostly adds features needed for
> > > displaying and processing 10-bit and AFBC formats, which are not yet
> > > supported by this series.
> > > 
> > > H6 is also the first SoC which supports IOMMU, but support for it is
> > > not yet added.
> > > 
> > > This series is based on linux-next at next-20181102.
> > > 
> > > I suggest all patches go through allwinner tree, except DRM patches,
> > > which should go through drm-misc tree.
> > 
> > Applied all patches up to the 26. The two last one however should not
> > use the clk bindings define you added in the first clk patches, since
> > clk and dt patches are going through different tree.
> 
> I went over clock defines again, but I don't think I use anything new. New 
> defines are:
> 
> #define CLK_BUS_ROT            9
> #define CLK_ROT                        10
> #define RST_ROT                3
> 
> but none of them are actually used in DT.
> 
> Did I miss anything?

No, I did. Sorry for that. Patches 27 and 28 are applied now.

I've fixed a few things in the patch 27, to fix the order of the de
node, and change the de3 node name, since it's supposed to be a
generic class name. I renamed it to display-engine.

Maxime

-- 
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

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

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

* Re: [PATCH v3 00/28] Allwinner H6 DE3 and HDMI support
  2018-11-05  9:43 ` [PATCH v3 00/28] Allwinner H6 DE3 and HDMI support Maxime Ripard
  2018-11-06 15:54   ` Jernej Škrabec
  2018-11-06 17:20   ` Jernej Škrabec
@ 2018-12-03 18:09   ` Jernej Škrabec
  2018-12-04  8:29     ` Maxime Ripard
  2 siblings, 1 reply; 41+ messages in thread
From: Jernej Škrabec @ 2018-12-03 18:09 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: wens, robh+dt, mturquette, sboyd, airlied, architt, a.hajda,
	Laurent.pinchart, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi

Dne ponedeljek, 05. november 2018 ob 10:43:41 CET je Maxime Ripard napisal(a):
> On Sun, Nov 04, 2018 at 07:26:37PM +0100, Jernej Skrabec wrote:
> > This series adds support for Display Engine 3.0 and HDMI 2.0a, which
> > can be found on H6 SoC.
> > 
> > Display Engine 3.0 in comparison to 2.0 mostly adds features needed for
> > displaying and processing 10-bit and AFBC formats, which are not yet
> > supported by this series.
> > 
> > H6 is also the first SoC which supports IOMMU, but support for it is
> > not yet added.
> > 
> > This series is based on linux-next at next-20181102.
> > 
> > I suggest all patches go through allwinner tree, except DRM patches,
> > which should go through drm-misc tree.
> 
> Applied all patches up to the 26. The two last one however should not
> use the clk bindings define you added in the first clk patches, since
> clk and dt patches are going through different tree.

I think you forgot to merge patch "drm/sun4i: Add compatible for H6 display 
engine". At least it is not in linux-next.

Best regards,
Jernej




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

* Re: [PATCH v3 00/28] Allwinner H6 DE3 and HDMI support
  2018-12-03 18:09   ` Jernej Škrabec
@ 2018-12-04  8:29     ` Maxime Ripard
  0 siblings, 0 replies; 41+ messages in thread
From: Maxime Ripard @ 2018-12-04  8:29 UTC (permalink / raw)
  To: Jernej Škrabec
  Cc: wens, robh+dt, mturquette, sboyd, airlied, architt, a.hajda,
	Laurent.pinchart, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi

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

On Mon, Dec 03, 2018 at 07:09:50PM +0100, Jernej Škrabec wrote:
> Dne ponedeljek, 05. november 2018 ob 10:43:41 CET je Maxime Ripard napisal(a):
> > On Sun, Nov 04, 2018 at 07:26:37PM +0100, Jernej Skrabec wrote:
> > > This series adds support for Display Engine 3.0 and HDMI 2.0a, which
> > > can be found on H6 SoC.
> > > 
> > > Display Engine 3.0 in comparison to 2.0 mostly adds features needed for
> > > displaying and processing 10-bit and AFBC formats, which are not yet
> > > supported by this series.
> > > 
> > > H6 is also the first SoC which supports IOMMU, but support for it is
> > > not yet added.
> > > 
> > > This series is based on linux-next at next-20181102.
> > > 
> > > I suggest all patches go through allwinner tree, except DRM patches,
> > > which should go through drm-misc tree.
> > 
> > Applied all patches up to the 26. The two last one however should not
> > use the clk bindings define you added in the first clk patches, since
> > clk and dt patches are going through different tree.
> 
> I think you forgot to merge patch "drm/sun4i: Add compatible for H6 display 
> engine". At least it is not in linux-next.

Sorry, I just applied it. thanks!
Maxime


-- 
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

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

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

* Re: [linux-sunxi] [PATCH v3 02/28] clk: sunxi-ng: Adjust MP clock parent rate when allowed
  2018-11-04 18:26 ` [PATCH v3 02/28] clk: sunxi-ng: Adjust MP clock parent rate when allowed Jernej Skrabec
@ 2019-01-10  9:15   ` " Priit Laes
  2019-01-10 17:10     ` Jernej Škrabec
  0 siblings, 1 reply; 41+ messages in thread
From: Priit Laes @ 2019-01-10  9:15 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: maxime.ripard, wens, robh+dt, mturquette, sboyd, airlied,
	architt, a.hajda, Laurent.pinchart, devicetree, linux-arm-kernel,
	linux-kernel, linux-clk, dri-devel, linux-sunxi

On Sun, Nov 04, 2018 at 07:26:39PM +0100, Jernej Skrabec wrote:
> Currently MP clocks don't consider adjusting parent rate even if they
> are allowed to do so. Such behaviour considerably lowers amount of
> possible rates, which is very inconvenient when such clock is used for
> pixel clock, for example.
> 
> In order to improve the situation, adjusting parent rate is considered
> when allowed.
> 
> This code is inspired by clk_divider_bestdiv() function, which does
> basically the same thing for different clock type.

This patch seems to break the eMMC support on Olinuxino-Lime2-eMMC boards:

EXT4-fs (mmcblk1p4): INFO: recovery required on readonly filesystem
EXT4-fs (mmcblk1p4): write access will be enabled during recovery
sunxi-mmc 1c11000.mmc: data error, sending stop command
sunxi-mmc 1c11000.mmc: send stop command failed


$ git bisect log
git bisect start
# good: [3df407b2a5346db1c48809706ece7a8616c79e0b] mmc: dw_mmc-bluefield: simplify the probe() function
git bisect good 3df407b2a5346db1c48809706ece7a8616c79e0b
# bad: [00d59fde8532b2d42e80909d2e58678755e04da9] Merge tag 'mmc-v4.21' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc
git bisect bad 00d59fde8532b2d42e80909d2e58678755e04da9
# good: [01e421feec0817bb3141eaae4c517410d193d440] Merge branch 'fixes' into next
git bisect good 01e421feec0817bb3141eaae4c517410d193d440
# bad: [1eefdec18eded41833401cfd64749643ff72e7da] Merge branch 'locking-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
git bisect bad 1eefdec18eded41833401cfd64749643ff72e7da
# good: [eaa76499711535fd64d747cc4ef0d78ab0fd41c6] Merge tag 'mtd/for-4.21' of git://git.infradead.org/linux-mtd
git bisect good eaa76499711535fd64d747cc4ef0d78ab0fd41c6
# good: [4e4390ad067a61ce4e7607bd0df31f19a4caa36a] Merge tag 'leds-for-4.21-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/j.anaszewski/linux-leds
git bisect good 4e4390ad067a61ce4e7607bd0df31f19a4caa36a
# bad: [c2f1f3e0e17d94ab0c66d83e669492cb9e9a3698] Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next
git bisect bad c2f1f3e0e17d94ab0c66d83e669492cb9e9a3698
# bad: [e4b99d415c3908581d4703203e1e805f043a3e71] Merge branch 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
git bisect bad e4b99d415c3908581d4703203e1e805f043a3e71
# bad: [ffe05540d18013db62c43627836a3638e9a2c7aa] Merge branches 'clk-renesas', 'clk-allwinner', 'clk-tegra', 'clk-meson' and 'clk-rockchip' into clk-next
git bisect bad ffe05540d18013db62c43627836a3638e9a2c7aa
# good: [1a501c8defe950571316d5ddd917bf44f5ed7bd4] Merge branches 'clk-managed-registration', 'clk-spdx', 'clk-remove-basic' and 'clk-ops-const' into clk-next
git bisect good 1a501c8defe950571316d5ddd917bf44f5ed7bd4
# good: [e74581b79ddd9b49b8c61e2791fc4dffc0245afb] Merge tag 'meson-clk-4.21-2' of https://github.com/BayLibre/clk-meson into clk-meson
git bisect good e74581b79ddd9b49b8c61e2791fc4dffc0245afb
# good: [60baf75e3f5b76043c25328ac0c5320aaef5ea41] Merge tag 'clk-renesas-for-v4.21-tag2' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers into clk-renesas
git bisect good 60baf75e3f5b76043c25328ac0c5320aaef5ea41
# bad: [a41f85b6017ee20952a60e4330bcae2527fe2c2a] Merge tag 'sunxi-clk-for-4.21' of https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux into clk-allwinner
git bisect bad a41f85b6017ee20952a60e4330bcae2527fe2c2a
# bad: [ee678706e46d0d185c27cc214ad97828e0643159] clk: sunxi-ng: a64: Fix gate bit of DSI DPHY
git bisect bad ee678706e46d0d185c27cc214ad97828e0643159
# bad: [65b6657672388b72822e0367f06d41c1e3ffb5bb] clk: sunxi-ng: Use u64 for calculation of NM rate
git bisect bad 65b6657672388b72822e0367f06d41c1e3ffb5bb
# good: [db7548934603d9eda12649dff97ea5c29884405d] clk: sunxi-ng: sun50i: h6: Fix MMC clock mux width
git bisect good db7548934603d9eda12649dff97ea5c29884405d
# bad: [3f790433c3cb27ecaf2ca0e07ac25964e4fd9f15] clk: sunxi-ng: Adjust MP clock parent rate when allowed
git bisect bad 3f790433c3cb27ecaf2ca0e07ac25964e4fd9f15
# first bad commit: [3f790433c3cb27ecaf2ca0e07ac25964e4fd9f15] clk: sunxi-ng: Adjust MP clock parent rate when allowed


> 
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> ---
>  drivers/clk/sunxi-ng/ccu_mp.c | 64 +++++++++++++++++++++++++++++++++--
>  1 file changed, 62 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/clk/sunxi-ng/ccu_mp.c b/drivers/clk/sunxi-ng/ccu_mp.c
> index 5d0af4051737..0357349eb767 100644
> --- a/drivers/clk/sunxi-ng/ccu_mp.c
> +++ b/drivers/clk/sunxi-ng/ccu_mp.c
> @@ -40,6 +40,61 @@ static void ccu_mp_find_best(unsigned long parent, unsigned long rate,
>  	*p = best_p;
>  }
>  
> +static unsigned long ccu_mp_find_best_with_parent_adj(struct clk_hw *hw,
> +						      unsigned long *parent,
> +						      unsigned long rate,
> +						      unsigned int max_m,
> +						      unsigned int max_p)
> +{
> +	unsigned long parent_rate_saved;
> +	unsigned long parent_rate, now;
> +	unsigned long best_rate = 0;
> +	unsigned int _m, _p, div;
> +	unsigned long maxdiv;
> +
> +	parent_rate_saved = *parent;
> +
> +	/*
> +	 * The maximum divider we can use without overflowing
> +	 * unsigned long in rate * m * p below
> +	 */
> +	maxdiv = max_m * max_p;
> +	maxdiv = min(ULONG_MAX / rate, maxdiv);
> +
> +	for (_p = 1; _p <= max_p; _p <<= 1) {
> +		for (_m = 1; _m <= max_m; _m++) {
> +			div = _m * _p;
> +
> +			if (div > maxdiv)
> +				break;
> +
> +			if (rate * div == parent_rate_saved) {
> +				/*
> +				 * It's the most ideal case if the requested
> +				 * rate can be divided from parent clock without
> +				 * needing to change parent rate, so return the
> +				 * divider immediately.
> +				 */
> +				*parent = parent_rate_saved;
> +				return rate;
> +			}
> +
> +			parent_rate = clk_hw_round_rate(hw, rate * div);
> +			now = parent_rate / div;
> +
> +			if (now <= rate && now > best_rate) {
> +				best_rate = now;
> +				*parent = parent_rate;
> +
> +				if (now == rate)
> +					return rate;
> +			}
> +		}
> +	}
> +
> +	return best_rate;
> +}
> +
>  static unsigned long ccu_mp_round_rate(struct ccu_mux_internal *mux,
>  				       struct clk_hw *hw,
>  				       unsigned long *parent_rate,
> @@ -56,8 +111,13 @@ static unsigned long ccu_mp_round_rate(struct ccu_mux_internal *mux,
>  	max_m = cmp->m.max ?: 1 << cmp->m.width;
>  	max_p = cmp->p.max ?: 1 << ((1 << cmp->p.width) - 1);
>  
> -	ccu_mp_find_best(*parent_rate, rate, max_m, max_p, &m, &p);
> -	rate = *parent_rate / p / m;
> +	if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) {
> +		ccu_mp_find_best(*parent_rate, rate, max_m, max_p, &m, &p);
> +		rate = *parent_rate / p / m;
> +	} else {
> +		rate = ccu_mp_find_best_with_parent_adj(hw, parent_rate, rate,
> +							max_m, max_p);
> +	}
>  
>  	if (cmp->common.features & CCU_FEATURE_FIXED_POSTDIV)
>  		rate /= cmp->fixed_post_div;
> -- 
> 2.19.1
> 
> -- 
> You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

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

* Re: [linux-sunxi] [PATCH v3 02/28] clk: sunxi-ng: Adjust MP clock parent rate when allowed
  2019-01-10  9:15   ` [linux-sunxi] " Priit Laes
@ 2019-01-10 17:10     ` Jernej Škrabec
  2019-01-16 12:09       ` Priit Laes
  0 siblings, 1 reply; 41+ messages in thread
From: Jernej Škrabec @ 2019-01-10 17:10 UTC (permalink / raw)
  To: Priit Laes
  Cc: maxime.ripard, wens, robh+dt, mturquette, sboyd, airlied,
	architt, a.hajda, Laurent.pinchart, devicetree, linux-arm-kernel,
	linux-kernel, linux-clk, dri-devel, linux-sunxi

Dne četrtek, 10. januar 2019 ob 10:15:48 CET je Priit Laes napisal(a):
> On Sun, Nov 04, 2018 at 07:26:39PM +0100, Jernej Skrabec wrote:
> > Currently MP clocks don't consider adjusting parent rate even if they
> > are allowed to do so. Such behaviour considerably lowers amount of
> > possible rates, which is very inconvenient when such clock is used for
> > pixel clock, for example.
> > 
> > In order to improve the situation, adjusting parent rate is considered
> > when allowed.
> > 
> > This code is inspired by clk_divider_bestdiv() function, which does
> > basically the same thing for different clock type.
> 
> This patch seems to break the eMMC support on Olinuxino-Lime2-eMMC boards:
> 
> EXT4-fs (mmcblk1p4): INFO: recovery required on readonly filesystem
> EXT4-fs (mmcblk1p4): write access will be enabled during recovery
> sunxi-mmc 1c11000.mmc: data error, sending stop command
> sunxi-mmc 1c11000.mmc: send stop command failed
> 

I'm not familiar with A20. What is interesting is that emmc clocks don't have 
CLK_SET_RATE_PARENT flag set, so you shouldn't see any difference.

Can you post content of clk_summary with and without this patch?

Best regards,
Jernej

> 
> $ git bisect log
> git bisect start
> # good: [3df407b2a5346db1c48809706ece7a8616c79e0b] mmc: dw_mmc-bluefield:
> simplify the probe() function git bisect good
> 3df407b2a5346db1c48809706ece7a8616c79e0b
> # bad: [00d59fde8532b2d42e80909d2e58678755e04da9] Merge tag 'mmc-v4.21' of
> git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc git bisect bad
> 00d59fde8532b2d42e80909d2e58678755e04da9
> # good: [01e421feec0817bb3141eaae4c517410d193d440] Merge branch 'fixes' into
> next git bisect good 01e421feec0817bb3141eaae4c517410d193d440
> # bad: [1eefdec18eded41833401cfd64749643ff72e7da] Merge branch
> 'locking-core-for-linus' of
> git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip git bisect bad
> 1eefdec18eded41833401cfd64749643ff72e7da
> # good: [eaa76499711535fd64d747cc4ef0d78ab0fd41c6] Merge tag 'mtd/for-4.21'
> of git://git.infradead.org/linux-mtd git bisect good
> eaa76499711535fd64d747cc4ef0d78ab0fd41c6
> # good: [4e4390ad067a61ce4e7607bd0df31f19a4caa36a] Merge tag
> 'leds-for-4.21-rc1' of
> git://git.kernel.org/pub/scm/linux/kernel/git/j.anaszewski/linux-leds git
> bisect good 4e4390ad067a61ce4e7607bd0df31f19a4caa36a
> # bad: [c2f1f3e0e17d94ab0c66d83e669492cb9e9a3698] Merge
> git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next git bisect
> bad c2f1f3e0e17d94ab0c66d83e669492cb9e9a3698
> # bad: [e4b99d415c3908581d4703203e1e805f043a3e71] Merge branch
> 'irq-core-for-linus' of
> git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip git bisect bad
> e4b99d415c3908581d4703203e1e805f043a3e71
> # bad: [ffe05540d18013db62c43627836a3638e9a2c7aa] Merge branches
> 'clk-renesas', 'clk-allwinner', 'clk-tegra', 'clk-meson' and 'clk-rockchip'
> into clk-next git bisect bad ffe05540d18013db62c43627836a3638e9a2c7aa
> # good: [1a501c8defe950571316d5ddd917bf44f5ed7bd4] Merge branches
> 'clk-managed-registration', 'clk-spdx', 'clk-remove-basic' and
> 'clk-ops-const' into clk-next git bisect good
> 1a501c8defe950571316d5ddd917bf44f5ed7bd4
> # good: [e74581b79ddd9b49b8c61e2791fc4dffc0245afb] Merge tag
> 'meson-clk-4.21-2' of https://github.com/BayLibre/clk-meson into clk-meson
> git bisect good e74581b79ddd9b49b8c61e2791fc4dffc0245afb
> # good: [60baf75e3f5b76043c25328ac0c5320aaef5ea41] Merge tag
> 'clk-renesas-for-v4.21-tag2' of
> git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers into
> clk-renesas git bisect good 60baf75e3f5b76043c25328ac0c5320aaef5ea41
> # bad: [a41f85b6017ee20952a60e4330bcae2527fe2c2a] Merge tag
> 'sunxi-clk-for-4.21' of
> https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux into
> clk-allwinner git bisect bad a41f85b6017ee20952a60e4330bcae2527fe2c2a
> # bad: [ee678706e46d0d185c27cc214ad97828e0643159] clk: sunxi-ng: a64: Fix
> gate bit of DSI DPHY git bisect bad
> ee678706e46d0d185c27cc214ad97828e0643159
> # bad: [65b6657672388b72822e0367f06d41c1e3ffb5bb] clk: sunxi-ng: Use u64 for
> calculation of NM rate git bisect bad
> 65b6657672388b72822e0367f06d41c1e3ffb5bb
> # good: [db7548934603d9eda12649dff97ea5c29884405d] clk: sunxi-ng: sun50i:
> h6: Fix MMC clock mux width git bisect good
> db7548934603d9eda12649dff97ea5c29884405d
> # bad: [3f790433c3cb27ecaf2ca0e07ac25964e4fd9f15] clk: sunxi-ng: Adjust MP
> clock parent rate when allowed git bisect bad
> 3f790433c3cb27ecaf2ca0e07ac25964e4fd9f15
> # first bad commit: [3f790433c3cb27ecaf2ca0e07ac25964e4fd9f15] clk:
> sunxi-ng: Adjust MP clock parent rate when allowed
> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> > ---
> > 
> >  drivers/clk/sunxi-ng/ccu_mp.c | 64 +++++++++++++++++++++++++++++++++--
> >  1 file changed, 62 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/clk/sunxi-ng/ccu_mp.c b/drivers/clk/sunxi-ng/ccu_mp.c
> > index 5d0af4051737..0357349eb767 100644
> > --- a/drivers/clk/sunxi-ng/ccu_mp.c
> > +++ b/drivers/clk/sunxi-ng/ccu_mp.c
> > @@ -40,6 +40,61 @@ static void ccu_mp_find_best(unsigned long parent,
> > unsigned long rate,> 
> >  	*p = best_p;
> >  
> >  }
> > 
> > +static unsigned long ccu_mp_find_best_with_parent_adj(struct clk_hw *hw,
> > +						      
unsigned long *parent,
> > +						      
unsigned long rate,
> > +						      
unsigned int max_m,
> > +						      
unsigned int max_p)
> > +{
> > +	unsigned long parent_rate_saved;
> > +	unsigned long parent_rate, now;
> > +	unsigned long best_rate = 0;
> > +	unsigned int _m, _p, div;
> > +	unsigned long maxdiv;
> > +
> > +	parent_rate_saved = *parent;
> > +
> > +	/*
> > +	 * The maximum divider we can use without overflowing
> > +	 * unsigned long in rate * m * p below
> > +	 */
> > +	maxdiv = max_m * max_p;
> > +	maxdiv = min(ULONG_MAX / rate, maxdiv);
> > +
> > +	for (_p = 1; _p <= max_p; _p <<= 1) {
> > +		for (_m = 1; _m <= max_m; _m++) {
> > +			div = _m * _p;
> > +
> > +			if (div > maxdiv)
> > +				break;
> > +
> > +			if (rate * div == parent_rate_saved) {
> > +				/*
> > +				 * It's the most ideal case if 
the requested
> > +				 * rate can be divided from 
parent clock without
> > +				 * needing to change parent rate, 
so return the
> > +				 * divider immediately.
> > +				 */
> > +				*parent = parent_rate_saved;
> > +				return rate;
> > +			}
> > +
> > +			parent_rate = clk_hw_round_rate(hw, rate * 
div);
> > +			now = parent_rate / div;
> > +
> > +			if (now <= rate && now > best_rate) {
> > +				best_rate = now;
> > +				*parent = parent_rate;
> > +
> > +				if (now == rate)
> > +					return rate;
> > +			}
> > +		}
> > +	}
> > +
> > +	return best_rate;
> > +}
> > +
> > 
> >  static unsigned long ccu_mp_round_rate(struct ccu_mux_internal *mux,
> >  
> >  				       struct clk_hw *hw,
> >  				       unsigned long 
*parent_rate,
> > 
> > @@ -56,8 +111,13 @@ static unsigned long ccu_mp_round_rate(struct
> > ccu_mux_internal *mux,> 
> >  	max_m = cmp->m.max ?: 1 << cmp->m.width;
> >  	max_p = cmp->p.max ?: 1 << ((1 << cmp->p.width) - 1);
> > 
> > -	ccu_mp_find_best(*parent_rate, rate, max_m, max_p, &m, &p);
> > -	rate = *parent_rate / p / m;
> > +	if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) {
> > +		ccu_mp_find_best(*parent_rate, rate, max_m, max_p, &m, 
&p);
> > +		rate = *parent_rate / p / m;
> > +	} else {
> > +		rate = ccu_mp_find_best_with_parent_adj(hw, parent_rate, 
rate,
> > +							
max_m, max_p);
> > +	}
> > 
> >  	if (cmp->common.features & CCU_FEATURE_FIXED_POSTDIV)
> >  	
> >  		rate /= cmp->fixed_post_div;





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

* Re: [linux-sunxi] [PATCH v3 02/28] clk: sunxi-ng: Adjust MP clock parent rate when allowed
  2019-01-10 17:10     ` Jernej Škrabec
@ 2019-01-16 12:09       ` Priit Laes
  2019-01-16 17:00         ` Jernej Škrabec
  0 siblings, 1 reply; 41+ messages in thread
From: Priit Laes @ 2019-01-16 12:09 UTC (permalink / raw)
  To: Jernej Škrabec
  Cc: maxime.ripard, wens, robh+dt, mturquette, sboyd, airlied,
	architt, a.hajda, Laurent.pinchart, devicetree, linux-arm-kernel,
	linux-kernel, linux-clk, dri-devel, linux-sunxi

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

On Thu, Jan 10, 2019 at 06:10:59PM +0100, Jernej Škrabec wrote:
> Dne četrtek, 10. januar 2019 ob 10:15:48 CET je Priit Laes napisal(a):
> > On Sun, Nov 04, 2018 at 07:26:39PM +0100, Jernej Skrabec wrote:
> > > Currently MP clocks don't consider adjusting parent rate even if they
> > > are allowed to do so. Such behaviour considerably lowers amount of
> > > possible rates, which is very inconvenient when such clock is used for
> > > pixel clock, for example.
> > > 
> > > In order to improve the situation, adjusting parent rate is considered
> > > when allowed.
> > > 
> > > This code is inspired by clk_divider_bestdiv() function, which does
> > > basically the same thing for different clock type.
> > 
> > This patch seems to break the eMMC support on Olinuxino-Lime2-eMMC boards:
> > 
> > EXT4-fs (mmcblk1p4): INFO: recovery required on readonly filesystem
> > EXT4-fs (mmcblk1p4): write access will be enabled during recovery
> > sunxi-mmc 1c11000.mmc: data error, sending stop command
> > sunxi-mmc 1c11000.mmc: send stop command failed
> > 
> 
> I'm not familiar with A20. What is interesting is that emmc clocks don't have 
> CLK_SET_RATE_PARENT flag set, so you shouldn't see any difference.
> 
> Can you post content of clk_summary with and without this patch?

In both cases I booted from FEL with rootfs on sdcard and tried to mount
partition from eMMC to /mnt. With your patch, last step it fails.

pre-patch working:
pll-ddr-other[768MHz] -> mmc2[512MHz]. (For some reason ahb-mmc2 is off?)

post-patch not working:
pll-periph[600MHz] ->  mmc2[500Mhz], (ahb-mmc2 is enabled)

Also, attached the logs.

> 
> Best regards,
> Jernej
> 
> > 
> > $ git bisect log
> > git bisect start
> > # good: [3df407b2a5346db1c48809706ece7a8616c79e0b] mmc: dw_mmc-bluefield:
> > simplify the probe() function git bisect good
> > 3df407b2a5346db1c48809706ece7a8616c79e0b
> > # bad: [00d59fde8532b2d42e80909d2e58678755e04da9] Merge tag 'mmc-v4.21' of
> > git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc git bisect bad
> > 00d59fde8532b2d42e80909d2e58678755e04da9
> > # good: [01e421feec0817bb3141eaae4c517410d193d440] Merge branch 'fixes' into
> > next git bisect good 01e421feec0817bb3141eaae4c517410d193d440
> > # bad: [1eefdec18eded41833401cfd64749643ff72e7da] Merge branch
> > 'locking-core-for-linus' of
> > git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip git bisect bad
> > 1eefdec18eded41833401cfd64749643ff72e7da
> > # good: [eaa76499711535fd64d747cc4ef0d78ab0fd41c6] Merge tag 'mtd/for-4.21'
> > of git://git.infradead.org/linux-mtd git bisect good
> > eaa76499711535fd64d747cc4ef0d78ab0fd41c6
> > # good: [4e4390ad067a61ce4e7607bd0df31f19a4caa36a] Merge tag
> > 'leds-for-4.21-rc1' of
> > git://git.kernel.org/pub/scm/linux/kernel/git/j.anaszewski/linux-leds git
> > bisect good 4e4390ad067a61ce4e7607bd0df31f19a4caa36a
> > # bad: [c2f1f3e0e17d94ab0c66d83e669492cb9e9a3698] Merge
> > git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next git bisect
> > bad c2f1f3e0e17d94ab0c66d83e669492cb9e9a3698
> > # bad: [e4b99d415c3908581d4703203e1e805f043a3e71] Merge branch
> > 'irq-core-for-linus' of
> > git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip git bisect bad
> > e4b99d415c3908581d4703203e1e805f043a3e71
> > # bad: [ffe05540d18013db62c43627836a3638e9a2c7aa] Merge branches
> > 'clk-renesas', 'clk-allwinner', 'clk-tegra', 'clk-meson' and 'clk-rockchip'
> > into clk-next git bisect bad ffe05540d18013db62c43627836a3638e9a2c7aa
> > # good: [1a501c8defe950571316d5ddd917bf44f5ed7bd4] Merge branches
> > 'clk-managed-registration', 'clk-spdx', 'clk-remove-basic' and
> > 'clk-ops-const' into clk-next git bisect good
> > 1a501c8defe950571316d5ddd917bf44f5ed7bd4
> > # good: [e74581b79ddd9b49b8c61e2791fc4dffc0245afb] Merge tag
> > 'meson-clk-4.21-2' of https://github.com/BayLibre/clk-meson into clk-meson
> > git bisect good e74581b79ddd9b49b8c61e2791fc4dffc0245afb
> > # good: [60baf75e3f5b76043c25328ac0c5320aaef5ea41] Merge tag
> > 'clk-renesas-for-v4.21-tag2' of
> > git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers into
> > clk-renesas git bisect good 60baf75e3f5b76043c25328ac0c5320aaef5ea41
> > # bad: [a41f85b6017ee20952a60e4330bcae2527fe2c2a] Merge tag
> > 'sunxi-clk-for-4.21' of
> > https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux into
> > clk-allwinner git bisect bad a41f85b6017ee20952a60e4330bcae2527fe2c2a
> > # bad: [ee678706e46d0d185c27cc214ad97828e0643159] clk: sunxi-ng: a64: Fix
> > gate bit of DSI DPHY git bisect bad
> > ee678706e46d0d185c27cc214ad97828e0643159
> > # bad: [65b6657672388b72822e0367f06d41c1e3ffb5bb] clk: sunxi-ng: Use u64 for
> > calculation of NM rate git bisect bad
> > 65b6657672388b72822e0367f06d41c1e3ffb5bb
> > # good: [db7548934603d9eda12649dff97ea5c29884405d] clk: sunxi-ng: sun50i:
> > h6: Fix MMC clock mux width git bisect good
> > db7548934603d9eda12649dff97ea5c29884405d
> > # bad: [3f790433c3cb27ecaf2ca0e07ac25964e4fd9f15] clk: sunxi-ng: Adjust MP
> > clock parent rate when allowed git bisect bad
> > 3f790433c3cb27ecaf2ca0e07ac25964e4fd9f15
> > # first bad commit: [3f790433c3cb27ecaf2ca0e07ac25964e4fd9f15] clk:
> > sunxi-ng: Adjust MP clock parent rate when allowed
> > > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> > > ---
> > > 
> > >  drivers/clk/sunxi-ng/ccu_mp.c | 64 +++++++++++++++++++++++++++++++++--
> > >  1 file changed, 62 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/drivers/clk/sunxi-ng/ccu_mp.c b/drivers/clk/sunxi-ng/ccu_mp.c
> > > index 5d0af4051737..0357349eb767 100644
> > > --- a/drivers/clk/sunxi-ng/ccu_mp.c
> > > +++ b/drivers/clk/sunxi-ng/ccu_mp.c
> > > @@ -40,6 +40,61 @@ static void ccu_mp_find_best(unsigned long parent,
> > > unsigned long rate,> 
> > >  	*p = best_p;
> > >  
> > >  }
> > > 
> > > +static unsigned long ccu_mp_find_best_with_parent_adj(struct clk_hw *hw,
> > > +						      
> unsigned long *parent,
> > > +						      
> unsigned long rate,
> > > +						      
> unsigned int max_m,
> > > +						      
> unsigned int max_p)
> > > +{
> > > +	unsigned long parent_rate_saved;
> > > +	unsigned long parent_rate, now;
> > > +	unsigned long best_rate = 0;
> > > +	unsigned int _m, _p, div;
> > > +	unsigned long maxdiv;
> > > +
> > > +	parent_rate_saved = *parent;
> > > +
> > > +	/*
> > > +	 * The maximum divider we can use without overflowing
> > > +	 * unsigned long in rate * m * p below
> > > +	 */
> > > +	maxdiv = max_m * max_p;
> > > +	maxdiv = min(ULONG_MAX / rate, maxdiv);
> > > +
> > > +	for (_p = 1; _p <= max_p; _p <<= 1) {
> > > +		for (_m = 1; _m <= max_m; _m++) {
> > > +			div = _m * _p;
> > > +
> > > +			if (div > maxdiv)
> > > +				break;
> > > +
> > > +			if (rate * div == parent_rate_saved) {
> > > +				/*
> > > +				 * It's the most ideal case if 
> the requested
> > > +				 * rate can be divided from 
> parent clock without
> > > +				 * needing to change parent rate, 
> so return the
> > > +				 * divider immediately.
> > > +				 */
> > > +				*parent = parent_rate_saved;
> > > +				return rate;
> > > +			}
> > > +
> > > +			parent_rate = clk_hw_round_rate(hw, rate * 
> div);
> > > +			now = parent_rate / div;
> > > +
> > > +			if (now <= rate && now > best_rate) {
> > > +				best_rate = now;
> > > +				*parent = parent_rate;
> > > +
> > > +				if (now == rate)
> > > +					return rate;
> > > +			}
> > > +		}
> > > +	}
> > > +
> > > +	return best_rate;
> > > +}
> > > +
> > > 
> > >  static unsigned long ccu_mp_round_rate(struct ccu_mux_internal *mux,
> > >  
> > >  				       struct clk_hw *hw,
> > >  				       unsigned long 
> *parent_rate,
> > > 
> > > @@ -56,8 +111,13 @@ static unsigned long ccu_mp_round_rate(struct
> > > ccu_mux_internal *mux,> 
> > >  	max_m = cmp->m.max ?: 1 << cmp->m.width;
> > >  	max_p = cmp->p.max ?: 1 << ((1 << cmp->p.width) - 1);
> > > 
> > > -	ccu_mp_find_best(*parent_rate, rate, max_m, max_p, &m, &p);
> > > -	rate = *parent_rate / p / m;
> > > +	if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) {
> > > +		ccu_mp_find_best(*parent_rate, rate, max_m, max_p, &m, 
> &p);
> > > +		rate = *parent_rate / p / m;
> > > +	} else {
> > > +		rate = ccu_mp_find_best_with_parent_adj(hw, parent_rate, 
> rate,
> > > +							
> max_m, max_p);
> > > +	}
> > > 
> > >  	if (cmp->common.features & CCU_FEATURE_FIXED_POSTDIV)
> > >  	
> > >  		rate /= cmp->fixed_post_div;
> 
> 
> 
> 
> -- 
> You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

[-- Attachment #2: pre-patch-clocks.log --]
[-- Type: text/plain, Size: 16826 bytes --]

                                 enable  prepare  protect                                duty
   clock                          count    count    count        rate   accuracy phase  cycle
---------------------------------------------------------------------------------------------
 gmac_int_tx                          1        1        0   125000000          0     0  50000
    gmac_tx                           1        1        0   125000000          0     0  50000
 mii_phy_tx                           0        0        0    25000000          0     0  50000
 osc32k                               0        0        0       32768          0     0  50000
 osc24M                               2        2        1    24000000          0     0  50000
    hosc                              6        6        1    24000000          0     0  50000
       out-b                          0        0        0       32000          0     0  50000
       out-a                          0        0        0       32000          0     0  50000
       hdmi1-slow                     0        0        0    24000000          0     0  50000
       avs                            0        0        0    24000000          0     0  50000
       csi1                           0        0        0    24000000          0     0  50000
       csi0                           0        0        0    24000000          0     0  50000
       spi3                           0        0        0    24000000          0     0  50000
       keypad                         0        0        0      750000          0     0  50000
       ir1                            0        0        0    24000000          0     0  50000
       ir0                            0        0        0    24000000          0     0  50000
       pata                           0        0        0    24000000          0     0  50000
       spi2                           0        0        0    24000000          0     0  50000
       spi1                           0        0        0    24000000          0     0  50000
       spi0                           0        0        0    24000000          0     0  50000
       ts                             0        0        0    24000000          0     0  50000
       mmc3                           0        0        0    24000000          0     0  50000
          mmc3_sample                 0        0        0    24000000          0   180  50000
          mmc3_output                 0        0        0    24000000          0   180  50000
       mmc1                           0        0        0    24000000          0     0  50000
          mmc1_sample                 0        0        0    24000000          0   180  50000
          mmc1_output                 0        0        0    24000000          0   180  50000
       ms                             0        0        0    24000000          0     0  50000
       nand                           0        0        0    24000000          0     0  50000
       apb1                           3        3        0    24000000          0     0  50000
          apb1-uart7                  0        0        0    24000000          0     0  50000
          apb1-uart6                  0        0        0    24000000          0     0  50000
          apb1-uart5                  0        0        0    24000000          0     0  50000
          apb1-uart4                  0        0        0    24000000          0     0  50000
          apb1-uart3                  0        0        0    24000000          0     0  50000
          apb1-uart2                  0        0        0    24000000          0     0  50000
          apb1-uart1                  0        0        0    24000000          0     0  50000
          apb1-uart0                  1        1        0    24000000          0     0  50000
          apb1-i2c4                   0        0        0    24000000          0     0  50000
          apb1-ps21                   0        0        0    24000000          0     0  50000
          apb1-ps20                   0        0        0    24000000          0     0  50000
          apb1-scr                    0        0        0    24000000          0     0  50000
          apb1-can                    0        0        0    24000000          0     0  50000
          apb1-i2c3                   0        0        0    24000000          0     0  50000
          apb1-i2c2                   0        0        0    24000000          0     0  50000
          apb1-i2c1                   1        1        0    24000000          0     0  50000
          apb1-i2c0                   1        1        0    24000000          0     0  50000
       pll-gpu                        0        0        0  1200000000          0     0  50000
       pll-video1                     1        1        0   327000000          0     0  50000
          pll-video1-2x               1        1        0   654000000          0     0  50000
             hdmi-tmds                1        1        0    25153846          0     0  50000
                hdmi-ddc              1        1        0       89835          0     0  50000
       pll-periph-base                3        3        0  1200000000          0     0  50000
          mbus                        1        1        0   300000000          0     0  50000
          pll-periph-sata             1        1        0   100000000          0     0  50000
             sata                     1        1        0   100000000          0     0  50000
          pll-periph                  5        5        0   600000000          0     0  50000
             mmc0                     0        0        0    50000000          0     0  50000
                mmc0_sample           0        0        0    50000000          0   120  50000
                mmc0_output           0        0        0    50000000          0    90  50000
             ss                       1        1        0   150000000          0     0  50000
             usb-phy                  3        3        0   600000000          0     0  50000
             usb-ohci1                1        1        0   600000000          0     0  50000
             usb-ohci0                1        1        0   600000000          0     0  50000
             ahb                     17       17        0   300000000          0     0  50000
                ahb-gpu               0        0        0   300000000          0     0  50000
                ahb-mp                0        0        0   300000000          0     0  50000
                ahb-gmac              1        1        0   300000000          0     0  50000
                ahb-de-fe1            0        0        0   300000000          0     0  50000
                ahb-de-fe0            0        0        0   300000000          0     0  50000
                ahb-de-be1            1        1        0   300000000          0     0  50000
                ahb-de-be0            1        1        0   300000000          0     0  50000
                ahb-hdmi1             0        0        0   300000000          0     0  50000
                ahb-hdmi0             1        1        0   300000000          0     0  50000
                ahb-csi1              0        0        0   300000000          0     0  50000
                ahb-csi0              0        0        0   300000000          0     0  50000
                ahb-lcd1              1        1        0   300000000          0     0  50000
                ahb-lcd0              1        1        0   300000000          0     0  50000
                ahb-tve1              0        0        0   300000000          0     0  50000
                ahb-tve0              0        0        0   300000000          0     0  50000
                ahb-tvd               0        0        0   300000000          0     0  50000
                ahb-ve                0        0        0   300000000          0     0  50000
                ahb-hstimer           2        2        0   300000000          0     0  50000
                ahb-sata              1        1        0   300000000          0     0  50000
                ahb-pata              0        0        0   300000000          0     0  50000
                ahb-spi3              0        0        0   300000000          0     0  50000
                ahb-spi2              0        0        0   300000000          0     0  50000
                ahb-spi1              0        0        0   300000000          0     0  50000
                ahb-spi0              0        0        0   300000000          0     0  50000
                ahb-ts                0        0        0   300000000          0     0  50000
                ahb-emac              0        0        0   300000000          0     0  50000
                ahb-ace               0        0        0   300000000          0     0  50000
                ahb-sdram             1        1        0   300000000          0     0  50000
                ahb-nand              0        0        0   300000000          0     0  50000
                ahb-ms                0        0        0   300000000          0     0  50000
                ahb-mmc3              0        0        0   300000000          0     0  50000
                ahb-mmc2              0        0        0   300000000          0     0  50000
                ahb-mmc1              0        0        0   300000000          0     0  50000
                ahb-mmc0              0        0        0   300000000          0     0  50000
                ahb-bist              0        0        0   300000000          0     0  50000
                ahb-dma               1        1        0   300000000          0     0  50000
                ahb-ss                1        1        0   300000000          0     0  50000
                ahb-ohci1             1        1        0   300000000          0     0  50000
                ahb-ehci1             1        1        0   300000000          0     0  50000
                ahb-ohci0             1        1        0   300000000          0     0  50000
                ahb-ehci0             1        1        0   300000000          0     0  50000
                ahb-otg               1        1        0   300000000          0     0  50000
                apb0                  1        1        0   150000000          0     0  50000
                   apb0-keypad        0        0        0   150000000          0     0  50000
                   apb0-i2s2          0        0        0   150000000          0     0  50000
                   apb0-ir1           0        0        0   150000000          0     0  50000
                   apb0-ir0           0        0        0   150000000          0     0  50000
                   apb0-pio           1        1        0   150000000          0     0  50000
                   apb0-i2s1          0        0        0   150000000          0     0  50000
                   apb0-ac97          0        0        0   150000000          0     0  50000
                   apb0-i2s0          0        0        0   150000000          0     0  50000
                   apb0-spdif         0        0        0   150000000          0     0  50000
                   apb0-codec         0        0        0   150000000          0     0  50000
       pll-ddr-base                   2        2        0   768000000          0     0  50000
          pll-ddr-other               1        1        0   768000000          0     0  50000
             mmc2                     0        0        0    51200000          0     0  50000
                mmc2_sample           0        0        0    51200000          0   120  50000
                mmc2_output           0        0        0    51200000          0    72  50000
             de-be0                   1        1        0   256000000          0     0  50000
          pll-ddr                     4        4        0   384000000          0     0  50000
             dram-ace                 0        0        0   384000000          0     0  50000
             dram-mp                  0        0        0   384000000          0     0  50000
             dram-de-be1              1        1        0   384000000          0     0  50000
             dram-de-be0              1        1        0   384000000          0     0  50000
             dram-de-fe0              0        0        0   384000000          0     0  50000
             dram-de-fe1              0        0        0   384000000          0     0  50000
             dram-out                 1        1        0   384000000          0     0  50000
             dram-tve1                0        0        0   384000000          0     0  50000
             dram-tve0                0        0        0   384000000          0     0  50000
             dram-tvd                 0        0        0   384000000          0     0  50000
             dram-ts                  0        0        0   384000000          0     0  50000
             dram-csi1                0        0        0   384000000          0     0  50000
             dram-csi0                0        0        0   384000000          0     0  50000
             dram-ve                  0        0        0   384000000          0     0  50000
       pll-ve                         0        0        0  1200000000          0     0  50000
          ace                         0        0        0  1200000000          0     0  50000
          ve                          0        0        0  1200000000          0     0  50000
       pll-video0                     3        3        1   327000000          0     0  50000
          hdmi1                       0        0        0   327000000          0     0  50000
          gpu                         0        0        0   327000000          0     0  50000
          hdmi                        1        1        0    25153847          0     0  50000
          tcon1-ch1-sclk2             0        0        0   327000000          0     0  50000
             tcon1-ch1-sclk1          0        0        0   327000000          0     0  50000
          tcon0-ch1-sclk2             1        1        1    25153847          0     0  50000
             tcon0-ch1-sclk1          1        1        1    25153847          0     0  50000
          tvd-sclk2                   0        0        0   327000000          0     0  50000
             tvd-sclk1                0        0        0   327000000          0     0  50000
          csi-sclk                    0        0        0   327000000          0     0  50000
          tcon1-ch0-sclk              0        0        0   327000000          0     0  50000
             tcon1-pixel-clock        0        0        0   327000000          0     0  50000
          tcon0-ch0-sclk              0        0        0   327000000          0     0  50000
             tcon0-pixel-clock        0        0        0   327000000          0     0  50000
          de-mp                       0        0        0   327000000          0     0  50000
          de-fe1                      0        0        0   327000000          0     0  50000
          de-fe0                      0        0        0   327000000          0     0  50000
          de-be1                      1        1        0   327000000          0     0  50000
          pll-video0-2x               0        0        0   654000000          0     0  50000
       pll-audio-base                 0        0        0     1500000          0     0  50000
          pll-audio-8x                0        0        0     3000000          0     0  50000
             i2s2                     0        0        0     3000000          0     0  50000
             i2s1                     0        0        0     3000000          0     0  50000
             i2s0                     0        0        0     3000000          0     0  50000
          pll-audio-4x                0        0        0     1500000          0     0  50000
             spdif                    0        0        0     1500000          0     0  50000
          pll-audio-2x                0        0        0      750000          0     0  50000
          pll-audio                   0        0        0     1500000          0     0  50000
             codec                    0        0        0     1500000          0     0  50000
             ac97                     0        0        0     1500000          0     0  50000
       pll-core                       1        1        0   960000000          0     0  50000
          cpu                         1        1        0   960000000          0     0  50000
             axi                      0        0        0   320000000          0     0  50000

[-- Attachment #3: post-patch-clocks.log --]
[-- Type: text/plain, Size: 16826 bytes --]

                                 enable  prepare  protect                                duty
   clock                          count    count    count        rate   accuracy phase  cycle
---------------------------------------------------------------------------------------------
 gmac_int_tx                          1        1        0   125000000          0     0  50000
    gmac_tx                           1        1        0   125000000          0     0  50000
 mii_phy_tx                           0        0        0    25000000          0     0  50000
 osc32k                               0        0        0       32768          0     0  50000
 osc24M                               2        2        1    24000000          0     0  50000
    hosc                              6        6        1    24000000          0     0  50000
       out-b                          0        0        0       32000          0     0  50000
       out-a                          0        0        0       32000          0     0  50000
       hdmi1-slow                     0        0        0    24000000          0     0  50000
       avs                            0        0        0    24000000          0     0  50000
       csi1                           0        0        0    24000000          0     0  50000
       csi0                           0        0        0    24000000          0     0  50000
       spi3                           0        0        0    24000000          0     0  50000
       keypad                         0        0        0      750000          0     0  50000
       ir1                            0        0        0    24000000          0     0  50000
       ir0                            0        0        0    24000000          0     0  50000
       pata                           0        0        0    24000000          0     0  50000
       spi2                           0        0        0    24000000          0     0  50000
       spi1                           0        0        0    24000000          0     0  50000
       spi0                           0        0        0    24000000          0     0  50000
       ts                             0        0        0    24000000          0     0  50000
       mmc3                           0        0        0    24000000          0     0  50000
          mmc3_sample                 0        0        0    24000000          0   180  50000
          mmc3_output                 0        0        0    24000000          0   180  50000
       mmc1                           0        0        0    24000000          0     0  50000
          mmc1_sample                 0        0        0    24000000          0   180  50000
          mmc1_output                 0        0        0    24000000          0   180  50000
       ms                             0        0        0    24000000          0     0  50000
       nand                           0        0        0    24000000          0     0  50000
       apb1                           3        3        0    24000000          0     0  50000
          apb1-uart7                  0        0        0    24000000          0     0  50000
          apb1-uart6                  0        0        0    24000000          0     0  50000
          apb1-uart5                  0        0        0    24000000          0     0  50000
          apb1-uart4                  0        0        0    24000000          0     0  50000
          apb1-uart3                  0        0        0    24000000          0     0  50000
          apb1-uart2                  0        0        0    24000000          0     0  50000
          apb1-uart1                  0        0        0    24000000          0     0  50000
          apb1-uart0                  1        1        0    24000000          0     0  50000
          apb1-i2c4                   0        0        0    24000000          0     0  50000
          apb1-ps21                   0        0        0    24000000          0     0  50000
          apb1-ps20                   0        0        0    24000000          0     0  50000
          apb1-scr                    0        0        0    24000000          0     0  50000
          apb1-can                    0        0        0    24000000          0     0  50000
          apb1-i2c3                   0        0        0    24000000          0     0  50000
          apb1-i2c2                   0        0        0    24000000          0     0  50000
          apb1-i2c1                   1        1        0    24000000          0     0  50000
          apb1-i2c0                   1        1        0    24000000          0     0  50000
       pll-gpu                        0        0        0  1200000000          0     0  50000
       pll-video1                     1        1        0   327000000          0     0  50000
          pll-video1-2x               1        1        0   654000000          0     0  50000
             hdmi-tmds                1        1        0    25153846          0     0  50000
                hdmi-ddc              1        1        0       89835          0     0  50000
       pll-periph-base                3        3        0  1200000000          0     0  50000
          mbus                        1        1        0   300000000          0     0  50000
          pll-periph-sata             1        1        0   100000000          0     0  50000
             sata                     1        1        0   100000000          0     0  50000
          pll-periph                  6        6        0   600000000          0     0  50000
             mmc2                     3        3        0    50000000          0     0  50000
                mmc2_sample           1        1        0    50000000          0   120  50000
                mmc2_output           1        1        0    50000000          0    60  50000
             mmc0                     0        0        0    50000000          0     0  50000
                mmc0_sample           0        0        0    50000000          0   120  50000
                mmc0_output           0        0        0    50000000          0    90  50000
             ss                       1        1        0   150000000          0     0  50000
             usb-phy                  3        3        0   600000000          0     0  50000
             usb-ohci1                1        1        0   600000000          0     0  50000
             usb-ohci0                1        1        0   600000000          0     0  50000
             ahb                     18       18        0   300000000          0     0  50000
                ahb-gpu               0        0        0   300000000          0     0  50000
                ahb-mp                0        0        0   300000000          0     0  50000
                ahb-gmac              1        1        0   300000000          0     0  50000
                ahb-de-fe1            0        0        0   300000000          0     0  50000
                ahb-de-fe0            0        0        0   300000000          0     0  50000
                ahb-de-be1            1        1        0   300000000          0     0  50000
                ahb-de-be0            1        1        0   300000000          0     0  50000
                ahb-hdmi1             0        0        0   300000000          0     0  50000
                ahb-hdmi0             1        1        0   300000000          0     0  50000
                ahb-csi1              0        0        0   300000000          0     0  50000
                ahb-csi0              0        0        0   300000000          0     0  50000
                ahb-lcd1              1        1        0   300000000          0     0  50000
                ahb-lcd0              1        1        0   300000000          0     0  50000
                ahb-tve1              0        0        0   300000000          0     0  50000
                ahb-tve0              0        0        0   300000000          0     0  50000
                ahb-tvd               0        0        0   300000000          0     0  50000
                ahb-ve                0        0        0   300000000          0     0  50000
                ahb-hstimer           2        2        0   300000000          0     0  50000
                ahb-sata              1        1        0   300000000          0     0  50000
                ahb-pata              0        0        0   300000000          0     0  50000
                ahb-spi3              0        0        0   300000000          0     0  50000
                ahb-spi2              0        0        0   300000000          0     0  50000
                ahb-spi1              0        0        0   300000000          0     0  50000
                ahb-spi0              0        0        0   300000000          0     0  50000
                ahb-ts                0        0        0   300000000          0     0  50000
                ahb-emac              0        0        0   300000000          0     0  50000
                ahb-ace               0        0        0   300000000          0     0  50000
                ahb-sdram             1        1        0   300000000          0     0  50000
                ahb-nand              0        0        0   300000000          0     0  50000
                ahb-ms                0        0        0   300000000          0     0  50000
                ahb-mmc3              0        0        0   300000000          0     0  50000
                ahb-mmc2              1        1        0   300000000          0     0  50000
                ahb-mmc1              0        0        0   300000000          0     0  50000
                ahb-mmc0              0        0        0   300000000          0     0  50000
                ahb-bist              0        0        0   300000000          0     0  50000
                ahb-dma               1        1        0   300000000          0     0  50000
                ahb-ss                1        1        0   300000000          0     0  50000
                ahb-ohci1             1        1        0   300000000          0     0  50000
                ahb-ehci1             1        1        0   300000000          0     0  50000
                ahb-ohci0             1        1        0   300000000          0     0  50000
                ahb-ehci0             1        1        0   300000000          0     0  50000
                ahb-otg               1        1        0   300000000          0     0  50000
                apb0                  1        1        0   150000000          0     0  50000
                   apb0-keypad        0        0        0   150000000          0     0  50000
                   apb0-i2s2          0        0        0   150000000          0     0  50000
                   apb0-ir1           0        0        0   150000000          0     0  50000
                   apb0-ir0           0        0        0   150000000          0     0  50000
                   apb0-pio           1        1        0   150000000          0     0  50000
                   apb0-i2s1          0        0        0   150000000          0     0  50000
                   apb0-ac97          0        0        0   150000000          0     0  50000
                   apb0-i2s0          0        0        0   150000000          0     0  50000
                   apb0-spdif         0        0        0   150000000          0     0  50000
                   apb0-codec         0        0        0   150000000          0     0  50000
       pll-ddr-base                   2        2        0   768000000          0     0  50000
          pll-ddr-other               1        1        0   768000000          0     0  50000
             de-be0                   1        1        0   256000000          0     0  50000
          pll-ddr                     4        4        0   384000000          0     0  50000
             dram-ace                 0        0        0   384000000          0     0  50000
             dram-mp                  0        0        0   384000000          0     0  50000
             dram-de-be1              1        1        0   384000000          0     0  50000
             dram-de-be0              1        1        0   384000000          0     0  50000
             dram-de-fe0              0        0        0   384000000          0     0  50000
             dram-de-fe1              0        0        0   384000000          0     0  50000
             dram-out                 1        1        0   384000000          0     0  50000
             dram-tve1                0        0        0   384000000          0     0  50000
             dram-tve0                0        0        0   384000000          0     0  50000
             dram-tvd                 0        0        0   384000000          0     0  50000
             dram-ts                  0        0        0   384000000          0     0  50000
             dram-csi1                0        0        0   384000000          0     0  50000
             dram-csi0                0        0        0   384000000          0     0  50000
             dram-ve                  0        0        0   384000000          0     0  50000
       pll-ve                         0        0        0  1200000000          0     0  50000
          ace                         0        0        0  1200000000          0     0  50000
          ve                          0        0        0  1200000000          0     0  50000
       pll-video0                     3        3        1   327000000          0     0  50000
          hdmi1                       0        0        0   327000000          0     0  50000
          gpu                         0        0        0   327000000          0     0  50000
          hdmi                        1        1        0    25153847          0     0  50000
          tcon1-ch1-sclk2             0        0        0   327000000          0     0  50000
             tcon1-ch1-sclk1          0        0        0   327000000          0     0  50000
          tcon0-ch1-sclk2             1        1        1    25153847          0     0  50000
             tcon0-ch1-sclk1          1        1        1    25153847          0     0  50000
          tvd-sclk2                   0        0        0   327000000          0     0  50000
             tvd-sclk1                0        0        0   327000000          0     0  50000
          csi-sclk                    0        0        0   327000000          0     0  50000
          tcon1-ch0-sclk              0        0        0   327000000          0     0  50000
             tcon1-pixel-clock        0        0        0   327000000          0     0  50000
          tcon0-ch0-sclk              0        0        0   327000000          0     0  50000
             tcon0-pixel-clock        0        0        0   327000000          0     0  50000
          de-mp                       0        0        0   327000000          0     0  50000
          de-fe1                      0        0        0   327000000          0     0  50000
          de-fe0                      0        0        0   327000000          0     0  50000
          de-be1                      1        1        0   327000000          0     0  50000
          pll-video0-2x               0        0        0   654000000          0     0  50000
       pll-audio-base                 0        0        0     1500000          0     0  50000
          pll-audio-8x                0        0        0     3000000          0     0  50000
             i2s2                     0        0        0     3000000          0     0  50000
             i2s1                     0        0        0     3000000          0     0  50000
             i2s0                     0        0        0     3000000          0     0  50000
          pll-audio-4x                0        0        0     1500000          0     0  50000
             spdif                    0        0        0     1500000          0     0  50000
          pll-audio-2x                0        0        0      750000          0     0  50000
          pll-audio                   0        0        0     1500000          0     0  50000
             codec                    0        0        0     1500000          0     0  50000
             ac97                     0        0        0     1500000          0     0  50000
       pll-core                       1        1        0   960000000          0     0  50000
          cpu                         1        1        0   960000000          0     0  50000
             axi                      0        0        0   320000000          0     0  50000

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

* Re: [linux-sunxi] [PATCH v3 02/28] clk: sunxi-ng: Adjust MP clock parent rate when allowed
  2019-01-16 12:09       ` Priit Laes
@ 2019-01-16 17:00         ` Jernej Škrabec
  2019-01-17  7:24           ` Priit Laes
  0 siblings, 1 reply; 41+ messages in thread
From: Jernej Škrabec @ 2019-01-16 17:00 UTC (permalink / raw)
  To: Priit Laes
  Cc: maxime.ripard, wens, robh+dt, mturquette, sboyd, airlied,
	architt, a.hajda, Laurent.pinchart, devicetree, linux-arm-kernel,
	linux-kernel, linux-clk, dri-devel, linux-sunxi

Dne sreda, 16. januar 2019 ob 13:09:58 CET je Priit Laes napisal(a):
> On Thu, Jan 10, 2019 at 06:10:59PM +0100, Jernej Škrabec wrote:
> > Dne četrtek, 10. januar 2019 ob 10:15:48 CET je Priit Laes napisal(a):
> > > On Sun, Nov 04, 2018 at 07:26:39PM +0100, Jernej Skrabec wrote:
> > > > Currently MP clocks don't consider adjusting parent rate even if they
> > > > are allowed to do so. Such behaviour considerably lowers amount of
> > > > possible rates, which is very inconvenient when such clock is used for
> > > > pixel clock, for example.
> > > > 
> > > > In order to improve the situation, adjusting parent rate is considered
> > > > when allowed.
> > > > 
> > > > This code is inspired by clk_divider_bestdiv() function, which does
> > > > basically the same thing for different clock type.
> > > 
> > > This patch seems to break the eMMC support on Olinuxino-Lime2-eMMC
> > > boards:
> > > 
> > > EXT4-fs (mmcblk1p4): INFO: recovery required on readonly filesystem
> > > EXT4-fs (mmcblk1p4): write access will be enabled during recovery
> > > sunxi-mmc 1c11000.mmc: data error, sending stop command
> > > sunxi-mmc 1c11000.mmc: send stop command failed
> > 
> > I'm not familiar with A20. What is interesting is that emmc clocks don't
> > have CLK_SET_RATE_PARENT flag set, so you shouldn't see any difference.
> > 
> > Can you post content of clk_summary with and without this patch?
> 
> In both cases I booted from FEL with rootfs on sdcard and tried to mount
> partition from eMMC to /mnt. With your patch, last step it fails.
> 
> pre-patch working:
> pll-ddr-other[768MHz] -> mmc2[512MHz]. (For some reason ahb-mmc2 is off?)
> 
> post-patch not working:
> pll-periph[600MHz] ->  mmc2[500Mhz], (ahb-mmc2 is enabled)
> 
> Also, attached the logs.

Thanks. Just one more request. Can you enable debug messages in mmc driver? 
I'm interested in output of this line:

dev_dbg(mmc_dev(mmc), "setting clk to %d, rounded %ld\n",
		clock, rate);

Just wondering what it should be.

Best regards,
Jernej

> 
> > Best regards,
> > Jernej
> > 
> > > $ git bisect log
> > > git bisect start
> > > # good: [3df407b2a5346db1c48809706ece7a8616c79e0b] mmc:
> > > dw_mmc-bluefield:
> > > simplify the probe() function git bisect good
> > > 3df407b2a5346db1c48809706ece7a8616c79e0b
> > > # bad: [00d59fde8532b2d42e80909d2e58678755e04da9] Merge tag 'mmc-v4.21'
> > > of
> > > git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc git bisect bad
> > > 00d59fde8532b2d42e80909d2e58678755e04da9
> > > # good: [01e421feec0817bb3141eaae4c517410d193d440] Merge branch 'fixes'
> > > into next git bisect good 01e421feec0817bb3141eaae4c517410d193d440
> > > # bad: [1eefdec18eded41833401cfd64749643ff72e7da] Merge branch
> > > 'locking-core-for-linus' of
> > > git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip git bisect bad
> > > 1eefdec18eded41833401cfd64749643ff72e7da
> > > # good: [eaa76499711535fd64d747cc4ef0d78ab0fd41c6] Merge tag
> > > 'mtd/for-4.21'
> > > of git://git.infradead.org/linux-mtd git bisect good
> > > eaa76499711535fd64d747cc4ef0d78ab0fd41c6
> > > # good: [4e4390ad067a61ce4e7607bd0df31f19a4caa36a] Merge tag
> > > 'leds-for-4.21-rc1' of
> > > git://git.kernel.org/pub/scm/linux/kernel/git/j.anaszewski/linux-leds
> > > git
> > > bisect good 4e4390ad067a61ce4e7607bd0df31f19a4caa36a
> > > # bad: [c2f1f3e0e17d94ab0c66d83e669492cb9e9a3698] Merge
> > > git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next git
> > > bisect
> > > bad c2f1f3e0e17d94ab0c66d83e669492cb9e9a3698
> > > # bad: [e4b99d415c3908581d4703203e1e805f043a3e71] Merge branch
> > > 'irq-core-for-linus' of
> > > git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip git bisect bad
> > > e4b99d415c3908581d4703203e1e805f043a3e71
> > > # bad: [ffe05540d18013db62c43627836a3638e9a2c7aa] Merge branches
> > > 'clk-renesas', 'clk-allwinner', 'clk-tegra', 'clk-meson' and
> > > 'clk-rockchip'
> > > into clk-next git bisect bad ffe05540d18013db62c43627836a3638e9a2c7aa
> > > # good: [1a501c8defe950571316d5ddd917bf44f5ed7bd4] Merge branches
> > > 'clk-managed-registration', 'clk-spdx', 'clk-remove-basic' and
> > > 'clk-ops-const' into clk-next git bisect good
> > > 1a501c8defe950571316d5ddd917bf44f5ed7bd4
> > > # good: [e74581b79ddd9b49b8c61e2791fc4dffc0245afb] Merge tag
> > > 'meson-clk-4.21-2' of https://github.com/BayLibre/clk-meson into
> > > clk-meson
> > > git bisect good e74581b79ddd9b49b8c61e2791fc4dffc0245afb
> > > # good: [60baf75e3f5b76043c25328ac0c5320aaef5ea41] Merge tag
> > > 'clk-renesas-for-v4.21-tag2' of
> > > git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers into
> > > clk-renesas git bisect good 60baf75e3f5b76043c25328ac0c5320aaef5ea41
> > > # bad: [a41f85b6017ee20952a60e4330bcae2527fe2c2a] Merge tag
> > > 'sunxi-clk-for-4.21' of
> > > https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux into
> > > clk-allwinner git bisect bad a41f85b6017ee20952a60e4330bcae2527fe2c2a
> > > # bad: [ee678706e46d0d185c27cc214ad97828e0643159] clk: sunxi-ng: a64:
> > > Fix
> > > gate bit of DSI DPHY git bisect bad
> > > ee678706e46d0d185c27cc214ad97828e0643159
> > > # bad: [65b6657672388b72822e0367f06d41c1e3ffb5bb] clk: sunxi-ng: Use u64
> > > for calculation of NM rate git bisect bad
> > > 65b6657672388b72822e0367f06d41c1e3ffb5bb
> > > # good: [db7548934603d9eda12649dff97ea5c29884405d] clk: sunxi-ng:
> > > sun50i:
> > > h6: Fix MMC clock mux width git bisect good
> > > db7548934603d9eda12649dff97ea5c29884405d
> > > # bad: [3f790433c3cb27ecaf2ca0e07ac25964e4fd9f15] clk: sunxi-ng: Adjust
> > > MP
> > > clock parent rate when allowed git bisect bad
> > > 3f790433c3cb27ecaf2ca0e07ac25964e4fd9f15
> > > # first bad commit: [3f790433c3cb27ecaf2ca0e07ac25964e4fd9f15] clk:
> > > sunxi-ng: Adjust MP clock parent rate when allowed
> > > 
> > > > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> > > > ---
> > > > 
> > > >  drivers/clk/sunxi-ng/ccu_mp.c | 64
> > > >  +++++++++++++++++++++++++++++++++--
> > > >  1 file changed, 62 insertions(+), 2 deletions(-)
> > > > 
> > > > diff --git a/drivers/clk/sunxi-ng/ccu_mp.c
> > > > b/drivers/clk/sunxi-ng/ccu_mp.c
> > > > index 5d0af4051737..0357349eb767 100644
> > > > --- a/drivers/clk/sunxi-ng/ccu_mp.c
> > > > +++ b/drivers/clk/sunxi-ng/ccu_mp.c
> > > > @@ -40,6 +40,61 @@ static void ccu_mp_find_best(unsigned long parent,
> > > > unsigned long rate,>
> > > > 
> > > >  	*p = best_p;
> > > >  
> > > >  }
> > > > 
> > > > +static unsigned long ccu_mp_find_best_with_parent_adj(struct clk_hw
> > > > *hw,
> > > > +
> > 
> > unsigned long *parent,
> > 
> > > > +
> > 
> > unsigned long rate,
> > 
> > > > +
> > 
> > unsigned int max_m,
> > 
> > > > +
> > 
> > unsigned int max_p)
> > 
> > > > +{
> > > > +	unsigned long parent_rate_saved;
> > > > +	unsigned long parent_rate, now;
> > > > +	unsigned long best_rate = 0;
> > > > +	unsigned int _m, _p, div;
> > > > +	unsigned long maxdiv;
> > > > +
> > > > +	parent_rate_saved = *parent;
> > > > +
> > > > +	/*
> > > > +	 * The maximum divider we can use without overflowing
> > > > +	 * unsigned long in rate * m * p below
> > > > +	 */
> > > > +	maxdiv = max_m * max_p;
> > > > +	maxdiv = min(ULONG_MAX / rate, maxdiv);
> > > > +
> > > > +	for (_p = 1; _p <= max_p; _p <<= 1) {
> > > > +		for (_m = 1; _m <= max_m; _m++) {
> > > > +			div = _m * _p;
> > > > +
> > > > +			if (div > maxdiv)
> > > > +				break;
> > > > +
> > > > +			if (rate * div == parent_rate_saved) {
> > > > +				/*
> > > > +				 * It's the most ideal case if
> > 
> > the requested
> > 
> > > > +				 * rate can be divided from
> > 
> > parent clock without
> > 
> > > > +				 * needing to change parent 
rate,
> > 
> > so return the
> > 
> > > > +				 * divider immediately.
> > > > +				 */
> > > > +				*parent = parent_rate_saved;
> > > > +				return rate;
> > > > +			}
> > > > +
> > > > +			parent_rate = clk_hw_round_rate(hw, rate *
> > 
> > div);
> > 
> > > > +			now = parent_rate / div;
> > > > +
> > > > +			if (now <= rate && now > best_rate) {
> > > > +				best_rate = now;
> > > > +				*parent = parent_rate;
> > > > +
> > > > +				if (now == rate)
> > > > +					return rate;
> > > > +			}
> > > > +		}
> > > > +	}
> > > > +
> > > > +	return best_rate;
> > > > +}
> > > > +
> > > > 
> > > >  static unsigned long ccu_mp_round_rate(struct ccu_mux_internal *mux,
> > > >  
> > > >  				       struct clk_hw *hw,
> > > >  				       unsigned long
> > 
> > *parent_rate,
> > 
> > > > @@ -56,8 +111,13 @@ static unsigned long ccu_mp_round_rate(struct
> > > > ccu_mux_internal *mux,>
> > > > 
> > > >  	max_m = cmp->m.max ?: 1 << cmp->m.width;
> > > >  	max_p = cmp->p.max ?: 1 << ((1 << cmp->p.width) - 1);
> > > > 
> > > > -	ccu_mp_find_best(*parent_rate, rate, max_m, max_p, &m, &p);
> > > > -	rate = *parent_rate / p / m;
> > > > +	if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) {
> > > > +		ccu_mp_find_best(*parent_rate, rate, max_m, max_p, &m,
> > 
> > &p);
> > 
> > > > +		rate = *parent_rate / p / m;
> > > > +	} else {
> > > > +		rate = ccu_mp_find_best_with_parent_adj(hw, 
parent_rate,
> > 
> > rate,
> > 
> > > > +
> > 
> > max_m, max_p);
> > 
> > > > +	}
> > > > 
> > > >  	if (cmp->common.features & CCU_FEATURE_FIXED_POSTDIV)
> > > >  	
> > > >  		rate /= cmp->fixed_post_div;





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

* Re: [linux-sunxi] [PATCH v3 02/28] clk: sunxi-ng: Adjust MP clock parent rate when allowed
  2019-01-16 17:00         ` Jernej Škrabec
@ 2019-01-17  7:24           ` Priit Laes
  2019-01-18 21:51             ` Jernej Škrabec
  0 siblings, 1 reply; 41+ messages in thread
From: Priit Laes @ 2019-01-17  7:24 UTC (permalink / raw)
  To: Jernej Škrabec
  Cc: maxime.ripard, wens, robh+dt, mturquette, sboyd, airlied,
	architt, a.hajda, Laurent.pinchart, devicetree, linux-arm-kernel,
	linux-kernel, linux-clk, dri-devel, linux-sunxi

On Wed, Jan 16, 2019 at 06:00:32PM +0100, Jernej Škrabec wrote:
> Dne sreda, 16. januar 2019 ob 13:09:58 CET je Priit Laes napisal(a):
> > On Thu, Jan 10, 2019 at 06:10:59PM +0100, Jernej Škrabec wrote:
> > > Dne četrtek, 10. januar 2019 ob 10:15:48 CET je Priit Laes napisal(a):
> > > > On Sun, Nov 04, 2018 at 07:26:39PM +0100, Jernej Skrabec wrote:
> > > > > Currently MP clocks don't consider adjusting parent rate even if they
> > > > > are allowed to do so. Such behaviour considerably lowers amount of
> > > > > possible rates, which is very inconvenient when such clock is used for
> > > > > pixel clock, for example.
> > > > > 
> > > > > In order to improve the situation, adjusting parent rate is considered
> > > > > when allowed.
> > > > > 
> > > > > This code is inspired by clk_divider_bestdiv() function, which does
> > > > > basically the same thing for different clock type.
> > > > 
> > > > This patch seems to break the eMMC support on Olinuxino-Lime2-eMMC
> > > > boards:
> > > > 
> > > > EXT4-fs (mmcblk1p4): INFO: recovery required on readonly filesystem
> > > > EXT4-fs (mmcblk1p4): write access will be enabled during recovery
> > > > sunxi-mmc 1c11000.mmc: data error, sending stop command
> > > > sunxi-mmc 1c11000.mmc: send stop command failed
> > > 
> > > I'm not familiar with A20. What is interesting is that emmc clocks don't
> > > have CLK_SET_RATE_PARENT flag set, so you shouldn't see any difference.
> > > 
> > > Can you post content of clk_summary with and without this patch?
> > 
> > In both cases I booted from FEL with rootfs on sdcard and tried to mount
> > partition from eMMC to /mnt. With your patch, last step it fails.
> > 
> > pre-patch working:
> > pll-ddr-other[768MHz] -> mmc2[512MHz]. (For some reason ahb-mmc2 is off?)
> > 
> > post-patch not working:
> > pll-periph[600MHz] ->  mmc2[500Mhz], (ahb-mmc2 is enabled)
> > 
> > Also, attached the logs.
> 
> Thanks. Just one more request. Can you enable debug messages in mmc driver? 
> I'm interested in output of this line:
> 
> dev_dbg(mmc_dev(mmc), "setting clk to %d, rounded %ld\n",
> 		clock, rate);

1c11000 is eMMC:
[snip]
[    1.961644] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
[    2.004091] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
[    2.020296] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
[    2.039917] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
[    2.047847] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
[    2.055053] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
[    2.065256] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
[    2.092351] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
[    2.168725] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
[    2.189403] sunxi-mmc 1c11000.mmc: setting clk to 52000000, rounded 52000000
[    2.203340] sunxi-mmc 1c11000.mmc: setting clk to 52000000, rounded 52000000
[    2.211412] sunxi-mmc 1c11000.mmc: setting clk to 52000000, rounded 52000000
[    4.967865] sunxi-mmc 1c11000.mmc: setting clk to 52000000, rounded 52000000
[    8.755345] sunxi-mmc 1c11000.mmc: setting clk to 52000000, rounded 52000000
[    9.082510] sunxi-mmc 1c11000.mmc: setting clk to 52000000, rounded 52000000

Here I tried to mount partition from eMMC...

[   72.167311] sunxi-mmc 1c11000.mmc: setting clk to 52000000, rounded 52000000
[   72.269629] sunxi-mmc 1c11000.mmc: data error, sending stop command
[   73.268999] sunxi-mmc 1c11000.mmc: send stop command failed
[/snip]

And clock tree:
[snip]
pll-periph-base                3        3        0  1200000000          0     0  50000
   pll-periph                  6        6        0   600000000          0     0  50000
      mmc2                     3        3        0    50000000          0     0  50000
         mmc2_sample           1        1        0    50000000          0   120  50000
         mmc2_output           1        1        0    50000000          0    60  50000
      ahb                     18       18        0   300000000          0     0  50000
         ahb-mmc2              1        1        0   300000000          0     0  50000
[/snip]


And without patch:
[snip]
[    2.003341] sunxi-mmc 1c11000.mmc: XXX: setting clk to 400000, rounded 400000
[    2.019479] sunxi-mmc 1c11000.mmc: XXX: setting clk to 400000, rounded 400000
[    2.039144] sunxi-mmc 1c11000.mmc: XXX: setting clk to 400000, rounded 400000
[    2.047129] sunxi-mmc 1c11000.mmc: XXX: setting clk to 400000, rounded 400000
[    2.054324] sunxi-mmc 1c11000.mmc: XXX: setting clk to 400000, rounded 400000
[    2.064481] sunxi-mmc 1c11000.mmc: XXX: setting clk to 400000, rounded 400000
[    2.091624] sunxi-mmc 1c11000.mmc: XXX: setting clk to 400000, rounded 400000
[    2.168067] sunxi-mmc 1c11000.mmc: XXX: setting clk to 400000, rounded 400000
[    2.188239] sunxi-mmc 1c11000.mmc: XXX: setting clk to 52000000, rounded 51200000
[    2.202779] sunxi-mmc 1c11000.mmc: XXX: setting clk to 52000000, rounded 51200000
[    2.210817] sunxi-mmc 1c11000.mmc: XXX: setting clk to 52000000, rounded 51200000
[    5.103358] sunxi-mmc 1c11000.mmc: XXX: setting clk to 52000000, rounded 51200000
[    8.950237] sunxi-mmc 1c11000.mmc: XXX: setting clk to 52000000, rounded 51200000
[    9.376201] sunxi-mmc 1c11000.mmc: XXX: setting clk to 52000000, rounded 51200000
[  113.618387] sunxi-mmc 1c11000.mmc: XXX: setting clk to 52000000, rounded 51200000
[  113.707979] EXT4-fs (mmcblk1p4): recovery complete
[  113.728162] EXT4-fs (mmcblk1p4): mounted filesystem with ordered data mode. Opts: (null)
[/snip]

And clock tree:
[snip]
pll-ddr-base                   2        2        0   768000000          0     0  50000
   pll-ddr-other               1        1        0   768000000          0     0  50000
      mmc2                     0        0        0    51200000          0     0  50000
         mmc2_sample           0        0        0    51200000          0   120  50000
         mmc2_output           0        0        0    51200000          0    72  50000
[/snip]


> 
> Just wondering what it should be.
> 
> Best regards,
> Jernej
> 
> > 
> > > Best regards,
> > > Jernej
> > > 
> > > > $ git bisect log
> > > > git bisect start
> > > > # good: [3df407b2a5346db1c48809706ece7a8616c79e0b] mmc:
> > > > dw_mmc-bluefield:
> > > > simplify the probe() function git bisect good
> > > > 3df407b2a5346db1c48809706ece7a8616c79e0b
> > > > # bad: [00d59fde8532b2d42e80909d2e58678755e04da9] Merge tag 'mmc-v4.21'
> > > > of
> > > > git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc git bisect bad
> > > > 00d59fde8532b2d42e80909d2e58678755e04da9
> > > > # good: [01e421feec0817bb3141eaae4c517410d193d440] Merge branch 'fixes'
> > > > into next git bisect good 01e421feec0817bb3141eaae4c517410d193d440
> > > > # bad: [1eefdec18eded41833401cfd64749643ff72e7da] Merge branch
> > > > 'locking-core-for-linus' of
> > > > git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip git bisect bad
> > > > 1eefdec18eded41833401cfd64749643ff72e7da
> > > > # good: [eaa76499711535fd64d747cc4ef0d78ab0fd41c6] Merge tag
> > > > 'mtd/for-4.21'
> > > > of git://git.infradead.org/linux-mtd git bisect good
> > > > eaa76499711535fd64d747cc4ef0d78ab0fd41c6
> > > > # good: [4e4390ad067a61ce4e7607bd0df31f19a4caa36a] Merge tag
> > > > 'leds-for-4.21-rc1' of
> > > > git://git.kernel.org/pub/scm/linux/kernel/git/j.anaszewski/linux-leds
> > > > git
> > > > bisect good 4e4390ad067a61ce4e7607bd0df31f19a4caa36a
> > > > # bad: [c2f1f3e0e17d94ab0c66d83e669492cb9e9a3698] Merge
> > > > git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next git
> > > > bisect
> > > > bad c2f1f3e0e17d94ab0c66d83e669492cb9e9a3698
> > > > # bad: [e4b99d415c3908581d4703203e1e805f043a3e71] Merge branch
> > > > 'irq-core-for-linus' of
> > > > git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip git bisect bad
> > > > e4b99d415c3908581d4703203e1e805f043a3e71
> > > > # bad: [ffe05540d18013db62c43627836a3638e9a2c7aa] Merge branches
> > > > 'clk-renesas', 'clk-allwinner', 'clk-tegra', 'clk-meson' and
> > > > 'clk-rockchip'
> > > > into clk-next git bisect bad ffe05540d18013db62c43627836a3638e9a2c7aa
> > > > # good: [1a501c8defe950571316d5ddd917bf44f5ed7bd4] Merge branches
> > > > 'clk-managed-registration', 'clk-spdx', 'clk-remove-basic' and
> > > > 'clk-ops-const' into clk-next git bisect good
> > > > 1a501c8defe950571316d5ddd917bf44f5ed7bd4
> > > > # good: [e74581b79ddd9b49b8c61e2791fc4dffc0245afb] Merge tag
> > > > 'meson-clk-4.21-2' of https://github.com/BayLibre/clk-meson into
> > > > clk-meson
> > > > git bisect good e74581b79ddd9b49b8c61e2791fc4dffc0245afb
> > > > # good: [60baf75e3f5b76043c25328ac0c5320aaef5ea41] Merge tag
> > > > 'clk-renesas-for-v4.21-tag2' of
> > > > git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers into
> > > > clk-renesas git bisect good 60baf75e3f5b76043c25328ac0c5320aaef5ea41
> > > > # bad: [a41f85b6017ee20952a60e4330bcae2527fe2c2a] Merge tag
> > > > 'sunxi-clk-for-4.21' of
> > > > https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux into
> > > > clk-allwinner git bisect bad a41f85b6017ee20952a60e4330bcae2527fe2c2a
> > > > # bad: [ee678706e46d0d185c27cc214ad97828e0643159] clk: sunxi-ng: a64:
> > > > Fix
> > > > gate bit of DSI DPHY git bisect bad
> > > > ee678706e46d0d185c27cc214ad97828e0643159
> > > > # bad: [65b6657672388b72822e0367f06d41c1e3ffb5bb] clk: sunxi-ng: Use u64
> > > > for calculation of NM rate git bisect bad
> > > > 65b6657672388b72822e0367f06d41c1e3ffb5bb
> > > > # good: [db7548934603d9eda12649dff97ea5c29884405d] clk: sunxi-ng:
> > > > sun50i:
> > > > h6: Fix MMC clock mux width git bisect good
> > > > db7548934603d9eda12649dff97ea5c29884405d
> > > > # bad: [3f790433c3cb27ecaf2ca0e07ac25964e4fd9f15] clk: sunxi-ng: Adjust
> > > > MP
> > > > clock parent rate when allowed git bisect bad
> > > > 3f790433c3cb27ecaf2ca0e07ac25964e4fd9f15
> > > > # first bad commit: [3f790433c3cb27ecaf2ca0e07ac25964e4fd9f15] clk:
> > > > sunxi-ng: Adjust MP clock parent rate when allowed
> > > > 
> > > > > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> > > > > ---
> > > > > 
> > > > >  drivers/clk/sunxi-ng/ccu_mp.c | 64
> > > > >  +++++++++++++++++++++++++++++++++--
> > > > >  1 file changed, 62 insertions(+), 2 deletions(-)
> > > > > 
> > > > > diff --git a/drivers/clk/sunxi-ng/ccu_mp.c
> > > > > b/drivers/clk/sunxi-ng/ccu_mp.c
> > > > > index 5d0af4051737..0357349eb767 100644
> > > > > --- a/drivers/clk/sunxi-ng/ccu_mp.c
> > > > > +++ b/drivers/clk/sunxi-ng/ccu_mp.c
> > > > > @@ -40,6 +40,61 @@ static void ccu_mp_find_best(unsigned long parent,
> > > > > unsigned long rate,>
> > > > > 
> > > > >  	*p = best_p;
> > > > >  
> > > > >  }
> > > > > 
> > > > > +static unsigned long ccu_mp_find_best_with_parent_adj(struct clk_hw
> > > > > *hw,
> > > > > +
> > > 
> > > unsigned long *parent,
> > > 
> > > > > +
> > > 
> > > unsigned long rate,
> > > 
> > > > > +
> > > 
> > > unsigned int max_m,
> > > 
> > > > > +
> > > 
> > > unsigned int max_p)
> > > 
> > > > > +{
> > > > > +	unsigned long parent_rate_saved;
> > > > > +	unsigned long parent_rate, now;
> > > > > +	unsigned long best_rate = 0;
> > > > > +	unsigned int _m, _p, div;
> > > > > +	unsigned long maxdiv;
> > > > > +
> > > > > +	parent_rate_saved = *parent;
> > > > > +
> > > > > +	/*
> > > > > +	 * The maximum divider we can use without overflowing
> > > > > +	 * unsigned long in rate * m * p below
> > > > > +	 */
> > > > > +	maxdiv = max_m * max_p;
> > > > > +	maxdiv = min(ULONG_MAX / rate, maxdiv);
> > > > > +
> > > > > +	for (_p = 1; _p <= max_p; _p <<= 1) {
> > > > > +		for (_m = 1; _m <= max_m; _m++) {
> > > > > +			div = _m * _p;
> > > > > +
> > > > > +			if (div > maxdiv)
> > > > > +				break;
> > > > > +
> > > > > +			if (rate * div == parent_rate_saved) {
> > > > > +				/*
> > > > > +				 * It's the most ideal case if
> > > 
> > > the requested
> > > 
> > > > > +				 * rate can be divided from
> > > 
> > > parent clock without
> > > 
> > > > > +				 * needing to change parent 
> rate,
> > > 
> > > so return the
> > > 
> > > > > +				 * divider immediately.
> > > > > +				 */
> > > > > +				*parent = parent_rate_saved;
> > > > > +				return rate;
> > > > > +			}
> > > > > +
> > > > > +			parent_rate = clk_hw_round_rate(hw, rate *
> > > 
> > > div);
> > > 
> > > > > +			now = parent_rate / div;
> > > > > +
> > > > > +			if (now <= rate && now > best_rate) {
> > > > > +				best_rate = now;
> > > > > +				*parent = parent_rate;
> > > > > +
> > > > > +				if (now == rate)
> > > > > +					return rate;
> > > > > +			}
> > > > > +		}
> > > > > +	}
> > > > > +
> > > > > +	return best_rate;
> > > > > +}
> > > > > +
> > > > > 
> > > > >  static unsigned long ccu_mp_round_rate(struct ccu_mux_internal *mux,
> > > > >  
> > > > >  				       struct clk_hw *hw,
> > > > >  				       unsigned long
> > > 
> > > *parent_rate,
> > > 
> > > > > @@ -56,8 +111,13 @@ static unsigned long ccu_mp_round_rate(struct
> > > > > ccu_mux_internal *mux,>
> > > > > 
> > > > >  	max_m = cmp->m.max ?: 1 << cmp->m.width;
> > > > >  	max_p = cmp->p.max ?: 1 << ((1 << cmp->p.width) - 1);
> > > > > 
> > > > > -	ccu_mp_find_best(*parent_rate, rate, max_m, max_p, &m, &p);
> > > > > -	rate = *parent_rate / p / m;
> > > > > +	if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) {
> > > > > +		ccu_mp_find_best(*parent_rate, rate, max_m, max_p, &m,
> > > 
> > > &p);
> > > 
> > > > > +		rate = *parent_rate / p / m;
> > > > > +	} else {
> > > > > +		rate = ccu_mp_find_best_with_parent_adj(hw, 
> parent_rate,
> > > 
> > > rate,
> > > 
> > > > > +
> > > 
> > > max_m, max_p);
> > > 
> > > > > +	}
> > > > > 
> > > > >  	if (cmp->common.features & CCU_FEATURE_FIXED_POSTDIV)
> > > > >  	
> > > > >  		rate /= cmp->fixed_post_div;
> 
> 
> 
> 
> -- 
> You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

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

* Re: [linux-sunxi] [PATCH v3 02/28] clk: sunxi-ng: Adjust MP clock parent rate when allowed
  2019-01-17  7:24           ` Priit Laes
@ 2019-01-18 21:51             ` Jernej Škrabec
  0 siblings, 0 replies; 41+ messages in thread
From: Jernej Škrabec @ 2019-01-18 21:51 UTC (permalink / raw)
  To: Priit Laes
  Cc: maxime.ripard, wens, robh+dt, mturquette, sboyd, airlied,
	architt, a.hajda, Laurent.pinchart, devicetree, linux-arm-kernel,
	linux-kernel, linux-clk, dri-devel, linux-sunxi

Dne četrtek, 17. januar 2019 ob 08:24:02 CET je Priit Laes napisal(a):
> On Wed, Jan 16, 2019 at 06:00:32PM +0100, Jernej Škrabec wrote:
> > Dne sreda, 16. januar 2019 ob 13:09:58 CET je Priit Laes napisal(a):
> > > On Thu, Jan 10, 2019 at 06:10:59PM +0100, Jernej Škrabec wrote:
> > > > Dne četrtek, 10. januar 2019 ob 10:15:48 CET je Priit Laes napisal(a):
> > > > > On Sun, Nov 04, 2018 at 07:26:39PM +0100, Jernej Skrabec wrote:
> > > > > > Currently MP clocks don't consider adjusting parent rate even if
> > > > > > they
> > > > > > are allowed to do so. Such behaviour considerably lowers amount of
> > > > > > possible rates, which is very inconvenient when such clock is used
> > > > > > for
> > > > > > pixel clock, for example.
> > > > > > 
> > > > > > In order to improve the situation, adjusting parent rate is
> > > > > > considered
> > > > > > when allowed.
> > > > > > 
> > > > > > This code is inspired by clk_divider_bestdiv() function, which
> > > > > > does
> > > > > > basically the same thing for different clock type.
> > > > > 
> > > > > This patch seems to break the eMMC support on Olinuxino-Lime2-eMMC
> > > > > boards:
> > > > > 
> > > > > EXT4-fs (mmcblk1p4): INFO: recovery required on readonly filesystem
> > > > > EXT4-fs (mmcblk1p4): write access will be enabled during recovery
> > > > > sunxi-mmc 1c11000.mmc: data error, sending stop command
> > > > > sunxi-mmc 1c11000.mmc: send stop command failed
> > > > 
> > > > I'm not familiar with A20. What is interesting is that emmc clocks
> > > > don't
> > > > have CLK_SET_RATE_PARENT flag set, so you shouldn't see any
> > > > difference.
> > > > 
> > > > Can you post content of clk_summary with and without this patch?
> > > 
> > > In both cases I booted from FEL with rootfs on sdcard and tried to mount
> > > partition from eMMC to /mnt. With your patch, last step it fails.
> > > 
> > > pre-patch working:
> > > pll-ddr-other[768MHz] -> mmc2[512MHz]. (For some reason ahb-mmc2 is
> > > off?)
> > > 
> > > post-patch not working:
> > > pll-periph[600MHz] ->  mmc2[500Mhz], (ahb-mmc2 is enabled)
> > > 
> > > Also, attached the logs.
> > 
> > Thanks. Just one more request. Can you enable debug messages in mmc
> > driver?
> > I'm interested in output of this line:
> > 
> > dev_dbg(mmc_dev(mmc), "setting clk to %d, rounded %ld\n",
> > 
> > 		clock, rate);
> 
> 1c11000 is eMMC:
> [snip]
> [    1.961644] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
> [    2.004091] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
> [    2.020296] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
> [    2.039917] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
> [    2.047847] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
> [    2.055053] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
> [    2.065256] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
> [    2.092351] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
> [    2.168725] sunxi-mmc 1c11000.mmc: setting clk to 400000, rounded 400000
> [    2.189403] sunxi-mmc 1c11000.mmc: setting clk to 52000000, rounded
> 52000000 [    2.203340] sunxi-mmc 1c11000.mmc: setting clk to 52000000,
> rounded 52000000 [    2.211412] sunxi-mmc 1c11000.mmc: setting clk to
> 52000000, rounded 52000000 [    4.967865] sunxi-mmc 1c11000.mmc: setting
> clk to 52000000, rounded 52000000 [    8.755345] sunxi-mmc 1c11000.mmc:
> setting clk to 52000000, rounded 52000000 [    9.082510] sunxi-mmc
> 1c11000.mmc: setting clk to 52000000, rounded 52000000
> 
> Here I tried to mount partition from eMMC...
> 
> [   72.167311] sunxi-mmc 1c11000.mmc: setting clk to 52000000, rounded
> 52000000 [   72.269629] sunxi-mmc 1c11000.mmc: data error, sending stop
> command [   73.268999] sunxi-mmc 1c11000.mmc: send stop command failed
> [/snip]
> 
> And clock tree:
> [snip]
> pll-periph-base                3        3        0  1200000000          0   
>  0  50000 pll-periph                  6        6        0   600000000      
>    0     0  50000 mmc2                     3        3        0    50000000 
>         0     0  50000 mmc2_sample           1        1        0   
> 50000000          0   120  50000 mmc2_output           1        1        0 
>   50000000          0    60  50000 ahb                     18       18     
>   0   300000000          0     0  50000 ahb-mmc2              1        1   
>     0   300000000          0     0  50000 [/snip]
> 
> 
> And without patch:
> [snip]
> [    2.003341] sunxi-mmc 1c11000.mmc: XXX: setting clk to 400000, rounded
> 400000 [    2.019479] sunxi-mmc 1c11000.mmc: XXX: setting clk to 400000,
> rounded 400000 [    2.039144] sunxi-mmc 1c11000.mmc: XXX: setting clk to
> 400000, rounded 400000 [    2.047129] sunxi-mmc 1c11000.mmc: XXX: setting
> clk to 400000, rounded 400000 [    2.054324] sunxi-mmc 1c11000.mmc: XXX:
> setting clk to 400000, rounded 400000 [    2.064481] sunxi-mmc 1c11000.mmc:
> XXX: setting clk to 400000, rounded 400000 [    2.091624] sunxi-mmc
> 1c11000.mmc: XXX: setting clk to 400000, rounded 400000 [    2.168067]
> sunxi-mmc 1c11000.mmc: XXX: setting clk to 400000, rounded 400000 [   
> 2.188239] sunxi-mmc 1c11000.mmc: XXX: setting clk to 52000000, rounded
> 51200000 [    2.202779] sunxi-mmc 1c11000.mmc: XXX: setting clk to
> 52000000, rounded 51200000 [    2.210817] sunxi-mmc 1c11000.mmc: XXX:
> setting clk to 52000000, rounded 51200000 [    5.103358] sunxi-mmc
> 1c11000.mmc: XXX: setting clk to 52000000, rounded 51200000 [    8.950237]
> sunxi-mmc 1c11000.mmc: XXX: setting clk to 52000000, rounded 51200000 [   
> 9.376201] sunxi-mmc 1c11000.mmc: XXX: setting clk to 52000000, rounded
> 51200000 [  113.618387] sunxi-mmc 1c11000.mmc: XXX: setting clk to
> 52000000, rounded 51200000 [  113.707979] EXT4-fs (mmcblk1p4): recovery
> complete
> [  113.728162] EXT4-fs (mmcblk1p4): mounted filesystem with ordered data
> mode. Opts: (null) [/snip]
> 
> And clock tree:
> [snip]
> pll-ddr-base                   2        2        0   768000000          0   
>  0  50000 pll-ddr-other               1        1        0   768000000      
>    0     0  50000 mmc2                     0        0        0    51200000 
>         0     0  50000 mmc2_sample           0        0        0   
> 51200000          0   120  50000 mmc2_output           0        0        0 
>   51200000          0    72  50000 [/snip]
> 

It seems to me that clock rate is set properly. It's even better than before 
since there is no error between wanted and real clock. I bet that if you call 
clk_get_rate() directly behind clk_set_rate() in mmc driver, you'll get 
correct value.

However, it seems that at some point some other peripheral changes it's parent 
clock rate, which inadvertely changes emmc2 clock rate too. The only possible 
clock which could interfere is sata. Can you disable driver in you kernel 
config and try again?

Best regards,
Jernej

> > Just wondering what it should be.
> > 
> > Best regards,
> > Jernej
> > 
> > > > Best regards,
> > > > Jernej
> > > > 
> > > > > $ git bisect log
> > > > > git bisect start
> > > > > # good: [3df407b2a5346db1c48809706ece7a8616c79e0b] mmc:
> > > > > dw_mmc-bluefield:
> > > > > simplify the probe() function git bisect good
> > > > > 3df407b2a5346db1c48809706ece7a8616c79e0b
> > > > > # bad: [00d59fde8532b2d42e80909d2e58678755e04da9] Merge tag
> > > > > 'mmc-v4.21'
> > > > > of
> > > > > git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc git bisect
> > > > > bad
> > > > > 00d59fde8532b2d42e80909d2e58678755e04da9
> > > > > # good: [01e421feec0817bb3141eaae4c517410d193d440] Merge branch
> > > > > 'fixes'
> > > > > into next git bisect good 01e421feec0817bb3141eaae4c517410d193d440
> > > > > # bad: [1eefdec18eded41833401cfd64749643ff72e7da] Merge branch
> > > > > 'locking-core-for-linus' of
> > > > > git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip git bisect bad
> > > > > 1eefdec18eded41833401cfd64749643ff72e7da
> > > > > # good: [eaa76499711535fd64d747cc4ef0d78ab0fd41c6] Merge tag
> > > > > 'mtd/for-4.21'
> > > > > of git://git.infradead.org/linux-mtd git bisect good
> > > > > eaa76499711535fd64d747cc4ef0d78ab0fd41c6
> > > > > # good: [4e4390ad067a61ce4e7607bd0df31f19a4caa36a] Merge tag
> > > > > 'leds-for-4.21-rc1' of
> > > > > git://git.kernel.org/pub/scm/linux/kernel/git/j.anaszewski/linux-led
> > > > > s
> > > > > git
> > > > > bisect good 4e4390ad067a61ce4e7607bd0df31f19a4caa36a
> > > > > # bad: [c2f1f3e0e17d94ab0c66d83e669492cb9e9a3698] Merge
> > > > > git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next git
> > > > > bisect
> > > > > bad c2f1f3e0e17d94ab0c66d83e669492cb9e9a3698
> > > > > # bad: [e4b99d415c3908581d4703203e1e805f043a3e71] Merge branch
> > > > > 'irq-core-for-linus' of
> > > > > git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip git bisect bad
> > > > > e4b99d415c3908581d4703203e1e805f043a3e71
> > > > > # bad: [ffe05540d18013db62c43627836a3638e9a2c7aa] Merge branches
> > > > > 'clk-renesas', 'clk-allwinner', 'clk-tegra', 'clk-meson' and
> > > > > 'clk-rockchip'
> > > > > into clk-next git bisect bad
> > > > > ffe05540d18013db62c43627836a3638e9a2c7aa
> > > > > # good: [1a501c8defe950571316d5ddd917bf44f5ed7bd4] Merge branches
> > > > > 'clk-managed-registration', 'clk-spdx', 'clk-remove-basic' and
> > > > > 'clk-ops-const' into clk-next git bisect good
> > > > > 1a501c8defe950571316d5ddd917bf44f5ed7bd4
> > > > > # good: [e74581b79ddd9b49b8c61e2791fc4dffc0245afb] Merge tag
> > > > > 'meson-clk-4.21-2' of https://github.com/BayLibre/clk-meson into
> > > > > clk-meson
> > > > > git bisect good e74581b79ddd9b49b8c61e2791fc4dffc0245afb
> > > > > # good: [60baf75e3f5b76043c25328ac0c5320aaef5ea41] Merge tag
> > > > > 'clk-renesas-for-v4.21-tag2' of
> > > > > git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers
> > > > > into
> > > > > clk-renesas git bisect good 60baf75e3f5b76043c25328ac0c5320aaef5ea41
> > > > > # bad: [a41f85b6017ee20952a60e4330bcae2527fe2c2a] Merge tag
> > > > > 'sunxi-clk-for-4.21' of
> > > > > https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux into
> > > > > clk-allwinner git bisect bad
> > > > > a41f85b6017ee20952a60e4330bcae2527fe2c2a
> > > > > # bad: [ee678706e46d0d185c27cc214ad97828e0643159] clk: sunxi-ng:
> > > > > a64:
> > > > > Fix
> > > > > gate bit of DSI DPHY git bisect bad
> > > > > ee678706e46d0d185c27cc214ad97828e0643159
> > > > > # bad: [65b6657672388b72822e0367f06d41c1e3ffb5bb] clk: sunxi-ng: Use
> > > > > u64
> > > > > for calculation of NM rate git bisect bad
> > > > > 65b6657672388b72822e0367f06d41c1e3ffb5bb
> > > > > # good: [db7548934603d9eda12649dff97ea5c29884405d] clk: sunxi-ng:
> > > > > sun50i:
> > > > > h6: Fix MMC clock mux width git bisect good
> > > > > db7548934603d9eda12649dff97ea5c29884405d
> > > > > # bad: [3f790433c3cb27ecaf2ca0e07ac25964e4fd9f15] clk: sunxi-ng:
> > > > > Adjust
> > > > > MP
> > > > > clock parent rate when allowed git bisect bad
> > > > > 3f790433c3cb27ecaf2ca0e07ac25964e4fd9f15
> > > > > # first bad commit: [3f790433c3cb27ecaf2ca0e07ac25964e4fd9f15] clk:
> > > > > sunxi-ng: Adjust MP clock parent rate when allowed
> > > > > 
> > > > > > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> > > > > > ---
> > > > > > 
> > > > > >  drivers/clk/sunxi-ng/ccu_mp.c | 64
> > > > > >  +++++++++++++++++++++++++++++++++--
> > > > > >  1 file changed, 62 insertions(+), 2 deletions(-)
> > > > > > 
> > > > > > diff --git a/drivers/clk/sunxi-ng/ccu_mp.c
> > > > > > b/drivers/clk/sunxi-ng/ccu_mp.c
> > > > > > index 5d0af4051737..0357349eb767 100644
> > > > > > --- a/drivers/clk/sunxi-ng/ccu_mp.c
> > > > > > +++ b/drivers/clk/sunxi-ng/ccu_mp.c
> > > > > > @@ -40,6 +40,61 @@ static void ccu_mp_find_best(unsigned long
> > > > > > parent,
> > > > > > unsigned long rate,>
> > > > > > 
> > > > > >  	*p = best_p;
> > > > > >  
> > > > > >  }
> > > > > > 
> > > > > > +static unsigned long ccu_mp_find_best_with_parent_adj(struct
> > > > > > clk_hw
> > > > > > *hw,
> > > > > > +
> > > > 
> > > > unsigned long *parent,
> > > > 
> > > > > > +
> > > > 
> > > > unsigned long rate,
> > > > 
> > > > > > +
> > > > 
> > > > unsigned int max_m,
> > > > 
> > > > > > +
> > > > 
> > > > unsigned int max_p)
> > > > 
> > > > > > +{
> > > > > > +	unsigned long parent_rate_saved;
> > > > > > +	unsigned long parent_rate, now;
> > > > > > +	unsigned long best_rate = 0;
> > > > > > +	unsigned int _m, _p, div;
> > > > > > +	unsigned long maxdiv;
> > > > > > +
> > > > > > +	parent_rate_saved = *parent;
> > > > > > +
> > > > > > +	/*
> > > > > > +	 * The maximum divider we can use without overflowing
> > > > > > +	 * unsigned long in rate * m * p below
> > > > > > +	 */
> > > > > > +	maxdiv = max_m * max_p;
> > > > > > +	maxdiv = min(ULONG_MAX / rate, maxdiv);
> > > > > > +
> > > > > > +	for (_p = 1; _p <= max_p; _p <<= 1) {
> > > > > > +		for (_m = 1; _m <= max_m; _m++) {
> > > > > > +			div = _m * _p;
> > > > > > +
> > > > > > +			if (div > maxdiv)
> > > > > > +				break;
> > > > > > +
> > > > > > +			if (rate * div == parent_rate_saved) {
> > > > > > +				/*
> > > > > > +				 * It's the most ideal case if
> > > > 
> > > > the requested
> > > > 
> > > > > > +				 * rate can be divided from
> > > > 
> > > > parent clock without
> > > > 
> > > > > > +				 * needing to change parent
> > 
> > rate,
> > 
> > > > so return the
> > > > 
> > > > > > +				 * divider immediately.
> > > > > > +				 */
> > > > > > +				*parent = parent_rate_saved;
> > > > > > +				return rate;
> > > > > > +			}
> > > > > > +
> > > > > > +			parent_rate = clk_hw_round_rate(hw, rate *
> > > > 
> > > > div);
> > > > 
> > > > > > +			now = parent_rate / div;
> > > > > > +
> > > > > > +			if (now <= rate && now > best_rate) {
> > > > > > +				best_rate = now;
> > > > > > +				*parent = parent_rate;
> > > > > > +
> > > > > > +				if (now == rate)
> > > > > > +					return rate;
> > > > > > +			}
> > > > > > +		}
> > > > > > +	}
> > > > > > +
> > > > > > +	return best_rate;
> > > > > > +}
> > > > > > +
> > > > > > 
> > > > > >  static unsigned long ccu_mp_round_rate(struct ccu_mux_internal
> > > > > >  *mux,
> > > > > >  
> > > > > >  				       struct clk_hw *hw,
> > > > > >  				       unsigned long
> > > > 
> > > > *parent_rate,
> > > > 
> > > > > > @@ -56,8 +111,13 @@ static unsigned long ccu_mp_round_rate(struct
> > > > > > ccu_mux_internal *mux,>
> > > > > > 
> > > > > >  	max_m = cmp->m.max ?: 1 << cmp->m.width;
> > > > > >  	max_p = cmp->p.max ?: 1 << ((1 << cmp->p.width) - 1);
> > > > > > 
> > > > > > -	ccu_mp_find_best(*parent_rate, rate, max_m, max_p, &m, &p);
> > > > > > -	rate = *parent_rate / p / m;
> > > > > > +	if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) {
> > > > > > +		ccu_mp_find_best(*parent_rate, rate, max_m, max_p, &m,
> > > > 
> > > > &p);
> > > > 
> > > > > > +		rate = *parent_rate / p / m;
> > > > > > +	} else {
> > > > > > +		rate = ccu_mp_find_best_with_parent_adj(hw,
> > 
> > parent_rate,
> > 
> > > > rate,
> > > > 
> > > > > > +
> > > > 
> > > > max_m, max_p);
> > > > 
> > > > > > +	}
> > > > > > 
> > > > > >  	if (cmp->common.features & CCU_FEATURE_FIXED_POSTDIV)
> > > > > >  	
> > > > > >  		rate /= cmp->fixed_post_div;





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

end of thread, back to index

Thread overview: 41+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-11-04 18:26 [PATCH v3 00/28] Allwinner H6 DE3 and HDMI support Jernej Skrabec
2018-11-04 18:26 ` [PATCH v3 01/28] dt-bindings: bus: add H6 DE3 bus binding Jernej Skrabec
2018-11-04 18:26 ` [PATCH v3 02/28] clk: sunxi-ng: Adjust MP clock parent rate when allowed Jernej Skrabec
2019-01-10  9:15   ` [linux-sunxi] " Priit Laes
2019-01-10 17:10     ` Jernej Škrabec
2019-01-16 12:09       ` Priit Laes
2019-01-16 17:00         ` Jernej Škrabec
2019-01-17  7:24           ` Priit Laes
2019-01-18 21:51             ` Jernej Škrabec
2018-11-04 18:26 ` [PATCH v3 03/28] clk: sunxi-ng: Use u64 for calculation of NM rate Jernej Skrabec
2018-11-04 18:26 ` [PATCH v3 04/28] clk: sunxi-ng: h6: Set video PLLs limits Jernej Skrabec
2018-11-04 18:26 ` [PATCH v3 05/28] dt-bindings: clock: sun8i-de2: Add H6 DE3 clock description Jernej Skrabec
2018-11-04 18:26 ` [PATCH v3 06/28] clk: sunxi-ng: Add support for H6 DE3 clocks Jernej Skrabec
2018-11-04 18:26 ` [PATCH v3 07/28] dt-bindings: display: sun4i-drm: Add H6 display engine compatibles Jernej Skrabec
2018-11-04 18:26 ` [PATCH v3 08/28] drm/sun4i: Add compatible for H6 display engine Jernej Skrabec
2018-11-04 18:26 ` [PATCH v3 09/28] drm/sun4i: Rework DE2 register defines Jernej Skrabec
2018-11-04 18:26 ` [PATCH v3 10/28] drm/sun4i: Fix DE2 mixer size Jernej Skrabec
2018-11-04 18:26 ` [PATCH v3 11/28] drm/sun4i: Disable unused DE2 sub-engines Jernej Skrabec
2018-11-04 18:26 ` [PATCH v3 12/28] drm/sun4i: Add basic support for DE3 Jernej Skrabec
2018-11-04 18:26 ` [PATCH v3 13/28] drm/sun4i: Add support for H6 DE3 mixer 0 Jernej Skrabec
2018-11-04 18:26 ` [PATCH v3 14/28] drm/bridge/synopsys: dw-hdmi: Enable workaround for v2.12a Jernej Skrabec
2018-11-04 18:26 ` [PATCH v3 15/28] drm/sun4i: Not all DW HDMI controllers has scrambled addresses Jernej Skrabec
2018-11-04 18:26 ` [PATCH v3 16/28] drm/sun4i: dw-hdmi: Make mode_valid function configurable Jernej Skrabec
2018-11-04 18:26 ` [PATCH v3 17/28] drm/sun4i: dw-hdmi: Add quirk for setting TMDS clock Jernej Skrabec
2018-11-04 18:26 ` [PATCH v3 18/28] dt-bindings: display: sunxi: add DT binding for Allwinner H6 DW HDMI Jernej Skrabec
2018-11-04 18:26 ` [PATCH v3 19/28] drm/sun4i: Add support for H6 DW HDMI controller Jernej Skrabec
2018-11-04 18:26 ` [PATCH v3 20/28] drm/sun4i: dw-hdmi-phy: Reorder quirks by family Jernej Skrabec
2018-11-04 18:26 ` [PATCH v3 21/28] drm/sun4i: Add support for Synopsys HDMI PHY Jernej Skrabec
2018-11-04 18:26 ` [PATCH v3 22/28] drm/sun4i: Add support for H6 " Jernej Skrabec
2018-11-04 18:27 ` [PATCH v3 23/28] drm/sun4i: Initialize registers in tcon-top driver Jernej Skrabec
2018-11-04 18:27 ` [PATCH v3 24/28] drm: sun4i: add quirks for TCON TOP Jernej Skrabec
2018-11-04 18:27 ` [PATCH v3 25/28] dt-bindings: display: sun4i-drm: document H6 " Jernej Skrabec
2018-11-04 18:27 ` [PATCH v3 26/28] drm: sun4i: add support for " Jernej Skrabec
2018-11-04 18:27 ` [PATCH v3 27/28] arm64: dts: allwinner: h6: Add HDMI pipeline Jernej Skrabec
2018-11-04 18:27 ` [PATCH v3 28/28] arm64: dts: allwinner: h6: Enable HDMI output on Pine H64 board Jernej Skrabec
2018-11-05  9:43 ` [PATCH v3 00/28] Allwinner H6 DE3 and HDMI support Maxime Ripard
2018-11-06 15:54   ` Jernej Škrabec
2018-11-06 17:20   ` Jernej Škrabec
2018-11-07  9:44     ` Maxime Ripard
2018-12-03 18:09   ` Jernej Škrabec
2018-12-04  8:29     ` Maxime Ripard

Linux-Clk Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-clk/0 linux-clk/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-clk linux-clk/ https://lore.kernel.org/linux-clk \
		linux-clk@vger.kernel.org linux-clk@archiver.kernel.org
	public-inbox-index linux-clk


Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-clk


AGPL code for this site: git clone https://public-inbox.org/ public-inbox