aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/imx/imx-ldb.c
diff options
context:
space:
mode:
authorPeter Senna Tschudin <peter.senna@collabora.com>2016-08-04 18:36:58 -0400
committerPhilipp Zabel <p.zabel@pengutronix.de>2016-08-11 05:34:22 -0400
commitdc80d7038883feca2abd08975165bc0d83c84762 (patch)
tree7985a8fedbabcf37c8c8ed964ba4357b1291fcb3 /drivers/gpu/drm/imx/imx-ldb.c
parent3a2ad5028cf2cc3067c7d8bf7fab68d9c1c3c0e8 (diff)
drm/imx-ldb: Add support to drm-bridge
Add support to attach a drm_bridge to imx-ldb in addition to existing support to attach a LVDS panel. This patch does a simple code refactoring by moving code from for_each_child_of_node iterator to a new function named imx_ldb_panel_ddc(). This was necessary to allow the panel ddc code to run only when the imx_ldb is not attached to a bridge. Cc: Enric Balletbo i Serra <enric.balletbo@collabora.com> Cc: Philipp Zabel <p.zabel@pengutronix.de> Cc: Rob Herring <robh@kernel.org> Cc: Fabio Estevam <fabio.estevam@nxp.com> Cc: David Airlie <airlied@linux.ie> Cc: Thierry Reding <treding@nvidia.com> Cc: Thierry Reding <thierry.reding@gmail.com> Signed-off-by: Peter Senna Tschudin <peter.senna@collabora.com> Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Diffstat (limited to 'drivers/gpu/drm/imx/imx-ldb.c')
-rw-r--r--drivers/gpu/drm/imx/imx-ldb.c120
1 files changed, 79 insertions, 41 deletions
diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c
index 7b588b44b845..4eed3a6addad 100644
--- a/drivers/gpu/drm/imx/imx-ldb.c
+++ b/drivers/gpu/drm/imx/imx-ldb.c
@@ -57,7 +57,11 @@ struct imx_ldb_channel {
57 struct imx_ldb *ldb; 57 struct imx_ldb *ldb;
58 struct drm_connector connector; 58 struct drm_connector connector;
59 struct drm_encoder encoder; 59 struct drm_encoder encoder;
60
61 /* Defines what is connected to the ldb, only one at a time */
60 struct drm_panel *panel; 62 struct drm_panel *panel;
63 struct drm_bridge *bridge;
64
61 struct device_node *child; 65 struct device_node *child;
62 struct i2c_adapter *ddc; 66 struct i2c_adapter *ddc;
63 int chno; 67 int chno;
@@ -468,10 +472,30 @@ static int imx_ldb_register(struct drm_device *drm,
468 drm_encoder_init(drm, encoder, &imx_ldb_encoder_funcs, 472 drm_encoder_init(drm, encoder, &imx_ldb_encoder_funcs,
469 DRM_MODE_ENCODER_LVDS, NULL); 473 DRM_MODE_ENCODER_LVDS, NULL);
470 474
471 drm_connector_helper_add(&imx_ldb_ch->connector, 475 if (imx_ldb_ch->bridge) {
472 &imx_ldb_connector_helper_funcs); 476 imx_ldb_ch->bridge->encoder = encoder;
473 drm_connector_init(drm, &imx_ldb_ch->connector, 477
474 &imx_ldb_connector_funcs, DRM_MODE_CONNECTOR_LVDS); 478 imx_ldb_ch->encoder.bridge = imx_ldb_ch->bridge;
479 ret = drm_bridge_attach(drm, imx_ldb_ch->bridge);
480 if (ret) {
481 DRM_ERROR("Failed to initialize bridge with drm\n");
482 return ret;
483 }
484 } else {
485 /*
486 * We want to add the connector whenever there is no bridge
487 * that brings its own, not only when there is a panel. For
488 * historical reasons, the ldb driver can also work without
489 * a panel.
490 */
491 drm_connector_helper_add(&imx_ldb_ch->connector,
492 &imx_ldb_connector_helper_funcs);
493 drm_connector_init(drm, &imx_ldb_ch->connector,
494 &imx_ldb_connector_funcs,
495 DRM_MODE_CONNECTOR_LVDS);
496 drm_mode_connector_attach_encoder(&imx_ldb_ch->connector,
497 encoder);
498 }
475 499
476 if (imx_ldb_ch->panel) { 500 if (imx_ldb_ch->panel) {
477 ret = drm_panel_attach(imx_ldb_ch->panel, 501 ret = drm_panel_attach(imx_ldb_ch->panel,
@@ -480,8 +504,6 @@ static int imx_ldb_register(struct drm_device *drm,
480 return ret; 504 return ret;
481 } 505 }
482 506
483 drm_mode_connector_attach_encoder(&imx_ldb_ch->connector, encoder);
484
485 return 0; 507 return 0;
486} 508}
487 509
@@ -550,6 +572,46 @@ static const struct of_device_id imx_ldb_dt_ids[] = {
550}; 572};
551MODULE_DEVICE_TABLE(of, imx_ldb_dt_ids); 573MODULE_DEVICE_TABLE(of, imx_ldb_dt_ids);
552 574
575static int imx_ldb_panel_ddc(struct device *dev,
576 struct imx_ldb_channel *channel, struct device_node *child)
577{
578 struct device_node *ddc_node;
579 const u8 *edidp;
580 int ret;
581
582 ddc_node = of_parse_phandle(child, "ddc-i2c-bus", 0);
583 if (ddc_node) {
584 channel->ddc = of_find_i2c_adapter_by_node(ddc_node);
585 of_node_put(ddc_node);
586 if (!channel->ddc) {
587 dev_warn(dev, "failed to get ddc i2c adapter\n");
588 return -EPROBE_DEFER;
589 }
590 }
591
592 if (!channel->ddc) {
593 /* if no DDC available, fallback to hardcoded EDID */
594 dev_dbg(dev, "no ddc available\n");
595
596 edidp = of_get_property(child, "edid",
597 &channel->edid_len);
598 if (edidp) {
599 channel->edid = kmemdup(edidp,
600 channel->edid_len,
601 GFP_KERNEL);
602 } else if (!channel->panel) {
603 /* fallback to display-timings node */
604 ret = of_get_drm_display_mode(child,
605 &channel->mode,
606 &channel->bus_flags,
607 OF_USE_NATIVE_MODE);
608 if (!ret)
609 channel->mode_valid = 1;
610 }
611 }
612 return 0;
613}
614
553static int imx_ldb_bind(struct device *dev, struct device *master, void *data) 615static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
554{ 616{
555 struct drm_device *drm = data; 617 struct drm_device *drm = data;
@@ -557,7 +619,6 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
557 const struct of_device_id *of_id = 619 const struct of_device_id *of_id =
558 of_match_device(imx_ldb_dt_ids, dev); 620 of_match_device(imx_ldb_dt_ids, dev);
559 struct device_node *child; 621 struct device_node *child;
560 const u8 *edidp;
561 struct imx_ldb *imx_ldb; 622 struct imx_ldb *imx_ldb;
562 int dual; 623 int dual;
563 int ret; 624 int ret;
@@ -607,7 +668,6 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
607 668
608 for_each_child_of_node(np, child) { 669 for_each_child_of_node(np, child) {
609 struct imx_ldb_channel *channel; 670 struct imx_ldb_channel *channel;
610 struct device_node *ddc_node;
611 struct device_node *ep; 671 struct device_node *ep;
612 int bus_format; 672 int bus_format;
613 673
@@ -640,47 +700,25 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
640 700
641 remote = of_graph_get_remote_port_parent(ep); 701 remote = of_graph_get_remote_port_parent(ep);
642 of_node_put(ep); 702 of_node_put(ep);
643 if (remote) 703 if (remote) {
644 channel->panel = of_drm_find_panel(remote); 704 channel->panel = of_drm_find_panel(remote);
645 else 705 channel->bridge = of_drm_find_bridge(remote);
706 } else
646 return -EPROBE_DEFER; 707 return -EPROBE_DEFER;
647 of_node_put(remote); 708 of_node_put(remote);
648 if (!channel->panel) {
649 dev_err(dev, "panel not found: %s\n",
650 remote->full_name);
651 return -EPROBE_DEFER;
652 }
653 }
654 709
655 ddc_node = of_parse_phandle(child, "ddc-i2c-bus", 0); 710 if (!channel->panel && !channel->bridge) {
656 if (ddc_node) { 711 dev_err(dev, "panel/bridge not found: %s\n",
657 channel->ddc = of_find_i2c_adapter_by_node(ddc_node); 712 remote->full_name);
658 of_node_put(ddc_node);
659 if (!channel->ddc) {
660 dev_warn(dev, "failed to get ddc i2c adapter\n");
661 return -EPROBE_DEFER; 713 return -EPROBE_DEFER;
662 } 714 }
663 } 715 }
664 716
665 if (!channel->ddc) { 717 /* panel ddc only if there is no bridge */
666 /* if no DDC available, fallback to hardcoded EDID */ 718 if (!channel->bridge) {
667 dev_dbg(dev, "no ddc available\n"); 719 ret = imx_ldb_panel_ddc(dev, channel, child);
668 720 if (ret)
669 edidp = of_get_property(child, "edid", 721 return ret;
670 &channel->edid_len);
671 if (edidp) {
672 channel->edid = kmemdup(edidp,
673 channel->edid_len,
674 GFP_KERNEL);
675 } else if (!channel->panel) {
676 /* fallback to display-timings node */
677 ret = of_get_drm_display_mode(child,
678 &channel->mode,
679 &channel->bus_flags,
680 OF_USE_NATIVE_MODE);
681 if (!ret)
682 channel->mode_valid = 1;
683 }
684 } 722 }
685 723
686 bus_format = of_get_bus_format(dev, child); 724 bus_format = of_get_bus_format(dev, child);