Loading drivers/gpu/drm/nouveau/dispnv50/disp.c +19 −31 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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; Loading drivers/gpu/drm/nouveau/include/nvif/cl5070.h +0 −7 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading drivers/gpu/drm/nouveau/include/nvif/if0012.h +10 −0 Original line number Diff line number Diff line Loading @@ -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 { Loading Loading @@ -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 drivers/gpu/drm/nouveau/include/nvif/outp.h +1 −0 Original line number Diff line number Diff line Loading @@ -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 drivers/gpu/drm/nouveau/nvif/outp.c +21 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
drivers/gpu/drm/nouveau/dispnv50/disp.c +19 −31 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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; Loading
drivers/gpu/drm/nouveau/include/nvif/cl5070.h +0 −7 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading
drivers/gpu/drm/nouveau/include/nvif/if0012.h +10 −0 Original line number Diff line number Diff line Loading @@ -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 { Loading Loading @@ -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
drivers/gpu/drm/nouveau/include/nvif/outp.h +1 −0 Original line number Diff line number Diff line Loading @@ -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
drivers/gpu/drm/nouveau/nvif/outp.c +21 −0 Original line number Diff line number Diff line Loading @@ -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