diff mbox series

[V2,07/10] iommu/ipmmu-vmsa: Add Renesas R8A779F0 (R-Car S4) support

Message ID 1640034957-19764-8-git-send-email-olekstysh@gmail.com (mailing list archive)
State New, archived
Headers show
Series Add support for Renesas R-Car S4 IPMMU and other misc changes | expand

Commit Message

Oleksandr Tyshchenko Dec. 20, 2021, 9:15 p.m. UTC
From: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>

Based on the following Linux upsteam commit:
7a62ced8ebd0e1b692c9dc4781a8d4ddb0f74792

Original commit message:
 commit 7a62ced8ebd0e1b692c9dc4781a8d4ddb0f74792
 Author: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
 Date:   Tue Sep 7 17:30:20 2021 +0900

  iommu/ipmmu-vmsa: Add support for r8a779a0

  Add support for r8a779a0 (R-Car V3U). The IPMMU hardware design
  of this SoC differs than others. So, add a new ipmmu_features for it.

  Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
  Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
  Link: https://lore.kernel.org/r/20210907083020.907648-3-yoshihiro.shimoda.uh@renesas.com
  Signed-off-by: Joerg Roedel <jroedel@suse.de>

**********

The R-Car S4 is an automotive System-on-Chip (SoC) for Car
Server/Communication Gateway and is one of the first products
in Renesas’ 4th-generation R-Car Family.

The integrated IOMMU HW is also VMSA-compatible and supports
stage 2 translation table format, therefore can be used with
current driver with slight modifications (thanks to the prereq
work).

In the context of Xen driver the main differences between Gen3
and Gen4 are the following:
- HW capacity was enlarged to support up to 16 IPMMU contexts
  (sets of page table) and up to 64 micro-TLBs per IPMMU device
- the memory mapped registers have different bases and offsets

Please note that Linux upstream doesn't support R-Car S4 SoC
yet unlike Renesas BSP [1], but it was decided to reuse upstream
patch for R-Car V3U anyway as the IPMMU HW settings are similar.

[1]
7003b9f732cf iommu/ipmmu-vmsa: Add Renesas R8A779F0 (R-Car S4) support
https://github.com/renesas-rcar/linux-bsp/tree/v5.10.41/rcar-5.1.3.rc5

Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
Signed-off-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
---
Changes V1 -> V2:
   - base on the Linux upsteam patch instead of BSP's one
   - update patch description and comments in code
   - replace ipmmu_features_rcar_s4 with ipmmu_features_rcar_gen4
   - introduce control_offset_base field
---
 xen/drivers/passthrough/Kconfig          |  6 +--
 xen/drivers/passthrough/arm/ipmmu-vmsa.c | 63 +++++++++++++++++++++++---------
 2 files changed, 49 insertions(+), 20 deletions(-)

Comments

Yoshihiro Shimoda Dec. 29, 2021, 12:53 a.m. UTC | #1
Hello Oleksandr-san,

> From: Oleksandr Tyshchenko, Sent: Tuesday, December 21, 2021 6:16 AM
> 
> From: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
> 
> Based on the following Linux upsteam commit:
> 7a62ced8ebd0e1b692c9dc4781a8d4ddb0f74792
> 
> Original commit message:
>  commit 7a62ced8ebd0e1b692c9dc4781a8d4ddb0f74792
>  Author: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
>  Date:   Tue Sep 7 17:30:20 2021 +0900
> 
>   iommu/ipmmu-vmsa: Add support for r8a779a0
> 
>   Add support for r8a779a0 (R-Car V3U). The IPMMU hardware design
>   of this SoC differs than others. So, add a new ipmmu_features for it.
> 
>   Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
>   Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
>   Link:
> https://jpn01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flore.kernel.org%2Fr%2F20210907083020.907648-3-yosh
> ihiro.shimoda.uh%40renesas.com&amp;data=04%7C01%7Cyoshihiro.shimoda.uh%40renesas.com%7C995a1c66b6d841ccc79a08d9c3fdf
> 90a%7C53d82571da1947e49cb4625a166a4a2a%7C0%7C0%7C637756317833053012%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQ
> IjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&amp;sdata=TirhJToNqy33Fzt0tSpukl9YFOj4iHgd3M1lX8W%2Bxlo%3D&amp;res
> erved=0
>   Signed-off-by: Joerg Roedel <jroedel@suse.de>
> 
> **********
> 
> The R-Car S4 is an automotive System-on-Chip (SoC) for Car
> Server/Communication Gateway and is one of the first products
> in Renesas' 4th-generation R-Car Family.
> 
> The integrated IOMMU HW is also VMSA-compatible and supports
> stage 2 translation table format, therefore can be used with
> current driver with slight modifications (thanks to the prereq
> work).
> 
> In the context of Xen driver the main differences between Gen3
> and Gen4 are the following:
> - HW capacity was enlarged to support up to 16 IPMMU contexts
>   (sets of page table) and up to 64 micro-TLBs per IPMMU device
> - the memory mapped registers have different bases and offsets
> 
> Please note that Linux upstream doesn't support R-Car S4 SoC
> yet unlike Renesas BSP [1], but it was decided to reuse upstream
> patch for R-Car V3U anyway as the IPMMU HW settings are similar.
> 
> [1]
> 7003b9f732cf iommu/ipmmu-vmsa: Add Renesas R8A779F0 (R-Car S4) support
<snip>
> 
> Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
> Signed-off-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>

Thank you for the patch!

Reviewed-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>

Best regards,
Yoshihiro Shimoda
diff mbox series

Patch

diff --git a/xen/drivers/passthrough/Kconfig b/xen/drivers/passthrough/Kconfig
index 09505aa..479d7de 100644
--- a/xen/drivers/passthrough/Kconfig
+++ b/xen/drivers/passthrough/Kconfig
@@ -25,14 +25,14 @@  config ARM_SMMU_V3
 	 the ARM SMMUv3 architecture.
 
 config IPMMU_VMSA
-	bool "Renesas IPMMU-VMSA found in R-Car Gen3 SoCs"
+	bool "Renesas IPMMU-VMSA found in R-Car Gen3/Gen4 SoCs"
 	depends on ARM_64
 	---help---
 	  Support for implementations of the Renesas IPMMU-VMSA found
-	  in R-Car Gen3 SoCs.
+	  in R-Car Gen3/Gen4 SoCs.
 
 	  Say Y here if you are using newest R-Car Gen3 SoCs revisions
-	  (H3 ES3.0, M3-W+, etc) which IPMMU hardware supports stage 2
+	  (H3 ES3.0, M3-W+, etc) or Gen4 SoCs which IPMMU hardware supports stage 2
 	  translation table format and is able to use CPU's P2M table as is.
 
 endif
diff --git a/xen/drivers/passthrough/arm/ipmmu-vmsa.c b/xen/drivers/passthrough/arm/ipmmu-vmsa.c
index d8f96fc..14848ce 100644
--- a/xen/drivers/passthrough/arm/ipmmu-vmsa.c
+++ b/xen/drivers/passthrough/arm/ipmmu-vmsa.c
@@ -1,15 +1,15 @@ 
 /*
  * xen/drivers/passthrough/arm/ipmmu-vmsa.c
  *
- * Driver for the Renesas IPMMU-VMSA found in R-Car Gen3 SoCs.
+ * Driver for the Renesas IPMMU-VMSA found in R-Car Gen3/Gen4 SoCs.
  *
  * The IPMMU-VMSA is VMSA-compatible I/O Memory Management Unit (IOMMU)
  * which provides address translation and access protection functionalities
  * to processing units and interconnect networks.
  *
  * Please note, current driver is supposed to work only with newest
- * R-Car Gen3 SoCs revisions which IPMMU hardware supports stage 2 translation
- * table format and is able to use CPU's P2M table as is.
+ * R-Car Gen3/Gen4 SoCs revisions which IPMMU hardware supports stage 2
+ * translation table format and is able to use CPU's P2M table as is.
  *
  * Based on Linux's IPMMU-VMSA driver from Renesas BSP:
  *    drivers/iommu/ipmmu-vmsa.c
@@ -20,9 +20,9 @@ 
  * and Xen's SMMU driver:
  *    xen/drivers/passthrough/arm/smmu.c
  *
- * Copyright (C) 2014-2019 Renesas Electronics Corporation
+ * Copyright (C) 2014-2021 Renesas Electronics Corporation
  *
- * Copyright (C) 2016-2019 EPAM Systems Inc.
+ * Copyright (C) 2016-2021 EPAM Systems Inc.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms and conditions of the GNU General Public
@@ -68,12 +68,13 @@ 
     dev_print(dev, XENLOG_ERR, fmt, ## __VA_ARGS__)
 
 /*
- * R-Car Gen3 SoCs make use of up to 8 IPMMU contexts (sets of page table) and
- * these can be managed independently. Each context is mapped to one Xen domain.
+ * R-Car Gen3/Gen4 SoCs make use of up to 16 IPMMU contexts (sets of page table)
+ * and these can be managed independently. Each context is mapped to one Xen
+ * domain.
  */
-#define IPMMU_CTX_MAX     8U
-/* R-Car Gen3 SoCs make use of up to 48 micro-TLBs per IPMMU device. */
-#define IPMMU_UTLB_MAX    48U
+#define IPMMU_CTX_MAX     16U
+/* R-Car Gen3/Gen4 SoCs make use of up to 64 micro-TLBs per IPMMU device. */
+#define IPMMU_UTLB_MAX    64U
 
 /* IPMMU context supports IPA size up to 40 bit. */
 #define IPMMU_MAX_P2M_IPA_BITS    40
@@ -112,6 +113,8 @@  struct ipmmu_features {
     unsigned int ctx_offset_base;
     unsigned int ctx_offset_stride;
     unsigned int utlb_offset_base;
+    unsigned int control_offset_base;
+    unsigned int imuctr_ttsel_mask;
 };
 
 /* Root/Cache IPMMU device's information */
@@ -211,7 +214,6 @@  static DEFINE_SPINLOCK(ipmmu_devices_lock);
 #define IMUCTR0(n)             (0x0300 + ((n) * 16))
 #define IMUCTR32(n)            (0x0600 + (((n) - 32) * 16))
 #define IMUCTR_TTSEL_MMU(n)    ((n) << 4)
-#define IMUCTR_TTSEL_MASK      (15 << 4)
 #define IMUCTR_TTSEL_SHIFT     4
 #define IMUCTR_FLUSH           (1 << 1)
 #define IMUCTR_MMUEN           (1 << 0)
@@ -316,8 +318,12 @@  static void ipmmu_write(struct ipmmu_vmsa_device *mmu, uint32_t offset,
 static unsigned int ipmmu_ctx_reg(struct ipmmu_vmsa_device *mmu,
                                   unsigned int context_id, uint32_t reg)
 {
-    return mmu->features->ctx_offset_base +
-        context_id * mmu->features->ctx_offset_stride + reg;
+    unsigned int base = mmu->features->ctx_offset_base;
+
+    if ( context_id > 7 )
+        base += 0x800 - 8 * 0x40;
+
+    return base + context_id * mmu->features->ctx_offset_stride + reg;
 }
 
 static uint32_t ipmmu_ctx_read(struct ipmmu_vmsa_device *mmu,
@@ -448,7 +454,8 @@  static int ipmmu_utlb_enable(struct ipmmu_vmsa_domain *domain,
     {
         unsigned int context_id;
 
-        context_id = (imuctr & IMUCTR_TTSEL_MASK) >> IMUCTR_TTSEL_SHIFT;
+        context_id = (imuctr & mmu->features->imuctr_ttsel_mask) >>
+            IMUCTR_TTSEL_SHIFT;
         if ( domain->context_id != context_id )
         {
             dev_err(mmu->dev, "Micro-TLB %u already assigned to IPMMU context %u\n",
@@ -740,6 +747,18 @@  static const struct ipmmu_features ipmmu_features_rcar_gen3 = {
     .ctx_offset_base = 0,
     .ctx_offset_stride = 0x40,
     .utlb_offset_base = 0,
+    .control_offset_base = 0,
+    .imuctr_ttsel_mask = (15 << 4),
+};
+
+static const struct ipmmu_features ipmmu_features_rcar_gen4 = {
+    .number_of_contexts = 16,
+    .num_utlbs = 64,
+    .ctx_offset_base = 0x10000,
+    .ctx_offset_stride = 0x1040,
+    .utlb_offset_base = 0x3000,
+    .control_offset_base = 0x1000,
+    .imuctr_ttsel_mask = (31 << 4),
 };
 
 static void ipmmu_device_reset(struct ipmmu_vmsa_device *mmu)
@@ -751,11 +770,12 @@  static void ipmmu_device_reset(struct ipmmu_vmsa_device *mmu)
         ipmmu_ctx_write(mmu, i, IMCTR, 0);
 }
 
-/* R-Car Gen3 SoCs product and cut information. */
+/* R-Car Gen3/Gen4 SoCs product and cut information. */
 #define RCAR_PRODUCT_MASK    0x00007F00
 #define RCAR_PRODUCT_H3      0x00004F00
 #define RCAR_PRODUCT_M3W     0x00005200
 #define RCAR_PRODUCT_M3N     0x00005500
+#define RCAR_PRODUCT_S4      0x00005A00
 #define RCAR_CUT_MASK        0x000000FF
 #define RCAR_CUT_VER30       0x00000020
 
@@ -803,6 +823,10 @@  static __init bool ipmmu_stage2_supported(void)
         stage2_supported = true;
         break;
 
+    case RCAR_PRODUCT_S4:
+        stage2_supported = true;
+        break;
+
     default:
         printk(XENLOG_ERR "ipmmu: Unsupported SoC version\n");
         break;
@@ -831,6 +855,10 @@  static const struct dt_device_match ipmmu_dt_match[] __initconst =
         .compatible = "renesas,ipmmu-r8a77961",
         .data = &ipmmu_features_rcar_gen3,
     },
+    {
+        .compatible = "renesas,ipmmu-r8a779f0",
+        .data = &ipmmu_features_rcar_gen4,
+    },
     { /* sentinel */ },
 };
 
@@ -845,6 +873,7 @@  static int ipmmu_probe(struct dt_device_node *node)
     const struct dt_device_match *match;
     struct ipmmu_vmsa_device *mmu;
     uint64_t addr, size;
+    uint32_t reg;
     int irq, ret;
 
     mmu = xzalloc(struct ipmmu_vmsa_device);
@@ -930,8 +959,8 @@  static int ipmmu_probe(struct dt_device_node *node)
          * Use stage 2 translation table format when stage 2 translation
          * enabled.
          */
-        ipmmu_write(mmu, IMSAUXCTLR,
-                    ipmmu_read(mmu, IMSAUXCTLR) | IMSAUXCTLR_S2PTE);
+        reg = IMSAUXCTLR + mmu->features->control_offset_base;
+        ipmmu_write(mmu, reg, ipmmu_read(mmu, reg) | IMSAUXCTLR_S2PTE);
 
         dev_info(&node->dev, "IPMMU context 0 is reserved\n");
         set_bit(0, mmu->ctx);