staticint gpu_bind = -1;
module_param(gpu_bind, int, 0644);
MODULE_PARM_DESC(gpu_bind, "Whether to bind sound component to GPU " "(1=always, 0=never, -1=on nomodeset(default))");
/** * snd_hdac_i915_set_bclk - Reprogram BCLK for HSW/BDW * @bus: HDA core bus * * Intel HSW/BDW display HDA controller is in GPU. Both its power and link BCLK * depends on GPU. Two Extended Mode registers EM4 (M value) and EM5 (N Value) * are used to convert CDClk (Core Display Clock) to 24MHz BCLK: * BCLK = CDCLK * M / N * The values will be lost when the display power well is disabled and need to * be restored to avoid abnormal playback speed. * * Call this function at initializing and changing power well, as well as * at ELD notifier for the hotplug.
*/ void snd_hdac_i915_set_bclk(struct hdac_bus *bus)
{ struct drm_audio_component *acomp = bus->audio_component; struct pci_dev *pci = to_pci_dev(bus->dev); int cdclk_freq; unsignedint bclk_m, bclk_n;
if (!acomp || !acomp->ops || !acomp->ops->get_cdclk_freq) return; /* only for i915 binding */ if (!HDA_CONTROLLER_IS_HSW(pci)) return; /* only HSW/BDW */
/* returns true if the devices can be connected for audio */ staticbool connectivity_check(struct pci_dev *i915, struct pci_dev *hdac)
{ struct pci_bus *bus_a = i915->bus, *bus_b = hdac->bus;
/* directly connected on the same bus */ if (bus_a == bus_b) returntrue;
bus_a = bus_a->parent;
bus_b = bus_b->parent;
/* connected via parent bus (may be NULL!) */ if (bus_a == bus_b) returntrue;
if (!bus_a || !bus_b) returnfalse;
/* * on i915 discrete GPUs with embedded HDA audio, the two * devices are connected via 2nd level PCI bridge
*/
bus_a = bus_a->parent;
bus_b = bus_b->parent; if (bus_a && bus_a == bus_b) returntrue;
if (!gpu_bind || (gpu_bind < 0 && video_firmware_drivers_only())) returnfalse;
for_each_pci_dev(display_dev) { if (display_dev->vendor != PCI_VENDOR_ID_INTEL ||
!pci_is_display(display_dev)) continue;
if (pci_match_id(denylist, display_dev)) continue;
if (connectivity_check(display_dev, hdac_pci)) {
pci_dev_put(display_dev); returntrue;
}
}
returnfalse;
}
/** * snd_hdac_i915_init - Initialize i915 audio component * @bus: HDA core bus * * This function is supposed to be used only by a HD-audio controller * driver that needs the interaction with i915 graphics. * * This function initializes and sets up the audio component to communicate * with i915 graphics driver. * * Returns zero for success or a negative error code.
*/ int snd_hdac_i915_init(struct hdac_bus *bus)
{ struct drm_audio_component *acomp; int err;
if (!i915_gfx_present(to_pci_dev(bus->dev))) return -ENODEV;
err = snd_hdac_acomp_init(bus, NULL,
i915_component_master_match, sizeof(struct i915_audio_component) - sizeof(*acomp)); if (err < 0) return err;
acomp = bus->audio_component; if (!acomp) return -ENODEV; if (!acomp->ops) {
snd_hdac_acomp_exit(bus); return dev_err_probe(bus->dev, -EPROBE_DEFER, "couldn't bind with audio component\n");
} return 0;
}
EXPORT_SYMBOL_GPL(snd_hdac_i915_init);
Messung V0.5
¤ Dauer der Verarbeitung: 0.0 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.