Skip to content

Commit 6edc84b

Browse files
committed
Merge tag 'drm-fixes-2023-09-29' of git://anongit.freedesktop.org/drm/drm
Pull drm fixes from Dave Airlie: "Regular pull, this feel suspiciously light so I expect next week might be a bit heavier? Let's see how we go. This is from a code point of view ivpu and i915 fixes. The only other patch is adding Danilo Krummrich to the nouveau maintainers, he's agreed to take on more of the roll after Ben retired. MAINTAINERS: - add Danilo for nouveau 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 i915: - Fix a panic regression on gen8_ggtt_insert_entries - Fix load issue due to reservation address in ggtt_reserve_guc_top - Fix a possible deadlock with guc busyness worker" * tag 'drm-fixes-2023-09-29' of git://anongit.freedesktop.org/drm/drm: accel/ivpu: Use cached buffers for FW loading accel/ivpu/40xx: Fix missing VPUIP interrupts accel/ivpu/40xx: Disable frequency change interrupt accel/ivpu/40xx: Ensure clock resource ownership Ack before Power-Up accel/ivpu: Don't flood dmesg with VPU ready message accel/ivpu: Do not use wait event interruptible MAINTAINERS: update nouveau maintainers i915/guc: Get runtime pm in busyness worker only if already active drm/i915/gt: Fix reservation address in ggtt_reserve_guc_top i915: Limit the length of an sg list to the requested length accel/ivpu: Add Arrow Lake pci id
2 parents 71e5865 + 06365a0 commit 6edc84b

File tree

11 files changed

+100
-32
lines changed

11 files changed

+100
-32
lines changed

MAINTAINERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6647,6 +6647,7 @@ F: drivers/gpu/drm/panel/panel-novatek-nt36672a.c
66476647
DRM DRIVER FOR NVIDIA GEFORCE/QUADRO GPUS
66486648
M: Karol Herbst <kherbst@redhat.com>
66496649
M: Lyude Paul <lyude@redhat.com>
6650+
M: Danilo Krummrich <dakr@redhat.com>
66506651
L: dri-devel@lists.freedesktop.org
66516652
L: nouveau@lists.freedesktop.org
66526653
S: Supported

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) {

drivers/gpu/drm/i915/gem/i915_gem_shmem.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ int shmem_sg_alloc_table(struct drm_i915_private *i915, struct sg_table *st,
100100
st->nents = 0;
101101
for (i = 0; i < page_count; i++) {
102102
struct folio *folio;
103+
unsigned long nr_pages;
103104
const unsigned int shrink[] = {
104105
I915_SHRINK_BOUND | I915_SHRINK_UNBOUND,
105106
0,
@@ -150,20 +151,22 @@ int shmem_sg_alloc_table(struct drm_i915_private *i915, struct sg_table *st,
150151
}
151152
} while (1);
152153

154+
nr_pages = min_t(unsigned long,
155+
folio_nr_pages(folio), page_count - i);
153156
if (!i ||
154157
sg->length >= max_segment ||
155158
folio_pfn(folio) != next_pfn) {
156159
if (i)
157160
sg = sg_next(sg);
158161

159162
st->nents++;
160-
sg_set_folio(sg, folio, folio_size(folio), 0);
163+
sg_set_folio(sg, folio, nr_pages * PAGE_SIZE, 0);
161164
} else {
162165
/* XXX: could overflow? */
163-
sg->length += folio_size(folio);
166+
sg->length += nr_pages * PAGE_SIZE;
164167
}
165-
next_pfn = folio_pfn(folio) + folio_nr_pages(folio);
166-
i += folio_nr_pages(folio) - 1;
168+
next_pfn = folio_pfn(folio) + nr_pages;
169+
i += nr_pages - 1;
167170

168171
/* Check that the i965g/gm workaround works. */
169172
GEM_BUG_ON(gfp & __GFP_DMA32 && next_pfn >= 0x00100000UL);

drivers/gpu/drm/i915/gt/intel_ggtt.c

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -511,20 +511,31 @@ void intel_ggtt_unbind_vma(struct i915_address_space *vm,
511511
vm->clear_range(vm, vma_res->start, vma_res->vma_size);
512512
}
513513

514+
/*
515+
* Reserve the top of the GuC address space for firmware images. Addresses
516+
* beyond GUC_GGTT_TOP in the GuC address space are inaccessible by GuC,
517+
* which makes for a suitable range to hold GuC/HuC firmware images if the
518+
* size of the GGTT is 4G. However, on a 32-bit platform the size of the GGTT
519+
* is limited to 2G, which is less than GUC_GGTT_TOP, but we reserve a chunk
520+
* of the same size anyway, which is far more than needed, to keep the logic
521+
* in uc_fw_ggtt_offset() simple.
522+
*/
523+
#define GUC_TOP_RESERVE_SIZE (SZ_4G - GUC_GGTT_TOP)
524+
514525
static int ggtt_reserve_guc_top(struct i915_ggtt *ggtt)
515526
{
516-
u64 size;
527+
u64 offset;
517528
int ret;
518529

519530
if (!intel_uc_uses_guc(&ggtt->vm.gt->uc))
520531
return 0;
521532

522-
GEM_BUG_ON(ggtt->vm.total <= GUC_GGTT_TOP);
523-
size = ggtt->vm.total - GUC_GGTT_TOP;
533+
GEM_BUG_ON(ggtt->vm.total <= GUC_TOP_RESERVE_SIZE);
534+
offset = ggtt->vm.total - GUC_TOP_RESERVE_SIZE;
524535

525-
ret = i915_gem_gtt_reserve(&ggtt->vm, NULL, &ggtt->uc_fw, size,
526-
GUC_GGTT_TOP, I915_COLOR_UNEVICTABLE,
527-
PIN_NOEVICT);
536+
ret = i915_gem_gtt_reserve(&ggtt->vm, NULL, &ggtt->uc_fw,
537+
GUC_TOP_RESERVE_SIZE, offset,
538+
I915_COLOR_UNEVICTABLE, PIN_NOEVICT);
528539
if (ret)
529540
drm_dbg(&ggtt->vm.i915->drm,
530541
"Failed to reserve top of GGTT for GuC\n");

0 commit comments

Comments
 (0)