[U-Boot] [PATCH 0/5] rockchip: video: migrate RK3399 w/ HDMI to livetree

This series fixes the regression on the RK3399 (since some boards have moved to live tree) for HDMI output. This fix requires some new functionality in the ofnode family (i.e. finding an ofnode's parent node and finding an ofnode from a phandle), but these are all add-on functionality and thus should not interfere with any other boards or drivers (as it's only us using them so far).
To have working HDMI again, the fix for our PMU clk driver (so PLL_PPLL, which is listed in the 'assigned-clocks', is handled correctly during probing).
Kever Yang (1): core: add ofnode_get_by_phandle() api
Philipp Tomsich (4): core: ofnode: add ofnode_get_parent function rockchip: video: rk_hdmi: migrate to livetree rockchip: video: rk_vop: migrate to livetree rockchip: video: update MAINTAINERS
MAINTAINERS | 1 + drivers/core/ofnode.c | 27 +++++++++++++ drivers/video/rockchip/rk_hdmi.c | 2 +- drivers/video/rockchip/rk_vop.c | 85 +++++++++++++++++++++++++++------------- include/dm/ofnode.h | 16 ++++++++ 5 files changed, 102 insertions(+), 29 deletions(-)

The Rockchip video drivers need to walk the ofnode-parrents to find an enclosing device that has a UCLASS_DISPLAY driver bound. This adds a ofnode_get_parent()-function that returns the parent-node.
Signed-off-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com Tested-by: Klaus Goger klaus.goger@theobroma-systems.com ---
drivers/core/ofnode.c | 14 ++++++++++++++ include/dm/ofnode.h | 8 ++++++++ 2 files changed, 22 insertions(+)
diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index 98f4b53..dd6d57c 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -165,6 +165,20 @@ ofnode ofnode_next_subnode(ofnode node) fdt_next_subnode(gd->fdt_blob, ofnode_to_offset(node))); }
+ofnode ofnode_get_parent(ofnode node) +{ + ofnode parent; + + assert(ofnode_valid(node)); + if (ofnode_is_np(node)) + parent = np_to_ofnode(of_get_parent(ofnode_to_np(node))); + else + parent.of_offset = fdt_parent_offset(gd->fdt_blob, + ofnode_to_offset(node)); + + return parent; +} + const char *ofnode_get_name(ofnode node) { assert(ofnode_valid(node)); diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index c359a60..6938e62 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -302,6 +302,14 @@ ofnode ofnode_first_subnode(ofnode node); ofnode ofnode_next_subnode(ofnode node);
/** + * ofnode_get_parent() - get the ofnode's parent (enclosing ofnode) + * + * @node: valid node to look up + * @return ofnode reference of the parent node + */ +ofnode ofnode_get_parent(ofnode node); + +/** * ofnode_get_name() - get the name of a node * * @node: valid node to look up

On Fri, 23 Feb 2018 17:38:49 +0100 Philipp Tomsich philipp.tomsich@theobroma-systems.com wrote:
The Rockchip video drivers need to walk the ofnode-parrents to find an enclosing device that has a UCLASS_DISPLAY driver bound. This adds a ofnode_get_parent()-function that returns the parent-node.
Signed-off-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com Tested-by: Klaus Goger klaus.goger@theobroma-systems.com
Reviewed-by: Anatolij Gustschin agust@denx.de

On 23 February 2018 at 09:38, Philipp Tomsich philipp.tomsich@theobroma-systems.com wrote:
The Rockchip video drivers need to walk the ofnode-parrents to find an enclosing device that has a UCLASS_DISPLAY driver bound. This adds a ofnode_get_parent()-function that returns the parent-node.
Signed-off-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com Tested-by: Klaus Goger klaus.goger@theobroma-systems.com
drivers/core/ofnode.c | 14 ++++++++++++++ include/dm/ofnode.h | 8 ++++++++ 2 files changed, 22 insertions(+)
Reviewed-by: Simon Glass sjg@chromium.org
Do you think we could have a simple ofnode test in test/dm to call this new function?

From: Kever Yang kever.yang@rock-chips.com
We need to get ofnode from a phandle, add interface to support both live dt and fdt.
Signed-off-by: Kever Yang kever.yang@rock-chips.com Reviewed-by: Simon Glass sjg@chromium.org Reviewed-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com Tested-by: Klaus Goger klaus.goger@theobroma-systems.com Signed-off-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com ---
drivers/core/ofnode.c | 13 +++++++++++++ include/dm/ofnode.h | 8 ++++++++ 2 files changed, 21 insertions(+)
diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index dd6d57c..d0bdea0 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -188,6 +188,19 @@ const char *ofnode_get_name(ofnode node) return fdt_get_name(gd->fdt_blob, ofnode_to_offset(node), NULL); }
+ofnode ofnode_get_by_phandle(uint phandle) +{ + ofnode node; + + if (of_live_active()) + node = np_to_ofnode(of_find_node_by_phandle(phandle)); + else + node.of_offset = fdt_node_offset_by_phandle(gd->fdt_blob, + phandle); + + return node; +} + int ofnode_read_size(ofnode node, const char *propname) { int len; diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index 6938e62..0d00840 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -318,6 +318,14 @@ ofnode ofnode_get_parent(ofnode node); const char *ofnode_get_name(ofnode node);
/** + * ofnode_get_by_phandle() - get ofnode from phandle + * + * @phandle: phandle to look up + * @return ofnode reference to the phandle + */ +ofnode ofnode_get_by_phandle(uint phandle); + +/** * ofnode_read_size() - read the size of a property * * @node: node to check

The rk_hdmi (shared functions for multiple HDMI mini-drivers) has been using devfdt_get_addr() to read the HDMI controller's IO base address. This will cause a failure with a live tree.
This changes the driver to use dev_read_addr() which is safe both for flat trees and live trees.
Signed-off-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com Tested-by: Klaus Goger klaus.goger@theobroma-systems.com
---
drivers/video/rockchip/rk_hdmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/video/rockchip/rk_hdmi.c b/drivers/video/rockchip/rk_hdmi.c index a9c8fba..b55b397 100644 --- a/drivers/video/rockchip/rk_hdmi.c +++ b/drivers/video/rockchip/rk_hdmi.c @@ -84,7 +84,7 @@ int rk_hdmi_ofdata_to_platdata(struct udevice *dev) struct rk_hdmi_priv *priv = dev_get_priv(dev); struct dw_hdmi *hdmi = &priv->hdmi;
- hdmi->ioaddr = (ulong)devfdt_get_addr(dev); + hdmi->ioaddr = (ulong)dev_read_addr(dev); hdmi->mpll_cfg = rockchip_mpll_cfg; hdmi->phy_cfg = rockchip_phy_config;

On Fri, 23 Feb 2018 17:38:51 +0100 Philipp Tomsich philipp.tomsich@theobroma-systems.com wrote:
The rk_hdmi (shared functions for multiple HDMI mini-drivers) has been using devfdt_get_addr() to read the HDMI controller's IO base address. This will cause a failure with a live tree.
This changes the driver to use dev_read_addr() which is safe both for flat trees and live trees.
Signed-off-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com Tested-by: Klaus Goger klaus.goger@theobroma-systems.com
Reviewed-by: Anatolij Gustschin agust@denx.de

This migrates rk_vop (the shared functions used by multiple VOP mini-drivers) to be compatible with a live tree.
Unfortunately, there's (i) a lot of tree traversal needed for a VOP (as each active VOP vnode references back to the endpoints in the encoders and vice versa) to configure the connection between VOPs and encoders; (ii) the DTS binding is not too sane and one needs to walk a node's parents (the original code just assumed that the device would live 3 levels above the property linked through a phandle) until a UCLASS_DISPLAY device can be found.
As part of the migration, the code for finding the enclosing display device has been changed to not assume a specific depth of nesting (i.e. we walk until we reach the root or find a matching device) and to use the newly introduced (in the same series) ofnode_get_parent() function.
Signed-off-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com Tested-by: Klaus Goger klaus.goger@theobroma-systems.com ---
drivers/video/rockchip/rk_vop.c | 85 +++++++++++++++++++++++++++-------------- 1 file changed, 57 insertions(+), 28 deletions(-)
diff --git a/drivers/video/rockchip/rk_vop.c b/drivers/video/rockchip/rk_vop.c index c979049..1288608 100644 --- a/drivers/video/rockchip/rk_vop.c +++ b/drivers/video/rockchip/rk_vop.c @@ -218,41 +218,67 @@ static void rkvop_mode_set(struct udevice *dev, * node within the VOP's 'port' list. * @return 0 if OK, -ve if something went wrong */ -static int rk_display_init(struct udevice *dev, ulong fbbase, int ep_node) +static int rk_display_init(struct udevice *dev, ulong fbbase, ofnode ep_node) { struct video_priv *uc_priv = dev_get_uclass_priv(dev); - const void *blob = gd->fdt_blob; struct rk_vop_priv *priv = dev_get_priv(dev); int vop_id, remote_vop_id; struct rk3288_vop *regs = priv->regs; struct display_timing timing; struct udevice *disp; - int ret, remote, i, offset; + int ret; + u32 remote_phandle; struct display_plat *disp_uc_plat; struct clk clk; enum video_log2_bpp l2bpp; + ofnode remote;
- vop_id = fdtdec_get_int(blob, ep_node, "reg", -1); + debug("%s(%s, %lu, %s)\n", __func__, + dev_read_name(dev), fbbase, ofnode_get_name(ep_node)); + + vop_id = ofnode_read_s32_default(ep_node, "reg", -1); debug("vop_id=%d\n", vop_id); - remote = fdtdec_lookup_phandle(blob, ep_node, "remote-endpoint"); - if (remote < 0) - return -EINVAL; - remote_vop_id = fdtdec_get_int(blob, remote, "reg", -1); - debug("remote vop_id=%d\n", remote_vop_id); + ret = ofnode_read_u32(ep_node, "remote-endpoint", &remote_phandle); + if (ret) + return ret;
- for (i = 0, offset = remote; i < 3 && offset > 0; i++) - offset = fdt_parent_offset(blob, offset); - if (offset < 0) { - debug("%s: Invalid remote-endpoint position\n", dev->name); + remote = ofnode_get_by_phandle(remote_phandle); + if (!ofnode_valid(remote)) return -EINVAL; - } + remote_vop_id = ofnode_read_u32_default(remote, "reg", -1); + debug("remote vop_id=%d\n", remote_vop_id);
- ret = uclass_find_device_by_of_offset(UCLASS_DISPLAY, offset, &disp); - if (ret) { - debug("%s: device '%s' display not found (ret=%d)\n", __func__, - dev->name, ret); - return ret; - } + /* + * The remote-endpoint references into a subnode of the encoder + * (i.e. HDMI, MIPI, etc.) with the DTS looking something like + * the following (assume 'hdmi_in_vopl' to be referenced): + * + * hdmi: hdmi@ff940000 { + * ports { + * hdmi_in: port { + * hdmi_in_vopb: endpoint@0 { ... }; + * hdmi_in_vopl: endpoint@1 { ... }; + * } + * } + * } + * + * The original code had 3 steps of "walking the parent", but + * a much better (as in: less likely to break if the DTS + * changes) way of doing this is to "find the enclosing device + * of UCLASS_DISPLAY". + */ + while (ofnode_valid(remote)) { + remote = ofnode_get_parent(remote); + if (!ofnode_valid(remote)) { + debug("%s(%s): no UCLASS_DISPLAY for remote-endpoint\n", + __func__, dev_read_name(dev)); + return -EINVAL; + } + + uclass_find_device_by_ofnode(UCLASS_DISPLAY, remote, &disp); + if (disp) + break; + };
disp_uc_plat = dev_get_uclass_platdata(disp); debug("Found device '%s', disp_uc_priv=%p\n", disp->name, disp_uc_plat); @@ -334,16 +360,15 @@ void rk_vop_probe_regulators(struct udevice *dev, int rk_vop_probe(struct udevice *dev) { struct video_uc_platdata *plat = dev_get_uclass_platdata(dev); - const void *blob = gd->fdt_blob; struct rk_vop_priv *priv = dev_get_priv(dev); int ret = 0; - int port, node; + ofnode port, node;
/* Before relocation we don't need to do anything */ if (!(gd->flags & GD_FLG_RELOC)) return 0;
- priv->regs = (struct rk3288_vop *)devfdt_get_addr(dev); + priv->regs = (struct rk3288_vop *)dev_read_addr(dev);
/* * Try all the ports until we find one that works. In practice this @@ -353,12 +378,16 @@ int rk_vop_probe(struct udevice *dev) * clock so it is currently not possible to use more than one display * device simultaneously. */ - port = fdt_subnode_offset(blob, dev_of_offset(dev), "port"); - if (port < 0) + port = dev_read_subnode(dev, "port"); + if (!ofnode_valid(port)) { + debug("%s(%s): 'port' subnode not found\n", + __func__, dev_read_name(dev)); return -EINVAL; - for (node = fdt_first_subnode(blob, port); - node > 0; - node = fdt_next_subnode(blob, node)) { + } + + for (node = ofnode_first_subnode(port); + ofnode_valid(node); + node = dev_read_next_subnode(node)) { ret = rk_display_init(dev, plat->base, node); if (ret) debug("Device failed: ret=%d\n", ret);

On Fri, 23 Feb 2018 17:38:52 +0100 Philipp Tomsich philipp.tomsich@theobroma-systems.com wrote:
This migrates rk_vop (the shared functions used by multiple VOP mini-drivers) to be compatible with a live tree.
Unfortunately, there's (i) a lot of tree traversal needed for a VOP (as each active VOP vnode references back to the endpoints in the encoders and vice versa) to configure the connection between VOPs and encoders; (ii) the DTS binding is not too sane and one needs to walk a node's parents (the original code just assumed that the device would live 3 levels above the property linked through a phandle) until a UCLASS_DISPLAY device can be found.
As part of the migration, the code for finding the enclosing display device has been changed to not assume a specific depth of nesting (i.e. we walk until we reach the root or find a matching device) and to use the newly introduced (in the same series) ofnode_get_parent() function.
Signed-off-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com Tested-by: Klaus Goger klaus.goger@theobroma-systems.com
Reviewed-by: Anatolij Gustschin agust@denx.de

The video drivers (VOP, HDMI encoder, LVDS encoder, MIPI encoder) for Rockchip SOCs are self-contained and are mainly impacted by other changes in the architecture support (e.g. pinctrl, clocking, etc).
Let's add these to the list of files maintained as part of the Rockchip port.
Signed-off-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com ---
MAINTAINERS | 1 + 1 file changed, 1 insertion(+)
diff --git a/MAINTAINERS b/MAINTAINERS index d2f8c51..077828c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -163,6 +163,7 @@ F: drivers/misc/rockchip-efuse.c F: drivers/pinctrl/rockchip/ F: drivers/ram/rockchip/ F: drivers/sysreset/sysreset_rockchip.c +F: drivers/video/rockchip/ F: tools/rkcommon.c F: tools/rkcommon.h F: tools/rkimage.c

On Fri, 23 Feb 2018 17:38:53 +0100 Philipp Tomsich philipp.tomsich@theobroma-systems.com wrote:
The video drivers (VOP, HDMI encoder, LVDS encoder, MIPI encoder) for Rockchip SOCs are self-contained and are mainly impacted by other changes in the architecture support (e.g. pinctrl, clocking, etc).
Let's add these to the list of files maintained as part of the Rockchip port.
Signed-off-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com
Reviewed-by: Anatolij Gustschin agust@denx.de

Tom et al.,
I’d like to see this bug fix included in 2018.03, but don’t want to take the decision on my own: - some of this should have come via Anatolij’s tree - if touches ofnode.h/c and also needs a change by Kever that Simon reviewed (and noted that test cases should also be added) and that should normally come through the DM tree - it only affects our company's BSP and we can just keep a branch of 2018.03 alive in our public GIT until 2018.05 comes out...
Please let me know if I can process this through the Rockchip tree for 2018.03 or whether this has to wait until the new merge window.
Thanks, Philipp.
On 23 Feb 2018, at 17:38, Philipp Tomsich philipp.tomsich@theobroma-systems.com wrote:
This series fixes the regression on the RK3399 (since some boards have moved to live tree) for HDMI output. This fix requires some new functionality in the ofnode family (i.e. finding an ofnode's parent node and finding an ofnode from a phandle), but these are all add-on functionality and thus should not interfere with any other boards or drivers (as it's only us using them so far).
To have working HDMI again, the fix for our PMU clk driver (so PLL_PPLL, which is listed in the 'assigned-clocks', is handled correctly during probing).
Kever Yang (1): core: add ofnode_get_by_phandle() api
Philipp Tomsich (4): core: ofnode: add ofnode_get_parent function rockchip: video: rk_hdmi: migrate to livetree rockchip: video: rk_vop: migrate to livetree rockchip: video: update MAINTAINERS
MAINTAINERS | 1 + drivers/core/ofnode.c | 27 +++++++++++++ drivers/video/rockchip/rk_hdmi.c | 2 +- drivers/video/rockchip/rk_vop.c | 85 +++++++++++++++++++++++++++------------- include/dm/ofnode.h | 16 ++++++++ 5 files changed, 102 insertions(+), 29 deletions(-)
-- 2.1.4

On Fri, 23 Feb 2018 17:38:48 +0100 Philipp Tomsich philipp.tomsich@theobroma-systems.com wrote: ...
To have working HDMI again, the fix for our PMU clk driver (so PLL_PPLL, which is listed in the 'assigned-clocks', is handled correctly during probing).
Series applied to u-boot-video/master, thanks!
-- Anatolij
participants (4)
-
Anatolij Gustschin
-
Dr. Philipp Tomsich
-
Philipp Tomsich
-
Simon Glass