Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 81876bc8 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "platform: qcom-geni-se: Add support to enable IOMMU in atomic context"

parents 34eba393 d39cf6aa
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ Optional properties:
- qcom,vote-for-bw: Boolean flag to check if ab/ib vote should be given
		    as bandwidth or BCM threashold.
- qcom,subsys-name: SSC QUPv3 subsystem name for SSR notification registration.
- qcom,iommu-atomic-ctx: Boolean flag to enable iommu in atomic context.

Optional subnodes:
qcom,iommu_qupv3_geni_se_cb:	Child node representing the QUPV3 context
+19 −12
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ struct bus_vectors {
 * @iommu_lock:		Lock to protect IOMMU Mapping & attachment.
 * @iommu_map:		IOMMU map of the memory space supported by this core.
 * @iommu_s1_bypass:	Bypass IOMMU stage 1 translation.
 * @iommu_atomic_ctx:	Enable IOMMU in atomic context.
 * @base:		Base address of this instance of QUPv3 core.
 * @bus_bw:		Client handle to the bus bandwidth request.
 * @bus_bw_noc:		Client handle to the QUP clock and DDR path bus
@@ -99,6 +100,7 @@ struct geni_se_device {
	struct mutex iommu_lock;
	struct dma_iommu_mapping *iommu_map;
	bool iommu_s1_bypass;
	bool iommu_atomic_ctx;
	void __iomem *base;
	struct msm_bus_client_handle *bus_bw;
	uint32_t bus_bw_noc;
@@ -1466,7 +1468,7 @@ static int geni_se_iommu_map_and_attach(struct geni_se_device *geni_se_dev)
{
	dma_addr_t va_start = GENI_SE_IOMMU_VA_START;
	size_t va_size = GENI_SE_IOMMU_VA_SIZE;
	int bypass = 1;
	int bypass = 1, atomic_ctx = 1;
	struct device *cb_dev = geni_se_dev->cb_dev;

	/*Don't proceed if IOMMU node is disabled*/
@@ -1489,18 +1491,21 @@ static int geni_se_iommu_map_and_attach(struct geni_se_device *geni_se_dev)
		return PTR_ERR(geni_se_dev->iommu_map);
	}

	if (geni_se_dev->iommu_s1_bypass) {
		if (iommu_domain_set_attr(geni_se_dev->iommu_map->domain,
					  DOMAIN_ATTR_S1_BYPASS, &bypass)) {
	/* Set either s1_bypass or atomic context as defined in DT */
	if ((geni_se_dev->iommu_s1_bypass &&
			iommu_domain_set_attr(geni_se_dev->iommu_map->domain,
				DOMAIN_ATTR_S1_BYPASS, &bypass)) ||
		(geni_se_dev->iommu_atomic_ctx &&
			iommu_domain_set_attr(geni_se_dev->iommu_map->domain,
				DOMAIN_ATTR_ATOMIC, &atomic_ctx))) {
		GENI_SE_ERR(geni_se_dev->log_ctx, false, NULL,
				"%s:%s Couldn't bypass s1 translation\n",
			"%s:%s Couldn't set iommu attribute\n",
			__func__, dev_name(cb_dev));
		arm_iommu_release_mapping(geni_se_dev->iommu_map);
		geni_se_dev->iommu_map = NULL;
		mutex_unlock(&geni_se_dev->iommu_lock);
		return -EIO;
	}
	}

	if (arm_iommu_attach_device(cb_dev, geni_se_dev->iommu_map)) {
		GENI_SE_ERR(geni_se_dev->log_ctx, false, NULL,
@@ -1916,6 +1921,8 @@ static int geni_se_probe(struct platform_device *pdev)
							"qcom,vote-for-bw");
	geni_se_dev->iommu_s1_bypass = of_property_read_bool(dev->of_node,
							"qcom,iommu-s1-bypass");
	geni_se_dev->iommu_atomic_ctx = of_property_read_bool(dev->of_node,
							"qcom,iommu-atomic-ctx");
	geni_se_dev->bus_bw_set = default_bus_bw_set;
	geni_se_dev->bus_bw_set_size =
				ARRAY_SIZE(default_bus_bw_set);