29
29
30
30
#include <linux/dma-mapping.h>
31
31
#include <linux/hdmi.h>
32
+ #include <linux/component.h>
32
33
33
34
#include <drm/drm_atomic_helper.h>
34
35
#include <drm/drm_dp_helper.h>
@@ -476,12 +477,113 @@ nv50_dac_create(struct drm_connector *connector, struct dcb_output *dcbe)
476
477
return 0 ;
477
478
}
478
479
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
+
479
580
/******************************************************************************
480
581
* Audio
481
582
*****************************************************************************/
482
583
static void
483
584
nv50_audio_disable (struct drm_encoder * encoder , struct nouveau_crtc * nv_crtc )
484
585
{
586
+ struct nouveau_drm * drm = nouveau_drm (encoder -> dev );
485
587
struct nouveau_encoder * nv_encoder = nouveau_encoder (encoder );
486
588
struct nv50_disp * disp = nv50_disp (encoder -> dev );
487
589
struct {
@@ -496,11 +598,14 @@ nv50_audio_disable(struct drm_encoder *encoder, struct nouveau_crtc *nv_crtc)
496
598
};
497
599
498
600
nvif_mthd (& disp -> disp -> object , 0 , & args , sizeof (args ));
601
+
602
+ nv50_audio_component_eld_notify (drm -> audio .component , nv_crtc -> index );
499
603
}
500
604
501
605
static void
502
606
nv50_audio_enable (struct drm_encoder * encoder , struct drm_display_mode * mode )
503
607
{
608
+ struct nouveau_drm * drm = nouveau_drm (encoder -> dev );
504
609
struct nouveau_encoder * nv_encoder = nouveau_encoder (encoder );
505
610
struct nouveau_crtc * nv_crtc = nouveau_crtc (encoder -> crtc );
506
611
struct nouveau_connector * nv_connector ;
@@ -527,6 +632,8 @@ nv50_audio_enable(struct drm_encoder *encoder, struct drm_display_mode *mode)
527
632
528
633
nvif_mthd (& disp -> disp -> object , 0 , & args ,
529
634
sizeof (args .base ) + drm_eld_size (args .data ));
635
+
636
+ nv50_audio_component_eld_notify (drm -> audio .component , nv_crtc -> index );
530
637
}
531
638
532
639
/******************************************************************************
@@ -2296,6 +2403,8 @@ nv50_display_destroy(struct drm_device *dev)
2296
2403
{
2297
2404
struct nv50_disp * disp = nv50_disp (dev );
2298
2405
2406
+ nv50_audio_component_fini (nouveau_drm (dev ));
2407
+
2299
2408
nv50_core_del (& disp -> core );
2300
2409
2301
2410
nouveau_bo_unmap (disp -> sync );
@@ -2444,6 +2553,8 @@ nv50_display_create(struct drm_device *dev)
2444
2553
/* Disable vblank irqs aggressively for power-saving, safe on nv50+ */
2445
2554
dev -> vblank_disable_immediate = true;
2446
2555
2556
+ nv50_audio_component_init (drm );
2557
+
2447
2558
out :
2448
2559
if (ret )
2449
2560
nv50_display_destroy (dev );
0 commit comments