diff options
author | Philipp Zabel <p.zabel@pengutronix.de> | 2016-06-27 09:26:31 -0400 |
---|---|---|
committer | Philipp Zabel <p.zabel@pengutronix.de> | 2016-07-14 05:18:46 -0400 |
commit | f140b0cc776f8771adfa45d2ef234da72662443d (patch) | |
tree | e8d41146e4a5b9f0e2ccf7a9a53a166896fcba84 /drivers/gpu/drm/imx/parallel-display.c | |
parent | 76ecd9c9fb24b014a6f33fbb1287ede3be12158b (diff) |
drm/imx: parallel-display: add bridge support
Add support for bridge chips connected externally to the i.MX
DISP0/DISP1 DPI interfaces.
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Diffstat (limited to 'drivers/gpu/drm/imx/parallel-display.c')
-rw-r--r-- | drivers/gpu/drm/imx/parallel-display.c | 50 |
1 files changed, 41 insertions, 9 deletions
diff --git a/drivers/gpu/drm/imx/parallel-display.c b/drivers/gpu/drm/imx/parallel-display.c index 4abac21c5c9b..1dad297b01fd 100644 --- a/drivers/gpu/drm/imx/parallel-display.c +++ b/drivers/gpu/drm/imx/parallel-display.c | |||
@@ -35,6 +35,7 @@ struct imx_parallel_display { | |||
35 | u32 bus_format; | 35 | u32 bus_format; |
36 | struct drm_display_mode mode; | 36 | struct drm_display_mode mode; |
37 | struct drm_panel *panel; | 37 | struct drm_panel *panel; |
38 | struct drm_bridge *bridge; | ||
38 | }; | 39 | }; |
39 | 40 | ||
40 | static inline struct imx_parallel_display *con_to_imxpd(struct drm_connector *c) | 41 | static inline struct imx_parallel_display *con_to_imxpd(struct drm_connector *c) |
@@ -181,15 +182,29 @@ static int imx_pd_register(struct drm_device *drm, | |||
181 | drm_encoder_init(drm, encoder, &imx_pd_encoder_funcs, | 182 | drm_encoder_init(drm, encoder, &imx_pd_encoder_funcs, |
182 | DRM_MODE_ENCODER_NONE, NULL); | 183 | DRM_MODE_ENCODER_NONE, NULL); |
183 | 184 | ||
184 | drm_connector_helper_add(&imxpd->connector, | 185 | if (!imxpd->bridge) { |
185 | &imx_pd_connector_helper_funcs); | 186 | drm_connector_helper_add(&imxpd->connector, |
186 | drm_connector_init(drm, &imxpd->connector, &imx_pd_connector_funcs, | 187 | &imx_pd_connector_helper_funcs); |
187 | DRM_MODE_CONNECTOR_VGA); | 188 | drm_connector_init(drm, &imxpd->connector, |
189 | &imx_pd_connector_funcs, | ||
190 | DRM_MODE_CONNECTOR_VGA); | ||
191 | } | ||
188 | 192 | ||
189 | if (imxpd->panel) | 193 | if (imxpd->panel) |
190 | drm_panel_attach(imxpd->panel, &imxpd->connector); | 194 | drm_panel_attach(imxpd->panel, &imxpd->connector); |
191 | 195 | ||
192 | drm_mode_connector_attach_encoder(&imxpd->connector, encoder); | 196 | if (imxpd->bridge) { |
197 | imxpd->bridge->encoder = encoder; | ||
198 | encoder->bridge = imxpd->bridge; | ||
199 | ret = drm_bridge_attach(drm, imxpd->bridge); | ||
200 | if (ret < 0) { | ||
201 | dev_err(imxpd->dev, "failed to attach bridge: %d\n", | ||
202 | ret); | ||
203 | return ret; | ||
204 | } | ||
205 | } else { | ||
206 | drm_mode_connector_attach_encoder(&imxpd->connector, encoder); | ||
207 | } | ||
193 | 208 | ||
194 | return 0; | 209 | return 0; |
195 | } | 210 | } |
@@ -232,13 +247,30 @@ static int imx_pd_bind(struct device *dev, struct device *master, void *data) | |||
232 | struct device_node *remote; | 247 | struct device_node *remote; |
233 | 248 | ||
234 | remote = of_graph_get_remote_port_parent(ep); | 249 | remote = of_graph_get_remote_port_parent(ep); |
250 | if (!remote) { | ||
251 | dev_warn(dev, "endpoint %s not connected\n", | ||
252 | ep->full_name); | ||
253 | of_node_put(ep); | ||
254 | return -ENODEV; | ||
255 | } | ||
235 | of_node_put(ep); | 256 | of_node_put(ep); |
236 | if (remote) { | 257 | |
237 | imxpd->panel = of_drm_find_panel(remote); | 258 | imxpd->panel = of_drm_find_panel(remote); |
238 | of_node_put(remote); | 259 | if (imxpd->panel) { |
260 | dev_dbg(dev, "found panel %s\n", remote->full_name); | ||
261 | } else { | ||
262 | imxpd->bridge = of_drm_find_bridge(remote); | ||
263 | if (imxpd->bridge) | ||
264 | dev_dbg(dev, "found bridge %s\n", | ||
265 | remote->full_name); | ||
239 | } | 266 | } |
240 | if (!imxpd->panel) | 267 | if (!imxpd->panel && !imxpd->bridge) { |
268 | dev_dbg(dev, "waiting for panel or bridge %s\n", | ||
269 | remote->full_name); | ||
270 | of_node_put(remote); | ||
241 | return -EPROBE_DEFER; | 271 | return -EPROBE_DEFER; |
272 | } | ||
273 | of_node_put(remote); | ||
242 | } | 274 | } |
243 | 275 | ||
244 | imxpd->dev = dev; | 276 | imxpd->dev = dev; |