|
@@ -10,6 +10,7 @@
|
|
|
*/
|
|
|
|
|
|
#include <linux/backlight.h>
|
|
|
+#include <linux/of_graph.h>
|
|
|
|
|
|
#include <drm/drmP.h>
|
|
|
#include <drm/drm_atomic_helper.h>
|
|
@@ -132,12 +133,12 @@ static const struct drm_connector_helper_funcs connector_helper_funcs = {
|
|
|
.mode_valid = fsl_dcu_drm_connector_mode_valid,
|
|
|
};
|
|
|
|
|
|
-int fsl_dcu_drm_connector_create(struct fsl_dcu_drm_device *fsl_dev,
|
|
|
- struct drm_encoder *encoder)
|
|
|
+static int fsl_dcu_attach_panel(struct fsl_dcu_drm_device *fsl_dev,
|
|
|
+ struct drm_panel *panel)
|
|
|
{
|
|
|
+ struct drm_encoder *encoder = &fsl_dev->encoder;
|
|
|
struct drm_connector *connector = &fsl_dev->connector.base;
|
|
|
struct drm_mode_config *mode_config = &fsl_dev->drm->mode_config;
|
|
|
- struct device_node *panel_node;
|
|
|
int ret;
|
|
|
|
|
|
fsl_dev->connector.encoder = encoder;
|
|
@@ -161,21 +162,7 @@ int fsl_dcu_drm_connector_create(struct fsl_dcu_drm_device *fsl_dev,
|
|
|
mode_config->dpms_property,
|
|
|
DRM_MODE_DPMS_OFF);
|
|
|
|
|
|
- panel_node = of_parse_phandle(fsl_dev->np, "fsl,panel", 0);
|
|
|
- if (!panel_node) {
|
|
|
- dev_err(fsl_dev->dev, "fsl,panel property not found\n");
|
|
|
- ret = -ENODEV;
|
|
|
- goto err_sysfs;
|
|
|
- }
|
|
|
-
|
|
|
- fsl_dev->connector.panel = of_drm_find_panel(panel_node);
|
|
|
- if (!fsl_dev->connector.panel) {
|
|
|
- ret = -EPROBE_DEFER;
|
|
|
- goto err_panel;
|
|
|
- }
|
|
|
- of_node_put(panel_node);
|
|
|
-
|
|
|
- ret = drm_panel_attach(fsl_dev->connector.panel, connector);
|
|
|
+ ret = drm_panel_attach(panel, connector);
|
|
|
if (ret) {
|
|
|
dev_err(fsl_dev->dev, "failed to attach panel\n");
|
|
|
goto err_sysfs;
|
|
@@ -183,11 +170,52 @@ int fsl_dcu_drm_connector_create(struct fsl_dcu_drm_device *fsl_dev,
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
-err_panel:
|
|
|
- of_node_put(panel_node);
|
|
|
err_sysfs:
|
|
|
drm_connector_unregister(connector);
|
|
|
err_cleanup:
|
|
|
drm_connector_cleanup(connector);
|
|
|
return ret;
|
|
|
}
|
|
|
+
|
|
|
+static int fsl_dcu_attach_endpoint(struct fsl_dcu_drm_device *fsl_dev,
|
|
|
+ const struct of_endpoint *ep)
|
|
|
+{
|
|
|
+ struct device_node *np;
|
|
|
+
|
|
|
+ np = of_graph_get_remote_port_parent(ep->local_node);
|
|
|
+
|
|
|
+ fsl_dev->connector.panel = of_drm_find_panel(np);
|
|
|
+ of_node_put(np);
|
|
|
+ if (fsl_dev->connector.panel)
|
|
|
+ return fsl_dcu_attach_panel(fsl_dev, fsl_dev->connector.panel);
|
|
|
+
|
|
|
+ return -ENODEV;
|
|
|
+}
|
|
|
+
|
|
|
+int fsl_dcu_create_outputs(struct fsl_dcu_drm_device *fsl_dev)
|
|
|
+{
|
|
|
+ struct of_endpoint ep;
|
|
|
+ struct device_node *ep_node, *panel_node;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ /* This is for backward compatibility */
|
|
|
+ panel_node = of_parse_phandle(fsl_dev->np, "fsl,panel", 0);
|
|
|
+ if (panel_node) {
|
|
|
+ fsl_dev->connector.panel = of_drm_find_panel(panel_node);
|
|
|
+ of_node_put(panel_node);
|
|
|
+ if (!fsl_dev->connector.panel)
|
|
|
+ return -EPROBE_DEFER;
|
|
|
+ return fsl_dcu_attach_panel(fsl_dev, fsl_dev->connector.panel);
|
|
|
+ }
|
|
|
+
|
|
|
+ ep_node = of_graph_get_next_endpoint(fsl_dev->np, NULL);
|
|
|
+ if (!ep_node)
|
|
|
+ return -ENODEV;
|
|
|
+
|
|
|
+ ret = of_graph_parse_endpoint(ep_node, &ep);
|
|
|
+ of_node_put(ep_node);
|
|
|
+ if (ret)
|
|
|
+ return -ENODEV;
|
|
|
+
|
|
|
+ return fsl_dcu_attach_endpoint(fsl_dev, &ep);
|
|
|
+}
|