Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

accel/ivpu: Enable MCA ECC signalling based on MSR

Add new boot parameter for NPU5+ that enables
ECC signalling for on-chip memory based on the value
of MSR_INTEGRITY_CAPS register.

Signed-off-by: Tomasz Rusinowicz <tomasz.rusinowicz@intel.com>
Signed-off-by: Maciej Falkowski <maciej.falkowski@linux.intel.com>
Reviewed-by: Karol Wachowski <karol.wachowski@linux.intel.com>
Signed-off-by: Karol Wachowski <karol.wachowski@linux.intel.com>
Link: https://lore.kernel.org/r/20250925145020.1446208-1-maciej.falkowski@linux.intel.com

authored by

Tomasz Rusinowicz and committed by
Karol Wachowski
87a23fe2 306e6407

+28
+4
drivers/accel/ivpu/ivpu_fw.c
··· 606 606 boot_params->system_time_us); 607 607 ivpu_dbg(vdev, FW_BOOT, "boot_params.power_profile = 0x%x\n", 608 608 boot_params->power_profile); 609 + ivpu_dbg(vdev, FW_BOOT, "boot_params.vpu_uses_ecc_mca_signal = 0x%x\n", 610 + boot_params->vpu_uses_ecc_mca_signal); 609 611 } 610 612 611 613 void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params *boot_params) ··· 710 708 boot_params->d0i3_entry_vpu_ts = 0; 711 709 if (IVPU_WA(disable_d0i2)) 712 710 boot_params->power_profile |= BIT(1); 711 + boot_params->vpu_uses_ecc_mca_signal = 712 + ivpu_hw_uses_ecc_mca_signal(vdev) ? VPU_BOOT_MCA_ECC_BOTH : 0; 713 713 714 714 boot_params->system_time_us = ktime_to_us(ktime_get_real()); 715 715 wmb(); /* Flush WC buffers after writing bootparams */
+23
drivers/accel/ivpu/ivpu_hw.c
··· 8 8 #include "ivpu_hw_btrs.h" 9 9 #include "ivpu_hw_ip.h" 10 10 11 + #include <asm/msr-index.h> 12 + #include <asm/msr.h> 11 13 #include <linux/dmi.h> 12 14 #include <linux/fault-inject.h> 13 15 #include <linux/pm_runtime.h> ··· 23 21 #endif 24 22 25 23 #define FW_SHARED_MEM_ALIGNMENT SZ_512K /* VPU MTRR limitation */ 24 + 25 + #define ECC_MCA_SIGNAL_ENABLE_MASK 0xff 26 26 27 27 static char *platform_to_str(u32 platform) 28 28 { ··· 398 394 399 395 pm_runtime_mark_last_busy(vdev->drm.dev); 400 396 return IRQ_HANDLED; 397 + } 398 + 399 + bool ivpu_hw_uses_ecc_mca_signal(struct ivpu_device *vdev) 400 + { 401 + unsigned long long msr_integrity_caps; 402 + int ret; 403 + 404 + if (ivpu_hw_ip_gen(vdev) < IVPU_HW_IP_50XX) 405 + return false; 406 + 407 + ret = rdmsrq_safe(MSR_INTEGRITY_CAPS, &msr_integrity_caps); 408 + if (ret) { 409 + ivpu_warn(vdev, "Error reading MSR_INTEGRITY_CAPS: %d", ret); 410 + return false; 411 + } 412 + 413 + ivpu_dbg(vdev, MISC, "MSR_INTEGRITY_CAPS: 0x%llx\n", msr_integrity_caps); 414 + 415 + return msr_integrity_caps & ECC_MCA_SIGNAL_ENABLE_MASK; 401 416 }
+1
drivers/accel/ivpu/ivpu_hw.h
··· 63 63 void ivpu_hw_irq_enable(struct ivpu_device *vdev); 64 64 void ivpu_hw_irq_disable(struct ivpu_device *vdev); 65 65 irqreturn_t ivpu_hw_irq_handler(int irq, void *ptr); 66 + bool ivpu_hw_uses_ecc_mca_signal(struct ivpu_device *vdev); 66 67 67 68 static inline u32 ivpu_hw_btrs_irq_handler(struct ivpu_device *vdev, int irq) 68 69 {