Skip to content

Commit 5bcc483

Browse files
author
Laurent Pinchart
committed
drm: bridge: dw-hdmi: Attach to next bridge if available
On all platforms except i.MX and Rockchip, the dw-hdmi DT bindings require a video output port connected to an HDMI sink (most likely an HDMI connector, in rare cases another bridges converting HDMI to another protocol). For those platforms, retrieve the next bridge and attach it from the dw-hdmi bridge attach handler. Signed-off-by: Laurent Pinchart <[email protected]> Reviewed-by: Neil Armstrong <[email protected]> Tested-by: Kieran Bingham <[email protected]> # On V3U Reviewed-by: Kieran Bingham <[email protected]>
1 parent fb8d617 commit 5bcc483

File tree

2 files changed

+55
-1
lines changed

2 files changed

+55
-1
lines changed

drivers/gpu/drm/bridge/synopsys/dw-hdmi.c

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ struct dw_hdmi_phy_data {
143143
struct dw_hdmi {
144144
struct drm_connector connector;
145145
struct drm_bridge bridge;
146+
struct drm_bridge *next_bridge;
146147

147148
unsigned int version;
148149

@@ -2775,7 +2776,8 @@ static int dw_hdmi_bridge_attach(struct drm_bridge *bridge,
27752776
struct dw_hdmi *hdmi = bridge->driver_private;
27762777

27772778
if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)
2778-
return 0;
2779+
return drm_bridge_attach(bridge->encoder, hdmi->next_bridge,
2780+
bridge, flags);
27792781

27802782
return dw_hdmi_connector_create(hdmi);
27812783
}
@@ -3160,6 +3162,52 @@ static void dw_hdmi_init_hw(struct dw_hdmi *hdmi)
31603162
/* -----------------------------------------------------------------------------
31613163
* Probe/remove API, used from platforms based on the DRM bridge API.
31623164
*/
3165+
3166+
static int dw_hdmi_parse_dt(struct dw_hdmi *hdmi)
3167+
{
3168+
struct device_node *endpoint;
3169+
struct device_node *remote;
3170+
3171+
if (!hdmi->plat_data->output_port)
3172+
return 0;
3173+
3174+
endpoint = of_graph_get_endpoint_by_regs(hdmi->dev->of_node,
3175+
hdmi->plat_data->output_port,
3176+
-1);
3177+
if (!endpoint) {
3178+
/*
3179+
* On platforms whose bindings don't make the output port
3180+
* mandatory (such as Rockchip) the plat_data->output_port
3181+
* field isn't set, so it's safe to make this a fatal error.
3182+
*/
3183+
dev_err(hdmi->dev, "Missing endpoint in port@%u\n",
3184+
hdmi->plat_data->output_port);
3185+
return -ENODEV;
3186+
}
3187+
3188+
remote = of_graph_get_remote_port_parent(endpoint);
3189+
of_node_put(endpoint);
3190+
if (!remote) {
3191+
dev_err(hdmi->dev, "Endpoint in port@%u unconnected\n",
3192+
hdmi->plat_data->output_port);
3193+
return -ENODEV;
3194+
}
3195+
3196+
if (!of_device_is_available(remote)) {
3197+
dev_err(hdmi->dev, "port@%u remote device is disabled\n",
3198+
hdmi->plat_data->output_port);
3199+
of_node_put(remote);
3200+
return -ENODEV;
3201+
}
3202+
3203+
hdmi->next_bridge = of_drm_find_bridge(remote);
3204+
of_node_put(remote);
3205+
if (!hdmi->next_bridge)
3206+
return -EPROBE_DEFER;
3207+
3208+
return 0;
3209+
}
3210+
31633211
struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
31643212
const struct dw_hdmi_plat_data *plat_data)
31653213
{
@@ -3196,6 +3244,10 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
31963244
mutex_init(&hdmi->cec_notifier_mutex);
31973245
spin_lock_init(&hdmi->audio_lock);
31983246

3247+
ret = dw_hdmi_parse_dt(hdmi);
3248+
if (ret < 0)
3249+
return ERR_PTR(ret);
3250+
31993251
ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0);
32003252
if (ddc_node) {
32013253
hdmi->ddc = of_get_i2c_adapter_by_node(ddc_node);

include/drm/bridge/dw_hdmi.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,8 @@ struct dw_hdmi_phy_ops {
126126
struct dw_hdmi_plat_data {
127127
struct regmap *regm;
128128

129+
unsigned int output_port;
130+
129131
unsigned long input_bus_encoding;
130132
bool use_drm_infoframe;
131133
bool ycbcr_420_allowed;

0 commit comments

Comments
 (0)