iommu/arm-smmu-v3: Parse PASID devicetree property of platform devices

For platform devices that support SubstreamID (SSID), firmware provides
the number of supported SSID bits. Restrict it to what the SMMU supports
and cache it into master->ssid_bits, which will also be used for PCI
PASID.

Reviewed-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
Signed-off-by: Will Deacon <will@kernel.org>
This commit is contained in:
Jean-Philippe Brucker 2020-01-15 13:52:29 +01:00 committed by Will Deacon
parent 2e981b9468
commit 89535821c0
3 changed files with 20 additions and 1 deletions

View File

@ -289,6 +289,12 @@
#define CTXDESC_CD_1_TTB0_MASK GENMASK_ULL(51, 4)
/*
* When the SMMU only supports linear context descriptor tables, pick a
* reasonable size limit (64kB).
*/
#define CTXDESC_LINEAR_CDMAX ilog2(SZ_64K / (CTXDESC_CD_DWORDS << 3))
/* Command queue */
#define CMDQ_ENT_SZ_SHIFT 4
#define CMDQ_ENT_DWORDS ((1 << CMDQ_ENT_SZ_SHIFT) >> 3)
@ -627,6 +633,7 @@ struct arm_smmu_master {
u32 *sids;
unsigned int num_sids;
bool ats_enabled;
unsigned int ssid_bits;
};
/* SMMU private data for an IOMMU domain */
@ -2559,6 +2566,12 @@ static int arm_smmu_add_device(struct device *dev)
}
}
master->ssid_bits = min(smmu->ssid_bits, fwspec->num_pasid_bits);
if (!(smmu->features & ARM_SMMU_FEAT_2_LVL_CDTAB))
master->ssid_bits = min_t(u8, master->ssid_bits,
CTXDESC_LINEAR_CDMAX);
group = iommu_group_get_for_dev(dev);
if (!IS_ERR(group)) {
iommu_group_put(group);

View File

@ -203,8 +203,12 @@ const struct iommu_ops *of_iommu_configure(struct device *dev,
if (err)
break;
}
}
fwspec = dev_iommu_fwspec_get(dev);
if (!err && fwspec)
of_property_read_u32(master_np, "pasid-num-bits",
&fwspec->num_pasid_bits);
}
/*
* Two success conditions can be represented by non-negative err here:

View File

@ -579,6 +579,7 @@ struct iommu_group *fsl_mc_device_group(struct device *dev);
* @ops: ops for this device's IOMMU
* @iommu_fwnode: firmware handle for this device's IOMMU
* @iommu_priv: IOMMU driver private data for this device
* @num_pasid_bits: number of PASID bits supported by this device
* @num_ids: number of associated device IDs
* @ids: IDs which this device may present to the IOMMU
*/
@ -587,6 +588,7 @@ struct iommu_fwspec {
struct fwnode_handle *iommu_fwnode;
void *iommu_priv;
u32 flags;
u32 num_pasid_bits;
unsigned int num_ids;
u32 ids[1];
};