Skip to content

Commit d47c7f0

Browse files
committed
Merge branch 'linux-5.6' of git://github.com/skeggsb/linux into drm-next
A couple of OOPS fixes, fixes for TU1xx if firmware isn't available, better behaviour in the face of GPU faults, and a patch to make HD audio work again after runpm changes. Signed-off-by: Dave Airlie <[email protected]> From: Ben Skeggs <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/ <CACAvsv4xcLF6Ahh7UYEesn-wBEksd2da+ghusBAdODMrH7Sz2A@mail.gmail.com
2 parents c689b06 + c3463ae commit d47c7f0

File tree

14 files changed

+201
-22
lines changed

14 files changed

+201
-22
lines changed

drivers/gpu/drm/nouveau/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ config DRM_NOUVEAU
1717
select INPUT if ACPI && X86
1818
select THERMAL if ACPI && X86
1919
select ACPI_VIDEO if ACPI && X86
20+
select SND_HDA_COMPONENT if SND_HDA_CORE
2021
help
2122
Choose this option for open-source NVIDIA support.
2223

drivers/gpu/drm/nouveau/dispnv50/disp.c

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
#include <linux/dma-mapping.h>
3131
#include <linux/hdmi.h>
32+
#include <linux/component.h>
3233

3334
#include <drm/drm_atomic_helper.h>
3435
#include <drm/drm_dp_helper.h>
@@ -476,12 +477,113 @@ nv50_dac_create(struct drm_connector *connector, struct dcb_output *dcbe)
476477
return 0;
477478
}
478479

480+
/*
481+
* audio component binding for ELD notification
482+
*/
483+
static void
484+
nv50_audio_component_eld_notify(struct drm_audio_component *acomp, int port)
485+
{
486+
if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify)
487+
acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr,
488+
port, -1);
489+
}
490+
491+
static int
492+
nv50_audio_component_get_eld(struct device *kdev, int port, int pipe,
493+
bool *enabled, unsigned char *buf, int max_bytes)
494+
{
495+
struct drm_device *drm_dev = dev_get_drvdata(kdev);
496+
struct nouveau_drm *drm = nouveau_drm(drm_dev);
497+
struct drm_encoder *encoder;
498+
struct nouveau_encoder *nv_encoder;
499+
struct nouveau_connector *nv_connector;
500+
struct nouveau_crtc *nv_crtc;
501+
int ret = 0;
502+
503+
*enabled = false;
504+
drm_for_each_encoder(encoder, drm->dev) {
505+
nv_encoder = nouveau_encoder(encoder);
506+
nv_connector = nouveau_encoder_connector_get(nv_encoder);
507+
nv_crtc = nouveau_crtc(encoder->crtc);
508+
if (!nv_connector || !nv_crtc || nv_crtc->index != port)
509+
continue;
510+
*enabled = drm_detect_monitor_audio(nv_connector->edid);
511+
if (*enabled) {
512+
ret = drm_eld_size(nv_connector->base.eld);
513+
memcpy(buf, nv_connector->base.eld,
514+
min(max_bytes, ret));
515+
}
516+
break;
517+
}
518+
return ret;
519+
}
520+
521+
static const struct drm_audio_component_ops nv50_audio_component_ops = {
522+
.get_eld = nv50_audio_component_get_eld,
523+
};
524+
525+
static int
526+
nv50_audio_component_bind(struct device *kdev, struct device *hda_kdev,
527+
void *data)
528+
{
529+
struct drm_device *drm_dev = dev_get_drvdata(kdev);
530+
struct nouveau_drm *drm = nouveau_drm(drm_dev);
531+
struct drm_audio_component *acomp = data;
532+
533+
if (WARN_ON(!device_link_add(hda_kdev, kdev, DL_FLAG_STATELESS)))
534+
return -ENOMEM;
535+
536+
drm_modeset_lock_all(drm_dev);
537+
acomp->ops = &nv50_audio_component_ops;
538+
acomp->dev = kdev;
539+
drm->audio.component = acomp;
540+
drm_modeset_unlock_all(drm_dev);
541+
return 0;
542+
}
543+
544+
static void
545+
nv50_audio_component_unbind(struct device *kdev, struct device *hda_kdev,
546+
void *data)
547+
{
548+
struct drm_device *drm_dev = dev_get_drvdata(kdev);
549+
struct nouveau_drm *drm = nouveau_drm(drm_dev);
550+
struct drm_audio_component *acomp = data;
551+
552+
drm_modeset_lock_all(drm_dev);
553+
drm->audio.component = NULL;
554+
acomp->ops = NULL;
555+
acomp->dev = NULL;
556+
drm_modeset_unlock_all(drm_dev);
557+
}
558+
559+
static const struct component_ops nv50_audio_component_bind_ops = {
560+
.bind = nv50_audio_component_bind,
561+
.unbind = nv50_audio_component_unbind,
562+
};
563+
564+
static void
565+
nv50_audio_component_init(struct nouveau_drm *drm)
566+
{
567+
if (!component_add(drm->dev->dev, &nv50_audio_component_bind_ops))
568+
drm->audio.component_registered = true;
569+
}
570+
571+
static void
572+
nv50_audio_component_fini(struct nouveau_drm *drm)
573+
{
574+
if (drm->audio.component_registered) {
575+
component_del(drm->dev->dev, &nv50_audio_component_bind_ops);
576+
drm->audio.component_registered = false;
577+
}
578+
}
579+
479580
/******************************************************************************
480581
* Audio
481582
*****************************************************************************/
482583
static void
483584
nv50_audio_disable(struct drm_encoder *encoder, struct nouveau_crtc *nv_crtc)
484585
{
586+
struct nouveau_drm *drm = nouveau_drm(encoder->dev);
485587
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
486588
struct nv50_disp *disp = nv50_disp(encoder->dev);
487589
struct {
@@ -496,11 +598,14 @@ nv50_audio_disable(struct drm_encoder *encoder, struct nouveau_crtc *nv_crtc)
496598
};
497599

498600
nvif_mthd(&disp->disp->object, 0, &args, sizeof(args));
601+
602+
nv50_audio_component_eld_notify(drm->audio.component, nv_crtc->index);
499603
}
500604

501605
static void
502606
nv50_audio_enable(struct drm_encoder *encoder, struct drm_display_mode *mode)
503607
{
608+
struct nouveau_drm *drm = nouveau_drm(encoder->dev);
504609
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
505610
struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc);
506611
struct nouveau_connector *nv_connector;
@@ -527,6 +632,8 @@ nv50_audio_enable(struct drm_encoder *encoder, struct drm_display_mode *mode)
527632

528633
nvif_mthd(&disp->disp->object, 0, &args,
529634
sizeof(args.base) + drm_eld_size(args.data));
635+
636+
nv50_audio_component_eld_notify(drm->audio.component, nv_crtc->index);
530637
}
531638

532639
/******************************************************************************
@@ -2296,6 +2403,8 @@ nv50_display_destroy(struct drm_device *dev)
22962403
{
22972404
struct nv50_disp *disp = nv50_disp(dev);
22982405

2406+
nv50_audio_component_fini(nouveau_drm(dev));
2407+
22992408
nv50_core_del(&disp->core);
23002409

23012410
nouveau_bo_unmap(disp->sync);
@@ -2444,6 +2553,8 @@ nv50_display_create(struct drm_device *dev)
24442553
/* Disable vblank irqs aggressively for power-saving, safe on nv50+ */
24452554
dev->vblank_disable_immediate = true;
24462555

2556+
nv50_audio_component_init(drm);
2557+
24472558
out:
24482559
if (ret)
24492560
nv50_display_destroy(dev);

drivers/gpu/drm/nouveau/nouveau_chan.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ nouveau_channel_killed(struct nvif_notify *ntfy)
5555
struct nouveau_cli *cli = (void *)chan->user.client;
5656
NV_PRINTK(warn, cli, "channel %d killed!\n", chan->chid);
5757
atomic_set(&chan->killed, 1);
58+
if (chan->fence)
59+
nouveau_fence_context_kill(chan->fence, -ENODEV);
5860
return NVIF_NOTIFY_DROP;
5961
}
6062

drivers/gpu/drm/nouveau/nouveau_drv.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@
5858
#include <drm/ttm/ttm_module.h>
5959
#include <drm/ttm/ttm_page_alloc.h>
6060

61+
#include <drm/drm_audio_component.h>
62+
6163
#include "uapi/drm/nouveau_drm.h"
6264

6365
struct nouveau_channel;
@@ -211,6 +213,11 @@ struct nouveau_drm {
211213
struct nouveau_svm *svm;
212214

213215
struct nouveau_dmem *dmem;
216+
217+
struct {
218+
struct drm_audio_component *component;
219+
bool component_registered;
220+
} audio;
214221
};
215222

216223
static inline struct nouveau_drm *

drivers/gpu/drm/nouveau/nouveau_fence.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,19 +87,27 @@ nouveau_local_fence(struct dma_fence *fence, struct nouveau_drm *drm)
8787
}
8888

8989
void
90-
nouveau_fence_context_del(struct nouveau_fence_chan *fctx)
90+
nouveau_fence_context_kill(struct nouveau_fence_chan *fctx, int error)
9191
{
9292
struct nouveau_fence *fence;
9393

9494
spin_lock_irq(&fctx->lock);
9595
while (!list_empty(&fctx->pending)) {
9696
fence = list_entry(fctx->pending.next, typeof(*fence), head);
9797

98+
if (error)
99+
dma_fence_set_error(&fence->base, error);
100+
98101
if (nouveau_fence_signal(fence))
99102
nvif_notify_put(&fctx->notify);
100103
}
101104
spin_unlock_irq(&fctx->lock);
105+
}
102106

107+
void
108+
nouveau_fence_context_del(struct nouveau_fence_chan *fctx)
109+
{
110+
nouveau_fence_context_kill(fctx, 0);
103111
nvif_notify_fini(&fctx->notify);
104112
fctx->dead = 1;
105113

drivers/gpu/drm/nouveau/nouveau_fence.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ struct nouveau_fence_priv {
6363
void nouveau_fence_context_new(struct nouveau_channel *, struct nouveau_fence_chan *);
6464
void nouveau_fence_context_del(struct nouveau_fence_chan *);
6565
void nouveau_fence_context_free(struct nouveau_fence_chan *);
66+
void nouveau_fence_context_kill(struct nouveau_fence_chan *, int error);
6667

6768
int nv04_fence_create(struct nouveau_drm *);
6869
int nv04_fence_mthd(struct nouveau_channel *, u32, u32, u32);

drivers/gpu/drm/nouveau/nouveau_gem.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -688,7 +688,7 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
688688
struct validate_op op;
689689
struct nouveau_fence *fence = NULL;
690690
int i, j, ret = 0;
691-
bool do_reloc = false;
691+
bool do_reloc = false, sync = false;
692692

693693
if (unlikely(!abi16))
694694
return -ENOMEM;
@@ -702,6 +702,10 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
702702

703703
if (!chan)
704704
return nouveau_abi16_put(abi16, -ENOENT);
705+
if (unlikely(atomic_read(&chan->killed)))
706+
return nouveau_abi16_put(abi16, -ENODEV);
707+
708+
sync = req->vram_available & NOUVEAU_GEM_PUSHBUF_SYNC;
705709

706710
req->vram_available = drm->gem.vram_available;
707711
req->gart_available = drm->gem.gart_available;
@@ -850,6 +854,13 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
850854
goto out;
851855
}
852856

857+
if (sync) {
858+
if (!(ret = nouveau_fence_wait(fence, false, false))) {
859+
if ((ret = dma_fence_get_status(&fence->base)) == 1)
860+
ret = 0;
861+
}
862+
}
863+
853864
out:
854865
validate_fini(&op, chan, fence, bo);
855866
nouveau_fence_unref(&fence);

drivers/gpu/drm/nouveau/nouveau_vmm.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ nouveau_vma_del(struct nouveau_vma **pvma)
6969
}
7070
list_del(&vma->head);
7171
kfree(*pvma);
72-
*pvma = NULL;
7372
}
73+
*pvma = NULL;
7474
}
7575

7676
int

drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ nv50_disp_chan_mthd(struct nv50_disp_chan *chan, int debug)
7474

7575
if (debug > subdev->debug)
7676
return;
77+
if (!mthd)
78+
return;
7779

7880
for (i = 0; (list = mthd->data[i].mthd) != NULL; i++) {
7981
u32 base = chan->head * mthd->addr;

drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -101,15 +101,26 @@ gv100_disp_exception(struct nv50_disp *disp, int chid)
101101
u32 stat = nvkm_rd32(device, 0x611020 + (chid * 12));
102102
u32 type = (stat & 0x00007000) >> 12;
103103
u32 mthd = (stat & 0x00000fff) << 2;
104-
u32 data = nvkm_rd32(device, 0x611024 + (chid * 12));
105-
u32 code = nvkm_rd32(device, 0x611028 + (chid * 12));
106104
const struct nvkm_enum *reason =
107105
nvkm_enum_find(nv50_disp_intr_error_type, type);
108106

109-
nvkm_error(subdev, "chid %d stat %08x reason %d [%s] mthd %04x "
110-
"data %08x code %08x\n",
111-
chid, stat, type, reason ? reason->name : "",
112-
mthd, data, code);
107+
/*TODO: Suspect 33->41 are for WRBK channel exceptions, but we
108+
* don't support those currently.
109+
*
110+
* CORE+WIN CHIDs map directly to the FE_EXCEPT() slots.
111+
*/
112+
if (chid <= 32) {
113+
u32 data = nvkm_rd32(device, 0x611024 + (chid * 12));
114+
u32 code = nvkm_rd32(device, 0x611028 + (chid * 12));
115+
nvkm_error(subdev, "chid %d stat %08x reason %d [%s] "
116+
"mthd %04x data %08x code %08x\n",
117+
chid, stat, type, reason ? reason->name : "",
118+
mthd, data, code);
119+
} else {
120+
nvkm_error(subdev, "chid %d stat %08x reason %d [%s] "
121+
"mthd %04x\n",
122+
chid, stat, type, reason ? reason->name : "", mthd);
123+
}
113124

114125
if (chid < ARRAY_SIZE(disp->chan) && disp->chan[chid]) {
115126
switch (mthd) {

0 commit comments

Comments
 (0)