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

Commit 93e97525 authored by Michael Adisumarta's avatar Michael Adisumarta
Browse files

msm: ipa: SMMU S1 enable/bypass support for all context Banks



Changes to add support for enabling SMMU S1 for all context
Banks in IPA - AP/USB, WLAN and UC.

Change-Id: I8944efdbfd580f7ed3c7da59023bce918b90fe6a
Acked-by: default avatarJyothi Jayanthi <jyothij@qti.qualcomm.com>
Signed-off-by: default avatarMichael Adisumarta <madisuma@codeaurora.org>
parent 389894e0
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -28,7 +28,6 @@ Optional:
- qcom,lan-rx-ring-size: size of LAN rx ring, default is 192
- qcom,arm-smmu: SMMU is present and ARM SMMU driver is used
- qcom,msm-smmu: SMMU is present and QSMMU driver is used
- qcom,smmu-s1-bypass: Boolean context flag to set SMMU to S1 bypass
- qcom,smmu-fast-map: Boolean context flag to set SMMU to fastpath mode
- ipa_smmu_ap: AP general purpose SMMU device
	compatible "qcom,ipa-smmu-ap-cb"
@@ -122,6 +121,9 @@ IPA SMMU sub nodes

-compatible: "qcom,ipa-smmu-uc-cb" - represents IPA uC context bank (for uC
					offload scenarios).

- qcom,smmu-s1-bypass: Boolean context flag to set SMMU to S1 bypass.

- iommus : the phandle and stream IDs for the SMMU used by this root

- qcom,iova-mapping: specifies the start address and size of iova space.
+40 −34
Original line number Diff line number Diff line
@@ -255,7 +255,7 @@ static struct {
	bool present;
	bool arm_smmu;
	bool fast_map;
	bool s1_bypass;
	bool s1_bypass_arr[IPA_SMMU_CB_MAX];
	bool use_64_bit_dma_mask;
	u32 ipa_base;
	u32 ipa_size;
@@ -436,14 +436,6 @@ static void ipa3_active_clients_log_destroy(void)
		flags);
}

enum ipa_smmu_cb_type {
	IPA_SMMU_CB_AP,
	IPA_SMMU_CB_WLAN,
	IPA_SMMU_CB_UC,
	IPA_SMMU_CB_MAX

};

static struct ipa_smmu_cb_ctx smmu_cb[IPA_SMMU_CB_MAX];

struct iommu_domain *ipa3_get_smmu_domain(void)
@@ -4430,8 +4422,6 @@ static int ipa3_pil_load_ipa_fws(void)
	if (IS_ERR_OR_NULL(subsystem_get_retval)) {
		IPAERR("Unable to trigger PIL process for FW loading\n");
		return -EINVAL;
	} else {
		subsystem_put(subsystem_get_retval);
	}

	IPADBG("PIL FW loading process is complete\n");
@@ -4643,10 +4633,14 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p,
	ipa3_ctx->pdev = ipa_dev;
	ipa3_ctx->uc_pdev = ipa_dev;
	ipa3_ctx->smmu_present = smmu_info.present;
	if (!ipa3_ctx->smmu_present)
		ipa3_ctx->smmu_s1_bypass = true;
	else
		ipa3_ctx->smmu_s1_bypass = smmu_info.s1_bypass;
	if (!ipa3_ctx->smmu_present) {
		for (i = 0; i < IPA_SMMU_CB_MAX; i++)
			ipa3_ctx->s1_bypass_arr[i] = true;
	} else {
		for (i = 0; i < IPA_SMMU_CB_MAX; i++)
			ipa3_ctx->s1_bypass_arr[i] = smmu_info.s1_bypass_arr[i];
	}

	ipa3_ctx->ipa_wrapper_base = resource_p->ipa_mem_base;
	ipa3_ctx->ipa_wrapper_size = resource_p->ipa_mem_size;
	ipa3_ctx->ipa_hw_type = resource_p->ipa_hw_type;
@@ -5489,7 +5483,8 @@ static int ipa_smmu_wlan_cb_probe(struct device *dev)
	}
	cb->valid = true;

	if (smmu_info.s1_bypass) {
	if (of_property_read_bool(dev->of_node, "qcom,smmu-s1-bypass")) {
		smmu_info.s1_bypass_arr[IPA_SMMU_CB_WLAN] = true;
		if (iommu_domain_set_attr(cb->iommu,
					DOMAIN_ATTR_S1_BYPASS,
					&bypass)) {
@@ -5497,8 +5492,9 @@ static int ipa_smmu_wlan_cb_probe(struct device *dev)
			cb->valid = false;
			return -EIO;
		}
		IPADBG("SMMU S1 BYPASS\n");
		IPADBG("WLAN SMMU S1 BYPASS\n");
	} else {
		smmu_info.s1_bypass_arr[IPA_SMMU_CB_WLAN] = false;
		if (iommu_domain_set_attr(cb->iommu,
					DOMAIN_ATTR_ATOMIC,
					&atomic_ctx)) {
@@ -5506,7 +5502,7 @@ static int ipa_smmu_wlan_cb_probe(struct device *dev)
			cb->valid = false;
			return -EIO;
		}
		IPADBG("SMMU ATTR ATOMIC\n");
		IPADBG(" WLAN SMMU ATTR ATOMIC\n");

		if (smmu_info.fast_map) {
			if (iommu_domain_set_attr(cb->iommu,
@@ -5520,6 +5516,9 @@ static int ipa_smmu_wlan_cb_probe(struct device *dev)
		}
	}

	pr_info("IPA smmu_info.s1_bypass_arr[WLAN]=%d smmu_info.fast_map=%d\n",
		smmu_info.s1_bypass_arr[IPA_SMMU_CB_WLAN], smmu_info.fast_map);

	ret = iommu_attach_device(cb->iommu, dev);
	if (ret) {
		IPAERR("could not attach device ret=%d\n", ret);
@@ -5607,7 +5606,9 @@ static int ipa_smmu_uc_cb_probe(struct device *dev)
	cb->valid = true;

	IPADBG("UC CB PROBE sub pdev=%p set attribute\n", dev);
	if (smmu_info.s1_bypass) {

	if (of_property_read_bool(dev->of_node, "qcom,smmu-s1-bypass")) {
		smmu_info.s1_bypass_arr[IPA_SMMU_CB_UC] = true;
		if (iommu_domain_set_attr(cb->mapping->domain,
			DOMAIN_ATTR_S1_BYPASS,
			&bypass)) {
@@ -5616,8 +5617,9 @@ static int ipa_smmu_uc_cb_probe(struct device *dev)
			cb->valid = false;
			return -EIO;
		}
		IPADBG("SMMU S1 BYPASS\n");
		IPADBG("UC SMMU S1 BYPASS\n");
	} else {
		smmu_info.s1_bypass_arr[IPA_SMMU_CB_UC] = false;
		if (iommu_domain_set_attr(cb->mapping->domain,
			DOMAIN_ATTR_ATOMIC,
			&atomic_ctx)) {
@@ -5641,6 +5643,9 @@ static int ipa_smmu_uc_cb_probe(struct device *dev)
		}
	}

	pr_info("IPA smmu_info.s1_bypass_arr[UC]=%d smmu_info.fast_map=%d\n",
		smmu_info.s1_bypass_arr[IPA_SMMU_CB_UC], smmu_info.fast_map);

	IPADBG("UC CB PROBE sub pdev=%p attaching IOMMU device\n", dev);
	ret = arm_iommu_attach_device(cb->dev, cb->mapping);
	if (ret) {
@@ -5707,7 +5712,9 @@ static int ipa_smmu_ap_cb_probe(struct device *dev)
	IPADBG("SMMU mapping created\n");
	cb->valid = true;

	if (smmu_info.s1_bypass) {
	if (of_property_read_bool(dev->of_node,
		"qcom,smmu-s1-bypass")) {
		smmu_info.s1_bypass_arr[IPA_SMMU_CB_AP] = true;
		if (iommu_domain_set_attr(cb->mapping->domain,
				DOMAIN_ATTR_S1_BYPASS,
				&bypass)) {
@@ -5716,8 +5723,9 @@ static int ipa_smmu_ap_cb_probe(struct device *dev)
			cb->valid = false;
			return -EIO;
		}
		IPADBG("SMMU S1 BYPASS\n");
		IPADBG("AP/USB SMMU S1 BYPASS\n");
	} else {
		smmu_info.s1_bypass_arr[IPA_SMMU_CB_AP] = false;
		if (iommu_domain_set_attr(cb->mapping->domain,
				DOMAIN_ATTR_ATOMIC,
				&atomic_ctx)) {
@@ -5726,7 +5734,7 @@ static int ipa_smmu_ap_cb_probe(struct device *dev)
			cb->valid = false;
			return -EIO;
		}
		IPADBG("SMMU atomic set\n");
		IPADBG("AP/USB SMMU atomic set\n");

		if (iommu_domain_set_attr(cb->mapping->domain,
				DOMAIN_ATTR_FAST,
@@ -5739,6 +5747,9 @@ static int ipa_smmu_ap_cb_probe(struct device *dev)
		IPADBG("SMMU fast map set\n");
	}

	pr_info("IPA smmu_info.s1_bypass_arr[AP]=%d smmu_info.fast_map=%d\n",
		smmu_info.s1_bypass_arr[IPA_SMMU_CB_AP], smmu_info.fast_map);

	result = arm_iommu_attach_device(cb->dev, cb->mapping);
	if (result) {
		IPAERR("couldn't attach to IOMMU ret=%d\n", result);
@@ -5921,9 +5932,6 @@ int ipa3_plat_drv_probe(struct platform_device *pdev_p,
	}

	if (of_property_read_bool(pdev_p->dev.of_node, "qcom,arm-smmu")) {
		if (of_property_read_bool(pdev_p->dev.of_node,
		    "qcom,smmu-s1-bypass"))
			smmu_info.s1_bypass = true;
		if (of_property_read_bool(pdev_p->dev.of_node,
			"qcom,smmu-fast-map"))
			smmu_info.fast_map = true;
@@ -5931,8 +5939,6 @@ int ipa3_plat_drv_probe(struct platform_device *pdev_p,
			"qcom,use-64-bit-dma-mask"))
			smmu_info.use_64_bit_dma_mask = true;
		smmu_info.arm_smmu = true;
		pr_info("IPA smmu_info.s1_bypass=%d smmu_info.fast_map=%d\n",
			smmu_info.s1_bypass, smmu_info.fast_map);
	} else if (of_property_read_bool(pdev_p->dev.of_node,
				"qcom,msm-smmu")) {
		IPAERR("Legacy IOMMU not supported\n");
+2 −2
Original line number Diff line number Diff line
@@ -488,7 +488,7 @@ int ipa3_smmu_map_peer_reg(phys_addr_t phys_addr, bool map)
	struct iommu_domain *smmu_domain;
	int res;

	if (ipa3_ctx->smmu_s1_bypass)
	if (ipa3_ctx->s1_bypass_arr[IPA_SMMU_CB_AP])
		return 0;

	smmu_domain = ipa3_get_smmu_domain();
@@ -520,7 +520,7 @@ int ipa3_smmu_map_peer_buff(u64 iova, phys_addr_t phys_addr, u32 size, bool map)
	struct iommu_domain *smmu_domain;
	int res;

	if (ipa3_ctx->smmu_s1_bypass)
	if (ipa3_ctx->s1_bypass_arr[IPA_SMMU_CB_AP])
		return 0;

	smmu_domain = ipa3_get_smmu_domain();
+2 −2
Original line number Diff line number Diff line
@@ -136,8 +136,8 @@ static void ipa3_wq_write_done_common(struct ipa3_sys_context *sys,
					DMA_TO_DEVICE);
			} else {
				dma_unmap_page(ipa3_ctx->pdev,
					next_pkt->mem.phys_base,
					next_pkt->mem.size,
					tx_pkt->mem.phys_base,
					tx_pkt->mem.size,
					DMA_TO_DEVICE);
			}
		}
+8 −1
Original line number Diff line number Diff line
@@ -1098,6 +1098,13 @@ struct ipa_cne_evt {
	struct ipa_msg_meta msg_meta;
};

enum ipa_smmu_cb_type {
	IPA_SMMU_CB_AP,
	IPA_SMMU_CB_WLAN,
	IPA_SMMU_CB_UC,
	IPA_SMMU_CB_MAX
};

/**
 * struct ipa3_context - IPA context
 * @class: pointer to the struct class
@@ -1296,7 +1303,7 @@ struct ipa3_context {
	bool apply_rg10_wa;
	bool gsi_ch20_wa;
	bool smmu_present;
	bool smmu_s1_bypass;
	bool s1_bypass_arr[IPA_SMMU_CB_MAX];
	u32 wdi_map_cnt;
	struct wakeup_source w_lock;
	struct ipa3_wakelock_ref_cnt wakelock_ref_cnt;
Loading