Skip to content

Commit a9f5d77

Browse files
author
Ben Skeggs
committed
drm/nouveau/disp: move HDA ELD method
Signed-off-by: Ben Skeggs <bskeggs@redhat.com> Reviewed-by: Lyude Paul <lyude@redhat.com>
1 parent f530bc6 commit a9f5d77

File tree

7 files changed

+81
-71
lines changed

7 files changed

+81
-71
lines changed

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

Lines changed: 19 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -673,29 +673,33 @@ nv50_audio_component_fini(struct nouveau_drm *drm)
673673
/******************************************************************************
674674
* Audio
675675
*****************************************************************************/
676+
static bool
677+
nv50_audio_supported(struct drm_encoder *encoder)
678+
{
679+
struct nv50_disp *disp = nv50_disp(encoder->dev);
680+
681+
if (disp->disp->object.oclass <= GT200_DISP ||
682+
disp->disp->object.oclass == GT206_DISP)
683+
return false;
684+
685+
return true;
686+
}
687+
676688
static void
677689
nv50_audio_disable(struct drm_encoder *encoder, struct nouveau_crtc *nv_crtc)
678690
{
679691
struct nouveau_drm *drm = nouveau_drm(encoder->dev);
680692
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
681-
struct nv50_disp *disp = nv50_disp(encoder->dev);
682693
struct nvif_outp *outp = &nv_encoder->outp;
683-
struct {
684-
struct nv50_disp_mthd_v1 base;
685-
struct nv50_disp_sor_hda_eld_v0 eld;
686-
} args = {
687-
.base.version = 1,
688-
.base.method = NV50_DISP_MTHD_V1_SOR_HDA_ELD,
689-
.base.hasht = nv_encoder->dcb->hasht,
690-
.base.hashm = (0xf0ff & nv_encoder->dcb->hashm) |
691-
(0x0100 << nv_crtc->index),
692-
};
694+
695+
if (!nv50_audio_supported(encoder))
696+
return;
693697

694698
mutex_lock(&drm->audio.lock);
695699
if (nv_encoder->audio.enabled) {
696700
nv_encoder->audio.enabled = false;
697701
nv_encoder->audio.connector = NULL;
698-
nvif_mthd(&disp->disp->object, 0, &args, sizeof(args));
702+
nvif_outp_hda_eld(&nv_encoder->outp, nv_crtc->index, NULL, 0);
699703
}
700704
mutex_unlock(&drm->audio.lock);
701705

@@ -709,31 +713,15 @@ nv50_audio_enable(struct drm_encoder *encoder, struct nouveau_crtc *nv_crtc,
709713
{
710714
struct nouveau_drm *drm = nouveau_drm(encoder->dev);
711715
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
712-
struct nv50_disp *disp = nv50_disp(encoder->dev);
713716
struct nvif_outp *outp = &nv_encoder->outp;
714-
struct __packed {
715-
struct {
716-
struct nv50_disp_mthd_v1 mthd;
717-
struct nv50_disp_sor_hda_eld_v0 eld;
718-
} base;
719-
u8 data[sizeof(nv_connector->base.eld)];
720-
} args = {
721-
.base.mthd.version = 1,
722-
.base.mthd.method = NV50_DISP_MTHD_V1_SOR_HDA_ELD,
723-
.base.mthd.hasht = nv_encoder->dcb->hasht,
724-
.base.mthd.hashm = (0xf0ff & nv_encoder->dcb->hashm) |
725-
(0x0100 << nv_crtc->index),
726-
};
727717

728-
if (!drm_detect_monitor_audio(nv_connector->edid))
718+
if (!nv50_audio_supported(encoder) || !drm_detect_monitor_audio(nv_connector->edid))
729719
return;
730720

731721
mutex_lock(&drm->audio.lock);
732722

733-
memcpy(args.data, nv_connector->base.eld, sizeof(args.data));
734-
735-
nvif_mthd(&disp->disp->object, 0, &args,
736-
sizeof(args.base) + drm_eld_size(args.data));
723+
nvif_outp_hda_eld(&nv_encoder->outp, nv_crtc->index, nv_connector->base.eld,
724+
drm_eld_size(nv_connector->base.eld));
737725
nv_encoder->audio.enabled = true;
738726
nv_encoder->audio.connector = &nv_connector->base;
739727

drivers/gpu/drm/nouveau/include/nvif/cl5070.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ struct nv50_disp_scanoutpos_v0 {
2828

2929
struct nv50_disp_mthd_v1 {
3030
__u8 version;
31-
#define NV50_DISP_MTHD_V1_SOR_HDA_ELD 0x21
3231
#define NV50_DISP_MTHD_V1_SOR_DP_MST_LINK 0x25
3332
#define NV50_DISP_MTHD_V1_SOR_DP_MST_VCPI 0x26
3433
__u8 method;
@@ -37,12 +36,6 @@ struct nv50_disp_mthd_v1 {
3736
__u8 pad06[2];
3837
};
3938

40-
struct nv50_disp_sor_hda_eld_v0 {
41-
__u8 version;
42-
__u8 pad01[7];
43-
__u8 data[];
44-
};
45-
4639
struct nv50_disp_sor_dp_mst_link_v0 {
4740
__u8 version;
4841
__u8 state;

drivers/gpu/drm/nouveau/include/nvif/if0012.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ union nvif_outp_args {
1414
#define NVIF_OUTP_V0_ACQUIRE 0x01
1515
#define NVIF_OUTP_V0_RELEASE 0x02
1616
#define NVIF_OUTP_V0_INFOFRAME 0x03
17+
#define NVIF_OUTP_V0_HDA_ELD 0x04
1718

1819
union nvif_outp_load_detect_args {
1920
struct nvif_outp_load_detect_v0 {
@@ -77,4 +78,13 @@ union nvif_outp_infoframe_args {
7778
__u8 data[];
7879
} v0;
7980
};
81+
82+
union nvif_outp_hda_eld_args {
83+
struct nvif_outp_hda_eld_v0 {
84+
__u8 version;
85+
__u8 head;
86+
__u8 pad02[6];
87+
__u8 data[];
88+
} v0;
89+
};
8090
#endif

drivers/gpu/drm/nouveau/include/nvif/outp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,5 @@ int nvif_outp_acquire_lvds(struct nvif_outp *, bool dual, bool bpc8);
2424
int nvif_outp_acquire_dp(struct nvif_outp *, bool hda);
2525
void nvif_outp_release(struct nvif_outp *);
2626
int nvif_outp_infoframe(struct nvif_outp *, u8 type, struct nvif_outp_infoframe_v0 *, u32 size);
27+
int nvif_outp_hda_eld(struct nvif_outp *, int head, void *data, u32 size);
2728
#endif

drivers/gpu/drm/nouveau/nvif/outp.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,27 @@
2525

2626
#include <nvif/class.h>
2727

28+
int
29+
nvif_outp_hda_eld(struct nvif_outp *outp, int head, void *data, u32 size)
30+
{
31+
struct {
32+
struct nvif_outp_hda_eld_v0 mthd;
33+
u8 data[128];
34+
} args;
35+
int ret;
36+
37+
if (WARN_ON(size > ARRAY_SIZE(args.data)))
38+
return -EINVAL;
39+
40+
args.mthd.version = 0;
41+
args.mthd.head = head;
42+
43+
memcpy(args.data, data, size);
44+
ret = nvif_mthd(&outp->object, NVIF_OUTP_V0_HDA_ELD, &args, sizeof(args.mthd) + size);
45+
NVIF_ERRON(ret, &outp->object, "[HDA_ELD head:%d size:%d]", head, size);
46+
return ret;
47+
}
48+
2849
int
2950
nvif_outp_infoframe(struct nvif_outp *outp, u8 type, struct nvif_outp_infoframe_v0 *args, u32 size)
3051
{

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

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -91,39 +91,6 @@ nv50_disp_root_mthd_(struct nvkm_object *object, u32 mthd, void *data, u32 size)
9191
}
9292

9393
switch (mthd * !!outp) {
94-
case NV50_DISP_MTHD_V1_SOR_HDA_ELD: {
95-
union {
96-
struct nv50_disp_sor_hda_eld_v0 v0;
97-
} *args = data;
98-
struct nvkm_ior *ior = outp->ior;
99-
int ret = -ENOSYS;
100-
101-
nvif_ioctl(object, "disp sor hda eld size %d\n", size);
102-
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {
103-
nvif_ioctl(object, "disp sor hda eld vers %d\n",
104-
args->v0.version);
105-
if (size > 0x60)
106-
return -E2BIG;
107-
} else
108-
return ret;
109-
110-
if (!ior->hda)
111-
return -ENODEV;
112-
113-
if (size && args->v0.data[0]) {
114-
if (outp->info.type == DCB_OUTPUT_DP)
115-
ior->func->dp->audio(ior, hidx, true);
116-
ior->func->hda->hpd(ior, hidx, true);
117-
ior->func->hda->eld(ior, hidx, data, size);
118-
} else {
119-
if (outp->info.type == DCB_OUTPUT_DP)
120-
ior->func->dp->audio(ior, hidx, false);
121-
ior->func->hda->hpd(ior, hidx, false);
122-
}
123-
124-
return 0;
125-
}
126-
break;
12794
case NV50_DISP_MTHD_V1_SOR_DP_MST_LINK: {
12895
union {
12996
struct nv50_disp_sor_dp_mst_link_v0 v0;

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,35 @@
2626

2727
#include <nvif/if0012.h>
2828

29+
static int
30+
nvkm_uoutp_mthd_hda_eld(struct nvkm_outp *outp, void *argv, u32 argc)
31+
{
32+
struct nvkm_ior *ior = outp->ior;
33+
union nvif_outp_hda_eld_args *args = argv;
34+
35+
if (argc < sizeof(args->v0) || args->v0.version != 0)
36+
return -ENOSYS;
37+
argc -= sizeof(args->v0);
38+
39+
if (!ior->hda || !nvkm_head_find(outp->disp, args->v0.head))
40+
return -EINVAL;
41+
if (argc > 0x60)
42+
return -E2BIG;
43+
44+
if (argc && args->v0.data[0]) {
45+
if (outp->info.type == DCB_OUTPUT_DP)
46+
ior->func->dp->audio(ior, args->v0.head, true);
47+
ior->func->hda->hpd(ior, args->v0.head, true);
48+
ior->func->hda->eld(ior, args->v0.head, args->v0.data, argc);
49+
} else {
50+
if (outp->info.type == DCB_OUTPUT_DP)
51+
ior->func->dp->audio(ior, args->v0.head, false);
52+
ior->func->hda->hpd(ior, args->v0.head, false);
53+
}
54+
55+
return 0;
56+
}
57+
2958
static int
3059
nvkm_uoutp_mthd_infoframe(struct nvkm_outp *outp, void *argv, u32 argc)
3160
{
@@ -184,6 +213,7 @@ nvkm_uoutp_mthd_acquired(struct nvkm_outp *outp, u32 mthd, void *argv, u32 argc)
184213
switch (mthd) {
185214
case NVIF_OUTP_V0_RELEASE : return nvkm_uoutp_mthd_release (outp, argv, argc);
186215
case NVIF_OUTP_V0_INFOFRAME : return nvkm_uoutp_mthd_infoframe (outp, argv, argc);
216+
case NVIF_OUTP_V0_HDA_ELD : return nvkm_uoutp_mthd_hda_eld (outp, argv, argc);
187217
default:
188218
break;
189219
}

0 commit comments

Comments
 (0)