Commit 2c3801b1 authored by Wachowski, Karol's avatar Wachowski, Karol Committed by Jacek Lawrynowicz

accel/ivpu: Add force snoop module parameter

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: default avatarWachowski, Karol <karol.wachowski@intel.com>
Signed-off-by: default avatarJacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com>
Reviewed-by: default avatarJeffrey Hugo <quic_jhugo@quicinc.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240513120431.3187212-10-jacek.lawrynowicz@linux.intel.com
parent cdfad4db
...@@ -60,6 +60,10 @@ bool ivpu_disable_mmu_cont_pages; ...@@ -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_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"); 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_file_priv *ivpu_file_priv_get(struct ivpu_file_priv *file_priv)
{ {
struct ivpu_device *vdev = file_priv->vdev; struct ivpu_device *vdev = file_priv->vdev;
......
...@@ -167,6 +167,7 @@ extern u8 ivpu_pll_min_ratio; ...@@ -167,6 +167,7 @@ extern u8 ivpu_pll_min_ratio;
extern u8 ivpu_pll_max_ratio; extern u8 ivpu_pll_max_ratio;
extern int ivpu_sched_mode; extern int ivpu_sched_mode;
extern bool ivpu_disable_mmu_cont_pages; extern bool ivpu_disable_mmu_cont_pages;
extern bool ivpu_force_snoop;
#define IVPU_TEST_MODE_FW_TEST BIT(0) #define IVPU_TEST_MODE_FW_TEST BIT(0)
#define IVPU_TEST_MODE_NULL_HW BIT(1) #define IVPU_TEST_MODE_NULL_HW BIT(1)
...@@ -241,4 +242,9 @@ static inline bool ivpu_is_fpga(struct ivpu_device *vdev) ...@@ -241,4 +242,9 @@ static inline bool ivpu_is_fpga(struct ivpu_device *vdev)
return ivpu_get_platform(vdev) == IVPU_PLATFORM_FPGA; 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__ */ #endif /* __IVPU_DRV_H__ */
...@@ -60,14 +60,17 @@ static inline u32 ivpu_bo_cache_mode(struct ivpu_bo *bo) ...@@ -60,14 +60,17 @@ static inline u32 ivpu_bo_cache_mode(struct ivpu_bo *bo)
return bo->flags & DRM_IVPU_BO_CACHE_MASK; 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) static inline void *ivpu_to_cpu_addr(struct ivpu_bo *bo, u32 vpu_addr)
......
...@@ -514,7 +514,11 @@ static void ivpu_boot_no_snoop_enable(struct ivpu_device *vdev) ...@@ -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_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_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); REGV_WR32(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES, val);
} }
......
...@@ -531,7 +531,11 @@ static void ivpu_boot_no_snoop_enable(struct ivpu_device *vdev) ...@@ -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, SNOOP_OVERRIDE_EN, val);
val = REG_SET_FLD(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES, AW_SNOOP_OVERRIDE, 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); REGV_WR32(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES, val);
} }
......
...@@ -519,7 +519,8 @@ static int ivpu_mmu_cmdq_sync(struct ivpu_device *vdev) ...@@ -519,7 +519,8 @@ static int ivpu_mmu_cmdq_sync(struct ivpu_device *vdev)
if (ret) if (ret)
return 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); REGV_WR32(IVPU_MMU_REG_CMDQ_PROD, q->prod);
ret = ivpu_mmu_cmdq_wait_for_cons(vdev); ret = ivpu_mmu_cmdq_wait_for_cons(vdev);
...@@ -567,7 +568,8 @@ static int ivpu_mmu_reset(struct ivpu_device *vdev) ...@@ -567,7 +568,8 @@ static int ivpu_mmu_reset(struct ivpu_device *vdev)
int ret; int ret;
memset(mmu->cmdq.base, 0, IVPU_MMU_CMDQ_SIZE); 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.prod = 0;
mmu->cmdq.cons = 0; mmu->cmdq.cons = 0;
...@@ -661,7 +663,8 @@ static void ivpu_mmu_strtab_link_cd(struct ivpu_device *vdev, u32 sid) ...@@ -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[1], str[1]);
WRITE_ONCE(entry[0], str[0]); 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]); 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) ...@@ -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[3], cd[3]);
WRITE_ONCE(entry[0], cd[0]); 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", 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]); cd_dma ? "write" : "clear", ssid, &cd_dma, cd[0], cd[1], cd[2], cd[3]);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment