|
@@ -58,6 +58,8 @@
|
|
|
#include <linux/dma-buf.h>
|
|
|
#include <linux/module.h>
|
|
|
#include <linux/slab.h>
|
|
|
+#include <linux/of.h>
|
|
|
+#include <linux/of_graph.h>
|
|
|
|
|
|
#include <drm/drmP.h>
|
|
|
#include <drm/drm_atomic_helper.h>
|
|
@@ -85,9 +87,13 @@ static int pl111_modeset_init(struct drm_device *dev)
|
|
|
{
|
|
|
struct drm_mode_config *mode_config;
|
|
|
struct pl111_drm_dev_private *priv = dev->dev_private;
|
|
|
- struct drm_panel *panel;
|
|
|
- struct drm_bridge *bridge;
|
|
|
+ struct device_node *np = dev->dev->of_node;
|
|
|
+ struct device_node *remote;
|
|
|
+ struct drm_panel *panel = NULL;
|
|
|
+ struct drm_bridge *bridge = NULL;
|
|
|
+ bool defer = false;
|
|
|
int ret = 0;
|
|
|
+ int i;
|
|
|
|
|
|
drm_mode_config_init(dev);
|
|
|
mode_config = &dev->mode_config;
|
|
@@ -97,10 +103,54 @@ static int pl111_modeset_init(struct drm_device *dev)
|
|
|
mode_config->min_height = 1;
|
|
|
mode_config->max_height = 768;
|
|
|
|
|
|
- ret = drm_of_find_panel_or_bridge(dev->dev->of_node,
|
|
|
- 0, 0, &panel, &bridge);
|
|
|
- if (ret && ret != -ENODEV)
|
|
|
- return ret;
|
|
|
+ i = 0;
|
|
|
+ for_each_endpoint_of_node(np, remote) {
|
|
|
+ struct drm_panel *tmp_panel;
|
|
|
+ struct drm_bridge *tmp_bridge;
|
|
|
+
|
|
|
+ dev_dbg(dev->dev, "checking endpoint %d\n", i);
|
|
|
+
|
|
|
+ ret = drm_of_find_panel_or_bridge(dev->dev->of_node,
|
|
|
+ 0, i,
|
|
|
+ &tmp_panel,
|
|
|
+ &tmp_bridge);
|
|
|
+ if (ret) {
|
|
|
+ if (ret == -EPROBE_DEFER) {
|
|
|
+ /*
|
|
|
+ * Something deferred, but that is often just
|
|
|
+ * another way of saying -ENODEV, but let's
|
|
|
+ * cast a vote for later deferral.
|
|
|
+ */
|
|
|
+ defer = true;
|
|
|
+ } else if (ret != -ENODEV) {
|
|
|
+ /* Continue, maybe something else is working */
|
|
|
+ dev_err(dev->dev,
|
|
|
+ "endpoint %d returns %d\n", i, ret);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (tmp_panel) {
|
|
|
+ dev_info(dev->dev,
|
|
|
+ "found panel on endpoint %d\n", i);
|
|
|
+ panel = tmp_panel;
|
|
|
+ }
|
|
|
+ if (tmp_bridge) {
|
|
|
+ dev_info(dev->dev,
|
|
|
+ "found bridge on endpoint %d\n", i);
|
|
|
+ bridge = tmp_bridge;
|
|
|
+ }
|
|
|
+
|
|
|
+ i++;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * If we can't find neither panel nor bridge on any of the
|
|
|
+ * endpoints, and any of them retured -EPROBE_DEFER, then
|
|
|
+ * let's defer this driver too.
|
|
|
+ */
|
|
|
+ if ((!panel && !bridge) && defer)
|
|
|
+ return -EPROBE_DEFER;
|
|
|
+
|
|
|
if (panel) {
|
|
|
bridge = drm_panel_bridge_add(panel,
|
|
|
DRM_MODE_CONNECTOR_Unknown);
|