]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
accel/ivpu: Add force snoop module parameter
authorWachowski, Karol <karol.wachowski@intel.com>
Mon, 13 May 2024 12:04:28 +0000 (14:04 +0200)
committerJacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com>
Wed, 15 May 2024 05:42:26 +0000 (07:42 +0200)
Add module parameter that enforces snooping for all NPU accesses,
both through MMU PTEs mappings and through TCU page table walk
override register bits for MMU page walks / configuration access.

Signed-off-by: Wachowski, Karol <karol.wachowski@intel.com>
Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com>
Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240513120431.3187212-10-jacek.lawrynowicz@linux.intel.com
drivers/accel/ivpu/ivpu_drv.c
drivers/accel/ivpu/ivpu_drv.h
drivers/accel/ivpu/ivpu_gem.h
drivers/accel/ivpu/ivpu_hw_37xx.c
drivers/accel/ivpu/ivpu_hw_40xx.c
drivers/accel/ivpu/ivpu_mmu.c

index a02a1929f5a1d3f6d7355f235e49760c587c2701..bd702401216c31e2a0954e0c02424e2578258d87 100644 (file)
@@ -60,6 +60,10 @@ bool ivpu_disable_mmu_cont_pages;
 module_param_named(disable_mmu_cont_pages, ivpu_disable_mmu_cont_pages, bool, 0644);
 MODULE_PARM_DESC(disable_mmu_cont_pages, "Disable MMU contiguous pages optimization");
 
+bool ivpu_force_snoop;
+module_param_named(force_snoop, ivpu_force_snoop, bool, 0644);
+MODULE_PARM_DESC(force_snoop, "Force snooping for NPU host memory access");
+
 struct ivpu_file_priv *ivpu_file_priv_get(struct ivpu_file_priv *file_priv)
 {
        struct ivpu_device *vdev = file_priv->vdev;
index 55341762b9d9d558eab89c22d1990b702ab77ef1..973f8ded23e9a9c5c31d526c45f1293607aba985 100644 (file)
@@ -167,6 +167,7 @@ extern u8 ivpu_pll_min_ratio;
 extern u8 ivpu_pll_max_ratio;
 extern int ivpu_sched_mode;
 extern bool ivpu_disable_mmu_cont_pages;
+extern bool ivpu_force_snoop;
 
 #define IVPU_TEST_MODE_FW_TEST            BIT(0)
 #define IVPU_TEST_MODE_NULL_HW            BIT(1)
@@ -241,4 +242,9 @@ static inline bool ivpu_is_fpga(struct ivpu_device *vdev)
        return ivpu_get_platform(vdev) == IVPU_PLATFORM_FPGA;
 }
 
+static inline bool ivpu_is_force_snoop_enabled(struct ivpu_device *vdev)
+{
+       return ivpu_force_snoop;
+}
+
 #endif /* __IVPU_DRV_H__ */
index fb7117c13eec5c559ada14cec2ddc4f22ba09db3..d975000abd7859158180884d336363a3c1e03402 100644 (file)
@@ -60,14 +60,17 @@ static inline u32 ivpu_bo_cache_mode(struct ivpu_bo *bo)
        return bo->flags & DRM_IVPU_BO_CACHE_MASK;
 }
 
-static inline bool ivpu_bo_is_snooped(struct ivpu_bo *bo)
+static inline struct ivpu_device *ivpu_bo_to_vdev(struct ivpu_bo *bo)
 {
-       return ivpu_bo_cache_mode(bo) == DRM_IVPU_BO_CACHED;
+       return to_ivpu_device(bo->base.base.dev);
 }
 
-static inline struct ivpu_device *ivpu_bo_to_vdev(struct ivpu_bo *bo)
+static inline bool ivpu_bo_is_snooped(struct ivpu_bo *bo)
 {
-       return to_ivpu_device(bo->base.base.dev);
+       if (ivpu_is_force_snoop_enabled(ivpu_bo_to_vdev(bo)))
+               return true;
+
+       return ivpu_bo_cache_mode(bo) == DRM_IVPU_BO_CACHED;
 }
 
 static inline void *ivpu_to_cpu_addr(struct ivpu_bo *bo, u32 vpu_addr)
index ce664b6515aa0e34cde3b8a2f0abba95b9f0c091..250291cc1f3a00c2e472d34db3e27ee506d26f3a 100644 (file)
@@ -514,7 +514,11 @@ static void ivpu_boot_no_snoop_enable(struct ivpu_device *vdev)
 
        val = REG_SET_FLD(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES, NOSNOOP_OVERRIDE_EN, val);
        val = REG_CLR_FLD(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES, AW_NOSNOOP_OVERRIDE, val);
-       val = REG_SET_FLD(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES, AR_NOSNOOP_OVERRIDE, val);
+
+       if (ivpu_is_force_snoop_enabled(vdev))
+               val = REG_CLR_FLD(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES, AR_NOSNOOP_OVERRIDE, val);
+       else
+               val = REG_SET_FLD(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES, AR_NOSNOOP_OVERRIDE, val);
 
        REGV_WR32(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES, val);
 }
index 186cd87079c22b64ab5f3cd552c3f76ebfcce90c..e64ee705d00cb176758fa6618eca72564df84b88 100644 (file)
@@ -531,7 +531,11 @@ static void ivpu_boot_no_snoop_enable(struct ivpu_device *vdev)
 
        val = REG_SET_FLD(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES, SNOOP_OVERRIDE_EN, val);
        val = REG_SET_FLD(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES, AW_SNOOP_OVERRIDE, val);
-       val = REG_CLR_FLD(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES, AR_SNOOP_OVERRIDE, val);
+
+       if (ivpu_is_force_snoop_enabled(vdev))
+               val = REG_SET_FLD(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES, AR_SNOOP_OVERRIDE, val);
+       else
+               val = REG_CLR_FLD(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES, AR_SNOOP_OVERRIDE, val);
 
        REGV_WR32(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES, val);
 }
index 2e46b322c4505ea5f18997d0ef969f43239f72c8..8682e61455208c13bc4c64f6fa61beaa407681ed 100644 (file)
@@ -519,7 +519,8 @@ static int ivpu_mmu_cmdq_sync(struct ivpu_device *vdev)
        if (ret)
                return ret;
 
-       clflush_cache_range(q->base, IVPU_MMU_CMDQ_SIZE);
+       if (!ivpu_is_force_snoop_enabled(vdev))
+               clflush_cache_range(q->base, IVPU_MMU_CMDQ_SIZE);
        REGV_WR32(IVPU_MMU_REG_CMDQ_PROD, q->prod);
 
        ret = ivpu_mmu_cmdq_wait_for_cons(vdev);
@@ -567,7 +568,8 @@ static int ivpu_mmu_reset(struct ivpu_device *vdev)
        int ret;
 
        memset(mmu->cmdq.base, 0, IVPU_MMU_CMDQ_SIZE);
-       clflush_cache_range(mmu->cmdq.base, IVPU_MMU_CMDQ_SIZE);
+       if (!ivpu_is_force_snoop_enabled(vdev))
+               clflush_cache_range(mmu->cmdq.base, IVPU_MMU_CMDQ_SIZE);
        mmu->cmdq.prod = 0;
        mmu->cmdq.cons = 0;
 
@@ -661,7 +663,8 @@ static void ivpu_mmu_strtab_link_cd(struct ivpu_device *vdev, u32 sid)
        WRITE_ONCE(entry[1], str[1]);
        WRITE_ONCE(entry[0], str[0]);
 
-       clflush_cache_range(entry, IVPU_MMU_STRTAB_ENT_SIZE);
+       if (!ivpu_is_force_snoop_enabled(vdev))
+               clflush_cache_range(entry, IVPU_MMU_STRTAB_ENT_SIZE);
 
        ivpu_dbg(vdev, MMU, "STRTAB write entry (SSID=%u): 0x%llx, 0x%llx\n", sid, str[0], str[1]);
 }
@@ -735,7 +738,8 @@ static int ivpu_mmu_cd_add(struct ivpu_device *vdev, u32 ssid, u64 cd_dma)
        WRITE_ONCE(entry[3], cd[3]);
        WRITE_ONCE(entry[0], cd[0]);
 
-       clflush_cache_range(entry, IVPU_MMU_CDTAB_ENT_SIZE);
+       if (!ivpu_is_force_snoop_enabled(vdev))
+               clflush_cache_range(entry, IVPU_MMU_CDTAB_ENT_SIZE);
 
        ivpu_dbg(vdev, MMU, "CDTAB %s entry (SSID=%u, dma=%pad): 0x%llx, 0x%llx, 0x%llx, 0x%llx\n",
                 cd_dma ? "write" : "clear", ssid, &cd_dma, cd[0], cd[1], cd[2], cd[3]);