[PATCH 36/42] drm/mediatek: Support registering disp controller device subnodes
AngeloGioacchino Del Regno
angelogioacchino.delregno at collabora.com
Wed Jul 1 05:20:51 PDT 2026
In order to have a correct description of the hardware in the SoC
devicetree, look for Display Controller Subsystem sub-components
declared as subnodes of the display controller itself; to retain
compatibility with the older devicetrees, also keep looking for
sub-components in the main /soc node like before.
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
drivers/gpu/drm/mediatek/mtk_drm_drv.c | 218 ++++++++++++++-----------
1 file changed, 121 insertions(+), 97 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 482d05071125..50b4f79295b3 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -1237,6 +1237,107 @@ static int mtk_drm_of_ddp_path_build(struct device *dev, struct device_node *nod
return 0;
}
+static int mtk_drm_register_sibling(struct device *dev, struct mtk_drm_private *private,
+ struct device_node *node, struct component_match **match)
+{
+ enum mtk_ddp_comp_type comp_type;
+ int comp_inst_id;
+ bool comp_found;
+ int ret;
+
+ ret = mtk_drm_of_get_ddp_comp_type(node, &comp_type);
+ if (ret)
+ return -EAGAIN;
+
+ ret = of_device_is_available(node);
+ if (!ret) {
+ dev_dbg(dev, "Skipping disabled component %pOF\n", node);
+ return -EAGAIN;
+ }
+
+ if (comp_type == MTK_DISP_MUTEX) {
+ int id;
+
+ id = of_alias_get_id(node, "mutex");
+ if (id < 0 || id == private->data->mmsys_id) {
+ private->mutex_node = of_node_get(node);
+ dev_dbg(dev, "get mutex for mmsys %d", private->data->mmsys_id);
+ }
+ return 0;
+ }
+
+ comp_inst_id = mtk_ddp_comp_get_id(node, NULL, comp_type);
+ if (comp_inst_id < 0) {
+ dev_info(dev, "Skipping unknown component %pOF\n", node);
+ return 0;
+ }
+
+ if (comp_type == MTK_DISP_DIRECT_LINK)
+ comp_found = mtk_drm_find_directlink_comp(private);
+ else
+ comp_found = mtk_drm_find_mmsys_comp(private,
+ comp_type, comp_inst_id);
+
+ if (!comp_found)
+ return -EAGAIN;
+
+ /*
+ * Currently only the AAL, CCORR, COLOR, GAMMA, MERGE, OVL, RDMA, DSI, and DPI
+ * blocks have separate component platform drivers and initialize their own
+ * DDP component structure. The others are initialized here.
+ */
+ if (!mtk_ddp_comp_is_internal_comp(comp_type) &&
+ !mtk_ovl_adaptor_is_comp_present(node)) {
+ dev_info(dev, "Adding component match for %pOF\n",
+ node);
+ drm_of_component_match_add(dev, match, component_compare_of,
+ node);
+ }
+
+ if (comp_type == MTK_DISP_DIRECT_LINK) {
+ for_each_of_graph_port(node, port) {
+ u32 port_id;
+
+ of_property_read_u32(port, "reg", &port_id);
+ if (port_id > 1)
+ continue;
+
+ /* Even ports are inputs, odd ports are outputs */
+ if (port_id % 2)
+ comp_type = MTK_DISP_DIRECT_LINK_OUT;
+
+ for_each_of_graph_port_endpoint(port, ep) {
+ struct of_endpoint of_ep;
+
+ ret = of_graph_parse_endpoint(ep, &of_ep);
+ if (ret)
+ break;
+
+ ret = mtk_ddp_comp_init(dev, node, &private->hlist,
+ private->data->mmsys_id,
+ comp_type, of_ep.id);
+ if (ret)
+ break;
+ }
+
+ if (ret) {
+ of_node_put(node);
+ return ret;
+ }
+ }
+ } else {
+ ret = mtk_ddp_comp_init(dev, node, &private->hlist,
+ private->data->mmsys_id,
+ comp_type, comp_inst_id);
+ if (ret) {
+ of_node_put(node);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
static int mtk_drm_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -1298,107 +1399,29 @@ static int mtk_drm_probe(struct platform_device *pdev)
return -ENOMEM;
/* Iterate over sibling DISP function blocks */
- for_each_child_of_node(phandle->parent, node) {
- enum mtk_ddp_comp_type comp_type;
- u8 comp_inst_id;
- bool comp_found;
-
- ret = mtk_drm_of_get_ddp_comp_type(node, &comp_type);
- if (ret)
- continue;
-
- if (!of_device_is_available(node)) {
- dev_dbg(dev, "Skipping disabled component %pOF\n",
- node);
- continue;
- }
-
- if (comp_type == MTK_DISP_MUTEX) {
- int id;
-
- id = of_alias_get_id(node, "mutex");
- if (id < 0 || id == private->data->mmsys_id) {
- private->mutex_node = of_node_get(node);
- dev_dbg(dev, "get mutex for mmsys %d", private->data->mmsys_id);
- }
- continue;
- }
-
- comp_inst_id = mtk_ddp_comp_get_id(node, NULL, comp_type);
- if (comp_inst_id < 0) {
- dev_warn(dev, "Skipping unknown component %pOF\n",
- node);
- continue;
- }
-
- if (comp_type == MTK_DISP_DIRECT_LINK)
- comp_found = mtk_drm_find_directlink_comp(private);
- else
- comp_found = mtk_drm_find_mmsys_comp(private,
- comp_type, comp_inst_id);
-
- if (!comp_found)
- continue;
-
- /*
- * Currently only the AAL, CCORR, COLOR, GAMMA, MERGE, OVL, RDMA, DSI, and DPI
- * blocks have separate component platform drivers and initialize their own
- * DDP component structure. The others are initialized here.
- */
- if (!mtk_ddp_comp_is_internal_comp(comp_type) &&
- !mtk_ovl_adaptor_is_comp_present(node)) {
- dev_info(dev, "Adding component match for %pOF\n",
- node);
- drm_of_component_match_add(dev, &match, component_compare_of,
- node);
- }
-
- if (comp_type == MTK_DISP_DIRECT_LINK) {
- for_each_of_graph_port(node, port) {
- u32 port_id;
-
- of_property_read_u32(port, "reg", &port_id);
- if (port_id > 1)
- continue;
-
- /* Even ports are inputs, odd ports are outputs */
- if (port_id % 2)
- comp_type = MTK_DISP_DIRECT_LINK_OUT;
-
- for_each_of_graph_port_endpoint(port, ep) {
- struct of_endpoint of_ep;
-
- ret = of_graph_parse_endpoint(ep, &of_ep);
- if (ret)
- break;
-
- ret = mtk_ddp_comp_init(dev, node, &private->hlist,
- private->data->mmsys_id,
- comp_type, of_ep.id);
- if (ret)
- break;
- }
+ for_each_child_of_node(phandle, node) {
+ ret = mtk_drm_register_sibling(dev, private, node, &match);
+ if (ret && ret != -EAGAIN)
+ goto err_node;
+ }
- if (ret) {
- of_node_put(node);
- goto err_node;
- }
- }
- } else {
- ret = mtk_ddp_comp_init(dev, node, &private->hlist,
- private->data->mmsys_id,
- comp_type, comp_inst_id);
- if (ret) {
- of_node_put(node);
- goto err_node;
- }
- }
+ /*
+ * After the previous loop, it is expected to have all of the display
+ * controller sibling function blocks registered and added to the list.
+ *
+ * If nothing got registered this is a legacy devicetree with DISP
+ * siblings located under the /soc node instead of being children of
+ * the main Display Controller node.
+ */
+ for_each_child_of_node(phandle->parent, node) {
+ ret = mtk_drm_register_sibling(dev, private, node, &match);
+ if (ret && ret != -EAGAIN)
+ goto err_node;
}
if (!private->mutex_node) {
dev_err(dev, "Failed to find disp-mutex node\n");
- ret = -ENODEV;
- goto err_node;
+ return -ENODEV;
}
/* If mtk-mutex is not a trigger source, this is an old devicetree */
@@ -1425,7 +1448,8 @@ static int mtk_drm_probe(struct platform_device *pdev)
err_pm:
pm_runtime_disable(dev);
err_node:
- of_node_put(private->mutex_node);
+ if (private->mutex_node)
+ of_node_put(private->mutex_node);
return ret;
}
--
2.54.0
More information about the linux-arm-kernel
mailing list