Skip to content

Commit 4c93284

Browse files
AngeloGioacchino Del RegnoChun-Kuang Hu
authored andcommitted
drm/mediatek: Implement OF graphs support for display paths
It is impossible to add each and every possible DDP path combination for each and every possible combination of SoC and board: right now, this driver hardcodes configuration for 10 SoCs and this is going to grow larger and larger, and with new hacks like the introduction of mtk_drm_route which is anyway not enough for all final routes as the DSI cannot be connected to MERGE if it's not a dual-DSI, or enabling DSC preventively doesn't work if the display doesn't support it, or others. Since practically all display IPs in MediaTek SoCs support being interconnected with different instances of other, or the same, IPs or with different IPs and in different combinations, the final DDP pipeline is effectively a board specific configuration. Implement OF graphs support to the mediatek-drm drivers, allowing to stop hardcoding the paths, and preventing this driver to get a huge amount of arrays for each board and SoC combination, also paving the way to share the same mtk_mmsys_driver_data between multiple SoCs, making it more straightforward to add support for new chips. Note that the OVL_ADAPTOR software component driver needs relatively big changes in order to fully support OF Graphs (and more SoCs anyway) and such changes will come at a later time. As of now, the mtk_disp_ovl_adaptor driver takes the MERGE components (for example, on mt8195, merge 1 to 4) dynamically so, even though later updates to the ovl-adaptor driver will *not* require bindings changes, the merge1-4 will be temporarily omitted in the graph for the MT8195 SoC. This means that an example graph for this SoC looks like: mdp_rdma (0 ~ 7) -> padding (0 ~ 7) -> ethdr -> merge5 and the resulting path in this driver will be `ovl_adaptor -> merge5` Later updates to the ovl adaptor will expand it to support more SoCs and, in turn, to also fully support graphs. Reviewed-by: Alexandre Mergnat <[email protected]> Tested-by: Alexandre Mergnat <[email protected]> Acked-by: Sui Jingfeng <[email protected]> Tested-by: Michael Walle <[email protected]> # on kontron-sbc-i1200 Reviewed-by: CK Hu <[email protected]> Signed-off-by: AngeloGioacchino Del Regno <[email protected]> Link: https://patchwork.kernel.org/project/dri-devel/patch/[email protected]/ Signed-off-by: Chun-Kuang Hu <[email protected]>
1 parent 2b6433f commit 4c93284

File tree

6 files changed

+312
-22
lines changed

6 files changed

+312
-22
lines changed

drivers/gpu/drm/mediatek/mtk_disp_drv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ size_t mtk_ovl_get_num_formats(struct device *dev);
108108

109109
void mtk_ovl_adaptor_add_comp(struct device *dev, struct mtk_mutex *mutex);
110110
void mtk_ovl_adaptor_remove_comp(struct device *dev, struct mtk_mutex *mutex);
111+
bool mtk_ovl_adaptor_is_comp_present(struct device_node *node);
111112
void mtk_ovl_adaptor_connect(struct device *dev, struct device *mmsys_dev,
112113
unsigned int next);
113114
void mtk_ovl_adaptor_disconnect(struct device *dev, struct device *mmsys_dev,

drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,41 @@ static int compare_of(struct device *dev, void *data)
490490
return dev->of_node == data;
491491
}
492492

493+
static int ovl_adaptor_of_get_ddp_comp_type(struct device_node *node,
494+
enum mtk_ovl_adaptor_comp_type *ctype)
495+
{
496+
const struct of_device_id *of_id = of_match_node(mtk_ovl_adaptor_comp_dt_ids, node);
497+
498+
if (!of_id)
499+
return -EINVAL;
500+
501+
*ctype = (enum mtk_ovl_adaptor_comp_type)((uintptr_t)of_id->data);
502+
503+
return 0;
504+
}
505+
506+
bool mtk_ovl_adaptor_is_comp_present(struct device_node *node)
507+
{
508+
enum mtk_ovl_adaptor_comp_type type;
509+
int ret;
510+
511+
ret = ovl_adaptor_of_get_ddp_comp_type(node, &type);
512+
if (ret)
513+
return false;
514+
515+
if (type >= OVL_ADAPTOR_TYPE_NUM)
516+
return false;
517+
518+
/*
519+
* In the context of mediatek-drm, ETHDR, MDP_RDMA and Padding are
520+
* used exclusively by OVL Adaptor: if this component is not one of
521+
* those, it's likely not an OVL Adaptor path.
522+
*/
523+
return type == OVL_ADAPTOR_TYPE_ETHDR ||
524+
type == OVL_ADAPTOR_TYPE_MDP_RDMA ||
525+
type == OVL_ADAPTOR_TYPE_PADDING;
526+
}
527+
493528
static int ovl_adaptor_comp_init(struct device *dev, struct component_match **match)
494529
{
495530
struct mtk_disp_ovl_adaptor *priv = dev_get_drvdata(dev);
@@ -499,12 +534,11 @@ static int ovl_adaptor_comp_init(struct device *dev, struct component_match **ma
499534
parent = dev->parent->parent->of_node->parent;
500535

501536
for_each_child_of_node_scoped(parent, node) {
502-
const struct of_device_id *of_id;
503537
enum mtk_ovl_adaptor_comp_type type;
504-
int id;
538+
int id, ret;
505539

506-
of_id = of_match_node(mtk_ovl_adaptor_comp_dt_ids, node);
507-
if (!of_id)
540+
ret = ovl_adaptor_of_get_ddp_comp_type(node, &type);
541+
if (ret)
508542
continue;
509543

510544
if (!of_device_is_available(node)) {
@@ -513,7 +547,6 @@ static int ovl_adaptor_comp_init(struct device *dev, struct component_match **ma
513547
continue;
514548
}
515549

516-
type = (enum mtk_ovl_adaptor_comp_type)(uintptr_t)of_id->data;
517550
id = ovl_adaptor_comp_get_id(dev, node, type);
518551
if (id < 0) {
519552
dev_warn(dev, "Skipping unknown component %pOF\n",

drivers/gpu/drm/mediatek/mtk_dpi.c

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,20 @@ static int mtk_dpi_bridge_attach(struct drm_bridge *bridge,
704704
enum drm_bridge_attach_flags flags)
705705
{
706706
struct mtk_dpi *dpi = bridge_to_dpi(bridge);
707+
int ret;
708+
709+
dpi->next_bridge = devm_drm_of_get_bridge(dpi->dev, dpi->dev->of_node, 1, -1);
710+
if (IS_ERR(dpi->next_bridge)) {
711+
ret = PTR_ERR(dpi->next_bridge);
712+
if (ret == -EPROBE_DEFER)
713+
return ret;
714+
715+
/* Old devicetree has only one endpoint */
716+
dpi->next_bridge = devm_drm_of_get_bridge(dpi->dev, dpi->dev->of_node, 0, 0);
717+
if (IS_ERR(dpi->next_bridge))
718+
return dev_err_probe(dpi->dev, PTR_ERR(dpi->next_bridge),
719+
"Failed to get bridge\n");
720+
}
707721

708722
return drm_bridge_attach(bridge->encoder, dpi->next_bridge,
709723
&dpi->bridge, flags);
@@ -1058,13 +1072,6 @@ static int mtk_dpi_probe(struct platform_device *pdev)
10581072
if (dpi->irq < 0)
10591073
return dpi->irq;
10601074

1061-
dpi->next_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 0, 0);
1062-
if (IS_ERR(dpi->next_bridge))
1063-
return dev_err_probe(dev, PTR_ERR(dpi->next_bridge),
1064-
"Failed to get bridge\n");
1065-
1066-
dev_info(dev, "Found bridge node: %pOF\n", dpi->next_bridge->of_node);
1067-
10681075
platform_set_drvdata(pdev, dpi);
10691076

10701077
dpi->bridge.funcs = &mtk_dpi_bridge_funcs;

0 commit comments

Comments
 (0)