diff options
Diffstat (limited to 'drivers/gpu/drm/sun4i')
-rw-r--r-- | drivers/gpu/drm/sun4i/sun4i_tcon.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c index 08747fc3ee71..264bcc43da11 100644 --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c @@ -791,12 +791,14 @@ static int sun4i_tcon_init_regmap(struct device *dev, */ static struct sunxi_engine * sun4i_tcon_find_engine_traverse(struct sun4i_drv *drv, - struct device_node *node) + struct device_node *node, + u32 port_id) { struct device_node *port, *ep, *remote; struct sunxi_engine *engine = ERR_PTR(-EINVAL); + u32 reg = 0; - port = of_graph_get_port_by_id(node, 0); + port = of_graph_get_port_by_id(node, port_id); if (!port) return ERR_PTR(-EINVAL); @@ -826,8 +828,20 @@ sun4i_tcon_find_engine_traverse(struct sun4i_drv *drv, if (remote == engine->node) goto out_put_remote; + /* + * According to device tree binding input ports have even id + * number and output ports have odd id. Since component with + * more than one input and one output (TCON TOP) exits, correct + * remote input id has to be calculated by subtracting 1 from + * remote output id. If this for some reason can't be done, 0 + * is used as input port id. + */ + port = of_graph_get_remote_port(ep); + if (!of_property_read_u32(port, "reg", ®) && reg > 0) + reg -= 1; + /* keep looking through upstream ports */ - engine = sun4i_tcon_find_engine_traverse(drv, remote); + engine = sun4i_tcon_find_engine_traverse(drv, remote, reg); out_put_remote: of_node_put(remote); @@ -950,7 +964,7 @@ static struct sunxi_engine *sun4i_tcon_find_engine(struct sun4i_drv *drv, /* Fallback to old method by traversing input endpoints */ of_node_put(port); - return sun4i_tcon_find_engine_traverse(drv, node); + return sun4i_tcon_find_engine_traverse(drv, node, 0); } static int sun4i_tcon_bind(struct device *dev, struct device *master, |