[PATCH v6 31/34] iommu/mediatek: Get the proper bankid for multi banks
Matthias Brugger
matthias.bgg at gmail.com
Thu Apr 28 07:14:33 PDT 2022
On 07/04/2022 09:57, Yong Wu wrote:
> We preassign some ports in a special bank via the new defined
> banks_portmsk. Put it in the plat_data means it is not expected to be
> adjusted dynamically.
>
> If the iommu id in the iommu consumer's dtsi node is inside this
> banks_portmsk, then we switch it to this special iommu bank, and
> initialise the IOMMU bank HW.
>
> Each a bank has the independent pgtable(4GB iova range). Each a bank
> is a independent iommu domain/group. Currently we don't separate different
> iova ranges inside a bank.
>
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---
> drivers/iommu/mtk_iommu.c | 39 ++++++++++++++++++++++++++++++++++++---
> 1 file changed, 36 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
> index 0828cff97625..d42b3d35a36e 100644
> --- a/drivers/iommu/mtk_iommu.c
> +++ b/drivers/iommu/mtk_iommu.c
> @@ -191,6 +191,7 @@ struct mtk_iommu_plat_data {
>
> u8 banks_num;
> bool banks_enable[MTK_IOMMU_BANK_MAX];
> + unsigned int banks_portmsk[MTK_IOMMU_BANK_MAX];
> unsigned char larbid_remap[MTK_LARB_COM_MAX][MTK_LARB_SUBCOM_MAX];
> };
>
> @@ -467,6 +468,30 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
> return IRQ_HANDLED;
> }
>
> +static unsigned int mtk_iommu_get_bank_id(struct device *dev,
> + const struct mtk_iommu_plat_data *plat_data)
> +{
> + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
> + unsigned int i, portmsk = 0, bankid = 0;
> +
> + if (plat_data->banks_num == 1)
> + return bankid;
> +
> + for (i = 0; i < fwspec->num_ids; i++)
> + portmsk |= BIT(MTK_M4U_TO_PORT(fwspec->ids[i]));
> +
> + for (i = 0; i < plat_data->banks_num && i < MTK_IOMMU_BANK_MAX; i++) {
> + if (!plat_data->banks_enable[i])
> + continue;
> +
> + if (portmsk & plat_data->banks_portmsk[i]) {
> + bankid = i;
> + break;
> + }
> + }
> + return bankid; /* default is 0 */
> +}
> +
> static int mtk_iommu_get_iova_region_id(struct device *dev,
> const struct mtk_iommu_plat_data *plat_data)
> {
> @@ -619,13 +644,14 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain,
> struct list_head *hw_list = data->hw_list;
> struct device *m4udev = data->dev;
> struct mtk_iommu_bank_data *bank;
> - unsigned int bankid = 0;
> + unsigned int bankid;
> int ret, region_id;
>
> region_id = mtk_iommu_get_iova_region_id(dev, data->plat_data);
> if (region_id < 0)
> return region_id;
>
> + bankid = mtk_iommu_get_bank_id(dev, data->plat_data);
> mutex_lock(&dom->mutex);
> if (!dom->bank) {
> /* Data is in the frstdata in sharing pgtable case. */
> @@ -802,6 +828,7 @@ static struct iommu_group *mtk_iommu_device_group(struct device *dev)
> struct mtk_iommu_data *c_data = dev_iommu_priv_get(dev), *data;
> struct list_head *hw_list = c_data->hw_list;
> struct iommu_group *group;
> + unsigned int bankid, groupid;
> int regionid;
>
> data = mtk_iommu_get_frst_data(hw_list);
> @@ -812,12 +839,18 @@ static struct iommu_group *mtk_iommu_device_group(struct device *dev)
> if (regionid < 0)
> return ERR_PTR(regionid);
>
> + bankid = mtk_iommu_get_bank_id(dev, data->plat_data);
I think code readability would be improved if we add a new function like
mtk_iommu_get_id which call mtk_iommu_get_bankid and if necessary
mtk_iommu_get_regionid.
> mutex_lock(&data->mutex);
> - group = data->m4u_group[regionid];
> + /*
> + * If the bank function is enabled, each a bank is a iommu group/domain.
> + * otherwise, each a iova region is a iommu group/domain.
While at it:
"If the bank function is enabled, each bank is a iommu group/domain. Otherwise,
each iova region is a iommu group/domain."
Regards,
Matthias
> + */
> + groupid = bankid ? bankid : regionid;
> + group = data->m4u_group[groupid];
> if (!group) {
> group = iommu_group_alloc();
> if (!IS_ERR(group))
> - data->m4u_group[regionid] = group;
> + data->m4u_group[groupid] = group;
> } else {
> iommu_group_ref_get(group);
> }
More information about the Linux-mediatek
mailing list