Skip to content

Commit 97c7b66

Browse files
zhengnan-chenjoergroedel
authored andcommitted
iommu/mediatek: Add a flag DL_WITH_MULTI_LARB
Add DL_WITH_MULTI_LARB flag to support the HW which connect with multiple larbs. Prepare for mt8189. In mt8189, the display connect with larb1 and larb2 at the same time. Thus, we should add link between disp-dev with these two larbs. Signed-off-by: Zhengnan Chen <zhengnan.chen@mediatek.com> Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com> Reviewed-by: Yong Wu <yong.wu@mediatek.com> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
1 parent 812df54 commit 97c7b66

1 file changed

Lines changed: 43 additions & 13 deletions

File tree

drivers/iommu/mtk_iommu.c

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@
147147
#define TF_PORT_TO_ADDR_MT8173 BIT(18)
148148
#define INT_ID_PORT_WIDTH_6 BIT(19)
149149
#define CFG_IFA_MASTER_IN_ATF BIT(20)
150+
#define DL_WITH_MULTI_LARB BIT(21)
150151

151152
#define MTK_IOMMU_HAS_FLAG_MASK(pdata, _x, mask) \
152153
((((pdata)->flags) & (mask)) == (_x))
@@ -865,49 +866,78 @@ static struct iommu_device *mtk_iommu_probe_device(struct device *dev)
865866
struct mtk_iommu_data *data = dev_iommu_priv_get(dev);
866867
struct device_link *link;
867868
struct device *larbdev;
869+
unsigned long larbid_msk = 0;
868870
unsigned int larbid, larbidx, i;
869871

870872
if (!MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM))
871873
return &data->iommu;
872874

873875
/*
874876
* Link the consumer device with the smi-larb device(supplier).
875-
* The device that connects with each a larb is a independent HW.
876-
* All the ports in each a device should be in the same larbs.
877+
* w/DL_WITH_MULTI_LARB: the master may connect with multi larbs,
878+
* we should create device link with each larb.
879+
* w/o DL_WITH_MULTI_LARB: the master must connect with one larb,
880+
* otherwise fail.
877881
*/
878882
larbid = MTK_M4U_TO_LARB(fwspec->ids[0]);
879883
if (larbid >= MTK_LARB_NR_MAX)
880884
return ERR_PTR(-EINVAL);
881885

886+
larbid_msk |= BIT(larbid);
887+
882888
for (i = 1; i < fwspec->num_ids; i++) {
883889
larbidx = MTK_M4U_TO_LARB(fwspec->ids[i]);
884-
if (larbid != larbidx) {
890+
if (MTK_IOMMU_HAS_FLAG(data->plat_data, DL_WITH_MULTI_LARB)) {
891+
larbid_msk |= BIT(larbidx);
892+
} else if (larbid != larbidx) {
885893
dev_err(dev, "Can only use one larb. Fail@larb%d-%d.\n",
886894
larbid, larbidx);
887895
return ERR_PTR(-EINVAL);
888896
}
889897
}
890-
larbdev = data->larb_imu[larbid].dev;
891-
if (!larbdev)
892-
return ERR_PTR(-EINVAL);
893898

894-
link = device_link_add(dev, larbdev,
895-
DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS);
896-
if (!link)
897-
dev_err(dev, "Unable to link %s\n", dev_name(larbdev));
899+
for_each_set_bit(larbid, &larbid_msk, 32) {
900+
larbdev = data->larb_imu[larbid].dev;
901+
if (!larbdev)
902+
return ERR_PTR(-EINVAL);
903+
904+
link = device_link_add(dev, larbdev,
905+
DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS);
906+
if (!link) {
907+
dev_err(dev, "Unable to link %s\n", dev_name(larbdev));
908+
goto link_remove;
909+
}
910+
}
911+
898912
return &data->iommu;
913+
914+
link_remove:
915+
for_each_set_bit(i, &larbid_msk, larbid) {
916+
larbdev = data->larb_imu[i].dev;
917+
device_link_remove(dev, larbdev);
918+
}
919+
920+
return ERR_PTR(-ENODEV);
899921
}
900922

901923
static void mtk_iommu_release_device(struct device *dev)
902924
{
903925
struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
904926
struct mtk_iommu_data *data;
905927
struct device *larbdev;
906-
unsigned int larbid;
928+
unsigned int larbid, i;
929+
unsigned long larbid_msk = 0;
907930

908931
data = dev_iommu_priv_get(dev);
909-
if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM)) {
910-
larbid = MTK_M4U_TO_LARB(fwspec->ids[0]);
932+
if (!MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM))
933+
return;
934+
935+
for (i = 0; i < fwspec->num_ids; i++) {
936+
larbid = MTK_M4U_TO_LARB(fwspec->ids[i]);
937+
larbid_msk |= BIT(larbid);
938+
}
939+
940+
for_each_set_bit(larbid, &larbid_msk, 32) {
911941
larbdev = data->larb_imu[larbid].dev;
912942
device_link_remove(dev, larbdev);
913943
}

0 commit comments

Comments
 (0)