Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/mediatek: dpi/dsi: Fix possible_crtcs calculation

mtk_find_possible_crtcs() assumes that the main path will always have
the CRTC with id 0, the ext id 1 and the third id 2. This is only true
if the paths are all available. But paths are optional (see also
comment in mtk_drm_kms_init()), e.g. the main path might not be enabled
or available at all. Then the CRTC IDs will shift one up, e.g. ext will
be 0 and the third path will be 1.

To fix that, dynamically calculate the IDs by the presence of the paths.

While at it, make the return code a signed one and return -ENODEV if no
path is found and handle the error in the callers.

Fixes: 5aa8e7647676 ("drm/mediatek: dpi/dsi: Change the getting possible_crtc way")
Suggested-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
Signed-off-by: Michael Walle <mwalle@kernel.org>
Link: https://patchwork.kernel.org/project/dri-devel/patch/20240606092122.2026313-1-mwalle@kernel.org/
Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>

authored by

Michael Walle and committed by
Chun-Kuang Hu
9ff6df49 45b70f71

+79 -38
+70 -35
drivers/gpu/drm/mediatek/mtk_ddp_comp.c
··· 514 514 return false; 515 515 } 516 516 517 - static unsigned int mtk_ddp_comp_find_in_route(struct device *dev, 518 - const struct mtk_drm_route *routes, 519 - unsigned int num_routes, 520 - struct mtk_ddp_comp *ddp_comp) 517 + static int mtk_ddp_comp_find_in_route(struct device *dev, 518 + const struct mtk_drm_route *routes, 519 + unsigned int num_routes, 520 + struct mtk_ddp_comp *ddp_comp) 521 521 { 522 - int ret; 523 522 unsigned int i; 524 523 525 - if (!routes) { 526 - ret = -EINVAL; 527 - goto err; 528 - } 524 + if (!routes) 525 + return -EINVAL; 529 526 530 527 for (i = 0; i < num_routes; i++) 531 528 if (dev == ddp_comp[routes[i].route_ddp].dev) 532 529 return BIT(routes[i].crtc_id); 533 530 534 - ret = -ENODEV; 535 - err: 531 + return -ENODEV; 532 + } 536 533 537 - DRM_INFO("Failed to find comp in ddp table, ret = %d\n", ret); 534 + static bool mtk_ddp_path_available(const unsigned int *path, 535 + unsigned int path_len, 536 + struct device_node **comp_node) 537 + { 538 + unsigned int i; 538 539 539 - return 0; 540 + if (!path || !path_len) 541 + return false; 542 + 543 + for (i = 0U; i < path_len; i++) { 544 + /* OVL_ADAPTOR doesn't have a device node */ 545 + if (path[i] == DDP_COMPONENT_DRM_OVL_ADAPTOR) 546 + continue; 547 + 548 + if (!comp_node[path[i]]) 549 + return false; 550 + } 551 + 552 + return true; 540 553 } 541 554 542 555 int mtk_ddp_comp_get_id(struct device_node *node, ··· 567 554 return -EINVAL; 568 555 } 569 556 570 - unsigned int mtk_find_possible_crtcs(struct drm_device *drm, struct device *dev) 557 + int mtk_find_possible_crtcs(struct drm_device *drm, struct device *dev) 571 558 { 572 559 struct mtk_drm_private *private = drm->dev_private; 573 - unsigned int ret = 0; 560 + const struct mtk_mmsys_driver_data *data; 561 + struct mtk_drm_private *priv_n; 562 + int i = 0, j; 563 + int ret; 574 564 575 - if (mtk_ddp_comp_find(dev, 576 - private->data->main_path, 577 - private->data->main_len, 578 - private->ddp_comp)) 579 - ret = BIT(0); 580 - else if (mtk_ddp_comp_find(dev, 581 - private->data->ext_path, 582 - private->data->ext_len, 583 - private->ddp_comp)) 584 - ret = BIT(1); 585 - else if (mtk_ddp_comp_find(dev, 586 - private->data->third_path, 587 - private->data->third_len, 588 - private->ddp_comp)) 589 - ret = BIT(2); 590 - else 591 - ret = mtk_ddp_comp_find_in_route(dev, 592 - private->data->conn_routes, 593 - private->data->num_conn_routes, 594 - private->ddp_comp); 565 + for (j = 0; j < private->data->mmsys_dev_num; j++) { 566 + priv_n = private->all_drm_private[j]; 567 + data = priv_n->data; 568 + 569 + if (mtk_ddp_path_available(data->main_path, data->main_len, 570 + priv_n->comp_node)) { 571 + if (mtk_ddp_comp_find(dev, data->main_path, 572 + data->main_len, 573 + priv_n->ddp_comp)) 574 + return BIT(i); 575 + i++; 576 + } 577 + 578 + if (mtk_ddp_path_available(data->ext_path, data->ext_len, 579 + priv_n->comp_node)) { 580 + if (mtk_ddp_comp_find(dev, data->ext_path, 581 + data->ext_len, 582 + priv_n->ddp_comp)) 583 + return BIT(i); 584 + i++; 585 + } 586 + 587 + if (mtk_ddp_path_available(data->third_path, data->third_len, 588 + priv_n->comp_node)) { 589 + if (mtk_ddp_comp_find(dev, data->third_path, 590 + data->third_len, 591 + priv_n->ddp_comp)) 592 + return BIT(i); 593 + i++; 594 + } 595 + } 596 + 597 + ret = mtk_ddp_comp_find_in_route(dev, 598 + private->data->conn_routes, 599 + private->data->num_conn_routes, 600 + private->ddp_comp); 601 + 602 + if (ret < 0) 603 + DRM_INFO("Failed to find comp in ddp table, ret = %d\n", ret); 595 604 596 605 return ret; 597 606 }
+1 -1
drivers/gpu/drm/mediatek/mtk_ddp_comp.h
··· 330 330 331 331 int mtk_ddp_comp_get_id(struct device_node *node, 332 332 enum mtk_ddp_comp_type comp_type); 333 - unsigned int mtk_find_possible_crtcs(struct drm_device *drm, struct device *dev); 333 + int mtk_find_possible_crtcs(struct drm_device *drm, struct device *dev); 334 334 int mtk_ddp_comp_init(struct device_node *comp_node, struct mtk_ddp_comp *comp, 335 335 unsigned int comp_id); 336 336 enum mtk_ddp_comp_type mtk_ddp_comp_get_type(unsigned int comp_id);
+4 -1
drivers/gpu/drm/mediatek/mtk_dpi.c
··· 805 805 return ret; 806 806 } 807 807 808 - dpi->encoder.possible_crtcs = mtk_find_possible_crtcs(drm_dev, dpi->dev); 808 + ret = mtk_find_possible_crtcs(drm_dev, dpi->dev); 809 + if (ret < 0) 810 + goto err_cleanup; 811 + dpi->encoder.possible_crtcs = ret; 809 812 810 813 ret = drm_bridge_attach(&dpi->encoder, &dpi->bridge, NULL, 811 814 DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+4 -1
drivers/gpu/drm/mediatek/mtk_dsi.c
··· 837 837 return ret; 838 838 } 839 839 840 - dsi->encoder.possible_crtcs = mtk_find_possible_crtcs(drm, dsi->host.dev); 840 + ret = mtk_find_possible_crtcs(drm, dsi->host.dev); 841 + if (ret < 0) 842 + goto err_cleanup_encoder; 843 + dsi->encoder.possible_crtcs = ret; 841 844 842 845 ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL, 843 846 DRM_BRIDGE_ATTACH_NO_CONNECTOR);