Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/imx: imx-ldb: Add DDC support

Add support for reading EDID over Display Data Channel. If no DDC
adapter is available, falls back to hardcoded EDID or display-timings
node as before.

Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
Signed-off-by: Akshay Bhat <akshay.bhat@timesys.com>
Acked-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>

authored by

Steve Longerbeam and committed by
Philipp Zabel
a6d206e2 1a695a90

+34 -8
+34 -8
drivers/gpu/drm/imx/imx-ldb.c
··· 59 59 struct drm_encoder encoder; 60 60 struct drm_panel *panel; 61 61 struct device_node *child; 62 + struct i2c_adapter *ddc; 62 63 int chno; 63 64 void *edid; 64 65 int edid_len; ··· 107 106 if (num_modes > 0) 108 107 return num_modes; 109 108 } 109 + 110 + if (!imx_ldb_ch->edid && imx_ldb_ch->ddc) 111 + imx_ldb_ch->edid = drm_get_edid(connector, imx_ldb_ch->ddc); 110 112 111 113 if (imx_ldb_ch->edid) { 112 114 drm_mode_connector_update_edid_property(connector, ··· 557 553 558 554 for_each_child_of_node(np, child) { 559 555 struct imx_ldb_channel *channel; 556 + struct device_node *ddc_node; 560 557 struct device_node *port; 561 558 562 559 ret = of_property_read_u32(child, "reg", &i); ··· 600 595 } 601 596 } 602 597 603 - edidp = of_get_property(child, "edid", &channel->edid_len); 604 - if (edidp) { 605 - channel->edid = kmemdup(edidp, channel->edid_len, 606 - GFP_KERNEL); 607 - } else if (!channel->panel) { 608 - ret = of_get_drm_display_mode(child, &channel->mode, 0); 609 - if (!ret) 610 - channel->mode_valid = 1; 598 + ddc_node = of_parse_phandle(child, "ddc-i2c-bus", 0); 599 + if (ddc_node) { 600 + channel->ddc = of_find_i2c_adapter_by_node(ddc_node); 601 + of_node_put(ddc_node); 602 + if (!channel->ddc) { 603 + dev_warn(dev, "failed to get ddc i2c adapter\n"); 604 + return -EPROBE_DEFER; 605 + } 606 + } 607 + 608 + if (!channel->ddc) { 609 + /* if no DDC available, fallback to hardcoded EDID */ 610 + dev_dbg(dev, "no ddc available\n"); 611 + 612 + edidp = of_get_property(child, "edid", 613 + &channel->edid_len); 614 + if (edidp) { 615 + channel->edid = kmemdup(edidp, 616 + channel->edid_len, 617 + GFP_KERNEL); 618 + } else if (!channel->panel) { 619 + /* fallback to display-timings node */ 620 + ret = of_get_drm_display_mode(child, 621 + &channel->mode, 622 + 0); 623 + if (!ret) 624 + channel->mode_valid = 1; 625 + } 611 626 } 612 627 613 628 channel->bus_format = of_get_bus_format(dev, child); ··· 672 647 channel->encoder.funcs->destroy(&channel->encoder); 673 648 674 649 kfree(channel->edid); 650 + i2c_put_adapter(channel->ddc); 675 651 } 676 652 } 677 653