Commit a9f5d772 authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nouveau/disp: move HDA ELD method



Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
Reviewed-by: default avatarLyude Paul <lyude@redhat.com>
parent f530bc60
Loading
Loading
Loading
Loading
+19 −31
Original line number Diff line number Diff line
@@ -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;

+0 −7
Original line number Diff line number Diff line
@@ -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;
+10 −0
Original line number Diff line number Diff line
@@ -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
+1 −0
Original line number Diff line number Diff line
@@ -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
+21 −0
Original line number Diff line number Diff line
@@ -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)
{
Loading