LCOV - code coverage report
Current view: top level - sound/hda - hdac_i915.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 49 0.0 %
Date: 2022-04-01 14:17:54 Functions: 0 4 0.0 %
Branches: 0 32 0.0 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0-or-later
       2                 :            : /*
       3                 :            :  *  hdac_i915.c - routines for sync between HD-A core and i915 display driver
       4                 :            :  */
       5                 :            : 
       6                 :            : #include <linux/init.h>
       7                 :            : #include <linux/module.h>
       8                 :            : #include <linux/pci.h>
       9                 :            : #include <sound/core.h>
      10                 :            : #include <sound/hdaudio.h>
      11                 :            : #include <sound/hda_i915.h>
      12                 :            : #include <sound/hda_register.h>
      13                 :            : 
      14                 :            : static struct completion bind_complete;
      15                 :            : 
      16                 :            : #define CONTROLLER_IN_GPU(pci) (((pci)->device == 0x0a0c) || \
      17                 :            :                                 ((pci)->device == 0x0c0c) || \
      18                 :            :                                 ((pci)->device == 0x0d0c) || \
      19                 :            :                                 ((pci)->device == 0x160c))
      20                 :            : 
      21                 :            : /**
      22                 :            :  * snd_hdac_i915_set_bclk - Reprogram BCLK for HSW/BDW
      23                 :            :  * @bus: HDA core bus
      24                 :            :  *
      25                 :            :  * Intel HSW/BDW display HDA controller is in GPU. Both its power and link BCLK
      26                 :            :  * depends on GPU. Two Extended Mode registers EM4 (M value) and EM5 (N Value)
      27                 :            :  * are used to convert CDClk (Core Display Clock) to 24MHz BCLK:
      28                 :            :  * BCLK = CDCLK * M / N
      29                 :            :  * The values will be lost when the display power well is disabled and need to
      30                 :            :  * be restored to avoid abnormal playback speed.
      31                 :            :  *
      32                 :            :  * Call this function at initializing and changing power well, as well as
      33                 :            :  * at ELD notifier for the hotplug.
      34                 :            :  */
      35                 :          0 : void snd_hdac_i915_set_bclk(struct hdac_bus *bus)
      36                 :            : {
      37                 :          0 :         struct drm_audio_component *acomp = bus->audio_component;
      38                 :          0 :         struct pci_dev *pci = to_pci_dev(bus->dev);
      39                 :          0 :         int cdclk_freq;
      40                 :          0 :         unsigned int bclk_m, bclk_n;
      41                 :            : 
      42   [ #  #  #  #  :          0 :         if (!acomp || !acomp->ops || !acomp->ops->get_cdclk_freq)
                   #  # ]
      43                 :            :                 return; /* only for i915 binding */
      44   [ #  #  #  #  :          0 :         if (!CONTROLLER_IN_GPU(pci))
                   #  # ]
      45                 :            :                 return; /* only HSW/BDW */
      46                 :            : 
      47                 :          0 :         cdclk_freq = acomp->ops->get_cdclk_freq(acomp->dev);
      48   [ #  #  #  # ]:          0 :         switch (cdclk_freq) {
      49                 :            :         case 337500:
      50                 :            :                 bclk_m = 16;
      51                 :            :                 bclk_n = 225;
      52                 :            :                 break;
      53                 :            : 
      54                 :          0 :         case 450000:
      55                 :            :         default: /* default CDCLK 450MHz */
      56                 :          0 :                 bclk_m = 4;
      57                 :          0 :                 bclk_n = 75;
      58                 :          0 :                 break;
      59                 :            : 
      60                 :          0 :         case 540000:
      61                 :          0 :                 bclk_m = 4;
      62                 :          0 :                 bclk_n = 90;
      63                 :          0 :                 break;
      64                 :            : 
      65                 :          0 :         case 675000:
      66                 :          0 :                 bclk_m = 8;
      67                 :          0 :                 bclk_n = 225;
      68                 :          0 :                 break;
      69                 :            :         }
      70                 :            : 
      71                 :          0 :         snd_hdac_chip_writew(bus, HSW_EM4, bclk_m);
      72                 :          0 :         snd_hdac_chip_writew(bus, HSW_EM5, bclk_n);
      73                 :            : }
      74                 :            : EXPORT_SYMBOL_GPL(snd_hdac_i915_set_bclk);
      75                 :            : 
      76                 :          0 : static int i915_component_master_match(struct device *dev, int subcomponent,
      77                 :            :                                        void *data)
      78                 :            : {
      79   [ #  #  #  # ]:          0 :         return !strcmp(dev->driver->name, "i915") &&
      80                 :            :                subcomponent == I915_COMPONENT_AUDIO;
      81                 :            : }
      82                 :            : 
      83                 :            : /* check whether intel graphics is present */
      84                 :          0 : static bool i915_gfx_present(void)
      85                 :            : {
      86                 :          0 :         static const struct pci_device_id ids[] = {
      87                 :            :                 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_ANY_ID),
      88                 :            :                   .class = PCI_BASE_CLASS_DISPLAY << 16,
      89                 :            :                   .class_mask = 0xff << 16 },
      90                 :            :                 {}
      91                 :            :         };
      92                 :          0 :         return pci_dev_present(ids);
      93                 :            : }
      94                 :            : 
      95                 :          0 : static int i915_master_bind(struct device *dev,
      96                 :            :                             struct drm_audio_component *acomp)
      97                 :            : {
      98                 :          0 :         complete_all(&bind_complete);
      99                 :            :         /* clear audio_ops here as it was needed only for completion call */
     100                 :          0 :         acomp->audio_ops = NULL;
     101                 :          0 :         return 0;
     102                 :            : }
     103                 :            : 
     104                 :            : static const struct drm_audio_component_audio_ops i915_init_ops = {
     105                 :            :         .master_bind = i915_master_bind
     106                 :            : };
     107                 :            : 
     108                 :            : /**
     109                 :            :  * snd_hdac_i915_init - Initialize i915 audio component
     110                 :            :  * @bus: HDA core bus
     111                 :            :  *
     112                 :            :  * This function is supposed to be used only by a HD-audio controller
     113                 :            :  * driver that needs the interaction with i915 graphics.
     114                 :            :  *
     115                 :            :  * This function initializes and sets up the audio component to communicate
     116                 :            :  * with i915 graphics driver.
     117                 :            :  *
     118                 :            :  * Returns zero for success or a negative error code.
     119                 :            :  */
     120                 :          0 : int snd_hdac_i915_init(struct hdac_bus *bus)
     121                 :            : {
     122                 :          0 :         struct drm_audio_component *acomp;
     123                 :          0 :         int err;
     124                 :            : 
     125         [ #  # ]:          0 :         if (!i915_gfx_present())
     126                 :            :                 return -ENODEV;
     127                 :            : 
     128                 :          0 :         init_completion(&bind_complete);
     129                 :            : 
     130                 :          0 :         err = snd_hdac_acomp_init(bus, &i915_init_ops,
     131                 :            :                                   i915_component_master_match,
     132                 :            :                                   sizeof(struct i915_audio_component) - sizeof(*acomp));
     133         [ #  # ]:          0 :         if (err < 0)
     134                 :            :                 return err;
     135                 :          0 :         acomp = bus->audio_component;
     136         [ #  # ]:          0 :         if (!acomp)
     137                 :            :                 return -ENODEV;
     138         [ #  # ]:          0 :         if (!acomp->ops) {
     139         [ #  # ]:          0 :                 if (!IS_ENABLED(CONFIG_MODULES) ||
     140                 :          0 :                     !request_module("i915")) {
     141                 :            :                         /* 60s timeout */
     142                 :          0 :                         wait_for_completion_timeout(&bind_complete,
     143                 :            :                                                    msecs_to_jiffies(60 * 1000));
     144                 :            :                 }
     145                 :            :         }
     146         [ #  # ]:          0 :         if (!acomp->ops) {
     147                 :          0 :                 dev_info(bus->dev, "couldn't bind with audio component\n");
     148                 :          0 :                 snd_hdac_acomp_exit(bus);
     149                 :          0 :                 return -ENODEV;
     150                 :            :         }
     151                 :            :         return 0;
     152                 :            : }
     153                 :            : EXPORT_SYMBOL_GPL(snd_hdac_i915_init);

Generated by: LCOV version 1.14