Hi Laurent,
Thank you for the patch,
On 02/03/2019 16:17, Laurent Pinchart wrote:
The R-Car DU driver assumes that a bridge is always connected to the DU output. This is valid for the LVDS and HDMI outputs, but the DPAD outputs can be connected directly to a panel, in which case no bridge is available.
To support this use case, detect whether the entities connected to the DU DPAD outputs are encoders or panels based on the number of ports of their DT node, and retrieve the corresponding type of DRM objects. For panels, additionally create panel bridge instances.
Signed-off-by: Laurent Pinchart laurent.pinchart+renesas@ideasonboard.com
Except for some minor wording on the comment, which I'll let you handle,
Reviewed-by: Kieran Bingham kieran.bingham+renesas@ideasonboard.com
drivers/gpu/drm/rcar-du/rcar_du_encoder.c | 54 ++++++++++++++++++++--- 1 file changed, 48 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c index 8ee4e762f4e5..595ecfa1ff0e 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c @@ -28,13 +28,33 @@ static const struct drm_encoder_funcs encoder_funcs = { .destroy = drm_encoder_cleanup, };
+static unsigned int rcar_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(node);
- return num_ports;
+}
int rcar_du_encoder_init(struct rcar_du_device *rcdu, enum rcar_du_output output, struct device_node *enc_node) { struct rcar_du_encoder *renc; struct drm_encoder *encoder;
- struct drm_bridge *bridge = NULL;
struct drm_bridge *bridge; int ret;
renc = devm_kzalloc(rcdu->dev, sizeof(*renc), GFP_KERNEL);
@@ -48,11 +68,33 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu, dev_dbg(rcdu->dev, "initializing encoder %pOF for output %u\n", enc_node, output);
- /* Locate the DRM bridge from the encoder DT node. */
- bridge = of_drm_find_bridge(enc_node);
- if (!bridge) {
ret = -EPROBE_DEFER;
goto done;
- /*
* Locate the DRM bridge from the DT node. For the DPAD outputs, if the
* DT node has a single port, consider it describes a panel and create a
consider it as describing? (if it's an assumption that has been made)
consider if it describes? (if it's conditional)
I'm not sure I fully understand the intent of the sentence to correct it - but it needs a little tweak. The use of the word 'consider' makes me assume that it might not need a panel bridge, and some further decision needs to be made, but the code looks like it assumes one port means there should be a panel - and a bridge will be added.
* panel bridge.
*/
if ((output == RCAR_DU_OUTPUT_DPAD0 ||
output == RCAR_DU_OUTPUT_DPAD1) &&
rcar_du_encoder_count_ports(enc_node) == 1) {
struct drm_panel *panel = of_drm_find_panel(enc_node);
if (IS_ERR(panel)) {
ret = PTR_ERR(panel);
goto done;
}
bridge = devm_drm_panel_bridge_add(rcdu->dev, panel,
DRM_MODE_CONNECTOR_DPI);
if (IS_ERR(bridge)) {
ret = PTR_ERR(bridge);
goto done;
}
} else {
bridge = of_drm_find_bridge(enc_node);
if (!bridge) {
ret = -EPROBE_DEFER;
goto done;
}
}
ret = drm_encoder_init(rcdu->ddev, encoder, &encoder_funcs,