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 -----BEGIN PGP SIGNATURE----- iQEzBAABCAAdFiEEchf7rIzpz2NEoWjlaA3BHVMLeiMFAmUVNKwACgkQaA3BHVML eiPl1wgAs8Bhk7B0DOZyQdwbpNcfesvXtp/8CDpByXp95GwDinrmeV5+PQBD8rip kiozkp8OKXdVwI2c3RlrEzGrGE7kUMqzLsKjTEYRZHWWec9yphn/aFtFC+cE/5oL Ty6oh/1umphiTD549arv8EE/fpJY5ilJrpFl13u83qtvka3W2YyU///e1bSplT6X s4s1K3ZF9dw6HJD3mPatZdKcSD7xNHKfUrQGQEL/5Ow1d6cPylwE/x40bsII2+x/ EMMcwm9nZJp8V68jVAtHeeaU6DuDz4V+6Lf2ZA0mV8Qdxu22qCG9+fypZnFXIdRi R8SrytgMmXDBWLpt+zhFVwozH5hyjw== =1hC6 -----END PGP SIGNATURE----- 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: Dave Airlie <airlied@redhat.com> From: Thomas Zimmermann <tzimmermann@suse.de> Link: https://patchwork.freedesktop.org/patch/msgid/20230928081208.GA7881@linux-uq9g
This commit is contained in:
commit
8c4a5e8936
@ -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) },
|
||||
{ }
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -70,6 +70,8 @@
|
||||
#define VPU_40XX_BUTTRESS_VPU_STATUS_READY_MASK BIT_MASK(0)
|
||||
#define VPU_40XX_BUTTRESS_VPU_STATUS_IDLE_MASK BIT_MASK(1)
|
||||
#define VPU_40XX_BUTTRESS_VPU_STATUS_DUP_IDLE_MASK BIT_MASK(2)
|
||||
#define VPU_40XX_BUTTRESS_VPU_STATUS_CLOCK_RESOURCE_OWN_ACK_MASK BIT_MASK(6)
|
||||
#define VPU_40XX_BUTTRESS_VPU_STATUS_POWER_RESOURCE_OWN_ACK_MASK BIT_MASK(7)
|
||||
#define VPU_40XX_BUTTRESS_VPU_STATUS_PERF_CLK_MASK BIT_MASK(11)
|
||||
#define VPU_40XX_BUTTRESS_VPU_STATUS_DISABLE_CLK_RELINQUISH_MASK BIT_MASK(12)
|
||||
|
||||
|
@ -209,10 +209,10 @@ int ivpu_ipc_receive(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons,
|
||||
struct ivpu_ipc_rx_msg *rx_msg;
|
||||
int wait_ret, ret = 0;
|
||||
|
||||
wait_ret = wait_event_interruptible_timeout(cons->rx_msg_wq,
|
||||
(IS_KTHREAD() && kthread_should_stop()) ||
|
||||
!list_empty(&cons->rx_msg_list),
|
||||
msecs_to_jiffies(timeout_ms));
|
||||
wait_ret = wait_event_timeout(cons->rx_msg_wq,
|
||||
(IS_KTHREAD() && kthread_should_stop()) ||
|
||||
!list_empty(&cons->rx_msg_list),
|
||||
msecs_to_jiffies(timeout_ms));
|
||||
|
||||
if (IS_KTHREAD() && kthread_should_stop())
|
||||
return -EINTR;
|
||||
@ -220,9 +220,6 @@ int ivpu_ipc_receive(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons,
|
||||
if (wait_ret == 0)
|
||||
return -ETIMEDOUT;
|
||||
|
||||
if (wait_ret < 0)
|
||||
return -ERESTARTSYS;
|
||||
|
||||
spin_lock_irq(&cons->rx_msg_lock);
|
||||
rx_msg = list_first_entry_or_null(&cons->rx_msg_list, struct ivpu_ipc_rx_msg, link);
|
||||
if (!rx_msg) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user