Skip to content

Commit 38df7e5

Browse files
committed
Merge tag 'drm-misc-fixes-2024-02-15' of git://anongit.freedesktop.org/drm/drm-misc into drm-fixes
A suspend/resume error fix for ivpu, a couple of scheduler fixes for nouveau, a patch to support large page arrays in prime, a uninitialized variable fix in crtc, a locking fix in rockchip/vop2 and a buddy allocator error reporting fix. Signed-off-by: Dave Airlie <airlied@redhat.com> From: Maxime Ripard <mripard@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/b4ffqzigtfh6cgzdpwuk6jlrv3dnk4hu6etiizgvibysqgtl2p@42n2gdfdd5eu
2 parents 841c351 + a64056b commit 38df7e5

16 files changed

+216
-50
lines changed

drivers/accel/ivpu/ivpu_hw_37xx.c

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -510,16 +510,6 @@ static int ivpu_boot_pwr_domain_enable(struct ivpu_device *vdev)
510510
return ret;
511511
}
512512

513-
static int ivpu_boot_pwr_domain_disable(struct ivpu_device *vdev)
514-
{
515-
ivpu_boot_dpu_active_drive(vdev, false);
516-
ivpu_boot_pwr_island_isolation_drive(vdev, true);
517-
ivpu_boot_pwr_island_trickle_drive(vdev, false);
518-
ivpu_boot_pwr_island_drive(vdev, false);
519-
520-
return ivpu_boot_wait_for_pwr_island_status(vdev, 0x0);
521-
}
522-
523513
static void ivpu_boot_no_snoop_enable(struct ivpu_device *vdev)
524514
{
525515
u32 val = REGV_RD32(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES);
@@ -616,12 +606,37 @@ static int ivpu_hw_37xx_info_init(struct ivpu_device *vdev)
616606
return 0;
617607
}
618608

609+
static int ivpu_hw_37xx_ip_reset(struct ivpu_device *vdev)
610+
{
611+
int ret;
612+
u32 val;
613+
614+
if (IVPU_WA(punit_disabled))
615+
return 0;
616+
617+
ret = REGB_POLL_FLD(VPU_37XX_BUTTRESS_VPU_IP_RESET, TRIGGER, 0, TIMEOUT_US);
618+
if (ret) {
619+
ivpu_err(vdev, "Timed out waiting for TRIGGER bit\n");
620+
return ret;
621+
}
622+
623+
val = REGB_RD32(VPU_37XX_BUTTRESS_VPU_IP_RESET);
624+
val = REG_SET_FLD(VPU_37XX_BUTTRESS_VPU_IP_RESET, TRIGGER, val);
625+
REGB_WR32(VPU_37XX_BUTTRESS_VPU_IP_RESET, val);
626+
627+
ret = REGB_POLL_FLD(VPU_37XX_BUTTRESS_VPU_IP_RESET, TRIGGER, 0, TIMEOUT_US);
628+
if (ret)
629+
ivpu_err(vdev, "Timed out waiting for RESET completion\n");
630+
631+
return ret;
632+
}
633+
619634
static int ivpu_hw_37xx_reset(struct ivpu_device *vdev)
620635
{
621636
int ret = 0;
622637

623-
if (ivpu_boot_pwr_domain_disable(vdev)) {
624-
ivpu_err(vdev, "Failed to disable power domain\n");
638+
if (ivpu_hw_37xx_ip_reset(vdev)) {
639+
ivpu_err(vdev, "Failed to reset NPU\n");
625640
ret = -EIO;
626641
}
627642

@@ -661,6 +676,11 @@ static int ivpu_hw_37xx_power_up(struct ivpu_device *vdev)
661676
{
662677
int ret;
663678

679+
/* PLL requests may fail when powering down, so issue WP 0 here */
680+
ret = ivpu_pll_disable(vdev);
681+
if (ret)
682+
ivpu_warn(vdev, "Failed to disable PLL: %d\n", ret);
683+
664684
ret = ivpu_hw_37xx_d0i3_disable(vdev);
665685
if (ret)
666686
ivpu_warn(vdev, "Failed to disable D0I3: %d\n", ret);

drivers/accel/ivpu/ivpu_pm.c

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,14 @@ static int ivpu_suspend(struct ivpu_device *vdev)
5858
{
5959
int ret;
6060

61+
/* Save PCI state before powering down as it sometimes gets corrupted if NPU hangs */
62+
pci_save_state(to_pci_dev(vdev->drm.dev));
63+
6164
ret = ivpu_shutdown(vdev);
62-
if (ret) {
65+
if (ret)
6366
ivpu_err(vdev, "Failed to shutdown VPU: %d\n", ret);
64-
return ret;
65-
}
67+
68+
pci_set_power_state(to_pci_dev(vdev->drm.dev), PCI_D3hot);
6669

6770
return ret;
6871
}
@@ -71,6 +74,9 @@ static int ivpu_resume(struct ivpu_device *vdev)
7174
{
7275
int ret;
7376

77+
pci_set_power_state(to_pci_dev(vdev->drm.dev), PCI_D0);
78+
pci_restore_state(to_pci_dev(vdev->drm.dev));
79+
7480
retry:
7581
ret = ivpu_hw_power_up(vdev);
7682
if (ret) {
@@ -120,15 +126,20 @@ static void ivpu_pm_recovery_work(struct work_struct *work)
120126

121127
ivpu_fw_log_dump(vdev);
122128

123-
retry:
124-
ret = pci_try_reset_function(to_pci_dev(vdev->drm.dev));
125-
if (ret == -EAGAIN && !drm_dev_is_unplugged(&vdev->drm)) {
126-
cond_resched();
127-
goto retry;
128-
}
129+
atomic_inc(&vdev->pm->reset_counter);
130+
atomic_set(&vdev->pm->reset_pending, 1);
131+
down_write(&vdev->pm->reset_lock);
132+
133+
ivpu_suspend(vdev);
134+
ivpu_pm_prepare_cold_boot(vdev);
135+
ivpu_jobs_abort_all(vdev);
136+
137+
ret = ivpu_resume(vdev);
138+
if (ret)
139+
ivpu_err(vdev, "Failed to resume NPU: %d\n", ret);
129140

130-
if (ret && ret != -EAGAIN)
131-
ivpu_err(vdev, "Failed to reset VPU: %d\n", ret);
141+
up_write(&vdev->pm->reset_lock);
142+
atomic_set(&vdev->pm->reset_pending, 0);
132143

133144
kobject_uevent_env(&vdev->drm.dev->kobj, KOBJ_CHANGE, evt);
134145
pm_runtime_mark_last_busy(vdev->drm.dev);
@@ -200,9 +211,6 @@ int ivpu_pm_suspend_cb(struct device *dev)
200211
ivpu_suspend(vdev);
201212
ivpu_pm_prepare_warm_boot(vdev);
202213

203-
pci_save_state(to_pci_dev(dev));
204-
pci_set_power_state(to_pci_dev(dev), PCI_D3hot);
205-
206214
ivpu_dbg(vdev, PM, "Suspend done.\n");
207215

208216
return 0;
@@ -216,9 +224,6 @@ int ivpu_pm_resume_cb(struct device *dev)
216224

217225
ivpu_dbg(vdev, PM, "Resume..\n");
218226

219-
pci_set_power_state(to_pci_dev(dev), PCI_D0);
220-
pci_restore_state(to_pci_dev(dev));
221-
222227
ret = ivpu_resume(vdev);
223228
if (ret)
224229
ivpu_err(vdev, "Failed to resume: %d\n", ret);

drivers/gpu/drm/drm_buddy.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,12 @@ static int __alloc_range(struct drm_buddy *mm,
539539
} while (1);
540540

541541
list_splice_tail(&allocated, blocks);
542+
543+
if (total_allocated < size) {
544+
err = -ENOSPC;
545+
goto err_free;
546+
}
547+
542548
return 0;
543549

544550
err_undo:

drivers/gpu/drm/drm_crtc.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -904,6 +904,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
904904
connector_set = NULL;
905905
fb = NULL;
906906
mode = NULL;
907+
num_connectors = 0;
907908

908909
DRM_MODESET_LOCK_ALL_END(dev, ctx, ret);
909910

drivers/gpu/drm/drm_prime.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -820,7 +820,7 @@ struct sg_table *drm_prime_pages_to_sg(struct drm_device *dev,
820820
if (max_segment == 0)
821821
max_segment = UINT_MAX;
822822
err = sg_alloc_table_from_pages_segment(sg, pages, nr_pages, 0,
823-
nr_pages << PAGE_SHIFT,
823+
(unsigned long)nr_pages << PAGE_SHIFT,
824824
max_segment, GFP_KERNEL);
825825
if (err) {
826826
kfree(sg);

drivers/gpu/drm/nouveau/nouveau_abi16.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -128,12 +128,14 @@ nouveau_abi16_chan_fini(struct nouveau_abi16 *abi16,
128128
struct nouveau_abi16_ntfy *ntfy, *temp;
129129

130130
/* Cancel all jobs from the entity's queue. */
131-
drm_sched_entity_fini(&chan->sched.entity);
131+
if (chan->sched)
132+
drm_sched_entity_fini(&chan->sched->entity);
132133

133134
if (chan->chan)
134135
nouveau_channel_idle(chan->chan);
135136

136-
nouveau_sched_fini(&chan->sched);
137+
if (chan->sched)
138+
nouveau_sched_destroy(&chan->sched);
137139

138140
/* cleanup notifier state */
139141
list_for_each_entry_safe(ntfy, temp, &chan->notifiers, head) {
@@ -337,10 +339,16 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
337339
if (ret)
338340
goto done;
339341

340-
ret = nouveau_sched_init(&chan->sched, drm, drm->sched_wq,
341-
chan->chan->dma.ib_max);
342-
if (ret)
343-
goto done;
342+
/* If we're not using the VM_BIND uAPI, we don't need a scheduler.
343+
*
344+
* The client lock is already acquired by nouveau_abi16_get().
345+
*/
346+
if (nouveau_cli_uvmm(cli)) {
347+
ret = nouveau_sched_create(&chan->sched, drm, drm->sched_wq,
348+
chan->chan->dma.ib_max);
349+
if (ret)
350+
goto done;
351+
}
344352

345353
init->channel = chan->chan->chid;
346354

drivers/gpu/drm/nouveau/nouveau_abi16.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ struct nouveau_abi16_chan {
2626
struct nouveau_bo *ntfy;
2727
struct nouveau_vma *ntfy_vma;
2828
struct nvkm_mm heap;
29-
struct nouveau_sched sched;
29+
struct nouveau_sched *sched;
3030
};
3131

3232
struct nouveau_abi16 {

drivers/gpu/drm/nouveau/nouveau_drm.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,8 @@ nouveau_cli_fini(struct nouveau_cli *cli)
201201
WARN_ON(!list_empty(&cli->worker));
202202

203203
usif_client_fini(cli);
204-
nouveau_sched_fini(&cli->sched);
204+
if (cli->sched)
205+
nouveau_sched_destroy(&cli->sched);
205206
if (uvmm)
206207
nouveau_uvmm_fini(uvmm);
207208
nouveau_vmm_fini(&cli->svm);
@@ -311,7 +312,7 @@ nouveau_cli_init(struct nouveau_drm *drm, const char *sname,
311312
cli->mem = &mems[ret];
312313

313314
/* Don't pass in the (shared) sched_wq in order to let
314-
* nouveau_sched_init() create a dedicated one for VM_BIND jobs.
315+
* nouveau_sched_create() create a dedicated one for VM_BIND jobs.
315316
*
316317
* This is required to ensure that for VM_BIND jobs free_job() work and
317318
* run_job() work can always run concurrently and hence, free_job() work
@@ -320,7 +321,7 @@ nouveau_cli_init(struct nouveau_drm *drm, const char *sname,
320321
* locks which indirectly or directly are held for allocations
321322
* elsewhere.
322323
*/
323-
ret = nouveau_sched_init(&cli->sched, drm, NULL, 1);
324+
ret = nouveau_sched_create(&cli->sched, drm, NULL, 1);
324325
if (ret)
325326
goto done;
326327

drivers/gpu/drm/nouveau/nouveau_drv.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ struct nouveau_cli {
9898
bool disabled;
9999
} uvmm;
100100

101-
struct nouveau_sched sched;
101+
struct nouveau_sched *sched;
102102

103103
const struct nvif_mclass *mem;
104104

drivers/gpu/drm/nouveau/nouveau_exec.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ nouveau_exec_ioctl_exec(struct drm_device *dev,
389389
if (ret)
390390
goto out;
391391

392-
args.sched = &chan16->sched;
392+
args.sched = chan16->sched;
393393
args.file_priv = file_priv;
394394
args.chan = chan;
395395

0 commit comments

Comments
 (0)