aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/imx/parallel-display.c
diff options
context:
space:
mode:
authorPhilipp Zabel <p.zabel@pengutronix.de>2016-06-27 09:26:31 -0400
committerPhilipp Zabel <p.zabel@pengutronix.de>2016-07-14 05:18:46 -0400
commitf140b0cc776f8771adfa45d2ef234da72662443d (patch)
treee8d41146e4a5b9f0e2ccf7a9a53a166896fcba84 /drivers/gpu/drm/imx/parallel-display.c
parent76ecd9c9fb24b014a6f33fbb1287ede3be12158b (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.c50
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
40static inline struct imx_parallel_display *con_to_imxpd(struct drm_connector *c) 41static 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;