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 *****************************************************************************/
482583static void
483584nv50_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
501605static void
502606nv50_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+
24472558out :
24482559 if (ret )
24492560 nv50_display_destroy (dev );
0 commit comments