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 #include <video/nomodeset.h> 14 15 static int gpu_bind = -1; 16 module_param(gpu_bind, int, 0644); 17 MODULE_PARM_DESC(gpu_bind, "Whether to bind sound component to GPU " 18 "(1=always, 0=never, -1=on nomodeset(default))"); 19 20 /** 21 * snd_hdac_i915_set_bclk - Reprogram BCLK for HSW/BDW 22 * @bus: HDA core bus 23 * 24 * Intel HSW/BDW display HDA controller is in GPU. Both its power and link BCLK 25 * depends on GPU. Two Extended Mode registers EM4 (M value) and EM5 (N Value) 26 * are used to convert CDClk (Core Display Clock) to 24MHz BCLK: 27 * BCLK = CDCLK * M / N 28 * The values will be lost when the display power well is disabled and need to 29 * be restored to avoid abnormal playback speed. 30 * 31 * Call this function at initializing and changing power well, as well as 32 * at ELD notifier for the hotplug. 33 */ 34 void snd_hdac_i915_set_bclk(struct hdac_bus *bus) 35 { 36 struct drm_audio_component *acomp = bus->audio_component; 37 struct pci_dev *pci = to_pci_dev(bus->dev); 38 int cdclk_freq; 39 unsigned int bclk_m, bclk_n; 40 41 if (!acomp || !acomp->ops || !acomp->ops->get_cdclk_freq) 42 return; /* only for i915 binding */ 43 if (!HDA_CONTROLLER_IS_HSW(pci)) 44 return; /* only HSW/BDW */ 45 46 cdclk_freq = acomp->ops->get_cdclk_freq(acomp->dev); 47 switch (cdclk_freq) { 48 case 337500: 49 bclk_m = 16; 50 bclk_n = 225; 51 break; 52 53 case 450000: 54 default: /* default CDCLK 450MHz */ 55 bclk_m = 4; 56 bclk_n = 75; 57 break; 58 59 case 540000: 60 bclk_m = 4; 61 bclk_n = 90; 62 break; 63 64 case 675000: 65 bclk_m = 8; 66 bclk_n = 225; 67 break; 68 } 69 70 snd_hdac_chip_writew(bus, HSW_EM4, bclk_m); 71 snd_hdac_chip_writew(bus, HSW_EM5, bclk_n); 72 } 73 EXPORT_SYMBOL_GPL(snd_hdac_i915_set_bclk); 74 75 /* returns true if the devices can be connected for audio */ 76 static bool connectivity_check(struct pci_dev *i915, struct pci_dev *hdac) 77 { 78 struct pci_bus *bus_a = i915->bus, *bus_b = hdac->bus; 79 80 /* directly connected on the same bus */ 81 if (bus_a == bus_b) 82 return true; 83 84 bus_a = bus_a->parent; 85 bus_b = bus_b->parent; 86 87 /* connected via parent bus (may be NULL!) */ 88 if (bus_a == bus_b) 89 return true; 90 91 if (!bus_a || !bus_b) 92 return false; 93 94 /* 95 * on i915 discrete GPUs with embedded HDA audio, the two 96 * devices are connected via 2nd level PCI bridge 97 */ 98 bus_a = bus_a->parent; 99 bus_b = bus_b->parent; 100 if (bus_a && bus_a == bus_b) 101 return true; 102 103 return false; 104 } 105 106 static int i915_component_master_match(struct device *dev, int subcomponent, 107 void *data) 108 { 109 struct pci_dev *hdac_pci, *i915_pci; 110 struct hdac_bus *bus = data; 111 112 if (!dev_is_pci(dev)) 113 return 0; 114 115 hdac_pci = to_pci_dev(bus->dev); 116 i915_pci = to_pci_dev(dev); 117 118 if ((!strcmp(dev->driver->name, "i915") || 119 !strcmp(dev->driver->name, "xe")) && 120 subcomponent == I915_COMPONENT_AUDIO && 121 connectivity_check(i915_pci, hdac_pci)) 122 return 1; 123 124 return 0; 125 } 126 127 /* check whether Intel graphics is present and reachable */ 128 static int i915_gfx_present(struct pci_dev *hdac_pci) 129 { 130 /* List of known platforms with no i915 support. */ 131 static const struct pci_device_id denylist[] = { 132 /* CNL */ 133 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x5a40), 0x030000, 0xff0000 }, 134 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x5a41), 0x030000, 0xff0000 }, 135 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x5a42), 0x030000, 0xff0000 }, 136 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x5a44), 0x030000, 0xff0000 }, 137 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x5a49), 0x030000, 0xff0000 }, 138 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x5a4a), 0x030000, 0xff0000 }, 139 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x5a4c), 0x030000, 0xff0000 }, 140 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x5a50), 0x030000, 0xff0000 }, 141 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x5a51), 0x030000, 0xff0000 }, 142 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x5a52), 0x030000, 0xff0000 }, 143 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x5a54), 0x030000, 0xff0000 }, 144 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x5a59), 0x030000, 0xff0000 }, 145 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x5a5a), 0x030000, 0xff0000 }, 146 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x5a5c), 0x030000, 0xff0000 }, 147 /* LKF */ 148 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9840), 0x030000, 0xff0000 }, 149 {} 150 }; 151 struct pci_dev *display_dev = NULL; 152 153 if (!gpu_bind || (gpu_bind < 0 && video_firmware_drivers_only())) 154 return false; 155 156 for_each_pci_dev(display_dev) { 157 if (display_dev->vendor != PCI_VENDOR_ID_INTEL || 158 (display_dev->class >> 16) != PCI_BASE_CLASS_DISPLAY) 159 continue; 160 161 if (pci_match_id(denylist, display_dev)) 162 continue; 163 164 if (connectivity_check(display_dev, hdac_pci)) { 165 pci_dev_put(display_dev); 166 return true; 167 } 168 } 169 170 return false; 171 } 172 173 /** 174 * snd_hdac_i915_init - Initialize i915 audio component 175 * @bus: HDA core bus 176 * 177 * This function is supposed to be used only by a HD-audio controller 178 * driver that needs the interaction with i915 graphics. 179 * 180 * This function initializes and sets up the audio component to communicate 181 * with i915 graphics driver. 182 * 183 * Returns zero for success or a negative error code. 184 */ 185 int snd_hdac_i915_init(struct hdac_bus *bus) 186 { 187 struct drm_audio_component *acomp; 188 int err; 189 190 if (!i915_gfx_present(to_pci_dev(bus->dev))) 191 return -ENODEV; 192 193 err = snd_hdac_acomp_init(bus, NULL, 194 i915_component_master_match, 195 sizeof(struct i915_audio_component) - sizeof(*acomp)); 196 if (err < 0) 197 return err; 198 acomp = bus->audio_component; 199 if (!acomp) 200 return -ENODEV; 201 if (!acomp->ops) { 202 snd_hdac_acomp_exit(bus); 203 return dev_err_probe(bus->dev, -EPROBE_DEFER, 204 "couldn't bind with audio component\n"); 205 } 206 return 0; 207 } 208 EXPORT_SYMBOL_GPL(snd_hdac_i915_init); 209