summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c')
-rw-r--r--drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c44
1 files changed, 42 insertions, 2 deletions
diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
index 9f40a44b456b..31875b636434 100644
--- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
+++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
@@ -12,6 +12,7 @@
#include <drm/drm_crtc_helper.h>
#include "sun8i_dw_hdmi.h"
+#include "sun8i_tcon_top.h"
static void sun8i_dw_hdmi_encoder_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *mode,
@@ -41,6 +42,44 @@ sun8i_dw_hdmi_mode_valid(struct drm_connector *connector,
return MODE_OK;
}
+static bool sun8i_dw_hdmi_node_is_tcon_top(struct device_node *node)
+{
+ return IS_ENABLED(CONFIG_DRM_SUN8I_TCON_TOP) &&
+ !!of_match_node(sun8i_tcon_top_of_table, node);
+}
+
+static u32 sun8i_dw_hdmi_find_possible_crtcs(struct drm_device *drm,
+ struct device_node *node)
+{
+ struct device_node *port, *ep, *remote, *remote_port;
+ u32 crtcs = 0;
+
+ remote = of_graph_get_remote_node(node, 0, -1);
+ if (!remote)
+ return 0;
+
+ if (sun8i_dw_hdmi_node_is_tcon_top(remote)) {
+ port = of_graph_get_port_by_id(remote, 4);
+ if (!port)
+ goto crtcs_exit;
+
+ for_each_child_of_node(port, ep) {
+ remote_port = of_graph_get_remote_port(ep);
+ if (remote_port) {
+ crtcs |= drm_of_crtc_port_mask(drm, remote_port);
+ of_node_put(remote_port);
+ }
+ }
+ } else {
+ crtcs = drm_of_find_possible_crtcs(drm, node);
+ }
+
+crtcs_exit:
+ of_node_put(remote);
+
+ return crtcs;
+}
+
static int sun8i_dw_hdmi_bind(struct device *dev, struct device *master,
void *data)
{
@@ -63,7 +102,8 @@ static int sun8i_dw_hdmi_bind(struct device *dev, struct device *master,
hdmi->dev = &pdev->dev;
encoder = &hdmi->encoder;
- encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
+ encoder->possible_crtcs =
+ sun8i_dw_hdmi_find_possible_crtcs(drm, dev->of_node);
/*
* If we failed to find the CRTC(s) which this encoder is
* supposed to be connected to, it's because the CRTC has
@@ -181,7 +221,7 @@ static const struct of_device_id sun8i_dw_hdmi_dt_ids[] = {
};
MODULE_DEVICE_TABLE(of, sun8i_dw_hdmi_dt_ids);
-struct platform_driver sun8i_dw_hdmi_pltfm_driver = {
+static struct platform_driver sun8i_dw_hdmi_pltfm_driver = {
.probe = sun8i_dw_hdmi_probe,
.remove = sun8i_dw_hdmi_remove,
.driver = {