drm/nouveau/disp: move HDA ELD method
Signed-off-by: Ben Skeggs <bskeggs@redhat.com> Reviewed-by: Lyude Paul <lyude@redhat.com>
This commit is contained in:
parent
f530bc60a3
commit
a9f5d77219
@ -673,29 +673,33 @@ nv50_audio_component_fini(struct nouveau_drm *drm)
|
||||
/******************************************************************************
|
||||
* Audio
|
||||
*****************************************************************************/
|
||||
static bool
|
||||
nv50_audio_supported(struct drm_encoder *encoder)
|
||||
{
|
||||
struct nv50_disp *disp = nv50_disp(encoder->dev);
|
||||
|
||||
if (disp->disp->object.oclass <= GT200_DISP ||
|
||||
disp->disp->object.oclass == GT206_DISP)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
nv50_audio_disable(struct drm_encoder *encoder, struct nouveau_crtc *nv_crtc)
|
||||
{
|
||||
struct nouveau_drm *drm = nouveau_drm(encoder->dev);
|
||||
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
|
||||
struct nv50_disp *disp = nv50_disp(encoder->dev);
|
||||
struct nvif_outp *outp = &nv_encoder->outp;
|
||||
struct {
|
||||
struct nv50_disp_mthd_v1 base;
|
||||
struct nv50_disp_sor_hda_eld_v0 eld;
|
||||
} args = {
|
||||
.base.version = 1,
|
||||
.base.method = NV50_DISP_MTHD_V1_SOR_HDA_ELD,
|
||||
.base.hasht = nv_encoder->dcb->hasht,
|
||||
.base.hashm = (0xf0ff & nv_encoder->dcb->hashm) |
|
||||
(0x0100 << nv_crtc->index),
|
||||
};
|
||||
|
||||
if (!nv50_audio_supported(encoder))
|
||||
return;
|
||||
|
||||
mutex_lock(&drm->audio.lock);
|
||||
if (nv_encoder->audio.enabled) {
|
||||
nv_encoder->audio.enabled = false;
|
||||
nv_encoder->audio.connector = NULL;
|
||||
nvif_mthd(&disp->disp->object, 0, &args, sizeof(args));
|
||||
nvif_outp_hda_eld(&nv_encoder->outp, nv_crtc->index, NULL, 0);
|
||||
}
|
||||
mutex_unlock(&drm->audio.lock);
|
||||
|
||||
@ -709,31 +713,15 @@ nv50_audio_enable(struct drm_encoder *encoder, struct nouveau_crtc *nv_crtc,
|
||||
{
|
||||
struct nouveau_drm *drm = nouveau_drm(encoder->dev);
|
||||
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
|
||||
struct nv50_disp *disp = nv50_disp(encoder->dev);
|
||||
struct nvif_outp *outp = &nv_encoder->outp;
|
||||
struct __packed {
|
||||
struct {
|
||||
struct nv50_disp_mthd_v1 mthd;
|
||||
struct nv50_disp_sor_hda_eld_v0 eld;
|
||||
} base;
|
||||
u8 data[sizeof(nv_connector->base.eld)];
|
||||
} args = {
|
||||
.base.mthd.version = 1,
|
||||
.base.mthd.method = NV50_DISP_MTHD_V1_SOR_HDA_ELD,
|
||||
.base.mthd.hasht = nv_encoder->dcb->hasht,
|
||||
.base.mthd.hashm = (0xf0ff & nv_encoder->dcb->hashm) |
|
||||
(0x0100 << nv_crtc->index),
|
||||
};
|
||||
|
||||
if (!drm_detect_monitor_audio(nv_connector->edid))
|
||||
if (!nv50_audio_supported(encoder) || !drm_detect_monitor_audio(nv_connector->edid))
|
||||
return;
|
||||
|
||||
mutex_lock(&drm->audio.lock);
|
||||
|
||||
memcpy(args.data, nv_connector->base.eld, sizeof(args.data));
|
||||
|
||||
nvif_mthd(&disp->disp->object, 0, &args,
|
||||
sizeof(args.base) + drm_eld_size(args.data));
|
||||
nvif_outp_hda_eld(&nv_encoder->outp, nv_crtc->index, nv_connector->base.eld,
|
||||
drm_eld_size(nv_connector->base.eld));
|
||||
nv_encoder->audio.enabled = true;
|
||||
nv_encoder->audio.connector = &nv_connector->base;
|
||||
|
||||
|
@ -28,7 +28,6 @@ struct nv50_disp_scanoutpos_v0 {
|
||||
|
||||
struct nv50_disp_mthd_v1 {
|
||||
__u8 version;
|
||||
#define NV50_DISP_MTHD_V1_SOR_HDA_ELD 0x21
|
||||
#define NV50_DISP_MTHD_V1_SOR_DP_MST_LINK 0x25
|
||||
#define NV50_DISP_MTHD_V1_SOR_DP_MST_VCPI 0x26
|
||||
__u8 method;
|
||||
@ -37,12 +36,6 @@ struct nv50_disp_mthd_v1 {
|
||||
__u8 pad06[2];
|
||||
};
|
||||
|
||||
struct nv50_disp_sor_hda_eld_v0 {
|
||||
__u8 version;
|
||||
__u8 pad01[7];
|
||||
__u8 data[];
|
||||
};
|
||||
|
||||
struct nv50_disp_sor_dp_mst_link_v0 {
|
||||
__u8 version;
|
||||
__u8 state;
|
||||
|
@ -14,6 +14,7 @@ union nvif_outp_args {
|
||||
#define NVIF_OUTP_V0_ACQUIRE 0x01
|
||||
#define NVIF_OUTP_V0_RELEASE 0x02
|
||||
#define NVIF_OUTP_V0_INFOFRAME 0x03
|
||||
#define NVIF_OUTP_V0_HDA_ELD 0x04
|
||||
|
||||
union nvif_outp_load_detect_args {
|
||||
struct nvif_outp_load_detect_v0 {
|
||||
@ -77,4 +78,13 @@ union nvif_outp_infoframe_args {
|
||||
__u8 data[];
|
||||
} v0;
|
||||
};
|
||||
|
||||
union nvif_outp_hda_eld_args {
|
||||
struct nvif_outp_hda_eld_v0 {
|
||||
__u8 version;
|
||||
__u8 head;
|
||||
__u8 pad02[6];
|
||||
__u8 data[];
|
||||
} v0;
|
||||
};
|
||||
#endif
|
||||
|
@ -24,4 +24,5 @@ int nvif_outp_acquire_lvds(struct nvif_outp *, bool dual, bool bpc8);
|
||||
int nvif_outp_acquire_dp(struct nvif_outp *, bool hda);
|
||||
void nvif_outp_release(struct nvif_outp *);
|
||||
int nvif_outp_infoframe(struct nvif_outp *, u8 type, struct nvif_outp_infoframe_v0 *, u32 size);
|
||||
int nvif_outp_hda_eld(struct nvif_outp *, int head, void *data, u32 size);
|
||||
#endif
|
||||
|
@ -25,6 +25,27 @@
|
||||
|
||||
#include <nvif/class.h>
|
||||
|
||||
int
|
||||
nvif_outp_hda_eld(struct nvif_outp *outp, int head, void *data, u32 size)
|
||||
{
|
||||
struct {
|
||||
struct nvif_outp_hda_eld_v0 mthd;
|
||||
u8 data[128];
|
||||
} args;
|
||||
int ret;
|
||||
|
||||
if (WARN_ON(size > ARRAY_SIZE(args.data)))
|
||||
return -EINVAL;
|
||||
|
||||
args.mthd.version = 0;
|
||||
args.mthd.head = head;
|
||||
|
||||
memcpy(args.data, data, size);
|
||||
ret = nvif_mthd(&outp->object, NVIF_OUTP_V0_HDA_ELD, &args, sizeof(args.mthd) + size);
|
||||
NVIF_ERRON(ret, &outp->object, "[HDA_ELD head:%d size:%d]", head, size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
nvif_outp_infoframe(struct nvif_outp *outp, u8 type, struct nvif_outp_infoframe_v0 *args, u32 size)
|
||||
{
|
||||
|
@ -91,39 +91,6 @@ nv50_disp_root_mthd_(struct nvkm_object *object, u32 mthd, void *data, u32 size)
|
||||
}
|
||||
|
||||
switch (mthd * !!outp) {
|
||||
case NV50_DISP_MTHD_V1_SOR_HDA_ELD: {
|
||||
union {
|
||||
struct nv50_disp_sor_hda_eld_v0 v0;
|
||||
} *args = data;
|
||||
struct nvkm_ior *ior = outp->ior;
|
||||
int ret = -ENOSYS;
|
||||
|
||||
nvif_ioctl(object, "disp sor hda eld size %d\n", size);
|
||||
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {
|
||||
nvif_ioctl(object, "disp sor hda eld vers %d\n",
|
||||
args->v0.version);
|
||||
if (size > 0x60)
|
||||
return -E2BIG;
|
||||
} else
|
||||
return ret;
|
||||
|
||||
if (!ior->hda)
|
||||
return -ENODEV;
|
||||
|
||||
if (size && args->v0.data[0]) {
|
||||
if (outp->info.type == DCB_OUTPUT_DP)
|
||||
ior->func->dp->audio(ior, hidx, true);
|
||||
ior->func->hda->hpd(ior, hidx, true);
|
||||
ior->func->hda->eld(ior, hidx, data, size);
|
||||
} else {
|
||||
if (outp->info.type == DCB_OUTPUT_DP)
|
||||
ior->func->dp->audio(ior, hidx, false);
|
||||
ior->func->hda->hpd(ior, hidx, false);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case NV50_DISP_MTHD_V1_SOR_DP_MST_LINK: {
|
||||
union {
|
||||
struct nv50_disp_sor_dp_mst_link_v0 v0;
|
||||
|
@ -26,6 +26,35 @@
|
||||
|
||||
#include <nvif/if0012.h>
|
||||
|
||||
static int
|
||||
nvkm_uoutp_mthd_hda_eld(struct nvkm_outp *outp, void *argv, u32 argc)
|
||||
{
|
||||
struct nvkm_ior *ior = outp->ior;
|
||||
union nvif_outp_hda_eld_args *args = argv;
|
||||
|
||||
if (argc < sizeof(args->v0) || args->v0.version != 0)
|
||||
return -ENOSYS;
|
||||
argc -= sizeof(args->v0);
|
||||
|
||||
if (!ior->hda || !nvkm_head_find(outp->disp, args->v0.head))
|
||||
return -EINVAL;
|
||||
if (argc > 0x60)
|
||||
return -E2BIG;
|
||||
|
||||
if (argc && args->v0.data[0]) {
|
||||
if (outp->info.type == DCB_OUTPUT_DP)
|
||||
ior->func->dp->audio(ior, args->v0.head, true);
|
||||
ior->func->hda->hpd(ior, args->v0.head, true);
|
||||
ior->func->hda->eld(ior, args->v0.head, args->v0.data, argc);
|
||||
} else {
|
||||
if (outp->info.type == DCB_OUTPUT_DP)
|
||||
ior->func->dp->audio(ior, args->v0.head, false);
|
||||
ior->func->hda->hpd(ior, args->v0.head, false);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
nvkm_uoutp_mthd_infoframe(struct nvkm_outp *outp, void *argv, u32 argc)
|
||||
{
|
||||
@ -184,6 +213,7 @@ nvkm_uoutp_mthd_acquired(struct nvkm_outp *outp, u32 mthd, void *argv, u32 argc)
|
||||
switch (mthd) {
|
||||
case NVIF_OUTP_V0_RELEASE : return nvkm_uoutp_mthd_release (outp, argv, argc);
|
||||
case NVIF_OUTP_V0_INFOFRAME : return nvkm_uoutp_mthd_infoframe (outp, argv, argc);
|
||||
case NVIF_OUTP_V0_HDA_ELD : return nvkm_uoutp_mthd_hda_eld (outp, argv, argc);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user