linux-arm-msm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v5 0/3] iommu/arm-smmu-qcom: Support maintaining bootloader mappings
@ 2020-10-19 18:23 Bjorn Andersson
  2020-10-19 18:23 ` [PATCH v5 1/3] iommu/arm-smmu: Allow implementation specific write_s2cr Bjorn Andersson
                   ` (5 more replies)
  0 siblings, 6 replies; 9+ messages in thread
From: Bjorn Andersson @ 2020-10-19 18:23 UTC (permalink / raw)
  To: Will Deacon, Robin Murphy, Joerg Roedel, Sai Prakash Ranjan,
	Jordan Crouse, Thierry Reding, Rob Clark
  Cc: linux-arm-kernel, iommu, linux-kernel, linux-arm-msm

This is the revised fourth attempt of inheriting the stream mapping for
the framebuffer on many Qualcomm platforms, in order to not hit
catastrophic faults during arm-smmu initialization.

The new approach does, based on Robin's suggestion, take a much more
direct approach with the allocation of a context bank for bypass
emulation and use of this context bank pretty much isolated to the
Qualcomm specific implementation.

The patchset has been tested to boot DB845c and RB5 (with splash screen)
and Lenovo Yoga C630 (with EFI framebuffer).

Bjorn Andersson (3):
  iommu/arm-smmu: Allow implementation specific write_s2cr
  iommu/arm-smmu-qcom: Read back stream mappings
  iommu/arm-smmu-qcom: Implement S2CR quirk

 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 90 ++++++++++++++++++++++
 drivers/iommu/arm/arm-smmu/arm-smmu.c      | 13 +++-
 drivers/iommu/arm/arm-smmu/arm-smmu.h      |  1 +
 3 files changed, 101 insertions(+), 3 deletions(-)

-- 
2.28.0


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v5 1/3] iommu/arm-smmu: Allow implementation specific write_s2cr
  2020-10-19 18:23 [PATCH v5 0/3] iommu/arm-smmu-qcom: Support maintaining bootloader mappings Bjorn Andersson
@ 2020-10-19 18:23 ` Bjorn Andersson
  2020-10-19 18:23 ` [PATCH v5 2/3] iommu/arm-smmu-qcom: Read back stream mappings Bjorn Andersson
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Bjorn Andersson @ 2020-10-19 18:23 UTC (permalink / raw)
  To: Will Deacon, Robin Murphy, Joerg Roedel, Sai Prakash Ranjan,
	Jordan Crouse, Thierry Reding, Rob Clark
  Cc: linux-arm-kernel, iommu, linux-kernel, linux-arm-msm

The firmware found in some Qualcomm platforms intercepts writes to the
S2CR register in order to replace the BYPASS type with FAULT. Further
more it treats faults at this level as catastrophic and restarts the
device.

Add support for providing implementation specific versions of the S2CR
write function, to allow the Qualcomm driver to work around this
behavior.

Reviewed-by: Robin Murphy <robin.murphy@arm.com>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
---

Changes since v4:
- Return early instead of indenting the rest of the function

 drivers/iommu/arm/arm-smmu/arm-smmu.c | 13 ++++++++++---
 drivers/iommu/arm/arm-smmu/arm-smmu.h |  1 +
 2 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index dad7fa86fbd4..bcbacf22331d 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -929,9 +929,16 @@ static void arm_smmu_write_smr(struct arm_smmu_device *smmu, int idx)
 static void arm_smmu_write_s2cr(struct arm_smmu_device *smmu, int idx)
 {
 	struct arm_smmu_s2cr *s2cr = smmu->s2crs + idx;
-	u32 reg = FIELD_PREP(ARM_SMMU_S2CR_TYPE, s2cr->type) |
-		  FIELD_PREP(ARM_SMMU_S2CR_CBNDX, s2cr->cbndx) |
-		  FIELD_PREP(ARM_SMMU_S2CR_PRIVCFG, s2cr->privcfg);
+	u32 reg;
+
+	if (smmu->impl && smmu->impl->write_s2cr) {
+		smmu->impl->write_s2cr(smmu, idx);
+		return;
+	}
+
+	reg = FIELD_PREP(ARM_SMMU_S2CR_TYPE, s2cr->type) |
+	      FIELD_PREP(ARM_SMMU_S2CR_CBNDX, s2cr->cbndx) |
+	      FIELD_PREP(ARM_SMMU_S2CR_PRIVCFG, s2cr->privcfg);
 
 	if (smmu->features & ARM_SMMU_FEAT_EXIDS && smmu->smrs &&
 	    smmu->smrs[idx].valid)
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h b/drivers/iommu/arm/arm-smmu/arm-smmu.h
index 1a746476927c..b71647eaa319 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.h
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h
@@ -436,6 +436,7 @@ struct arm_smmu_impl {
 	int (*alloc_context_bank)(struct arm_smmu_domain *smmu_domain,
 				  struct arm_smmu_device *smmu,
 				  struct device *dev, int start);
+	void (*write_s2cr)(struct arm_smmu_device *smmu, int idx);
 };
 
 #define INVALID_SMENDX			-1
-- 
2.28.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v5 2/3] iommu/arm-smmu-qcom: Read back stream mappings
  2020-10-19 18:23 [PATCH v5 0/3] iommu/arm-smmu-qcom: Support maintaining bootloader mappings Bjorn Andersson
  2020-10-19 18:23 ` [PATCH v5 1/3] iommu/arm-smmu: Allow implementation specific write_s2cr Bjorn Andersson
@ 2020-10-19 18:23 ` Bjorn Andersson
  2020-10-19 18:50   ` Robin Murphy
  2020-10-19 18:23 ` [PATCH v5 3/3] iommu/arm-smmu-qcom: Implement S2CR quirk Bjorn Andersson
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 9+ messages in thread
From: Bjorn Andersson @ 2020-10-19 18:23 UTC (permalink / raw)
  To: Will Deacon, Robin Murphy, Joerg Roedel, Sai Prakash Ranjan,
	Jordan Crouse, Thierry Reding, Rob Clark
  Cc: linux-arm-kernel, iommu, linux-kernel, linux-arm-msm

The Qualcomm boot loader configures stream mapping for the peripherals
that it accesses and in particular it sets up the stream mapping for the
display controller to be allowed to scan out a splash screen or EFI
framebuffer.

Read back the stream mappings during initialization and make the
arm-smmu driver maintain the streams in bypass mode.

Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
---

Changes since v4:
- Don't increment s2cr[i]->count, as this is not actually needed to survive
  probe deferral

 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 23 ++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
index be4318044f96..48627fcf6bed 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
@@ -23,6 +23,28 @@ static const struct of_device_id qcom_smmu_client_of_match[] __maybe_unused = {
 	{ }
 };
 
+static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu)
+{
+	u32 smr;
+	int i;
+
+	for (i = 0; i < smmu->num_mapping_groups; i++) {
+		smr = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_SMR(i));
+
+		if (FIELD_GET(ARM_SMMU_SMR_VALID, smr)) {
+			smmu->smrs[i].id = FIELD_GET(ARM_SMMU_SMR_ID, smr);
+			smmu->smrs[i].mask = FIELD_GET(ARM_SMMU_SMR_MASK, smr);
+			smmu->smrs[i].valid = true;
+
+			smmu->s2crs[i].type = S2CR_TYPE_BYPASS;
+			smmu->s2crs[i].privcfg = S2CR_PRIVCFG_DEFAULT;
+			smmu->s2crs[i].cbndx = 0xff;
+		}
+	}
+
+	return 0;
+}
+
 static int qcom_smmu_def_domain_type(struct device *dev)
 {
 	const struct of_device_id *match =
@@ -61,6 +83,7 @@ static int qcom_smmu500_reset(struct arm_smmu_device *smmu)
 }
 
 static const struct arm_smmu_impl qcom_smmu_impl = {
+	.cfg_probe = qcom_smmu_cfg_probe,
 	.def_domain_type = qcom_smmu_def_domain_type,
 	.reset = qcom_smmu500_reset,
 };
-- 
2.28.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v5 3/3] iommu/arm-smmu-qcom: Implement S2CR quirk
  2020-10-19 18:23 [PATCH v5 0/3] iommu/arm-smmu-qcom: Support maintaining bootloader mappings Bjorn Andersson
  2020-10-19 18:23 ` [PATCH v5 1/3] iommu/arm-smmu: Allow implementation specific write_s2cr Bjorn Andersson
  2020-10-19 18:23 ` [PATCH v5 2/3] iommu/arm-smmu-qcom: Read back stream mappings Bjorn Andersson
@ 2020-10-19 18:23 ` Bjorn Andersson
  2020-10-19 19:02   ` Robin Murphy
  2020-10-22 17:14 ` [PATCH v5 0/3] iommu/arm-smmu-qcom: Support maintaining bootloader mappings Steev Klimaszewski
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 9+ messages in thread
From: Bjorn Andersson @ 2020-10-19 18:23 UTC (permalink / raw)
  To: Will Deacon, Robin Murphy, Joerg Roedel, Sai Prakash Ranjan,
	Jordan Crouse, Thierry Reding, Rob Clark
  Cc: linux-arm-kernel, iommu, linux-kernel, linux-arm-msm

The firmware found in some Qualcomm platforms intercepts writes to S2CR
in order to replace bypass type streams with fault; and ignore S2CR
updates of type fault.

Detect this behavior and implement a custom write_s2cr function in order
to trick the firmware into supporting bypass streams by the means of
configuring the stream for translation using a reserved and disabled
context bank.

Also circumvent the problem of configuring faulting streams by
configuring the stream as bypass.

Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
---

Changes since v4:
- Made the bypass_cbndx an integer...
- Separated out the "quirk enabled or not" into a bool, rather than reusing
  (the valid) context bank 0 to represent this.
- Dropped the unused EXIDS handling.

 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 67 ++++++++++++++++++++++
 1 file changed, 67 insertions(+)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
index 48627fcf6bed..66ba4870659f 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
@@ -10,8 +10,15 @@
 
 struct qcom_smmu {
 	struct arm_smmu_device smmu;
+	bool bypass_quirk;
+	u8 bypass_cbndx;
 };
 
+static struct qcom_smmu *to_qcom_smmu(struct arm_smmu_device *smmu)
+{
+	return container_of(smmu, struct qcom_smmu, smmu);
+}
+
 static const struct of_device_id qcom_smmu_client_of_match[] __maybe_unused = {
 	{ .compatible = "qcom,adreno" },
 	{ .compatible = "qcom,mdp4" },
@@ -25,9 +32,33 @@ static const struct of_device_id qcom_smmu_client_of_match[] __maybe_unused = {
 
 static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu)
 {
+	unsigned int last_s2cr = ARM_SMMU_GR0_S2CR(smmu->num_mapping_groups - 1);
+	struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);
+	u32 reg;
 	u32 smr;
 	int i;
 
+	/*
+	 * With some firmware versions writes to S2CR of type FAULT are
+	 * ignored, and writing BYPASS will end up written as FAULT in the
+	 * register. Perform a write to S2CR to detect if this is the case and
+	 * if so reserve a context bank to emulate bypass streams.
+	 */
+	reg = FIELD_PREP(ARM_SMMU_S2CR_TYPE, S2CR_TYPE_BYPASS) |
+	      FIELD_PREP(ARM_SMMU_S2CR_CBNDX, 0xff) |
+	      FIELD_PREP(ARM_SMMU_S2CR_PRIVCFG, S2CR_PRIVCFG_DEFAULT);
+	arm_smmu_gr0_write(smmu, last_s2cr, reg);
+	reg = arm_smmu_gr0_read(smmu, last_s2cr);
+	if (FIELD_GET(ARM_SMMU_S2CR_TYPE, reg) != S2CR_TYPE_BYPASS) {
+		qsmmu->bypass_quirk = true;
+		qsmmu->bypass_cbndx = smmu->num_context_banks - 1;
+
+		set_bit(qsmmu->bypass_cbndx, smmu->context_map);
+
+		reg = FIELD_PREP(ARM_SMMU_CBAR_TYPE, CBAR_TYPE_S1_TRANS_S2_BYPASS);
+		arm_smmu_gr1_write(smmu, ARM_SMMU_GR1_CBAR(qsmmu->bypass_cbndx), reg);
+	}
+
 	for (i = 0; i < smmu->num_mapping_groups; i++) {
 		smr = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_SMR(i));
 
@@ -45,6 +76,41 @@ static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu)
 	return 0;
 }
 
+static void qcom_smmu_write_s2cr(struct arm_smmu_device *smmu, int idx)
+{
+	struct arm_smmu_s2cr *s2cr = smmu->s2crs + idx;
+	struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);
+	u32 cbndx = s2cr->cbndx;
+	u32 type = s2cr->type;
+	u32 reg;
+
+	if (qsmmu->bypass_quirk) {
+		if (type == S2CR_TYPE_BYPASS) {
+			/*
+			 * Firmware with quirky S2CR handling will substitute
+			 * BYPASS writes with FAULT, so point the stream to the
+			 * reserved context bank and ask for translation on the
+			 * stream
+			 */
+			type = S2CR_TYPE_TRANS;
+			cbndx = qsmmu->bypass_cbndx;
+		} else if (type == S2CR_TYPE_FAULT) {
+			/*
+			 * Firmware with quirky S2CR handling will ignore FAULT
+			 * writes, so trick it to write FAULT by asking for a
+			 * BYPASS.
+			 */
+			type = S2CR_TYPE_BYPASS;
+			cbndx = 0xff;
+		}
+	}
+
+	reg = FIELD_PREP(ARM_SMMU_S2CR_TYPE, type) |
+	      FIELD_PREP(ARM_SMMU_S2CR_CBNDX, cbndx) |
+	      FIELD_PREP(ARM_SMMU_S2CR_PRIVCFG, s2cr->privcfg);
+	arm_smmu_gr0_write(smmu, ARM_SMMU_GR0_S2CR(idx), reg);
+}
+
 static int qcom_smmu_def_domain_type(struct device *dev)
 {
 	const struct of_device_id *match =
@@ -86,6 +152,7 @@ static const struct arm_smmu_impl qcom_smmu_impl = {
 	.cfg_probe = qcom_smmu_cfg_probe,
 	.def_domain_type = qcom_smmu_def_domain_type,
 	.reset = qcom_smmu500_reset,
+	.write_s2cr = qcom_smmu_write_s2cr,
 };
 
 struct arm_smmu_device *qcom_smmu_impl_init(struct arm_smmu_device *smmu)
-- 
2.28.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v5 2/3] iommu/arm-smmu-qcom: Read back stream mappings
  2020-10-19 18:23 ` [PATCH v5 2/3] iommu/arm-smmu-qcom: Read back stream mappings Bjorn Andersson
@ 2020-10-19 18:50   ` Robin Murphy
  0 siblings, 0 replies; 9+ messages in thread
From: Robin Murphy @ 2020-10-19 18:50 UTC (permalink / raw)
  To: Bjorn Andersson, Will Deacon, Joerg Roedel, Sai Prakash Ranjan,
	Jordan Crouse, Thierry Reding, Rob Clark
  Cc: linux-arm-kernel, iommu, linux-kernel, linux-arm-msm

On 2020-10-19 19:23, Bjorn Andersson wrote:
> The Qualcomm boot loader configures stream mapping for the peripherals
> that it accesses and in particular it sets up the stream mapping for the
> display controller to be allowed to scan out a splash screen or EFI
> framebuffer.
> 
> Read back the stream mappings during initialization and make the
> arm-smmu driver maintain the streams in bypass mode.

Acked-by: Robin Murphy <robin.murphy@arm.com>

> Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
> ---
> 
> Changes since v4:
> - Don't increment s2cr[i]->count, as this is not actually needed to survive
>    probe deferral
> 
>   drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 23 ++++++++++++++++++++++
>   1 file changed, 23 insertions(+)
> 
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> index be4318044f96..48627fcf6bed 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> @@ -23,6 +23,28 @@ static const struct of_device_id qcom_smmu_client_of_match[] __maybe_unused = {
>   	{ }
>   };
>   
> +static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu)
> +{
> +	u32 smr;
> +	int i;
> +
> +	for (i = 0; i < smmu->num_mapping_groups; i++) {
> +		smr = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_SMR(i));
> +
> +		if (FIELD_GET(ARM_SMMU_SMR_VALID, smr)) {
> +			smmu->smrs[i].id = FIELD_GET(ARM_SMMU_SMR_ID, smr);
> +			smmu->smrs[i].mask = FIELD_GET(ARM_SMMU_SMR_MASK, smr);
> +			smmu->smrs[i].valid = true;
> +
> +			smmu->s2crs[i].type = S2CR_TYPE_BYPASS;
> +			smmu->s2crs[i].privcfg = S2CR_PRIVCFG_DEFAULT;
> +			smmu->s2crs[i].cbndx = 0xff;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
>   static int qcom_smmu_def_domain_type(struct device *dev)
>   {
>   	const struct of_device_id *match =
> @@ -61,6 +83,7 @@ static int qcom_smmu500_reset(struct arm_smmu_device *smmu)
>   }
>   
>   static const struct arm_smmu_impl qcom_smmu_impl = {
> +	.cfg_probe = qcom_smmu_cfg_probe,
>   	.def_domain_type = qcom_smmu_def_domain_type,
>   	.reset = qcom_smmu500_reset,
>   };
> 

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v5 3/3] iommu/arm-smmu-qcom: Implement S2CR quirk
  2020-10-19 18:23 ` [PATCH v5 3/3] iommu/arm-smmu-qcom: Implement S2CR quirk Bjorn Andersson
@ 2020-10-19 19:02   ` Robin Murphy
  0 siblings, 0 replies; 9+ messages in thread
From: Robin Murphy @ 2020-10-19 19:02 UTC (permalink / raw)
  To: Bjorn Andersson, Will Deacon, Joerg Roedel, Sai Prakash Ranjan,
	Jordan Crouse, Thierry Reding, Rob Clark
  Cc: linux-arm-kernel, iommu, linux-kernel, linux-arm-msm

On 2020-10-19 19:23, Bjorn Andersson wrote:
> The firmware found in some Qualcomm platforms intercepts writes to S2CR
> in order to replace bypass type streams with fault; and ignore S2CR
> updates of type fault.
> 
> Detect this behavior and implement a custom write_s2cr function in order
> to trick the firmware into supporting bypass streams by the means of
> configuring the stream for translation using a reserved and disabled
> context bank.
> 
> Also circumvent the problem of configuring faulting streams by
> configuring the stream as bypass.
> 
> Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
> ---
> 
> Changes since v4:
> - Made the bypass_cbndx an integer...
> - Separated out the "quirk enabled or not" into a bool, rather than reusing
>    (the valid) context bank 0 to represent this.
> - Dropped the unused EXIDS handling.
> 
>   drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 67 ++++++++++++++++++++++
>   1 file changed, 67 insertions(+)
> 
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> index 48627fcf6bed..66ba4870659f 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> @@ -10,8 +10,15 @@
>   
>   struct qcom_smmu {
>   	struct arm_smmu_device smmu;
> +	bool bypass_quirk;
> +	u8 bypass_cbndx;
>   };
>   
> +static struct qcom_smmu *to_qcom_smmu(struct arm_smmu_device *smmu)
> +{
> +	return container_of(smmu, struct qcom_smmu, smmu);
> +}
> +
>   static const struct of_device_id qcom_smmu_client_of_match[] __maybe_unused = {
>   	{ .compatible = "qcom,adreno" },
>   	{ .compatible = "qcom,mdp4" },
> @@ -25,9 +32,33 @@ static const struct of_device_id qcom_smmu_client_of_match[] __maybe_unused = {
>   
>   static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu)
>   {
> +	unsigned int last_s2cr = ARM_SMMU_GR0_S2CR(smmu->num_mapping_groups - 1);
> +	struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);
> +	u32 reg;
>   	u32 smr;
>   	int i;
>   
> +	/*
> +	 * With some firmware versions writes to S2CR of type FAULT are
> +	 * ignored, and writing BYPASS will end up written as FAULT in the
> +	 * register. Perform a write to S2CR to detect if this is the case and
> +	 * if so reserve a context bank to emulate bypass streams.
> +	 */
> +	reg = FIELD_PREP(ARM_SMMU_S2CR_TYPE, S2CR_TYPE_BYPASS) |
> +	      FIELD_PREP(ARM_SMMU_S2CR_CBNDX, 0xff) |
> +	      FIELD_PREP(ARM_SMMU_S2CR_PRIVCFG, S2CR_PRIVCFG_DEFAULT);
> +	arm_smmu_gr0_write(smmu, last_s2cr, reg);
> +	reg = arm_smmu_gr0_read(smmu, last_s2cr);
> +	if (FIELD_GET(ARM_SMMU_S2CR_TYPE, reg) != S2CR_TYPE_BYPASS) {
> +		qsmmu->bypass_quirk = true;
> +		qsmmu->bypass_cbndx = smmu->num_context_banks - 1;

FWIW you could arguably just calculate that at point of use. Or store 
the index as an int and use a negative value to indicate when it's 
irrelevant to save the separate flag. But there's also nothing *wrong* 
with having it all spelled out, so regardless,

Acked-by: Robin Murphy <robin.murphy@arm.com>

Cheers,
Robin.

> +
> +		set_bit(qsmmu->bypass_cbndx, smmu->context_map);
> +
> +		reg = FIELD_PREP(ARM_SMMU_CBAR_TYPE, CBAR_TYPE_S1_TRANS_S2_BYPASS);
> +		arm_smmu_gr1_write(smmu, ARM_SMMU_GR1_CBAR(qsmmu->bypass_cbndx), reg);
> +	}
> +
>   	for (i = 0; i < smmu->num_mapping_groups; i++) {
>   		smr = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_SMR(i));
>   
> @@ -45,6 +76,41 @@ static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu)
>   	return 0;
>   }
>   
> +static void qcom_smmu_write_s2cr(struct arm_smmu_device *smmu, int idx)
> +{
> +	struct arm_smmu_s2cr *s2cr = smmu->s2crs + idx;
> +	struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);
> +	u32 cbndx = s2cr->cbndx;
> +	u32 type = s2cr->type;
> +	u32 reg;
> +
> +	if (qsmmu->bypass_quirk) {
> +		if (type == S2CR_TYPE_BYPASS) {
> +			/*
> +			 * Firmware with quirky S2CR handling will substitute
> +			 * BYPASS writes with FAULT, so point the stream to the
> +			 * reserved context bank and ask for translation on the
> +			 * stream
> +			 */
> +			type = S2CR_TYPE_TRANS;
> +			cbndx = qsmmu->bypass_cbndx;
> +		} else if (type == S2CR_TYPE_FAULT) {
> +			/*
> +			 * Firmware with quirky S2CR handling will ignore FAULT
> +			 * writes, so trick it to write FAULT by asking for a
> +			 * BYPASS.
> +			 */
> +			type = S2CR_TYPE_BYPASS;
> +			cbndx = 0xff;
> +		}
> +	}
> +
> +	reg = FIELD_PREP(ARM_SMMU_S2CR_TYPE, type) |
> +	      FIELD_PREP(ARM_SMMU_S2CR_CBNDX, cbndx) |
> +	      FIELD_PREP(ARM_SMMU_S2CR_PRIVCFG, s2cr->privcfg);
> +	arm_smmu_gr0_write(smmu, ARM_SMMU_GR0_S2CR(idx), reg);
> +}
> +
>   static int qcom_smmu_def_domain_type(struct device *dev)
>   {
>   	const struct of_device_id *match =
> @@ -86,6 +152,7 @@ static const struct arm_smmu_impl qcom_smmu_impl = {
>   	.cfg_probe = qcom_smmu_cfg_probe,
>   	.def_domain_type = qcom_smmu_def_domain_type,
>   	.reset = qcom_smmu500_reset,
> +	.write_s2cr = qcom_smmu_write_s2cr,
>   };
>   
>   struct arm_smmu_device *qcom_smmu_impl_init(struct arm_smmu_device *smmu)
> 

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v5 0/3] iommu/arm-smmu-qcom: Support maintaining bootloader mappings
  2020-10-19 18:23 [PATCH v5 0/3] iommu/arm-smmu-qcom: Support maintaining bootloader mappings Bjorn Andersson
                   ` (2 preceding siblings ...)
  2020-10-19 18:23 ` [PATCH v5 3/3] iommu/arm-smmu-qcom: Implement S2CR quirk Bjorn Andersson
@ 2020-10-22 17:14 ` Steev Klimaszewski
  2020-10-29 18:34 ` Will Deacon
  2020-12-29 20:15 ` patchwork-bot+linux-arm-msm
  5 siblings, 0 replies; 9+ messages in thread
From: Steev Klimaszewski @ 2020-10-22 17:14 UTC (permalink / raw)
  To: Bjorn Andersson, Will Deacon, Robin Murphy, Joerg Roedel,
	Sai Prakash Ranjan, Jordan Crouse, Thierry Reding, Rob Clark
  Cc: linux-arm-kernel, iommu, linux-kernel, linux-arm-msm


On 10/19/20 1:23 PM, Bjorn Andersson wrote:
> This is the revised fourth attempt of inheriting the stream mapping for
> the framebuffer on many Qualcomm platforms, in order to not hit
> catastrophic faults during arm-smmu initialization.
>
> The new approach does, based on Robin's suggestion, take a much more
> direct approach with the allocation of a context bank for bypass
> emulation and use of this context bank pretty much isolated to the
> Qualcomm specific implementation.
>
> The patchset has been tested to boot DB845c and RB5 (with splash screen)
> and Lenovo Yoga C630 (with EFI framebuffer).
>
> Bjorn Andersson (3):
>   iommu/arm-smmu: Allow implementation specific write_s2cr
>   iommu/arm-smmu-qcom: Read back stream mappings
>   iommu/arm-smmu-qcom: Implement S2CR quirk
>
>  drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 90 ++++++++++++++++++++++
>  drivers/iommu/arm/arm-smmu/arm-smmu.c      | 13 +++-
>  drivers/iommu/arm/arm-smmu/arm-smmu.h      |  1 +
>  3 files changed, 101 insertions(+), 3 deletions(-)
>
Tested series here on my Lenovo C630.

Tested-by: Steev Klimaszewski <steev@kali.org>


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v5 0/3] iommu/arm-smmu-qcom: Support maintaining bootloader mappings
  2020-10-19 18:23 [PATCH v5 0/3] iommu/arm-smmu-qcom: Support maintaining bootloader mappings Bjorn Andersson
                   ` (3 preceding siblings ...)
  2020-10-22 17:14 ` [PATCH v5 0/3] iommu/arm-smmu-qcom: Support maintaining bootloader mappings Steev Klimaszewski
@ 2020-10-29 18:34 ` Will Deacon
  2020-12-29 20:15 ` patchwork-bot+linux-arm-msm
  5 siblings, 0 replies; 9+ messages in thread
From: Will Deacon @ 2020-10-29 18:34 UTC (permalink / raw)
  To: Thierry Reding, Bjorn Andersson, Joerg Roedel, Jordan Crouse,
	Robin Murphy, Rob Clark, Sai Prakash Ranjan
  Cc: catalin.marinas, kernel-team, Will Deacon, linux-arm-msm,
	linux-arm-kernel, iommu, linux-kernel

On Mon, 19 Oct 2020 11:23:20 -0700, Bjorn Andersson wrote:
> This is the revised fourth attempt of inheriting the stream mapping for
> the framebuffer on many Qualcomm platforms, in order to not hit
> catastrophic faults during arm-smmu initialization.
> 
> The new approach does, based on Robin's suggestion, take a much more
> direct approach with the allocation of a context bank for bypass
> emulation and use of this context bank pretty much isolated to the
> Qualcomm specific implementation.
> 
> [...]

Applied to will (for-joerg/arm-smmu/updates), thanks!

[1/3] iommu/arm-smmu: Allow implementation specific write_s2cr
      https://git.kernel.org/will/c/56b75b51ed6d
[2/3] iommu/arm-smmu-qcom: Read back stream mappings
      https://git.kernel.org/will/c/07a7f2caaa5a
[3/3] iommu/arm-smmu-qcom: Implement S2CR quirk
      https://git.kernel.org/will/c/f9081b8ff593

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v5 0/3] iommu/arm-smmu-qcom: Support maintaining bootloader mappings
  2020-10-19 18:23 [PATCH v5 0/3] iommu/arm-smmu-qcom: Support maintaining bootloader mappings Bjorn Andersson
                   ` (4 preceding siblings ...)
  2020-10-29 18:34 ` Will Deacon
@ 2020-12-29 20:15 ` patchwork-bot+linux-arm-msm
  5 siblings, 0 replies; 9+ messages in thread
From: patchwork-bot+linux-arm-msm @ 2020-12-29 20:15 UTC (permalink / raw)
  To: Bjorn Andersson; +Cc: linux-arm-msm

Hello:

This series was applied to qcom/linux.git (refs/heads/for-next):

On Mon, 19 Oct 2020 11:23:20 -0700 you wrote:
> This is the revised fourth attempt of inheriting the stream mapping for
> the framebuffer on many Qualcomm platforms, in order to not hit
> catastrophic faults during arm-smmu initialization.
> 
> The new approach does, based on Robin's suggestion, take a much more
> direct approach with the allocation of a context bank for bypass
> emulation and use of this context bank pretty much isolated to the
> Qualcomm specific implementation.
> 
> [...]

Here is the summary with links:
  - [v5,1/3] iommu/arm-smmu: Allow implementation specific write_s2cr
    https://git.kernel.org/qcom/c/56b75b51ed6d
  - [v5,2/3] iommu/arm-smmu-qcom: Read back stream mappings
    https://git.kernel.org/qcom/c/07a7f2caaa5a
  - [v5,3/3] iommu/arm-smmu-qcom: Implement S2CR quirk
    https://git.kernel.org/qcom/c/f9081b8ff593

You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2020-12-29 20:17 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-19 18:23 [PATCH v5 0/3] iommu/arm-smmu-qcom: Support maintaining bootloader mappings Bjorn Andersson
2020-10-19 18:23 ` [PATCH v5 1/3] iommu/arm-smmu: Allow implementation specific write_s2cr Bjorn Andersson
2020-10-19 18:23 ` [PATCH v5 2/3] iommu/arm-smmu-qcom: Read back stream mappings Bjorn Andersson
2020-10-19 18:50   ` Robin Murphy
2020-10-19 18:23 ` [PATCH v5 3/3] iommu/arm-smmu-qcom: Implement S2CR quirk Bjorn Andersson
2020-10-19 19:02   ` Robin Murphy
2020-10-22 17:14 ` [PATCH v5 0/3] iommu/arm-smmu-qcom: Support maintaining bootloader mappings Steev Klimaszewski
2020-10-29 18:34 ` Will Deacon
2020-12-29 20:15 ` patchwork-bot+linux-arm-msm

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).