[PATCH/RFC] iommu/ipmmu-vmsa: Initial R-Car Gen3 VA64 mode support
diff mbox

Message ID 148517236353.14544.12595546402748556370.sendpatchset@little-apple
State Under Review
Delegated to: Geert Uytterhoeven
Headers show

Commit Message

Magnus Damm Jan. 23, 2017, 11:52 a.m. UTC
From: Magnus Damm <damm+renesas@opensource.se>

Here's a prototype that enables IMCTR_VA64 support for the IPMMU driver
on R-Car Gen3 platforms. I've tested it lightly on r8a7796 Salvator-X
with local second serial port code and SYS-DMAC support via DMA Engine.

My goal has been to enable 40 bits or more of IOVA space, but it turns
out that it requires either 64K page size support or support for 4K pages
starting from level 0.

For now this keeps 32-bit IOVA space however the hardware gets configured
to enable IMCTR_VA64 which also seems to require setting up TSZ0[5:0].

Signed-off-by: Magnus Damm <damm+renesas@opensource.se>
---

 Developed on top of renesas-drivers-2017-01-10-v4.10-rc3
 
 drivers/iommu/ipmmu-vmsa.c |   18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

Comments

Geert Uytterhoeven Jan. 23, 2017, 12:53 p.m. UTC | #1
Hi Magnus,

On Mon, Jan 23, 2017 at 12:52 PM, Magnus Damm <magnus.damm@gmail.com> wrote:
> From: Magnus Damm <damm+renesas@opensource.se>
>
> Here's a prototype that enables IMCTR_VA64 support for the IPMMU driver
> on R-Car Gen3 platforms. I've tested it lightly on r8a7796 Salvator-X
> with local second serial port code and SYS-DMAC support via DMA Engine.
>
> My goal has been to enable 40 bits or more of IOVA space, but it turns
> out that it requires either 64K page size support or support for 4K pages
> starting from level 0.
>
> For now this keeps 32-bit IOVA space however the hardware gets configured
> to enable IMCTR_VA64 which also seems to require setting up TSZ0[5:0].
>
> Signed-off-by: Magnus Damm <damm+renesas@opensource.se>

Do you mean this is incompatible with "dmaengine: rcar-dmac: Widen DMA mask
to 40 bits" (http://www.spinics.net/lists/linux-renesas-soc/msg08338.html),
so we can still not upstream that patch?

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

Patch
diff mbox

--- 0001/drivers/iommu/ipmmu-vmsa.c
+++ work/drivers/iommu/ipmmu-vmsa.c	2017-01-23 20:43:31.200607110 +0900
@@ -39,6 +39,7 @@  struct ipmmu_features {
 	bool has_eight_ctx;
 	bool setup_imbuscr;
 	bool twobit_imttbcr_sl0;
+	bool imctr_va64;
 };
 
 struct ipmmu_vmsa_device {
@@ -117,6 +118,7 @@  static void set_archdata(struct device *
 #define IM_CTX_SIZE			0x40
 
 #define IMCTR				0x0000
+#define IMCTR_VA64			(1 << 29)
 #define IMCTR_TRE			(1 << 17)
 #define IMCTR_AFE			(1 << 16)
 #define IMCTR_RTSEL_MASK		(3 << 4)
@@ -430,8 +432,9 @@  static int ipmmu_domain_init_context(str
 	 */
 	domain->cfg.iommu_dev = domain->root->dev;
 
-	domain->iop = alloc_io_pgtable_ops(ARM_32_LPAE_S1, &domain->cfg,
-					   domain);
+	domain->iop = alloc_io_pgtable_ops(domain->root->features->imctr_va64 ?
+					   ARM_64_LPAE_S1 : ARM_32_LPAE_S1,
+					   &domain->cfg, domain);
 	if (!domain->iop)
 		return -EINVAL;
 
@@ -462,6 +465,12 @@  static int ipmmu_domain_init_context(str
 	else
 		tmp = IMTTBCR_SL0_LVL_1;
 
+	/*
+	 * For IMCTR_VA64 and ARM_64_LPAE_S1 we need lowest bits of TTBCR
+	 */
+	if (domain->root->features->imctr_va64)
+		tmp |= 32;
+
 	ipmmu_ctx_write(domain, IMTTBCR, IMTTBCR_EAE |
 			IMTTBCR_SH0_INNER_SHAREABLE | IMTTBCR_ORGN0_WB_WA |
 			IMTTBCR_IRGN0_WB_WA | tmp);
@@ -488,7 +497,8 @@  static int ipmmu_domain_init_context(str
 	 * required when modifying the context registers.
 	 */
 	ipmmu_ctx_write2(domain, IMCTR,
-			 IMCTR_INTEN | IMCTR_FLUSH | IMCTR_MMUEN);
+			 (domain->root->features->imctr_va64 ? IMCTR_VA64 : 0)
+			 | IMCTR_INTEN | IMCTR_FLUSH | IMCTR_MMUEN);
 
 	return 0;
 }
@@ -1098,6 +1108,7 @@  static const struct ipmmu_features ipmmu
 	.has_eight_ctx = false,
 	.setup_imbuscr = true,
 	.twobit_imttbcr_sl0 = false,
+	.imctr_va64 = false,
 };
 
 static const struct ipmmu_features ipmmu_features_rcar_gen3 = {
@@ -1106,6 +1117,7 @@  static const struct ipmmu_features ipmmu
 	.has_eight_ctx = true,
 	.setup_imbuscr = false,
 	.twobit_imttbcr_sl0 = true,
+	.imctr_va64 = true,
 };
 
 static const struct of_device_id ipmmu_of_ids[] = {