Commit 8c4a5e89 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm-misc-fixes-2023-09-28' of git://anongit.freedesktop.org/drm/drm-misc into drm-fixes



Short summary of fixes pull:

 * ivpu:
   * Add PCI ids for Arrow Lake
   * Fix memory corruption during IPC
   * Avoid dmesg flooding
   * 40xx: Wait for clock resource
   * 40xx: Fix interrupt usage
   * 40xx: Support caching when loading firmware

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>

From: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patchwork.freedesktop.org/patch/msgid/20230928081208.GA7881@linux-uq9g
parents 69390f35 645d6945
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -327,7 +327,7 @@ static int ivpu_wait_for_ready(struct ivpu_device *vdev)
	}

	if (!ret)
		ivpu_info(vdev, "VPU ready message received successfully\n");
		ivpu_dbg(vdev, PM, "VPU ready message received successfully\n");
	else
		ivpu_hw_diagnose_failure(vdev);

@@ -634,6 +634,7 @@ static void ivpu_dev_fini(struct ivpu_device *vdev)

static struct pci_device_id ivpu_pci_ids[] = {
	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_MTL) },
	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_ARL) },
	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_LNL) },
	{ }
};
+2 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#define DRIVER_DATE "20230117"

#define PCI_DEVICE_ID_MTL   0x7d1d
#define PCI_DEVICE_ID_ARL   0xad1d
#define PCI_DEVICE_ID_LNL   0x643e

#define IVPU_HW_37XX	37
@@ -165,6 +166,7 @@ static inline int ivpu_hw_gen(struct ivpu_device *vdev)
{
	switch (ivpu_device_id(vdev)) {
	case PCI_DEVICE_ID_MTL:
	case PCI_DEVICE_ID_ARL:
		return IVPU_HW_37XX;
	case PCI_DEVICE_ID_LNL:
		return IVPU_HW_40XX;
+5 −3
Original line number Diff line number Diff line
@@ -220,7 +220,8 @@ static int ivpu_fw_mem_init(struct ivpu_device *vdev)
	if (ret)
		return ret;

	fw->mem = ivpu_bo_alloc_internal(vdev, fw->runtime_addr, fw->runtime_size, DRM_IVPU_BO_WC);
	fw->mem = ivpu_bo_alloc_internal(vdev, fw->runtime_addr, fw->runtime_size,
					 DRM_IVPU_BO_CACHED | DRM_IVPU_BO_NOSNOOP);
	if (!fw->mem) {
		ivpu_err(vdev, "Failed to allocate firmware runtime memory\n");
		return -ENOMEM;
@@ -330,7 +331,7 @@ int ivpu_fw_load(struct ivpu_device *vdev)
		memset(start, 0, size);
	}

	wmb(); /* Flush WC buffers after writing fw->mem */
	clflush_cache_range(fw->mem->kvaddr, fw->mem->base.size);

	return 0;
}
@@ -432,6 +433,7 @@ void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params
	if (!ivpu_fw_is_cold_boot(vdev)) {
		boot_params->save_restore_ret_address = 0;
		vdev->pm->is_warmboot = true;
		clflush_cache_range(vdev->fw->mem->kvaddr, SZ_4K);
		return;
	}

@@ -493,7 +495,7 @@ void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params
	boot_params->punit_telemetry_sram_size = ivpu_hw_reg_telemetry_size_get(vdev);
	boot_params->vpu_telemetry_enable = ivpu_hw_reg_telemetry_enable_get(vdev);

	wmb(); /* Flush WC buffers after writing bootparams */
	clflush_cache_range(vdev->fw->mem->kvaddr, SZ_4K);

	ivpu_fw_boot_params_print(vdev, boot_params);
}
+5 −0
Original line number Diff line number Diff line
@@ -8,6 +8,8 @@
#include <drm/drm_gem.h>
#include <drm/drm_mm.h>

#define DRM_IVPU_BO_NOSNOOP       0x10000000

struct dma_buf;
struct ivpu_bo_ops;
struct ivpu_file_priv;
@@ -83,6 +85,9 @@ static inline u32 ivpu_bo_cache_mode(struct ivpu_bo *bo)

static inline bool ivpu_bo_is_snooped(struct ivpu_bo *bo)
{
	if (bo->flags & DRM_IVPU_BO_NOSNOOP)
		return false;

	return ivpu_bo_cache_mode(bo) == DRM_IVPU_BO_CACHED;
}

+20 −8
Original line number Diff line number Diff line
@@ -57,8 +57,7 @@

#define ICB_0_1_IRQ_MASK ((((u64)ICB_1_IRQ_MASK) << 32) | ICB_0_IRQ_MASK)

#define BUTTRESS_IRQ_MASK ((REG_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, FREQ_CHANGE)) | \
			   (REG_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, ATS_ERR)) | \
#define BUTTRESS_IRQ_MASK ((REG_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, ATS_ERR)) | \
			   (REG_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, CFI0_ERR)) | \
			   (REG_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, CFI1_ERR)) | \
			   (REG_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, IMR0_ERR)) | \
@@ -196,6 +195,14 @@ static int ivpu_pll_wait_for_status_ready(struct ivpu_device *vdev)
	return REGB_POLL_FLD(VPU_40XX_BUTTRESS_VPU_STATUS, READY, 1, PLL_TIMEOUT_US);
}

static int ivpu_wait_for_clock_own_resource_ack(struct ivpu_device *vdev)
{
	if (ivpu_is_simics(vdev))
		return 0;

	return REGB_POLL_FLD(VPU_40XX_BUTTRESS_VPU_STATUS, CLOCK_RESOURCE_OWN_ACK, 1, TIMEOUT_US);
}

static void ivpu_pll_init_frequency_ratios(struct ivpu_device *vdev)
{
	struct ivpu_hw_info *hw = vdev->hw;
@@ -556,6 +563,12 @@ static int ivpu_boot_pwr_domain_enable(struct ivpu_device *vdev)
{
	int ret;

	ret = ivpu_wait_for_clock_own_resource_ack(vdev);
	if (ret) {
		ivpu_err(vdev, "Timed out waiting for clock own resource ACK\n");
		return ret;
	}

	ivpu_boot_pwr_island_trickle_drive(vdev, true);
	ivpu_boot_pwr_island_drive(vdev, true);

@@ -1046,9 +1059,6 @@ static irqreturn_t ivpu_hw_40xx_irqb_handler(struct ivpu_device *vdev, int irq)
	if (status == 0)
		return IRQ_NONE;

	/* Disable global interrupt before handling local buttress interrupts */
	REGB_WR32(VPU_40XX_BUTTRESS_GLOBAL_INT_MASK, 0x1);

	if (REG_TEST_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, FREQ_CHANGE, status))
		ivpu_dbg(vdev, IRQ, "FREQ_CHANGE");

@@ -1096,9 +1106,6 @@ static irqreturn_t ivpu_hw_40xx_irqb_handler(struct ivpu_device *vdev, int irq)
	/* This must be done after interrupts are cleared at the source. */
	REGB_WR32(VPU_40XX_BUTTRESS_INTERRUPT_STAT, status);

	/* Re-enable global interrupt */
	REGB_WR32(VPU_40XX_BUTTRESS_GLOBAL_INT_MASK, 0x0);

	if (schedule_recovery)
		ivpu_pm_schedule_recovery(vdev);

@@ -1110,9 +1117,14 @@ static irqreturn_t ivpu_hw_40xx_irq_handler(int irq, void *ptr)
	struct ivpu_device *vdev = ptr;
	irqreturn_t ret = IRQ_NONE;

	REGB_WR32(VPU_40XX_BUTTRESS_GLOBAL_INT_MASK, 0x1);

	ret |= ivpu_hw_40xx_irqv_handler(vdev, irq);
	ret |= ivpu_hw_40xx_irqb_handler(vdev, irq);

	/* Re-enable global interrupts to re-trigger MSI for pending interrupts */
	REGB_WR32(VPU_40XX_BUTTRESS_GLOBAL_INT_MASK, 0x0);

	if (ret & IRQ_WAKE_THREAD)
		return IRQ_WAKE_THREAD;

Loading