diff mbox series

[3/3] iommu/arm-smmu-qcom: Add support for the interconnect

Message ID 20230609055225.20717-1-quic_ppareek@quicinc.com (mailing list archive)
State Not Applicable
Headers show
Series arm64: dts: qcom: sa8775p: Add interconnect to SMMU | expand

Commit Message

Parikshit Pareek June 9, 2023, 5:52 a.m. UTC
Introduce support to detect the interconnect, and set its bandwidth.
For certain targets, we need to set the bandwidth of interconnect,
connecting smmu to memory. This is accessed during memory mapped IO
access to smmu registers, and during page tables walks.

Reported-by: Eric Chanudet <echanude@redhat.com>
Signed-off-by: Parikshit Pareek <quic_ppareek@quicinc.com>
---
 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

Comments

Konrad Dybcio June 9, 2023, 8:56 a.m. UTC | #1
On 9.06.2023 07:52, Parikshit Pareek wrote:
> Introduce support to detect the interconnect, and set its bandwidth.
> For certain targets, we need to set the bandwidth of interconnect,
> connecting smmu to memory. This is accessed during memory mapped IO
> access to smmu registers, and during page tables walks.
> 
> Reported-by: Eric Chanudet <echanude@redhat.com>
> Signed-off-by: Parikshit Pareek <quic_ppareek@quicinc.com>
> ---
Quite recently, I've been toying with this too.. I coded it in
a way that allows it to be reused by other impls and uses OPP APIs.
Please take a look at the attached patch.

Konrad
>  drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
> 
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> index c71afda79d64..6961d564869b 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> @@ -8,6 +8,7 @@
>  #include <linux/delay.h>
>  #include <linux/of_device.h>
>  #include <linux/firmware/qcom/qcom_scm.h>
> +#include <linux/interconnect.h>
>  
>  #include "arm-smmu.h"
>  #include "arm-smmu-qcom.h"
> @@ -549,6 +550,8 @@ struct arm_smmu_device *qcom_smmu_impl_init(struct arm_smmu_device *smmu)
>  {
>  	const struct device_node *np = smmu->dev->of_node;
>  	const struct of_device_id *match;
> +	struct icc_path *icc_path;
> +	int ret, icc_bw;
>  
>  #ifdef CONFIG_ACPI
>  	if (np == NULL) {
> @@ -558,6 +561,19 @@ struct arm_smmu_device *qcom_smmu_impl_init(struct arm_smmu_device *smmu)
>  	}
>  #endif
>  
> +	icc_path = devm_of_icc_get(smmu->dev, "tbu_mc");
> +	if (IS_ERR(icc_path))
> +		return (struct arm_smmu_device *)icc_path;
> +
> +	ret = of_property_read_u32(np, "icc_bw", &icc_bw);
> +
> +	/*if interconnect exists, check for the  bandwidth value*/
> +	if (icc_path && !ret) {
> +		ret = icc_set_bw(icc_path, 0, MBps_to_icc(icc_bw));
> +		if (ret)
> +			return ERR_PTR(ret);
> +	}
> +
>  	match = of_match_node(qcom_smmu_impl_of_match, np);
>  	if (match)
>  		return qcom_smmu_create(smmu, match->data);
diff mbox series

Patch

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
index c71afda79d64..6961d564869b 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
@@ -8,6 +8,7 @@ 
 #include <linux/delay.h>
 #include <linux/of_device.h>
 #include <linux/firmware/qcom/qcom_scm.h>
+#include <linux/interconnect.h>
 
 #include "arm-smmu.h"
 #include "arm-smmu-qcom.h"
@@ -549,6 +550,8 @@  struct arm_smmu_device *qcom_smmu_impl_init(struct arm_smmu_device *smmu)
 {
 	const struct device_node *np = smmu->dev->of_node;
 	const struct of_device_id *match;
+	struct icc_path *icc_path;
+	int ret, icc_bw;
 
 #ifdef CONFIG_ACPI
 	if (np == NULL) {
@@ -558,6 +561,19 @@  struct arm_smmu_device *qcom_smmu_impl_init(struct arm_smmu_device *smmu)
 	}
 #endif
 
+	icc_path = devm_of_icc_get(smmu->dev, "tbu_mc");
+	if (IS_ERR(icc_path))
+		return (struct arm_smmu_device *)icc_path;
+
+	ret = of_property_read_u32(np, "icc_bw", &icc_bw);
+
+	/*if interconnect exists, check for the  bandwidth value*/
+	if (icc_path && !ret) {
+		ret = icc_set_bw(icc_path, 0, MBps_to_icc(icc_bw));
+		if (ret)
+			return ERR_PTR(ret);
+	}
+
 	match = of_match_node(qcom_smmu_impl_of_match, np);
 	if (match)
 		return qcom_smmu_create(smmu, match->data);