// SPDX-License-Identifier: GPL-2.0-or-later/* * * hda_intel.c - Implementation of primary alsa driver code base * for Intel HD Audio. * * Copyright(c) 2004 Intel Corporation * * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de> * PeiSen Hou <pshou@realtek.com.tw> * * CONTACTS: * * Matt Jared matt.jared@intel.com * Andy Kopp andy.kopp@intel.com * Dan Kogan dan.d.kogan@intel.com * * CHANGES: * * 2004.12.01 Major rewrite by tiwai, merged the work of pshou */ #include <linux/delay.h>#include <linux/interrupt.h>#include <linux/kernel.h>#include <linux/module.h>#include <linux/dma-mapping.h>#include <linux/moduleparam.h>#include <linux/init.h>#include <linux/slab.h>#include <linux/pci.h>#include <linux/mutex.h>#include <linux/io.h>#include <linux/pm_runtime.h>#include <linux/clocksource.h>#include <linux/time.h>#include <linux/completion.h>#include <linux/acpi.h>#include <linux/pgtable.h>#include <linux/dmi.h> #ifdef CONFIG_X86/* for snoop control */#include <asm/set_memory.h>#include <asm/cpufeature.h>#endif#include <sound/core.h>#include <sound/initval.h>#include <sound/hdaudio.h>#include <sound/hda_i915.h>#include <sound/intel-dsp-config.h>#include <linux/vgaarb.h>#include <linux/vga_switcheroo.h>#include <linux/apple-gmux.h>#include <linux/firmware.h>#include <sound/hda_codec.h>#include "intel.h" #define CREATE_TRACE_POINTS#include "intel_trace.h" /* position fix mode */enum { POS_FIX_AUTO, POS_FIX_LPIB, POS_FIX_POSBUF, POS_FIX_VIACOMBO, POS_FIX_COMBO, POS_FIX_SKL, POS_FIX_FIFO,}; /* Defines for ATI HD Audio support in SB450 south bridge */#define ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR 0x42#define ATI_SB450_HDAUDIO_ENABLE_SNOOP 0x02 /* Defines for Nvidia HDA support */#define NVIDIA_HDA_TRANSREG_ADDR 0x4e#define NVIDIA_HDA_ENABLE_COHBITS 0x0f#define NVIDIA_HDA_ISTRM_COH 0x4d#define NVIDIA_HDA_OSTRM_COH 0x4c#define NVIDIA_HDA_ENABLE_COHBIT 0x01 /* Defines for Intel SCH HDA snoop control */#define INTEL_HDA_CGCTL 0x48#define INTEL_HDA_CGCTL_MISCBDCGE (0x1 << 6)#define INTEL_SCH_HDA_DEVC 0x78#define INTEL_SCH_HDA_DEVC_NOSNOOP (0x1<<11) /* max number of SDs *//* ICH, ATI and VIA have 4 playback and 4 capture */#define ICH6_NUM_CAPTURE 4#define ICH6_NUM_PLAYBACK 4 /* ULI has 6 playback and 5 capture */#define ULI_NUM_CAPTURE 5#define ULI_NUM_PLAYBACK 6 /* ATI HDMI may have up to 8 playbacks and 0 capture */#define ATIHDMI_NUM_CAPTURE 0#define ATIHDMI_NUM_PLAYBACK 8 /* Hygon HD Audio controller */#define PCI_DEVICE_ID_HYGON_18H_M05H_HDA 0x14a9 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;static char *model[SNDRV_CARDS];static int position_fix[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};static int bdl_pos_adj[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};static int probe_mask[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};static int probe_only[SNDRV_CARDS];static int jackpoll_ms[SNDRV_CARDS];static int single_cmd = -1;static int enable_msi = -1;#ifdef CONFIG_SND_HDA_PATCH_LOADERstatic char *patch[SNDRV_CARDS];#endif#ifdef CONFIG_SND_HDA_INPUT_BEEPstatic bool beep_mode[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = CONFIG_SND_HDA_INPUT_BEEP_MODE};#endifstatic bool dmic_detect = 1;static bool ctl_dev_id = IS_ENABLED(CONFIG_SND_HDA_CTL_DEV_ID) ? 1 : 0; module_param_array(index, int, NULL, 0444);MODULE_PARM_DESC(index, "Index value for Intel HD audio interface.");module_param_array(id, charp, NULL, 0444);MODULE_PARM_DESC(id, "ID string for Intel HD audio interface.");module_param_array(enable, bool, NULL, 0444);MODULE_PARM_DESC(enable, "Enable Intel HD audio interface.");module_param_array(model, charp, NULL, 0444);MODULE_PARM_DESC(model, "Use the given board model.");module_param_array(position_fix, int, NULL, 0444);MODULE_PARM_DESC(position_fix, "DMA pointer read method." "(-1 = system default, 0 = auto, 1 = LPIB, 2 = POSBUF, 3 = VIACOMBO, 4 = COMBO, 5 = SKL+, 6 = FIFO).");module_param_array(bdl_pos_adj, int, NULL, 0644);MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset.");module_param_array(probe_mask, int, NULL, 0444);MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1).");module_param_array(probe_only, int, NULL, 0444);MODULE_PARM_DESC(probe_only, "Only probing and no codec initialization.");module_param_array(jackpoll_ms, int, NULL, 0444);MODULE_PARM_DESC(jackpoll_ms, "Ms between polling for jack events (default = 0, using unsol events only)");module_param(single_cmd, bint, 0444);MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs " "(for debugging only).");module_param(enable_msi, bint, 0444);MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)");#ifdef CONFIG_SND_HDA_PATCH_LOADERmodule_param_array(patch, charp, NULL, 0444);MODULE_PARM_DESC(patch, "Patch file for Intel HD audio interface.");#endif#ifdef CONFIG_SND_HDA_INPUT_BEEPmodule_param_array(beep_mode, bool, NULL, 0444);MODULE_PARM_DESC(beep_mode, "Select HDA Beep registration mode " "(0=off, 1=on) (default=1).");#endifmodule_param(dmic_detect, bool, 0444);MODULE_PARM_DESC(dmic_detect, "Allow DSP driver selection (bypass this driver) " "(0=off, 1=on) (default=1); " "deprecated, use snd-intel-dspcfg.dsp_driver option instead");module_param(ctl_dev_id, bool, 0444);MODULE_PARM_DESC(ctl_dev_id, "Use control device identifier (based on codec address)."); #ifdef CONFIG_PMstatic int param_set_xint(const char *val, const struct kernel_param *kp);static const struct kernel_param_ops param_ops_xint = { .set = param_set_xint, .get = param_get_int,};#define param_check_xint param_check_int static int power_save = CONFIG_SND_HDA_POWER_SAVE_DEFAULT;module_param(power_save, xint, 0644);MODULE_PARM_DESC(power_save, "Automatic power-saving timeout " "(in second, 0 = disable)."); static int pm_blacklist = -1;module_param(pm_blacklist, bint, 0644);MODULE_PARM_DESC(pm_blacklist, "Enable power-management denylist"); /* reset the HD-audio controller in power save mode. * this may give more power-saving, but will take longer time to * wake up. */static bool power_save_controller = 1;module_param(power_save_controller, bool, 0644);MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode.");#else /* CONFIG_PM */#define power_save 0#define pm_blacklist 0#define power_save_controller false#endif /* CONFIG_PM */ static int align_buffer_size = -1;module_param(align_buffer_size, bint, 0644);MODULE_PARM_DESC(align_buffer_size, "Force buffer and period sizes to be multiple of 128 bytes."); #ifdef CONFIG_X86static int hda_snoop = -1;module_param_named(snoop, hda_snoop, bint, 0444);MODULE_PARM_DESC(snoop, "Enable/disable snooping");#else#define hda_snoop true#endif MODULE_LICENSE("GPL");MODULE_DESCRIPTION("Intel HDA driver"); #if defined(CONFIG_PM) && defined(CONFIG_VGA_SWITCHEROO)#if IS_ENABLED(CONFIG_SND_HDA_CODEC_HDMI)#define SUPPORT_VGA_SWITCHEROO#endif#endif /* */ /* driver types */enum { AZX_DRIVER_ICH, AZX_DRIVER_PCH, AZX_DRIVER_SCH, AZX_DRIVER_SKL, AZX_DRIVER_HDMI, AZX_DRIVER_ATI, AZX_DRIVER_ATIHDMI, AZX_DRIVER_ATIHDMI_NS, AZX_DRIVER_GFHDMI, AZX_DRIVER_VIA, AZX_DRIVER_SIS, AZX_DRIVER_ULI, AZX_DRIVER_NVIDIA, AZX_DRIVER_TERA, AZX_DRIVER_CTX, AZX_DRIVER_CTHDA, AZX_DRIVER_CMEDIA, AZX_DRIVER_ZHAOXIN, AZX_DRIVER_ZHAOXINHDMI, AZX_DRIVER_LOONGSON, AZX_DRIVER_HYGON, AZX_DRIVER_GENERIC, AZX_NUM_DRIVERS, /* keep this as last entry */}; #define azx_get_snoop_type(chip) \ (((chip)->driver_caps & AZX_DCAPS_SNOOP_MASK) >> 10)#define AZX_DCAPS_SNOOP_TYPE(type) ((AZX_SNOOP_TYPE_ ## type) << 10) /* quirks for old Intel chipsets */#define AZX_DCAPS_INTEL_ICH \ (AZX_DCAPS_OLD_SSYNC | AZX_DCAPS_NO_ALIGN_BUFSIZE) /* quirks for Intel PCH */#define AZX_DCAPS_INTEL_PCH_BASE \ (AZX_DCAPS_NO_ALIGN_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY |\ AZX_DCAPS_SNOOP_TYPE(SCH)) /* PCH up to IVB; no runtime PM; bind with i915 gfx */#define AZX_DCAPS_INTEL_PCH_NOPM \ (AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_I915_COMPONENT) /* PCH for HSW/BDW; with runtime PM *//* no i915 binding for this as HSW/BDW has another controller for HDMI */#define AZX_DCAPS_INTEL_PCH \ (AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_PM_RUNTIME) /* HSW HDMI */#define AZX_DCAPS_INTEL_HASWELL \ (/*AZX_DCAPS_ALIGN_BUFSIZE |*/ AZX_DCAPS_COUNT_LPIB_DELAY |\ AZX_DCAPS_PM_RUNTIME | AZX_DCAPS_I915_COMPONENT |\ AZX_DCAPS_SNOOP_TYPE(SCH)) /* Broadwell HDMI can't use position buffer reliably, force to use LPIB */#define AZX_DCAPS_INTEL_BROADWELL \ (/*AZX_DCAPS_ALIGN_BUFSIZE |*/ AZX_DCAPS_POSFIX_LPIB |\ AZX_DCAPS_PM_RUNTIME | AZX_DCAPS_I915_COMPONENT |\ AZX_DCAPS_SNOOP_TYPE(SCH)) #define AZX_DCAPS_INTEL_BAYTRAIL \ (AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_I915_COMPONENT) #define AZX_DCAPS_INTEL_BRASWELL \ (AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_PM_RUNTIME |\ AZX_DCAPS_I915_COMPONENT) #define AZX_DCAPS_INTEL_SKYLAKE \ (AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_PM_RUNTIME |\ AZX_DCAPS_SEPARATE_STREAM_TAG | AZX_DCAPS_I915_COMPONENT) #define AZX_DCAPS_INTEL_BROXTON AZX_DCAPS_INTEL_SKYLAKE #define AZX_DCAPS_INTEL_LNL \ (AZX_DCAPS_INTEL_SKYLAKE | AZX_DCAPS_PIO_COMMANDS) #define AZX_DCAPS_INTEL_NVL \ (AZX_DCAPS_INTEL_LNL & ~AZX_DCAPS_NO_ALIGN_BUFSIZE) /* quirks for ATI SB / AMD Hudson */#define AZX_DCAPS_PRESET_ATI_SB \ (AZX_DCAPS_NO_TCSEL | AZX_DCAPS_POSFIX_LPIB |\ AZX_DCAPS_SNOOP_TYPE(ATI)) /* quirks for ATI/AMD HDMI */#define AZX_DCAPS_PRESET_ATI_HDMI \ (AZX_DCAPS_NO_TCSEL | AZX_DCAPS_POSFIX_LPIB|\ AZX_DCAPS_NO_MSI64) /* quirks for ATI HDMI with snoop off */#define AZX_DCAPS_PRESET_ATI_HDMI_NS \ (AZX_DCAPS_PRESET_ATI_HDMI | AZX_DCAPS_SNOOP_OFF) /* quirks for AMD SB */#define AZX_DCAPS_PRESET_AMD_SB \ (AZX_DCAPS_NO_TCSEL | AZX_DCAPS_AMD_WORKAROUND |\ AZX_DCAPS_SNOOP_TYPE(ATI) | AZX_DCAPS_PM_RUNTIME |\ AZX_DCAPS_RETRY_PROBE) /* quirks for Nvidia */#define AZX_DCAPS_PRESET_NVIDIA \ (AZX_DCAPS_NO_MSI | AZX_DCAPS_CORBRP_SELF_CLEAR |\ AZX_DCAPS_SNOOP_TYPE(NVIDIA)) #define AZX_DCAPS_PRESET_CTHDA \ (AZX_DCAPS_NO_MSI | AZX_DCAPS_POSFIX_LPIB |\ AZX_DCAPS_NO_64BIT |\ AZX_DCAPS_4K_BDLE_BOUNDARY | AZX_DCAPS_SNOOP_OFF) /* * vga_switcheroo support */#ifdef SUPPORT_VGA_SWITCHEROO#define use_vga_switcheroo(chip) ((chip)->use_vga_switcheroo)#define needs_eld_notify_link(chip) ((chip)->bus.keep_power)#else#define use_vga_switcheroo(chip) 0#define needs_eld_notify_link(chip) false#endif static const char * const driver_short_names[] = { [AZX_DRIVER_ICH] = "HDA Intel", [AZX_DRIVER_PCH] = "HDA Intel PCH", [AZX_DRIVER_SCH] = "HDA Intel MID", [AZX_DRIVER_SKL] = "HDA Intel PCH", /* kept old name for compatibility */ [AZX_DRIVER_HDMI] = "HDA Intel HDMI", [AZX_DRIVER_ATI] = "HDA ATI SB", [AZX_DRIVER_ATIHDMI] = "HDA ATI HDMI", [AZX_DRIVER_ATIHDMI_NS] = "HDA ATI HDMI", [AZX_DRIVER_GFHDMI] = "HDA GF HDMI", [AZX_DRIVER_VIA] = "HDA VIA VT82xx", [AZX_DRIVER_SIS] = "HDA SIS966", [AZX_DRIVER_ULI] = "HDA ULI M5461", [AZX_DRIVER_NVIDIA] = "HDA NVidia", [AZX_DRIVER_TERA] = "HDA Teradici", [AZX_DRIVER_CTX] = "HDA Creative", [AZX_DRIVER_CTHDA] = "HDA Creative", [AZX_DRIVER_CMEDIA] = "HDA C-Media", [AZX_DRIVER_ZHAOXIN] = "HDA Zhaoxin", [AZX_DRIVER_ZHAOXINHDMI] = "HDA Zhaoxin HDMI", [AZX_DRIVER_LOONGSON] = "HDA Loongson", [AZX_DRIVER_HYGON] = "HDA Hygon", [AZX_DRIVER_GENERIC] = "HD-Audio Generic",}; static int azx_acquire_irq(struct azx *chip, int do_disconnect);static void set_default_power_save(struct azx *chip); /* * initialize the PCI registers *//* update bits in a PCI register byte */static void update_pci_byte(struct pci_dev *pci, unsigned int reg, unsigned char mask, unsigned char val){ unsigned char data; pci_read_config_byte(pci, reg, &data); data &= ~mask; data |= (val & mask); pci_write_config_byte(pci, reg, data);} static void azx_init_pci(struct azx *chip){ int snoop_type = azx_get_snoop_type(chip); /* Clear bits 0-2 of PCI register TCSEL (at offset 0x44) * TCSEL == Traffic Class Select Register, which sets PCI express QOS * Ensuring these bits are 0 clears playback static on some HD Audio * codecs. * The PCI register TCSEL is defined in the Intel manuals. */ if (!(chip->driver_caps & AZX_DCAPS_NO_TCSEL)) { dev_dbg(chip->card->dev, "Clearing TCSEL\n"); update_pci_byte(chip->pci, AZX_PCIREG_TCSEL, 0x07, 0); } /* For ATI SB450/600/700/800/900 and AMD Hudson azalia HD audio, * we need to enable snoop. */ if (snoop_type == AZX_SNOOP_TYPE_ATI) { dev_dbg(chip->card->dev, "Setting ATI snoop: %d\n", azx_snoop(chip)); update_pci_byte(chip->pci, ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, 0x07, azx_snoop(chip) ? ATI_SB450_HDAUDIO_ENABLE_SNOOP : 0); } /* For NVIDIA HDA, enable snoop */ if (snoop_type == AZX_SNOOP_TYPE_NVIDIA) { dev_dbg(chip->card->dev, "Setting Nvidia snoop: %d\n", azx_snoop(chip)); update_pci_byte(chip->pci, NVIDIA_HDA_TRANSREG_ADDR, 0x0f, NVIDIA_HDA_ENABLE_COHBITS); update_pci_byte(chip->pci, NVIDIA_HDA_ISTRM_COH, 0x01, NVIDIA_HDA_ENABLE_COHBIT); update_pci_byte(chip->pci, NVIDIA_HDA_OSTRM_COH, 0x01, NVIDIA_HDA_ENABLE_COHBIT); } /* Enable SCH/PCH snoop if needed */ if (snoop_type == AZX_SNOOP_TYPE_SCH) { unsigned short snoop; pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop); if ((!azx_snoop(chip) && !(snoop & INTEL_SCH_HDA_DEVC_NOSNOOP)) || (azx_snoop(chip) && (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP))) { snoop &= ~INTEL_SCH_HDA_DEVC_NOSNOOP; if (!azx_snoop(chip)) snoop |= INTEL_SCH_HDA_DEVC_NOSNOOP; pci_write_config_word(chip->pci, INTEL_SCH_HDA_DEVC, snoop); pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop); } dev_dbg(chip->card->dev, "SCH snoop: %s\n", (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) ? "Disabled" : "Enabled"); }} /* * In BXT-P A0, HD-Audio DMA requests is later than expected, * and makes an audio stream sensitive to system latencies when * 24/32 bits are playing. * Adjusting threshold of DMA fifo to force the DMA request * sooner to improve latency tolerance at the expense of power. */static void bxt_reduce_dma_latency(struct azx *chip){ u32 val; val = azx_readl(chip, VS_EM4L); val &= (0x3 << 20); azx_writel(chip, VS_EM4L, val);} /* * ML_LCAP bits: * bit 0: 6 MHz Supported * bit 1: 12 MHz Supported * bit 2: 24 MHz Supported * bit 3: 48 MHz Supported * bit 4: 96 MHz Supported * bit 5: 192 MHz Supported */static int intel_get_lctl_scf(struct azx *chip){ struct hdac_bus *bus = azx_bus(chip); static const int preferred_bits[] = { 2, 3, 1, 4, 5 }; u32 val, t; int i; val = readl(bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCAP); for (i = 0; i < ARRAY_SIZE(preferred_bits); i++) { t = preferred_bits[i]; if (val & (1 << t)) return t; } dev_warn(chip->card->dev, "set audio clock frequency to 6MHz"); return 0;} static int intel_ml_lctl_set_power(struct azx *chip, int state){ struct hdac_bus *bus = azx_bus(chip); u32 val; int timeout; /* * Changes to LCTL.SCF are only needed for the first multi-link dealing * with external codecsLines 1–500 of 2878. Load more
// SPDX-License-Identifier: GPL-2.0-or-later /* * * hda_intel.c - Implementation of primary alsa driver code base * for Intel HD Audio. * * Copyright(c) 2004 Intel Corporation * * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de> * PeiSen Hou <pshou@realtek.com.tw> * * CONTACTS: * * Matt Jared matt.jared@intel.com * Andy Kopp andy.kopp@intel.com * Dan Kogan dan.d.kogan@intel.com * * CHANGES: * * 2004.12.01 Major rewrite by tiwai, merged the work of pshou */ #include <linux/delay.h> #include <linux/interrupt.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/dma-mapping.h> #include <linux/moduleparam.h> #include <linux/init.h> #include <linux/slab.h> #include <linux/pci.h> #include <linux/mutex.h> #include <linux/io.h> #include <linux/pm_runtime.h> #include <linux/clocksource.h> #include <linux/time.h> #include <linux/completion.h> #include <linux/acpi.h> #include <linux/pgtable.h> #include <linux/dmi.h> #ifdef CONFIG_X86 /* for snoop control */ #include <asm/set_memory.h> #include <asm/cpufeature.h> #endif #include <sound/core.h> #include <sound/initval.h> #include <sound/hdaudio.h> #include <sound/hda_i915.h> #include <sound/intel-dsp-config.h> #include <linux/vgaarb.h> #include <linux/vga_switcheroo.h> #include <linux/apple-gmux.h> #include <linux/firmware.h> #include <sound/hda_codec.h> #include "intel.h" #define CREATE_TRACE_POINTS #include "intel_trace.h" /* position fix mode */ enum { POS_FIX_AUTO, POS_FIX_LPIB, POS_FIX_POSBUF, POS_FIX_VIACOMBO, POS_FIX_COMBO, POS_FIX_SKL, POS_FIX_FIFO, }; /* Defines for ATI HD Audio support in SB450 south bridge */ #define ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR 0x42 #define ATI_SB450_HDAUDIO_ENABLE_SNOOP 0x02 /* Defines for Nvidia HDA support */ #define NVIDIA_HDA_TRANSREG_ADDR 0x4e #define NVIDIA_HDA_ENABLE_COHBITS 0x0f #define NVIDIA_HDA_ISTRM_COH 0x4d #define NVIDIA_HDA_OSTRM_COH 0x4c #define NVIDIA_HDA_ENABLE_COHBIT 0x01 /* Defines for Intel SCH HDA snoop control */ #define INTEL_HDA_CGCTL 0x48 #define INTEL_HDA_CGCTL_MISCBDCGE (0x1 << 6) #define INTEL_SCH_HDA_DEVC 0x78 #define INTEL_SCH_HDA_DEVC_NOSNOOP (0x1<<11) /* max number of SDs */ /* ICH, ATI and VIA have 4 playback and 4 capture */ #define ICH6_NUM_CAPTURE 4 #define ICH6_NUM_PLAYBACK 4 /* ULI has 6 playback and 5 capture */ #define ULI_NUM_CAPTURE 5 #define ULI_NUM_PLAYBACK 6 /* ATI HDMI may have up to 8 playbacks and 0 capture */ #define ATIHDMI_NUM_CAPTURE 0 #define ATIHDMI_NUM_PLAYBACK 8 /* Hygon HD Audio controller */ #define PCI_DEVICE_ID_HYGON_18H_M05H_HDA 0x14a9 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; static char *model[SNDRV_CARDS]; static int position_fix[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1}; static int bdl_pos_adj[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1}; static int probe_mask[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1}; static int probe_only[SNDRV_CARDS]; static int jackpoll_ms[SNDRV_CARDS]; static int single_cmd = -1; static int enable_msi = -1; #ifdef CONFIG_SND_HDA_PATCH_LOADER static char *patch[SNDRV_CARDS]; #endif #ifdef CONFIG_SND_HDA_INPUT_BEEP static bool beep_mode[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = CONFIG_SND_HDA_INPUT_BEEP_MODE}; #endif static bool dmic_detect = 1; static bool ctl_dev_id = IS_ENABLED(CONFIG_SND_HDA_CTL_DEV_ID) ? 1 : 0; module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for Intel HD audio interface."); module_param_array(id, charp, NULL, 0444); MODULE_PARM_DESC(id, "ID string for Intel HD audio interface."); module_param_array(enable, bool, NULL, 0444); MODULE_PARM_DESC(enable, "Enable Intel HD audio interface."); module_param_array(model, charp, NULL, 0444); MODULE_PARM_DESC(model, "Use the given board model."); module_param_array(position_fix, int, NULL, 0444); MODULE_PARM_DESC(position_fix, "DMA pointer read method." "(-1 = system default, 0 = auto, 1 = LPIB, 2 = POSBUF, 3 = VIACOMBO, 4 = COMBO, 5 = SKL+, 6 = FIFO)."); module_param_array(bdl_pos_adj, int, NULL, 0644); MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset."); module_param_array(probe_mask, int, NULL, 0444); MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1)."); module_param_array(probe_only, int, NULL, 0444); MODULE_PARM_DESC(probe_only, "Only probing and no codec initialization."); module_param_array(jackpoll_ms, int, NULL, 0444); MODULE_PARM_DESC(jackpoll_ms, "Ms between polling for jack events (default = 0, using unsol events only)"); module_param(single_cmd, bint, 0444); MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs " "(for debugging only)."); module_param(enable_msi, bint, 0444); MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)"); #ifdef CONFIG_SND_HDA_PATCH_LOADER module_param_array(patch, charp, NULL, 0444); MODULE_PARM_DESC(patch, "Patch file for Intel HD audio interface."); #endif #ifdef CONFIG_SND_HDA_INPUT_BEEP module_param_array(beep_mode, bool, NULL, 0444); MODULE_PARM_DESC(beep_mode, "Select HDA Beep registration mode " "(0=off, 1=on) (default=1)."); #endif module_param(dmic_detect, bool, 0444); MODULE_PARM_DESC(dmic_detect, "Allow DSP driver selection (bypass this driver) " "(0=off, 1=on) (default=1); " "deprecated, use snd-intel-dspcfg.dsp_driver option instead"); module_param(ctl_dev_id, bool, 0444); MODULE_PARM_DESC(ctl_dev_id, "Use control device identifier (based on codec address)."); #ifdef CONFIG_PM static int param_set_xint(const char *val, const struct kernel_param *kp); static const struct kernel_param_ops param_ops_xint = { .set = param_set_xint, .get = param_get_int, }; #define param_check_xint param_check_int static int power_save = CONFIG_SND_HDA_POWER_SAVE_DEFAULT; module_param(power_save, xint, 0644); MODULE_PARM_DESC(power_save, "Automatic power-saving timeout " "(in second, 0 = disable)."); static int pm_blacklist = -1; module_param(pm_blacklist, bint, 0644); MODULE_PARM_DESC(pm_blacklist, "Enable power-management denylist"); /* reset the HD-audio controller in power save mode. * this may give more power-saving, but will take longer time to * wake up. */ static bool power_save_controller = 1; module_param(power_save_controller, bool, 0644); MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode."); #else /* CONFIG_PM */ #define power_save 0 #define pm_blacklist 0 #define power_save_controller false #endif /* CONFIG_PM */ static int align_buffer_size = -1; module_param(align_buffer_size, bint, 0644); MODULE_PARM_DESC(align_buffer_size, "Force buffer and period sizes to be multiple of 128 bytes."); #ifdef CONFIG_X86 static int hda_snoop = -1; module_param_named(snoop, hda_snoop, bint, 0444); MODULE_PARM_DESC(snoop, "Enable/disable snooping"); #else #define hda_snoop true #endif MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Intel HDA driver"); #if defined(CONFIG_PM) && defined(CONFIG_VGA_SWITCHEROO) #if IS_ENABLED(CONFIG_SND_HDA_CODEC_HDMI) #define SUPPORT_VGA_SWITCHEROO #endif #endif /* */ /* driver types */ enum { AZX_DRIVER_ICH, AZX_DRIVER_PCH, AZX_DRIVER_SCH, AZX_DRIVER_SKL, AZX_DRIVER_HDMI, AZX_DRIVER_ATI, AZX_DRIVER_ATIHDMI, AZX_DRIVER_ATIHDMI_NS, AZX_DRIVER_GFHDMI, AZX_DRIVER_VIA, AZX_DRIVER_SIS, AZX_DRIVER_ULI, AZX_DRIVER_NVIDIA, AZX_DRIVER_TERA, AZX_DRIVER_CTX, AZX_DRIVER_CTHDA, AZX_DRIVER_CMEDIA, AZX_DRIVER_ZHAOXIN, AZX_DRIVER_ZHAOXINHDMI, AZX_DRIVER_LOONGSON, AZX_DRIVER_HYGON, AZX_DRIVER_GENERIC, AZX_NUM_DRIVERS, /* keep this as last entry */ }; #define azx_get_snoop_type(chip) \ (((chip)->driver_caps & AZX_DCAPS_SNOOP_MASK) >> 10) #define AZX_DCAPS_SNOOP_TYPE(type) ((AZX_SNOOP_TYPE_ ## type) << 10) /* quirks for old Intel chipsets */ #define AZX_DCAPS_INTEL_ICH \ (AZX_DCAPS_OLD_SSYNC | AZX_DCAPS_NO_ALIGN_BUFSIZE) /* quirks for Intel PCH */ #define AZX_DCAPS_INTEL_PCH_BASE \ (AZX_DCAPS_NO_ALIGN_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY |\ AZX_DCAPS_SNOOP_TYPE(SCH)) /* PCH up to IVB; no runtime PM; bind with i915 gfx */ #define AZX_DCAPS_INTEL_PCH_NOPM \ (AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_I915_COMPONENT) /* PCH for HSW/BDW; with runtime PM */ /* no i915 binding for this as HSW/BDW has another controller for HDMI */ #define AZX_DCAPS_INTEL_PCH \ (AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_PM_RUNTIME) /* HSW HDMI */ #define AZX_DCAPS_INTEL_HASWELL \ (/*AZX_DCAPS_ALIGN_BUFSIZE |*/ AZX_DCAPS_COUNT_LPIB_DELAY |\ AZX_DCAPS_PM_RUNTIME | AZX_DCAPS_I915_COMPONENT |\ AZX_DCAPS_SNOOP_TYPE(SCH)) /* Broadwell HDMI can't use position buffer reliably, force to use LPIB */ #define AZX_DCAPS_INTEL_BROADWELL \ (/*AZX_DCAPS_ALIGN_BUFSIZE |*/ AZX_DCAPS_POSFIX_LPIB |\ AZX_DCAPS_PM_RUNTIME | AZX_DCAPS_I915_COMPONENT |\ AZX_DCAPS_SNOOP_TYPE(SCH)) #define AZX_DCAPS_INTEL_BAYTRAIL \ (AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_I915_COMPONENT) #define AZX_DCAPS_INTEL_BRASWELL \ (AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_PM_RUNTIME |\ AZX_DCAPS_I915_COMPONENT) #define AZX_DCAPS_INTEL_SKYLAKE \ (AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_PM_RUNTIME |\ AZX_DCAPS_SEPARATE_STREAM_TAG | AZX_DCAPS_I915_COMPONENT) #define AZX_DCAPS_INTEL_BROXTON AZX_DCAPS_INTEL_SKYLAKE #define AZX_DCAPS_INTEL_LNL \ (AZX_DCAPS_INTEL_SKYLAKE | AZX_DCAPS_PIO_COMMANDS) #define AZX_DCAPS_INTEL_NVL \ (AZX_DCAPS_INTEL_LNL & ~AZX_DCAPS_NO_ALIGN_BUFSIZE) /* quirks for ATI SB / AMD Hudson */ #define AZX_DCAPS_PRESET_ATI_SB \ (AZX_DCAPS_NO_TCSEL | AZX_DCAPS_POSFIX_LPIB |\ AZX_DCAPS_SNOOP_TYPE(ATI)) /* quirks for ATI/AMD HDMI */ #define AZX_DCAPS_PRESET_ATI_HDMI \ (AZX_DCAPS_NO_TCSEL | AZX_DCAPS_POSFIX_LPIB|\ AZX_DCAPS_NO_MSI64) /* quirks for ATI HDMI with snoop off */ #define AZX_DCAPS_PRESET_ATI_HDMI_NS \ (AZX_DCAPS_PRESET_ATI_HDMI | AZX_DCAPS_SNOOP_OFF) /* quirks for AMD SB */ #define AZX_DCAPS_PRESET_AMD_SB \ (AZX_DCAPS_NO_TCSEL | AZX_DCAPS_AMD_WORKAROUND |\ AZX_DCAPS_SNOOP_TYPE(ATI) | AZX_DCAPS_PM_RUNTIME |\ AZX_DCAPS_RETRY_PROBE) /* quirks for Nvidia */ #define AZX_DCAPS_PRESET_NVIDIA \ (AZX_DCAPS_NO_MSI | AZX_DCAPS_CORBRP_SELF_CLEAR |\ AZX_DCAPS_SNOOP_TYPE(NVIDIA)) #define AZX_DCAPS_PRESET_CTHDA \ (AZX_DCAPS_NO_MSI | AZX_DCAPS_POSFIX_LPIB |\ AZX_DCAPS_NO_64BIT |\ AZX_DCAPS_4K_BDLE_BOUNDARY | AZX_DCAPS_SNOOP_OFF) /* * vga_switcheroo support */ #ifdef SUPPORT_VGA_SWITCHEROO #define use_vga_switcheroo(chip) ((chip)->use_vga_switcheroo) #define needs_eld_notify_link(chip) ((chip)->bus.keep_power) #else #define use_vga_switcheroo(chip) 0 #define needs_eld_notify_link(chip) false #endif static const char * const driver_short_names[] = { [AZX_DRIVER_ICH] = "HDA Intel", [AZX_DRIVER_PCH] = "HDA Intel PCH", [AZX_DRIVER_SCH] = "HDA Intel MID", [AZX_DRIVER_SKL] = "HDA Intel PCH", /* kept old name for compatibility */ [AZX_DRIVER_HDMI] = "HDA Intel HDMI", [AZX_DRIVER_ATI] = "HDA ATI SB", [AZX_DRIVER_ATIHDMI] = "HDA ATI HDMI", [AZX_DRIVER_ATIHDMI_NS] = "HDA ATI HDMI", [AZX_DRIVER_GFHDMI] = "HDA GF HDMI", [AZX_DRIVER_VIA] = "HDA VIA VT82xx", [AZX_DRIVER_SIS] = "HDA SIS966", [AZX_DRIVER_ULI] = "HDA ULI M5461", [AZX_DRIVER_NVIDIA] = "HDA NVidia", [AZX_DRIVER_TERA] = "HDA Teradici", [AZX_DRIVER_CTX] = "HDA Creative", [AZX_DRIVER_CTHDA] = "HDA Creative", [AZX_DRIVER_CMEDIA] = "HDA C-Media", [AZX_DRIVER_ZHAOXIN] = "HDA Zhaoxin", [AZX_DRIVER_ZHAOXINHDMI] = "HDA Zhaoxin HDMI", [AZX_DRIVER_LOONGSON] = "HDA Loongson", [AZX_DRIVER_HYGON] = "HDA Hygon", [AZX_DRIVER_GENERIC] = "HD-Audio Generic", }; static int azx_acquire_irq(struct azx *chip, int do_disconnect); static void set_default_power_save(struct azx *chip); /* * initialize the PCI registers */ /* update bits in a PCI register byte */ static void update_pci_byte(struct pci_dev *pci, unsigned int reg, unsigned char mask, unsigned char val) { unsigned char data; pci_read_config_byte(pci, reg, &data); data &= ~mask; data |= (val & mask); pci_write_config_byte(pci, reg, data); } static void azx_init_pci(struct azx *chip) { int snoop_type = azx_get_snoop_type(chip); /* Clear bits 0-2 of PCI register TCSEL (at offset 0x44) * TCSEL == Traffic Class Select Register, which sets PCI express QOS * Ensuring these bits are 0 clears playback static on some HD Audio * codecs. * The PCI register TCSEL is defined in the Intel manuals. */ if (!(chip->driver_caps & AZX_DCAPS_NO_TCSEL)) { dev_dbg(chip->card->dev, "Clearing TCSEL\n"); update_pci_byte(chip->pci, AZX_PCIREG_TCSEL, 0x07, 0); } /* For ATI SB450/600/700/800/900 and AMD Hudson azalia HD audio, * we need to enable snoop. */ if (snoop_type == AZX_SNOOP_TYPE_ATI) { dev_dbg(chip->card->dev, "Setting ATI snoop: %d\n", azx_snoop(chip)); update_pci_byte(chip->pci, ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, 0x07, azx_snoop(chip) ? ATI_SB450_HDAUDIO_ENABLE_SNOOP : 0); } /* For NVIDIA HDA, enable snoop */ if (snoop_type == AZX_SNOOP_TYPE_NVIDIA) { dev_dbg(chip->card->dev, "Setting Nvidia snoop: %d\n", azx_snoop(chip)); update_pci_byte(chip->pci, NVIDIA_HDA_TRANSREG_ADDR, 0x0f, NVIDIA_HDA_ENABLE_COHBITS); update_pci_byte(chip->pci, NVIDIA_HDA_ISTRM_COH, 0x01, NVIDIA_HDA_ENABLE_COHBIT); update_pci_byte(chip->pci, NVIDIA_HDA_OSTRM_COH, 0x01, NVIDIA_HDA_ENABLE_COHBIT); } /* Enable SCH/PCH snoop if needed */ if (snoop_type == AZX_SNOOP_TYPE_SCH) { unsigned short snoop; pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop); if ((!azx_snoop(chip) && !(snoop & INTEL_SCH_HDA_DEVC_NOSNOOP)) || (azx_snoop(chip) && (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP))) { snoop &= ~INTEL_SCH_HDA_DEVC_NOSNOOP; if (!azx_snoop(chip)) snoop |= INTEL_SCH_HDA_DEVC_NOSNOOP; pci_write_config_word(chip->pci, INTEL_SCH_HDA_DEVC, snoop); pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop); } dev_dbg(chip->card->dev, "SCH snoop: %s\n", (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) ? "Disabled" : "Enabled"); } } /* * In BXT-P A0, HD-Audio DMA requests is later than expected, * and makes an audio stream sensitive to system latencies when * 24/32 bits are playing. * Adjusting threshold of DMA fifo to force the DMA request * sooner to improve latency tolerance at the expense of power. */ static void bxt_reduce_dma_latency(struct azx *chip) { u32 val; val = azx_readl(chip, VS_EM4L); val &= (0x3 << 20); azx_writel(chip, VS_EM4L, val); } /* * ML_LCAP bits: * bit 0: 6 MHz Supported * bit 1: 12 MHz Supported * bit 2: 24 MHz Supported * bit 3: 48 MHz Supported * bit 4: 96 MHz Supported * bit 5: 192 MHz Supported */ static int intel_get_lctl_scf(struct azx *chip) { struct hdac_bus *bus = azx_bus(chip); static const int preferred_bits[] = { 2, 3, 1, 4, 5 }; u32 val, t; int i; val = readl(bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCAP); for (i = 0; i < ARRAY_SIZE(preferred_bits); i++) { t = preferred_bits[i]; if (val & (1 << t)) return t; } dev_warn(chip->card->dev, "set audio clock frequency to 6MHz"); return 0; } static int intel_ml_lctl_set_power(struct azx *chip, int state) { struct hdac_bus *bus = azx_bus(chip); u32 val; int timeout; /* * Changes to LCTL.SCF are only needed for the first multi-link dealing * with external codecs