diff options
Diffstat (limited to 'drivers/gpu/drm/renesas/rz-du/rzg2l_du_encoder.c')
-rw-r--r-- | drivers/gpu/drm/renesas/rz-du/rzg2l_du_encoder.c | 44 |
1 files changed, 40 insertions, 4 deletions
diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_encoder.c b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_encoder.c index 564ab4cb3d37..5e6dd16705e6 100644 --- a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_encoder.c +++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_encoder.c @@ -22,6 +22,26 @@ * Encoder */ +static unsigned int rzg2l_du_encoder_count_ports(struct device_node *node) +{ + struct device_node *ports; + struct device_node *port; + unsigned int num_ports = 0; + + ports = of_get_child_by_name(node, "ports"); + if (!ports) + ports = of_node_get(node); + + for_each_child_of_node(ports, port) { + if (of_node_name_eq(port, "port")) + num_ports++; + } + + of_node_put(ports); + + return num_ports; +} + static const struct drm_encoder_funcs rzg2l_du_encoder_funcs = { }; @@ -50,10 +70,26 @@ int rzg2l_du_encoder_init(struct rzg2l_du_device *rcdu, struct drm_bridge *bridge; int ret; - /* Locate the DRM bridge from the DT node. */ - bridge = of_drm_find_bridge(enc_node); - if (!bridge) - return -EPROBE_DEFER; + /* + * Locate the DRM bridge from the DT node. For the DPAD outputs, if the + * DT node has a single port, assume that it describes a panel and + * create a panel bridge. + */ + if (output == RZG2L_DU_OUTPUT_DPAD0 && rzg2l_du_encoder_count_ports(enc_node) == 1) { + struct drm_panel *panel = of_drm_find_panel(enc_node); + + if (IS_ERR(panel)) + return PTR_ERR(panel); + + bridge = devm_drm_panel_bridge_add_typed(rcdu->dev, panel, + DRM_MODE_CONNECTOR_DPI); + if (IS_ERR(bridge)) + return PTR_ERR(bridge); + } else { + bridge = of_drm_find_bridge(enc_node); + if (!bridge) + return -EPROBE_DEFER; + } dev_dbg(rcdu->dev, "initializing encoder %pOF for output %s\n", enc_node, rzg2l_du_output_name(output)); |