Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 04/15] iommu/arm-smmu: Rework cb_base handling
From: Robin Murphy @ 2019-08-09 17:07 UTC (permalink / raw)
  To: will
  Cc: robdclark, joro, bjorn.andersson, iommu, vivek.gautam,
	gregory.clement, linux-arm-kernel
In-Reply-To: <cover.1565369764.git.robin.murphy@arm.com>

To keep register-access quirks manageable, we want to structure things
to avoid needing too many individual overrides. It seems fairly clean to
have a single interface which handles both global and context registers
in terms of the architectural pages, so the first preparatory step is to
rework cb_base into a page number rather than an absolute address.

Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---
 drivers/iommu/arm-smmu.c | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index d9a93e5f422f..463bc8d98adb 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -95,7 +95,7 @@
 #endif
 
 /* Translation context bank */
-#define ARM_SMMU_CB(smmu, n)	((smmu)->cb_base + ((n) << (smmu)->pgshift))
+#define ARM_SMMU_CB(smmu, n)	((smmu)->base + (((smmu)->cb_base + (n)) << (smmu)->pgshift))
 
 #define MSI_IOVA_BASE			0x8000000
 #define MSI_IOVA_LENGTH			0x100000
@@ -168,8 +168,8 @@ struct arm_smmu_device {
 	struct device			*dev;
 
 	void __iomem			*base;
-	void __iomem			*cb_base;
-	unsigned long			pgshift;
+	unsigned int			cb_base;
+	unsigned int			pgshift;
 
 #define ARM_SMMU_FEAT_COHERENT_WALK	(1 << 0)
 #define ARM_SMMU_FEAT_STREAM_MATCH	(1 << 1)
@@ -1815,7 +1815,7 @@ static int arm_smmu_id_size_to_bits(int size)
 
 static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
 {
-	unsigned long size;
+	unsigned int size;
 	void __iomem *gr0_base = ARM_SMMU_GR0(smmu);
 	u32 id;
 	bool cttw_reg, cttw_fw = smmu->features & ARM_SMMU_FEAT_COHERENT_WALK;
@@ -1899,7 +1899,7 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
 			return -ENOMEM;
 
 		dev_notice(smmu->dev,
-			   "\tstream matching with %lu register groups", size);
+			   "\tstream matching with %u register groups", size);
 	}
 	/* s2cr->type == 0 means translation, so initialise explicitly */
 	smmu->s2crs = devm_kmalloc_array(smmu->dev, size, sizeof(*smmu->s2crs),
@@ -1925,11 +1925,12 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
 
 	/* Check for size mismatch of SMMU address space from mapped region */
 	size = 1 << (FIELD_GET(ID1_NUMPAGENDXB, id) + 1);
-	size <<= smmu->pgshift;
-	if (smmu->cb_base != gr0_base + size)
+	if (smmu->cb_base != 2 * size << smmu->pgshift)
 		dev_warn(smmu->dev,
-			"SMMU address space size (0x%lx) differs from mapped region size (0x%tx)!\n",
-			size * 2, (smmu->cb_base - gr0_base) * 2);
+			"SMMU address space size (0x%x) differs from mapped region size (0x%x)!\n",
+			2 * size << smmu->pgshift, smmu->cb_base);
+	/* Now cb_base can reach its final form: a page number */
+	smmu->cb_base = size;
 
 	smmu->num_s2_context_banks = FIELD_GET(ID1_NUMS2CB, id);
 	smmu->num_context_banks = FIELD_GET(ID1_NUMCB, id);
@@ -2200,7 +2201,8 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
 	smmu->base = devm_ioremap_resource(dev, res);
 	if (IS_ERR(smmu->base))
 		return PTR_ERR(smmu->base);
-	smmu->cb_base = smmu->base + resource_size(res) / 2;
+	/* We'll finish calculating this later once we know the page size */
+	smmu->cb_base = resource_size(res);
 
 	num_irqs = 0;
 	while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, num_irqs))) {
-- 
2.21.0.dirty


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH 05/15] iommu/arm-smmu: Split arm_smmu_tlb_inv_range_nosync()
From: Robin Murphy @ 2019-08-09 17:07 UTC (permalink / raw)
  To: will
  Cc: robdclark, joro, bjorn.andersson, iommu, vivek.gautam,
	gregory.clement, linux-arm-kernel
In-Reply-To: <cover.1565369764.git.robin.murphy@arm.com>

Since we now use separate iommu_gather_ops for stage 1 and stage 2
contexts, we may as well divide up the monolithic callback into its
respective stage 1 and stage 2 parts.

Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---
 drivers/iommu/arm-smmu.c | 66 ++++++++++++++++++++++------------------
 1 file changed, 37 insertions(+), 29 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 463bc8d98adb..a681e000e704 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -490,46 +490,54 @@ static void arm_smmu_tlb_inv_context_s2(void *cookie)
 	arm_smmu_tlb_sync_global(smmu);
 }
 
-static void arm_smmu_tlb_inv_range_nosync(unsigned long iova, size_t size,
-					  size_t granule, bool leaf, void *cookie)
+static void arm_smmu_tlb_inv_range_s1(unsigned long iova, size_t size,
+				      size_t granule, bool leaf, void *cookie)
 {
 	struct arm_smmu_domain *smmu_domain = cookie;
+	struct arm_smmu_device *smmu = smmu_domain->smmu;
 	struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
-	bool stage1 = cfg->cbar != CBAR_TYPE_S2_TRANS;
-	void __iomem *reg = ARM_SMMU_CB(smmu_domain->smmu, cfg->cbndx);
+	void __iomem *reg = ARM_SMMU_CB(smmu, cfg->cbndx);
 
-	if (smmu_domain->smmu->features & ARM_SMMU_FEAT_COHERENT_WALK)
+	if (smmu->features & ARM_SMMU_FEAT_COHERENT_WALK)
 		wmb();
 
-	if (stage1) {
-		reg += leaf ? ARM_SMMU_CB_S1_TLBIVAL : ARM_SMMU_CB_S1_TLBIVA;
+	reg += leaf ? ARM_SMMU_CB_S1_TLBIVAL : ARM_SMMU_CB_S1_TLBIVA;
 
-		if (cfg->fmt != ARM_SMMU_CTX_FMT_AARCH64) {
-			iova &= ~12UL;
-			iova |= cfg->asid;
-			do {
-				writel_relaxed(iova, reg);
-				iova += granule;
-			} while (size -= granule);
-		} else {
-			iova >>= 12;
-			iova |= (u64)cfg->asid << 48;
-			do {
-				writeq_relaxed(iova, reg);
-				iova += granule >> 12;
-			} while (size -= granule);
-		}
-	} else {
-		reg += leaf ? ARM_SMMU_CB_S2_TLBIIPAS2L :
-			      ARM_SMMU_CB_S2_TLBIIPAS2;
-		iova >>= 12;
+	if (cfg->fmt != ARM_SMMU_CTX_FMT_AARCH64) {
+		iova &= ~12UL;
+		iova |= cfg->asid;
 		do {
-			smmu_write_atomic_lq(iova, reg);
+			writel_relaxed(iova, reg);
+			iova += granule;
+		} while (size -= granule);
+	} else {
+		iova >>= 12;
+		iova |= (u64)cfg->asid << 48;
+		do {
+			writeq_relaxed(iova, reg);
 			iova += granule >> 12;
 		} while (size -= granule);
 	}
 }
 
+static void arm_smmu_tlb_inv_range_s2(unsigned long iova, size_t size,
+				      size_t granule, bool leaf, void *cookie)
+{
+	struct arm_smmu_domain *smmu_domain = cookie;
+	struct arm_smmu_device *smmu = smmu_domain->smmu;
+	void __iomem *reg = ARM_SMMU_CB(smmu, smmu_domain->cfg.cbndx);
+
+	if (smmu->features & ARM_SMMU_FEAT_COHERENT_WALK)
+		wmb();
+
+	reg += leaf ? ARM_SMMU_CB_S2_TLBIIPAS2L : ARM_SMMU_CB_S2_TLBIIPAS2;
+	iova >>= 12;
+	do {
+		smmu_write_atomic_lq(iova, reg);
+		iova += granule >> 12;
+	} while (size -= granule);
+}
+
 /*
  * On MMU-401 at least, the cost of firing off multiple TLBIVMIDs appears
  * almost negligible, but the benefit of getting the first one in as far ahead
@@ -550,13 +558,13 @@ static void arm_smmu_tlb_inv_vmid_nosync(unsigned long iova, size_t size,
 
 static const struct iommu_gather_ops arm_smmu_s1_tlb_ops = {
 	.tlb_flush_all	= arm_smmu_tlb_inv_context_s1,
-	.tlb_add_flush	= arm_smmu_tlb_inv_range_nosync,
+	.tlb_add_flush	= arm_smmu_tlb_inv_range_s1,
 	.tlb_sync	= arm_smmu_tlb_sync_context,
 };
 
 static const struct iommu_gather_ops arm_smmu_s2_tlb_ops_v2 = {
 	.tlb_flush_all	= arm_smmu_tlb_inv_context_s2,
-	.tlb_add_flush	= arm_smmu_tlb_inv_range_nosync,
+	.tlb_add_flush	= arm_smmu_tlb_inv_range_s2,
 	.tlb_sync	= arm_smmu_tlb_sync_context,
 };
 
-- 
2.21.0.dirty


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH 03/15] iommu/arm-smmu: Convert context bank registers to bitfields
From: Robin Murphy @ 2019-08-09 17:07 UTC (permalink / raw)
  To: will
  Cc: robdclark, joro, bjorn.andersson, iommu, vivek.gautam,
	gregory.clement, linux-arm-kernel
In-Reply-To: <cover.1565369764.git.robin.murphy@arm.com>

Finish the final part of the job, once again updating some names to
match the current spec.

Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---
 drivers/iommu/arm-smmu-regs.h | 86 ++++++++++++++++++-----------------
 drivers/iommu/arm-smmu.c      | 16 +++----
 drivers/iommu/qcom_iommu.c    | 13 +++---
 3 files changed, 59 insertions(+), 56 deletions(-)

diff --git a/drivers/iommu/arm-smmu-regs.h b/drivers/iommu/arm-smmu-regs.h
index 671c2d98c9da..75056edad31d 100644
--- a/drivers/iommu/arm-smmu-regs.h
+++ b/drivers/iommu/arm-smmu-regs.h
@@ -129,19 +129,59 @@ enum arm_smmu_cbar_type {
 #define CBA2R_VA64			BIT(0)
 
 #define ARM_SMMU_CB_SCTLR		0x0
+#define SCTLR_S1_ASIDPNE		BIT(12)
+#define SCTLR_CFCFG			BIT(7)
+#define SCTLR_CFIE			BIT(6)
+#define SCTLR_CFRE			BIT(5)
+#define SCTLR_E				BIT(4)
+#define SCTLR_AFE			BIT(2)
+#define SCTLR_TRE			BIT(1)
+#define SCTLR_M				BIT(0)
+
 #define ARM_SMMU_CB_ACTLR		0x4
+
 #define ARM_SMMU_CB_RESUME		0x8
-#define ARM_SMMU_CB_TTBCR2		0x10
+#define RESUME_TERMINATE		BIT(0)
+
+#define ARM_SMMU_CB_TCR2		0x10
+#define TCR2_SEP			GENMASK(17, 15)
+#define TCR2_SEP_UPSTREAM		0x7
+#define TCR2_AS				BIT(4)
+
 #define ARM_SMMU_CB_TTBR0		0x20
 #define ARM_SMMU_CB_TTBR1		0x28
-#define ARM_SMMU_CB_TTBCR		0x30
+#define TTBRn_ASID			GENMASK_ULL(63, 48)
+
+#define ARM_SMMU_CB_TCR			0x30
 #define ARM_SMMU_CB_CONTEXTIDR		0x34
 #define ARM_SMMU_CB_S1_MAIR0		0x38
 #define ARM_SMMU_CB_S1_MAIR1		0x3c
+
 #define ARM_SMMU_CB_PAR			0x50
+#define CB_PAR_F			BIT(0)
+
 #define ARM_SMMU_CB_FSR			0x58
+#define FSR_MULTI			BIT(31)
+#define FSR_SS				BIT(30)
+#define FSR_UUT				BIT(8)
+#define FSR_ASF				BIT(7)
+#define FSR_TLBLKF			BIT(6)
+#define FSR_TLBMCF			BIT(5)
+#define FSR_EF				BIT(4)
+#define FSR_PF				BIT(3)
+#define FSR_AFF				BIT(2)
+#define FSR_TF				BIT(1)
+
+#define FSR_IGN				(FSR_AFF | FSR_ASF | \
+					 FSR_TLBMCF | FSR_TLBLKF)
+#define FSR_FAULT			(FSR_MULTI | FSR_SS | FSR_UUT | \
+					 FSR_EF | FSR_PF | FSR_TF | FSR_IGN)
+
 #define ARM_SMMU_CB_FAR			0x60
+
 #define ARM_SMMU_CB_FSYNR0		0x68
+#define FSYNR0_WNR			BIT(4)
+
 #define ARM_SMMU_CB_S1_TLBIVA		0x600
 #define ARM_SMMU_CB_S1_TLBIASID		0x610
 #define ARM_SMMU_CB_S1_TLBIVAL		0x620
@@ -150,46 +190,8 @@ enum arm_smmu_cbar_type {
 #define ARM_SMMU_CB_TLBSYNC		0x7f0
 #define ARM_SMMU_CB_TLBSTATUS		0x7f4
 #define ARM_SMMU_CB_ATS1PR		0x800
+
 #define ARM_SMMU_CB_ATSR		0x8f0
-
-#define SCTLR_S1_ASIDPNE		(1 << 12)
-#define SCTLR_CFCFG			(1 << 7)
-#define SCTLR_CFIE			(1 << 6)
-#define SCTLR_CFRE			(1 << 5)
-#define SCTLR_E				(1 << 4)
-#define SCTLR_AFE			(1 << 2)
-#define SCTLR_TRE			(1 << 1)
-#define SCTLR_M				(1 << 0)
-
-#define CB_PAR_F			(1 << 0)
-
-#define ATSR_ACTIVE			(1 << 0)
-
-#define RESUME_RETRY			(0 << 0)
-#define RESUME_TERMINATE		(1 << 0)
-
-#define TTBCR2_SEP_SHIFT		15
-#define TTBCR2_SEP_UPSTREAM		(0x7 << TTBCR2_SEP_SHIFT)
-#define TTBCR2_AS			(1 << 4)
-
-#define TTBRn_ASID_SHIFT		48
-
-#define FSR_MULTI			(1 << 31)
-#define FSR_SS				(1 << 30)
-#define FSR_UUT				(1 << 8)
-#define FSR_ASF				(1 << 7)
-#define FSR_TLBLKF			(1 << 6)
-#define FSR_TLBMCF			(1 << 5)
-#define FSR_EF				(1 << 4)
-#define FSR_PF				(1 << 3)
-#define FSR_AFF				(1 << 2)
-#define FSR_TF				(1 << 1)
-
-#define FSR_IGN				(FSR_AFF | FSR_ASF | \
-					 FSR_TLBMCF | FSR_TLBLKF)
-#define FSR_FAULT			(FSR_MULTI | FSR_SS | FSR_UUT | \
-					 FSR_EF | FSR_PF | FSR_TF | FSR_IGN)
-
-#define FSYNR0_WNR			(1 << 4)
+#define ATSR_ACTIVE			BIT(0)
 
 #endif /* _ARM_SMMU_REGS_H */
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 515fb1ce39ed..d9a93e5f422f 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -628,16 +628,16 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain,
 
 	cb->cfg = cfg;
 
-	/* TTBCR */
+	/* TCR */
 	if (stage1) {
 		if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH32_S) {
 			cb->tcr[0] = pgtbl_cfg->arm_v7s_cfg.tcr;
 		} else {
 			cb->tcr[0] = pgtbl_cfg->arm_lpae_s1_cfg.tcr;
 			cb->tcr[1] = pgtbl_cfg->arm_lpae_s1_cfg.tcr >> 32;
-			cb->tcr[1] |= TTBCR2_SEP_UPSTREAM;
+			cb->tcr[1] |= FIELD_PREP(TCR2_SEP, TCR2_SEP_UPSTREAM);
 			if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH64)
-				cb->tcr[1] |= TTBCR2_AS;
+				cb->tcr[1] |= TCR2_AS;
 		}
 	} else {
 		cb->tcr[0] = pgtbl_cfg->arm_lpae_s2_cfg.vtcr;
@@ -650,9 +650,9 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain,
 			cb->ttbr[1] = pgtbl_cfg->arm_v7s_cfg.ttbr[1];
 		} else {
 			cb->ttbr[0] = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0];
-			cb->ttbr[0] |= (u64)cfg->asid << TTBRn_ASID_SHIFT;
+			cb->ttbr[0] |= FIELD_PREP(TTBRn_ASID, cfg->asid);
 			cb->ttbr[1] = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[1];
-			cb->ttbr[1] |= (u64)cfg->asid << TTBRn_ASID_SHIFT;
+			cb->ttbr[1] |= FIELD_PREP(TTBRn_ASID, cfg->asid);
 		}
 	} else {
 		cb->ttbr[0] = pgtbl_cfg->arm_lpae_s2_cfg.vttbr;
@@ -721,13 +721,13 @@ static void arm_smmu_write_context_bank(struct arm_smmu_device *smmu, int idx)
 	writel_relaxed(reg, gr1_base + ARM_SMMU_GR1_CBAR(idx));
 
 	/*
-	 * TTBCR
+	 * TCR
 	 * We must write this before the TTBRs, since it determines the
 	 * access behaviour of some fields (in particular, ASID[15:8]).
 	 */
 	if (stage1 && smmu->version > ARM_SMMU_V1)
-		writel_relaxed(cb->tcr[1], cb_base + ARM_SMMU_CB_TTBCR2);
-	writel_relaxed(cb->tcr[0], cb_base + ARM_SMMU_CB_TTBCR);
+		writel_relaxed(cb->tcr[1], cb_base + ARM_SMMU_CB_TCR2);
+	writel_relaxed(cb->tcr[0], cb_base + ARM_SMMU_CB_TCR);
 
 	/* TTBRs */
 	if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH32_S) {
diff --git a/drivers/iommu/qcom_iommu.c b/drivers/iommu/qcom_iommu.c
index 34d0b9783b3e..746bf2a7df05 100644
--- a/drivers/iommu/qcom_iommu.c
+++ b/drivers/iommu/qcom_iommu.c
@@ -7,6 +7,7 @@
  */
 
 #include <linux/atomic.h>
+#include <linux/bitfield.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/dma-iommu.h>
@@ -247,16 +248,16 @@ static int qcom_iommu_init_domain(struct iommu_domain *domain,
 		/* TTBRs */
 		iommu_writeq(ctx, ARM_SMMU_CB_TTBR0,
 				pgtbl_cfg.arm_lpae_s1_cfg.ttbr[0] |
-				((u64)ctx->asid << TTBRn_ASID_SHIFT));
+				FIELD_PREP(TTBRn_ASID, ctx->asid));
 		iommu_writeq(ctx, ARM_SMMU_CB_TTBR1,
 				pgtbl_cfg.arm_lpae_s1_cfg.ttbr[1] |
-				((u64)ctx->asid << TTBRn_ASID_SHIFT));
+				FIELD_PREP(TTBRn_ASID, ctx->asid));
 
-		/* TTBCR */
-		iommu_writel(ctx, ARM_SMMU_CB_TTBCR2,
+		/* TCR */
+		iommu_writel(ctx, ARM_SMMU_CB_TCR2,
 				(pgtbl_cfg.arm_lpae_s1_cfg.tcr >> 32) |
-				TTBCR2_SEP_UPSTREAM);
-		iommu_writel(ctx, ARM_SMMU_CB_TTBCR,
+				FIELD_PREP(TCR2_SEP, TCR2_SEP_UPSTREAM));
+		iommu_writel(ctx, ARM_SMMU_CB_TCR,
 				pgtbl_cfg.arm_lpae_s1_cfg.tcr);
 
 		/* MAIRs (stage-1 only) */
-- 
2.21.0.dirty


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH 02/15] iommu/arm-smmu: Convert GR1 registers to bitfields
From: Robin Murphy @ 2019-08-09 17:07 UTC (permalink / raw)
  To: will
  Cc: robdclark, joro, bjorn.andersson, iommu, vivek.gautam,
	gregory.clement, linux-arm-kernel
In-Reply-To: <cover.1565369764.git.robin.murphy@arm.com>

As for GR0, use the bitfield helpers to make GR1 usage a little cleaner,
and use it as an opportunity to audit and tidy the definitions. This
tweaks the handling of CBAR types to match what we did for S2CR a while
back, and fixes a couple of names which didn't quite match the latest
architecture spec (IHI0062D.c).

Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---
 drivers/iommu/arm-smmu-regs.h | 33 ++++++++++++++-------------------
 drivers/iommu/arm-smmu.c      | 18 +++++++++---------
 2 files changed, 23 insertions(+), 28 deletions(-)

diff --git a/drivers/iommu/arm-smmu-regs.h b/drivers/iommu/arm-smmu-regs.h
index d189f025537a..671c2d98c9da 100644
--- a/drivers/iommu/arm-smmu-regs.h
+++ b/drivers/iommu/arm-smmu-regs.h
@@ -108,30 +108,25 @@ enum arm_smmu_s2cr_type {
 
 /* Context bank attribute registers */
 #define ARM_SMMU_GR1_CBAR(n)		(0x0 + ((n) << 2))
-#define CBAR_VMID_SHIFT			0
-#define CBAR_VMID_MASK			0xff
-#define CBAR_S1_BPSHCFG_SHIFT		8
-#define CBAR_S1_BPSHCFG_MASK		3
-#define CBAR_S1_BPSHCFG_NSH		3
-#define CBAR_S1_MEMATTR_SHIFT		12
-#define CBAR_S1_MEMATTR_MASK		0xf
+#define CBAR_IRPTNDX			GENMASK(31, 24)
+#define CBAR_TYPE			GENMASK(17, 16)
+enum arm_smmu_cbar_type {
+	CBAR_TYPE_S2_TRANS,
+	CBAR_TYPE_S1_TRANS_S2_BYPASS,
+	CBAR_TYPE_S1_TRANS_S2_FAULT,
+	CBAR_TYPE_S1_TRANS_S2_TRANS,
+};
+#define CBAR_S1_MEMATTR			GENMASK(15, 12)
 #define CBAR_S1_MEMATTR_WB		0xf
-#define CBAR_TYPE_SHIFT			16
-#define CBAR_TYPE_MASK			0x3
-#define CBAR_TYPE_S2_TRANS		(0 << CBAR_TYPE_SHIFT)
-#define CBAR_TYPE_S1_TRANS_S2_BYPASS	(1 << CBAR_TYPE_SHIFT)
-#define CBAR_TYPE_S1_TRANS_S2_FAULT	(2 << CBAR_TYPE_SHIFT)
-#define CBAR_TYPE_S1_TRANS_S2_TRANS	(3 << CBAR_TYPE_SHIFT)
-#define CBAR_IRPTNDX_SHIFT		24
-#define CBAR_IRPTNDX_MASK		0xff
+#define CBAR_S1_BPSHCFG			GENMASK(9, 8)
+#define CBAR_S1_BPSHCFG_NSH		3
+#define CBAR_VMID			GENMASK(7, 0)
 
 #define ARM_SMMU_GR1_CBFRSYNRA(n)	(0x400 + ((n) << 2))
 
 #define ARM_SMMU_GR1_CBA2R(n)		(0x800 + ((n) << 2))
-#define CBA2R_RW64_32BIT		(0 << 0)
-#define CBA2R_RW64_64BIT		(1 << 0)
-#define CBA2R_VMID_SHIFT		16
-#define CBA2R_VMID_MASK			0xffff
+#define CBA2R_VMID16			GENMASK(31, 16)
+#define CBA2R_VA64			BIT(0)
 
 #define ARM_SMMU_CB_SCTLR		0x0
 #define ARM_SMMU_CB_ACTLR		0x4
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 89eddc54e41c..515fb1ce39ed 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -237,7 +237,7 @@ struct arm_smmu_cfg {
 		u16			asid;
 		u16			vmid;
 	};
-	u32				cbar;
+	enum arm_smmu_cbar_type		cbar;
 	enum arm_smmu_context_fmt	fmt;
 };
 #define INVALID_IRPTNDX			0xff
@@ -692,31 +692,31 @@ static void arm_smmu_write_context_bank(struct arm_smmu_device *smmu, int idx)
 	/* CBA2R */
 	if (smmu->version > ARM_SMMU_V1) {
 		if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH64)
-			reg = CBA2R_RW64_64BIT;
+			reg = CBA2R_VA64;
 		else
-			reg = CBA2R_RW64_32BIT;
+			reg = 0;
 		/* 16-bit VMIDs live in CBA2R */
 		if (smmu->features & ARM_SMMU_FEAT_VMID16)
-			reg |= cfg->vmid << CBA2R_VMID_SHIFT;
+			reg |= FIELD_PREP(CBA2R_VMID16, cfg->vmid);
 
 		writel_relaxed(reg, gr1_base + ARM_SMMU_GR1_CBA2R(idx));
 	}
 
 	/* CBAR */
-	reg = cfg->cbar;
+	reg = FIELD_PREP(CBAR_TYPE, cfg->cbar);
 	if (smmu->version < ARM_SMMU_V2)
-		reg |= cfg->irptndx << CBAR_IRPTNDX_SHIFT;
+		reg |= FIELD_PREP(CBAR_IRPTNDX, cfg->irptndx);
 
 	/*
 	 * Use the weakest shareability/memory types, so they are
 	 * overridden by the ttbcr/pte.
 	 */
 	if (stage1) {
-		reg |= (CBAR_S1_BPSHCFG_NSH << CBAR_S1_BPSHCFG_SHIFT) |
-			(CBAR_S1_MEMATTR_WB << CBAR_S1_MEMATTR_SHIFT);
+		reg |= FIELD_PREP(CBAR_S1_BPSHCFG, CBAR_S1_BPSHCFG_NSH) |
+			FIELD_PREP(CBAR_S1_MEMATTR, CBAR_S1_MEMATTR_WB);
 	} else if (!(smmu->features & ARM_SMMU_FEAT_VMID16)) {
 		/* 8-bit VMIDs live in CBAR */
-		reg |= cfg->vmid << CBAR_VMID_SHIFT;
+		reg |= FIELD_PREP(CBAR_VMID, cfg->vmid);
 	}
 	writel_relaxed(reg, gr1_base + ARM_SMMU_GR1_CBAR(idx));
 
-- 
2.21.0.dirty


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH 01/15] iommu/arm-smmu: Convert GR0 registers to bitfields
From: Robin Murphy @ 2019-08-09 17:07 UTC (permalink / raw)
  To: will
  Cc: robdclark, joro, bjorn.andersson, iommu, vivek.gautam,
	gregory.clement, linux-arm-kernel
In-Reply-To: <cover.1565369764.git.robin.murphy@arm.com>

FIELD_PREP remains a terrible name, but the overall simplification will
make further work on this stuff that much more manageable. This also
serves as an audit of the header, wherein we can impose a consistent
grouping and ordering of the offset and field definitions

Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---
 drivers/iommu/arm-smmu-regs.h | 126 ++++++++++++++++------------------
 drivers/iommu/arm-smmu.c      |  51 +++++++-------
 2 files changed, 84 insertions(+), 93 deletions(-)

diff --git a/drivers/iommu/arm-smmu-regs.h b/drivers/iommu/arm-smmu-regs.h
index 1c278f7ae888..d189f025537a 100644
--- a/drivers/iommu/arm-smmu-regs.h
+++ b/drivers/iommu/arm-smmu-regs.h
@@ -10,111 +10,101 @@
 #ifndef _ARM_SMMU_REGS_H
 #define _ARM_SMMU_REGS_H
 
+#include <linux/bits.h>
+
 /* Configuration registers */
 #define ARM_SMMU_GR0_sCR0		0x0
-#define sCR0_CLIENTPD			(1 << 0)
-#define sCR0_GFRE			(1 << 1)
-#define sCR0_GFIE			(1 << 2)
-#define sCR0_EXIDENABLE			(1 << 3)
-#define sCR0_GCFGFRE			(1 << 4)
-#define sCR0_GCFGFIE			(1 << 5)
-#define sCR0_USFCFG			(1 << 10)
-#define sCR0_VMIDPNE			(1 << 11)
-#define sCR0_PTM			(1 << 12)
-#define sCR0_FB				(1 << 13)
-#define sCR0_VMID16EN			(1 << 31)
-#define sCR0_BSU_SHIFT			14
-#define sCR0_BSU_MASK			0x3
+#define sCR0_VMID16EN			BIT(31)
+#define sCR0_BSU			GENMASK(15, 14)
+#define sCR0_FB				BIT(13)
+#define sCR0_PTM			BIT(12)
+#define sCR0_VMIDPNE			BIT(11)
+#define sCR0_USFCFG			BIT(10)
+#define sCR0_GCFGFIE			BIT(5)
+#define sCR0_GCFGFRE			BIT(4)
+#define sCR0_EXIDENABLE			BIT(3)
+#define sCR0_GFIE			BIT(2)
+#define sCR0_GFRE			BIT(1)
+#define sCR0_CLIENTPD			BIT(0)
 
 /* Auxiliary Configuration register */
 #define ARM_SMMU_GR0_sACR		0x10
 
 /* Identification registers */
 #define ARM_SMMU_GR0_ID0		0x20
+#define ID0_S1TS			BIT(30)
+#define ID0_S2TS			BIT(29)
+#define ID0_NTS				BIT(28)
+#define ID0_SMS				BIT(27)
+#define ID0_ATOSNS			BIT(26)
+#define ID0_PTFS_NO_AARCH32		BIT(25)
+#define ID0_PTFS_NO_AARCH32S		BIT(24)
+#define ID0_CTTW			BIT(14)
+#define ID0_NUMIRPT			GENMASK(23, 16)
+#define ID0_NUMSIDB			GENMASK(12, 9)
+#define ID0_EXIDS			BIT(8)
+#define ID0_NUMSMRG			GENMASK(7, 0)
+
 #define ARM_SMMU_GR0_ID1		0x24
+#define ID1_PAGESIZE			BIT(31)
+#define ID1_NUMPAGENDXB			GENMASK(30, 28)
+#define ID1_NUMS2CB			GENMASK(23, 16)
+#define ID1_NUMCB			GENMASK(7, 0)
+
 #define ARM_SMMU_GR0_ID2		0x28
+#define ID2_VMID16			BIT(15)
+#define ID2_PTFS_64K			BIT(14)
+#define ID2_PTFS_16K			BIT(13)
+#define ID2_PTFS_4K			BIT(12)
+#define ID2_UBS				GENMASK(11, 8)
+#define ID2_OAS				GENMASK(7, 4)
+#define ID2_IAS				GENMASK(3, 0)
+
 #define ARM_SMMU_GR0_ID3		0x2c
 #define ARM_SMMU_GR0_ID4		0x30
 #define ARM_SMMU_GR0_ID5		0x34
 #define ARM_SMMU_GR0_ID6		0x38
+
 #define ARM_SMMU_GR0_ID7		0x3c
+#define ID7_MAJOR			GENMASK(7, 4)
+#define ID7_MINOR			GENMASK(3, 0)
+
 #define ARM_SMMU_GR0_sGFSR		0x48
 #define ARM_SMMU_GR0_sGFSYNR0		0x50
 #define ARM_SMMU_GR0_sGFSYNR1		0x54
 #define ARM_SMMU_GR0_sGFSYNR2		0x58
 
-#define ID0_S1TS			(1 << 30)
-#define ID0_S2TS			(1 << 29)
-#define ID0_NTS				(1 << 28)
-#define ID0_SMS				(1 << 27)
-#define ID0_ATOSNS			(1 << 26)
-#define ID0_PTFS_NO_AARCH32		(1 << 25)
-#define ID0_PTFS_NO_AARCH32S		(1 << 24)
-#define ID0_CTTW			(1 << 14)
-#define ID0_NUMIRPT_SHIFT		16
-#define ID0_NUMIRPT_MASK		0xff
-#define ID0_NUMSIDB_SHIFT		9
-#define ID0_NUMSIDB_MASK		0xf
-#define ID0_EXIDS			(1 << 8)
-#define ID0_NUMSMRG_SHIFT		0
-#define ID0_NUMSMRG_MASK		0xff
-
-#define ID1_PAGESIZE			(1 << 31)
-#define ID1_NUMPAGENDXB_SHIFT		28
-#define ID1_NUMPAGENDXB_MASK		7
-#define ID1_NUMS2CB_SHIFT		16
-#define ID1_NUMS2CB_MASK		0xff
-#define ID1_NUMCB_SHIFT			0
-#define ID1_NUMCB_MASK			0xff
-
-#define ID2_OAS_SHIFT			4
-#define ID2_OAS_MASK			0xf
-#define ID2_IAS_SHIFT			0
-#define ID2_IAS_MASK			0xf
-#define ID2_UBS_SHIFT			8
-#define ID2_UBS_MASK			0xf
-#define ID2_PTFS_4K			(1 << 12)
-#define ID2_PTFS_16K			(1 << 13)
-#define ID2_PTFS_64K			(1 << 14)
-#define ID2_VMID16			(1 << 15)
-
-#define ID7_MAJOR_SHIFT			4
-#define ID7_MAJOR_MASK			0xf
-
 /* Global TLB invalidation */
 #define ARM_SMMU_GR0_TLBIVMID		0x64
 #define ARM_SMMU_GR0_TLBIALLNSNH	0x68
 #define ARM_SMMU_GR0_TLBIALLH		0x6c
 #define ARM_SMMU_GR0_sTLBGSYNC		0x70
+
 #define ARM_SMMU_GR0_sTLBGSTATUS	0x74
-#define sTLBGSTATUS_GSACTIVE		(1 << 0)
+#define sTLBGSTATUS_GSACTIVE		BIT(0)
 
 /* Stream mapping registers */
 #define ARM_SMMU_GR0_SMR(n)		(0x800 + ((n) << 2))
-#define SMR_VALID			(1 << 31)
-#define SMR_MASK_SHIFT			16
-#define SMR_ID_SHIFT			0
+#define SMR_VALID			BIT(31)
+#define SMR_MASK			GENMASK(31, 16)
+#define SMR_ID				GENMASK(15, 0)
 
 #define ARM_SMMU_GR0_S2CR(n)		(0xc00 + ((n) << 2))
-#define S2CR_CBNDX_SHIFT		0
-#define S2CR_CBNDX_MASK			0xff
-#define S2CR_EXIDVALID			(1 << 10)
-#define S2CR_TYPE_SHIFT			16
-#define S2CR_TYPE_MASK			0x3
-enum arm_smmu_s2cr_type {
-	S2CR_TYPE_TRANS,
-	S2CR_TYPE_BYPASS,
-	S2CR_TYPE_FAULT,
-};
-
-#define S2CR_PRIVCFG_SHIFT		24
-#define S2CR_PRIVCFG_MASK		0x3
+#define S2CR_PRIVCFG			GENMASK(25, 24)
 enum arm_smmu_s2cr_privcfg {
 	S2CR_PRIVCFG_DEFAULT,
 	S2CR_PRIVCFG_DIPAN,
 	S2CR_PRIVCFG_UNPRIV,
 	S2CR_PRIVCFG_PRIV,
 };
+#define S2CR_TYPE			GENMASK(17, 16)
+enum arm_smmu_s2cr_type {
+	S2CR_TYPE_TRANS,
+	S2CR_TYPE_BYPASS,
+	S2CR_TYPE_FAULT,
+};
+#define S2CR_EXIDVALID			BIT(10)
+#define S2CR_CBNDX			GENMASK(7, 0)
 
 /* Context bank attribute registers */
 #define ARM_SMMU_GR1_CBAR(n)		(0x0 + ((n) << 2))
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 64977c131ee6..89eddc54e41c 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -20,6 +20,7 @@
 #include <linux/acpi.h>
 #include <linux/acpi_iort.h>
 #include <linux/atomic.h>
+#include <linux/bitfield.h>
 #include <linux/delay.h>
 #include <linux/dma-iommu.h>
 #include <linux/dma-mapping.h>
@@ -1019,7 +1020,7 @@ static void arm_smmu_domain_free(struct iommu_domain *domain)
 static void arm_smmu_write_smr(struct arm_smmu_device *smmu, int idx)
 {
 	struct arm_smmu_smr *smr = smmu->smrs + idx;
-	u32 reg = smr->id << SMR_ID_SHIFT | smr->mask << SMR_MASK_SHIFT;
+	u32 reg = FIELD_PREP(SMR_ID, smr->id) | FIELD_PREP(SMR_MASK, smr->mask);
 
 	if (!(smmu->features & ARM_SMMU_FEAT_EXIDS) && smr->valid)
 		reg |= SMR_VALID;
@@ -1029,9 +1030,9 @@ 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 = (s2cr->type & S2CR_TYPE_MASK) << S2CR_TYPE_SHIFT |
-		  (s2cr->cbndx & S2CR_CBNDX_MASK) << S2CR_CBNDX_SHIFT |
-		  (s2cr->privcfg & S2CR_PRIVCFG_MASK) << S2CR_PRIVCFG_SHIFT;
+	u32 reg = FIELD_PREP(S2CR_TYPE, s2cr->type) |
+		  FIELD_PREP(S2CR_CBNDX, s2cr->cbndx) |
+		  FIELD_PREP(S2CR_PRIVCFG, s2cr->privcfg);
 
 	if (smmu->features & ARM_SMMU_FEAT_EXIDS && smmu->smrs &&
 	    smmu->smrs[idx].valid)
@@ -1063,15 +1064,15 @@ static void arm_smmu_test_smr_masks(struct arm_smmu_device *smmu)
 	 * bits are set, so check each one separately. We can reject
 	 * masters later if they try to claim IDs outside these masks.
 	 */
-	smr = smmu->streamid_mask << SMR_ID_SHIFT;
+	smr = FIELD_PREP(SMR_ID, smmu->streamid_mask);
 	writel_relaxed(smr, gr0_base + ARM_SMMU_GR0_SMR(0));
 	smr = readl_relaxed(gr0_base + ARM_SMMU_GR0_SMR(0));
-	smmu->streamid_mask = smr >> SMR_ID_SHIFT;
+	smmu->streamid_mask = FIELD_GET(SMR_ID, smr);
 
-	smr = smmu->streamid_mask << SMR_MASK_SHIFT;
+	smr = FIELD_PREP(SMR_MASK, smmu->streamid_mask);
 	writel_relaxed(smr, gr0_base + ARM_SMMU_GR0_SMR(0));
 	smr = readl_relaxed(gr0_base + ARM_SMMU_GR0_SMR(0));
-	smmu->smr_mask_mask = smr >> SMR_MASK_SHIFT;
+	smmu->smr_mask_mask = FIELD_GET(SMR_MASK, smr);
 }
 
 static int arm_smmu_find_sme(struct arm_smmu_device *smmu, u16 id, u16 mask)
@@ -1140,8 +1141,8 @@ static int arm_smmu_master_alloc_smes(struct device *dev)
 	mutex_lock(&smmu->stream_map_mutex);
 	/* Figure out a viable stream map entry allocation */
 	for_each_cfg_sme(fwspec, i, idx) {
-		u16 sid = fwspec->ids[i];
-		u16 mask = fwspec->ids[i] >> SMR_MASK_SHIFT;
+		u16 sid = FIELD_GET(SMR_ID, fwspec->ids[i]);
+		u16 mask = FIELD_GET(SMR_MASK, fwspec->ids[i]);
 
 		if (idx != INVALID_SMENDX) {
 			ret = -EEXIST;
@@ -1466,8 +1467,8 @@ static int arm_smmu_add_device(struct device *dev)
 
 	ret = -EINVAL;
 	for (i = 0; i < fwspec->num_ids; i++) {
-		u16 sid = fwspec->ids[i];
-		u16 mask = fwspec->ids[i] >> SMR_MASK_SHIFT;
+		u16 sid = FIELD_GET(SMR_ID, fwspec->ids[i]);
+		u16 mask = FIELD_GET(SMR_MASK, fwspec->ids[i]);
 
 		if (sid & ~smmu->streamid_mask) {
 			dev_err(dev, "stream ID 0x%x out of range for SMMU (0x%x)\n",
@@ -1648,12 +1649,12 @@ static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args)
 	u32 mask, fwid = 0;
 
 	if (args->args_count > 0)
-		fwid |= (u16)args->args[0];
+		fwid |= FIELD_PREP(SMR_ID, args->args[0]);
 
 	if (args->args_count > 1)
-		fwid |= (u16)args->args[1] << SMR_MASK_SHIFT;
+		fwid |= FIELD_PREP(SMR_MASK, args->args[1]);
 	else if (!of_property_read_u32(args->np, "stream-match-mask", &mask))
-		fwid |= (u16)mask << SMR_MASK_SHIFT;
+		fwid |= FIELD_PREP(SMR_MASK, mask);
 
 	return iommu_fwspec_add_ids(dev, &fwid, 1);
 }
@@ -1728,7 +1729,7 @@ static void arm_smmu_device_reset(struct arm_smmu_device *smmu)
 		 * bit is only present in MMU-500r2 onwards.
 		 */
 		reg = readl_relaxed(gr0_base + ARM_SMMU_GR0_ID7);
-		major = (reg >> ID7_MAJOR_SHIFT) & ID7_MAJOR_MASK;
+		major = FIELD_GET(ID7_MAJOR, reg);
 		reg = readl_relaxed(gr0_base + ARM_SMMU_GR0_sACR);
 		if (major >= 2)
 			reg &= ~ARM_MMU500_ACR_CACHE_LOCK;
@@ -1780,7 +1781,7 @@ static void arm_smmu_device_reset(struct arm_smmu_device *smmu)
 	reg &= ~sCR0_FB;
 
 	/* Don't upgrade barriers */
-	reg &= ~(sCR0_BSU_MASK << sCR0_BSU_SHIFT);
+	reg &= ~(sCR0_BSU);
 
 	if (smmu->features & ARM_SMMU_FEAT_VMID16)
 		reg |= sCR0_VMID16EN;
@@ -1879,12 +1880,12 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
 		smmu->features |= ARM_SMMU_FEAT_EXIDS;
 		size = 1 << 16;
 	} else {
-		size = 1 << ((id >> ID0_NUMSIDB_SHIFT) & ID0_NUMSIDB_MASK);
+		size = 1 << FIELD_GET(ID0_NUMSIDB, id);
 	}
 	smmu->streamid_mask = size - 1;
 	if (id & ID0_SMS) {
 		smmu->features |= ARM_SMMU_FEAT_STREAM_MATCH;
-		size = (id >> ID0_NUMSMRG_SHIFT) & ID0_NUMSMRG_MASK;
+		size = FIELD_GET(ID0_NUMSMRG, id);
 		if (size == 0) {
 			dev_err(smmu->dev,
 				"stream-matching supported, but no SMRs present!\n");
@@ -1923,15 +1924,15 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
 	smmu->pgshift = (id & ID1_PAGESIZE) ? 16 : 12;
 
 	/* Check for size mismatch of SMMU address space from mapped region */
-	size = 1 << (((id >> ID1_NUMPAGENDXB_SHIFT) & ID1_NUMPAGENDXB_MASK) + 1);
+	size = 1 << (FIELD_GET(ID1_NUMPAGENDXB, id) + 1);
 	size <<= smmu->pgshift;
 	if (smmu->cb_base != gr0_base + size)
 		dev_warn(smmu->dev,
 			"SMMU address space size (0x%lx) differs from mapped region size (0x%tx)!\n",
 			size * 2, (smmu->cb_base - gr0_base) * 2);
 
-	smmu->num_s2_context_banks = (id >> ID1_NUMS2CB_SHIFT) & ID1_NUMS2CB_MASK;
-	smmu->num_context_banks = (id >> ID1_NUMCB_SHIFT) & ID1_NUMCB_MASK;
+	smmu->num_s2_context_banks = FIELD_GET(ID1_NUMS2CB, id);
+	smmu->num_context_banks = FIELD_GET(ID1_NUMCB, id);
 	if (smmu->num_s2_context_banks > smmu->num_context_banks) {
 		dev_err(smmu->dev, "impossible number of S2 context banks!\n");
 		return -ENODEV;
@@ -1957,11 +1958,11 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
 
 	/* ID2 */
 	id = readl_relaxed(gr0_base + ARM_SMMU_GR0_ID2);
-	size = arm_smmu_id_size_to_bits((id >> ID2_IAS_SHIFT) & ID2_IAS_MASK);
+	size = arm_smmu_id_size_to_bits(FIELD_GET(ID2_IAS, id));
 	smmu->ipa_size = size;
 
 	/* The output mask is also applied for bypass */
-	size = arm_smmu_id_size_to_bits((id >> ID2_OAS_SHIFT) & ID2_OAS_MASK);
+	size = arm_smmu_id_size_to_bits(FIELD_GET(ID2_OAS, id));
 	smmu->pa_size = size;
 
 	if (id & ID2_VMID16)
@@ -1981,7 +1982,7 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
 		if (smmu->version == ARM_SMMU_V1_64K)
 			smmu->features |= ARM_SMMU_FEAT_FMT_AARCH64_64K;
 	} else {
-		size = (id >> ID2_UBS_SHIFT) & ID2_UBS_MASK;
+		size = FIELD_GET(ID2_UBS, id);
 		smmu->va_size = arm_smmu_id_size_to_bits(size);
 		if (id & ID2_PTFS_4K)
 			smmu->features |= ARM_SMMU_FEAT_FMT_AARCH64_4K;
-- 
2.21.0.dirty


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH 00/15] Arm SMMU refactoring
From: Robin Murphy @ 2019-08-09 17:07 UTC (permalink / raw)
  To: will
  Cc: robdclark, joro, bjorn.andersson, iommu, vivek.gautam,
	gregory.clement, linux-arm-kernel

Hi all,

This is a big refactoring of arm-smmu in order to help cope with the
various divergent implementation details currently flying around. So
far we've been accruing various quirks and errata workarounds within
the main flow of the driver, but given that it's written to an
architecture rather than any particular hardware implementation, after
a point these start to become increasingly invasive and potentially
conflict with each other.

These patches clean up the existing quirks handled by the driver to
lay a foundation on which we can continue to add more in a maintainable
fashion. The idea is that major vendor customisations can then be kept
in arm-smmu-<vendor>.c implementation files out of each others' way.

A branch is available at:

  git://linux-arm.org/linux-rm  iommu/smmu-impl

which I'll probably keep tweaking until I'm happy with the names of
things; I just didn't want to delay this initial posting any lomnger.

Robin.


Robin Murphy (15):
  iommu/arm-smmu: Convert GR0 registers to bitfields
  iommu/arm-smmu: Convert GR1 registers to bitfields
  iommu/arm-smmu: Convert context bank registers to bitfields
  iommu/arm-smmu: Rework cb_base handling
  iommu/arm-smmu: Split arm_smmu_tlb_inv_range_nosync()
  iommu/arm-smmu: Get rid of weird "atomic" write
  iommu/arm-smmu: Abstract GR1 accesses
  iommu/arm-smmu: Abstract context bank accesses
  iommu/arm-smmu: Abstract GR0 accesses
  iommu/arm-smmu: Rename arm-smmu-regs.h
  iommu/arm-smmu: Add implementation infrastructure
  iommu/arm-smmu: Move Secure access quirk to implementation
  iommu/arm-smmu: Add configuration implementation hook
  iommu/arm-smmu: Add reset implementation hook
  iommu/arm-smmu: Add context init implementation hook

 MAINTAINERS                   |   3 +-
 drivers/iommu/Makefile        |   2 +-
 drivers/iommu/arm-smmu-impl.c | 165 ++++++++++
 drivers/iommu/arm-smmu-regs.h | 210 -------------
 drivers/iommu/arm-smmu.c      | 570 +++++++++++-----------------------
 drivers/iommu/arm-smmu.h      | 386 +++++++++++++++++++++++
 drivers/iommu/qcom_iommu.c    |  15 +-
 7 files changed, 743 insertions(+), 608 deletions(-)
 create mode 100644 drivers/iommu/arm-smmu-impl.c
 delete mode 100644 drivers/iommu/arm-smmu-regs.h
 create mode 100644 drivers/iommu/arm-smmu.h

-- 
2.21.0.dirty


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH 1/7] [RFC] ARM: remove Intel iop33x and iop13xx support
From: Wolfram Sang @ 2019-08-09 16:57 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-gpio, linux-kernel, Linus Walleij, soc, Russell King,
	Bartosz Golaszewski, Vinod Koul, linux-i2c, dmaengine,
	Dan Williams, linux-arm-kernel
In-Reply-To: <20190809163334.489360-1-arnd@arndb.de>


[-- Attachment #1.1: Type: text/plain, Size: 918 bytes --]

On Fri, Aug 09, 2019 at 06:33:15PM +0200, Arnd Bergmann wrote:
> There are three families of IOP machines we support in Linux: iop32x
> (which includes EP80219), iop33x and iop13xx (aka IOP34x aka WP8134x).
> 
> All products we support in the kernel are based on the first of these,
> iop32x, the other families only ever supported the Intel reference
> boards but no actual machine anyone could ever buy.
> 
> While one could clearly make them all three work in a single kernel
> with some work, this takes the easy way out, removing the later two
> platforms entirely, under the assumption that there are no remaining
> users.
> 
> Earlier versions of OpenWRT and Debian both had support for iop32x
> but not the others, and they both dropped iop32x as well in their 2015
> releases.
> 
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>

Acked-by: Wolfram Sang <wsa@the-dreams.de> # for I2C parts


[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v2 7/8] arm64: defconfig: Enable the PSCI CPUidle driver
From: Will Deacon @ 2019-08-09 16:53 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Mark Rutland, Ulf Hansson, linux-pm, Catalin Marinas,
	Daniel Lezcano, Rafael J. Wysocki, LKML, Sudeep Holla, Shawn Guo,
	LAKML
In-Reply-To: <58d9677db3510ed106fe23118090c84f78a44102.1565348376.git.lorenzo.pieralisi@arm.com>

On Fri, Aug 09, 2019 at 12:03:13PM +0100, Lorenzo Pieralisi wrote:
> Enable the PSCI CPUidle driver to replace the functionality
> previously provided by the generic ARM CPUidle driver through
> CPU operations.
> 
> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> Cc: Will Deacon <will@kernel.org>
> Cc: Sudeep Holla <sudeep.holla@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> ---
>  arch/arm64/configs/defconfig | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
> index 0e58ef02880c..c0a7cfe3aebd 100644
> --- a/arch/arm64/configs/defconfig
> +++ b/arch/arm64/configs/defconfig
> @@ -72,6 +72,7 @@ CONFIG_RANDOMIZE_BASE=y
>  CONFIG_HIBERNATION=y
>  CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y
>  CONFIG_ARM_CPUIDLE=y
> +CONFIG_ARM_PSCI_CPUIDLE=y
>  CONFIG_CPU_FREQ=y
>  CONFIG_CPU_FREQ_STAT=y
>  CONFIG_CPU_FREQ_GOV_POWERSAVE=m

I'll queue the first 6 patches in this series, but please route this one
via arm-soc to avoid conflicts:

Acked-by: Will Deacon <will@kernel.org>

Failing that, I'm happy to take it at -rc1.

Will

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH V5 00/12] 52-bit kernel + user VAs
From: Will Deacon @ 2019-08-09 16:47 UTC (permalink / raw)
  To: Steve Capper
  Cc: crecklin, ard.biesheuvel, catalin.marinas, bhsharma, maz,
	linux-arm-kernel
In-Reply-To: <20190807155524.5112-1-steve.capper@arm.com>

On Wed, Aug 07, 2019 at 04:55:12PM +0100, Steve Capper wrote:
> This patch series adds support for 52-bit kernel VAs using some of the
> machinery already introduced by the 52-bit userspace VA code in 5.0.

Cheers, I've pushed this out on a for-next/52-bit-kva branch with one
small patch on top and Catalin's tags added.

Will

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH] mxsfb: allow attachment of display bridges
From: Guido Günther @ 2019-08-09 16:45 UTC (permalink / raw)
  To: Ville Baillie
  Cc: marex, kernel, dri-devel, airlied, festevam, s.hauer,
	linux-kernel, stefan, linux-imx, daniel, Robert Chiras, shawnguo,
	linux-arm-kernel
In-Reply-To: <20190801111853.GA24574@villeb-dev>

Hi,
On Thu, Aug 01, 2019 at 11:18:53AM +0000, Ville Baillie wrote:
> ---
>  drivers/gpu/drm/mxsfb/mxsfb_drv.c | 20 ++++++++++++++++----
>  drivers/gpu/drm/mxsfb/mxsfb_drv.h |  1 +
>  drivers/gpu/drm/mxsfb/mxsfb_out.c | 14 +++++++++++---
>  3 files changed, 28 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.c b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
> index 6fafc90da4ec..c19a7b7aa3a6 100644
> --- a/drivers/gpu/drm/mxsfb/mxsfb_drv.c
> +++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
> @@ -229,10 +229,22 @@ static int mxsfb_load(struct drm_device *drm, unsigned long flags)
>  		goto err_vblank;
>  	}
>  
> -	ret = drm_panel_attach(mxsfb->panel, &mxsfb->connector);
> -	if (ret) {
> -		dev_err(drm->dev, "Cannot connect panel\n");
> -		goto err_vblank;
> +	if (mxsfb->panel) {
> +		ret = drm_panel_attach(mxsfb->panel, &mxsfb->connector);
> +		if (ret) {
> +			dev_err(drm->dev, "Cannot connect panel\n");
> +			goto err_vblank;
> +		}
> +	} else if (mxsfb->bridge) {
> +		ret = drm_bridge_attach(&mxsfb->pipe.encoder, mxsfb->bridge,
> +				NULL);
> +		if (ret) {
> +			dev_err(drm->dev, "Cannot connect bridge\n");
> +			goto err_vblank;
> +		}
> +	} else {
> +		dev_err(drm->dev, "No panel or bridge\n");
> +		return -EINVAL;
>  	}
>  
>  	drm->mode_config.min_width	= MXSFB_MIN_XRES;
> diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.h b/drivers/gpu/drm/mxsfb/mxsfb_drv.h
> index d975300dca05..436fe4bbb47a 100644
> --- a/drivers/gpu/drm/mxsfb/mxsfb_drv.h
> +++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.h
> @@ -29,6 +29,7 @@ struct mxsfb_drm_private {
>  	struct drm_simple_display_pipe	pipe;
>  	struct drm_connector		connector;
>  	struct drm_panel		*panel;
> +	struct drm_bridge		*bridge;
>  };
>  
>  int mxsfb_setup_crtc(struct drm_device *dev);
> diff --git a/drivers/gpu/drm/mxsfb/mxsfb_out.c b/drivers/gpu/drm/mxsfb/mxsfb_out.c
> index 91e76f9cead6..77e03eb0fca6 100644
> --- a/drivers/gpu/drm/mxsfb/mxsfb_out.c
> +++ b/drivers/gpu/drm/mxsfb/mxsfb_out.c
> @@ -78,9 +78,11 @@ int mxsfb_create_output(struct drm_device *drm)
>  {
>  	struct mxsfb_drm_private *mxsfb = drm->dev_private;
>  	struct drm_panel *panel;
> +	struct drm_bridge *bridge;
>  	int ret;
>  
> -	ret = drm_of_find_panel_or_bridge(drm->dev->of_node, 0, 0, &panel, NULL);
> +	ret = drm_of_find_panel_or_bridge(drm->dev->of_node, 0, 0, &panel,
> +			&bridge);
>  	if (ret)
>  		return ret;
>  
> @@ -91,8 +93,14 @@ int mxsfb_create_output(struct drm_device *drm)
>  	ret = drm_connector_init(drm, &mxsfb->connector,
>  				 &mxsfb_panel_connector_funcs,
>  				 DRM_MODE_CONNECTOR_Unknown);
> -	if (!ret)
> -		mxsfb->panel = panel;
> +	if (!ret) {
> +		if (panel)
> +			mxsfb->panel = panel;
> +		else if (bridge)
> +			mxsfb->bridge = bridge;
> +		else
> +			return -EINVAL;
> +	}
>  
>  	return ret;
>  }
> -- 
> 2.17.1

Robert Chiras posted bridge support for mxsfb back in June:

    https://patchwork.freedesktop.org/patch/314430/?series=62822&rev=1

Cheers,
 -- Guido

> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH 1/4] dt-bindings: watchdog: Add i.MX7ULP bindings
From: Guenter Roeck @ 2019-08-09 16:42 UTC (permalink / raw)
  To: Anson Huang
  Cc: mark.rutland, devicetree, leonard.crestez, schnitzeltony,
	linux-watchdog, otavio, festevam, s.hauer, jan.tuerk, linux,
	linux-kernel, robh+dt, Linux-imx, kernel, u.kleine-koenig, wim,
	shawnguo, linux-arm-kernel
In-Reply-To: <1565334842-28161-1-git-send-email-Anson.Huang@nxp.com>

On Fri, Aug 09, 2019 at 03:13:59PM +0800, Anson Huang wrote:
> Add the watchdog bindings for Freescale i.MX7ULP.
> 
> Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
> ---
>  .../bindings/watchdog/fsl-imx7ulp-wdt.txt          | 22 ++++++++++++++++++++++
>  1 file changed, 22 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/watchdog/fsl-imx7ulp-wdt.txt
> 
> diff --git a/Documentation/devicetree/bindings/watchdog/fsl-imx7ulp-wdt.txt b/Documentation/devicetree/bindings/watchdog/fsl-imx7ulp-wdt.txt
> new file mode 100644
> index 0000000..d83fc5c
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/watchdog/fsl-imx7ulp-wdt.txt
> @@ -0,0 +1,22 @@
> +* Freescale i.MX7ULP Watchdog Timer (WDT) Controller
> +
> +Required properties:
> +- compatible : Should be "fsl,imx7ulp-wdt"
> +- reg : Should contain WDT registers location and length
> +- interrupts : Should contain WDT interrupt
> +- clocks: Should contain a phandle pointing to the gated peripheral clock.

The driver as submitted does not include clock or interrupt handling.
Why are those properties listed as mandatory if they are not really
needed (nor used) ?

> +
> +Optional properties:
> +- timeout-sec : Contains the watchdog timeout in seconds
> +
> +Examples:
> +
> +wdog1: wdog@403d0000 {
> +	compatible = "fsl,imx7ulp-wdt";
> +	reg = <0x403d0000 0x10000>;
> +	interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
> +	clocks = <&pcc2 IMX7ULP_CLK_WDG1>;
> +	assigned-clocks = <&pcc2 IMX7ULP_CLK_WDG1>;
> +	assigned-clocks-parents = <&scg1 IMX7ULP_CLK_FIRC_BUS_CLK>;
> +	timeout-sec = <40>;
> +};
> -- 
> 2.7.4
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH 0/7] ARM: preparation for multiplatform iop32x
From: Lennert Buytenhek @ 2019-08-09 16:38 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Dave Jiang, Linus Walleij, Russell King, soc, Dan Williams,
	Imre Kaloz, Martin Michlmayr, linux-arm-kernel
In-Reply-To: <20190809162956.488941-1-arnd@arndb.de>

On Fri, Aug 09, 2019 at 06:29:41PM +0200, Arnd Bergmann wrote:

> I'm looking into converting some of the remaining ARMv5
> platforms in arch/arm/ to work together in a single kernel
> binary.
> 
> IOP32x seems to be a fairly easy target for multiplatform
> by itself, but the way the plat-iop code interacts with
> three generations of the code, and how the dma-adma driver
> is configured at compile-time for each version gets in the
> way.
> 
> I considered adding more indirection layers for those two,
> but removing iop33x and iop13xx is much easier in comparison,
> so this is the first approach I'm posting.
> 
> If we conclude that iop33x and iop13xx are indeed not used
> any more, the remaining patches in this series are
> straightforward. The actual multiplatform conversion also
> requires changes to the irqchip driver that are not completely
> mechanic, and we can discuss those after deciding what to do
> with the first set.
> 
> Adding a few people to Cc that historically worked on IOP.

I haven't worked with any of these platforms for many years now,
and I can't really say much about their current use.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [GIT PULL] arm64 fixes for 5.3-rc4
From: pr-tracker-bot @ 2019-08-09 16:35 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Will Deacon, Linus Torvalds, linux-kernel, linux-arm-kernel
In-Reply-To: <20190809161513.GA42536@arrakis.emea.arm.com>

The pull request you sent on Fri, 9 Aug 2019 17:15:14 +0100:

> git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux tags/arm64-fixes

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/15a555a4b8be26683d77df8d5dbe8ac83f5ec3a6

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.wiki.kernel.org/userdoc/prtracker

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH 7/7] ARM: iop32x: merge everything into mach-iop32x/
From: Arnd Bergmann @ 2019-08-09 16:33 UTC (permalink / raw)
  To: soc
  Cc: Arnd Bergmann, linux-gpio, Linus Walleij, Russell King,
	linux-kernel, Bartosz Golaszewski, Vinod Koul, linux-i2c,
	dmaengine, Dan Williams, linux-arm-kernel
In-Reply-To: <20190809163334.489360-1-arnd@arndb.de>

Various bits of iop32x are now in their traditional locations in plat-iop,
mach-iop/include/mach/ and in include/asm/mach/hardware. As nothing
outside of the iop32x mach code references these any more, this can all
be moved into one place now.

The only remaining things in the include/mach/ directory are now the
NR_IRQS definition, the entry-macros.S file and the the decompressor
uart access. After the irqchip code has been converted to SPARSE_IRQ
and GENERIC_IRQ_MULTI_HANDLER, it can be moved to ARCH_MULTIPLATFORM.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 arch/arm/Makefile                             |  1 -
 arch/arm/mach-iop32x/Makefile                 | 10 ++++-
 arch/arm/{plat-iop => mach-iop32x}/adma.c     |  4 +-
 arch/arm/{plat-iop => mach-iop32x}/cp6.c      |  0
 arch/arm/mach-iop32x/em7210.c                 |  5 ++-
 arch/arm/mach-iop32x/glantank.c               |  5 ++-
 .../mach-iop32x/{include/mach => }/glantank.h |  2 -
 .../mach-iop32x/{include/mach => }/hardware.h |  6 +--
 arch/arm/{plat-iop => mach-iop32x}/i2c.c      |  6 ++-
 .../mach-iop32x/include/mach/entry-macro.S    |  2 -
 arch/arm/mach-iop32x/include/mach/iop32x.h    | 31 --------------
 arch/arm/mach-iop32x/include/mach/irqs.h      | 33 ---------------
 arch/arm/mach-iop32x/include/mach/time.h      |  5 ---
 .../asm/hardware => mach-iop32x}/iop3xx.h     | 18 +++++++-
 arch/arm/mach-iop32x/iq31244.c                |  5 ++-
 .../mach-iop32x/{include/mach => }/iq31244.h  |  2 -
 arch/arm/mach-iop32x/iq80321.c                |  5 ++-
 .../mach-iop32x/{include/mach => }/iq80321.h  |  2 -
 arch/arm/mach-iop32x/irq.c                    |  3 +-
 arch/arm/mach-iop32x/irqs.h                   | 42 +++++++++++++++++++
 arch/arm/mach-iop32x/n2100.c                  |  5 ++-
 .../mach-iop32x/{include/mach => }/n2100.h    |  2 -
 arch/arm/{plat-iop => mach-iop32x}/pci.c      |  4 +-
 arch/arm/{plat-iop => mach-iop32x}/pmu.c      |  2 +-
 arch/arm/{plat-iop => mach-iop32x}/restart.c  |  4 +-
 arch/arm/{plat-iop => mach-iop32x}/setup.c    |  2 +-
 arch/arm/{plat-iop => mach-iop32x}/time.c     |  7 ++--
 arch/arm/plat-iop/Makefile                    | 14 -------
 28 files changed, 102 insertions(+), 125 deletions(-)
 rename arch/arm/{plat-iop => mach-iop32x}/adma.c (98%)
 rename arch/arm/{plat-iop => mach-iop32x}/cp6.c (100%)
 rename arch/arm/mach-iop32x/{include/mach => }/glantank.h (78%)
 rename arch/arm/mach-iop32x/{include/mach => }/hardware.h (90%)
 rename arch/arm/{plat-iop => mach-iop32x}/i2c.c (96%)
 delete mode 100644 arch/arm/mach-iop32x/include/mach/iop32x.h
 delete mode 100644 arch/arm/mach-iop32x/include/mach/time.h
 rename arch/arm/{include/asm/hardware => mach-iop32x}/iop3xx.h (96%)
 rename arch/arm/mach-iop32x/{include/mach => }/iq31244.h (89%)
 rename arch/arm/mach-iop32x/{include/mach => }/iq80321.h (89%)
 create mode 100644 arch/arm/mach-iop32x/irqs.h
 rename arch/arm/mach-iop32x/{include/mach => }/n2100.h (89%)
 rename arch/arm/{plat-iop => mach-iop32x}/pci.c (99%)
 rename arch/arm/{plat-iop => mach-iop32x}/pmu.c (96%)
 rename arch/arm/{plat-iop => mach-iop32x}/restart.c (82%)
 rename arch/arm/{plat-iop => mach-iop32x}/setup.c (95%)
 rename arch/arm/{plat-iop => mach-iop32x}/time.c (97%)
 delete mode 100644 arch/arm/plat-iop/Makefile

diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index d92bc5328df7..075dd2f06d78 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -231,7 +231,6 @@ plat-$(CONFIG_ARCH_EXYNOS)	+= samsung
 plat-$(CONFIG_ARCH_OMAP)	+= omap
 plat-$(CONFIG_ARCH_S3C64XX)	+= samsung
 plat-$(CONFIG_ARCH_S5PV210)	+= samsung
-plat-$(CONFIG_PLAT_IOP)		+= iop
 plat-$(CONFIG_PLAT_ORION)	+= orion
 plat-$(CONFIG_PLAT_PXA)		+= pxa
 plat-$(CONFIG_PLAT_S3C24XX)	+= samsung
diff --git a/arch/arm/mach-iop32x/Makefile b/arch/arm/mach-iop32x/Makefile
index 71d62447d4d5..c8018ef5c6a9 100644
--- a/arch/arm/mach-iop32x/Makefile
+++ b/arch/arm/mach-iop32x/Makefile
@@ -3,7 +3,15 @@
 # Makefile for the linux kernel.
 #
 
-obj-y			:= irq.o
+obj-$(CONFIG_ARCH_IOP32X) += irq.o
+obj-$(CONFIG_ARCH_IOP32X) += i2c.o
+obj-$(CONFIG_ARCH_IOP32X) += pci.o
+obj-$(CONFIG_ARCH_IOP32X) += setup.o
+obj-$(CONFIG_ARCH_IOP32X) += time.o
+obj-$(CONFIG_ARCH_IOP32X) += cp6.o
+obj-$(CONFIG_ARCH_IOP32X) += adma.o
+obj-$(CONFIG_ARCH_IOP32X) += pmu.o
+obj-$(CONFIG_ARCH_IOP32X) += restart.o
 
 obj-$(CONFIG_MACH_GLANTANK) += glantank.o
 obj-$(CONFIG_ARCH_IQ80321) += iq80321.o
diff --git a/arch/arm/plat-iop/adma.c b/arch/arm/mach-iop32x/adma.c
similarity index 98%
rename from arch/arm/plat-iop/adma.c
rename to arch/arm/mach-iop32x/adma.c
index 601cc9c11b07..764bcbff98df 100644
--- a/arch/arm/plat-iop/adma.c
+++ b/arch/arm/mach-iop32x/adma.c
@@ -4,10 +4,12 @@
  * Copyright © 2006, Intel Corporation.
  */
 #include <linux/platform_device.h>
-#include <asm/hardware/iop3xx.h>
 #include <linux/dma-mapping.h>
 #include <linux/platform_data/dma-iop32x.h>
 
+#include "iop3xx.h"
+#include "irqs.h"
+
 #define IRQ_DMA0_EOT IRQ_IOP32X_DMA0_EOT
 #define IRQ_DMA0_EOC IRQ_IOP32X_DMA0_EOC
 #define IRQ_DMA0_ERR IRQ_IOP32X_DMA0_ERR
diff --git a/arch/arm/plat-iop/cp6.c b/arch/arm/mach-iop32x/cp6.c
similarity index 100%
rename from arch/arm/plat-iop/cp6.c
rename to arch/arm/mach-iop32x/cp6.c
diff --git a/arch/arm/mach-iop32x/em7210.c b/arch/arm/mach-iop32x/em7210.c
index 61a1e593f9ec..d43ced3cd4e7 100644
--- a/arch/arm/mach-iop32x/em7210.c
+++ b/arch/arm/mach-iop32x/em7210.c
@@ -21,7 +21,6 @@
 #include <linux/i2c.h>
 #include <linux/gpio.h>
 #include <linux/gpio/machine.h>
-#include <mach/hardware.h>
 #include <linux/io.h>
 #include <linux/irq.h>
 #include <asm/mach/arch.h>
@@ -29,8 +28,10 @@
 #include <asm/mach/pci.h>
 #include <asm/mach/time.h>
 #include <asm/mach-types.h>
-#include <mach/time.h>
+
+#include "hardware.h"
 #include "gpio-iop32x.h"
+#include "irqs.h"
 
 static void __init em7210_timer_init(void)
 {
diff --git a/arch/arm/mach-iop32x/glantank.c b/arch/arm/mach-iop32x/glantank.c
index 5a45d616d9ac..2fe0f77d1f1d 100644
--- a/arch/arm/mach-iop32x/glantank.c
+++ b/arch/arm/mach-iop32x/glantank.c
@@ -22,7 +22,6 @@
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/gpio/machine.h>
-#include <mach/hardware.h>
 #include <asm/irq.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -30,8 +29,10 @@
 #include <asm/mach/time.h>
 #include <asm/mach-types.h>
 #include <asm/page.h>
-#include <mach/time.h>
+
+#include "hardware.h"
 #include "gpio-iop32x.h"
+#include "irqs.h"
 
 /*
  * GLAN Tank timer tick configuration.
diff --git a/arch/arm/mach-iop32x/include/mach/glantank.h b/arch/arm/mach-iop32x/glantank.h
similarity index 78%
rename from arch/arm/mach-iop32x/include/mach/glantank.h
rename to arch/arm/mach-iop32x/glantank.h
index b9df2e4614cf..f38e86b82c3d 100644
--- a/arch/arm/mach-iop32x/include/mach/glantank.h
+++ b/arch/arm/mach-iop32x/glantank.h
@@ -1,7 +1,5 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
- * arch/arm/mach-iop32x/include/mach/glantank.h
- *
  * IO-Data GLAN Tank board registers
  */
 
diff --git a/arch/arm/mach-iop32x/include/mach/hardware.h b/arch/arm/mach-iop32x/hardware.h
similarity index 90%
rename from arch/arm/mach-iop32x/include/mach/hardware.h
rename to arch/arm/mach-iop32x/hardware.h
index 6e5303e60226..43ab4fb8f9b0 100644
--- a/arch/arm/mach-iop32x/include/mach/hardware.h
+++ b/arch/arm/mach-iop32x/hardware.h
@@ -1,8 +1,4 @@
 /* SPDX-License-Identifier: GPL-2.0 */
-/*
- * arch/arm/mach-iop32x/include/mach/hardware.h
- */
-
 #ifndef __HARDWARE_H
 #define __HARDWARE_H
 
@@ -28,7 +24,7 @@ void iop32x_init_irq(void);
 /*
  * Generic chipset bits
  */
-#include "iop32x.h"
+#include "iop3xx.h"
 
 /*
  * Board specific bits
diff --git a/arch/arm/plat-iop/i2c.c b/arch/arm/mach-iop32x/i2c.c
similarity index 96%
rename from arch/arm/plat-iop/i2c.c
rename to arch/arm/mach-iop32x/i2c.c
index 8d5fe349c7cd..dc9f6a14ab1b 100644
--- a/arch/arm/plat-iop/i2c.c
+++ b/arch/arm/mach-iop32x/i2c.c
@@ -22,10 +22,12 @@
 #include <asm/mach/map.h>
 #include <asm/setup.h>
 #include <asm/memory.h>
-#include <mach/hardware.h>
-#include <asm/hardware/iop3xx.h>
 #include <asm/mach/arch.h>
 
+#include "hardware.h"
+#include "iop3xx.h"
+#include "irqs.h"
+
 /*
  * Each of the I2C busses have corresponding GPIO lines, and the driver
  * need to access these directly to drive the bus low at times.
diff --git a/arch/arm/mach-iop32x/include/mach/entry-macro.S b/arch/arm/mach-iop32x/include/mach/entry-macro.S
index ea13ae02d9b1..8e6766d4621e 100644
--- a/arch/arm/mach-iop32x/include/mach/entry-macro.S
+++ b/arch/arm/mach-iop32x/include/mach/entry-macro.S
@@ -7,8 +7,6 @@
  * License version 2. This program is licensed "as is" without any
  * warranty of any kind, whether express or implied.
  */
-#include <mach/iop32x.h>
-
 	.macro get_irqnr_preamble, base, tmp
 	mrc	p15, 0, \tmp, c15, c1, 0
 	orr	\tmp, \tmp, #(1 << 6)
diff --git a/arch/arm/mach-iop32x/include/mach/iop32x.h b/arch/arm/mach-iop32x/include/mach/iop32x.h
deleted file mode 100644
index 84223f86552f..000000000000
--- a/arch/arm/mach-iop32x/include/mach/iop32x.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * arch/arm/mach-iop32x/include/mach/iop32x.h
- *
- * Intel IOP32X Chip definitions
- *
- * Author: Rory Bolt <rorybolt@pacbell.net>
- * Copyright (C) 2002 Rory Bolt
- * Copyright (C) 2004 Intel Corp.
- */
-
-#ifndef __IOP32X_H
-#define __IOP32X_H
-
-/*
- * Peripherals that are shared between the iop32x and iop33x but
- * located at different addresses.
- */
-#define IOP3XX_TIMER_REG(reg)	(IOP3XX_PERIPHERAL_VIRT_BASE + 0x07e0 + (reg))
-
-#include <asm/hardware/iop3xx.h>
-
-/* ATU Parameters
- * set up a 1:1 bus to physical ram relationship
- * w/ physical ram on top of pci in the memory map
- */
-#define IOP32X_MAX_RAM_SIZE            0x40000000UL
-#define IOP3XX_MAX_RAM_SIZE            IOP32X_MAX_RAM_SIZE
-#define IOP3XX_PCI_LOWER_MEM_BA        0x80000000
-
-#endif
diff --git a/arch/arm/mach-iop32x/include/mach/irqs.h b/arch/arm/mach-iop32x/include/mach/irqs.h
index 82b11743e91c..c4e78df428e8 100644
--- a/arch/arm/mach-iop32x/include/mach/irqs.h
+++ b/arch/arm/mach-iop32x/include/mach/irqs.h
@@ -9,39 +9,6 @@
 #ifndef __IRQS_H
 #define __IRQS_H
 
-/*
- * IOP80321 chipset interrupts
- */
-#define IRQ_IOP32X_DMA0_EOT	0
-#define IRQ_IOP32X_DMA0_EOC	1
-#define IRQ_IOP32X_DMA1_EOT	2
-#define IRQ_IOP32X_DMA1_EOC	3
-#define IRQ_IOP32X_AA_EOT	6
-#define IRQ_IOP32X_AA_EOC	7
-#define IRQ_IOP32X_CORE_PMON	8
-#define IRQ_IOP32X_TIMER0	9
-#define IRQ_IOP32X_TIMER1	10
-#define IRQ_IOP32X_I2C_0	11
-#define IRQ_IOP32X_I2C_1	12
-#define IRQ_IOP32X_MESSAGING	13
-#define IRQ_IOP32X_ATU_BIST	14
-#define IRQ_IOP32X_PERFMON	15
-#define IRQ_IOP32X_CORE_PMU	16
-#define IRQ_IOP32X_BIU_ERR	17
-#define IRQ_IOP32X_ATU_ERR	18
-#define IRQ_IOP32X_MCU_ERR	19
-#define IRQ_IOP32X_DMA0_ERR	20
-#define IRQ_IOP32X_DMA1_ERR	21
-#define IRQ_IOP32X_AA_ERR	23
-#define IRQ_IOP32X_MSG_ERR	24
-#define IRQ_IOP32X_SSP		25
-#define IRQ_IOP32X_XINT0	27
-#define IRQ_IOP32X_XINT1	28
-#define IRQ_IOP32X_XINT2	29
-#define IRQ_IOP32X_XINT3	30
-#define IRQ_IOP32X_HPI		31
-
 #define NR_IRQS			32
 
-
 #endif
diff --git a/arch/arm/mach-iop32x/include/mach/time.h b/arch/arm/mach-iop32x/include/mach/time.h
deleted file mode 100644
index d08950ccebc4..000000000000
--- a/arch/arm/mach-iop32x/include/mach/time.h
+++ /dev/null
@@ -1,5 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _IOP32X_TIME_H_
-#define _IOP32X_TIME_H_
-#define IRQ_IOP_TIMER0 IRQ_IOP32X_TIMER0
-#endif
diff --git a/arch/arm/include/asm/hardware/iop3xx.h b/arch/arm/mach-iop32x/iop3xx.h
similarity index 96%
rename from arch/arm/include/asm/hardware/iop3xx.h
rename to arch/arm/mach-iop32x/iop3xx.h
index 3cb6f22f510b..46b4b34a4ad2 100644
--- a/arch/arm/include/asm/hardware/iop3xx.h
+++ b/arch/arm/mach-iop32x/iop3xx.h
@@ -1,7 +1,5 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * arch/arm/include/asm/hardware/iop3xx.h
- *
  * Intel IOP32X and IOP33X register definitions
  *
  * Author: Rory Bolt <rorybolt@pacbell.net>
@@ -12,6 +10,22 @@
 #ifndef __IOP3XX_H
 #define __IOP3XX_H
 
+/*
+ * Peripherals that are shared between the iop32x and iop33x but
+ * located at different addresses.
+ */
+#define IOP3XX_TIMER_REG(reg)	(IOP3XX_PERIPHERAL_VIRT_BASE + 0x07e0 + (reg))
+
+#include "iop3xx.h"
+
+/* ATU Parameters
+ * set up a 1:1 bus to physical ram relationship
+ * w/ physical ram on top of pci in the memory map
+ */
+#define IOP32X_MAX_RAM_SIZE            0x40000000UL
+#define IOP3XX_MAX_RAM_SIZE            IOP32X_MAX_RAM_SIZE
+#define IOP3XX_PCI_LOWER_MEM_BA        0x80000000
+
 /*
  * IOP3XX GPIO handling
  */
diff --git a/arch/arm/mach-iop32x/iq31244.c b/arch/arm/mach-iop32x/iq31244.c
index 8755aa87e591..04a7d389d365 100644
--- a/arch/arm/mach-iop32x/iq31244.c
+++ b/arch/arm/mach-iop32x/iq31244.c
@@ -23,7 +23,6 @@
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/gpio/machine.h>
-#include <mach/hardware.h>
 #include <asm/cputype.h>
 #include <asm/irq.h>
 #include <asm/mach/arch.h>
@@ -33,7 +32,9 @@
 #include <asm/mach-types.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
-#include <mach/time.h>
+
+#include "hardware.h"
+#include "irqs.h"
 #include "gpio-iop32x.h"
 
 /*
diff --git a/arch/arm/mach-iop32x/include/mach/iq31244.h b/arch/arm/mach-iop32x/iq31244.h
similarity index 89%
rename from arch/arm/mach-iop32x/include/mach/iq31244.h
rename to arch/arm/mach-iop32x/iq31244.h
index e62da5da6ed4..a7ac691e48d3 100644
--- a/arch/arm/mach-iop32x/include/mach/iq31244.h
+++ b/arch/arm/mach-iop32x/iq31244.h
@@ -1,7 +1,5 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
- * arch/arm/mach-iop32x/include/mach/iq31244.h
- *
  * Intel IQ31244 evaluation board registers
  */
 
diff --git a/arch/arm/mach-iop32x/iq80321.c b/arch/arm/mach-iop32x/iq80321.c
index e12699d1c540..4bd596d6c9c1 100644
--- a/arch/arm/mach-iop32x/iq80321.c
+++ b/arch/arm/mach-iop32x/iq80321.c
@@ -20,7 +20,6 @@
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/gpio/machine.h>
-#include <mach/hardware.h>
 #include <asm/irq.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -29,7 +28,9 @@
 #include <asm/mach-types.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
-#include <mach/time.h>
+
+#include "hardware.h"
+#include "irqs.h"
 #include "gpio-iop32x.h"
 
 /*
diff --git a/arch/arm/mach-iop32x/include/mach/iq80321.h b/arch/arm/mach-iop32x/iq80321.h
similarity index 89%
rename from arch/arm/mach-iop32x/include/mach/iq80321.h
rename to arch/arm/mach-iop32x/iq80321.h
index faf62c26f6f8..3a5d10626ea6 100644
--- a/arch/arm/mach-iop32x/include/mach/iq80321.h
+++ b/arch/arm/mach-iop32x/iq80321.h
@@ -1,7 +1,5 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
- * arch/arm/mach-iop32x/include/mach/iq80321.h
- *
  * Intel IQ80321 evaluation board registers
  */
 
diff --git a/arch/arm/mach-iop32x/irq.c b/arch/arm/mach-iop32x/irq.c
index 2f5d4ec94f9c..2d48bf1398c1 100644
--- a/arch/arm/mach-iop32x/irq.c
+++ b/arch/arm/mach-iop32x/irq.c
@@ -13,9 +13,10 @@
 #include <linux/list.h>
 #include <asm/mach/irq.h>
 #include <asm/irq.h>
-#include <mach/hardware.h>
 #include <asm/mach-types.h>
 
+#include "hardware.h"
+
 static u32 iop32x_mask;
 
 static void intctl_write(u32 val)
diff --git a/arch/arm/mach-iop32x/irqs.h b/arch/arm/mach-iop32x/irqs.h
new file mode 100644
index 000000000000..69858e4e905d
--- /dev/null
+++ b/arch/arm/mach-iop32x/irqs.h
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Author:	Rory Bolt <rorybolt@pacbell.net>
+ * Copyright:	(C) 2002 Rory Bolt
+ */
+
+#ifndef __IOP32X_IRQS_H
+#define __IOP32X_IRQS_H
+
+/*
+ * IOP80321 chipset interrupts
+ */
+#define IRQ_IOP32X_DMA0_EOT	0
+#define IRQ_IOP32X_DMA0_EOC	1
+#define IRQ_IOP32X_DMA1_EOT	2
+#define IRQ_IOP32X_DMA1_EOC	3
+#define IRQ_IOP32X_AA_EOT	6
+#define IRQ_IOP32X_AA_EOC	7
+#define IRQ_IOP32X_CORE_PMON	8
+#define IRQ_IOP32X_TIMER0	9
+#define IRQ_IOP32X_TIMER1	10
+#define IRQ_IOP32X_I2C_0	11
+#define IRQ_IOP32X_I2C_1	12
+#define IRQ_IOP32X_MESSAGING	13
+#define IRQ_IOP32X_ATU_BIST	14
+#define IRQ_IOP32X_PERFMON	15
+#define IRQ_IOP32X_CORE_PMU	16
+#define IRQ_IOP32X_BIU_ERR	17
+#define IRQ_IOP32X_ATU_ERR	18
+#define IRQ_IOP32X_MCU_ERR	19
+#define IRQ_IOP32X_DMA0_ERR	20
+#define IRQ_IOP32X_DMA1_ERR	21
+#define IRQ_IOP32X_AA_ERR	23
+#define IRQ_IOP32X_MSG_ERR	24
+#define IRQ_IOP32X_SSP		25
+#define IRQ_IOP32X_XINT0	27
+#define IRQ_IOP32X_XINT1	28
+#define IRQ_IOP32X_XINT2	29
+#define IRQ_IOP32X_XINT3	30
+#define IRQ_IOP32X_HPI		31
+
+#endif
diff --git a/arch/arm/mach-iop32x/n2100.c b/arch/arm/mach-iop32x/n2100.c
index 26d76b377e79..5382a93ad0f8 100644
--- a/arch/arm/mach-iop32x/n2100.c
+++ b/arch/arm/mach-iop32x/n2100.c
@@ -28,7 +28,6 @@
 #include <linux/io.h>
 #include <linux/gpio.h>
 #include <linux/gpio/machine.h>
-#include <mach/hardware.h>
 #include <asm/irq.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -37,7 +36,9 @@
 #include <asm/mach-types.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
-#include <mach/time.h>
+
+#include "hardware.h"
+#include "irqs.h"
 #include "gpio-iop32x.h"
 
 /*
diff --git a/arch/arm/mach-iop32x/include/mach/n2100.h b/arch/arm/mach-iop32x/n2100.h
similarity index 89%
rename from arch/arm/mach-iop32x/include/mach/n2100.h
rename to arch/arm/mach-iop32x/n2100.h
index 70bb660b643a..0b97b940d3e7 100644
--- a/arch/arm/mach-iop32x/include/mach/n2100.h
+++ b/arch/arm/mach-iop32x/n2100.h
@@ -1,7 +1,5 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
- * arch/arm/mach-iop32x/include/mach/n2100.h
- *
  * Thecus N2100 board registers
  */
 
diff --git a/arch/arm/plat-iop/pci.c b/arch/arm/mach-iop32x/pci.c
similarity index 99%
rename from arch/arm/plat-iop/pci.c
rename to arch/arm/mach-iop32x/pci.c
index 4c42c95e4bf5..ab0010dc3145 100644
--- a/arch/arm/plat-iop/pci.c
+++ b/arch/arm/mach-iop32x/pci.c
@@ -17,9 +17,9 @@
 #include <linux/io.h>
 #include <asm/irq.h>
 #include <asm/signal.h>
-#include <mach/hardware.h>
 #include <asm/mach/pci.h>
-#include <asm/hardware/iop3xx.h>
+#include "hardware.h"
+#include "iop3xx.h"
 
 // #define DEBUG
 
diff --git a/arch/arm/plat-iop/pmu.c b/arch/arm/mach-iop32x/pmu.c
similarity index 96%
rename from arch/arm/plat-iop/pmu.c
rename to arch/arm/mach-iop32x/pmu.c
index 3834142c17f4..bdbc7a3cb8a3 100644
--- a/arch/arm/plat-iop/pmu.c
+++ b/arch/arm/mach-iop32x/pmu.c
@@ -5,7 +5,7 @@
  */
 
 #include <linux/platform_device.h>
-#include <mach/irqs.h>
+#include "irqs.h"
 
 static struct resource pmu_resource = {
 	.start	= IRQ_IOP32X_CORE_PMU,
diff --git a/arch/arm/plat-iop/restart.c b/arch/arm/mach-iop32x/restart.c
similarity index 82%
rename from arch/arm/plat-iop/restart.c
rename to arch/arm/mach-iop32x/restart.c
index cf6d3d9a2112..3dfa54d3a7a8 100644
--- a/arch/arm/plat-iop/restart.c
+++ b/arch/arm/mach-iop32x/restart.c
@@ -4,9 +4,9 @@
  *
  * Copyright (C) 2001 MontaVista Software, Inc.
  */
-#include <asm/hardware/iop3xx.h>
 #include <asm/system_misc.h>
-#include <mach/hardware.h>
+#include "hardware.h"
+#include "iop3xx.h"
 
 void iop3xx_restart(enum reboot_mode mode, const char *cmd)
 {
diff --git a/arch/arm/plat-iop/setup.c b/arch/arm/mach-iop32x/setup.c
similarity index 95%
rename from arch/arm/plat-iop/setup.c
rename to arch/arm/mach-iop32x/setup.c
index d10e0102d82c..a0a81c28a632 100644
--- a/arch/arm/plat-iop/setup.c
+++ b/arch/arm/mach-iop32x/setup.c
@@ -10,7 +10,7 @@
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <asm/mach/map.h>
-#include <asm/hardware/iop3xx.h>
+#include "iop3xx.h"
 
 /*
  * Standard IO mapping for all IOP3xx based systems.  Note that
diff --git a/arch/arm/plat-iop/time.c b/arch/arm/mach-iop32x/time.c
similarity index 97%
rename from arch/arm/plat-iop/time.c
rename to arch/arm/mach-iop32x/time.c
index f9dd1f50cfe5..18a4df5c1baa 100644
--- a/arch/arm/plat-iop/time.c
+++ b/arch/arm/mach-iop32x/time.c
@@ -19,12 +19,13 @@
 #include <linux/clockchips.h>
 #include <linux/export.h>
 #include <linux/sched_clock.h>
-#include <mach/hardware.h>
 #include <asm/irq.h>
 #include <linux/uaccess.h>
 #include <asm/mach/irq.h>
 #include <asm/mach/time.h>
-#include <mach/time.h>
+
+#include "hardware.h"
+#include "irqs.h"
 
 /*
  * Minimum clocksource/clockevent timer range in seconds
@@ -167,7 +168,7 @@ void __init iop_init_time(unsigned long tick_rate)
 	 */
 	write_tmr0(timer_ctl & ~IOP_TMR_EN);
 	write_tisr(1);
-	setup_irq(IRQ_IOP_TIMER0, &iop_timer_irq);
+	setup_irq(IRQ_IOP32X_TIMER0, &iop_timer_irq);
 	iop_clockevent.cpumask = cpumask_of(0);
 	clockevents_config_and_register(&iop_clockevent, tick_rate,
 					0xf, 0xfffffffe);
diff --git a/arch/arm/plat-iop/Makefile b/arch/arm/plat-iop/Makefile
deleted file mode 100644
index 86e354b9065d..000000000000
--- a/arch/arm/plat-iop/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-#
-# Makefile for the linux kernel.
-#
-
-# IOP32X
-obj-$(CONFIG_ARCH_IOP32X) += i2c.o
-obj-$(CONFIG_ARCH_IOP32X) += pci.o
-obj-$(CONFIG_ARCH_IOP32X) += setup.o
-obj-$(CONFIG_ARCH_IOP32X) += time.o
-obj-$(CONFIG_ARCH_IOP32X) += cp6.o
-obj-$(CONFIG_ARCH_IOP32X) += adma.o
-obj-$(CONFIG_ARCH_IOP32X) += pmu.o
-obj-$(CONFIG_ARCH_IOP32X) += restart.o
-- 
2.20.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH 6/7] ARM: iop32x: make mach/uncompress.h independent of mach/hardware.h
From: Arnd Bergmann @ 2019-08-09 16:33 UTC (permalink / raw)
  To: soc
  Cc: Arnd Bergmann, linux-gpio, Linus Walleij, Russell King,
	linux-kernel, Bartosz Golaszewski, Vinod Koul, linux-i2c,
	dmaengine, Dan Williams, linux-arm-kernel
In-Reply-To: <20190809163334.489360-1-arnd@arndb.de>

All supported uarts use the same address: IQ80321_UART and IQ31244_UART
are both defined to the default value of 0xfe800000. By using that as
the address unconditionally, all dependencies on other machine headers
can be avoided.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 arch/arm/mach-iop32x/include/mach/uncompress.h | 18 ++----------------
 1 file changed, 2 insertions(+), 16 deletions(-)

diff --git a/arch/arm/mach-iop32x/include/mach/uncompress.h b/arch/arm/mach-iop32x/include/mach/uncompress.h
index ed4ac3e28fa1..c8548875d942 100644
--- a/arch/arm/mach-iop32x/include/mach/uncompress.h
+++ b/arch/arm/mach-iop32x/include/mach/uncompress.h
@@ -6,9 +6,8 @@
 #include <asm/types.h>
 #include <asm/mach-types.h>
 #include <linux/serial_reg.h>
-#include <mach/hardware.h>
 
-volatile u8 *uart_base;
+#define uart_base ((volatile u8 *)0xfe800000)
 
 #define TX_DONE		(UART_LSR_TEMT | UART_LSR_THRE)
 
@@ -23,17 +22,4 @@ static inline void flush(void)
 {
 }
 
-static __inline__ void __arch_decomp_setup(unsigned long arch_id)
-{
-	if (machine_is_iq80321())
-		uart_base = (volatile u8 *)IQ80321_UART;
-	else if (machine_is_iq31244() || machine_is_em7210())
-		uart_base = (volatile u8 *)IQ31244_UART;
-	else
-		uart_base = (volatile u8 *)0xfe800000;
-}
-
-/*
- * nothing to do
- */
-#define arch_decomp_setup()	__arch_decomp_setup(arch_id)
+#define arch_decomp_setup() do { } while (0)
-- 
2.20.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH 4/7] dma: iop-adma: allow building without platform headers
From: Arnd Bergmann @ 2019-08-09 16:33 UTC (permalink / raw)
  To: soc
  Cc: Arnd Bergmann, linux-gpio, Linus Walleij, Russell King,
	linux-kernel, Bartosz Golaszewski, Vinod Koul, linux-i2c,
	dmaengine, Dan Williams, linux-arm-kernel
In-Reply-To: <20190809163334.489360-1-arnd@arndb.de>

Now that iop3xx and iop13xx are gone, the iop-adma driver no
longer needs to deal with incompatible register layout defined
in machine specific header files.

Move the iop32x specific definitions into drivers/dma/iop-adma.h
and the platform_data into include/linux/platform_data/dma-iop32x.h,
and change the machine code to no longer reference those.

The DMA0_ID/DMA1_ID/AAU_ID macros are required as part of the
platform data interface and still need to be visible, so move
those from one header to the other.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 arch/arm/mach-iop32x/include/mach/adma.h                   | 6 ------
 arch/arm/plat-iop/adma.c                                   | 3 +--
 drivers/dma/Kconfig                                        | 4 ++--
 drivers/dma/iop-adma.c                                     | 3 +--
 .../asm/hardware/iop3xx-adma.h => drivers/dma/iop-adma.h   | 7 +------
 .../iop_adma.h => include/linux/platform_data/dma-iop32x.h | 4 ++++
 6 files changed, 9 insertions(+), 18 deletions(-)
 delete mode 100644 arch/arm/mach-iop32x/include/mach/adma.h
 rename arch/arm/include/asm/hardware/iop3xx-adma.h => drivers/dma/iop-adma.h (99%)
 rename arch/arm/include/asm/hardware/iop_adma.h => include/linux/platform_data/dma-iop32x.h (98%)

diff --git a/arch/arm/mach-iop32x/include/mach/adma.h b/arch/arm/mach-iop32x/include/mach/adma.h
deleted file mode 100644
index 2b20063123ad..000000000000
--- a/arch/arm/mach-iop32x/include/mach/adma.h
+++ /dev/null
@@ -1,6 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef IOP32X_ADMA_H
-#define IOP32X_ADMA_H
-#include <asm/hardware/iop3xx-adma.h>
-#endif
-
diff --git a/arch/arm/plat-iop/adma.c b/arch/arm/plat-iop/adma.c
index 368496471e60..601cc9c11b07 100644
--- a/arch/arm/plat-iop/adma.c
+++ b/arch/arm/plat-iop/adma.c
@@ -6,8 +6,7 @@
 #include <linux/platform_device.h>
 #include <asm/hardware/iop3xx.h>
 #include <linux/dma-mapping.h>
-#include <mach/adma.h>
-#include <asm/hardware/iop_adma.h>
+#include <linux/platform_data/dma-iop32x.h>
 
 #define IRQ_DMA0_EOT IRQ_IOP32X_DMA0_EOT
 #define IRQ_DMA0_EOC IRQ_IOP32X_DMA0_EOC
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index cc84863bc52b..7c511e3db4c8 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -294,8 +294,8 @@ config INTEL_IOATDMA
 	  If unsure, say N.
 
 config INTEL_IOP_ADMA
-	tristate "Intel IOP ADMA support"
-	depends on ARCH_IOP32X
+	tristate "Intel IOP32x ADMA support"
+	depends on ARCH_IOP32X || COMPILE_TEST
 	select DMA_ENGINE
 	select ASYNC_TX_ENABLE_CHANNEL_SWITCH
 	help
diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c
index aebdd671651a..03f4a588cf7f 100644
--- a/drivers/dma/iop-adma.c
+++ b/drivers/dma/iop-adma.c
@@ -22,8 +22,7 @@
 #include <linux/raid/pq.h>
 #include <linux/slab.h>
 
-#include <mach/adma.h>
-
+#include "iop-adma.h"
 #include "dmaengine.h"
 
 #define to_iop_adma_chan(chan) container_of(chan, struct iop_adma_chan, common)
diff --git a/arch/arm/include/asm/hardware/iop3xx-adma.h b/drivers/dma/iop-adma.h
similarity index 99%
rename from arch/arm/include/asm/hardware/iop3xx-adma.h
rename to drivers/dma/iop-adma.h
index 6d998df17efd..c499c9578f00 100644
--- a/arch/arm/include/asm/hardware/iop3xx-adma.h
+++ b/drivers/dma/iop-adma.h
@@ -6,8 +6,7 @@
 #define _ADMA_H
 #include <linux/types.h>
 #include <linux/io.h>
-#include <mach/hardware.h>
-#include <asm/hardware/iop_adma.h>
+#include <linux/platform_data/dma-iop32x.h>
 
 /* Memory copy units */
 #define DMA_CCR(chan)		(chan->mmr_base + 0x0)
@@ -34,10 +33,6 @@
 #define AAU_EDCR1_IDX	17
 #define AAU_EDCR2_IDX	26
 
-#define DMA0_ID 0
-#define DMA1_ID 1
-#define AAU_ID 2
-
 struct iop3xx_aau_desc_ctrl {
 	unsigned int int_en:1;
 	unsigned int blk1_cmd_ctrl:3;
diff --git a/arch/arm/include/asm/hardware/iop_adma.h b/include/linux/platform_data/dma-iop32x.h
similarity index 98%
rename from arch/arm/include/asm/hardware/iop_adma.h
rename to include/linux/platform_data/dma-iop32x.h
index bcedbab90ac0..ac83cff89549 100644
--- a/arch/arm/include/asm/hardware/iop_adma.h
+++ b/include/linux/platform_data/dma-iop32x.h
@@ -17,6 +17,10 @@
 #endif
 #define iop_paranoia(x) BUG_ON(IOP_PARANOIA && (x))
 
+#define DMA0_ID 0
+#define DMA1_ID 1
+#define AAU_ID 2
+
 /**
  * struct iop_adma_device - internal representation of an ADMA device
  * @pdev: Platform device
-- 
2.20.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH 5/7] ARM: xscale: fix multi-cpu compilation
From: Arnd Bergmann @ 2019-08-09 16:33 UTC (permalink / raw)
  To: soc
  Cc: Arnd Bergmann, linux-gpio, Linus Walleij, Russell King,
	linux-kernel, Bartosz Golaszewski, Vinod Koul, linux-i2c,
	dmaengine, Dan Williams, linux-arm-kernel
In-Reply-To: <20190809163334.489360-1-arnd@arndb.de>

Building a combined ARMv4+XScale kernel produces these
and other build failures:

/tmp/copypage-xscale-3aa821.s: Assembler messages:
/tmp/copypage-xscale-3aa821.s:167: Error: selected processor does not support `pld [r7,#0]' in ARM mode
/tmp/copypage-xscale-3aa821.s:168: Error: selected processor does not support `pld [r7,#32]' in ARM mode
/tmp/copypage-xscale-3aa821.s:169: Error: selected processor does not support `pld [r1,#0]' in ARM mode
/tmp/copypage-xscale-3aa821.s:170: Error: selected processor does not support `pld [r1,#32]' in ARM mode
/tmp/copypage-xscale-3aa821.s:171: Error: selected processor does not support `pld [r7,#64]' in ARM mode
/tmp/copypage-xscale-3aa821.s:176: Error: selected processor does not support `ldrd r4,r5,[r7],#8' in ARM mode
/tmp/copypage-xscale-3aa821.s:180: Error: selected processor does not support `strd r4,r5,[r1],#8' in ARM mode

Add an explict .arch armv5 in the inline assembly to allow the ARMv5
specific instructions regardless of the compiler -march= target.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 arch/arm/mm/copypage-xscale.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mm/copypage-xscale.c b/arch/arm/mm/copypage-xscale.c
index 61d834157bc0..382e1c2855e8 100644
--- a/arch/arm/mm/copypage-xscale.c
+++ b/arch/arm/mm/copypage-xscale.c
@@ -42,6 +42,7 @@ static void mc_copy_user_page(void *from, void *to)
 	 * when prefetching destination as well.  (NP)
 	 */
 	asm volatile ("\
+.arch xscale					\n\
 	pld	[%0, #0]			\n\
 	pld	[%0, #32]			\n\
 	pld	[%1, #0]			\n\
@@ -106,8 +107,9 @@ void
 xscale_mc_clear_user_highpage(struct page *page, unsigned long vaddr)
 {
 	void *ptr, *kaddr = kmap_atomic(page);
-	asm volatile(
-	"mov	r1, %2				\n\
+	asm volatile("\
+.arch xscale					\n\
+	mov	r1, %2				\n\
 	mov	r2, #0				\n\
 	mov	r3, #0				\n\
 1:	mov	ip, %0				\n\
-- 
2.20.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH 3/7] dma: iop-adma: use correct printk format strings
From: Arnd Bergmann @ 2019-08-09 16:33 UTC (permalink / raw)
  To: soc
  Cc: Arnd Bergmann, linux-gpio, Linus Walleij, Russell King,
	linux-kernel, Bartosz Golaszewski, Vinod Koul, linux-i2c,
	dmaengine, Dan Williams, linux-arm-kernel
In-Reply-To: <20190809163334.489360-1-arnd@arndb.de>

When compile-testing on other architectures, we get lots of warnings
about incorrect format strings, like:

   drivers/dma/iop-adma.c: In function 'iop_adma_alloc_slots':
   drivers/dma/iop-adma.c:307:6: warning: format '%x' expects argument of type 'unsigned int', but argument 6 has type 'dma_addr_t {aka long long unsigned int}' [-Wformat=]

   drivers/dma/iop-adma.c: In function 'iop_adma_prep_dma_memcpy':
>> drivers/dma/iop-adma.c:518:40: warning: format '%u' expects argument of type 'unsigned int', but argument 5 has type 'size_t {aka long unsigned int}' [-Wformat=]

Use %zu for printing size_t as required, and cast the dma_addr_t
arguments to 'u64' for printing with %llx. Ideally this should use
the %pad format string, but that requires an lvalue argument that
doesn't work here.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 drivers/dma/iop-adma.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c
index 7857b54770d1..aebdd671651a 100644
--- a/drivers/dma/iop-adma.c
+++ b/drivers/dma/iop-adma.c
@@ -117,9 +117,9 @@ static void __iop_adma_slot_cleanup(struct iop_adma_chan *iop_chan)
 	list_for_each_entry_safe(iter, _iter, &iop_chan->chain,
 					chain_node) {
 		pr_debug("\tcookie: %d slot: %d busy: %d "
-			"this_desc: %#x next_desc: %#x ack: %d\n",
+			"this_desc: %#x next_desc: %#llx ack: %d\n",
 			iter->async_tx.cookie, iter->idx, busy,
-			iter->async_tx.phys, iop_desc_get_next_desc(iter),
+			iter->async_tx.phys, (u64)iop_desc_get_next_desc(iter),
 			async_tx_test_ack(&iter->async_tx));
 		prefetch(_iter);
 		prefetch(&_iter->async_tx);
@@ -307,9 +307,9 @@ iop_adma_alloc_slots(struct iop_adma_chan *iop_chan, int num_slots,
 				int i;
 				dev_dbg(iop_chan->device->common.dev,
 					"allocated slot: %d "
-					"(desc %p phys: %#x) slots_per_op %d\n",
+					"(desc %p phys: %#llx) slots_per_op %d\n",
 					iter->idx, iter->hw_desc,
-					iter->async_tx.phys, slots_per_op);
+					(u64)iter->async_tx.phys, slots_per_op);
 
 				/* pre-ack all but the last descriptor */
 				if (num_slots != slots_per_op)
@@ -517,7 +517,7 @@ iop_adma_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dma_dest,
 		return NULL;
 	BUG_ON(len > IOP_ADMA_MAX_BYTE_COUNT);
 
-	dev_dbg(iop_chan->device->common.dev, "%s len: %u\n",
+	dev_dbg(iop_chan->device->common.dev, "%s len: %zu\n",
 		__func__, len);
 
 	spin_lock_bh(&iop_chan->lock);
@@ -550,7 +550,7 @@ iop_adma_prep_dma_xor(struct dma_chan *chan, dma_addr_t dma_dest,
 	BUG_ON(len > IOP_ADMA_XOR_MAX_BYTE_COUNT);
 
 	dev_dbg(iop_chan->device->common.dev,
-		"%s src_cnt: %d len: %u flags: %lx\n",
+		"%s src_cnt: %d len: %zu flags: %lx\n",
 		__func__, src_cnt, len, flags);
 
 	spin_lock_bh(&iop_chan->lock);
@@ -583,7 +583,7 @@ iop_adma_prep_dma_xor_val(struct dma_chan *chan, dma_addr_t *dma_src,
 	if (unlikely(!len))
 		return NULL;
 
-	dev_dbg(iop_chan->device->common.dev, "%s src_cnt: %d len: %u\n",
+	dev_dbg(iop_chan->device->common.dev, "%s src_cnt: %d len: %zu\n",
 		__func__, src_cnt, len);
 
 	spin_lock_bh(&iop_chan->lock);
@@ -621,7 +621,7 @@ iop_adma_prep_dma_pq(struct dma_chan *chan, dma_addr_t *dst, dma_addr_t *src,
 	BUG_ON(len > IOP_ADMA_XOR_MAX_BYTE_COUNT);
 
 	dev_dbg(iop_chan->device->common.dev,
-		"%s src_cnt: %d len: %u flags: %lx\n",
+		"%s src_cnt: %d len: %zu flags: %lx\n",
 		__func__, src_cnt, len, flags);
 
 	if (dmaf_p_disabled_continue(flags))
@@ -684,7 +684,7 @@ iop_adma_prep_dma_pq_val(struct dma_chan *chan, dma_addr_t *pq, dma_addr_t *src,
 		return NULL;
 	BUG_ON(len > IOP_ADMA_XOR_MAX_BYTE_COUNT);
 
-	dev_dbg(iop_chan->device->common.dev, "%s src_cnt: %d len: %u\n",
+	dev_dbg(iop_chan->device->common.dev, "%s src_cnt: %d len: %zu\n",
 		__func__, src_cnt, len);
 
 	spin_lock_bh(&iop_chan->lock);
-- 
2.20.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH 2/7] dma: iop-adma: include prefetch.h
From: Arnd Bergmann @ 2019-08-09 16:33 UTC (permalink / raw)
  To: soc
  Cc: kbuild test robot, Arnd Bergmann, linux-gpio, Linus Walleij,
	Russell King, linux-kernel, Bartosz Golaszewski, Vinod Koul,
	linux-i2c, dmaengine, Dan Williams, linux-arm-kernel
In-Reply-To: <20190809163334.489360-1-arnd@arndb.de>

Compile-testing this driver fails on m68k without the
extra header inclusion.

Reported-by: kbuild test robot <lkp@intel.com>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 drivers/dma/iop-adma.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c
index c6c0143670d9..7857b54770d1 100644
--- a/drivers/dma/iop-adma.c
+++ b/drivers/dma/iop-adma.c
@@ -16,6 +16,7 @@
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
+#include <linux/prefetch.h>
 #include <linux/memory.h>
 #include <linux/ioport.h>
 #include <linux/raid/pq.h>
-- 
2.20.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* Re: [PATCH v2 09/13] net: lpc-enet: fix printk format strings
From: Joe Perches @ 2019-08-09 16:30 UTC (permalink / raw)
  To: Arnd Bergmann, soc
  Cc: kbuild test robot, netdev, linux-kernel, Vladimir Zapolskiy,
	Sylvain Lemieux, David S. Miller, linux-arm-kernel
In-Reply-To: <20190809144043.476786-10-arnd@arndb.de>

On Fri, 2019-08-09 at 16:40 +0200, Arnd Bergmann wrote:
> compile-testing this driver on other architectures showed
> multiple warnings:
> 
>   drivers/net/ethernet/nxp/lpc_eth.c: In function 'lpc_eth_drv_probe':
>   drivers/net/ethernet/nxp/lpc_eth.c:1337:19: warning: format '%d' expects argument of type 'int', but argument 4 has type 'resource_size_t {aka long long unsigned int}' [-Wformat=]
> 
>   drivers/net/ethernet/nxp/lpc_eth.c:1342:19: warning: format '%x' expects argument of type 'unsigned int', but argument 4 has type 'dma_addr_t {aka long long unsigned int}' [-Wformat=]
> 
> Use format strings that work on all architectures.
[]
> diff --git a/drivers/net/ethernet/nxp/lpc_eth.c b/drivers/net/ethernet/nxp/lpc_eth.c
[]
> @@ -1333,13 +1333,14 @@ static int lpc_eth_drv_probe(struct platform_device *pdev)
>  	pldat->dma_buff_base_p = dma_handle;
>  
>  	netdev_dbg(ndev, "IO address space     :%pR\n", res);
> -	netdev_dbg(ndev, "IO address size      :%d\n", resource_size(res));
> +	netdev_dbg(ndev, "IO address size      :%zd\n",
> +			(size_t)resource_size(res));

Ideally all these would use %zu not %zd



_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH 0/7] ARM: preparation for multiplatform iop32x
From: Arnd Bergmann @ 2019-08-09 16:29 UTC (permalink / raw)
  To: soc
  Cc: Dave Jiang, Arnd Bergmann, Linus Walleij, Russell King,
	linux-arm-kernel, Dan Williams, Imre Kaloz, Martin Michlmayr,
	Lennert Buytenhek

I'm looking into converting some of the remaining ARMv5
platforms in arch/arm/ to work together in a single kernel
binary.

IOP32x seems to be a fairly easy target for multiplatform
by itself, but the way the plat-iop code interacts with
three generations of the code, and how the dma-adma driver
is configured at compile-time for each version gets in the
way.

I considered adding more indirection layers for those two,
but removing iop33x and iop13xx is much easier in comparison,
so this is the first approach I'm posting.

If we conclude that iop33x and iop13xx are indeed not used
any more, the remaining patches in this series are
straightforward. The actual multiplatform conversion also
requires changes to the irqchip driver that are not completely
mechanic, and we can discuss those after deciding what to do
with the first set.

Adding a few people to Cc that historically worked on IOP.

      Arnd

Arnd Bergmann (7):
  [RFC] ARM: remove Intel iop33x and iop13xx support
  dma: iop-adma: include prefetch.h
  dma: iop-adma: use correct printk format strings
  dma: iop-adma: allow building without platform headers
  ARM: xscale: fix multi-cpu compilation
  ARM: iop32x: make mach/uncompress.h independent of mach/hardware.h
  ARM: iop32x: merge everything into mach-iop32x/

 arch/arm/Kconfig                              |   30 -
 arch/arm/Kconfig.debug                        |    8 +-
 arch/arm/Makefile                             |    3 -
 arch/arm/configs/iop13xx_defconfig            |  118 --
 arch/arm/configs/iop33x_defconfig             |   85 --
 arch/arm/mach-iop13xx/Kconfig                 |   21 -
 arch/arm/mach-iop13xx/Makefile                |    9 -
 arch/arm/mach-iop13xx/Makefile.boot           |    4 -
 arch/arm/mach-iop13xx/include/mach/adma.h     |  608 ---------
 .../mach-iop13xx/include/mach/entry-macro.S   |   29 -
 arch/arm/mach-iop13xx/include/mach/hardware.h |   22 -
 arch/arm/mach-iop13xx/include/mach/iop13xx.h  |  508 --------
 arch/arm/mach-iop13xx/include/mach/iq81340.h  |   29 -
 arch/arm/mach-iop13xx/include/mach/irqs.h     |  195 ---
 arch/arm/mach-iop13xx/include/mach/time.h     |  127 --
 .../mach-iop13xx/include/mach/uncompress.h    |   23 -
 arch/arm/mach-iop13xx/io.c                    |   77 --
 arch/arm/mach-iop13xx/iq81340mc.c             |   84 --
 arch/arm/mach-iop13xx/iq81340sc.c             |   86 --
 arch/arm/mach-iop13xx/irq.c                   |  227 ----
 arch/arm/mach-iop13xx/msi.c                   |  152 ---
 arch/arm/mach-iop13xx/msi.h                   |   12 -
 arch/arm/mach-iop13xx/pci.c                   | 1115 -----------------
 arch/arm/mach-iop13xx/pci.h                   |   66 -
 arch/arm/mach-iop13xx/setup.c                 |  595 ---------
 arch/arm/mach-iop13xx/tpmi.c                  |  244 ----
 arch/arm/mach-iop32x/Makefile                 |   10 +-
 arch/arm/{plat-iop => mach-iop32x}/adma.c     |   39 +-
 arch/arm/{plat-iop => mach-iop32x}/cp6.c      |    0
 arch/arm/mach-iop32x/em7210.c                 |    5 +-
 arch/arm/mach-iop32x/glantank.c               |    5 +-
 .../mach-iop32x/{include/mach => }/glantank.h |    2 -
 .../mach-iop32x/{include/mach => }/hardware.h |    6 +-
 arch/arm/{plat-iop => mach-iop32x}/i2c.c      |   21 +-
 arch/arm/mach-iop32x/include/mach/adma.h      |    6 -
 .../mach-iop32x/include/mach/entry-macro.S    |    2 -
 arch/arm/mach-iop32x/include/mach/iop32x.h    |   31 -
 arch/arm/mach-iop32x/include/mach/irqs.h      |   33 -
 arch/arm/mach-iop32x/include/mach/time.h      |    5 -
 .../arm/mach-iop32x/include/mach/uncompress.h |   18 +-
 .../asm/hardware => mach-iop32x}/iop3xx.h     |   18 +-
 arch/arm/mach-iop32x/iq31244.c                |    5 +-
 .../mach-iop32x/{include/mach => }/iq31244.h  |    2 -
 arch/arm/mach-iop32x/iq80321.c                |    5 +-
 .../mach-iop32x/{include/mach => }/iq80321.h  |    2 -
 arch/arm/mach-iop32x/irq.c                    |    3 +-
 arch/arm/mach-iop32x/irqs.h                   |   42 +
 arch/arm/mach-iop32x/n2100.c                  |    5 +-
 .../mach-iop32x/{include/mach => }/n2100.h    |    2 -
 arch/arm/{plat-iop => mach-iop32x}/pci.c      |    4 +-
 arch/arm/{plat-iop => mach-iop32x}/pmu.c      |    8 +-
 arch/arm/{plat-iop => mach-iop32x}/restart.c  |    4 +-
 arch/arm/{plat-iop => mach-iop32x}/setup.c    |    2 +-
 arch/arm/{plat-iop => mach-iop32x}/time.c     |    7 +-
 arch/arm/mach-iop33x/Kconfig                  |   22 -
 arch/arm/mach-iop33x/Makefile                 |    9 -
 arch/arm/mach-iop33x/Makefile.boot            |    4 -
 arch/arm/mach-iop33x/include/mach/adma.h      |    6 -
 .../mach-iop33x/include/mach/entry-macro.S    |   34 -
 arch/arm/mach-iop33x/include/mach/hardware.h  |   44 -
 arch/arm/mach-iop33x/include/mach/iop33x.h    |   37 -
 arch/arm/mach-iop33x/include/mach/iq80331.h   |   17 -
 arch/arm/mach-iop33x/include/mach/iq80332.h   |   17 -
 arch/arm/mach-iop33x/include/mach/irqs.h      |   57 -
 arch/arm/mach-iop33x/include/mach/time.h      |    5 -
 .../arm/mach-iop33x/include/mach/uncompress.h |   37 -
 arch/arm/mach-iop33x/iq80331.c                |  148 ---
 arch/arm/mach-iop33x/iq80332.c                |  148 ---
 arch/arm/mach-iop33x/irq.c                    |  115 --
 arch/arm/mach-iop33x/uart.c                   |  100 --
 arch/arm/mm/copypage-xscale.c                 |    6 +-
 arch/arm/plat-iop/Makefile                    |   28 -
 drivers/dma/Kconfig                           |    4 +-
 drivers/dma/iop-adma.c                        |   22 +-
 .../iop3xx-adma.h => drivers/dma/iop-adma.h   |    7 +-
 drivers/gpio/Kconfig                          |    2 +-
 drivers/i2c/busses/Kconfig                    |    2 +-
 .../linux/platform_data/dma-iop32x.h          |    4 +
 78 files changed, 134 insertions(+), 5510 deletions(-)
 delete mode 100644 arch/arm/configs/iop13xx_defconfig
 delete mode 100644 arch/arm/configs/iop33x_defconfig
 delete mode 100644 arch/arm/mach-iop13xx/Kconfig
 delete mode 100644 arch/arm/mach-iop13xx/Makefile
 delete mode 100644 arch/arm/mach-iop13xx/Makefile.boot
 delete mode 100644 arch/arm/mach-iop13xx/include/mach/adma.h
 delete mode 100644 arch/arm/mach-iop13xx/include/mach/entry-macro.S
 delete mode 100644 arch/arm/mach-iop13xx/include/mach/hardware.h
 delete mode 100644 arch/arm/mach-iop13xx/include/mach/iop13xx.h
 delete mode 100644 arch/arm/mach-iop13xx/include/mach/iq81340.h
 delete mode 100644 arch/arm/mach-iop13xx/include/mach/irqs.h
 delete mode 100644 arch/arm/mach-iop13xx/include/mach/time.h
 delete mode 100644 arch/arm/mach-iop13xx/include/mach/uncompress.h
 delete mode 100644 arch/arm/mach-iop13xx/io.c
 delete mode 100644 arch/arm/mach-iop13xx/iq81340mc.c
 delete mode 100644 arch/arm/mach-iop13xx/iq81340sc.c
 delete mode 100644 arch/arm/mach-iop13xx/irq.c
 delete mode 100644 arch/arm/mach-iop13xx/msi.c
 delete mode 100644 arch/arm/mach-iop13xx/msi.h
 delete mode 100644 arch/arm/mach-iop13xx/pci.c
 delete mode 100644 arch/arm/mach-iop13xx/pci.h
 delete mode 100644 arch/arm/mach-iop13xx/setup.c
 delete mode 100644 arch/arm/mach-iop13xx/tpmi.c
 rename arch/arm/{plat-iop => mach-iop32x}/adma.c (75%)
 rename arch/arm/{plat-iop => mach-iop32x}/cp6.c (100%)
 rename arch/arm/mach-iop32x/{include/mach => }/glantank.h (78%)
 rename arch/arm/mach-iop32x/{include/mach => }/hardware.h (90%)
 rename arch/arm/{plat-iop => mach-iop32x}/i2c.c (81%)
 delete mode 100644 arch/arm/mach-iop32x/include/mach/adma.h
 delete mode 100644 arch/arm/mach-iop32x/include/mach/iop32x.h
 delete mode 100644 arch/arm/mach-iop32x/include/mach/time.h
 rename arch/arm/{include/asm/hardware => mach-iop32x}/iop3xx.h (96%)
 rename arch/arm/mach-iop32x/{include/mach => }/iq31244.h (89%)
 rename arch/arm/mach-iop32x/{include/mach => }/iq80321.h (89%)
 create mode 100644 arch/arm/mach-iop32x/irqs.h
 rename arch/arm/mach-iop32x/{include/mach => }/n2100.h (89%)
 rename arch/arm/{plat-iop => mach-iop32x}/pci.c (99%)
 rename arch/arm/{plat-iop => mach-iop32x}/pmu.c (79%)
 rename arch/arm/{plat-iop => mach-iop32x}/restart.c (82%)
 rename arch/arm/{plat-iop => mach-iop32x}/setup.c (95%)
 rename arch/arm/{plat-iop => mach-iop32x}/time.c (97%)
 delete mode 100644 arch/arm/mach-iop33x/Kconfig
 delete mode 100644 arch/arm/mach-iop33x/Makefile
 delete mode 100644 arch/arm/mach-iop33x/Makefile.boot
 delete mode 100644 arch/arm/mach-iop33x/include/mach/adma.h
 delete mode 100644 arch/arm/mach-iop33x/include/mach/entry-macro.S
 delete mode 100644 arch/arm/mach-iop33x/include/mach/hardware.h
 delete mode 100644 arch/arm/mach-iop33x/include/mach/iop33x.h
 delete mode 100644 arch/arm/mach-iop33x/include/mach/iq80331.h
 delete mode 100644 arch/arm/mach-iop33x/include/mach/iq80332.h
 delete mode 100644 arch/arm/mach-iop33x/include/mach/irqs.h
 delete mode 100644 arch/arm/mach-iop33x/include/mach/time.h
 delete mode 100644 arch/arm/mach-iop33x/include/mach/uncompress.h
 delete mode 100644 arch/arm/mach-iop33x/iq80331.c
 delete mode 100644 arch/arm/mach-iop33x/iq80332.c
 delete mode 100644 arch/arm/mach-iop33x/irq.c
 delete mode 100644 arch/arm/mach-iop33x/uart.c
 delete mode 100644 arch/arm/plat-iop/Makefile
 rename arch/arm/include/asm/hardware/iop3xx-adma.h => drivers/dma/iop-adma.h (99%)
 rename arch/arm/include/asm/hardware/iop_adma.h => include/linux/platform_data/dma-iop32x.h (98%)

-- 
2.20.0

Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Dave Jiang <dave.jiang@intel.com>
Cc: Russell King <linux@armlinux.org.uk>
Cc: Lennert Buytenhek <buytenh@wantstofly.org>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Martin Michlmayr <tbm@cyrius.com>
Cc: Imre Kaloz <kaloz@openwrt.org>
Cc: linux-arm-kernel@lists.infradead.org

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH 0/2] Minor cleanups/improvements in rpmsg-client-sample
From: Suman Anna @ 2019-08-09 16:27 UTC (permalink / raw)
  To: Bjorn Andersson, Ohad Ben-Cohen
  Cc: linux-remoteproc, linux-kernel, linux-arm-kernel

Hi Bjorn,

The following are minor cleanup/improvement patches to the rpmsg_client_sample.
The first patch is new, and the second patch is a repost. Appreciate it if you
can pick these up for 5.4 merge window.

regards
Suman

Suman Anna (2):
  samples/rpmsg: Replace print_hex_dump() with print_hex_dump_debug()
  samples/rpmsg: Introduce a module parameter for message count

 samples/rpmsg/rpmsg_client_sample.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

-- 
2.22.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH 2/2] samples/rpmsg: Introduce a module parameter for message count
From: Suman Anna @ 2019-08-09 16:27 UTC (permalink / raw)
  To: Bjorn Andersson, Ohad Ben-Cohen
  Cc: linux-remoteproc, linux-kernel, linux-arm-kernel
In-Reply-To: <20190809162710.823-1-s-anna@ti.com>

The current rpmsg_client_sample uses a fixed number of messages to
be sent to each instance. This is currently set at 100. Introduce
an optional module parameter 'count' so that the number of messages
to be exchanged can be made flexible.

Signed-off-by: Suman Anna <s-anna@ti.com>
---
 samples/rpmsg/rpmsg_client_sample.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/samples/rpmsg/rpmsg_client_sample.c b/samples/rpmsg/rpmsg_client_sample.c
index b9a99e621a5c..ae5081662283 100644
--- a/samples/rpmsg/rpmsg_client_sample.c
+++ b/samples/rpmsg/rpmsg_client_sample.c
@@ -14,7 +14,9 @@
 #include <linux/rpmsg.h>
 
 #define MSG		"hello world!"
-#define MSG_LIMIT	100
+
+static int count = 100;
+module_param(count, int, 0644);
 
 struct instance_data {
 	int rx_count;
@@ -33,7 +35,7 @@ static int rpmsg_sample_cb(struct rpmsg_device *rpdev, void *data, int len,
 			     true);
 
 	/* samples should not live forever */
-	if (idata->rx_count >= MSG_LIMIT) {
+	if (idata->rx_count >= count) {
 		dev_info(&rpdev->dev, "goodbye!\n");
 		return 0;
 	}
-- 
2.22.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH 1/2] samples/rpmsg: Replace print_hex_dump() with print_hex_dump_debug()
From: Suman Anna @ 2019-08-09 16:27 UTC (permalink / raw)
  To: Bjorn Andersson, Ohad Ben-Cohen
  Cc: linux-remoteproc, linux-kernel, linux-arm-kernel
In-Reply-To: <20190809162710.823-1-s-anna@ti.com>

Replace the raw print_hex_dump() call in the rpmsg_sample_cb() function
with the equivalent print_hex_dump_debug() better suited for dynamic
debug. This switch allows flexibility of controlling this trace through
dynamic debug when enabled.

Signed-off-by: Suman Anna <s-anna@ti.com>
---
 samples/rpmsg/rpmsg_client_sample.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/samples/rpmsg/rpmsg_client_sample.c b/samples/rpmsg/rpmsg_client_sample.c
index 2a0695573b47..b9a99e621a5c 100644
--- a/samples/rpmsg/rpmsg_client_sample.c
+++ b/samples/rpmsg/rpmsg_client_sample.c
@@ -29,8 +29,8 @@ static int rpmsg_sample_cb(struct rpmsg_device *rpdev, void *data, int len,
 	dev_info(&rpdev->dev, "incoming msg %d (src: 0x%x)\n",
 		 ++idata->rx_count, src);
 
-	print_hex_dump(KERN_DEBUG, __func__, DUMP_PREFIX_NONE, 16, 1,
-		       data, len,  true);
+	print_hex_dump_debug(__func__, DUMP_PREFIX_NONE, 16, 1, data, len,
+			     true);
 
 	/* samples should not live forever */
 	if (idata->rx_count >= MSG_LIMIT) {
-- 
2.22.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* Re: [PATCH 3/3] drm/bridge: Add NWL MIPI DSI host controller support
From: Guido Günther @ 2019-08-09 16:25 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Mark Rutland, devicetree, Jernej Skrabec, Pengutronix Kernel Team,
	Neil Armstrong, David Airlie, Fabio Estevam, Sascha Hauer,
	Jonas Karlman, linux-kernel, dri-devel, Andrzej Hajda,
	Rob Herring, NXP Linux Team, Daniel Vetter, Robert Chiras,
	Lee Jones, Shawn Guo, linux-arm-kernel
In-Reply-To: <20190727024700.GD4902@pendragon.ideasonboard.com>

Hi Laurent,

thanks for the review! Most of it seemed clear how to fix for the rest
i've put some questions below:

On Sat, Jul 27, 2019 at 05:47:00AM +0300, Laurent Pinchart wrote:
> Hello Guido,
> 
> Thank you for the patch.
> 
> On Wed, Jul 24, 2019 at 05:52:26PM +0200, Guido Günther wrote:
> > This adds initial support for the NWL MIPI DSI Host controller found on
> > i.MX8 SoCs.
> > 
> > It adds support for the i.MX8MQ but the same IP can be found on
> > e.g. the i.MX8QXP.
> > 
> > It has been tested on the Librem 5 devkit using mxsfb.
> > 
> > Signed-off-by: Guido Günther <agx@sigxcpu.org>
> > Co-developed-by: Robert Chiras <robert.chiras@nxp.com>
> > ---
> >  drivers/gpu/drm/bridge/Kconfig           |   2 +
> >  drivers/gpu/drm/bridge/Makefile          |   1 +
> >  drivers/gpu/drm/bridge/imx-nwl/Kconfig   |  15 +
> >  drivers/gpu/drm/bridge/imx-nwl/Makefile  |   2 +
> >  drivers/gpu/drm/bridge/imx-nwl/nwl-drv.c | 529 ++++++++++++++++
> >  drivers/gpu/drm/bridge/imx-nwl/nwl-drv.h |  72 +++
> >  drivers/gpu/drm/bridge/imx-nwl/nwl-dsi.c | 745 +++++++++++++++++++++++
> >  drivers/gpu/drm/bridge/imx-nwl/nwl-dsi.h | 111 ++++
> >  8 files changed, 1477 insertions(+)
> >  create mode 100644 drivers/gpu/drm/bridge/imx-nwl/Kconfig
> >  create mode 100644 drivers/gpu/drm/bridge/imx-nwl/Makefile
> >  create mode 100644 drivers/gpu/drm/bridge/imx-nwl/nwl-drv.c
> >  create mode 100644 drivers/gpu/drm/bridge/imx-nwl/nwl-drv.h
> >  create mode 100644 drivers/gpu/drm/bridge/imx-nwl/nwl-dsi.c
> >  create mode 100644 drivers/gpu/drm/bridge/imx-nwl/nwl-dsi.h
> > 
> > diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
> > index a6eec908c43e..38c3145a7e57 100644
> > --- a/drivers/gpu/drm/bridge/Kconfig
> > +++ b/drivers/gpu/drm/bridge/Kconfig
> > @@ -152,6 +152,8 @@ source "drivers/gpu/drm/bridge/analogix/Kconfig"
> >  
> >  source "drivers/gpu/drm/bridge/adv7511/Kconfig"
> >  
> > +source "drivers/gpu/drm/bridge/imx-nwl/Kconfig"
> > +
> 
> As this doesn't seem to be an i.MX-specific IP, I wouldn't use the name
> imx in file names or in the code, at least in the parts that are not
> NXP-specific.

O.k. Since i've not seen other SoCs using this ip core I wasn't sure
what would be sharable but we'll figure that out. Renamed to nwl-dsi/

> >  source "drivers/gpu/drm/bridge/synopsys/Kconfig"
> >  
> >  endmenu
> > diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
> > index 4934fcf5a6f8..904a9eb3a20a 100644
> > --- a/drivers/gpu/drm/bridge/Makefile
> > +++ b/drivers/gpu/drm/bridge/Makefile
> > @@ -16,4 +16,5 @@ obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix/
> >  obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511/
> >  obj-$(CONFIG_DRM_TI_SN65DSI86) += ti-sn65dsi86.o
> >  obj-$(CONFIG_DRM_TI_TFP410) += ti-tfp410.o
> > +obj-y += imx-nwl/
> >  obj-y += synopsys/
> > diff --git a/drivers/gpu/drm/bridge/imx-nwl/Kconfig b/drivers/gpu/drm/bridge/imx-nwl/Kconfig
> > new file mode 100644
> > index 000000000000..822dba1b380a
> > --- /dev/null
> > +++ b/drivers/gpu/drm/bridge/imx-nwl/Kconfig
> > @@ -0,0 +1,15 @@
> > +config DRM_IMX_NWL_DSI
> > +	tristate "Support for Northwest Logic MIPI DSI Host controller"
> > +	depends on DRM && (ARCH_MXC || ARCH_MULTIPLATFORM || COMPILE_TEST)
> > +	depends on COMMON_CLK
> > +	depends on OF && HAS_IOMEM
> > +	select DRM_KMS_HELPER
> > +	select DRM_MIPI_DSI
> > +	select DRM_PANEL_BRIDGE
> > +	select GENERIC_PHY_MIPI_DPHY
> > +	select MFD_SYSCON
> > +	select REGMAP_MMIO
> > +	help
> > +	  This enables the Northwest Logic MIPI DSI Host controller as
> > +	  found on NXP's i.MX8 Processors.
> > +
> > diff --git a/drivers/gpu/drm/bridge/imx-nwl/Makefile b/drivers/gpu/drm/bridge/imx-nwl/Makefile
> > new file mode 100644
> > index 000000000000..9fa63483da5b
> > --- /dev/null
> > +++ b/drivers/gpu/drm/bridge/imx-nwl/Makefile
> > @@ -0,0 +1,2 @@
> > +imx-nwl-objs := nwl-drv.o nwl-dsi.o
> > +obj-$(CONFIG_DRM_IMX_NWL_DSI) += imx-nwl.o
> > diff --git a/drivers/gpu/drm/bridge/imx-nwl/nwl-drv.c b/drivers/gpu/drm/bridge/imx-nwl/nwl-drv.c
> > new file mode 100644
> > index 000000000000..451f8f067c6f
> > --- /dev/null
> > +++ b/drivers/gpu/drm/bridge/imx-nwl/nwl-drv.c
> > @@ -0,0 +1,529 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * i.MX8 NWL MIPI DSI host driver
> > + *
> > + * Copyright (C) 2017 NXP
> > + * Copyright (C) 2019 Purism SPC
> > + */
> > +
> > +#include <drm/drm_atomic_helper.h>
> > +#include <drm/drm_of.h>
> > +#include <drm/drm_panel.h>
> > +#include <drm/drm_print.h>
> > +#include <drm/drm_probe_helper.h>
> > +#include <linux/clk-provider.h>
> 
> This doesn't seem to be needed.

Dropped.

> 
> > +#include <linux/clk.h>
> > +#include <linux/component.h>
> 
> Same here.

Dropped (it was a component driver before).

> > +#include <linux/gpio/consumer.h>
> > +#include <linux/irq.h>
> > +#include <linux/mfd/syscon.h>
> > +#include <linux/mfd/syscon/imx8mq-iomuxc-gpr.h>
> > +#include <linux/module.h>
> > +#include <linux/of.h>
> > +#include <linux/of_platform.h>
> > +#include <linux/phy/phy.h>
> > +#include <linux/regmap.h>
> > +#include <linux/sys_soc.h>
> > +#include <video/videomode.h>
> > +
> > +#include "nwl-drv.h"
> > +#include "nwl-dsi.h"
> > +
> > +#define DRV_NAME "imx-nwl-dsi"
> > +
> > +/* 8MQ SRC specific registers */
> > +#define SRC_MIPIPHY_RCR	0x28
> > +#define RESET_BYTE_N	BIT(1)
> > +#define RESET_N		BIT(2)
> > +#define DPI_RESET_N	BIT(3)
> > +#define ESC_RESET_N	BIT(4)
> > +#define PCLK_RESET_N	BIT(5)
> > +
> > +/* Possible clocks */
> > +#define CLK_PIXEL	"pixel"
> > +#define CLK_CORE	"core"
> > +#define CLK_BYPASS	"bypass"
> > +
> > +enum imx_ext_regs {
> > +	IMX_REG_CSR = BIT(1),
> > +	IMX_REG_SRC = BIT(2),
> > +	IMX_REG_GPR = BIT(3),
> > +};
> > +
> > +static const struct regmap_config nwl_dsi_regmap_config = {
> > +	.reg_bits = 16,
> > +	.val_bits = 32,
> > +	.reg_stride = 4,
> > +	.max_register = IRQ_MASK2,
> > +	.name = DRV_NAME,
> > +};
> > +
> > +struct imx_nwl_platform_data {
> > +	int (*poweron)(struct imx_nwl_dsi *dsi);
> > +	int (*poweroff)(struct imx_nwl_dsi *dsi);
> > +	u32 ext_regs; /* required external registers */
> > +	struct imx_nwl_clk_config clk_config[NWL_MAX_PLATFORM_CLOCKS];
> > +};
> > +
> > +static inline struct imx_nwl_dsi *bridge_to_dsi(struct drm_bridge *bridge)
> > +{
> > +	return container_of(bridge, struct imx_nwl_dsi, bridge);
> > +}
> > +
> > +static void imx_nwl_dsi_set_clocks(struct imx_nwl_dsi *dsi, bool enable)
> > +{
> > +	struct device *dev = dsi->dev;
> > +	const char *id;
> > +	struct clk *clk;
> > +	unsigned long new_rate, cur_rate;
> > +	bool enabled;
> > +	size_t i;
> > +	int ret;
> > +
> > +	DRM_DEV_DEBUG_DRIVER(dev, "%sabling platform clocks",
> > +			     enable ? "en" : "dis");
> > +	for (i = 0; i < ARRAY_SIZE(dsi->pdata->clk_config); i++) {
> > +		if (!dsi->clk_config[i].present)
> > +			continue;
> > +		id = dsi->clk_config[i].id;
> > +		clk = dsi->clk_config[i].clk;
> > +		new_rate = dsi->clk_config[i].rate;
> > +		cur_rate = clk_get_rate(clk);
> > +		enabled = dsi->clk_config[i].enabled;
> > +
> > +		/* BYPASS clk must have the same rate as PHY_REF clk */
> > +		if (!strcmp(id, CLK_BYPASS))
> > +			new_rate = clk_get_rate(dsi->phy_ref_clk);
> > +
> > +		if (enable) {
> > +			if (enabled && new_rate != cur_rate)
> > +				clk_disable_unprepare(clk);
> > +			else if (enabled && new_rate == cur_rate)
> > +				continue;
> > +			if (new_rate > 0)
> > +				clk_set_rate(clk, new_rate);
> > +			ret = clk_prepare_enable(clk);
> > +			if (ret < 0) {
> > +				DRM_DEV_ERROR(dev, "Failed to enable clock %s",
> > +					      id);
> > +			}
> > +			dsi->clk_config[i].enabled = true;
> > +			cur_rate = clk_get_rate(clk);
> > +			DRM_DEV_DEBUG_DRIVER(
> > +				dev, "Enabled %s clk (rate: req=%lu act=%lu)\n",
> > +				id, new_rate, cur_rate);
> > +		} else if (enabled) {
> > +			clk_disable_unprepare(clk);
> > +			dsi->clk_config[i].enabled = false;
> > +			DRM_DEV_DEBUG_DRIVER(dev, "Disabled %s clk\n", id);
> > +		}
> > +	}
> > +}
> > +
> > +static void imx_nwl_dsi_enable(struct imx_nwl_dsi *dsi)
> > +{
> > +	struct device *dev = dsi->dev;
> > +	int ret;
> > +
> > +	imx_nwl_dsi_set_clocks(dsi, true);
> > +
> > +	ret = dsi->pdata->poweron(dsi);
> > +	if (ret < 0)
> > +		DRM_DEV_ERROR(dev, "Failed to power on DSI (%d)\n", ret);
> > +}
> > +
> > +static void imx_nwl_dsi_disable(struct imx_nwl_dsi *dsi)
> > +{
> > +	struct device *dev = dsi->dev;
> > +
> > +	if (dsi->dpms_mode != DRM_MODE_DPMS_ON)
> > +		return;
> > +
> 
> The DRM core should guarantee that the bridge won't be disabled twice,
> so I don't think you need this check. Similarly I think the enabled flag
> in the imx_nwl_clk_config structure can be removed.
  
Dropped and i also simplified the imx_nwl_clk_config - rates are supplied
via DT here anyway. 

> 
> > +	DRM_DEV_DEBUG_DRIVER(dev, "Disabling encoder");
> 
> Is this really needed ?

Dropped.

> > +	dsi->pdata->poweroff(dsi);
> > +	imx_nwl_dsi_set_clocks(dsi, false);
> > +}
> > +
> > +static void imx_nwl_select_input_source(struct imx_nwl_dsi *dsi)
> > +{
> > +	struct device_node *remote;
> > +	u32 mux_val = IMX8MQ_GPR13_MIPI_MUX_SEL;
> > +
> > +	remote = of_graph_get_remote_node(dsi->dev->of_node, 0, 0);
> > +	if (strcmp(remote->name, "lcdif") == 0)
> > +		mux_val = 0;
> > +

Getting it from dt spares us carrying around more platform specific
state. Should i change it anyway?

> 
> Can't you check the remote node at probe time instead of every time the
> bridge gets enabled, and program the IO mux accordingly there ?
> 
> This code is i.MX-specific, so it should be isolated in an operation in
> struct imx_nwl_platform_data.

Done.

> 
> > +	DRM_DEV_INFO(dsi->dev, "Using %s as input source\n",
> > +		     (mux_val) ? "DCSS" : "LCDIF");
> > +	regmap_update_bits(dsi->mux_sel, IOMUXC_GPR13,
> > +			   IMX8MQ_GPR13_MIPI_MUX_SEL, mux_val);
> > +	of_node_put(remote);
> > +}
> > +
> > +static void imx_nwl_dsi_bridge_disable(struct drm_bridge *bridge)
> > +{
> > +	struct imx_nwl_dsi *dsi = bridge_to_dsi(bridge);
> > +
> > +	if (dsi->dpms_mode != DRM_MODE_DPMS_ON)
> > +		return;
> > +
> > +	nwl_dsi_disable(dsi);
> > +	imx_nwl_dsi_disable(dsi);
> > +	pm_runtime_put_sync(dsi->dev);
> 
> Do you need a put_sync, wouldn't a put do ?

Switched to put() only.

> 
> > +	dsi->dpms_mode = DRM_MODE_DPMS_OFF;
> > +}
> > +
> > +static bool
> > +imx_nwl_dsi_bridge_mode_fixup(struct drm_bridge *bridge,
> > +			      const struct drm_display_mode *mode,
> > +			      struct drm_display_mode *adjusted_mode)
> > +{
> > +	struct imx_nwl_dsi *dsi = bridge_to_dsi(bridge);
> > +	struct device *dev = dsi->dev;
> > +	union phy_configure_opts new_cfg;
> > +	unsigned long phy_ref_rate;
> > +	int ret;
> > +
> > +	ret = nwl_dsi_get_dphy_params(dsi, adjusted_mode, &new_cfg);
> > +	if (ret < 0)
> > +		return ret;
> > +
> > +	/*
> > +	 * If hs clock is unchanged, we're all good - all parameters are
> > +	 * derived from it atm.
> > +	 */
> > +	if (new_cfg.mipi_dphy.hs_clk_rate == dsi->phy_cfg.mipi_dphy.hs_clk_rate)
> > +		return true;
> > +
> > +	phy_ref_rate = clk_get_rate(dsi->phy_ref_clk);
> > +	DRM_DEV_DEBUG_DRIVER(dev, "PHY at ref rate: %lu\n", phy_ref_rate);
> > +	if (ret < 0) {
> 
> This can't happen. Or are you missing a function call before the check
> ?

The code used that a long time ago, fixed that path.

> 
> > +		DRM_DEV_ERROR(dsi->dev,
> > +			      "Cannot setup PHY for mode: %ux%u @%d Hz\n",
> > +			      adjusted_mode->hdisplay, adjusted_mode->vdisplay,
> > +			      adjusted_mode->clock);
> > +		DRM_DEV_ERROR(dsi->dev, "PHY ref clk: %lu, bit clk: %lu\n",
> > +			      phy_ref_rate, new_cfg.mipi_dphy.hs_clk_rate);
> > +	} else {
> > +		/* Save the new desired phy config */
> > +		memcpy(&dsi->phy_cfg, &new_cfg, sizeof(new_cfg));
> 
> The mode_fixup operation shall not change the device state, it can be
> called multiple times when trying modes.

Moved the parts to 'mode_set' instead.

> 
> > +	}
> > +
> > +	/* LCDIF + NWL needs active high sync */
> > +	adjusted_mode->flags |= (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC);
> > +	adjusted_mode->flags &= ~(DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC);
> > +
> > +	drm_display_mode_to_videomode(adjusted_mode, &dsi->vm);
> > +	drm_mode_debug_printmodeline(adjusted_mode);
> > +
> > +	return ret == 0;
> 
> 	return 0;

mode_fixup wants a bool but that code is gone anyways.

> 
> > +}
> > +
> > +static enum drm_mode_status
> > +imx_nwl_dsi_bridge_mode_valid(struct drm_bridge *bridge,
> > +			      const struct drm_display_mode *mode)
> > +{
> > +	struct imx_nwl_dsi *dsi = bridge_to_dsi(bridge);
> > +	int bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
> > +
> > +	if (bpp < 0) {
> > +		DRM_DEV_ERROR(dsi->dev, "Invalid pixel format: %d\n",
> > +			      dsi->format);
> > +		return MODE_BAD;
> > +	}
> 
> The format isn't part of the mode, so this doesn't belong here. You
> should here instead check that the mode clock and other timing data
> (especially the visible resolution) are within the range supported by
> the device.

O.k. I've added a clock check derived from the spec instead.

> > +
> > +	return MODE_OK;
> > +}
> > +
> > +static void imx_nwl_dsi_bridge_pre_enable(struct drm_bridge *bridge)
> > +{
> > +	struct imx_nwl_dsi *dsi = bridge_to_dsi(bridge);
> > +
> > +	if (dsi->dpms_mode == DRM_MODE_DPMS_ON)
> > +		return;
> > +
> > +	imx_nwl_select_input_source(dsi);
> > +	pm_runtime_get_sync(dsi->dev);
> > +	imx_nwl_dsi_enable(dsi);
> > +	nwl_dsi_enable(dsi);
> > +	dsi->dpms_mode = DRM_MODE_DPMS_ON;
> > +}
> > +
> > +static int imx_nwl_dsi_bridge_attach(struct drm_bridge *bridge)
> > +{
> > +	struct imx_nwl_dsi *dsi = bridge->driver_private;
> > +	struct drm_encoder *encoder = bridge->encoder;
> > +
> > +	if (!encoder) {
> > +		DRM_DEV_ERROR(dsi->dev, "Parent encoder object not found\n");
> > +		return -ENODEV;
> > +	}
> 
> Can't this happen ?

Dropped.

> 
> > +
> > +	/* Set the encoder type as caller does not know it */
> > +	bridge->encoder->encoder_type = DRM_MODE_ENCODER_DSI;
> 
> The encoder type is quite meaningless and userspace should not depend on
> it, so I wouldn't set it here, especially that the encoder may not
> expect the bridge to override its type.

Dropped.

> 
> > +
> > +	/* Attach the panel-bridge to the dsi bridge */
> > +	return drm_bridge_attach(bridge->encoder, dsi->panel_bridge, bridge);
> > +}
> > +
> > +static void imx_nwl_dsi_bridge_detach(struct drm_bridge *bridge)
> > +{
> > +	struct imx_nwl_dsi *dsi = bridge->driver_private;
> > +
> > +	drm_of_panel_bridge_remove(dsi->dev->of_node, 1, 0);
> 
> This is already done in nwl_dsi_host_detach().

Dropped the whole detach.

> 
> > +}
> > +
> > +/* see dw-mipi-dsi.c */
> 
> What for ? :-)

Dropped.

> 
> > +static const struct drm_bridge_funcs imx_nwl_dsi_bridge_funcs = {
> > +	.pre_enable	= imx_nwl_dsi_bridge_pre_enable,
> > +	.disable    = imx_nwl_dsi_bridge_disable,
> > +	.mode_fixup = imx_nwl_dsi_bridge_mode_fixup,
> > +	.mode_valid = imx_nwl_dsi_bridge_mode_valid,
> > +	.attach	    = imx_nwl_dsi_bridge_attach,
> > +	.detach	    = imx_nwl_dsi_bridge_detach,
> > +};
> > +
> > +static int imx_nwl_dsi_parse_dt(struct imx_nwl_dsi *dsi)
> > +{
> > +	struct device_node *np = dsi->dev->of_node;
> > +	struct platform_device *pdev = to_platform_device(dsi->dev);
> > +	struct resource *res;
> > +	struct clk *clk;
> > +	const char *clk_id;
> > +	void __iomem *base;
> > +	int i, ret;
> > +
> > +	dsi->phy = devm_phy_get(dsi->dev, "dphy");
> > +	if (IS_ERR(dsi->phy)) {
> > +		ret = PTR_ERR(dsi->phy);
> > +		dev_err(dsi->dev, "Could not get PHY (%d)\n", ret);
> > +		return ret;
> > +	}
> > +
> > +	/* Platform dependent clocks */
> > +	memcpy(dsi->clk_config, dsi->pdata->clk_config,
> > +	       sizeof(dsi->pdata->clk_config));
> > +
> > +	for (i = 0; i < ARRAY_SIZE(dsi->pdata->clk_config); i++) {
> > +		if (!dsi->clk_config[i].present)
> > +			continue;
> > +
> > +		clk_id = dsi->clk_config[i].id;
> > +		clk = devm_clk_get(dsi->dev, clk_id);
> > +		if (IS_ERR(clk)) {
> > +			ret = PTR_ERR(clk);
> > +			dev_err(dsi->dev, "Failed to get %s clock (%d)\n",
> > +				clk_id, ret);
> > +			return ret;
> > +		}
> > +		DRM_DEV_DEBUG_DRIVER(dsi->dev, "Setup clk %s (rate: %lu)\n",
> > +				     clk_id, clk_get_rate(clk));
> > +		dsi->clk_config[i].clk = clk;
> > +	}
> > +
> > +	/* DSI clocks */
> > +	clk = devm_clk_get(dsi->dev, "phy_ref");
> > +	if (IS_ERR(clk)) {
> > +		ret = PTR_ERR(clk);
> > +		dev_err(dsi->dev, "Failed to get phy_ref clock: %d\n", ret);
> > +		return ret;
> > +	}
> > +	dsi->phy_ref_clk = clk;
> > +
> > +	clk = devm_clk_get(dsi->dev, "rx_esc");
> > +	if (IS_ERR(clk)) {
> > +		ret = PTR_ERR(clk);
> > +		dev_err(dsi->dev, "Failed to get rx_esc clock: %d\n", ret);
> > +		return ret;
> > +	}
> > +	dsi->rx_esc_clk = clk;
> > +
> > +	clk = devm_clk_get(dsi->dev, "tx_esc");
> > +	if (IS_ERR(clk)) {
> > +		ret = PTR_ERR(clk);
> > +		dev_err(dsi->dev, "Failed to get tx_esc clock: %d\n", ret);
> > +		return ret;
> > +	}
> > +	dsi->tx_esc_clk = clk;
> > +
> > +	dsi->csr = syscon_regmap_lookup_by_phandle(np, "csr");
> > +	if (IS_ERR(dsi->csr) && dsi->pdata->ext_regs & IMX_REG_CSR) {
> > +		ret = PTR_ERR(dsi->csr);
> > +		DRM_DEV_ERROR(dsi->dev, "Failed to get CSR regmap: %d\n",
> > +			      ret);
> > +		return ret;
> > +	}
> 
> This doesn't seem to be used anywhere.

That's true. i had it in for the imx8q*, dropped that (and some other
parts) until support for that soc is added.

> 
> > +	dsi->reset = syscon_regmap_lookup_by_phandle(np, "src");
> > +	if (IS_ERR(dsi->reset) && (dsi->pdata->ext_regs & IMX_REG_SRC)) {
> > +		ret = PTR_ERR(dsi->reset);
> > +		DRM_DEV_ERROR(dsi->dev, "Failed to get SRC regmap: %d\n",
> > +			      ret);
> > +		return ret;
> > +	}
> 
> Couldn't you model a reset controller in that syscon, and use the reset
> controller API here ? It would allow moving the i.MX-specific power on
> and off functions from this driver, making it more generic.

In fact the reset controller is already there, wired it up accordingly.

> 
> > +	dsi->mux_sel = syscon_regmap_lookup_by_phandle(np, "mux-sel");
> > +	if (IS_ERR(dsi->mux_sel) && (dsi->pdata->ext_regs & IMX_REG_GPR)) {
> > +		ret = PTR_ERR(dsi->mux_sel);
> > +		DRM_DEV_ERROR(dsi->dev, "Failed to get GPR regmap: %d\n",
> > +			      ret);
> > +		return ret;
> > +	}
> > +
> > +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +	base = devm_ioremap_resource(dsi->dev, res);
> 
> You can replace those two calls with devm_platform_ioremap_resource().

Done.

> 
> > +	if (IS_ERR(base))
> > +		return PTR_ERR(base);
> > +
> > +	dsi->regmap =
> > +		devm_regmap_init_mmio(dsi->dev, base, &nwl_dsi_regmap_config);
> > +	if (IS_ERR(dsi->regmap)) {
> > +		ret = PTR_ERR(dsi->regmap);
> > +		DRM_DEV_ERROR(dsi->dev,
> > +			      "Failed to create NWL DSI regmap: %d\n", ret);
> > +		return ret;
> > +	}
> > +
> > +	dsi->irq = platform_get_irq(pdev, 0);
> > +	if (dsi->irq < 0) {
> > +		DRM_DEV_ERROR(dsi->dev, "Failed to get device IRQ: %d\n",
> > +			      dsi->irq);
> > +		return dsi->irq;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int imx8mq_dsi_poweron(struct imx_nwl_dsi *dsi)
> > +{
> > +	/* otherwise the display stays blank */
> > +	usleep_range(200, 300);
> > +
> > +	regmap_update_bits(dsi->reset, SRC_MIPIPHY_RCR, PCLK_RESET_N,
> > +			   PCLK_RESET_N);
> > +	regmap_update_bits(dsi->reset, SRC_MIPIPHY_RCR, ESC_RESET_N,
> > +			   ESC_RESET_N);
> > +	regmap_update_bits(dsi->reset, SRC_MIPIPHY_RCR, RESET_BYTE_N,
> > +			   RESET_BYTE_N);
> > +	regmap_update_bits(dsi->reset, SRC_MIPIPHY_RCR, DPI_RESET_N,
> > +			   DPI_RESET_N);
> > +
> > +	return 0;
> > +}
> > +
> > +static int imx8mq_dsi_poweroff(struct imx_nwl_dsi *dsi)
> > +{
> > +	if (USE_SRC_RESET_QUIRK(dsi->quirks))
> > +		return 0;
> > +
> > +	regmap_update_bits(dsi->reset, SRC_MIPIPHY_RCR, PCLK_RESET_N, 0);
> > +	regmap_update_bits(dsi->reset, SRC_MIPIPHY_RCR, ESC_RESET_N, 0);
> > +	regmap_update_bits(dsi->reset, SRC_MIPIPHY_RCR, RESET_BYTE_N, 0);
> > +	regmap_update_bits(dsi->reset, SRC_MIPIPHY_RCR, DPI_RESET_N, 0);
> > +	return 0;
> > +}
> > +
> > +static const struct drm_bridge_timings imx_nwl_timings = {
> > +	.input_bus_flags = DRM_BUS_FLAG_DE_LOW,
> > +};
> > +
> > +static struct imx_nwl_platform_data imx8mq_dev = {
> 
> This structure should be const, especially as it contains function
> pointers.

Done.

> 
> > +	.poweron = &imx8mq_dsi_poweron,
> > +	.poweroff = &imx8mq_dsi_poweroff,
> > +	.clk_config = {
> > +		{ .id = CLK_CORE,   .present = true },
> > +		{ .id = CLK_PIXEL,  .present = false },
> > +		{ .id = CLK_BYPASS, .present = false },
> > +	},
> > +	.ext_regs = IMX_REG_SRC | IMX_REG_GPR,
> > +};
> > +
> > +static const struct of_device_id imx_nwl_dsi_dt_ids[] = {
> > +	{ .compatible = "fsl,imx8mq-nwl-dsi", .data = &imx8mq_dev, },
> > +	{ /* sentinel */ }
> > +};
> > +MODULE_DEVICE_TABLE(of, imx_nwl_dsi_dt_ids);
> > +
> > +static const struct soc_device_attribute imx_nwl_quirks_match[] = {
> > +	{ .soc_id = "i.MX8MQ", .revision = "2.0",
> > +	  .data = (void *)(E11418_HS_MODE_QUIRK | SRC_RESET_QUIRK) },
> > +	{ /* sentinel. */ },
> > +};
> > +
> > +static int imx_nwl_dsi_probe(struct platform_device *pdev)
> > +{
> > +	struct device *dev = &pdev->dev;
> > +	const struct of_device_id *of_id =
> > +		of_match_device(imx_nwl_dsi_dt_ids, dev);
> > +	const struct imx_nwl_platform_data *pdata = of_id->data;
> > +	const struct soc_device_attribute *attr;
> > +	struct imx_nwl_dsi *dsi;
> > +	int ret;
> > +
> > +	dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL);
> > +	if (!dsi)
> > +		return -ENOMEM;
> > +
> > +	dsi->dev = dev;
> > +	dsi->pdata = pdata;
> > +	dsi->dpms_mode = DRM_MODE_DPMS_OFF;
> 
> DPMS is legacy, let's not use it within the driver.

Removed that since the drm layer keeps the state for us.

> > +
> > +	ret = imx_nwl_dsi_parse_dt(dsi);
> > +	if (ret)
> > +		return ret;
> > +
> > +	ret = devm_request_irq(dev, dsi->irq, nwl_dsi_irq_handler, 0,
> > +			       dev_name(dev), dsi);
> > +	if (ret < 0) {
> > +		DRM_DEV_ERROR(dev, "Failed to request IRQ: %d (%d)\n", dsi->irq,
> > +			      ret);
> > +		return ret;
> > +	}
> > +
> > +	dsi->dsi_host.ops = &nwl_dsi_host_ops;
> > +	dsi->dsi_host.dev = dev;
> > +	ret = mipi_dsi_host_register(&dsi->dsi_host);
> > +	if (ret) {
> > +		DRM_DEV_ERROR(dev, "Failed to register MIPI host: %d\n", ret);
> > +		goto err_cleanup;
> > +	}
> > +
> > +	attr = soc_device_match(imx_nwl_quirks_match);
> > +	if (attr)
> > +		dsi->quirks = (uintptr_t)attr->data;
> > +
> > +	dsi->bridge.driver_private = dsi;
> > +	dsi->bridge.funcs = &imx_nwl_dsi_bridge_funcs;
> > +	dsi->bridge.of_node = dev->of_node;
> > +	dsi->bridge.timings = &imx_nwl_timings;
> > +
> > +	drm_bridge_add(&dsi->bridge);
> > +
> > +	dev_set_drvdata(dev, dsi);
> > +	pm_runtime_enable(dev);
> > +	return 0;
> > +
> > +err_cleanup:
> > +	devm_free_irq(dev, dsi->irq, dsi);
> > +	return ret;
> > +}
> > +
> > +static int imx_nwl_dsi_remove(struct platform_device *pdev)
> > +{
> > +	pm_runtime_disable(&pdev->dev);
> 
> You should call drm_bridge_remove() here, not in
> nwl_dsi_host_detach().

I opted to call `mipi_dsi_host_unregister(&dsi->dsi_host)` which would
keep the removal in `nwl_dsi_host_detach()` but would also make sure
it's called on removal (modelled like cdns-dsi).

> 
> > +	return 0;
> > +}
> > +
> > +static struct platform_driver imx_nwl_dsi_driver = {
> > +	.probe		= imx_nwl_dsi_probe,
> > +	.remove		= imx_nwl_dsi_remove,
> > +	.driver		= {
> > +		.of_match_table = imx_nwl_dsi_dt_ids,
> > +		.name	= DRV_NAME,
> > +	},
> > +};
> > +
> > +module_platform_driver(imx_nwl_dsi_driver);
> > +
> > +MODULE_AUTHOR("NXP Semiconductor");
> > +MODULE_AUTHOR("Purism SPC");
> > +MODULE_DESCRIPTION("i.MX8 Northwest Logic MIPI-DSI driver");
> > +MODULE_LICENSE("GPL"); /* GPLv2 or later */
> > diff --git a/drivers/gpu/drm/bridge/imx-nwl/nwl-drv.h b/drivers/gpu/drm/bridge/imx-nwl/nwl-drv.h
> > new file mode 100644
> > index 000000000000..a1e30c58b627
> > --- /dev/null
> > +++ b/drivers/gpu/drm/bridge/imx-nwl/nwl-drv.h
> > @@ -0,0 +1,72 @@
> > +/* SPDX-License-Identifier: GPL-2.0+ */
> > +/*
> > + * i.MX8 NWL MIPI DSI host driver
> > + *
> > + * Copyright (C) 2017 NXP
> > + * Copyright (C) 2019 Purism SPC
> > + */
> > +
> > +#ifndef __NWL_DRV_H__
> > +#define __NWL_DRV_H__
> > +
> > +#include <drm/drm_mipi_dsi.h>
> > +#include <linux/phy/phy.h>
> > +
> > +struct imx_nwl_platform_data;
> > +
> > +/* i.MX8 NWL quirks */
> > +/* i.MX8MQ errata E11418 */
> > +#define E11418_HS_MODE_QUIRK	    BIT(0)
> > +#define USE_E11418_HS_MODE_QUIRK(x) ((x) & E11418_HS_MODE_QUIRK)
> > +
> > +/* Skip DSI bits in SRC on disable to avoid blank display on enable */
> > +#define SRC_RESET_QUIRK		    BIT(1)
> > +#define USE_SRC_RESET_QUIRK(x)	    ((x) & SRC_RESET_QUIRK)
> 
> The USE_* macros are not shorter to type, so I would type out the &
> check explicitly.

Dropped.

> > +
> > +#define NWL_MAX_PLATFORM_CLOCKS 3
> > +struct imx_nwl_clk_config {
> > +	const char *id;
> > +	struct clk *clk;
> > +	bool present;
> > +	bool enabled;
> > +	u32 rate;
> > +};
> > +
> > +struct imx_nwl_dsi {
> > +	struct drm_bridge bridge;
> > +	struct mipi_dsi_host dsi_host;
> > +	struct drm_bridge *panel_bridge;
> > +	struct device *dev;
> > +	struct phy *phy;
> > +	union phy_configure_opts phy_cfg;
> > +	unsigned int quirks;
> > +
> > +	struct regmap *regmap;
> > +	int irq;
> > +
> > +	/* External registers */
> > +	struct regmap *csr;
> > +	struct regmap *mux_sel;
> > +	struct regmap *reset;
> > +
> > +	/* Platform dependent clocks */
> > +	struct imx_nwl_clk_config clk_config[3];
> 
> I would use NWL_MAX_PLATFORM_CLOCKS instead of 3 as
> imx_nwl_platform_data uses the macro.

That was an omission, fixed.

> 
> > +	/* DSI clocks */
> > +	struct clk *phy_ref_clk;
> > +	struct clk *rx_esc_clk;
> > +	struct clk *tx_esc_clk;
> > +
> > +	/* dsi lanes */
> > +	u32 lanes;
> > +	enum mipi_dsi_pixel_format format;
> > +	struct videomode vm;
> > +	unsigned long dsi_mode_flags;
> > +
> > +	int dpms_mode;
> > +
> > +	struct mipi_dsi_transfer *xfer;
> > +
> > +	const struct imx_nwl_platform_data *pdata;
> > +};
> > +
> > +#endif /* __NWL_DRV_H__ */
> > diff --git a/drivers/gpu/drm/bridge/imx-nwl/nwl-dsi.c b/drivers/gpu/drm/bridge/imx-nwl/nwl-dsi.c
> > new file mode 100644
> > index 000000000000..0e1463af162f
> > --- /dev/null
> > +++ b/drivers/gpu/drm/bridge/imx-nwl/nwl-dsi.c
> > @@ -0,0 +1,745 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * NWL DSI host driver
> > + *
> > + * Copyright (C) 2017 NXP
> > + * Copyright (C) 2019 Purism SPC
> > + */
> > +
> > +#include <asm/unaligned.h>
> > +#include <drm/drm_atomic_helper.h>
> > +#include <drm/drm_crtc_helper.h>
> > +#include <drm/drm_of.h>
> > +#include <drm/drm_panel.h>
> > +#include <drm/drm_print.h>
> > +#include <linux/clk.h>
> > +#include <linux/irq.h>
> > +#include <linux/regmap.h>
> > +#include <video/mipi_display.h>
> > +#include <video/videomode.h>
> > +
> > +#include "nwl-drv.h"
> > +#include "nwl-dsi.h"
> > +
> > +#define MIPI_FIFO_TIMEOUT msecs_to_jiffies(500)
> > +
> > +/* PKT reg bit manipulation */
> > +#define REG_MASK(e, s) (((1 << ((e) - (s) + 1)) - 1) << (s))
> > +#define REG_PUT(x, e, s) (((x) << (s)) & REG_MASK(e, s))
> > +#define REG_GET(x, e, s) (((x) & REG_MASK(e, s)) >> (s))
> 
> Let's not reinvent the wheel, linux/bits.h and linux/bitfield.h can be
> used instead.

Done.

> 
> > +
> > +/*
> > + * PKT_CONTROL format:
> > + * [15: 0] - word count
> > + * [17:16] - virtual channel
> > + * [23:18] - data type
> > + * [24]	   - LP or HS select (0 - LP, 1 - HS)
> > + * [25]	   - perform BTA after packet is sent
> > + * [26]	   - perform BTA only, no packet tx
> > + */
> > +#define WC(x)		REG_PUT((x), 15,  0)
> > +#define TX_VC(x)	REG_PUT((x), 17, 16)
> > +#define TX_DT(x)	REG_PUT((x), 23, 18)
> > +#define HS_SEL(x)	REG_PUT((x), 24, 24)
> > +#define BTA_TX(x)	REG_PUT((x), 25, 25)
> > +#define BTA_NO_TX(x)	REG_PUT((x), 26, 26)
> > +
> > +/*
> > + * RX_PKT_HEADER format:
> > + * [15: 0] - word count
> > + * [21:16] - data type
> > + * [23:22] - virtual channel
> > + */
> > +#define RX_DT(x) REG_GET((x), 21, 16)
> > +#define RX_VC(x) REG_GET((x), 23, 22)
> > +
> > +/*
> > + * DSI Video mode
> > + */
> > +#define VIDEO_MODE_BURST_MODE_WITH_SYNC_PULSES		0
> > +#define VIDEO_MODE_NON_BURST_MODE_WITH_SYNC_EVENTS	BIT(0)
> > +#define VIDEO_MODE_BURST_MODE				BIT(1)
> > +
> > +/*
> > + * DPI color coding
> > + */
> > +#define DPI_16_BIT_565_PACKED	0
> > +#define DPI_16_BIT_565_ALIGNED	1
> > +#define DPI_16_BIT_565_SHIFTED	2
> > +#define DPI_18_BIT_PACKED	3
> > +#define DPI_18_BIT_ALIGNED	4
> > +#define DPI_24_BIT		5
> > +
> > +/*
> > + * DPI Pixel format
> > + */
> > +#define PIXEL_FORMAT_16  0
> > +#define PIXEL_FORMAT_18  BIT(0)
> > +#define PIXEL_FORMAT_18L BIT(1)
> > +#define PIXEL_FORMAT_24  (BIT(0) | BIT(1))
> > +
> > +enum transfer_direction { DSI_PACKET_SEND, DSI_PACKET_RECEIVE };
> 
> Line breaks please.

Done.

> 
> > +
> > +struct mipi_dsi_transfer {
> 
> Let's not use such a generic name for a driver-specific structure. You
> should name is nwl_dsi_transfer.

Fixed.

> 
> > +	const struct mipi_dsi_msg *msg;
> > +	struct mipi_dsi_packet packet;
> > +	struct completion completed;
> > +
> > +	int status; /* status of transmission */
> > +	enum transfer_direction direction;
> > +	bool need_bta;
> > +	u8 cmd;
> > +	u16 rx_word_count;
> > +	size_t tx_len; /* bytes sent */
> > +	size_t rx_len; /* bytes received */
> > +};
> > +
> > +static inline int nwl_dsi_write(struct imx_nwl_dsi *dsi, unsigned int reg,
> > +				u32 val)
> > +{
> > +	int ret;
> > +
> > +	ret = regmap_write(dsi->regmap, reg, val);
> > +	if (ret < 0)
> > +		DRM_DEV_ERROR(dsi->dev,
> > +			      "Failed to write NWL DSI reg 0x%x: %d\n", reg,
> > +			      ret);
> > +	return ret;
> > +}
> > +
> > +static inline u32 nwl_dsi_read(struct imx_nwl_dsi *dsi, u32 reg)
> > +{
> > +	unsigned int val;
> > +	int ret;
> > +
> > +	ret = regmap_read(dsi->regmap, reg, &val);
> > +	if (ret < 0)
> > +		DRM_DEV_ERROR(dsi->dev, "Failed to read NWL DSI reg 0x%x: %d\n",
> > +			      reg, ret);
> > +
> > +	return val;
> 
> You're loosing the error...

Looking at other drivers they often just ignore the return value of
regmap_read. The places we use this can't do much to recover from errors
so i figured it'd be best to at least log it so it becomes debuggable
instead of just dropping it to the floor.

> > +}
> > +
> > +static u32 nwl_dsi_get_dpi_pixel_format(enum mipi_dsi_pixel_format format)
> > +{
> > +	switch (format) {
> > +	case MIPI_DSI_FMT_RGB565:
> > +		return PIXEL_FORMAT_16;
> > +	case MIPI_DSI_FMT_RGB666:
> > +		return PIXEL_FORMAT_18L;
> > +	case MIPI_DSI_FMT_RGB666_PACKED:
> > +		return PIXEL_FORMAT_18;
> > +	case MIPI_DSI_FMT_RGB888:
> > +		return PIXEL_FORMAT_24;
> > +	default:
> > +		return -EINVAL;
> > +	}
> > +}
> > +
> > +int nwl_dsi_get_dphy_params(struct imx_nwl_dsi *dsi,
> > +			    const struct drm_display_mode *mode,
> > +			    union phy_configure_opts *phy_opts)
> > +{
> > +	unsigned long rate;
> > +
> > +	if (dsi->lanes < 1 || dsi->lanes > 4)
> > +		return -EINVAL;
> > +
> > +	/*
> > +	 * So far the DPHY spec minimal timings work for both mixel
> > +	 * dphy and nwl dsi host
> > +	 */
> > +	phy_mipi_dphy_get_default_config(
> > +		mode->crtc_clock * 1000,
> > +		mipi_dsi_pixel_format_to_bpp(dsi->format), dsi->lanes,
> > +		&phy_opts->mipi_dphy);
> > +	rate = clk_get_rate(dsi->tx_esc_clk);
> > +	DRM_DEV_DEBUG_DRIVER(dsi->dev, "LP clk is @%lu Hz\n", rate);
> > +	phy_opts->mipi_dphy.lp_clk_rate = rate;
> > +
> > +	return 0;
> > +}
> > +EXPORT_SYMBOL_GPL(nwl_dsi_get_dphy_params);
> 
> No need to export symbols, those fubctions are only meant to be called
> from within the same module.

Removed (also left overs when i had these in two modules).

> 
> > +
> > +#define PSEC_PER_SEC 1000000000000LL
> > +/*
> > + * ps2bc - Picoseconds to byte clock cycles
> > + */
> > +static u32 ps2bc(struct imx_nwl_dsi *dsi, unsigned long long ps)
> > +{
> > +	int bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
> > +
> > +	return DIV_ROUND_UP(ps * dsi->vm.pixelclock * bpp,
> > +			    dsi->lanes * 8 * PSEC_PER_SEC);
> > +}
> > +
> > +/**
> > + * ui2bc - UI time periods to byte clock cycles
> > + */
> > +static u32 ui2bc(struct imx_nwl_dsi *dsi, unsigned long long ui)
> > +{
> > +	int bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
> > +
> > +	return DIV_ROUND_UP(ui * dsi->lanes, dsi->vm.pixelclock * bpp);
> > +}
> > +
> > +#define USEC_PER_SEC 1000000L
> > +/*
> > + * us2bc - micro seconds to lp clock cycles
> > + */
> > +static u32 us2lp(u32 lp_clk_rate, unsigned long us)
> > +{
> > +	return DIV_ROUND_UP(us * lp_clk_rate, USEC_PER_SEC);
> > +}
> > +
> > +static int nwl_dsi_config_host(struct imx_nwl_dsi *dsi)
> > +{
> > +	u32 cycles;
> > +	struct phy_configure_opts_mipi_dphy *cfg = &dsi->phy_cfg.mipi_dphy;
> > +
> > +	if (dsi->lanes < 1 || dsi->lanes > 4)
> > +		return -EINVAL;
> > +
> > +	DRM_DEV_DEBUG_DRIVER(dsi->dev, "DSI Lanes %d\n", dsi->lanes);
> > +	nwl_dsi_write(dsi, CFG_NUM_LANES, dsi->lanes - 1);
> > +
> > +	if (dsi->dsi_mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) {
> > +		nwl_dsi_write(dsi, CFG_NONCONTINUOUS_CLK, 0x01);
> > +		nwl_dsi_write(dsi, CFG_AUTOINSERT_EOTP, 0x01);
> > +	} else {
> > +		nwl_dsi_write(dsi, CFG_NONCONTINUOUS_CLK, 0x00);
> > +		nwl_dsi_write(dsi, CFG_AUTOINSERT_EOTP, 0x00);
> > +	}
> > +
> > +	/* values in byte clock cycles */
> > +	cycles = ui2bc(dsi, cfg->clk_pre);
> > +	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_t_pre: 0x%x\n", cycles);
> > +	nwl_dsi_write(dsi, CFG_T_PRE, cycles);
> > +	cycles = ps2bc(dsi, cfg->lpx + cfg->clk_prepare + cfg->clk_zero);
> > +	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_tx_gap (pre): 0x%x\n", cycles);
> > +	cycles += ui2bc(dsi, cfg->clk_pre);
> > +	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_tx_gap: 0x%x\n", cycles);
> > +	nwl_dsi_write(dsi, CFG_T_POST, cycles);
> > +	cycles = ps2bc(dsi, cfg->hs_exit);
> > +	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_tx_gap: 0x%x\n", cycles);
> > +	nwl_dsi_write(dsi, CFG_TX_GAP, cycles);
> > +
> > +	nwl_dsi_write(dsi, CFG_EXTRA_CMDS_AFTER_EOTP, 0x01);
> > +	nwl_dsi_write(dsi, CFG_HTX_TO_COUNT, 0x00);
> > +	nwl_dsi_write(dsi, CFG_LRX_H_TO_COUNT, 0x00);
> > +	nwl_dsi_write(dsi, CFG_BTA_H_TO_COUNT, 0x00);
> > +	/* In LP clock cycles */
> > +	cycles = us2lp(cfg->lp_clk_rate, cfg->wakeup);
> > +	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_twakeup: 0x%x\n", cycles);
> > +	nwl_dsi_write(dsi, CFG_TWAKEUP, cycles);
> > +
> > +	return 0;
> > +}
> > +
> > +static int nwl_dsi_config_dpi(struct imx_nwl_dsi *dsi)
> > +{
> > +	struct videomode *vm = &dsi->vm;
> > +	u32 color_format, mode;
> > +	bool burst_mode;
> > +
> > +	DRM_DEV_DEBUG_DRIVER(dsi->dev, "hfront_porch = %d\n", vm->hfront_porch);
> > +	DRM_DEV_DEBUG_DRIVER(dsi->dev, "hback_porch = %d\n", vm->hback_porch);
> > +	DRM_DEV_DEBUG_DRIVER(dsi->dev, "hsync_len = %d\n", vm->hsync_len);
> > +	DRM_DEV_DEBUG_DRIVER(dsi->dev, "hactive = %d\n", vm->hactive);
> > +	DRM_DEV_DEBUG_DRIVER(dsi->dev, "vfront_porch = %d\n", vm->vfront_porch);
> > +	DRM_DEV_DEBUG_DRIVER(dsi->dev, "vback_porch = %d\n", vm->vback_porch);
> > +	DRM_DEV_DEBUG_DRIVER(dsi->dev, "vsync_len = %d\n", vm->vsync_len);
> > +	DRM_DEV_DEBUG_DRIVER(dsi->dev, "vactive = %d\n", vm->vactive);
> > +	DRM_DEV_DEBUG_DRIVER(dsi->dev, "clock = %lu kHz\n",
> > +			     vm->pixelclock / 1000);
> > +
> > +	color_format = nwl_dsi_get_dpi_pixel_format(dsi->format);
> > +	if (color_format < 0) {
> > +		DRM_DEV_ERROR(dsi->dev, "Invalid color format 0x%x\n",
> > +			      dsi->format);
> > +		return color_format;
> > +	}
> > +	DRM_DEV_DEBUG_DRIVER(dsi->dev, "pixel fmt = %d\n", dsi->format);
> > +
> > +	nwl_dsi_write(dsi, INTERFACE_COLOR_CODING, DPI_24_BIT);
> > +	nwl_dsi_write(dsi, PIXEL_FORMAT, color_format);
> > +	/*
> > +	 * Adjusting input polarity based on the video mode results in
> > +	 * a black screen so always pick active low:
> > +	 */
> > +	nwl_dsi_write(dsi, VSYNC_POLARITY, VSYNC_POLARITY_ACTIVE_LOW);
> > +	nwl_dsi_write(dsi, HSYNC_POLARITY, HSYNC_POLARITY_ACTIVE_LOW);
> > +
> > +	burst_mode = (dsi->dsi_mode_flags & MIPI_DSI_MODE_VIDEO_BURST) &&
> > +		     !(dsi->dsi_mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE);
> > +
> > +	if (burst_mode) {
> > +		nwl_dsi_write(dsi, VIDEO_MODE, VIDEO_MODE_BURST_MODE);
> > +		nwl_dsi_write(dsi, PIXEL_FIFO_SEND_LEVEL, 256);
> > +	} else {
> > +		mode = ((dsi->dsi_mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) ?
> > +				VIDEO_MODE_BURST_MODE_WITH_SYNC_PULSES :
> > +				VIDEO_MODE_NON_BURST_MODE_WITH_SYNC_EVENTS);
> > +		nwl_dsi_write(dsi, VIDEO_MODE, mode);
> > +		nwl_dsi_write(dsi, PIXEL_FIFO_SEND_LEVEL, vm->hactive);
> > +	}
> > +
> > +	nwl_dsi_write(dsi, HFP, vm->hfront_porch);
> > +	nwl_dsi_write(dsi, HBP, vm->hback_porch);
> > +	nwl_dsi_write(dsi, HSA, vm->hsync_len);
> > +
> > +	nwl_dsi_write(dsi, ENABLE_MULT_PKTS, 0x0);
> > +	nwl_dsi_write(dsi, BLLP_MODE, 0x1);
> > +	nwl_dsi_write(dsi, ENABLE_MULT_PKTS, 0x0);
> > +	nwl_dsi_write(dsi, USE_NULL_PKT_BLLP, 0x0);
> > +	nwl_dsi_write(dsi, VC, 0x0);
> > +
> > +	nwl_dsi_write(dsi, PIXEL_PAYLOAD_SIZE, vm->hactive);
> > +	nwl_dsi_write(dsi, VACTIVE, vm->vactive - 1);
> > +	nwl_dsi_write(dsi, VBP, vm->vback_porch);
> > +	nwl_dsi_write(dsi, VFP, vm->vfront_porch);
> > +
> > +	return 0;
> > +}
> > +
> > +static int nwl_dsi_enable_tx_clock(struct imx_nwl_dsi *dsi)
> > +{
> > +	struct device *dev = dsi->dev;
> > +	int ret;
> > +
> > +	ret = clk_prepare_enable(dsi->tx_esc_clk);
> > +	if (ret < 0) {
> > +		DRM_DEV_ERROR(dev, "Failed to enable tx_esc clk: %d\n", ret);
> > +		return ret;
> > +	}
> > +
> > +	DRM_DEV_DEBUG_DRIVER(dev, "Enabled tx_esc clk @%lu Hz\n",
> > +			     clk_get_rate(dsi->tx_esc_clk));
> > +	return 0;
> > +}
> > +
> > +static int nwl_dsi_enable_rx_clock(struct imx_nwl_dsi *dsi)
> > +{
> > +	struct device *dev = dsi->dev;
> > +	int ret;
> > +
> > +	ret = clk_prepare_enable(dsi->rx_esc_clk);
> > +	if (ret < 0) {
> > +		DRM_DEV_ERROR(dev, "Failed to enable rx_esc clk: %d\n", ret);
> > +		return ret;
> > +	}
> > +
> > +	DRM_DEV_DEBUG_DRIVER(dev, "Enabled rx_esc clk @%lu Hz\n",
> > +			     clk_get_rate(dsi->rx_esc_clk));
> > +	return 0;
> > +}
> > +
> > +static void nwl_dsi_init_interrupts(struct imx_nwl_dsi *dsi)
> > +{
> > +	u32 irq_enable;
> > +
> > +	nwl_dsi_write(dsi, IRQ_MASK, 0xffffffff);
> > +	nwl_dsi_write(dsi, IRQ_MASK2, 0x7);
> > +
> > +	irq_enable = ~(u32)(TX_PKT_DONE_MASK | RX_PKT_HDR_RCVD_MASK |
> > +			    TX_FIFO_OVFLW_MASK | HS_TX_TIMEOUT_MASK);
> > +
> > +	nwl_dsi_write(dsi, IRQ_MASK, irq_enable);
> > +}
> > +
> > +static int nwl_dsi_host_attach(struct mipi_dsi_host *dsi_host,
> > +			       struct mipi_dsi_device *device)
> > +{
> > +	struct imx_nwl_dsi *dsi =
> > +		container_of(dsi_host, struct imx_nwl_dsi, dsi_host);
> > +	struct device *dev = dsi->dev;
> > +	struct drm_bridge *bridge;
> > +	struct drm_panel *panel;
> > +	int ret;
> > +
> > +	DRM_DEV_INFO(dev, "lanes=%u, format=0x%x flags=0x%lx\n", device->lanes,
> > +		     device->format, device->mode_flags);
> > +
> > +	if (device->lanes < 1 || device->lanes > 4)
> > +		return -EINVAL;
> > +
> > +	dsi->lanes = device->lanes;
> > +	dsi->format = device->format;
> > +	dsi->dsi_mode_flags = device->mode_flags;
> > +
> > +	ret = drm_of_find_panel_or_bridge(dsi->dev->of_node, 1, 0, &panel,
> > +					  &bridge);
> > +	if (ret)
> > +		return ret;
> > +
> > +	if (panel) {
> > +		bridge = drm_panel_bridge_add(panel, DRM_MODE_CONNECTOR_DSI);
> > +		if (IS_ERR(bridge))
> > +			return PTR_ERR(bridge);
> > +	}
> > +
> > +	dsi->panel_bridge = bridge;
> > +	drm_bridge_add(&dsi->bridge);
> > +
> > +	return 0;
> > +}
> > +
> > +static int nwl_dsi_host_detach(struct mipi_dsi_host *dsi_host,
> > +			       struct mipi_dsi_device *device)
> > +{
> > +	struct imx_nwl_dsi *dsi =
> > +		container_of(dsi_host, struct imx_nwl_dsi, dsi_host);
> > +
> > +	drm_of_panel_bridge_remove(dsi->dev->of_node, 1, 0);
> > +	drm_bridge_remove(&dsi->bridge);
> > +
> > +	return 0;
> > +}
> > +
> > +static bool nwl_dsi_read_packet(struct imx_nwl_dsi *dsi, u32 status)
> > +{
> > +	struct device *dev = dsi->dev;
> > +	struct mipi_dsi_transfer *xfer = dsi->xfer;
> > +	u8 *payload = xfer->msg->rx_buf;
> > +	u32 val;
> > +	u16 word_count;
> > +	u8 channel;
> > +	u8 data_type;
> > +
> > +	xfer->status = 0;
> > +
> > +	if (xfer->rx_word_count == 0) {
> > +		if (!(status & RX_PKT_HDR_RCVD))
> > +			return false;
> > +		/* Get the RX header and parse it */
> > +		val = nwl_dsi_read(dsi, RX_PKT_HEADER);
> > +		word_count = WC(val);
> > +		channel = RX_VC(val);
> > +		data_type = RX_DT(val);
> > +
> > +		if (channel != xfer->msg->channel) {
> > +			DRM_DEV_ERROR(dev,
> > +				      "[%02X] Channel mismatch (%u != %u)\n",
> > +				      xfer->cmd, channel, xfer->msg->channel);
> > +			return true;
> > +		}
> > +
> > +		switch (data_type) {
> > +		case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_2BYTE:
> > +			/* Fall through */
> > +		case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_2BYTE:
> > +			if (xfer->msg->rx_len > 1) {
> > +				/* read second byte */
> > +				payload[1] = word_count >> 8;
> > +				++xfer->rx_len;
> > +			}
> > +			/* Fall through */
> > +		case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_1BYTE:
> > +			/* Fall through */
> > +		case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE:
> > +			if (xfer->msg->rx_len > 0) {
> > +				/* read first byte */
> > +				payload[0] = word_count & 0xff;
> > +				++xfer->rx_len;
> > +			}
> > +			xfer->status = xfer->rx_len;
> > +			return true;
> > +		case MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT:
> > +			word_count &= 0xff;
> > +			DRM_DEV_ERROR(dev, "[%02X] DSI error report: 0x%02x\n",
> > +				      xfer->cmd, word_count);
> > +			xfer->status = -EPROTO;
> > +			return true;
> > +		}
> > +
> > +		if (word_count > xfer->msg->rx_len) {
> > +			DRM_DEV_ERROR(
> > +				dev,
> > +				"[%02X] Receive buffer too small: %lu (< %u)\n",
> > +				xfer->cmd, xfer->msg->rx_len, word_count);
> > +			return true;
> > +		}
> > +
> > +		xfer->rx_word_count = word_count;
> > +	} else {
> > +		/* Set word_count from previous header read */
> > +		word_count = xfer->rx_word_count;
> > +	}
> > +
> > +	/* If RX payload is not yet received, wait for it */
> > +	if (!(status & RX_PKT_PAYLOAD_DATA_RCVD))
> > +		return false;
> > +
> > +	/* Read the RX payload */
> > +	while (word_count >= 4) {
> > +		val = nwl_dsi_read(dsi, RX_PAYLOAD);
> > +		payload[0] = (val >> 0) & 0xff;
> > +		payload[1] = (val >> 8) & 0xff;
> > +		payload[2] = (val >> 16) & 0xff;
> > +		payload[3] = (val >> 24) & 0xff;
> > +		payload += 4;
> > +		xfer->rx_len += 4;
> > +		word_count -= 4;
> > +	}
> > +
> > +	if (word_count > 0) {
> > +		val = nwl_dsi_read(dsi, RX_PAYLOAD);
> > +		switch (word_count) {
> > +		case 3:
> > +			payload[2] = (val >> 16) & 0xff;
> > +			++xfer->rx_len;
> > +			/* Fall through */
> > +		case 2:
> > +			payload[1] = (val >> 8) & 0xff;
> > +			++xfer->rx_len;
> > +			/* Fall through */
> > +		case 1:
> > +			payload[0] = (val >> 0) & 0xff;
> > +			++xfer->rx_len;
> > +			break;
> > +		}
> > +	}
> > +
> > +	xfer->status = xfer->rx_len;
> > +
> > +	return true;
> > +}
> > +
> > +static void nwl_dsi_finish_transmission(struct imx_nwl_dsi *dsi, u32 status)
> > +{
> > +	struct mipi_dsi_transfer *xfer = dsi->xfer;
> > +	bool end_packet = false;
> > +
> > +	if (!xfer)
> > +		return;
> > +
> > +	if (status & TX_FIFO_OVFLW) {
> > +		DRM_DEV_ERROR_RATELIMITED(dsi->dev, "tx fifo overflow\n");
> > +		return;
> > +	}
> > +
> > +	if (status & HS_TX_TIMEOUT) {
> > +		DRM_DEV_ERROR_RATELIMITED(dsi->dev, "HS tx timeout\n");
> > +		return;
> > +	}
> > +
> > +	if (xfer->direction == DSI_PACKET_SEND && status & TX_PKT_DONE) {
> > +		xfer->status = xfer->tx_len;
> > +		end_packet = true;
> > +	} else if (status & DPHY_DIRECTION &&
> > +		   ((status & (RX_PKT_HDR_RCVD | RX_PKT_PAYLOAD_DATA_RCVD)))) {
> > +		end_packet = nwl_dsi_read_packet(dsi, status);
> > +	}
> > +
> > +	if (end_packet)
> > +		complete(&xfer->completed);
> > +}
> > +
> > +static void nwl_dsi_begin_transmission(struct imx_nwl_dsi *dsi)
> > +{
> > +	struct mipi_dsi_transfer *xfer = dsi->xfer;
> > +	struct mipi_dsi_packet *pkt = &xfer->packet;
> > +	const u8 *payload;
> > +	size_t length;
> > +	u16 word_count;
> > +	u8 hs_mode;
> > +	u32 val;
> > +	u32 hs_workaround = 0;
> > +
> > +	/* Send the payload, if any */
> > +	length = pkt->payload_length;
> > +	payload = pkt->payload;
> > +
> > +	while (length >= 4) {
> > +		val = get_unaligned_le32(payload);
> 
> The framework doesn't guarantee the payload to be aligned on a multiple
> of 4 bytes ?

It does as far as i can tell, dropped.

> 
> > +		hs_workaround |= !(val & 0xFFFF00);
> > +		nwl_dsi_write(dsi, TX_PAYLOAD, val);
> > +		payload += 4;
> > +		length -= 4;
> > +	}
> > +	/* Send the rest of the payload */
> > +	val = 0;
> > +	switch (length) {
> > +	case 3:
> > +		val |= payload[2] << 16;
> > +		/* Fall through */
> > +	case 2:
> > +		val |= payload[1] << 8;
> > +		hs_workaround |= !(val & 0xFFFF00);
> > +		/* Fall through */
> > +	case 1:
> > +		val |= payload[0];
> > +		nwl_dsi_write(dsi, TX_PAYLOAD, val);
> > +		break;
> > +	}
> > +	xfer->tx_len = pkt->payload_length;
> > +
> > +	/*
> > +	 * Send the header
> > +	 * header[0] = Virtual Channel + Data Type
> > +	 * header[1] = Word Count LSB (LP) or first param (SP)
> > +	 * header[2] = Word Count MSB (LP) or second param (SP)
> > +	 */
> > +	word_count = pkt->header[1] | (pkt->header[2] << 8);
> > +	if ((hs_workaround && USE_E11418_HS_MODE_QUIRK(dsi->quirks))) {
> > +		DRM_DEV_DEBUG_DRIVER(dsi->dev,
> > +				     "Using hs mode workaround for cmd 0x%x\n",
> > +				     xfer->cmd);
> > +		hs_mode = 1;
> > +	} else {
> > +		hs_mode = (xfer->msg->flags & MIPI_DSI_MSG_USE_LPM) ? 0 : 1;
> > +	}
> > +	val = WC(word_count) |
> > +		TX_VC(xfer->msg->channel) |
> > +		TX_DT(xfer->msg->type) |
> > +		HS_SEL(hs_mode) |
> > +		BTA_TX(xfer->need_bta);
> > +	nwl_dsi_write(dsi, PKT_CONTROL, val);
> > +
> > +	/* Send packet command */
> > +	nwl_dsi_write(dsi, SEND_PACKET, 0x1);
> > +}
> > +
> > +static ssize_t nwl_dsi_host_transfer(struct mipi_dsi_host *dsi_host,
> > +				     const struct mipi_dsi_msg *msg)
> > +{
> > +	struct imx_nwl_dsi *dsi =
> > +		container_of(dsi_host, struct imx_nwl_dsi, dsi_host);
> > +	struct mipi_dsi_transfer xfer;
> > +	ssize_t ret = 0;
> > +
> > +	/* Create packet to be sent */
> > +	dsi->xfer = &xfer;
> > +	ret = mipi_dsi_create_packet(&xfer.packet, msg);
> > +	if (ret < 0) {
> > +		dsi->xfer = NULL;
> > +		return ret;
> > +	}
> > +
> > +	if ((msg->type & MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM ||
> > +	     msg->type & MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM ||
> > +	     msg->type & MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM ||
> > +	     msg->type & MIPI_DSI_DCS_READ) &&
> > +	    msg->rx_len > 0 && msg->rx_buf != NULL)
> > +		xfer.direction = DSI_PACKET_RECEIVE;
> > +	else
> > +		xfer.direction = DSI_PACKET_SEND;
> > +
> > +	xfer.need_bta = (xfer.direction == DSI_PACKET_RECEIVE);
> > +	xfer.need_bta |= (msg->flags & MIPI_DSI_MSG_REQ_ACK) ? 1 : 0;
> > +	xfer.msg = msg;
> > +	xfer.status = -ETIMEDOUT;
> > +	xfer.rx_word_count = 0;
> > +	xfer.rx_len = 0;
> > +	xfer.cmd = 0x00;
> > +	if (msg->tx_len > 0)
> > +		xfer.cmd = ((u8 *)(msg->tx_buf))[0];
> > +	init_completion(&xfer.completed);
> > +
> > +	nwl_dsi_enable_rx_clock(dsi);
> > +
> > +	/* Initiate the DSI packet transmision */
> > +	nwl_dsi_begin_transmission(dsi);
> > +
> > +	if (!wait_for_completion_timeout(&xfer.completed, MIPI_FIFO_TIMEOUT)) {
> > +		DRM_DEV_ERROR(dsi_host->dev, "[%02X] DSI transfer timed out\n",
> > +			      xfer.cmd);
> > +		ret = -ETIMEDOUT;
> > +	} else {
> > +		ret = xfer.status;
> > +	}
> > +
> > +	clk_disable_unprepare(dsi->rx_esc_clk);
> > +
> > +	return ret;
> > +}
> > +
> > +const struct mipi_dsi_host_ops nwl_dsi_host_ops = {
> > +	.attach = nwl_dsi_host_attach,
> > +	.detach = nwl_dsi_host_detach,
> > +	.transfer = nwl_dsi_host_transfer,
> > +};
> > +
> > +irqreturn_t nwl_dsi_irq_handler(int irq, void *data)
> > +{
> > +	u32 irq_status;
> > +	struct imx_nwl_dsi *dsi = data;
> > +
> > +	irq_status = nwl_dsi_read(dsi, IRQ_STATUS);
> > +
> > +	if (irq_status & TX_PKT_DONE || irq_status & RX_PKT_HDR_RCVD ||
> > +	    irq_status & RX_PKT_PAYLOAD_DATA_RCVD)
> > +		nwl_dsi_finish_transmission(dsi, irq_status);
> > +
> > +	return IRQ_HANDLED;
> > +}
> > +EXPORT_SYMBOL_GPL(nwl_dsi_irq_handler);
> > +
> > +int nwl_dsi_enable(struct imx_nwl_dsi *dsi)
> > +{
> > +	struct device *dev = dsi->dev;
> > +	union phy_configure_opts *phy_cfg = &dsi->phy_cfg;
> > +	int ret;
> > +
> > +	if (!dsi->lanes) {
> > +		DRM_DEV_ERROR(dev, "Need DSI lanes: %d\n", dsi->lanes);
> > +		return -EINVAL;
> > +	}
> > +
> > +	ret = phy_init(dsi->phy);
> > +	if (ret < 0) {
> > +		DRM_DEV_ERROR(dev, "Failed to init DSI phy: %d\n", ret);
> > +		return ret;
> > +	}
> > +
> > +	ret = phy_configure(dsi->phy, phy_cfg);
> > +	if (ret < 0) {
> > +		DRM_DEV_ERROR(dev, "Failed to configure DSI phy: %d\n", ret);
> > +		return ret;
> > +	}
> > +
> > +	ret = nwl_dsi_enable_tx_clock(dsi);
> > +	if (ret < 0) {
> > +		DRM_DEV_ERROR(dev, "Failed to enable tx clock: %d\n", ret);
> > +		return ret;
> > +	}
> > +
> > +	ret = nwl_dsi_config_host(dsi);
> > +	if (ret < 0) {
> > +		DRM_DEV_ERROR(dev, "Failed to set up DSI: %d", ret);
> > +		return ret;
> > +	}
> > +
> > +	ret = nwl_dsi_config_dpi(dsi);
> > +	if (ret < 0) {
> > +		DRM_DEV_ERROR(dev, "Failed to set up DPI: %d", ret);
> > +		return ret;
> > +	}
> > +
> > +	ret = phy_power_on(dsi->phy);
> > +	if (ret < 0) {
> > +		DRM_DEV_ERROR(dev, "Failed to power on DPHY (%d)\n", ret);
> > +		return ret;
> > +	}
> > +
> > +	nwl_dsi_init_interrupts(dsi);
> > +
> > +	return 0;
> > +}
> > +EXPORT_SYMBOL_GPL(nwl_dsi_enable);
> > +
> > +int nwl_dsi_disable(struct imx_nwl_dsi *dsi)
> > +{
> > +	struct device *dev = dsi->dev;
> > +
> > +	DRM_DEV_DEBUG_DRIVER(dev, "Disabling clocks and phy\n");
> > +
> > +	phy_power_off(dsi->phy);
> > +	phy_exit(dsi->phy);
> > +
> > +	/* Disabling the clock before the phy breaks enabling dsi again */
> > +	clk_disable_unprepare(dsi->tx_esc_clk);
> > +
> > +	return 0;
> > +}
> > +EXPORT_SYMBOL_GPL(nwl_dsi_disable);
> > diff --git a/drivers/gpu/drm/bridge/imx-nwl/nwl-dsi.h b/drivers/gpu/drm/bridge/imx-nwl/nwl-dsi.h
> > new file mode 100644
> > index 000000000000..7bcf804843e2
> > --- /dev/null
> > +++ b/drivers/gpu/drm/bridge/imx-nwl/nwl-dsi.h
> > @@ -0,0 +1,111 @@
> > +/* SPDX-License-Identifier: GPL-2.0+ */
> > +/*
> > + * i.MX8 NWL MIPI DSI host driver
> > + *
> > + * Copyright (C) 2017 NXP
> > + * Copyright (C) 2019 Purism SPC
> > + */
> > +#ifndef __NWL_DSI_H__
> > +#define __NWL_DSI_H__
> > +
> > +#include <drm/drm_mipi_dsi.h>
> > +
> > +/* DSI HOST registers */
> > +#define CFG_NUM_LANES			0x0
> 
> Some of the register names are quite prone to namespace clashes. I
> recommend prefixing them all with NWL_DSI_.

Done, also the defines in nwl-dsi.c.

> 
> > +#define CFG_NONCONTINUOUS_CLK		0x4
> > +#define CFG_T_PRE			0x8
> > +#define CFG_T_POST			0xc
> > +#define CFG_TX_GAP			0x10
> > +#define CFG_AUTOINSERT_EOTP		0x14
> > +#define CFG_EXTRA_CMDS_AFTER_EOTP	0x18
> > +#define CFG_HTX_TO_COUNT		0x1c
> > +#define CFG_LRX_H_TO_COUNT		0x20
> > +#define CFG_BTA_H_TO_COUNT		0x24
> > +#define CFG_TWAKEUP			0x28
> > +#define CFG_STATUS_OUT			0x2c
> > +#define RX_ERROR_STATUS			0x30
> > +
> > +/* DSI DPI registers */
> > +#define PIXEL_PAYLOAD_SIZE		0x200
> > +#define PIXEL_FIFO_SEND_LEVEL		0x204
> > +#define INTERFACE_COLOR_CODING		0x208
> > +#define PIXEL_FORMAT			0x20c
> > +#define VSYNC_POLARITY			0x210
> > +#define VSYNC_POLARITY_ACTIVE_LOW	0
> > +#define VSYNC_POLARITY_ACTIVE_HIGH	BIT(1)
> > +
> > +#define HSYNC_POLARITY			0x214
> > +#define HSYNC_POLARITY_ACTIVE_LOW	0
> > +#define HSYNC_POLARITY_ACTIVE_HIGH	BIT(1)
> > +
> > +#define VIDEO_MODE			0x218
> > +#define HFP				0x21c
> > +#define HBP				0x220
> > +#define HSA				0x224
> > +#define ENABLE_MULT_PKTS		0x228
> > +#define VBP				0x22c
> > +#define VFP				0x230
> > +#define BLLP_MODE			0x234
> > +#define USE_NULL_PKT_BLLP		0x238
> > +#define VACTIVE				0x23c
> > +#define VC				0x240
> > +
> > +/* DSI APB PKT control */
> > +#define TX_PAYLOAD			0x280
> > +#define PKT_CONTROL			0x284
> > +#define SEND_PACKET			0x288
> > +#define PKT_STATUS			0x28c
> > +#define PKT_FIFO_WR_LEVEL		0x290
> > +#define PKT_FIFO_RD_LEVEL		0x294
> > +#define RX_PAYLOAD			0x298
> > +#define RX_PKT_HEADER			0x29c
> > +
> > +/* DSI IRQ handling */
> > +#define IRQ_STATUS			0x2a0
> > +#define SM_NOT_IDLE			BIT(0)
> > +#define TX_PKT_DONE			BIT(1)
> > +#define DPHY_DIRECTION			BIT(2)
> > +#define TX_FIFO_OVFLW			BIT(3)
> > +#define TX_FIFO_UDFLW			BIT(4)
> > +#define RX_FIFO_OVFLW			BIT(5)
> > +#define RX_FIFO_UDFLW			BIT(6)
> > +#define RX_PKT_HDR_RCVD			BIT(7)
> > +#define RX_PKT_PAYLOAD_DATA_RCVD	BIT(8)
> > +#define BTA_TIMEOUT			BIT(29)
> > +#define LP_RX_TIMEOUT			BIT(30)
> > +#define HS_TX_TIMEOUT			BIT(31)
> > +
> > +#define IRQ_STATUS2			0x2a4
> > +#define SINGLE_BIT_ECC_ERR		BIT(0)
> > +#define MULTI_BIT_ECC_ERR		BIT(1)
> > +#define CRC_ERR				BIT(2)
> > +
> > +#define IRQ_MASK			0x2a8
> > +#define SM_NOT_IDLE_MASK		BIT(0)
> > +#define TX_PKT_DONE_MASK		BIT(1)
> > +#define DPHY_DIRECTION_MASK		BIT(2)
> > +#define TX_FIFO_OVFLW_MASK		BIT(3)
> > +#define TX_FIFO_UDFLW_MASK		BIT(4)
> > +#define RX_FIFO_OVFLW_MASK		BIT(5)
> > +#define RX_FIFO_UDFLW_MASK		BIT(6)
> > +#define RX_PKT_HDR_RCVD_MASK		BIT(7)
> > +#define RX_PKT_PAYLOAD_DATA_RCVD_MASK	BIT(8)
> > +#define BTA_TIMEOUT_MASK		BIT(29)
> > +#define LP_RX_TIMEOUT_MASK		BIT(30)
> > +#define HS_TX_TIMEOUT_MASK		BIT(31)
> > +
> > +#define IRQ_MASK2			0x2ac
> > +#define SINGLE_BIT_ECC_ERR_MASK		BIT(0)
> > +#define MULTI_BIT_ECC_ERR_MASK		BIT(1)
> > +#define CRC_ERR_MASK			BIT(2)
> > +
> > +extern const struct mipi_dsi_host_ops nwl_dsi_host_ops;
> > +
> > +irqreturn_t nwl_dsi_irq_handler(int irq, void *data);
> > +int nwl_dsi_enable(struct imx_nwl_dsi *dsi);
> > +int nwl_dsi_disable(struct imx_nwl_dsi *dsi);
> > +int nwl_dsi_get_dphy_params(struct imx_nwl_dsi *dsi,
> > +			    const struct drm_display_mode *mode,
> > +			    union phy_configure_opts *phy_opts);
> > +
> > +#endif /* __NWL_DSI_H__ */
> 
> -- 
> Regards,
> 
> Laurent Pinchart
> 

Cheers and thanks for having a look!
 -- Guido

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox