Skip to content

Commit 8c4a5e8

Browse files
committed
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
2 parents 69390f3 + 645d694 commit 8c4a5e8

File tree

7 files changed

+40
-19
lines changed

7 files changed

+40
-19
lines changed

drivers/accel/ivpu/ivpu_drv.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ static int ivpu_wait_for_ready(struct ivpu_device *vdev)
327327
}
328328

329329
if (!ret)
330-
ivpu_info(vdev, "VPU ready message received successfully\n");
330+
ivpu_dbg(vdev, PM, "VPU ready message received successfully\n");
331331
else
332332
ivpu_hw_diagnose_failure(vdev);
333333

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

635635
static struct pci_device_id ivpu_pci_ids[] = {
636636
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_MTL) },
637+
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_ARL) },
637638
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_LNL) },
638639
{ }
639640
};

drivers/accel/ivpu/ivpu_drv.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#define DRIVER_DATE "20230117"
2424

2525
#define PCI_DEVICE_ID_MTL 0x7d1d
26+
#define PCI_DEVICE_ID_ARL 0xad1d
2627
#define PCI_DEVICE_ID_LNL 0x643e
2728

2829
#define IVPU_HW_37XX 37
@@ -165,6 +166,7 @@ static inline int ivpu_hw_gen(struct ivpu_device *vdev)
165166
{
166167
switch (ivpu_device_id(vdev)) {
167168
case PCI_DEVICE_ID_MTL:
169+
case PCI_DEVICE_ID_ARL:
168170
return IVPU_HW_37XX;
169171
case PCI_DEVICE_ID_LNL:
170172
return IVPU_HW_40XX;

drivers/accel/ivpu/ivpu_fw.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,8 @@ static int ivpu_fw_mem_init(struct ivpu_device *vdev)
220220
if (ret)
221221
return ret;
222222

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

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

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

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

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

498500
ivpu_fw_boot_params_print(vdev, boot_params);
499501
}

drivers/accel/ivpu/ivpu_gem.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
#include <drm/drm_gem.h>
99
#include <drm/drm_mm.h>
1010

11+
#define DRM_IVPU_BO_NOSNOOP 0x10000000
12+
1113
struct dma_buf;
1214
struct ivpu_bo_ops;
1315
struct ivpu_file_priv;
@@ -83,6 +85,9 @@ static inline u32 ivpu_bo_cache_mode(struct ivpu_bo *bo)
8385

8486
static inline bool ivpu_bo_is_snooped(struct ivpu_bo *bo)
8587
{
88+
if (bo->flags & DRM_IVPU_BO_NOSNOOP)
89+
return false;
90+
8691
return ivpu_bo_cache_mode(bo) == DRM_IVPU_BO_CACHED;
8792
}
8893

drivers/accel/ivpu/ivpu_hw_40xx.c

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,7 @@
5757

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

60-
#define BUTTRESS_IRQ_MASK ((REG_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, FREQ_CHANGE)) | \
61-
(REG_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, ATS_ERR)) | \
60+
#define BUTTRESS_IRQ_MASK ((REG_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, ATS_ERR)) | \
6261
(REG_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, CFI0_ERR)) | \
6362
(REG_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, CFI1_ERR)) | \
6463
(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)
196195
return REGB_POLL_FLD(VPU_40XX_BUTTRESS_VPU_STATUS, READY, 1, PLL_TIMEOUT_US);
197196
}
198197

198+
static int ivpu_wait_for_clock_own_resource_ack(struct ivpu_device *vdev)
199+
{
200+
if (ivpu_is_simics(vdev))
201+
return 0;
202+
203+
return REGB_POLL_FLD(VPU_40XX_BUTTRESS_VPU_STATUS, CLOCK_RESOURCE_OWN_ACK, 1, TIMEOUT_US);
204+
}
205+
199206
static void ivpu_pll_init_frequency_ratios(struct ivpu_device *vdev)
200207
{
201208
struct ivpu_hw_info *hw = vdev->hw;
@@ -556,6 +563,12 @@ static int ivpu_boot_pwr_domain_enable(struct ivpu_device *vdev)
556563
{
557564
int ret;
558565

566+
ret = ivpu_wait_for_clock_own_resource_ack(vdev);
567+
if (ret) {
568+
ivpu_err(vdev, "Timed out waiting for clock own resource ACK\n");
569+
return ret;
570+
}
571+
559572
ivpu_boot_pwr_island_trickle_drive(vdev, true);
560573
ivpu_boot_pwr_island_drive(vdev, true);
561574

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

1049-
/* Disable global interrupt before handling local buttress interrupts */
1050-
REGB_WR32(VPU_40XX_BUTTRESS_GLOBAL_INT_MASK, 0x1);
1051-
10521062
if (REG_TEST_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, FREQ_CHANGE, status))
10531063
ivpu_dbg(vdev, IRQ, "FREQ_CHANGE");
10541064

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

1099-
/* Re-enable global interrupt */
1100-
REGB_WR32(VPU_40XX_BUTTRESS_GLOBAL_INT_MASK, 0x0);
1101-
11021109
if (schedule_recovery)
11031110
ivpu_pm_schedule_recovery(vdev);
11041111

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

1120+
REGB_WR32(VPU_40XX_BUTTRESS_GLOBAL_INT_MASK, 0x1);
1121+
11131122
ret |= ivpu_hw_40xx_irqv_handler(vdev, irq);
11141123
ret |= ivpu_hw_40xx_irqb_handler(vdev, irq);
11151124

1125+
/* Re-enable global interrupts to re-trigger MSI for pending interrupts */
1126+
REGB_WR32(VPU_40XX_BUTTRESS_GLOBAL_INT_MASK, 0x0);
1127+
11161128
if (ret & IRQ_WAKE_THREAD)
11171129
return IRQ_WAKE_THREAD;
11181130

drivers/accel/ivpu/ivpu_hw_40xx_reg.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@
7070
#define VPU_40XX_BUTTRESS_VPU_STATUS_READY_MASK BIT_MASK(0)
7171
#define VPU_40XX_BUTTRESS_VPU_STATUS_IDLE_MASK BIT_MASK(1)
7272
#define VPU_40XX_BUTTRESS_VPU_STATUS_DUP_IDLE_MASK BIT_MASK(2)
73+
#define VPU_40XX_BUTTRESS_VPU_STATUS_CLOCK_RESOURCE_OWN_ACK_MASK BIT_MASK(6)
74+
#define VPU_40XX_BUTTRESS_VPU_STATUS_POWER_RESOURCE_OWN_ACK_MASK BIT_MASK(7)
7375
#define VPU_40XX_BUTTRESS_VPU_STATUS_PERF_CLK_MASK BIT_MASK(11)
7476
#define VPU_40XX_BUTTRESS_VPU_STATUS_DISABLE_CLK_RELINQUISH_MASK BIT_MASK(12)
7577

drivers/accel/ivpu/ivpu_ipc.c

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -209,20 +209,17 @@ int ivpu_ipc_receive(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons,
209209
struct ivpu_ipc_rx_msg *rx_msg;
210210
int wait_ret, ret = 0;
211211

212-
wait_ret = wait_event_interruptible_timeout(cons->rx_msg_wq,
213-
(IS_KTHREAD() && kthread_should_stop()) ||
214-
!list_empty(&cons->rx_msg_list),
215-
msecs_to_jiffies(timeout_ms));
212+
wait_ret = wait_event_timeout(cons->rx_msg_wq,
213+
(IS_KTHREAD() && kthread_should_stop()) ||
214+
!list_empty(&cons->rx_msg_list),
215+
msecs_to_jiffies(timeout_ms));
216216

217217
if (IS_KTHREAD() && kthread_should_stop())
218218
return -EINTR;
219219

220220
if (wait_ret == 0)
221221
return -ETIMEDOUT;
222222

223-
if (wait_ret < 0)
224-
return -ERESTARTSYS;
225-
226223
spin_lock_irq(&cons->rx_msg_lock);
227224
rx_msg = list_first_entry_or_null(&cons->rx_msg_list, struct ivpu_ipc_rx_msg, link);
228225
if (!rx_msg) {

0 commit comments

Comments
 (0)