2019-05-27 06:55:05 +00:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2005-04-16 22:20:36 +00:00
|
|
|
/*
|
|
|
|
*
|
2007-07-27 14:52:19 +00:00
|
|
|
* hda_intel.c - Implementation of primary alsa driver code base
|
|
|
|
* for Intel HD Audio.
|
2005-04-16 22:20:36 +00:00
|
|
|
*
|
|
|
|
* Copyright(c) 2004 Intel Corporation. All rights reserved.
|
|
|
|
*
|
|
|
|
* 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>
|
2005-11-07 13:43:23 +00:00
|
|
|
#include <linux/kernel.h>
|
2005-04-16 22:20:36 +00:00
|
|
|
#include <linux/module.h>
|
2008-03-04 09:08:58 +00:00
|
|
|
#include <linux/dma-mapping.h>
|
2005-04-16 22:20:36 +00:00
|
|
|
#include <linux/moduleparam.h>
|
|
|
|
#include <linux/init.h>
|
|
|
|
#include <linux/slab.h>
|
|
|
|
#include <linux/pci.h>
|
2006-01-16 15:34:20 +00:00
|
|
|
#include <linux/mutex.h>
|
2011-09-28 15:16:09 +00:00
|
|
|
#include <linux/io.h>
|
2012-08-23 09:32:30 +00:00
|
|
|
#include <linux/pm_runtime.h>
|
2012-10-22 21:42:16 +00:00
|
|
|
#include <linux/clocksource.h>
|
|
|
|
#include <linux/time.h>
|
2012-12-04 14:09:23 +00:00
|
|
|
#include <linux/completion.h>
|
2019-11-22 21:43:50 +00:00
|
|
|
#include <linux/acpi.h>
|
2020-06-09 04:32:42 +00:00
|
|
|
#include <linux/pgtable.h>
|
2012-10-22 21:42:16 +00:00
|
|
|
|
2011-09-28 15:16:09 +00:00
|
|
|
#ifdef CONFIG_X86
|
|
|
|
/* for snoop control */
|
2017-05-08 22:58:35 +00:00
|
|
|
#include <asm/set_memory.h>
|
2016-08-04 10:16:03 +00:00
|
|
|
#include <asm/cpufeature.h>
|
2011-09-28 15:16:09 +00:00
|
|
|
#endif
|
2005-04-16 22:20:36 +00:00
|
|
|
#include <sound/core.h>
|
|
|
|
#include <sound/initval.h>
|
2015-05-19 14:29:30 +00:00
|
|
|
#include <sound/hdaudio.h>
|
|
|
|
#include <sound/hda_i915.h>
|
2019-10-22 17:43:12 +00:00
|
|
|
#include <sound/intel-dsp-config.h>
|
2012-04-26 10:13:25 +00:00
|
|
|
#include <linux/vgaarb.h>
|
2012-04-26 10:23:42 +00:00
|
|
|
#include <linux/vga_switcheroo.h>
|
2012-08-09 10:33:28 +00:00
|
|
|
#include <linux/firmware.h>
|
2018-08-22 20:24:57 +00:00
|
|
|
#include <sound/hda_codec.h>
|
2014-02-28 23:41:22 +00:00
|
|
|
#include "hda_controller.h"
|
2015-01-08 15:54:15 +00:00
|
|
|
#include "hda_intel.h"
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2015-05-12 01:43:22 +00:00
|
|
|
#define CREATE_TRACE_POINTS
|
|
|
|
#include "hda_intel_trace.h"
|
|
|
|
|
2014-06-26 14:50:16 +00:00
|
|
|
/* position fix mode */
|
|
|
|
enum {
|
|
|
|
POS_FIX_AUTO,
|
|
|
|
POS_FIX_LPIB,
|
|
|
|
POS_FIX_POSBUF,
|
|
|
|
POS_FIX_VIACOMBO,
|
|
|
|
POS_FIX_COMBO,
|
2017-03-29 06:46:00 +00:00
|
|
|
POS_FIX_SKL,
|
ALSA: hda - Workaround for crackled sound on AMD controller (1022:1457)
A long-time problem on the recent AMD chip (X370, X470, B450, etc with
PCI ID 1022:1457) with Realtek codecs is the crackled or distorted
sound for capture streams, as well as occasional playback hiccups.
After lengthy debugging sessions, the workarounds we've found are like
the following:
- Set up the proper driver caps for this controller, similar as the
other AMD controller.
- Correct the DMA position reporting with the fixed FIFO size, which
is similar like as workaround used for VIA chip set.
- Even after the position correction, PulseAudio still shows
mysterious stalls of playback streams when a capture is triggered in
timer-scheduled mode. Since we have no clear way to eliminate the
stall, pass the BATCH PCM flag for PA to suppress the tsched mode as
a temporary workaround.
This patch implements the workarounds. For the driver caps, it
defines a new preset, AXZ_DCAPS_PRESET_AMD_SB. It enables the FIFO-
corrected position reporting (corresponding to the new position_fix=6)
and enforces the SNDRV_PCM_INFO_BATCH flag.
Note that the current implementation is merely a workaround.
Hopefully we'll find a better alternative in future, especially about
removing the BATCH flag hack again.
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=195303
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2019-08-06 15:31:48 +00:00
|
|
|
POS_FIX_FIFO,
|
2014-06-26 14:50:16 +00:00
|
|
|
};
|
|
|
|
|
2014-06-26 15:19:20 +00:00
|
|
|
/* 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 */
|
2016-01-29 12:39:09 +00:00
|
|
|
#define INTEL_HDA_CGCTL 0x48
|
|
|
|
#define INTEL_HDA_CGCTL_MISCBDCGE (0x1 << 6)
|
2014-06-26 15:19:20 +00:00
|
|
|
#define INTEL_SCH_HDA_DEVC 0x78
|
|
|
|
#define INTEL_SCH_HDA_DEVC_NOSNOOP (0x1<<11)
|
|
|
|
|
|
|
|
/* Define VIA HD Audio Device ID*/
|
|
|
|
#define VIA_HDAC_DEVICE_ID 0x3288
|
|
|
|
|
2014-06-26 15:28:06 +00:00
|
|
|
/* 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
|
|
|
|
|
|
|
|
/* TERA has 4 playback and 3 capture */
|
|
|
|
#define TERA_NUM_CAPTURE 3
|
|
|
|
#define TERA_NUM_PLAYBACK 4
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2008-01-07 14:16:37 +00:00
|
|
|
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
|
|
|
|
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
|
2011-12-15 03:19:36 +00:00
|
|
|
static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
|
2008-01-07 14:16:37 +00:00
|
|
|
static char *model[SNDRV_CARDS];
|
2012-09-13 12:59:47 +00:00
|
|
|
static int position_fix[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};
|
2008-06-10 15:53:35 +00:00
|
|
|
static int bdl_pos_adj[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};
|
2008-01-07 14:16:37 +00:00
|
|
|
static int probe_mask[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};
|
2008-12-19 14:19:11 +00:00
|
|
|
static int probe_only[SNDRV_CARDS];
|
2012-10-09 13:04:21 +00:00
|
|
|
static int jackpoll_ms[SNDRV_CARDS];
|
2017-01-12 16:13:21 +00:00
|
|
|
static int single_cmd = -1;
|
2009-09-28 11:14:04 +00:00
|
|
|
static int enable_msi = -1;
|
2009-06-17 07:52:54 +00:00
|
|
|
#ifdef CONFIG_SND_HDA_PATCH_LOADER
|
|
|
|
static char *patch[SNDRV_CARDS];
|
|
|
|
#endif
|
2009-11-13 17:41:52 +00:00
|
|
|
#ifdef CONFIG_SND_HDA_INPUT_BEEP
|
2012-07-03 14:58:48 +00:00
|
|
|
static bool beep_mode[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] =
|
2009-11-13 17:41:52 +00:00
|
|
|
CONFIG_SND_HDA_INPUT_BEEP_MODE};
|
|
|
|
#endif
|
2020-01-09 08:20:00 +00:00
|
|
|
static bool dmic_detect = 1;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2008-01-07 14:16:37 +00:00
|
|
|
module_param_array(index, int, NULL, 0444);
|
2005-04-16 22:20:36 +00:00
|
|
|
MODULE_PARM_DESC(index, "Index value for Intel HD audio interface.");
|
2008-01-07 14:16:37 +00:00
|
|
|
module_param_array(id, charp, NULL, 0444);
|
2005-04-16 22:20:36 +00:00
|
|
|
MODULE_PARM_DESC(id, "ID string for Intel HD audio interface.");
|
2008-01-07 14:16:37 +00:00
|
|
|
module_param_array(enable, bool, NULL, 0444);
|
|
|
|
MODULE_PARM_DESC(enable, "Enable Intel HD audio interface.");
|
|
|
|
module_param_array(model, charp, NULL, 0444);
|
2005-04-16 22:20:36 +00:00
|
|
|
MODULE_PARM_DESC(model, "Use the given board model.");
|
2008-01-07 14:16:37 +00:00
|
|
|
module_param_array(position_fix, int, NULL, 0444);
|
2010-09-30 08:12:50 +00:00
|
|
|
MODULE_PARM_DESC(position_fix, "DMA pointer read method."
|
ALSA: hda - Workaround for crackled sound on AMD controller (1022:1457)
A long-time problem on the recent AMD chip (X370, X470, B450, etc with
PCI ID 1022:1457) with Realtek codecs is the crackled or distorted
sound for capture streams, as well as occasional playback hiccups.
After lengthy debugging sessions, the workarounds we've found are like
the following:
- Set up the proper driver caps for this controller, similar as the
other AMD controller.
- Correct the DMA position reporting with the fixed FIFO size, which
is similar like as workaround used for VIA chip set.
- Even after the position correction, PulseAudio still shows
mysterious stalls of playback streams when a capture is triggered in
timer-scheduled mode. Since we have no clear way to eliminate the
stall, pass the BATCH PCM flag for PA to suppress the tsched mode as
a temporary workaround.
This patch implements the workarounds. For the driver caps, it
defines a new preset, AXZ_DCAPS_PRESET_AMD_SB. It enables the FIFO-
corrected position reporting (corresponding to the new position_fix=6)
and enforces the SNDRV_PCM_INFO_BATCH flag.
Note that the current implementation is merely a workaround.
Hopefully we'll find a better alternative in future, especially about
removing the BATCH flag hack again.
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=195303
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2019-08-06 15:31:48 +00:00
|
|
|
"(-1 = system default, 0 = auto, 1 = LPIB, 2 = POSBUF, 3 = VIACOMBO, 4 = COMBO, 5 = SKL+, 6 = FIFO).");
|
2008-06-10 15:53:34 +00:00
|
|
|
module_param_array(bdl_pos_adj, int, NULL, 0644);
|
|
|
|
MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset.");
|
2008-01-07 14:16:37 +00:00
|
|
|
module_param_array(probe_mask, int, NULL, 0444);
|
2005-11-24 15:03:40 +00:00
|
|
|
MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1).");
|
2010-03-26 10:16:59 +00:00
|
|
|
module_param_array(probe_only, int, NULL, 0444);
|
2008-12-19 14:19:11 +00:00
|
|
|
MODULE_PARM_DESC(probe_only, "Only probing and no codec initialization.");
|
2012-10-09 13:04:21 +00:00
|
|
|
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)");
|
2017-01-12 16:13:21 +00:00
|
|
|
module_param(single_cmd, bint, 0444);
|
2007-07-27 14:52:19 +00:00
|
|
|
MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs "
|
|
|
|
"(for debugging only).");
|
2012-01-20 11:08:44 +00:00
|
|
|
module_param(enable_msi, bint, 0444);
|
2006-11-10 11:08:37 +00:00
|
|
|
MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)");
|
2009-06-17 07:52:54 +00:00
|
|
|
#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
|
2009-11-13 17:41:52 +00:00
|
|
|
#ifdef CONFIG_SND_HDA_INPUT_BEEP
|
2012-07-03 14:58:48 +00:00
|
|
|
module_param_array(beep_mode, bool, NULL, 0444);
|
2009-11-13 17:41:52 +00:00
|
|
|
MODULE_PARM_DESC(beep_mode, "Select HDA Beep registration mode "
|
2012-07-03 14:58:48 +00:00
|
|
|
"(0=off, 1=on) (default=1).");
|
2009-11-13 17:41:52 +00:00
|
|
|
#endif
|
2020-01-09 08:20:00 +00:00
|
|
|
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");
|
2005-11-24 15:03:40 +00:00
|
|
|
|
2012-08-24 16:38:08 +00:00
|
|
|
#ifdef CONFIG_PM
|
2012-08-14 15:13:32 +00:00
|
|
|
static int param_set_xint(const char *val, const struct kernel_param *kp);
|
2015-05-27 01:39:38 +00:00
|
|
|
static const struct kernel_param_ops param_ops_xint = {
|
2012-08-14 15:13:32 +00:00
|
|
|
.set = param_set_xint,
|
|
|
|
.get = param_get_int,
|
|
|
|
};
|
|
|
|
#define param_check_xint param_check_int
|
|
|
|
|
2008-11-27 11:43:28 +00:00
|
|
|
static int power_save = CONFIG_SND_HDA_POWER_SAVE_DEFAULT;
|
2012-08-14 15:13:32 +00:00
|
|
|
module_param(power_save, xint, 0644);
|
2008-11-27 11:43:28 +00:00
|
|
|
MODULE_PARM_DESC(power_save, "Automatic power-saving timeout "
|
|
|
|
"(in second, 0 = disable).");
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2018-03-12 12:55:48 +00:00
|
|
|
static bool pm_blacklist = true;
|
|
|
|
module_param(pm_blacklist, bool, 0644);
|
2020-07-14 17:26:27 +00:00
|
|
|
MODULE_PARM_DESC(pm_blacklist, "Enable power-management denylist");
|
2018-03-12 12:55:48 +00:00
|
|
|
|
2007-08-13 14:10:30 +00:00
|
|
|
/* reset the HD-audio controller in power save mode.
|
|
|
|
* this may give more power-saving, but will take longer time to
|
|
|
|
* wake up.
|
|
|
|
*/
|
2013-04-04 13:35:24 +00:00
|
|
|
static bool power_save_controller = 1;
|
|
|
|
module_param(power_save_controller, bool, 0644);
|
2007-08-13 14:10:30 +00:00
|
|
|
MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode.");
|
2014-02-28 23:41:19 +00:00
|
|
|
#else
|
2015-02-20 08:26:04 +00:00
|
|
|
#define power_save 0
|
2012-08-24 16:38:08 +00:00
|
|
|
#endif /* CONFIG_PM */
|
2007-08-13 14:10:30 +00:00
|
|
|
|
2012-01-23 16:53:39 +00:00
|
|
|
static int align_buffer_size = -1;
|
|
|
|
module_param(align_buffer_size, bint, 0644);
|
2011-08-04 15:12:56 +00:00
|
|
|
MODULE_PARM_DESC(align_buffer_size,
|
|
|
|
"Force buffer and period sizes to be multiple of 128 bytes.");
|
|
|
|
|
2011-09-28 15:16:09 +00:00
|
|
|
#ifdef CONFIG_X86
|
2014-11-25 11:54:16 +00:00
|
|
|
static int hda_snoop = -1;
|
|
|
|
module_param_named(snoop, hda_snoop, bint, 0444);
|
2011-09-28 15:16:09 +00:00
|
|
|
MODULE_PARM_DESC(snoop, "Enable/disable snooping");
|
|
|
|
#else
|
|
|
|
#define hda_snoop true
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
MODULE_LICENSE("GPL");
|
|
|
|
MODULE_DESCRIPTION("Intel HDA driver");
|
|
|
|
|
2012-04-26 10:23:42 +00:00
|
|
|
#if defined(CONFIG_PM) && defined(CONFIG_VGA_SWITCHEROO)
|
2014-02-06 17:14:03 +00:00
|
|
|
#if IS_ENABLED(CONFIG_SND_HDA_CODEC_HDMI)
|
2012-04-26 10:23:42 +00:00
|
|
|
#define SUPPORT_VGA_SWITCHEROO
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
/*
|
|
|
|
*/
|
|
|
|
|
2005-08-24 12:14:57 +00:00
|
|
|
/* driver types */
|
|
|
|
enum {
|
|
|
|
AZX_DRIVER_ICH,
|
2010-02-23 01:31:09 +00:00
|
|
|
AZX_DRIVER_PCH,
|
2008-01-30 07:13:55 +00:00
|
|
|
AZX_DRIVER_SCH,
|
2017-06-14 05:26:00 +00:00
|
|
|
AZX_DRIVER_SKL,
|
2013-11-05 16:54:05 +00:00
|
|
|
AZX_DRIVER_HDMI,
|
2005-08-24 12:14:57 +00:00
|
|
|
AZX_DRIVER_ATI,
|
2006-05-17 09:22:21 +00:00
|
|
|
AZX_DRIVER_ATIHDMI,
|
2011-12-14 08:10:27 +00:00
|
|
|
AZX_DRIVER_ATIHDMI_NS,
|
2005-08-24 12:14:57 +00:00
|
|
|
AZX_DRIVER_VIA,
|
|
|
|
AZX_DRIVER_SIS,
|
|
|
|
AZX_DRIVER_ULI,
|
2005-09-13 16:49:12 +00:00
|
|
|
AZX_DRIVER_NVIDIA,
|
2008-05-27 09:44:55 +00:00
|
|
|
AZX_DRIVER_TERA,
|
2010-10-21 07:03:25 +00:00
|
|
|
AZX_DRIVER_CTX,
|
2012-05-08 08:34:08 +00:00
|
|
|
AZX_DRIVER_CTHDA,
|
2014-08-06 12:27:42 +00:00
|
|
|
AZX_DRIVER_CMEDIA,
|
2019-08-02 03:04:08 +00:00
|
|
|
AZX_DRIVER_ZHAOXIN,
|
2008-11-13 10:07:07 +00:00
|
|
|
AZX_DRIVER_GENERIC,
|
2008-09-03 14:00:44 +00:00
|
|
|
AZX_NUM_DRIVERS, /* keep this as last entry */
|
2005-08-24 12:14:57 +00:00
|
|
|
};
|
|
|
|
|
2014-11-25 10:28:07 +00:00
|
|
|
#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)
|
|
|
|
|
2014-12-03 08:47:20 +00:00
|
|
|
/* quirks for old Intel chipsets */
|
|
|
|
#define AZX_DCAPS_INTEL_ICH \
|
2020-06-18 14:40:51 +00:00
|
|
|
(AZX_DCAPS_OLD_SSYNC | AZX_DCAPS_NO_ALIGN_BUFSIZE)
|
2014-12-03 08:47:20 +00:00
|
|
|
|
2012-11-19 19:03:37 +00:00
|
|
|
/* quirks for Intel PCH */
|
2015-12-01 15:49:35 +00:00
|
|
|
#define AZX_DCAPS_INTEL_PCH_BASE \
|
2014-12-03 08:56:20 +00:00
|
|
|
(AZX_DCAPS_NO_ALIGN_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY |\
|
2020-06-18 14:40:51 +00:00
|
|
|
AZX_DCAPS_SNOOP_TYPE(SCH))
|
2013-01-08 12:51:30 +00:00
|
|
|
|
2017-06-29 14:18:12 +00:00
|
|
|
/* PCH up to IVB; no runtime PM; bind with i915 gfx */
|
2015-12-01 15:49:35 +00:00
|
|
|
#define AZX_DCAPS_INTEL_PCH_NOPM \
|
2017-06-29 14:18:12 +00:00
|
|
|
(AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_I915_COMPONENT)
|
2015-12-01 15:49:35 +00:00
|
|
|
|
2015-12-10 12:03:29 +00:00
|
|
|
/* PCH for HSW/BDW; with runtime PM */
|
2017-06-29 14:18:12 +00:00
|
|
|
/* no i915 binding for this as HSW/BDW has another controller for HDMI */
|
2013-01-08 12:51:30 +00:00
|
|
|
#define AZX_DCAPS_INTEL_PCH \
|
2020-10-27 13:00:37 +00:00
|
|
|
(AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_PM_RUNTIME)
|
2011-05-25 07:11:37 +00:00
|
|
|
|
2015-12-01 15:49:35 +00:00
|
|
|
/* HSW HDMI */
|
2013-11-05 16:34:46 +00:00
|
|
|
#define AZX_DCAPS_INTEL_HASWELL \
|
2014-12-03 08:56:20 +00:00
|
|
|
(/*AZX_DCAPS_ALIGN_BUFSIZE |*/ AZX_DCAPS_COUNT_LPIB_DELAY |\
|
2017-06-29 14:18:12 +00:00
|
|
|
AZX_DCAPS_PM_RUNTIME | AZX_DCAPS_I915_COMPONENT |\
|
2020-06-18 14:40:51 +00:00
|
|
|
AZX_DCAPS_SNOOP_TYPE(SCH))
|
2013-11-05 16:34:46 +00:00
|
|
|
|
2014-06-09 07:28:59 +00:00
|
|
|
/* Broadwell HDMI can't use position buffer reliably, force to use LPIB */
|
|
|
|
#define AZX_DCAPS_INTEL_BROADWELL \
|
2014-12-03 08:56:20 +00:00
|
|
|
(/*AZX_DCAPS_ALIGN_BUFSIZE |*/ AZX_DCAPS_POSFIX_LPIB |\
|
2017-06-29 14:18:12 +00:00
|
|
|
AZX_DCAPS_PM_RUNTIME | AZX_DCAPS_I915_COMPONENT |\
|
2020-06-18 14:40:51 +00:00
|
|
|
AZX_DCAPS_SNOOP_TYPE(SCH))
|
2014-06-09 07:28:59 +00:00
|
|
|
|
2015-04-21 05:12:23 +00:00
|
|
|
#define AZX_DCAPS_INTEL_BAYTRAIL \
|
2018-12-09 08:57:37 +00:00
|
|
|
(AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_I915_COMPONENT)
|
2015-04-21 05:12:23 +00:00
|
|
|
|
2015-04-07 12:32:20 +00:00
|
|
|
#define AZX_DCAPS_INTEL_BRASWELL \
|
2017-06-29 14:18:12 +00:00
|
|
|
(AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_PM_RUNTIME |\
|
2018-12-09 08:57:37 +00:00
|
|
|
AZX_DCAPS_I915_COMPONENT)
|
2015-04-07 12:32:20 +00:00
|
|
|
|
2014-12-19 00:44:31 +00:00
|
|
|
#define AZX_DCAPS_INTEL_SKYLAKE \
|
2017-06-29 14:18:12 +00:00
|
|
|
(AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_PM_RUNTIME |\
|
2018-12-09 08:57:37 +00:00
|
|
|
AZX_DCAPS_SEPARATE_STREAM_TAG | AZX_DCAPS_I915_COMPONENT)
|
2014-12-19 00:44:31 +00:00
|
|
|
|
2019-07-19 08:27:54 +00:00
|
|
|
#define AZX_DCAPS_INTEL_BROXTON AZX_DCAPS_INTEL_SKYLAKE
|
2015-11-19 15:25:12 +00:00
|
|
|
|
2011-05-25 07:11:37 +00:00
|
|
|
/* quirks for ATI SB / AMD Hudson */
|
|
|
|
#define AZX_DCAPS_PRESET_ATI_SB \
|
2020-06-18 14:40:51 +00:00
|
|
|
(AZX_DCAPS_NO_TCSEL | AZX_DCAPS_POSFIX_LPIB |\
|
2014-11-25 10:28:07 +00:00
|
|
|
AZX_DCAPS_SNOOP_TYPE(ATI))
|
2011-05-25 07:11:37 +00:00
|
|
|
|
|
|
|
/* quirks for ATI/AMD HDMI */
|
|
|
|
#define AZX_DCAPS_PRESET_ATI_HDMI \
|
2020-06-18 14:40:51 +00:00
|
|
|
(AZX_DCAPS_NO_TCSEL | AZX_DCAPS_POSFIX_LPIB|\
|
2014-11-24 03:17:08 +00:00
|
|
|
AZX_DCAPS_NO_MSI64)
|
2011-05-25 07:11:37 +00:00
|
|
|
|
2014-11-25 10:28:07 +00:00
|
|
|
/* quirks for ATI HDMI with snoop off */
|
|
|
|
#define AZX_DCAPS_PRESET_ATI_HDMI_NS \
|
|
|
|
(AZX_DCAPS_PRESET_ATI_HDMI | AZX_DCAPS_SNOOP_OFF)
|
|
|
|
|
ALSA: hda - Workaround for crackled sound on AMD controller (1022:1457)
A long-time problem on the recent AMD chip (X370, X470, B450, etc with
PCI ID 1022:1457) with Realtek codecs is the crackled or distorted
sound for capture streams, as well as occasional playback hiccups.
After lengthy debugging sessions, the workarounds we've found are like
the following:
- Set up the proper driver caps for this controller, similar as the
other AMD controller.
- Correct the DMA position reporting with the fixed FIFO size, which
is similar like as workaround used for VIA chip set.
- Even after the position correction, PulseAudio still shows
mysterious stalls of playback streams when a capture is triggered in
timer-scheduled mode. Since we have no clear way to eliminate the
stall, pass the BATCH PCM flag for PA to suppress the tsched mode as
a temporary workaround.
This patch implements the workarounds. For the driver caps, it
defines a new preset, AXZ_DCAPS_PRESET_AMD_SB. It enables the FIFO-
corrected position reporting (corresponding to the new position_fix=6)
and enforces the SNDRV_PCM_INFO_BATCH flag.
Note that the current implementation is merely a workaround.
Hopefully we'll find a better alternative in future, especially about
removing the BATCH flag hack again.
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=195303
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2019-08-06 15:31:48 +00:00
|
|
|
/* quirks for AMD SB */
|
|
|
|
#define AZX_DCAPS_PRESET_AMD_SB \
|
2020-06-18 14:40:51 +00:00
|
|
|
(AZX_DCAPS_NO_TCSEL | AZX_DCAPS_AMD_WORKAROUND |\
|
ALSA: hda: intel: Allow repeatedly probing on codec configuration errors
It seems that a few recent AMD systems show the codec configuration
errors at the early boot, while loading the driver at a later stage
works magically. Although the root cause of the error isn't clear,
it's certainly not bad to allow retrying the codec probe in such a
case if that helps.
This patch adds the capability for retrying the probe upon codec probe
errors on the certain AMD platforms. The probe_work is changed to a
delayed work, and at the secondary call, it'll jump to the codec
probing.
Note that, not only adding the re-probing, this includes the behavior
changes in the codec configuration function. Namely,
snd_hda_codec_configure() won't unregister the codec at errors any
longer. Instead, its caller, azx_codec_configure() unregisters the
codecs with the probe failures *if* any codec has been successfully
configured. If all codec probe failed, it doesn't unregister but let
it re-probed -- which is the most case we're seeing and this patch
tries to improve.
Even if the driver doesn't re-probe or give up, it will go to the
"free-all" error path, hence the leftover codecs shall be disabled /
deleted in anyway.
BugLink: https://bugzilla.suse.com/show_bug.cgi?id=1190801
Link: https://lore.kernel.org/r/20211006141940.2897-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2021-10-06 14:19:40 +00:00
|
|
|
AZX_DCAPS_SNOOP_TYPE(ATI) | AZX_DCAPS_PM_RUNTIME |\
|
|
|
|
AZX_DCAPS_RETRY_PROBE)
|
ALSA: hda - Workaround for crackled sound on AMD controller (1022:1457)
A long-time problem on the recent AMD chip (X370, X470, B450, etc with
PCI ID 1022:1457) with Realtek codecs is the crackled or distorted
sound for capture streams, as well as occasional playback hiccups.
After lengthy debugging sessions, the workarounds we've found are like
the following:
- Set up the proper driver caps for this controller, similar as the
other AMD controller.
- Correct the DMA position reporting with the fixed FIFO size, which
is similar like as workaround used for VIA chip set.
- Even after the position correction, PulseAudio still shows
mysterious stalls of playback streams when a capture is triggered in
timer-scheduled mode. Since we have no clear way to eliminate the
stall, pass the BATCH PCM flag for PA to suppress the tsched mode as
a temporary workaround.
This patch implements the workarounds. For the driver caps, it
defines a new preset, AXZ_DCAPS_PRESET_AMD_SB. It enables the FIFO-
corrected position reporting (corresponding to the new position_fix=6)
and enforces the SNDRV_PCM_INFO_BATCH flag.
Note that the current implementation is merely a workaround.
Hopefully we'll find a better alternative in future, especially about
removing the BATCH flag hack again.
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=195303
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2019-08-06 15:31:48 +00:00
|
|
|
|
2011-05-25 07:11:37 +00:00
|
|
|
/* quirks for Nvidia */
|
|
|
|
#define AZX_DCAPS_PRESET_NVIDIA \
|
2016-10-17 16:23:59 +00:00
|
|
|
(AZX_DCAPS_NO_MSI | AZX_DCAPS_CORBRP_SELF_CLEAR |\
|
2014-11-25 10:28:07 +00:00
|
|
|
AZX_DCAPS_SNOOP_TYPE(NVIDIA))
|
2011-05-25 07:11:37 +00:00
|
|
|
|
2012-05-08 08:34:08 +00:00
|
|
|
#define AZX_DCAPS_PRESET_CTHDA \
|
2014-11-25 10:28:07 +00:00
|
|
|
(AZX_DCAPS_NO_MSI | AZX_DCAPS_POSFIX_LPIB |\
|
2015-10-27 13:21:51 +00:00
|
|
|
AZX_DCAPS_NO_64BIT |\
|
2014-11-25 10:28:07 +00:00
|
|
|
AZX_DCAPS_4K_BDLE_BOUNDARY | AZX_DCAPS_SNOOP_OFF)
|
2012-05-08 08:34:08 +00:00
|
|
|
|
2012-04-26 10:23:42 +00:00
|
|
|
/*
|
2015-09-04 18:49:36 +00:00
|
|
|
* vga_switcheroo support
|
2012-04-26 10:23:42 +00:00
|
|
|
*/
|
|
|
|
#ifdef SUPPORT_VGA_SWITCHEROO
|
2012-08-09 11:49:23 +00:00
|
|
|
#define use_vga_switcheroo(chip) ((chip)->use_vga_switcheroo)
|
2019-08-27 14:37:50 +00:00
|
|
|
#define needs_eld_notify_link(chip) ((chip)->bus.keep_power)
|
2012-08-09 11:49:23 +00:00
|
|
|
#else
|
|
|
|
#define use_vga_switcheroo(chip) 0
|
ALSA: hda - Enable runtime PM only for discrete GPU
The recent change of vga_switcheroo allowed the runtime PM for
HD-audio on AMD GPUs, but this also resulted in a regression. When
the HD-audio controller driver gets runtime-suspended, HD-audio link
is turned off, and the hotplug notification is ignored. This leads to
the inconsistent audio state (the connection isn't notified and ELD is
ignored).
The best fix would be to implement the proper ELD notification via the
audio component, but it's still not ready. As a quick workaround,
this patch adds the check of runtime_idle and allows the runtime
suspend only when the vga_switcheroo is bound with discrete GPU.
That is, a system with a single GPU and APU would be again without
runtime PM to keep the HD-audio link for the hotplug notification and
ELD read out.
Also, the codec->auto_runtime_pm flag is set only for the discrete GPU
at the time GPU gets bound via vga_switcheroo (i.e. only dGPU is
forcibly runtime-PM enabled), so that APU can still get the ELD
notification.
For identifying which GPU is bound, a new vga_switcheroo client
callback, gpu_bound, is implemented. The vga_switcheroo simply calls
this when GPU is bound, and tells whether it's dGPU or APU.
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=200945
Fixes: 07f4f97d7b4b ("vga_switcheroo: Use device link for HDA controller")
Reported-by: Jian-Hong Pan <jian-hong@endlessm.com>
Tested-by: Jian-Hong Pan <jian-hong@endlessm.com>
Acked-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2018-09-10 14:20:25 +00:00
|
|
|
#define needs_eld_notify_link(chip) false
|
2012-08-09 11:49:23 +00:00
|
|
|
#endif
|
|
|
|
|
2015-06-03 01:30:15 +00:00
|
|
|
#define CONTROLLER_IN_GPU(pci) (((pci)->device == 0x0a0c) || \
|
|
|
|
((pci)->device == 0x0c0c) || \
|
|
|
|
((pci)->device == 0x0d0c) || \
|
2020-09-21 14:17:39 +00:00
|
|
|
((pci)->device == 0x160c) || \
|
2021-11-30 12:47:31 +00:00
|
|
|
((pci)->device == 0x490d) || \
|
|
|
|
((pci)->device == 0x4f90) || \
|
|
|
|
((pci)->device == 0x4f91) || \
|
|
|
|
((pci)->device == 0x4f92))
|
2015-06-03 01:30:15 +00:00
|
|
|
|
2016-02-22 14:18:13 +00:00
|
|
|
#define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98)
|
2015-12-07 07:59:13 +00:00
|
|
|
|
2020-01-05 14:47:24 +00:00
|
|
|
static const char * const driver_short_names[] = {
|
2005-08-24 12:14:57 +00:00
|
|
|
[AZX_DRIVER_ICH] = "HDA Intel",
|
2010-02-23 01:31:09 +00:00
|
|
|
[AZX_DRIVER_PCH] = "HDA Intel PCH",
|
2008-01-30 07:13:55 +00:00
|
|
|
[AZX_DRIVER_SCH] = "HDA Intel MID",
|
2017-06-14 05:26:00 +00:00
|
|
|
[AZX_DRIVER_SKL] = "HDA Intel PCH", /* kept old name for compatibility */
|
2013-11-05 16:54:05 +00:00
|
|
|
[AZX_DRIVER_HDMI] = "HDA Intel HDMI",
|
2005-08-24 12:14:57 +00:00
|
|
|
[AZX_DRIVER_ATI] = "HDA ATI SB",
|
2006-05-17 09:22:21 +00:00
|
|
|
[AZX_DRIVER_ATIHDMI] = "HDA ATI HDMI",
|
2011-12-14 08:10:27 +00:00
|
|
|
[AZX_DRIVER_ATIHDMI_NS] = "HDA ATI HDMI",
|
2005-08-24 12:14:57 +00:00
|
|
|
[AZX_DRIVER_VIA] = "HDA VIA VT82xx",
|
|
|
|
[AZX_DRIVER_SIS] = "HDA SIS966",
|
2005-09-13 16:49:12 +00:00
|
|
|
[AZX_DRIVER_ULI] = "HDA ULI M5461",
|
|
|
|
[AZX_DRIVER_NVIDIA] = "HDA NVidia",
|
2008-05-27 09:44:55 +00:00
|
|
|
[AZX_DRIVER_TERA] = "HDA Teradici",
|
2010-10-21 07:03:25 +00:00
|
|
|
[AZX_DRIVER_CTX] = "HDA Creative",
|
2012-05-08 08:34:08 +00:00
|
|
|
[AZX_DRIVER_CTHDA] = "HDA Creative",
|
2014-08-06 12:27:42 +00:00
|
|
|
[AZX_DRIVER_CMEDIA] = "HDA C-Media",
|
2019-08-02 03:04:08 +00:00
|
|
|
[AZX_DRIVER_ZHAOXIN] = "HDA Zhaoxin",
|
2008-11-13 10:07:07 +00:00
|
|
|
[AZX_DRIVER_GENERIC] = "HD-Audio Generic",
|
2005-08-24 12:14:57 +00:00
|
|
|
};
|
|
|
|
|
2006-10-23 11:40:59 +00:00
|
|
|
static int azx_acquire_irq(struct azx *chip, int do_disconnect);
|
ALSA: hda - Enable runtime PM only for discrete GPU
The recent change of vga_switcheroo allowed the runtime PM for
HD-audio on AMD GPUs, but this also resulted in a regression. When
the HD-audio controller driver gets runtime-suspended, HD-audio link
is turned off, and the hotplug notification is ignored. This leads to
the inconsistent audio state (the connection isn't notified and ELD is
ignored).
The best fix would be to implement the proper ELD notification via the
audio component, but it's still not ready. As a quick workaround,
this patch adds the check of runtime_idle and allows the runtime
suspend only when the vga_switcheroo is bound with discrete GPU.
That is, a system with a single GPU and APU would be again without
runtime PM to keep the HD-audio link for the hotplug notification and
ELD read out.
Also, the codec->auto_runtime_pm flag is set only for the discrete GPU
at the time GPU gets bound via vga_switcheroo (i.e. only dGPU is
forcibly runtime-PM enabled), so that APU can still get the ELD
notification.
For identifying which GPU is bound, a new vga_switcheroo client
callback, gpu_bound, is implemented. The vga_switcheroo simply calls
this when GPU is bound, and tells whether it's dGPU or APU.
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=200945
Fixes: 07f4f97d7b4b ("vga_switcheroo: Use device link for HDA controller")
Reported-by: Jian-Hong Pan <jian-hong@endlessm.com>
Tested-by: Jian-Hong Pan <jian-hong@endlessm.com>
Acked-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2018-09-10 14:20:25 +00:00
|
|
|
static void set_default_power_save(struct azx *chip);
|
2006-02-16 17:17:58 +00:00
|
|
|
|
2007-08-10 15:21:45 +00:00
|
|
|
/*
|
|
|
|
* 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)
|
|
|
|
{
|
2014-11-25 10:28:07 +00:00
|
|
|
int snoop_type = azx_get_snoop_type(chip);
|
|
|
|
|
2007-08-10 15:21:45 +00:00
|
|
|
/* 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
|
2011-03-10 16:41:56 +00:00
|
|
|
* codecs.
|
|
|
|
* The PCI register TCSEL is defined in the Intel manuals.
|
2007-08-10 15:21:45 +00:00
|
|
|
*/
|
2011-05-28 02:45:28 +00:00
|
|
|
if (!(chip->driver_caps & AZX_DCAPS_NO_TCSEL)) {
|
2014-02-25 11:21:03 +00:00
|
|
|
dev_dbg(chip->card->dev, "Clearing TCSEL\n");
|
2014-06-26 15:54:37 +00:00
|
|
|
update_pci_byte(chip->pci, AZX_PCIREG_TCSEL, 0x07, 0);
|
2011-05-25 07:11:37 +00:00
|
|
|
}
|
2007-08-10 15:21:45 +00:00
|
|
|
|
2011-05-25 07:11:37 +00:00
|
|
|
/* For ATI SB450/600/700/800/900 and AMD Hudson azalia HD audio,
|
|
|
|
* we need to enable snoop.
|
|
|
|
*/
|
2014-11-25 10:28:07 +00:00
|
|
|
if (snoop_type == AZX_SNOOP_TYPE_ATI) {
|
2014-02-25 11:21:03 +00:00
|
|
|
dev_dbg(chip->card->dev, "Setting ATI snoop: %d\n",
|
|
|
|
azx_snoop(chip));
|
2007-08-10 15:21:45 +00:00
|
|
|
update_pci_byte(chip->pci,
|
2011-09-28 15:16:09 +00:00
|
|
|
ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, 0x07,
|
|
|
|
azx_snoop(chip) ? ATI_SB450_HDAUDIO_ENABLE_SNOOP : 0);
|
2011-05-25 07:11:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* For NVIDIA HDA, enable snoop */
|
2014-11-25 10:28:07 +00:00
|
|
|
if (snoop_type == AZX_SNOOP_TYPE_NVIDIA) {
|
2014-02-25 11:21:03 +00:00
|
|
|
dev_dbg(chip->card->dev, "Setting Nvidia snoop: %d\n",
|
|
|
|
azx_snoop(chip));
|
2007-08-10 15:21:45 +00:00
|
|
|
update_pci_byte(chip->pci,
|
|
|
|
NVIDIA_HDA_TRANSREG_ADDR,
|
|
|
|
0x0f, NVIDIA_HDA_ENABLE_COHBITS);
|
2008-08-20 23:43:24 +00:00
|
|
|
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);
|
2011-05-25 07:11:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Enable SCH/PCH snoop if needed */
|
2014-11-25 10:28:07 +00:00
|
|
|
if (snoop_type == AZX_SNOOP_TYPE_SCH) {
|
2011-09-28 15:16:09 +00:00
|
|
|
unsigned short snoop;
|
2008-02-22 17:36:22 +00:00
|
|
|
pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop);
|
2011-09-28 15:16:09 +00:00
|
|
|
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);
|
2008-02-22 17:36:22 +00:00
|
|
|
pci_read_config_word(chip->pci,
|
|
|
|
INTEL_SCH_HDA_DEVC, &snoop);
|
|
|
|
}
|
2014-02-25 11:21:03 +00:00
|
|
|
dev_dbg(chip->card->dev, "SCH snoop: %s\n",
|
|
|
|
(snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) ?
|
|
|
|
"Disabled" : "Enabled");
|
2005-09-13 16:49:12 +00:00
|
|
|
}
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
2015-12-07 07:59:13 +00:00
|
|
|
/*
|
|
|
|
* 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;
|
|
|
|
|
2017-03-29 06:39:19 +00:00
|
|
|
val = azx_readl(chip, VS_EM4L);
|
2015-12-07 07:59:13 +00:00
|
|
|
val &= (0x3 << 20);
|
2017-03-29 06:39:19 +00:00
|
|
|
azx_writel(chip, VS_EM4L, val);
|
2015-12-07 07:59:13 +00:00
|
|
|
}
|
|
|
|
|
2017-04-06 11:18:21 +00:00
|
|
|
/*
|
|
|
|
* 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);
|
2020-01-05 14:47:24 +00:00
|
|
|
static const int preferred_bits[] = { 2, 3, 1, 4, 5 };
|
2017-04-06 11:18:21 +00:00
|
|
|
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;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* the codecs are sharing the first link setting by default
|
|
|
|
* If other links are enabled for stream, they need similar fix
|
|
|
|
*/
|
|
|
|
val = readl(bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCTL);
|
|
|
|
val &= ~AZX_MLCTL_SPA;
|
|
|
|
val |= state << AZX_MLCTL_SPA_SHIFT;
|
|
|
|
writel(val, bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCTL);
|
|
|
|
/* wait for CPA */
|
|
|
|
timeout = 50;
|
|
|
|
while (timeout) {
|
|
|
|
if (((readl(bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCTL)) &
|
|
|
|
AZX_MLCTL_CPA) == (state << AZX_MLCTL_CPA_SHIFT))
|
|
|
|
return 0;
|
|
|
|
timeout--;
|
|
|
|
udelay(10);
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void intel_init_lctl(struct azx *chip)
|
|
|
|
{
|
|
|
|
struct hdac_bus *bus = azx_bus(chip);
|
|
|
|
u32 val;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
/* 0. check lctl register value is correct or not */
|
|
|
|
val = readl(bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCTL);
|
|
|
|
/* if SCF is already set, let's use it */
|
|
|
|
if ((val & ML_LCTL_SCF_MASK) != 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Before operating on SPA, CPA must match SPA.
|
|
|
|
* Any deviation may result in undefined behavior.
|
|
|
|
*/
|
|
|
|
if (((val & AZX_MLCTL_SPA) >> AZX_MLCTL_SPA_SHIFT) !=
|
|
|
|
((val & AZX_MLCTL_CPA) >> AZX_MLCTL_CPA_SHIFT))
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* 1. turn link down: set SPA to 0 and wait CPA to 0 */
|
|
|
|
ret = intel_ml_lctl_set_power(chip, 0);
|
|
|
|
udelay(100);
|
|
|
|
if (ret)
|
|
|
|
goto set_spa;
|
|
|
|
|
|
|
|
/* 2. update SCF to select a properly audio clock*/
|
|
|
|
val &= ~ML_LCTL_SCF_MASK;
|
|
|
|
val |= intel_get_lctl_scf(chip);
|
|
|
|
writel(val, bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCTL);
|
|
|
|
|
|
|
|
set_spa:
|
|
|
|
/* 4. turn link up: set SPA to 1 and wait CPA to 1 */
|
|
|
|
intel_ml_lctl_set_power(chip, 1);
|
|
|
|
udelay(100);
|
|
|
|
}
|
|
|
|
|
2015-05-05 01:05:48 +00:00
|
|
|
static void hda_intel_init_chip(struct azx *chip, bool full_reset)
|
|
|
|
{
|
2015-05-19 14:29:30 +00:00
|
|
|
struct hdac_bus *bus = azx_bus(chip);
|
2015-12-07 07:59:13 +00:00
|
|
|
struct pci_dev *pci = chip->pci;
|
2016-01-29 12:39:09 +00:00
|
|
|
u32 val;
|
2015-05-05 01:05:48 +00:00
|
|
|
|
2018-12-09 08:57:37 +00:00
|
|
|
snd_hdac_set_codec_wakeup(bus, true);
|
2017-06-14 05:26:00 +00:00
|
|
|
if (chip->driver_type == AZX_DRIVER_SKL) {
|
2016-01-29 12:39:09 +00:00
|
|
|
pci_read_config_dword(pci, INTEL_HDA_CGCTL, &val);
|
|
|
|
val = val & ~INTEL_HDA_CGCTL_MISCBDCGE;
|
|
|
|
pci_write_config_dword(pci, INTEL_HDA_CGCTL, val);
|
|
|
|
}
|
2015-05-05 01:05:48 +00:00
|
|
|
azx_init_chip(chip, full_reset);
|
2017-06-14 05:26:00 +00:00
|
|
|
if (chip->driver_type == AZX_DRIVER_SKL) {
|
2016-01-29 12:39:09 +00:00
|
|
|
pci_read_config_dword(pci, INTEL_HDA_CGCTL, &val);
|
|
|
|
val = val | INTEL_HDA_CGCTL_MISCBDCGE;
|
|
|
|
pci_write_config_dword(pci, INTEL_HDA_CGCTL, val);
|
|
|
|
}
|
2018-12-09 08:57:37 +00:00
|
|
|
|
|
|
|
snd_hdac_set_codec_wakeup(bus, false);
|
2015-12-07 07:59:13 +00:00
|
|
|
|
|
|
|
/* reduce dma latency to avoid noise */
|
2016-02-22 14:18:13 +00:00
|
|
|
if (IS_BXT(pci))
|
2015-12-07 07:59:13 +00:00
|
|
|
bxt_reduce_dma_latency(chip);
|
2017-04-06 11:18:21 +00:00
|
|
|
|
|
|
|
if (bus->mlcap != NULL)
|
|
|
|
intel_init_lctl(chip);
|
2015-05-05 01:05:48 +00:00
|
|
|
}
|
|
|
|
|
2014-06-26 14:50:16 +00:00
|
|
|
/* calculate runtime delay from LPIB */
|
|
|
|
static int azx_get_delay_from_lpib(struct azx *chip, struct azx_dev *azx_dev,
|
|
|
|
unsigned int pos)
|
|
|
|
{
|
2015-04-14 16:13:13 +00:00
|
|
|
struct snd_pcm_substream *substream = azx_dev->core.substream;
|
2014-06-26 14:50:16 +00:00
|
|
|
int stream = substream->stream;
|
|
|
|
unsigned int lpib_pos = azx_get_pos_lpib(chip, azx_dev);
|
|
|
|
int delay;
|
|
|
|
|
|
|
|
if (stream == SNDRV_PCM_STREAM_PLAYBACK)
|
|
|
|
delay = pos - lpib_pos;
|
|
|
|
else
|
|
|
|
delay = lpib_pos - pos;
|
|
|
|
if (delay < 0) {
|
2015-04-14 16:13:13 +00:00
|
|
|
if (delay >= azx_dev->core.delay_negative_threshold)
|
2014-06-26 14:50:16 +00:00
|
|
|
delay = 0;
|
|
|
|
else
|
2015-04-14 16:13:13 +00:00
|
|
|
delay += azx_dev->core.bufsize;
|
2014-06-26 14:50:16 +00:00
|
|
|
}
|
|
|
|
|
2015-04-14 16:13:13 +00:00
|
|
|
if (delay >= azx_dev->core.period_bytes) {
|
2014-06-26 14:50:16 +00:00
|
|
|
dev_info(chip->card->dev,
|
|
|
|
"Unstable LPIB (%d >= %d); disabling LPIB delay counting\n",
|
2015-04-14 16:13:13 +00:00
|
|
|
delay, azx_dev->core.period_bytes);
|
2014-06-26 14:50:16 +00:00
|
|
|
delay = 0;
|
|
|
|
chip->driver_caps &= ~AZX_DCAPS_COUNT_LPIB_DELAY;
|
|
|
|
chip->get_delay[stream] = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return bytes_to_frames(substream->runtime, delay);
|
|
|
|
}
|
|
|
|
|
2008-05-16 10:34:47 +00:00
|
|
|
static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev);
|
|
|
|
|
2014-02-28 23:41:28 +00:00
|
|
|
/* called from IRQ */
|
|
|
|
static int azx_position_check(struct azx *chip, struct azx_dev *azx_dev)
|
|
|
|
{
|
2014-06-26 15:19:20 +00:00
|
|
|
struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
|
2014-02-28 23:41:28 +00:00
|
|
|
int ok;
|
|
|
|
|
|
|
|
ok = azx_position_ok(chip, azx_dev);
|
|
|
|
if (ok == 1) {
|
|
|
|
azx_dev->irq_pending = 0;
|
|
|
|
return ok;
|
2015-02-27 21:43:26 +00:00
|
|
|
} else if (ok == 0) {
|
2014-02-28 23:41:28 +00:00
|
|
|
/* bogus IRQ, process it later */
|
|
|
|
azx_dev->irq_pending = 1;
|
2015-02-27 21:43:26 +00:00
|
|
|
schedule_work(&hda->irq_pending_work);
|
2014-02-28 23:41:28 +00:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-12-08 16:31:49 +00:00
|
|
|
#define display_power(chip, enable) \
|
|
|
|
snd_hdac_display_power(azx_bus(chip), HDA_CODEC_IDX_CONTROLLER, enable)
|
2015-04-29 09:43:29 +00:00
|
|
|
|
2008-05-16 10:34:47 +00:00
|
|
|
/*
|
|
|
|
* Check whether the current DMA position is acceptable for updating
|
|
|
|
* periods. Returns non-zero if it's OK.
|
|
|
|
*
|
|
|
|
* Many HD-audio controllers appear pretty inaccurate about
|
|
|
|
* the update-IRQ timing. The IRQ is issued before actually the
|
|
|
|
* data is processed. So, we need to process it afterwords in a
|
|
|
|
* workqueue.
|
2021-09-29 07:29:33 +00:00
|
|
|
*
|
|
|
|
* Returns 1 if OK to proceed, 0 for delay handling, -1 for skipping update
|
2008-05-16 10:34:47 +00:00
|
|
|
*/
|
|
|
|
static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev)
|
|
|
|
{
|
2015-04-14 16:13:13 +00:00
|
|
|
struct snd_pcm_substream *substream = azx_dev->core.substream;
|
2021-09-29 07:29:33 +00:00
|
|
|
struct snd_pcm_runtime *runtime = substream->runtime;
|
2014-06-26 14:50:16 +00:00
|
|
|
int stream = substream->stream;
|
2010-05-11 08:21:46 +00:00
|
|
|
u32 wallclk;
|
2008-05-16 10:34:47 +00:00
|
|
|
unsigned int pos;
|
2021-09-29 07:29:33 +00:00
|
|
|
snd_pcm_uframes_t hwptr, target;
|
2008-05-16 10:34:47 +00:00
|
|
|
|
2015-04-14 16:13:13 +00:00
|
|
|
wallclk = azx_readl(chip, WALLCLK) - azx_dev->core.start_wallclk;
|
|
|
|
if (wallclk < (azx_dev->core.period_wallclk * 2) / 3)
|
2009-04-10 10:20:45 +00:00
|
|
|
return -1; /* bogus (too early) interrupt */
|
|
|
|
|
2014-06-26 14:50:16 +00:00
|
|
|
if (chip->get_position[stream])
|
|
|
|
pos = chip->get_position[stream](chip, azx_dev);
|
|
|
|
else { /* use the position buffer as default */
|
|
|
|
pos = azx_get_pos_posbuf(chip, azx_dev);
|
|
|
|
if (!pos || pos == (u32)-1) {
|
|
|
|
dev_info(chip->card->dev,
|
|
|
|
"Invalid position buffer, using LPIB read method instead.\n");
|
|
|
|
chip->get_position[stream] = azx_get_pos_lpib;
|
2015-04-14 20:06:53 +00:00
|
|
|
if (chip->get_position[0] == azx_get_pos_lpib &&
|
|
|
|
chip->get_position[1] == azx_get_pos_lpib)
|
|
|
|
azx_bus(chip)->use_posbuf = false;
|
2014-06-26 14:50:16 +00:00
|
|
|
pos = azx_get_pos_lpib(chip, azx_dev);
|
|
|
|
chip->get_delay[stream] = NULL;
|
|
|
|
} else {
|
|
|
|
chip->get_position[stream] = azx_get_pos_posbuf;
|
|
|
|
if (chip->driver_caps & AZX_DCAPS_COUNT_LPIB_DELAY)
|
|
|
|
chip->get_delay[stream] = azx_get_delay_from_lpib;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-14 16:13:13 +00:00
|
|
|
if (pos >= azx_dev->core.bufsize)
|
2014-06-26 14:50:16 +00:00
|
|
|
pos = 0;
|
2008-05-16 10:34:47 +00:00
|
|
|
|
2015-04-14 16:13:13 +00:00
|
|
|
if (WARN_ONCE(!azx_dev->core.period_bytes,
|
2010-02-12 17:17:06 +00:00
|
|
|
"hda-intel: zero azx_dev->period_bytes"))
|
2010-05-11 10:10:47 +00:00
|
|
|
return -1; /* this shouldn't happen! */
|
2015-04-14 16:13:13 +00:00
|
|
|
if (wallclk < (azx_dev->core.period_wallclk * 5) / 4 &&
|
|
|
|
pos % azx_dev->core.period_bytes > azx_dev->core.period_bytes / 2)
|
2010-05-11 10:10:47 +00:00
|
|
|
/* NG - it's below the first next period boundary */
|
2015-12-10 15:44:08 +00:00
|
|
|
return chip->bdl_pos_adj ? 0 : -1;
|
2015-04-14 16:13:13 +00:00
|
|
|
azx_dev->core.start_wallclk += wallclk;
|
2021-09-29 07:29:33 +00:00
|
|
|
|
|
|
|
if (azx_dev->core.no_period_wakeup)
|
|
|
|
return 1; /* OK, no need to check period boundary */
|
|
|
|
|
|
|
|
if (runtime->hw_ptr_base != runtime->hw_ptr_interrupt)
|
|
|
|
return 1; /* OK, already in hwptr updating process */
|
|
|
|
|
|
|
|
/* check whether the period gets really elapsed */
|
|
|
|
pos = bytes_to_frames(runtime, pos);
|
|
|
|
hwptr = runtime->hw_ptr_base + pos;
|
|
|
|
if (hwptr < runtime->status->hw_ptr)
|
|
|
|
hwptr += runtime->buffer_size;
|
|
|
|
target = runtime->hw_ptr_interrupt + runtime->period_size;
|
|
|
|
if (hwptr < target) {
|
|
|
|
/* too early wakeup, process it later */
|
|
|
|
return chip->bdl_pos_adj ? 0 : -1;
|
|
|
|
}
|
|
|
|
|
2008-05-16 10:34:47 +00:00
|
|
|
return 1; /* OK, it's fine */
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The work for pending PCM period updates.
|
|
|
|
*/
|
|
|
|
static void azx_irq_pending_work(struct work_struct *work)
|
|
|
|
{
|
2014-06-26 15:19:20 +00:00
|
|
|
struct hda_intel *hda = container_of(work, struct hda_intel, irq_pending_work);
|
|
|
|
struct azx *chip = &hda->chip;
|
2015-04-14 16:13:13 +00:00
|
|
|
struct hdac_bus *bus = azx_bus(chip);
|
|
|
|
struct hdac_stream *s;
|
|
|
|
int pending, ok;
|
2008-05-16 10:34:47 +00:00
|
|
|
|
2014-06-26 15:19:20 +00:00
|
|
|
if (!hda->irq_pending_warned) {
|
2014-02-25 11:21:03 +00:00
|
|
|
dev_info(chip->card->dev,
|
|
|
|
"IRQ timing workaround is activated for card #%d. Suggest a bigger bdl_pos_adj.\n",
|
|
|
|
chip->card->number);
|
2014-06-26 15:19:20 +00:00
|
|
|
hda->irq_pending_warned = 1;
|
2008-06-10 15:53:35 +00:00
|
|
|
}
|
|
|
|
|
2008-05-16 10:34:47 +00:00
|
|
|
for (;;) {
|
|
|
|
pending = 0;
|
2015-04-14 20:13:18 +00:00
|
|
|
spin_lock_irq(&bus->reg_lock);
|
2015-04-14 16:13:13 +00:00
|
|
|
list_for_each_entry(s, &bus->stream_list, list) {
|
|
|
|
struct azx_dev *azx_dev = stream_to_azx_dev(s);
|
2008-05-16 10:34:47 +00:00
|
|
|
if (!azx_dev->irq_pending ||
|
2015-04-14 16:13:13 +00:00
|
|
|
!s->substream ||
|
|
|
|
!s->running)
|
2008-05-16 10:34:47 +00:00
|
|
|
continue;
|
2010-05-11 08:21:46 +00:00
|
|
|
ok = azx_position_ok(chip, azx_dev);
|
|
|
|
if (ok > 0) {
|
2008-05-16 10:34:47 +00:00
|
|
|
azx_dev->irq_pending = 0;
|
2015-04-14 20:13:18 +00:00
|
|
|
spin_unlock(&bus->reg_lock);
|
2015-04-14 16:13:13 +00:00
|
|
|
snd_pcm_period_elapsed(s->substream);
|
2015-04-14 20:13:18 +00:00
|
|
|
spin_lock(&bus->reg_lock);
|
2010-05-11 08:21:46 +00:00
|
|
|
} else if (ok < 0) {
|
|
|
|
pending = 0; /* too early */
|
2008-05-16 10:34:47 +00:00
|
|
|
} else
|
|
|
|
pending++;
|
|
|
|
}
|
2015-04-14 20:13:18 +00:00
|
|
|
spin_unlock_irq(&bus->reg_lock);
|
2008-05-16 10:34:47 +00:00
|
|
|
if (!pending)
|
|
|
|
return;
|
2010-08-03 12:39:04 +00:00
|
|
|
msleep(1);
|
2008-05-16 10:34:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* clear irq_pending flags and assure no on-going workq */
|
|
|
|
static void azx_clear_irq_pending(struct azx *chip)
|
|
|
|
{
|
2015-04-14 16:13:13 +00:00
|
|
|
struct hdac_bus *bus = azx_bus(chip);
|
|
|
|
struct hdac_stream *s;
|
2008-05-16 10:34:47 +00:00
|
|
|
|
2015-04-14 20:13:18 +00:00
|
|
|
spin_lock_irq(&bus->reg_lock);
|
2015-04-14 16:13:13 +00:00
|
|
|
list_for_each_entry(s, &bus->stream_list, list) {
|
|
|
|
struct azx_dev *azx_dev = stream_to_azx_dev(s);
|
|
|
|
azx_dev->irq_pending = 0;
|
|
|
|
}
|
2015-04-14 20:13:18 +00:00
|
|
|
spin_unlock_irq(&bus->reg_lock);
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
2006-10-23 11:40:59 +00:00
|
|
|
static int azx_acquire_irq(struct azx *chip, int do_disconnect)
|
|
|
|
{
|
2015-04-14 20:13:18 +00:00
|
|
|
struct hdac_bus *bus = azx_bus(chip);
|
|
|
|
|
2006-11-21 11:14:23 +00:00
|
|
|
if (request_irq(chip->pci->irq, azx_interrupt,
|
|
|
|
chip->msi ? 0 : IRQF_SHARED,
|
2015-12-22 18:09:05 +00:00
|
|
|
chip->card->irq_descr, chip)) {
|
2014-02-25 11:21:03 +00:00
|
|
|
dev_err(chip->card->dev,
|
|
|
|
"unable to grab IRQ %d, disabling device\n",
|
|
|
|
chip->pci->irq);
|
2006-10-23 11:40:59 +00:00
|
|
|
if (do_disconnect)
|
|
|
|
snd_card_disconnect(chip->card);
|
|
|
|
return -1;
|
|
|
|
}
|
2015-04-14 20:13:18 +00:00
|
|
|
bus->irq = chip->pci->irq;
|
2019-12-10 06:34:20 +00:00
|
|
|
chip->card->sync_irq = bus->irq;
|
2006-11-21 11:10:55 +00:00
|
|
|
pci_intx(chip->pci, !chip->msi);
|
2006-10-23 11:40:59 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-06-26 14:50:16 +00:00
|
|
|
/* get the current DMA position with correction on VIA chips */
|
|
|
|
static unsigned int azx_via_get_position(struct azx *chip,
|
|
|
|
struct azx_dev *azx_dev)
|
|
|
|
{
|
|
|
|
unsigned int link_pos, mini_pos, bound_pos;
|
|
|
|
unsigned int mod_link_pos, mod_dma_pos, mod_mini_pos;
|
|
|
|
unsigned int fifo_size;
|
|
|
|
|
2015-04-16 10:14:17 +00:00
|
|
|
link_pos = snd_hdac_stream_get_pos_lpib(azx_stream(azx_dev));
|
2015-04-14 16:13:13 +00:00
|
|
|
if (azx_dev->core.substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
2014-06-26 14:50:16 +00:00
|
|
|
/* Playback, no problem using link position */
|
|
|
|
return link_pos;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Capture */
|
|
|
|
/* For new chipset,
|
|
|
|
* use mod to get the DMA position just like old chipset
|
|
|
|
*/
|
2015-04-14 16:13:13 +00:00
|
|
|
mod_dma_pos = le32_to_cpu(*azx_dev->core.posbuf);
|
|
|
|
mod_dma_pos %= azx_dev->core.period_bytes;
|
2014-06-26 14:50:16 +00:00
|
|
|
|
2019-08-12 16:01:47 +00:00
|
|
|
fifo_size = azx_stream(azx_dev)->fifo_size - 1;
|
2014-06-26 14:50:16 +00:00
|
|
|
|
|
|
|
if (azx_dev->insufficient) {
|
|
|
|
/* Link position never gather than FIFO size */
|
|
|
|
if (link_pos <= fifo_size)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
azx_dev->insufficient = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (link_pos <= fifo_size)
|
2015-04-14 16:13:13 +00:00
|
|
|
mini_pos = azx_dev->core.bufsize + link_pos - fifo_size;
|
2014-06-26 14:50:16 +00:00
|
|
|
else
|
|
|
|
mini_pos = link_pos - fifo_size;
|
|
|
|
|
|
|
|
/* Find nearest previous boudary */
|
2015-04-14 16:13:13 +00:00
|
|
|
mod_mini_pos = mini_pos % azx_dev->core.period_bytes;
|
|
|
|
mod_link_pos = link_pos % azx_dev->core.period_bytes;
|
2014-06-26 14:50:16 +00:00
|
|
|
if (mod_link_pos >= fifo_size)
|
|
|
|
bound_pos = link_pos - mod_link_pos;
|
|
|
|
else if (mod_dma_pos >= mod_mini_pos)
|
|
|
|
bound_pos = mini_pos - mod_mini_pos;
|
|
|
|
else {
|
2015-04-14 16:13:13 +00:00
|
|
|
bound_pos = mini_pos - mod_mini_pos + azx_dev->core.period_bytes;
|
|
|
|
if (bound_pos >= azx_dev->core.bufsize)
|
2014-06-26 14:50:16 +00:00
|
|
|
bound_pos = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Calculate real DMA position we want */
|
|
|
|
return bound_pos + mod_dma_pos;
|
|
|
|
}
|
|
|
|
|
ALSA: hda - Workaround for crackled sound on AMD controller (1022:1457)
A long-time problem on the recent AMD chip (X370, X470, B450, etc with
PCI ID 1022:1457) with Realtek codecs is the crackled or distorted
sound for capture streams, as well as occasional playback hiccups.
After lengthy debugging sessions, the workarounds we've found are like
the following:
- Set up the proper driver caps for this controller, similar as the
other AMD controller.
- Correct the DMA position reporting with the fixed FIFO size, which
is similar like as workaround used for VIA chip set.
- Even after the position correction, PulseAudio still shows
mysterious stalls of playback streams when a capture is triggered in
timer-scheduled mode. Since we have no clear way to eliminate the
stall, pass the BATCH PCM flag for PA to suppress the tsched mode as
a temporary workaround.
This patch implements the workarounds. For the driver caps, it
defines a new preset, AXZ_DCAPS_PRESET_AMD_SB. It enables the FIFO-
corrected position reporting (corresponding to the new position_fix=6)
and enforces the SNDRV_PCM_INFO_BATCH flag.
Note that the current implementation is merely a workaround.
Hopefully we'll find a better alternative in future, especially about
removing the BATCH flag hack again.
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=195303
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2019-08-06 15:31:48 +00:00
|
|
|
#define AMD_FIFO_SIZE 32
|
|
|
|
|
|
|
|
/* get the current DMA position with FIFO size correction */
|
|
|
|
static unsigned int azx_get_pos_fifo(struct azx *chip, struct azx_dev *azx_dev)
|
|
|
|
{
|
|
|
|
struct snd_pcm_substream *substream = azx_dev->core.substream;
|
|
|
|
struct snd_pcm_runtime *runtime = substream->runtime;
|
|
|
|
unsigned int pos, delay;
|
|
|
|
|
|
|
|
pos = snd_hdac_stream_get_pos_lpib(azx_stream(azx_dev));
|
|
|
|
if (!runtime)
|
|
|
|
return pos;
|
|
|
|
|
|
|
|
runtime->delay = AMD_FIFO_SIZE;
|
|
|
|
delay = frames_to_bytes(runtime, AMD_FIFO_SIZE);
|
|
|
|
if (azx_dev->insufficient) {
|
|
|
|
if (pos < delay) {
|
|
|
|
delay = pos;
|
|
|
|
runtime->delay = bytes_to_frames(runtime, pos);
|
|
|
|
} else {
|
|
|
|
azx_dev->insufficient = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* correct the DMA position for capture stream */
|
|
|
|
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
|
|
|
|
if (pos < delay)
|
|
|
|
pos += azx_dev->core.bufsize;
|
|
|
|
pos -= delay;
|
|
|
|
}
|
|
|
|
|
|
|
|
return pos;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int azx_get_delay_from_fifo(struct azx *chip, struct azx_dev *azx_dev,
|
|
|
|
unsigned int pos)
|
|
|
|
{
|
|
|
|
struct snd_pcm_substream *substream = azx_dev->core.substream;
|
|
|
|
|
|
|
|
/* just read back the calculated value in the above */
|
|
|
|
return substream->runtime->delay;
|
|
|
|
}
|
|
|
|
|
2021-09-13 12:43:30 +00:00
|
|
|
static void __azx_shutdown_chip(struct azx *chip, bool skip_link_reset)
|
2021-06-23 13:46:00 +00:00
|
|
|
{
|
|
|
|
azx_stop_chip(chip);
|
2021-09-13 12:43:30 +00:00
|
|
|
if (!skip_link_reset)
|
|
|
|
azx_enter_link_reset(chip);
|
2021-06-23 13:46:00 +00:00
|
|
|
azx_clear_irq_pending(chip);
|
|
|
|
display_power(chip, false);
|
|
|
|
}
|
|
|
|
|
2012-08-24 16:38:08 +00:00
|
|
|
#ifdef CONFIG_PM
|
2012-08-14 15:13:32 +00:00
|
|
|
static DEFINE_MUTEX(card_list_lock);
|
|
|
|
static LIST_HEAD(card_list);
|
|
|
|
|
2021-09-13 12:43:30 +00:00
|
|
|
static void azx_shutdown_chip(struct azx *chip)
|
|
|
|
{
|
|
|
|
__azx_shutdown_chip(chip, false);
|
|
|
|
}
|
|
|
|
|
2012-08-14 15:13:32 +00:00
|
|
|
static void azx_add_card_list(struct azx *chip)
|
|
|
|
{
|
2014-06-26 15:19:20 +00:00
|
|
|
struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
|
2012-08-14 15:13:32 +00:00
|
|
|
mutex_lock(&card_list_lock);
|
2014-06-26 15:19:20 +00:00
|
|
|
list_add(&hda->list, &card_list);
|
2012-08-14 15:13:32 +00:00
|
|
|
mutex_unlock(&card_list_lock);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void azx_del_card_list(struct azx *chip)
|
|
|
|
{
|
2014-06-26 15:19:20 +00:00
|
|
|
struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
|
2012-08-14 15:13:32 +00:00
|
|
|
mutex_lock(&card_list_lock);
|
2014-06-26 15:19:20 +00:00
|
|
|
list_del_init(&hda->list);
|
2012-08-14 15:13:32 +00:00
|
|
|
mutex_unlock(&card_list_lock);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* trigger power-save check at writing parameter */
|
|
|
|
static int param_set_xint(const char *val, const struct kernel_param *kp)
|
|
|
|
{
|
2014-06-26 15:19:20 +00:00
|
|
|
struct hda_intel *hda;
|
2012-08-14 15:13:32 +00:00
|
|
|
struct azx *chip;
|
|
|
|
int prev = power_save;
|
|
|
|
int ret = param_set_int(val, kp);
|
|
|
|
|
|
|
|
if (ret || prev == power_save)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
mutex_lock(&card_list_lock);
|
2014-06-26 15:19:20 +00:00
|
|
|
list_for_each_entry(hda, &card_list, list) {
|
|
|
|
chip = &hda->chip;
|
2015-04-14 20:13:18 +00:00
|
|
|
if (!hda->probe_continued || chip->disabled)
|
2012-08-14 15:13:32 +00:00
|
|
|
continue;
|
2015-04-14 20:13:18 +00:00
|
|
|
snd_hda_set_power_save(&chip->bus, power_save * 1000);
|
2012-08-14 15:13:32 +00:00
|
|
|
}
|
|
|
|
mutex_unlock(&card_list_lock);
|
|
|
|
return 0;
|
|
|
|
}
|
2008-12-11 10:47:17 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* power management
|
|
|
|
*/
|
2018-12-07 14:11:09 +00:00
|
|
|
static bool azx_is_pm_ready(struct snd_card *card)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
2014-07-16 14:31:04 +00:00
|
|
|
struct azx *chip;
|
|
|
|
struct hda_intel *hda;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2014-07-16 14:31:04 +00:00
|
|
|
if (!card)
|
2018-12-07 14:11:09 +00:00
|
|
|
return false;
|
2014-07-16 14:31:04 +00:00
|
|
|
chip = card->private_data;
|
|
|
|
hda = container_of(chip, struct hda_intel, chip);
|
2015-07-28 20:29:56 +00:00
|
|
|
if (chip->disabled || hda->init_failed || !chip->running)
|
2018-12-07 14:11:09 +00:00
|
|
|
return false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2020-10-27 13:00:37 +00:00
|
|
|
static void __azx_runtime_resume(struct azx *chip)
|
2018-12-07 14:11:09 +00:00
|
|
|
{
|
|
|
|
struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
|
|
|
|
struct hdac_bus *bus = azx_bus(chip);
|
|
|
|
struct hda_codec *codec;
|
|
|
|
int status;
|
|
|
|
|
2018-12-09 08:57:37 +00:00
|
|
|
display_power(chip, true);
|
|
|
|
if (hda->need_i915_power)
|
|
|
|
snd_hdac_i915_set_bclk(bus);
|
2018-12-07 14:11:09 +00:00
|
|
|
|
|
|
|
/* Read STATESTS before controller reset */
|
|
|
|
status = azx_readw(chip, STATESTS);
|
|
|
|
|
|
|
|
azx_init_pci(chip);
|
|
|
|
hda_intel_init_chip(chip, true);
|
|
|
|
|
2020-10-27 13:00:37 +00:00
|
|
|
/* Avoid codec resume if runtime resume is for system suspend */
|
|
|
|
if (!chip->pm_prepared) {
|
2020-10-12 10:27:04 +00:00
|
|
|
list_for_each_codec(codec, &chip->bus) {
|
|
|
|
if (codec->relaxed_resume)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (codec->forced_resume || (status & (1 << codec->addr)))
|
|
|
|
pm_request_resume(hda_codec_dev(codec));
|
|
|
|
}
|
2018-12-07 14:11:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* power down again for link-controlled chips */
|
2018-12-09 08:57:37 +00:00
|
|
|
if (!hda->need_i915_power)
|
2018-12-08 16:31:49 +00:00
|
|
|
display_power(chip, false);
|
2018-12-07 14:11:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef CONFIG_PM_SLEEP
|
2020-10-27 13:00:37 +00:00
|
|
|
static int azx_prepare(struct device *dev)
|
|
|
|
{
|
|
|
|
struct snd_card *card = dev_get_drvdata(dev);
|
|
|
|
struct azx *chip;
|
|
|
|
|
2021-03-29 11:30:59 +00:00
|
|
|
if (!azx_is_pm_ready(card))
|
|
|
|
return 0;
|
|
|
|
|
2020-10-27 13:00:37 +00:00
|
|
|
chip = card->private_data;
|
|
|
|
chip->pm_prepared = 1;
|
2021-03-29 11:30:58 +00:00
|
|
|
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
|
2020-10-27 13:00:37 +00:00
|
|
|
|
2021-03-10 11:28:07 +00:00
|
|
|
flush_work(&azx_bus(chip)->unsol_work);
|
|
|
|
|
2020-10-27 13:00:37 +00:00
|
|
|
/* HDA controller always requires different WAKEEN for runtime suspend
|
|
|
|
* and system suspend, so don't use direct-complete here.
|
|
|
|
*/
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void azx_complete(struct device *dev)
|
|
|
|
{
|
|
|
|
struct snd_card *card = dev_get_drvdata(dev);
|
|
|
|
struct azx *chip;
|
|
|
|
|
2021-03-29 11:30:59 +00:00
|
|
|
if (!azx_is_pm_ready(card))
|
|
|
|
return;
|
|
|
|
|
2020-10-27 13:00:37 +00:00
|
|
|
chip = card->private_data;
|
2021-03-29 11:30:58 +00:00
|
|
|
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
|
2020-10-27 13:00:37 +00:00
|
|
|
chip->pm_prepared = 0;
|
|
|
|
}
|
|
|
|
|
2018-12-07 14:11:09 +00:00
|
|
|
static int azx_suspend(struct device *dev)
|
|
|
|
{
|
|
|
|
struct snd_card *card = dev_get_drvdata(dev);
|
|
|
|
struct azx *chip;
|
|
|
|
struct hdac_bus *bus;
|
|
|
|
|
|
|
|
if (!azx_is_pm_ready(card))
|
2012-12-04 16:01:25 +00:00
|
|
|
return 0;
|
|
|
|
|
2018-12-07 14:11:09 +00:00
|
|
|
chip = card->private_data;
|
2015-04-14 20:13:18 +00:00
|
|
|
bus = azx_bus(chip);
|
2021-06-23 13:46:00 +00:00
|
|
|
azx_shutdown_chip(chip);
|
2015-04-14 20:13:18 +00:00
|
|
|
if (bus->irq >= 0) {
|
|
|
|
free_irq(bus->irq, chip);
|
|
|
|
bus->irq = -1;
|
2019-12-10 06:34:20 +00:00
|
|
|
chip->card->sync_irq = -1;
|
2006-10-11 16:52:53 +00:00
|
|
|
}
|
2014-06-26 10:45:16 +00:00
|
|
|
|
2006-10-23 11:40:59 +00:00
|
|
|
if (chip->msi)
|
2006-09-08 10:30:03 +00:00
|
|
|
pci_disable_msi(chip->pci);
|
2015-05-12 01:43:22 +00:00
|
|
|
|
|
|
|
trace_azx_suspend(chip);
|
2005-04-16 22:20:36 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-07-02 13:20:37 +00:00
|
|
|
static int azx_resume(struct device *dev)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
2012-07-02 13:20:37 +00:00
|
|
|
struct snd_card *card = dev_get_drvdata(dev);
|
2014-07-16 14:31:04 +00:00
|
|
|
struct azx *chip;
|
|
|
|
|
2018-12-07 14:11:09 +00:00
|
|
|
if (!azx_is_pm_ready(card))
|
2014-07-16 14:31:04 +00:00
|
|
|
return 0;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2014-07-16 14:31:04 +00:00
|
|
|
chip = card->private_data;
|
2006-10-23 11:40:59 +00:00
|
|
|
if (chip->msi)
|
2018-12-07 14:11:09 +00:00
|
|
|
if (pci_enable_msi(chip->pci) < 0)
|
2006-10-23 11:40:59 +00:00
|
|
|
chip->msi = 0;
|
|
|
|
if (azx_acquire_irq(chip, 1) < 0)
|
2006-10-11 16:52:53 +00:00
|
|
|
return -EIO;
|
ALSA: hda: Skip controller resume if not needed
The HD-audio controller does system-suspend and resume operations by
directly calling its helpers __azx_runtime_suspend() and
__azx_runtime_resume(). However, in general, we don't have to resume
always the device fully at the system resume; typically, if a device
has been runtime-suspended, we can leave it to runtime resume.
Usually for achieving this, the driver would call
pm_runtime_force_suspend() and pm_runtime_force_resume() pairs in the
system suspend and resume ops. Unfortunately, this doesn't work for
the resume path in our case. For handling the jack detection at the
system resume, a child codec device may need the (literally) forcibly
resume even if it's been runtime-suspended, and for that, the
controller device must be also resumed even if it's been suspended.
This patch is an attempt to improve the situation. It replaces the
direct __azx_runtime_suspend()/_resume() calls with with
pm_runtime_force_suspend() and pm_runtime_force_resume() with a slight
trick as we've done for the codec side. More exactly:
- azx_has_pm_runtime() check is dropped from azx_runtime_suspend() and
azx_runtime_resume(), so that it can be properly executed from the
system-suspend/resume path
- The WAKEEN handling depends on the card's power state now; it's set
and cleared only for the runtime-suspend
- azx_resume() checks whether any codec may need the forcible resume
beforehand. If the forcible resume is required, it does temporary
PM refcount up/down for actually triggering the runtime resume.
- A new helper function, hda_codec_need_resume(), is introduced for
checking whether the codec needs a forcible runtime-resume, and the
existing code is rewritten with that.
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=207043
Link: https://lore.kernel.org/r/20200413082034.25166-6-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2020-04-13 08:20:33 +00:00
|
|
|
|
2020-10-27 13:00:37 +00:00
|
|
|
__azx_runtime_resume(chip);
|
2015-05-12 01:43:22 +00:00
|
|
|
|
|
|
|
trace_azx_resume(chip);
|
2005-04-16 22:20:36 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2012-08-23 09:32:30 +00:00
|
|
|
|
2015-12-18 05:29:18 +00:00
|
|
|
/* put codec down to D3 at hibernation for Intel SKL+;
|
|
|
|
* otherwise BIOS may still access the codec and screw up the driver
|
|
|
|
*/
|
|
|
|
static int azx_freeze_noirq(struct device *dev)
|
|
|
|
{
|
2017-06-14 05:26:00 +00:00
|
|
|
struct snd_card *card = dev_get_drvdata(dev);
|
|
|
|
struct azx *chip = card->private_data;
|
2015-12-18 05:29:18 +00:00
|
|
|
struct pci_dev *pci = to_pci_dev(dev);
|
|
|
|
|
2020-04-13 08:20:30 +00:00
|
|
|
if (!azx_is_pm_ready(card))
|
|
|
|
return 0;
|
2017-06-14 05:26:00 +00:00
|
|
|
if (chip->driver_type == AZX_DRIVER_SKL)
|
2015-12-18 05:29:18 +00:00
|
|
|
pci_set_power_state(pci, PCI_D3hot);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int azx_thaw_noirq(struct device *dev)
|
|
|
|
{
|
2017-06-14 05:26:00 +00:00
|
|
|
struct snd_card *card = dev_get_drvdata(dev);
|
|
|
|
struct azx *chip = card->private_data;
|
2015-12-18 05:29:18 +00:00
|
|
|
struct pci_dev *pci = to_pci_dev(dev);
|
|
|
|
|
2020-04-13 08:20:30 +00:00
|
|
|
if (!azx_is_pm_ready(card))
|
|
|
|
return 0;
|
2017-06-14 05:26:00 +00:00
|
|
|
if (chip->driver_type == AZX_DRIVER_SKL)
|
2015-12-18 05:29:18 +00:00
|
|
|
pci_set_power_state(pci, PCI_D0);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif /* CONFIG_PM_SLEEP */
|
|
|
|
|
2012-08-23 09:32:30 +00:00
|
|
|
static int azx_runtime_suspend(struct device *dev)
|
|
|
|
{
|
|
|
|
struct snd_card *card = dev_get_drvdata(dev);
|
2014-07-16 14:31:04 +00:00
|
|
|
struct azx *chip;
|
2012-08-23 09:32:30 +00:00
|
|
|
|
2018-12-07 14:11:09 +00:00
|
|
|
if (!azx_is_pm_ready(card))
|
2014-07-16 14:31:04 +00:00
|
|
|
return 0;
|
|
|
|
chip = card->private_data;
|
2013-07-29 05:19:29 +00:00
|
|
|
|
2013-07-26 03:34:46 +00:00
|
|
|
/* enable controller wake up event */
|
2020-10-27 13:00:37 +00:00
|
|
|
azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) | STATESTS_INT_MASK);
|
2013-07-26 03:34:46 +00:00
|
|
|
|
2021-06-23 13:46:00 +00:00
|
|
|
azx_shutdown_chip(chip);
|
2015-05-12 01:43:22 +00:00
|
|
|
trace_azx_runtime_suspend(chip);
|
2012-08-23 09:32:30 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int azx_runtime_resume(struct device *dev)
|
|
|
|
{
|
|
|
|
struct snd_card *card = dev_get_drvdata(dev);
|
2014-07-16 14:31:04 +00:00
|
|
|
struct azx *chip;
|
2012-08-23 09:32:30 +00:00
|
|
|
|
2018-12-07 14:11:09 +00:00
|
|
|
if (!azx_is_pm_ready(card))
|
2014-07-16 14:31:04 +00:00
|
|
|
return 0;
|
|
|
|
chip = card->private_data;
|
2020-10-27 13:00:37 +00:00
|
|
|
__azx_runtime_resume(chip);
|
2013-07-26 03:34:46 +00:00
|
|
|
|
|
|
|
/* disable controller Wake Up event*/
|
2020-10-27 13:00:37 +00:00
|
|
|
azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) & ~STATESTS_INT_MASK);
|
2013-07-26 03:34:46 +00:00
|
|
|
|
2015-05-12 01:43:22 +00:00
|
|
|
trace_azx_runtime_resume(chip);
|
2012-08-23 09:32:30 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2012-12-12 10:50:12 +00:00
|
|
|
|
|
|
|
static int azx_runtime_idle(struct device *dev)
|
|
|
|
{
|
|
|
|
struct snd_card *card = dev_get_drvdata(dev);
|
2014-07-16 14:31:04 +00:00
|
|
|
struct azx *chip;
|
|
|
|
struct hda_intel *hda;
|
|
|
|
|
|
|
|
if (!card)
|
|
|
|
return 0;
|
2012-12-12 10:50:12 +00:00
|
|
|
|
2014-07-16 14:31:04 +00:00
|
|
|
chip = card->private_data;
|
|
|
|
hda = container_of(chip, struct hda_intel, chip);
|
2014-07-15 13:27:19 +00:00
|
|
|
if (chip->disabled || hda->init_failed)
|
2013-07-29 05:19:29 +00:00
|
|
|
return 0;
|
|
|
|
|
2015-02-19 16:35:32 +00:00
|
|
|
if (!power_save_controller || !azx_has_pm_runtime(chip) ||
|
2015-07-28 20:29:56 +00:00
|
|
|
azx_bus(chip)->codec_powered || !chip->running)
|
2012-12-12 10:50:12 +00:00
|
|
|
return -EBUSY;
|
|
|
|
|
ALSA: hda - Enable runtime PM only for discrete GPU
The recent change of vga_switcheroo allowed the runtime PM for
HD-audio on AMD GPUs, but this also resulted in a regression. When
the HD-audio controller driver gets runtime-suspended, HD-audio link
is turned off, and the hotplug notification is ignored. This leads to
the inconsistent audio state (the connection isn't notified and ELD is
ignored).
The best fix would be to implement the proper ELD notification via the
audio component, but it's still not ready. As a quick workaround,
this patch adds the check of runtime_idle and allows the runtime
suspend only when the vga_switcheroo is bound with discrete GPU.
That is, a system with a single GPU and APU would be again without
runtime PM to keep the HD-audio link for the hotplug notification and
ELD read out.
Also, the codec->auto_runtime_pm flag is set only for the discrete GPU
at the time GPU gets bound via vga_switcheroo (i.e. only dGPU is
forcibly runtime-PM enabled), so that APU can still get the ELD
notification.
For identifying which GPU is bound, a new vga_switcheroo client
callback, gpu_bound, is implemented. The vga_switcheroo simply calls
this when GPU is bound, and tells whether it's dGPU or APU.
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=200945
Fixes: 07f4f97d7b4b ("vga_switcheroo: Use device link for HDA controller")
Reported-by: Jian-Hong Pan <jian-hong@endlessm.com>
Tested-by: Jian-Hong Pan <jian-hong@endlessm.com>
Acked-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2018-09-10 14:20:25 +00:00
|
|
|
/* ELD notification gets broken when HD-audio bus is off */
|
2019-08-27 14:37:50 +00:00
|
|
|
if (needs_eld_notify_link(chip))
|
ALSA: hda - Enable runtime PM only for discrete GPU
The recent change of vga_switcheroo allowed the runtime PM for
HD-audio on AMD GPUs, but this also resulted in a regression. When
the HD-audio controller driver gets runtime-suspended, HD-audio link
is turned off, and the hotplug notification is ignored. This leads to
the inconsistent audio state (the connection isn't notified and ELD is
ignored).
The best fix would be to implement the proper ELD notification via the
audio component, but it's still not ready. As a quick workaround,
this patch adds the check of runtime_idle and allows the runtime
suspend only when the vga_switcheroo is bound with discrete GPU.
That is, a system with a single GPU and APU would be again without
runtime PM to keep the HD-audio link for the hotplug notification and
ELD read out.
Also, the codec->auto_runtime_pm flag is set only for the discrete GPU
at the time GPU gets bound via vga_switcheroo (i.e. only dGPU is
forcibly runtime-PM enabled), so that APU can still get the ELD
notification.
For identifying which GPU is bound, a new vga_switcheroo client
callback, gpu_bound, is implemented. The vga_switcheroo simply calls
this when GPU is bound, and tells whether it's dGPU or APU.
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=200945
Fixes: 07f4f97d7b4b ("vga_switcheroo: Use device link for HDA controller")
Reported-by: Jian-Hong Pan <jian-hong@endlessm.com>
Tested-by: Jian-Hong Pan <jian-hong@endlessm.com>
Acked-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2018-09-10 14:20:25 +00:00
|
|
|
return -EBUSY;
|
|
|
|
|
2012-12-12 10:50:12 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-08-23 09:32:30 +00:00
|
|
|
static const struct dev_pm_ops azx_pm = {
|
|
|
|
SET_SYSTEM_SLEEP_PM_OPS(azx_suspend, azx_resume)
|
2015-12-18 05:29:18 +00:00
|
|
|
#ifdef CONFIG_PM_SLEEP
|
2020-10-27 13:00:37 +00:00
|
|
|
.prepare = azx_prepare,
|
|
|
|
.complete = azx_complete,
|
2015-12-18 05:29:18 +00:00
|
|
|
.freeze_noirq = azx_freeze_noirq,
|
|
|
|
.thaw_noirq = azx_thaw_noirq,
|
|
|
|
#endif
|
2012-12-12 10:50:12 +00:00
|
|
|
SET_RUNTIME_PM_OPS(azx_runtime_suspend, azx_runtime_resume, azx_runtime_idle)
|
2012-08-23 09:32:30 +00:00
|
|
|
};
|
|
|
|
|
2012-07-02 13:20:37 +00:00
|
|
|
#define AZX_PM_OPS &azx_pm
|
|
|
|
#else
|
2018-12-07 14:11:09 +00:00
|
|
|
#define azx_add_card_list(chip) /* NOP */
|
|
|
|
#define azx_del_card_list(chip) /* NOP */
|
2012-07-02 13:20:37 +00:00
|
|
|
#define AZX_PM_OPS NULL
|
2012-08-23 09:32:30 +00:00
|
|
|
#endif /* CONFIG_PM */
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
|
2012-12-07 06:40:35 +00:00
|
|
|
static int azx_probe_continue(struct azx *chip);
|
2012-04-26 10:23:42 +00:00
|
|
|
|
2012-06-08 11:06:29 +00:00
|
|
|
#ifdef SUPPORT_VGA_SWITCHEROO
|
2012-12-06 17:35:10 +00:00
|
|
|
static struct pci_dev *get_bound_vga(struct pci_dev *pci);
|
2012-04-26 10:23:42 +00:00
|
|
|
|
|
|
|
static void azx_vs_set_state(struct pci_dev *pci,
|
|
|
|
enum vga_switcheroo_state state)
|
|
|
|
{
|
|
|
|
struct snd_card *card = pci_get_drvdata(pci);
|
|
|
|
struct azx *chip = card->private_data;
|
2014-06-26 15:19:20 +00:00
|
|
|
struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
|
vga_switcheroo: Use device link for HDA controller
Back in 2013, runtime PM for GPUs with integrated HDA controller was
introduced with commits 0d69704ae348 ("gpu/vga_switcheroo: add driver
control power feature. (v3)") and 246efa4a072f ("snd/hda: add runtime
suspend/resume on optimus support (v4)").
Briefly, the idea was that the HDA controller is forced on and off in
unison with the GPU.
The original code is mostly still in place even though it was never a
100% perfect solution: E.g. on access to the HDA controller, the GPU
is powered up via vga_switcheroo_runtime_resume_hdmi_audio() but there
are no provisions to keep it resumed until access to the HDA controller
has ceased: The GPU autosuspends after 5 seconds, rendering the HDA
controller inaccessible.
Additionally, a kludge is required when hda_intel.c probes: It has to
check whether the GPU is powered down (check_hdmi_disabled()) and defer
probing if so.
However in the meantime (in v4.10) the driver core has gained a feature
called device links which promises to solve such issues in a clean way:
It allows us to declare a dependency from the HDA controller (consumer)
to the GPU (supplier). The PM core then automagically ensures that the
GPU is runtime resumed as long as the HDA controller's ->probe hook is
executed and whenever the HDA controller is accessed.
By default, the HDA controller has a dependency on its parent, a PCIe
Root Port. Adding a device link creates another dependency on its
sibling:
PCIe Root Port
^ ^
| |
| |
HDA ===> GPU
The device link is not only used for runtime PM, it also guarantees that
on system sleep, the HDA controller suspends before the GPU and resumes
after the GPU, and on system shutdown the HDA controller's ->shutdown
hook is executed before the one of the GPU. It is a complete solution.
Using this functionality is as simple as calling device_link_add(),
which results in a dmesg entry like this:
pci 0000:01:00.1: Linked as a consumer to 0000:01:00.0
The code for the GPU-governed audio power management can thus be removed
(except where it's still needed for legacy manual power control).
The device link is added in a PCI quirk rather than in hda_intel.c.
It is therefore legal for the GPU to runtime suspend to D3cold even if
the HDA controller is not bound to a driver or if CONFIG_SND_HDA_INTEL
is not enabled, for accesses to the HDA controller will cause the GPU to
wake up regardless if they're occurring outside of hda_intel.c (think
config space readout via sysfs).
Contrary to the previous implementation, the HDA controller's power
state is now self-governed, rather than GPU-governed, whereas the GPU's
power state is no longer fully self-governed. (The HDA controller needs
to runtime suspend before the GPU can.)
It is thus crucial that runtime PM is always activated on the HDA
controller even if CONFIG_SND_HDA_POWER_SAVE_DEFAULT is set to 0 (which
is the default), lest the GPU stays awake. This is achieved by setting
the auto_runtime_pm flag on every codec and the AZX_DCAPS_PM_RUNTIME
flag on the HDA controller.
A side effect is that power consumption might be reduced if the GPU is
in use but the HDA controller is not, because the HDA controller is now
allowed to go to D3hot. Before, it was forced to stay in D0 as long as
the GPU was in use. (There is no reduction in power consumption on my
Nvidia GK107, but there might be on other chips.)
The code paths for legacy manual power control are adjusted such that
runtime PM is disabled during power off, thereby preventing the PM core
from resuming the HDA controller.
Note that the device link is not only added on vga_switcheroo capable
systems, but for *any* GPU with integrated HDA controller. The idea is
that the HDA controller streams audio via connectors located on the GPU,
so the GPU needs to be on for the HDA controller to do anything useful.
This commit implicitly fixes an unbalanced runtime PM ref upon unbind of
hda_intel.c: On ->probe, a runtime PM ref was previously released under
the condition "azx_has_pm_runtime(chip) || hda->use_vga_switcheroo", but
on ->remove a runtime PM ref was only acquired under the first of those
conditions. Thus, binding and unbinding the driver twice on a
vga_switcheroo capable system caused the runtime PM refcount to drop
below zero. The issue is resolved because the AZX_DCAPS_PM_RUNTIME flag
is now always set if use_vga_switcheroo is true.
For more information on device links please refer to:
https://www.kernel.org/doc/html/latest/driver-api/device_link.html
Documentation/driver-api/device_link.rst
Cc: Dave Airlie <airlied@redhat.com>
Cc: Ben Skeggs <bskeggs@redhat.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Takashi Iwai <tiwai@suse.de>
Reviewed-by: Peter Wu <peter@lekensteyn.nl>
Tested-by: Kai Heng Feng <kai.heng.feng@canonical.com> # AMD PowerXpress
Tested-by: Mike Lothian <mike@fireburn.co.uk> # AMD PowerXpress
Tested-by: Denis Lisov <dennis.lissov@gmail.com> # Nvidia Optimus
Tested-by: Peter Wu <peter@lekensteyn.nl> # Nvidia Optimus
Tested-by: Lukas Wunner <lukas@wunner.de> # MacBook Pro
Signed-off-by: Lukas Wunner <lukas@wunner.de>
Link: https://patchwork.freedesktop.org/patch/msgid/51bd38360ff502a8c42b1ebf4405ee1d3f27118d.1520068884.git.lukas@wunner.de
2018-03-03 09:53:24 +00:00
|
|
|
struct hda_codec *codec;
|
2012-04-26 10:23:42 +00:00
|
|
|
bool disabled;
|
|
|
|
|
2014-06-26 15:19:20 +00:00
|
|
|
wait_for_completion(&hda->probe_wait);
|
|
|
|
if (hda->init_failed)
|
2012-04-26 10:23:42 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
disabled = (state == VGA_SWITCHEROO_OFF);
|
|
|
|
if (chip->disabled == disabled)
|
|
|
|
return;
|
|
|
|
|
2015-04-14 20:13:18 +00:00
|
|
|
if (!hda->probe_continued) {
|
2012-04-26 10:23:42 +00:00
|
|
|
chip->disabled = disabled;
|
|
|
|
if (!disabled) {
|
2014-02-25 11:21:03 +00:00
|
|
|
dev_info(chip->card->dev,
|
|
|
|
"Start delayed initialization\n");
|
ALSA: hda: Release resources at error in delayed probe
snd-hda-intel driver handles the most of its probe task in the delayed
work (either via workqueue or via firmware loader). When an error
happens in the later delayed probe, we can't deregister the device
itself because the probe callback already returned success and the
device was bound. So, for now, we set hda->init_failed flag and make
the rest untouched until the device gets really unbound.
However, this leaves the device up running, keeping the resources
without any use that prevents other operations.
In this patch, we release the resources at first when a probe error
happens in the delayed probe stage, but keeps the top-level object, so
that the PM and other ops can still refer to the object itself.
Also for simplicity, snd_hda_intel object is allocated via devm, so
that we can get rid of the explicit kfree calls.
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=207043
Link: https://lore.kernel.org/r/20200413082034.25166-4-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2020-04-13 08:20:31 +00:00
|
|
|
if (azx_probe_continue(chip) < 0)
|
2014-02-25 11:21:03 +00:00
|
|
|
dev_err(chip->card->dev, "initialization error\n");
|
2012-04-26 10:23:42 +00:00
|
|
|
}
|
|
|
|
} else {
|
2015-09-04 18:49:36 +00:00
|
|
|
dev_info(chip->card->dev, "%s via vga_switcheroo\n",
|
2014-02-25 11:21:03 +00:00
|
|
|
disabled ? "Disabling" : "Enabling");
|
2012-04-26 10:23:42 +00:00
|
|
|
if (disabled) {
|
vga_switcheroo: Use device link for HDA controller
Back in 2013, runtime PM for GPUs with integrated HDA controller was
introduced with commits 0d69704ae348 ("gpu/vga_switcheroo: add driver
control power feature. (v3)") and 246efa4a072f ("snd/hda: add runtime
suspend/resume on optimus support (v4)").
Briefly, the idea was that the HDA controller is forced on and off in
unison with the GPU.
The original code is mostly still in place even though it was never a
100% perfect solution: E.g. on access to the HDA controller, the GPU
is powered up via vga_switcheroo_runtime_resume_hdmi_audio() but there
are no provisions to keep it resumed until access to the HDA controller
has ceased: The GPU autosuspends after 5 seconds, rendering the HDA
controller inaccessible.
Additionally, a kludge is required when hda_intel.c probes: It has to
check whether the GPU is powered down (check_hdmi_disabled()) and defer
probing if so.
However in the meantime (in v4.10) the driver core has gained a feature
called device links which promises to solve such issues in a clean way:
It allows us to declare a dependency from the HDA controller (consumer)
to the GPU (supplier). The PM core then automagically ensures that the
GPU is runtime resumed as long as the HDA controller's ->probe hook is
executed and whenever the HDA controller is accessed.
By default, the HDA controller has a dependency on its parent, a PCIe
Root Port. Adding a device link creates another dependency on its
sibling:
PCIe Root Port
^ ^
| |
| |
HDA ===> GPU
The device link is not only used for runtime PM, it also guarantees that
on system sleep, the HDA controller suspends before the GPU and resumes
after the GPU, and on system shutdown the HDA controller's ->shutdown
hook is executed before the one of the GPU. It is a complete solution.
Using this functionality is as simple as calling device_link_add(),
which results in a dmesg entry like this:
pci 0000:01:00.1: Linked as a consumer to 0000:01:00.0
The code for the GPU-governed audio power management can thus be removed
(except where it's still needed for legacy manual power control).
The device link is added in a PCI quirk rather than in hda_intel.c.
It is therefore legal for the GPU to runtime suspend to D3cold even if
the HDA controller is not bound to a driver or if CONFIG_SND_HDA_INTEL
is not enabled, for accesses to the HDA controller will cause the GPU to
wake up regardless if they're occurring outside of hda_intel.c (think
config space readout via sysfs).
Contrary to the previous implementation, the HDA controller's power
state is now self-governed, rather than GPU-governed, whereas the GPU's
power state is no longer fully self-governed. (The HDA controller needs
to runtime suspend before the GPU can.)
It is thus crucial that runtime PM is always activated on the HDA
controller even if CONFIG_SND_HDA_POWER_SAVE_DEFAULT is set to 0 (which
is the default), lest the GPU stays awake. This is achieved by setting
the auto_runtime_pm flag on every codec and the AZX_DCAPS_PM_RUNTIME
flag on the HDA controller.
A side effect is that power consumption might be reduced if the GPU is
in use but the HDA controller is not, because the HDA controller is now
allowed to go to D3hot. Before, it was forced to stay in D0 as long as
the GPU was in use. (There is no reduction in power consumption on my
Nvidia GK107, but there might be on other chips.)
The code paths for legacy manual power control are adjusted such that
runtime PM is disabled during power off, thereby preventing the PM core
from resuming the HDA controller.
Note that the device link is not only added on vga_switcheroo capable
systems, but for *any* GPU with integrated HDA controller. The idea is
that the HDA controller streams audio via connectors located on the GPU,
so the GPU needs to be on for the HDA controller to do anything useful.
This commit implicitly fixes an unbalanced runtime PM ref upon unbind of
hda_intel.c: On ->probe, a runtime PM ref was previously released under
the condition "azx_has_pm_runtime(chip) || hda->use_vga_switcheroo", but
on ->remove a runtime PM ref was only acquired under the first of those
conditions. Thus, binding and unbinding the driver twice on a
vga_switcheroo capable system caused the runtime PM refcount to drop
below zero. The issue is resolved because the AZX_DCAPS_PM_RUNTIME flag
is now always set if use_vga_switcheroo is true.
For more information on device links please refer to:
https://www.kernel.org/doc/html/latest/driver-api/device_link.html
Documentation/driver-api/device_link.rst
Cc: Dave Airlie <airlied@redhat.com>
Cc: Ben Skeggs <bskeggs@redhat.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Takashi Iwai <tiwai@suse.de>
Reviewed-by: Peter Wu <peter@lekensteyn.nl>
Tested-by: Kai Heng Feng <kai.heng.feng@canonical.com> # AMD PowerXpress
Tested-by: Mike Lothian <mike@fireburn.co.uk> # AMD PowerXpress
Tested-by: Denis Lisov <dennis.lissov@gmail.com> # Nvidia Optimus
Tested-by: Peter Wu <peter@lekensteyn.nl> # Nvidia Optimus
Tested-by: Lukas Wunner <lukas@wunner.de> # MacBook Pro
Signed-off-by: Lukas Wunner <lukas@wunner.de>
Link: https://patchwork.freedesktop.org/patch/msgid/51bd38360ff502a8c42b1ebf4405ee1d3f27118d.1520068884.git.lukas@wunner.de
2018-03-03 09:53:24 +00:00
|
|
|
list_for_each_codec(codec, &chip->bus) {
|
|
|
|
pm_runtime_suspend(hda_codec_dev(codec));
|
|
|
|
pm_runtime_disable(hda_codec_dev(codec));
|
|
|
|
}
|
|
|
|
pm_runtime_suspend(card->dev);
|
|
|
|
pm_runtime_disable(card->dev);
|
2015-09-04 18:49:36 +00:00
|
|
|
/* when we get suspended by vga_switcheroo we end up in D3cold,
|
2013-07-29 05:19:29 +00:00
|
|
|
* however we have no ACPI handle, so pci/acpi can't put us there,
|
|
|
|
* put ourselves there */
|
|
|
|
pci->current_state = PCI_D3cold;
|
2012-04-26 10:23:42 +00:00
|
|
|
chip->disabled = true;
|
2015-04-14 20:13:18 +00:00
|
|
|
if (snd_hda_lock_devices(&chip->bus))
|
2014-02-25 11:21:03 +00:00
|
|
|
dev_warn(chip->card->dev,
|
|
|
|
"Cannot lock devices!\n");
|
2012-04-26 10:23:42 +00:00
|
|
|
} else {
|
2015-04-14 20:13:18 +00:00
|
|
|
snd_hda_unlock_devices(&chip->bus);
|
2012-04-26 10:23:42 +00:00
|
|
|
chip->disabled = false;
|
vga_switcheroo: Use device link for HDA controller
Back in 2013, runtime PM for GPUs with integrated HDA controller was
introduced with commits 0d69704ae348 ("gpu/vga_switcheroo: add driver
control power feature. (v3)") and 246efa4a072f ("snd/hda: add runtime
suspend/resume on optimus support (v4)").
Briefly, the idea was that the HDA controller is forced on and off in
unison with the GPU.
The original code is mostly still in place even though it was never a
100% perfect solution: E.g. on access to the HDA controller, the GPU
is powered up via vga_switcheroo_runtime_resume_hdmi_audio() but there
are no provisions to keep it resumed until access to the HDA controller
has ceased: The GPU autosuspends after 5 seconds, rendering the HDA
controller inaccessible.
Additionally, a kludge is required when hda_intel.c probes: It has to
check whether the GPU is powered down (check_hdmi_disabled()) and defer
probing if so.
However in the meantime (in v4.10) the driver core has gained a feature
called device links which promises to solve such issues in a clean way:
It allows us to declare a dependency from the HDA controller (consumer)
to the GPU (supplier). The PM core then automagically ensures that the
GPU is runtime resumed as long as the HDA controller's ->probe hook is
executed and whenever the HDA controller is accessed.
By default, the HDA controller has a dependency on its parent, a PCIe
Root Port. Adding a device link creates another dependency on its
sibling:
PCIe Root Port
^ ^
| |
| |
HDA ===> GPU
The device link is not only used for runtime PM, it also guarantees that
on system sleep, the HDA controller suspends before the GPU and resumes
after the GPU, and on system shutdown the HDA controller's ->shutdown
hook is executed before the one of the GPU. It is a complete solution.
Using this functionality is as simple as calling device_link_add(),
which results in a dmesg entry like this:
pci 0000:01:00.1: Linked as a consumer to 0000:01:00.0
The code for the GPU-governed audio power management can thus be removed
(except where it's still needed for legacy manual power control).
The device link is added in a PCI quirk rather than in hda_intel.c.
It is therefore legal for the GPU to runtime suspend to D3cold even if
the HDA controller is not bound to a driver or if CONFIG_SND_HDA_INTEL
is not enabled, for accesses to the HDA controller will cause the GPU to
wake up regardless if they're occurring outside of hda_intel.c (think
config space readout via sysfs).
Contrary to the previous implementation, the HDA controller's power
state is now self-governed, rather than GPU-governed, whereas the GPU's
power state is no longer fully self-governed. (The HDA controller needs
to runtime suspend before the GPU can.)
It is thus crucial that runtime PM is always activated on the HDA
controller even if CONFIG_SND_HDA_POWER_SAVE_DEFAULT is set to 0 (which
is the default), lest the GPU stays awake. This is achieved by setting
the auto_runtime_pm flag on every codec and the AZX_DCAPS_PM_RUNTIME
flag on the HDA controller.
A side effect is that power consumption might be reduced if the GPU is
in use but the HDA controller is not, because the HDA controller is now
allowed to go to D3hot. Before, it was forced to stay in D0 as long as
the GPU was in use. (There is no reduction in power consumption on my
Nvidia GK107, but there might be on other chips.)
The code paths for legacy manual power control are adjusted such that
runtime PM is disabled during power off, thereby preventing the PM core
from resuming the HDA controller.
Note that the device link is not only added on vga_switcheroo capable
systems, but for *any* GPU with integrated HDA controller. The idea is
that the HDA controller streams audio via connectors located on the GPU,
so the GPU needs to be on for the HDA controller to do anything useful.
This commit implicitly fixes an unbalanced runtime PM ref upon unbind of
hda_intel.c: On ->probe, a runtime PM ref was previously released under
the condition "azx_has_pm_runtime(chip) || hda->use_vga_switcheroo", but
on ->remove a runtime PM ref was only acquired under the first of those
conditions. Thus, binding and unbinding the driver twice on a
vga_switcheroo capable system caused the runtime PM refcount to drop
below zero. The issue is resolved because the AZX_DCAPS_PM_RUNTIME flag
is now always set if use_vga_switcheroo is true.
For more information on device links please refer to:
https://www.kernel.org/doc/html/latest/driver-api/device_link.html
Documentation/driver-api/device_link.rst
Cc: Dave Airlie <airlied@redhat.com>
Cc: Ben Skeggs <bskeggs@redhat.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Takashi Iwai <tiwai@suse.de>
Reviewed-by: Peter Wu <peter@lekensteyn.nl>
Tested-by: Kai Heng Feng <kai.heng.feng@canonical.com> # AMD PowerXpress
Tested-by: Mike Lothian <mike@fireburn.co.uk> # AMD PowerXpress
Tested-by: Denis Lisov <dennis.lissov@gmail.com> # Nvidia Optimus
Tested-by: Peter Wu <peter@lekensteyn.nl> # Nvidia Optimus
Tested-by: Lukas Wunner <lukas@wunner.de> # MacBook Pro
Signed-off-by: Lukas Wunner <lukas@wunner.de>
Link: https://patchwork.freedesktop.org/patch/msgid/51bd38360ff502a8c42b1ebf4405ee1d3f27118d.1520068884.git.lukas@wunner.de
2018-03-03 09:53:24 +00:00
|
|
|
pm_runtime_enable(card->dev);
|
|
|
|
list_for_each_codec(codec, &chip->bus) {
|
|
|
|
pm_runtime_enable(hda_codec_dev(codec));
|
|
|
|
pm_runtime_resume(hda_codec_dev(codec));
|
|
|
|
}
|
2012-04-26 10:23:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool azx_vs_can_switch(struct pci_dev *pci)
|
|
|
|
{
|
|
|
|
struct snd_card *card = pci_get_drvdata(pci);
|
|
|
|
struct azx *chip = card->private_data;
|
2014-06-26 15:19:20 +00:00
|
|
|
struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
|
2012-04-26 10:23:42 +00:00
|
|
|
|
2014-06-26 15:19:20 +00:00
|
|
|
wait_for_completion(&hda->probe_wait);
|
|
|
|
if (hda->init_failed)
|
2012-04-26 10:23:42 +00:00
|
|
|
return false;
|
2015-04-14 20:13:18 +00:00
|
|
|
if (chip->disabled || !hda->probe_continued)
|
2012-04-26 10:23:42 +00:00
|
|
|
return true;
|
2015-04-14 20:13:18 +00:00
|
|
|
if (snd_hda_lock_devices(&chip->bus))
|
2012-04-26 10:23:42 +00:00
|
|
|
return false;
|
2015-04-14 20:13:18 +00:00
|
|
|
snd_hda_unlock_devices(&chip->bus);
|
2012-04-26 10:23:42 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
ALSA: hda - Enable runtime PM only for discrete GPU
The recent change of vga_switcheroo allowed the runtime PM for
HD-audio on AMD GPUs, but this also resulted in a regression. When
the HD-audio controller driver gets runtime-suspended, HD-audio link
is turned off, and the hotplug notification is ignored. This leads to
the inconsistent audio state (the connection isn't notified and ELD is
ignored).
The best fix would be to implement the proper ELD notification via the
audio component, but it's still not ready. As a quick workaround,
this patch adds the check of runtime_idle and allows the runtime
suspend only when the vga_switcheroo is bound with discrete GPU.
That is, a system with a single GPU and APU would be again without
runtime PM to keep the HD-audio link for the hotplug notification and
ELD read out.
Also, the codec->auto_runtime_pm flag is set only for the discrete GPU
at the time GPU gets bound via vga_switcheroo (i.e. only dGPU is
forcibly runtime-PM enabled), so that APU can still get the ELD
notification.
For identifying which GPU is bound, a new vga_switcheroo client
callback, gpu_bound, is implemented. The vga_switcheroo simply calls
this when GPU is bound, and tells whether it's dGPU or APU.
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=200945
Fixes: 07f4f97d7b4b ("vga_switcheroo: Use device link for HDA controller")
Reported-by: Jian-Hong Pan <jian-hong@endlessm.com>
Tested-by: Jian-Hong Pan <jian-hong@endlessm.com>
Acked-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2018-09-10 14:20:25 +00:00
|
|
|
/*
|
|
|
|
* The discrete GPU cannot power down unless the HDA controller runtime
|
|
|
|
* suspends, so activate runtime PM on codecs even if power_save == 0.
|
|
|
|
*/
|
|
|
|
static void setup_vga_switcheroo_runtime_pm(struct azx *chip)
|
|
|
|
{
|
|
|
|
struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
|
|
|
|
struct hda_codec *codec;
|
|
|
|
|
2019-08-27 14:37:50 +00:00
|
|
|
if (hda->use_vga_switcheroo && !needs_eld_notify_link(chip)) {
|
ALSA: hda - Enable runtime PM only for discrete GPU
The recent change of vga_switcheroo allowed the runtime PM for
HD-audio on AMD GPUs, but this also resulted in a regression. When
the HD-audio controller driver gets runtime-suspended, HD-audio link
is turned off, and the hotplug notification is ignored. This leads to
the inconsistent audio state (the connection isn't notified and ELD is
ignored).
The best fix would be to implement the proper ELD notification via the
audio component, but it's still not ready. As a quick workaround,
this patch adds the check of runtime_idle and allows the runtime
suspend only when the vga_switcheroo is bound with discrete GPU.
That is, a system with a single GPU and APU would be again without
runtime PM to keep the HD-audio link for the hotplug notification and
ELD read out.
Also, the codec->auto_runtime_pm flag is set only for the discrete GPU
at the time GPU gets bound via vga_switcheroo (i.e. only dGPU is
forcibly runtime-PM enabled), so that APU can still get the ELD
notification.
For identifying which GPU is bound, a new vga_switcheroo client
callback, gpu_bound, is implemented. The vga_switcheroo simply calls
this when GPU is bound, and tells whether it's dGPU or APU.
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=200945
Fixes: 07f4f97d7b4b ("vga_switcheroo: Use device link for HDA controller")
Reported-by: Jian-Hong Pan <jian-hong@endlessm.com>
Tested-by: Jian-Hong Pan <jian-hong@endlessm.com>
Acked-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2018-09-10 14:20:25 +00:00
|
|
|
list_for_each_codec(codec, &chip->bus)
|
|
|
|
codec->auto_runtime_pm = 1;
|
|
|
|
/* reset the power save setup */
|
|
|
|
if (chip->running)
|
|
|
|
set_default_power_save(chip);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void azx_vs_gpu_bound(struct pci_dev *pci,
|
|
|
|
enum vga_switcheroo_client_id client_id)
|
|
|
|
{
|
|
|
|
struct snd_card *card = pci_get_drvdata(pci);
|
|
|
|
struct azx *chip = card->private_data;
|
|
|
|
|
|
|
|
if (client_id == VGA_SWITCHEROO_DIS)
|
2019-08-27 14:37:50 +00:00
|
|
|
chip->bus.keep_power = 0;
|
ALSA: hda - Enable runtime PM only for discrete GPU
The recent change of vga_switcheroo allowed the runtime PM for
HD-audio on AMD GPUs, but this also resulted in a regression. When
the HD-audio controller driver gets runtime-suspended, HD-audio link
is turned off, and the hotplug notification is ignored. This leads to
the inconsistent audio state (the connection isn't notified and ELD is
ignored).
The best fix would be to implement the proper ELD notification via the
audio component, but it's still not ready. As a quick workaround,
this patch adds the check of runtime_idle and allows the runtime
suspend only when the vga_switcheroo is bound with discrete GPU.
That is, a system with a single GPU and APU would be again without
runtime PM to keep the HD-audio link for the hotplug notification and
ELD read out.
Also, the codec->auto_runtime_pm flag is set only for the discrete GPU
at the time GPU gets bound via vga_switcheroo (i.e. only dGPU is
forcibly runtime-PM enabled), so that APU can still get the ELD
notification.
For identifying which GPU is bound, a new vga_switcheroo client
callback, gpu_bound, is implemented. The vga_switcheroo simply calls
this when GPU is bound, and tells whether it's dGPU or APU.
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=200945
Fixes: 07f4f97d7b4b ("vga_switcheroo: Use device link for HDA controller")
Reported-by: Jian-Hong Pan <jian-hong@endlessm.com>
Tested-by: Jian-Hong Pan <jian-hong@endlessm.com>
Acked-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2018-09-10 14:20:25 +00:00
|
|
|
setup_vga_switcheroo_runtime_pm(chip);
|
|
|
|
}
|
|
|
|
|
2012-12-06 17:35:10 +00:00
|
|
|
static void init_vga_switcheroo(struct azx *chip)
|
2012-04-26 10:23:42 +00:00
|
|
|
{
|
2014-06-26 15:19:20 +00:00
|
|
|
struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
|
2012-04-26 10:23:42 +00:00
|
|
|
struct pci_dev *p = get_bound_vga(chip->pci);
|
ALSA: hda: Allow HDA to be runtime suspended when dGPU is not bound to a driver
Nvidia proprietary driver doesn't support runtime power management, so
when a user only wants to use the integrated GPU, it's a common practice
to let dGPU not to bind any driver, and let its upstream port to be
runtime suspended. At the end of runtime suspension the port uses
platform power management to disable power through _OFF method of power
resource, which is listed by _PR3.
After commit b516ea586d71 ("PCI: Enable NVIDIA HDA controllers"), when
the dGPU comes with an HDA function, the HDA won't be suspended if the
dGPU is unbound, so the power resource can't be turned off by its
upstream port driver.
Commit 37a3a98ef601 ("ALSA: hda - Enable runtime PM only for
discrete GPU") only allows HDA to be runtime suspended once GPU is
bound, to keep APU's HDA working.
However, HDA on dGPU isn't that useful if dGPU is not bound to any
driver. So let's relax the runtime suspend requirement for dGPU's HDA
function, to disable the power source to save lots of power.
BugLink: https://bugs.launchpad.net/bugs/1840835
Fixes: b516ea586d71 ("PCI: Enable NVIDIA HDA controllers")
Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
Link: https://lore.kernel.org/r/20191018073848.14590-2-kai.heng.feng@canonical.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2019-10-18 07:38:48 +00:00
|
|
|
struct pci_dev *parent;
|
2012-04-26 10:23:42 +00:00
|
|
|
if (p) {
|
2014-02-25 11:21:03 +00:00
|
|
|
dev_info(chip->card->dev,
|
2015-09-04 18:49:36 +00:00
|
|
|
"Handle vga_switcheroo audio client\n");
|
2014-06-26 15:19:20 +00:00
|
|
|
hda->use_vga_switcheroo = 1;
|
ALSA: hda: Allow HDA to be runtime suspended when dGPU is not bound to a driver
Nvidia proprietary driver doesn't support runtime power management, so
when a user only wants to use the integrated GPU, it's a common practice
to let dGPU not to bind any driver, and let its upstream port to be
runtime suspended. At the end of runtime suspension the port uses
platform power management to disable power through _OFF method of power
resource, which is listed by _PR3.
After commit b516ea586d71 ("PCI: Enable NVIDIA HDA controllers"), when
the dGPU comes with an HDA function, the HDA won't be suspended if the
dGPU is unbound, so the power resource can't be turned off by its
upstream port driver.
Commit 37a3a98ef601 ("ALSA: hda - Enable runtime PM only for
discrete GPU") only allows HDA to be runtime suspended once GPU is
bound, to keep APU's HDA working.
However, HDA on dGPU isn't that useful if dGPU is not bound to any
driver. So let's relax the runtime suspend requirement for dGPU's HDA
function, to disable the power source to save lots of power.
BugLink: https://bugs.launchpad.net/bugs/1840835
Fixes: b516ea586d71 ("PCI: Enable NVIDIA HDA controllers")
Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
Link: https://lore.kernel.org/r/20191018073848.14590-2-kai.heng.feng@canonical.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2019-10-18 07:38:48 +00:00
|
|
|
|
|
|
|
/* cleared in either gpu_bound op or codec probe, or when its
|
|
|
|
* upstream port has _PR3 (i.e. dGPU).
|
|
|
|
*/
|
|
|
|
parent = pci_upstream_bridge(p);
|
|
|
|
chip->bus.keep_power = parent ? !pci_pr3_present(parent) : 1;
|
vga_switcheroo: Use device link for HDA controller
Back in 2013, runtime PM for GPUs with integrated HDA controller was
introduced with commits 0d69704ae348 ("gpu/vga_switcheroo: add driver
control power feature. (v3)") and 246efa4a072f ("snd/hda: add runtime
suspend/resume on optimus support (v4)").
Briefly, the idea was that the HDA controller is forced on and off in
unison with the GPU.
The original code is mostly still in place even though it was never a
100% perfect solution: E.g. on access to the HDA controller, the GPU
is powered up via vga_switcheroo_runtime_resume_hdmi_audio() but there
are no provisions to keep it resumed until access to the HDA controller
has ceased: The GPU autosuspends after 5 seconds, rendering the HDA
controller inaccessible.
Additionally, a kludge is required when hda_intel.c probes: It has to
check whether the GPU is powered down (check_hdmi_disabled()) and defer
probing if so.
However in the meantime (in v4.10) the driver core has gained a feature
called device links which promises to solve such issues in a clean way:
It allows us to declare a dependency from the HDA controller (consumer)
to the GPU (supplier). The PM core then automagically ensures that the
GPU is runtime resumed as long as the HDA controller's ->probe hook is
executed and whenever the HDA controller is accessed.
By default, the HDA controller has a dependency on its parent, a PCIe
Root Port. Adding a device link creates another dependency on its
sibling:
PCIe Root Port
^ ^
| |
| |
HDA ===> GPU
The device link is not only used for runtime PM, it also guarantees that
on system sleep, the HDA controller suspends before the GPU and resumes
after the GPU, and on system shutdown the HDA controller's ->shutdown
hook is executed before the one of the GPU. It is a complete solution.
Using this functionality is as simple as calling device_link_add(),
which results in a dmesg entry like this:
pci 0000:01:00.1: Linked as a consumer to 0000:01:00.0
The code for the GPU-governed audio power management can thus be removed
(except where it's still needed for legacy manual power control).
The device link is added in a PCI quirk rather than in hda_intel.c.
It is therefore legal for the GPU to runtime suspend to D3cold even if
the HDA controller is not bound to a driver or if CONFIG_SND_HDA_INTEL
is not enabled, for accesses to the HDA controller will cause the GPU to
wake up regardless if they're occurring outside of hda_intel.c (think
config space readout via sysfs).
Contrary to the previous implementation, the HDA controller's power
state is now self-governed, rather than GPU-governed, whereas the GPU's
power state is no longer fully self-governed. (The HDA controller needs
to runtime suspend before the GPU can.)
It is thus crucial that runtime PM is always activated on the HDA
controller even if CONFIG_SND_HDA_POWER_SAVE_DEFAULT is set to 0 (which
is the default), lest the GPU stays awake. This is achieved by setting
the auto_runtime_pm flag on every codec and the AZX_DCAPS_PM_RUNTIME
flag on the HDA controller.
A side effect is that power consumption might be reduced if the GPU is
in use but the HDA controller is not, because the HDA controller is now
allowed to go to D3hot. Before, it was forced to stay in D0 as long as
the GPU was in use. (There is no reduction in power consumption on my
Nvidia GK107, but there might be on other chips.)
The code paths for legacy manual power control are adjusted such that
runtime PM is disabled during power off, thereby preventing the PM core
from resuming the HDA controller.
Note that the device link is not only added on vga_switcheroo capable
systems, but for *any* GPU with integrated HDA controller. The idea is
that the HDA controller streams audio via connectors located on the GPU,
so the GPU needs to be on for the HDA controller to do anything useful.
This commit implicitly fixes an unbalanced runtime PM ref upon unbind of
hda_intel.c: On ->probe, a runtime PM ref was previously released under
the condition "azx_has_pm_runtime(chip) || hda->use_vga_switcheroo", but
on ->remove a runtime PM ref was only acquired under the first of those
conditions. Thus, binding and unbinding the driver twice on a
vga_switcheroo capable system caused the runtime PM refcount to drop
below zero. The issue is resolved because the AZX_DCAPS_PM_RUNTIME flag
is now always set if use_vga_switcheroo is true.
For more information on device links please refer to:
https://www.kernel.org/doc/html/latest/driver-api/device_link.html
Documentation/driver-api/device_link.rst
Cc: Dave Airlie <airlied@redhat.com>
Cc: Ben Skeggs <bskeggs@redhat.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Takashi Iwai <tiwai@suse.de>
Reviewed-by: Peter Wu <peter@lekensteyn.nl>
Tested-by: Kai Heng Feng <kai.heng.feng@canonical.com> # AMD PowerXpress
Tested-by: Mike Lothian <mike@fireburn.co.uk> # AMD PowerXpress
Tested-by: Denis Lisov <dennis.lissov@gmail.com> # Nvidia Optimus
Tested-by: Peter Wu <peter@lekensteyn.nl> # Nvidia Optimus
Tested-by: Lukas Wunner <lukas@wunner.de> # MacBook Pro
Signed-off-by: Lukas Wunner <lukas@wunner.de>
Link: https://patchwork.freedesktop.org/patch/msgid/51bd38360ff502a8c42b1ebf4405ee1d3f27118d.1520068884.git.lukas@wunner.de
2018-03-03 09:53:24 +00:00
|
|
|
chip->driver_caps |= AZX_DCAPS_PM_RUNTIME;
|
2012-04-26 10:23:42 +00:00
|
|
|
pci_dev_put(p);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct vga_switcheroo_client_ops azx_vs_ops = {
|
|
|
|
.set_gpu_state = azx_vs_set_state,
|
|
|
|
.can_switch = azx_vs_can_switch,
|
ALSA: hda - Enable runtime PM only for discrete GPU
The recent change of vga_switcheroo allowed the runtime PM for
HD-audio on AMD GPUs, but this also resulted in a regression. When
the HD-audio controller driver gets runtime-suspended, HD-audio link
is turned off, and the hotplug notification is ignored. This leads to
the inconsistent audio state (the connection isn't notified and ELD is
ignored).
The best fix would be to implement the proper ELD notification via the
audio component, but it's still not ready. As a quick workaround,
this patch adds the check of runtime_idle and allows the runtime
suspend only when the vga_switcheroo is bound with discrete GPU.
That is, a system with a single GPU and APU would be again without
runtime PM to keep the HD-audio link for the hotplug notification and
ELD read out.
Also, the codec->auto_runtime_pm flag is set only for the discrete GPU
at the time GPU gets bound via vga_switcheroo (i.e. only dGPU is
forcibly runtime-PM enabled), so that APU can still get the ELD
notification.
For identifying which GPU is bound, a new vga_switcheroo client
callback, gpu_bound, is implemented. The vga_switcheroo simply calls
this when GPU is bound, and tells whether it's dGPU or APU.
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=200945
Fixes: 07f4f97d7b4b ("vga_switcheroo: Use device link for HDA controller")
Reported-by: Jian-Hong Pan <jian-hong@endlessm.com>
Tested-by: Jian-Hong Pan <jian-hong@endlessm.com>
Acked-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2018-09-10 14:20:25 +00:00
|
|
|
.gpu_bound = azx_vs_gpu_bound,
|
2012-04-26 10:23:42 +00:00
|
|
|
};
|
|
|
|
|
2012-12-06 17:35:10 +00:00
|
|
|
static int register_vga_switcheroo(struct azx *chip)
|
2012-04-26 10:23:42 +00:00
|
|
|
{
|
2014-06-26 15:19:20 +00:00
|
|
|
struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
|
2018-07-17 08:20:50 +00:00
|
|
|
struct pci_dev *p;
|
2012-10-12 15:28:18 +00:00
|
|
|
int err;
|
|
|
|
|
2014-06-26 15:19:20 +00:00
|
|
|
if (!hda->use_vga_switcheroo)
|
2012-04-26 10:23:42 +00:00
|
|
|
return 0;
|
2018-07-17 08:20:50 +00:00
|
|
|
|
|
|
|
p = get_bound_vga(chip->pci);
|
|
|
|
err = vga_switcheroo_register_audio_client(chip->pci, &azx_vs_ops, p);
|
|
|
|
pci_dev_put(p);
|
|
|
|
|
2012-10-12 15:28:18 +00:00
|
|
|
if (err < 0)
|
|
|
|
return err;
|
2014-06-26 15:19:20 +00:00
|
|
|
hda->vga_switcheroo_registered = 1;
|
2013-07-29 05:19:29 +00:00
|
|
|
|
2012-10-12 15:28:18 +00:00
|
|
|
return 0;
|
2012-04-26 10:23:42 +00:00
|
|
|
}
|
|
|
|
#else
|
|
|
|
#define init_vga_switcheroo(chip) /* NOP */
|
|
|
|
#define register_vga_switcheroo(chip) 0
|
2012-06-08 11:06:29 +00:00
|
|
|
#define check_hdmi_disabled(pci) false
|
ALSA: hda - Enable runtime PM only for discrete GPU
The recent change of vga_switcheroo allowed the runtime PM for
HD-audio on AMD GPUs, but this also resulted in a regression. When
the HD-audio controller driver gets runtime-suspended, HD-audio link
is turned off, and the hotplug notification is ignored. This leads to
the inconsistent audio state (the connection isn't notified and ELD is
ignored).
The best fix would be to implement the proper ELD notification via the
audio component, but it's still not ready. As a quick workaround,
this patch adds the check of runtime_idle and allows the runtime
suspend only when the vga_switcheroo is bound with discrete GPU.
That is, a system with a single GPU and APU would be again without
runtime PM to keep the HD-audio link for the hotplug notification and
ELD read out.
Also, the codec->auto_runtime_pm flag is set only for the discrete GPU
at the time GPU gets bound via vga_switcheroo (i.e. only dGPU is
forcibly runtime-PM enabled), so that APU can still get the ELD
notification.
For identifying which GPU is bound, a new vga_switcheroo client
callback, gpu_bound, is implemented. The vga_switcheroo simply calls
this when GPU is bound, and tells whether it's dGPU or APU.
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=200945
Fixes: 07f4f97d7b4b ("vga_switcheroo: Use device link for HDA controller")
Reported-by: Jian-Hong Pan <jian-hong@endlessm.com>
Tested-by: Jian-Hong Pan <jian-hong@endlessm.com>
Acked-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2018-09-10 14:20:25 +00:00
|
|
|
#define setup_vga_switcheroo_runtime_pm(chip) /* NOP */
|
2012-04-26 10:23:42 +00:00
|
|
|
#endif /* SUPPORT_VGA_SWITCHER */
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
/*
|
|
|
|
* destructor
|
|
|
|
*/
|
ALSA: hda: Release resources at error in delayed probe
snd-hda-intel driver handles the most of its probe task in the delayed
work (either via workqueue or via firmware loader). When an error
happens in the later delayed probe, we can't deregister the device
itself because the probe callback already returned success and the
device was bound. So, for now, we set hda->init_failed flag and make
the rest untouched until the device gets really unbound.
However, this leaves the device up running, keeping the resources
without any use that prevents other operations.
In this patch, we release the resources at first when a probe error
happens in the delayed probe stage, but keeps the top-level object, so
that the PM and other ops can still refer to the object itself.
Also for simplicity, snd_hda_intel object is allocated via devm, so
that we can get rid of the explicit kfree calls.
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=207043
Link: https://lore.kernel.org/r/20200413082034.25166-4-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2020-04-13 08:20:31 +00:00
|
|
|
static void azx_free(struct azx *chip)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
2013-05-30 14:07:08 +00:00
|
|
|
struct pci_dev *pci = chip->pci;
|
2014-06-26 10:45:16 +00:00
|
|
|
struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
|
2015-04-14 20:13:18 +00:00
|
|
|
struct hdac_bus *bus = azx_bus(chip);
|
2008-02-06 13:50:19 +00:00
|
|
|
|
ALSA: hda: Release resources at error in delayed probe
snd-hda-intel driver handles the most of its probe task in the delayed
work (either via workqueue or via firmware loader). When an error
happens in the later delayed probe, we can't deregister the device
itself because the probe callback already returned success and the
device was bound. So, for now, we set hda->init_failed flag and make
the rest untouched until the device gets really unbound.
However, this leaves the device up running, keeping the resources
without any use that prevents other operations.
In this patch, we release the resources at first when a probe error
happens in the delayed probe stage, but keeps the top-level object, so
that the PM and other ops can still refer to the object itself.
Also for simplicity, snd_hda_intel object is allocated via devm, so
that we can get rid of the explicit kfree calls.
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=207043
Link: https://lore.kernel.org/r/20200413082034.25166-4-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2020-04-13 08:20:31 +00:00
|
|
|
if (hda->freed)
|
|
|
|
return;
|
|
|
|
|
2021-11-15 07:59:44 +00:00
|
|
|
if (azx_has_pm_runtime(chip) && chip->running) {
|
2013-05-30 14:07:08 +00:00
|
|
|
pm_runtime_get_noresume(&pci->dev);
|
2021-11-15 07:59:44 +00:00
|
|
|
pm_runtime_forbid(&pci->dev);
|
|
|
|
pm_runtime_dont_use_autosuspend(&pci->dev);
|
|
|
|
}
|
|
|
|
|
ALSA: hda - Enable runtime PM only for discrete GPU
The recent change of vga_switcheroo allowed the runtime PM for
HD-audio on AMD GPUs, but this also resulted in a regression. When
the HD-audio controller driver gets runtime-suspended, HD-audio link
is turned off, and the hotplug notification is ignored. This leads to
the inconsistent audio state (the connection isn't notified and ELD is
ignored).
The best fix would be to implement the proper ELD notification via the
audio component, but it's still not ready. As a quick workaround,
this patch adds the check of runtime_idle and allows the runtime
suspend only when the vga_switcheroo is bound with discrete GPU.
That is, a system with a single GPU and APU would be again without
runtime PM to keep the HD-audio link for the hotplug notification and
ELD read out.
Also, the codec->auto_runtime_pm flag is set only for the discrete GPU
at the time GPU gets bound via vga_switcheroo (i.e. only dGPU is
forcibly runtime-PM enabled), so that APU can still get the ELD
notification.
For identifying which GPU is bound, a new vga_switcheroo client
callback, gpu_bound, is implemented. The vga_switcheroo simply calls
this when GPU is bound, and tells whether it's dGPU or APU.
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=200945
Fixes: 07f4f97d7b4b ("vga_switcheroo: Use device link for HDA controller")
Reported-by: Jian-Hong Pan <jian-hong@endlessm.com>
Tested-by: Jian-Hong Pan <jian-hong@endlessm.com>
Acked-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2018-09-10 14:20:25 +00:00
|
|
|
chip->running = 0;
|
2013-05-30 14:07:08 +00:00
|
|
|
|
2012-08-14 15:13:32 +00:00
|
|
|
azx_del_card_list(chip);
|
|
|
|
|
2014-06-26 15:19:20 +00:00
|
|
|
hda->init_failed = 1; /* to be sure */
|
|
|
|
complete_all(&hda->probe_wait);
|
2012-12-04 14:09:23 +00:00
|
|
|
|
2014-06-26 15:19:20 +00:00
|
|
|
if (use_vga_switcheroo(hda)) {
|
2015-04-14 20:13:18 +00:00
|
|
|
if (chip->disabled && hda->probe_continued)
|
|
|
|
snd_hda_unlock_devices(&chip->bus);
|
vga_switcheroo: Use device link for HDA controller
Back in 2013, runtime PM for GPUs with integrated HDA controller was
introduced with commits 0d69704ae348 ("gpu/vga_switcheroo: add driver
control power feature. (v3)") and 246efa4a072f ("snd/hda: add runtime
suspend/resume on optimus support (v4)").
Briefly, the idea was that the HDA controller is forced on and off in
unison with the GPU.
The original code is mostly still in place even though it was never a
100% perfect solution: E.g. on access to the HDA controller, the GPU
is powered up via vga_switcheroo_runtime_resume_hdmi_audio() but there
are no provisions to keep it resumed until access to the HDA controller
has ceased: The GPU autosuspends after 5 seconds, rendering the HDA
controller inaccessible.
Additionally, a kludge is required when hda_intel.c probes: It has to
check whether the GPU is powered down (check_hdmi_disabled()) and defer
probing if so.
However in the meantime (in v4.10) the driver core has gained a feature
called device links which promises to solve such issues in a clean way:
It allows us to declare a dependency from the HDA controller (consumer)
to the GPU (supplier). The PM core then automagically ensures that the
GPU is runtime resumed as long as the HDA controller's ->probe hook is
executed and whenever the HDA controller is accessed.
By default, the HDA controller has a dependency on its parent, a PCIe
Root Port. Adding a device link creates another dependency on its
sibling:
PCIe Root Port
^ ^
| |
| |
HDA ===> GPU
The device link is not only used for runtime PM, it also guarantees that
on system sleep, the HDA controller suspends before the GPU and resumes
after the GPU, and on system shutdown the HDA controller's ->shutdown
hook is executed before the one of the GPU. It is a complete solution.
Using this functionality is as simple as calling device_link_add(),
which results in a dmesg entry like this:
pci 0000:01:00.1: Linked as a consumer to 0000:01:00.0
The code for the GPU-governed audio power management can thus be removed
(except where it's still needed for legacy manual power control).
The device link is added in a PCI quirk rather than in hda_intel.c.
It is therefore legal for the GPU to runtime suspend to D3cold even if
the HDA controller is not bound to a driver or if CONFIG_SND_HDA_INTEL
is not enabled, for accesses to the HDA controller will cause the GPU to
wake up regardless if they're occurring outside of hda_intel.c (think
config space readout via sysfs).
Contrary to the previous implementation, the HDA controller's power
state is now self-governed, rather than GPU-governed, whereas the GPU's
power state is no longer fully self-governed. (The HDA controller needs
to runtime suspend before the GPU can.)
It is thus crucial that runtime PM is always activated on the HDA
controller even if CONFIG_SND_HDA_POWER_SAVE_DEFAULT is set to 0 (which
is the default), lest the GPU stays awake. This is achieved by setting
the auto_runtime_pm flag on every codec and the AZX_DCAPS_PM_RUNTIME
flag on the HDA controller.
A side effect is that power consumption might be reduced if the GPU is
in use but the HDA controller is not, because the HDA controller is now
allowed to go to D3hot. Before, it was forced to stay in D0 as long as
the GPU was in use. (There is no reduction in power consumption on my
Nvidia GK107, but there might be on other chips.)
The code paths for legacy manual power control are adjusted such that
runtime PM is disabled during power off, thereby preventing the PM core
from resuming the HDA controller.
Note that the device link is not only added on vga_switcheroo capable
systems, but for *any* GPU with integrated HDA controller. The idea is
that the HDA controller streams audio via connectors located on the GPU,
so the GPU needs to be on for the HDA controller to do anything useful.
This commit implicitly fixes an unbalanced runtime PM ref upon unbind of
hda_intel.c: On ->probe, a runtime PM ref was previously released under
the condition "azx_has_pm_runtime(chip) || hda->use_vga_switcheroo", but
on ->remove a runtime PM ref was only acquired under the first of those
conditions. Thus, binding and unbinding the driver twice on a
vga_switcheroo capable system caused the runtime PM refcount to drop
below zero. The issue is resolved because the AZX_DCAPS_PM_RUNTIME flag
is now always set if use_vga_switcheroo is true.
For more information on device links please refer to:
https://www.kernel.org/doc/html/latest/driver-api/device_link.html
Documentation/driver-api/device_link.rst
Cc: Dave Airlie <airlied@redhat.com>
Cc: Ben Skeggs <bskeggs@redhat.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Takashi Iwai <tiwai@suse.de>
Reviewed-by: Peter Wu <peter@lekensteyn.nl>
Tested-by: Kai Heng Feng <kai.heng.feng@canonical.com> # AMD PowerXpress
Tested-by: Mike Lothian <mike@fireburn.co.uk> # AMD PowerXpress
Tested-by: Denis Lisov <dennis.lissov@gmail.com> # Nvidia Optimus
Tested-by: Peter Wu <peter@lekensteyn.nl> # Nvidia Optimus
Tested-by: Lukas Wunner <lukas@wunner.de> # MacBook Pro
Signed-off-by: Lukas Wunner <lukas@wunner.de>
Link: https://patchwork.freedesktop.org/patch/msgid/51bd38360ff502a8c42b1ebf4405ee1d3f27118d.1520068884.git.lukas@wunner.de
2018-03-03 09:53:24 +00:00
|
|
|
if (hda->vga_switcheroo_registered)
|
2012-10-12 15:28:18 +00:00
|
|
|
vga_switcheroo_unregister_client(chip->pci);
|
2012-04-26 10:23:42 +00:00
|
|
|
}
|
|
|
|
|
2015-04-14 20:13:18 +00:00
|
|
|
if (bus->chip_init) {
|
2008-05-16 10:34:47 +00:00
|
|
|
azx_clear_irq_pending(chip);
|
2015-04-14 16:13:13 +00:00
|
|
|
azx_stop_all_streams(chip);
|
2019-10-28 08:10:56 +00:00
|
|
|
azx_stop_chip(chip);
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
2015-04-14 20:13:18 +00:00
|
|
|
if (bus->irq >= 0)
|
|
|
|
free_irq(bus->irq, (void*)chip);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2014-02-28 23:41:23 +00:00
|
|
|
azx_free_stream_pages(chip);
|
2015-04-14 20:13:18 +00:00
|
|
|
azx_free_streams(chip);
|
|
|
|
snd_hdac_bus_exit(bus);
|
|
|
|
|
2012-08-09 10:33:28 +00:00
|
|
|
#ifdef CONFIG_SND_HDA_PATCH_LOADER
|
2014-11-17 09:44:33 +00:00
|
|
|
release_firmware(chip->fw);
|
2012-08-09 10:33:28 +00:00
|
|
|
#endif
|
2018-12-09 08:57:37 +00:00
|
|
|
display_power(chip, false);
|
2015-05-19 14:29:30 +00:00
|
|
|
|
2017-07-04 14:04:38 +00:00
|
|
|
if (chip->driver_caps & AZX_DCAPS_I915_COMPONENT)
|
2017-06-28 10:54:53 +00:00
|
|
|
snd_hdac_i915_exit(bus);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
ALSA: hda: Release resources at error in delayed probe
snd-hda-intel driver handles the most of its probe task in the delayed
work (either via workqueue or via firmware loader). When an error
happens in the later delayed probe, we can't deregister the device
itself because the probe callback already returned success and the
device was bound. So, for now, we set hda->init_failed flag and make
the rest untouched until the device gets really unbound.
However, this leaves the device up running, keeping the resources
without any use that prevents other operations.
In this patch, we release the resources at first when a probe error
happens in the delayed probe stage, but keeps the top-level object, so
that the PM and other ops can still refer to the object itself.
Also for simplicity, snd_hda_intel object is allocated via devm, so
that we can get rid of the explicit kfree calls.
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=207043
Link: https://lore.kernel.org/r/20200413082034.25166-4-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2020-04-13 08:20:31 +00:00
|
|
|
hda->freed = 1;
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
2015-04-14 20:13:18 +00:00
|
|
|
static int azx_dev_disconnect(struct snd_device *device)
|
|
|
|
{
|
|
|
|
struct azx *chip = device->device_data;
|
2019-10-28 10:58:03 +00:00
|
|
|
struct hdac_bus *bus = azx_bus(chip);
|
2015-04-14 20:13:18 +00:00
|
|
|
|
|
|
|
chip->bus.shutdown = 1;
|
2019-10-28 10:58:03 +00:00
|
|
|
cancel_work_sync(&bus->unsol_work);
|
|
|
|
|
2015-04-14 20:13:18 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-11-17 13:59:02 +00:00
|
|
|
static int azx_dev_free(struct snd_device *device)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
ALSA: hda: Release resources at error in delayed probe
snd-hda-intel driver handles the most of its probe task in the delayed
work (either via workqueue or via firmware loader). When an error
happens in the later delayed probe, we can't deregister the device
itself because the probe callback already returned success and the
device was bound. So, for now, we set hda->init_failed flag and make
the rest untouched until the device gets really unbound.
However, this leaves the device up running, keeping the resources
without any use that prevents other operations.
In this patch, we release the resources at first when a probe error
happens in the delayed probe stage, but keeps the top-level object, so
that the PM and other ops can still refer to the object itself.
Also for simplicity, snd_hda_intel object is allocated via devm, so
that we can get rid of the explicit kfree calls.
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=207043
Link: https://lore.kernel.org/r/20200413082034.25166-4-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2020-04-13 08:20:31 +00:00
|
|
|
azx_free(device->device_data);
|
|
|
|
return 0;
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
2012-06-08 11:06:29 +00:00
|
|
|
#ifdef SUPPORT_VGA_SWITCHEROO
|
2019-11-22 21:43:50 +00:00
|
|
|
#ifdef CONFIG_ACPI
|
|
|
|
/* ATPX is in the integrated GPU's namespace */
|
|
|
|
static bool atpx_present(void)
|
|
|
|
{
|
|
|
|
struct pci_dev *pdev = NULL;
|
|
|
|
acpi_handle dhandle, atpx_handle;
|
|
|
|
acpi_status status;
|
|
|
|
|
2019-12-21 00:17:02 +00:00
|
|
|
while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) {
|
|
|
|
dhandle = ACPI_HANDLE(&pdev->dev);
|
|
|
|
if (dhandle) {
|
|
|
|
status = acpi_get_handle(dhandle, "ATPX", &atpx_handle);
|
2021-01-26 20:23:17 +00:00
|
|
|
if (ACPI_SUCCESS(status)) {
|
2019-12-21 00:17:02 +00:00
|
|
|
pci_dev_put(pdev);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_OTHER << 8, pdev)) != NULL) {
|
2019-11-22 21:43:50 +00:00
|
|
|
dhandle = ACPI_HANDLE(&pdev->dev);
|
|
|
|
if (dhandle) {
|
|
|
|
status = acpi_get_handle(dhandle, "ATPX", &atpx_handle);
|
2021-01-26 20:23:17 +00:00
|
|
|
if (ACPI_SUCCESS(status)) {
|
2019-11-22 21:43:50 +00:00
|
|
|
pci_dev_put(pdev);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
static bool atpx_present(void)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2012-04-26 10:13:25 +00:00
|
|
|
/*
|
2015-09-04 18:49:36 +00:00
|
|
|
* Check of disabled HDMI controller by vga_switcheroo
|
2012-04-26 10:13:25 +00:00
|
|
|
*/
|
2012-12-06 17:35:10 +00:00
|
|
|
static struct pci_dev *get_bound_vga(struct pci_dev *pci)
|
2012-04-26 10:13:25 +00:00
|
|
|
{
|
|
|
|
struct pci_dev *p;
|
|
|
|
|
|
|
|
/* check only discrete GPU */
|
|
|
|
switch (pci->vendor) {
|
|
|
|
case PCI_VENDOR_ID_ATI:
|
|
|
|
case PCI_VENDOR_ID_AMD:
|
2019-11-22 21:43:50 +00:00
|
|
|
if (pci->devfn == 1) {
|
|
|
|
p = pci_get_domain_bus_and_slot(pci_domain_nr(pci->bus),
|
|
|
|
pci->bus->number, 0);
|
|
|
|
if (p) {
|
|
|
|
/* ATPX is in the integrated GPU's ACPI namespace
|
|
|
|
* rather than the dGPU's namespace. However,
|
|
|
|
* the dGPU is the one who is involved in
|
|
|
|
* vgaswitcheroo.
|
|
|
|
*/
|
|
|
|
if (((p->class >> 16) == PCI_BASE_CLASS_DISPLAY) &&
|
|
|
|
atpx_present())
|
|
|
|
return p;
|
|
|
|
pci_dev_put(p);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2012-04-26 10:13:25 +00:00
|
|
|
case PCI_VENDOR_ID_NVIDIA:
|
|
|
|
if (pci->devfn == 1) {
|
|
|
|
p = pci_get_domain_bus_and_slot(pci_domain_nr(pci->bus),
|
|
|
|
pci->bus->number, 0);
|
|
|
|
if (p) {
|
2018-07-16 06:06:34 +00:00
|
|
|
if ((p->class >> 16) == PCI_BASE_CLASS_DISPLAY)
|
2012-04-26 10:13:25 +00:00
|
|
|
return p;
|
|
|
|
pci_dev_put(p);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2012-12-06 17:35:10 +00:00
|
|
|
static bool check_hdmi_disabled(struct pci_dev *pci)
|
2012-04-26 10:13:25 +00:00
|
|
|
{
|
|
|
|
bool vga_inactive = false;
|
|
|
|
struct pci_dev *p = get_bound_vga(pci);
|
|
|
|
|
|
|
|
if (p) {
|
2012-06-07 10:15:16 +00:00
|
|
|
if (vga_switcheroo_get_client_state(p) == VGA_SWITCHEROO_OFF)
|
2012-04-26 10:13:25 +00:00
|
|
|
vga_inactive = true;
|
|
|
|
pci_dev_put(p);
|
|
|
|
}
|
|
|
|
return vga_inactive;
|
|
|
|
}
|
2012-06-08 11:06:29 +00:00
|
|
|
#endif /* SUPPORT_VGA_SWITCHEROO */
|
2012-04-26 10:13:25 +00:00
|
|
|
|
2007-02-01 14:46:50 +00:00
|
|
|
/*
|
2020-07-14 17:26:27 +00:00
|
|
|
* allow/deny-listing for position_fix
|
2007-02-01 14:46:50 +00:00
|
|
|
*/
|
2020-01-03 08:17:13 +00:00
|
|
|
static const struct snd_pci_quirk position_fix_list[] = {
|
2008-06-10 15:53:34 +00:00
|
|
|
SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB),
|
|
|
|
SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB),
|
2009-12-01 13:17:37 +00:00
|
|
|
SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB),
|
2008-06-10 15:53:34 +00:00
|
|
|
SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB),
|
2010-05-30 05:17:03 +00:00
|
|
|
SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB),
|
2010-05-30 17:08:41 +00:00
|
|
|
SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS M2V", POS_FIX_LPIB),
|
2010-05-27 22:32:18 +00:00
|
|
|
SND_PCI_QUIRK(0x104d, 0x9069, "Sony VPCS11V9E", POS_FIX_LPIB),
|
2012-01-12 15:31:14 +00:00
|
|
|
SND_PCI_QUIRK(0x10de, 0xcb89, "Macbook Pro 7,1", POS_FIX_LPIB),
|
2010-05-29 15:04:11 +00:00
|
|
|
SND_PCI_QUIRK(0x1297, 0x3166, "Shuttle", POS_FIX_LPIB),
|
2010-03-28 06:34:40 +00:00
|
|
|
SND_PCI_QUIRK(0x1458, 0xa022, "ga-ma770-ud3", POS_FIX_LPIB),
|
2009-11-30 10:58:30 +00:00
|
|
|
SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB),
|
2010-04-15 07:02:41 +00:00
|
|
|
SND_PCI_QUIRK(0x1565, 0x8218, "Biostar Microtech", POS_FIX_LPIB),
|
2010-05-30 23:31:41 +00:00
|
|
|
SND_PCI_QUIRK(0x1849, 0x0888, "775Dual-VSTA", POS_FIX_LPIB),
|
2010-04-21 23:55:43 +00:00
|
|
|
SND_PCI_QUIRK(0x8086, 0x2503, "DG965OT AAD63733-203", POS_FIX_LPIB),
|
2007-02-01 14:46:50 +00:00
|
|
|
{}
|
|
|
|
};
|
|
|
|
|
2012-12-06 17:35:10 +00:00
|
|
|
static int check_position_fix(struct azx *chip, int fix)
|
2007-02-01 14:46:50 +00:00
|
|
|
{
|
|
|
|
const struct snd_pci_quirk *q;
|
|
|
|
|
2009-03-17 06:49:14 +00:00
|
|
|
switch (fix) {
|
2012-09-13 12:59:47 +00:00
|
|
|
case POS_FIX_AUTO:
|
2009-03-17 06:49:14 +00:00
|
|
|
case POS_FIX_LPIB:
|
|
|
|
case POS_FIX_POSBUF:
|
2010-09-30 08:12:50 +00:00
|
|
|
case POS_FIX_VIACOMBO:
|
2012-02-28 10:58:40 +00:00
|
|
|
case POS_FIX_COMBO:
|
2017-03-29 06:46:00 +00:00
|
|
|
case POS_FIX_SKL:
|
ALSA: hda - Workaround for crackled sound on AMD controller (1022:1457)
A long-time problem on the recent AMD chip (X370, X470, B450, etc with
PCI ID 1022:1457) with Realtek codecs is the crackled or distorted
sound for capture streams, as well as occasional playback hiccups.
After lengthy debugging sessions, the workarounds we've found are like
the following:
- Set up the proper driver caps for this controller, similar as the
other AMD controller.
- Correct the DMA position reporting with the fixed FIFO size, which
is similar like as workaround used for VIA chip set.
- Even after the position correction, PulseAudio still shows
mysterious stalls of playback streams when a capture is triggered in
timer-scheduled mode. Since we have no clear way to eliminate the
stall, pass the BATCH PCM flag for PA to suppress the tsched mode as
a temporary workaround.
This patch implements the workarounds. For the driver caps, it
defines a new preset, AXZ_DCAPS_PRESET_AMD_SB. It enables the FIFO-
corrected position reporting (corresponding to the new position_fix=6)
and enforces the SNDRV_PCM_INFO_BATCH flag.
Note that the current implementation is merely a workaround.
Hopefully we'll find a better alternative in future, especially about
removing the BATCH flag hack again.
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=195303
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2019-08-06 15:31:48 +00:00
|
|
|
case POS_FIX_FIFO:
|
2009-03-17 06:49:14 +00:00
|
|
|
return fix;
|
|
|
|
}
|
|
|
|
|
|
|
|
q = snd_pci_quirk_lookup(chip->pci, position_fix_list);
|
|
|
|
if (q) {
|
2014-02-25 11:21:03 +00:00
|
|
|
dev_info(chip->card->dev,
|
|
|
|
"position_fix set to %d for device %04x:%04x\n",
|
|
|
|
q->value, q->subvendor, q->subdevice);
|
2009-03-17 06:49:14 +00:00
|
|
|
return q->value;
|
2007-02-01 14:46:50 +00:00
|
|
|
}
|
2010-10-04 10:02:14 +00:00
|
|
|
|
|
|
|
/* Check VIA/ATI HD Audio Controller exist */
|
2015-12-17 07:29:53 +00:00
|
|
|
if (chip->driver_type == AZX_DRIVER_VIA) {
|
2014-02-25 11:21:03 +00:00
|
|
|
dev_dbg(chip->card->dev, "Using VIACOMBO position fix\n");
|
2010-10-04 10:02:14 +00:00
|
|
|
return POS_FIX_VIACOMBO;
|
2011-05-25 07:11:37 +00:00
|
|
|
}
|
ALSA: hda - Workaround for crackled sound on AMD controller (1022:1457)
A long-time problem on the recent AMD chip (X370, X470, B450, etc with
PCI ID 1022:1457) with Realtek codecs is the crackled or distorted
sound for capture streams, as well as occasional playback hiccups.
After lengthy debugging sessions, the workarounds we've found are like
the following:
- Set up the proper driver caps for this controller, similar as the
other AMD controller.
- Correct the DMA position reporting with the fixed FIFO size, which
is similar like as workaround used for VIA chip set.
- Even after the position correction, PulseAudio still shows
mysterious stalls of playback streams when a capture is triggered in
timer-scheduled mode. Since we have no clear way to eliminate the
stall, pass the BATCH PCM flag for PA to suppress the tsched mode as
a temporary workaround.
This patch implements the workarounds. For the driver caps, it
defines a new preset, AXZ_DCAPS_PRESET_AMD_SB. It enables the FIFO-
corrected position reporting (corresponding to the new position_fix=6)
and enforces the SNDRV_PCM_INFO_BATCH flag.
Note that the current implementation is merely a workaround.
Hopefully we'll find a better alternative in future, especially about
removing the BATCH flag hack again.
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=195303
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2019-08-06 15:31:48 +00:00
|
|
|
if (chip->driver_caps & AZX_DCAPS_AMD_WORKAROUND) {
|
|
|
|
dev_dbg(chip->card->dev, "Using FIFO position fix\n");
|
|
|
|
return POS_FIX_FIFO;
|
|
|
|
}
|
2011-05-25 07:11:37 +00:00
|
|
|
if (chip->driver_caps & AZX_DCAPS_POSFIX_LPIB) {
|
2014-02-25 11:21:03 +00:00
|
|
|
dev_dbg(chip->card->dev, "Using LPIB position fix\n");
|
2011-05-20 14:29:09 +00:00
|
|
|
return POS_FIX_LPIB;
|
2010-10-04 10:02:14 +00:00
|
|
|
}
|
2017-06-14 05:26:00 +00:00
|
|
|
if (chip->driver_type == AZX_DRIVER_SKL) {
|
2017-03-29 06:46:00 +00:00
|
|
|
dev_dbg(chip->card->dev, "Using SKL position fix\n");
|
|
|
|
return POS_FIX_SKL;
|
|
|
|
}
|
2009-03-17 06:49:14 +00:00
|
|
|
return POS_FIX_AUTO;
|
2007-02-01 14:46:50 +00:00
|
|
|
}
|
|
|
|
|
2014-06-26 14:50:16 +00:00
|
|
|
static void assign_position_fix(struct azx *chip, int fix)
|
|
|
|
{
|
2020-01-05 14:47:24 +00:00
|
|
|
static const azx_get_pos_callback_t callbacks[] = {
|
2014-06-26 14:50:16 +00:00
|
|
|
[POS_FIX_AUTO] = NULL,
|
|
|
|
[POS_FIX_LPIB] = azx_get_pos_lpib,
|
|
|
|
[POS_FIX_POSBUF] = azx_get_pos_posbuf,
|
|
|
|
[POS_FIX_VIACOMBO] = azx_via_get_position,
|
|
|
|
[POS_FIX_COMBO] = azx_get_pos_lpib,
|
2021-09-29 07:29:34 +00:00
|
|
|
[POS_FIX_SKL] = azx_get_pos_posbuf,
|
ALSA: hda - Workaround for crackled sound on AMD controller (1022:1457)
A long-time problem on the recent AMD chip (X370, X470, B450, etc with
PCI ID 1022:1457) with Realtek codecs is the crackled or distorted
sound for capture streams, as well as occasional playback hiccups.
After lengthy debugging sessions, the workarounds we've found are like
the following:
- Set up the proper driver caps for this controller, similar as the
other AMD controller.
- Correct the DMA position reporting with the fixed FIFO size, which
is similar like as workaround used for VIA chip set.
- Even after the position correction, PulseAudio still shows
mysterious stalls of playback streams when a capture is triggered in
timer-scheduled mode. Since we have no clear way to eliminate the
stall, pass the BATCH PCM flag for PA to suppress the tsched mode as
a temporary workaround.
This patch implements the workarounds. For the driver caps, it
defines a new preset, AXZ_DCAPS_PRESET_AMD_SB. It enables the FIFO-
corrected position reporting (corresponding to the new position_fix=6)
and enforces the SNDRV_PCM_INFO_BATCH flag.
Note that the current implementation is merely a workaround.
Hopefully we'll find a better alternative in future, especially about
removing the BATCH flag hack again.
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=195303
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2019-08-06 15:31:48 +00:00
|
|
|
[POS_FIX_FIFO] = azx_get_pos_fifo,
|
2014-06-26 14:50:16 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
chip->get_position[0] = chip->get_position[1] = callbacks[fix];
|
|
|
|
|
|
|
|
/* combo mode uses LPIB only for playback */
|
|
|
|
if (fix == POS_FIX_COMBO)
|
|
|
|
chip->get_position[1] = NULL;
|
|
|
|
|
2017-03-29 06:46:00 +00:00
|
|
|
if ((fix == POS_FIX_POSBUF || fix == POS_FIX_SKL) &&
|
2014-06-26 14:50:16 +00:00
|
|
|
(chip->driver_caps & AZX_DCAPS_COUNT_LPIB_DELAY)) {
|
|
|
|
chip->get_delay[0] = chip->get_delay[1] =
|
|
|
|
azx_get_delay_from_lpib;
|
|
|
|
}
|
|
|
|
|
ALSA: hda - Workaround for crackled sound on AMD controller (1022:1457)
A long-time problem on the recent AMD chip (X370, X470, B450, etc with
PCI ID 1022:1457) with Realtek codecs is the crackled or distorted
sound for capture streams, as well as occasional playback hiccups.
After lengthy debugging sessions, the workarounds we've found are like
the following:
- Set up the proper driver caps for this controller, similar as the
other AMD controller.
- Correct the DMA position reporting with the fixed FIFO size, which
is similar like as workaround used for VIA chip set.
- Even after the position correction, PulseAudio still shows
mysterious stalls of playback streams when a capture is triggered in
timer-scheduled mode. Since we have no clear way to eliminate the
stall, pass the BATCH PCM flag for PA to suppress the tsched mode as
a temporary workaround.
This patch implements the workarounds. For the driver caps, it
defines a new preset, AXZ_DCAPS_PRESET_AMD_SB. It enables the FIFO-
corrected position reporting (corresponding to the new position_fix=6)
and enforces the SNDRV_PCM_INFO_BATCH flag.
Note that the current implementation is merely a workaround.
Hopefully we'll find a better alternative in future, especially about
removing the BATCH flag hack again.
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=195303
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2019-08-06 15:31:48 +00:00
|
|
|
if (fix == POS_FIX_FIFO)
|
|
|
|
chip->get_delay[0] = chip->get_delay[1] =
|
|
|
|
azx_get_delay_from_fifo;
|
2014-06-26 14:50:16 +00:00
|
|
|
}
|
|
|
|
|
2007-08-17 07:17:36 +00:00
|
|
|
/*
|
2020-07-14 17:26:27 +00:00
|
|
|
* deny-lists for probe_mask
|
2007-08-17 07:17:36 +00:00
|
|
|
*/
|
2020-01-03 08:17:13 +00:00
|
|
|
static const struct snd_pci_quirk probe_mask_list[] = {
|
2007-08-17 07:17:36 +00:00
|
|
|
/* Thinkpad often breaks the controller communication when accessing
|
|
|
|
* to the non-working (or non-existing) modem codec slot.
|
|
|
|
*/
|
|
|
|
SND_PCI_QUIRK(0x1014, 0x05b7, "Thinkpad Z60", 0x01),
|
|
|
|
SND_PCI_QUIRK(0x17aa, 0x2010, "Thinkpad X/T/R60", 0x01),
|
|
|
|
SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X/T/R61", 0x01),
|
2008-11-07 13:53:09 +00:00
|
|
|
/* broken BIOS */
|
|
|
|
SND_PCI_QUIRK(0x1028, 0x20ac, "Dell Studio Desktop", 0x01),
|
2008-11-24 16:29:28 +00:00
|
|
|
/* including bogus ALC268 in slot#2 that conflicts with ALC888 */
|
|
|
|
SND_PCI_QUIRK(0x17c0, 0x4085, "Medion MD96630", 0x01),
|
2009-02-13 07:18:48 +00:00
|
|
|
/* forced codec slots */
|
2009-05-23 12:00:04 +00:00
|
|
|
SND_PCI_QUIRK(0x1043, 0x1262, "ASUS W5Fm", 0x103),
|
2009-02-13 07:18:48 +00:00
|
|
|
SND_PCI_QUIRK(0x1046, 0x1262, "ASUS W5F", 0x103),
|
2022-02-14 10:00:20 +00:00
|
|
|
SND_PCI_QUIRK(0x1558, 0x0351, "Schenker Dock 15", 0x105),
|
2012-04-26 15:52:35 +00:00
|
|
|
/* WinFast VP200 H (Teradici) user reported broken communication */
|
|
|
|
SND_PCI_QUIRK(0x3a21, 0x040d, "WinFast VP200 H", 0x101),
|
2007-08-17 07:17:36 +00:00
|
|
|
{}
|
|
|
|
};
|
|
|
|
|
2009-02-13 07:16:55 +00:00
|
|
|
#define AZX_FORCE_CODEC_MASK 0x100
|
|
|
|
|
2012-12-06 17:35:10 +00:00
|
|
|
static void check_probe_mask(struct azx *chip, int dev)
|
2007-08-17 07:17:36 +00:00
|
|
|
{
|
|
|
|
const struct snd_pci_quirk *q;
|
|
|
|
|
2009-02-13 07:16:55 +00:00
|
|
|
chip->codec_probe_mask = probe_mask[dev];
|
|
|
|
if (chip->codec_probe_mask == -1) {
|
2007-08-17 07:17:36 +00:00
|
|
|
q = snd_pci_quirk_lookup(chip->pci, probe_mask_list);
|
|
|
|
if (q) {
|
2014-02-25 11:21:03 +00:00
|
|
|
dev_info(chip->card->dev,
|
|
|
|
"probe_mask set to 0x%x for device %04x:%04x\n",
|
|
|
|
q->value, q->subvendor, q->subdevice);
|
2009-02-13 07:16:55 +00:00
|
|
|
chip->codec_probe_mask = q->value;
|
2007-08-17 07:17:36 +00:00
|
|
|
}
|
|
|
|
}
|
2009-02-13 07:16:55 +00:00
|
|
|
|
|
|
|
/* check forced option */
|
|
|
|
if (chip->codec_probe_mask != -1 &&
|
|
|
|
(chip->codec_probe_mask & AZX_FORCE_CODEC_MASK)) {
|
2015-04-14 20:13:18 +00:00
|
|
|
azx_bus(chip)->codec_mask = chip->codec_probe_mask & 0xff;
|
2014-02-25 11:21:03 +00:00
|
|
|
dev_info(chip->card->dev, "codec_mask forced to 0x%x\n",
|
2015-04-14 20:13:18 +00:00
|
|
|
(int)azx_bus(chip)->codec_mask);
|
2009-02-13 07:16:55 +00:00
|
|
|
}
|
2007-08-17 07:17:36 +00:00
|
|
|
}
|
|
|
|
|
2009-08-11 12:21:26 +00:00
|
|
|
/*
|
2020-07-14 17:26:27 +00:00
|
|
|
* allow/deny-list for enable_msi
|
2009-08-11 12:21:26 +00:00
|
|
|
*/
|
2020-07-14 17:26:27 +00:00
|
|
|
static const struct snd_pci_quirk msi_deny_list[] = {
|
2013-12-12 08:52:03 +00:00
|
|
|
SND_PCI_QUIRK(0x103c, 0x2191, "HP", 0), /* AMD Hudson */
|
|
|
|
SND_PCI_QUIRK(0x103c, 0x2192, "HP", 0), /* AMD Hudson */
|
|
|
|
SND_PCI_QUIRK(0x103c, 0x21f7, "HP", 0), /* AMD Hudson */
|
|
|
|
SND_PCI_QUIRK(0x103c, 0x21fa, "HP", 0), /* AMD Hudson */
|
2009-12-22 07:15:01 +00:00
|
|
|
SND_PCI_QUIRK(0x1043, 0x81f2, "ASUS", 0), /* Athlon64 X2 + nvidia */
|
2010-02-15 16:05:28 +00:00
|
|
|
SND_PCI_QUIRK(0x1043, 0x81f6, "ASUS", 0), /* nvidia */
|
2010-03-09 17:25:47 +00:00
|
|
|
SND_PCI_QUIRK(0x1043, 0x822d, "ASUS", 0), /* Athlon64 X2 + nvidia MCP55 */
|
2013-09-09 08:20:48 +00:00
|
|
|
SND_PCI_QUIRK(0x1179, 0xfb44, "Toshiba Satellite C870", 0), /* AMD Hudson */
|
2010-03-06 20:06:46 +00:00
|
|
|
SND_PCI_QUIRK(0x1849, 0x0888, "ASRock", 0), /* Athlon64 X2 + nvidia */
|
2010-04-04 10:14:03 +00:00
|
|
|
SND_PCI_QUIRK(0xa0a0, 0x0575, "Aopen MZ915-M", 0), /* ICH6 */
|
2009-08-11 12:21:26 +00:00
|
|
|
{}
|
|
|
|
};
|
|
|
|
|
2012-12-06 17:35:10 +00:00
|
|
|
static void check_msi(struct azx *chip)
|
2009-08-11 12:21:26 +00:00
|
|
|
{
|
|
|
|
const struct snd_pci_quirk *q;
|
|
|
|
|
2009-09-28 11:14:04 +00:00
|
|
|
if (enable_msi >= 0) {
|
|
|
|
chip->msi = !!enable_msi;
|
2009-08-11 12:21:26 +00:00
|
|
|
return;
|
2009-09-28 11:14:04 +00:00
|
|
|
}
|
|
|
|
chip->msi = 1; /* enable MSI as default */
|
2020-07-14 17:26:27 +00:00
|
|
|
q = snd_pci_quirk_lookup(chip->pci, msi_deny_list);
|
2009-08-11 12:21:26 +00:00
|
|
|
if (q) {
|
2014-02-25 11:21:03 +00:00
|
|
|
dev_info(chip->card->dev,
|
|
|
|
"msi for device %04x:%04x set to %d\n",
|
|
|
|
q->subvendor, q->subdevice, q->value);
|
2009-08-11 12:21:26 +00:00
|
|
|
chip->msi = q->value;
|
2010-03-15 14:51:53 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* NVidia chipsets seem to cause troubles with MSI */
|
2011-05-25 07:11:37 +00:00
|
|
|
if (chip->driver_caps & AZX_DCAPS_NO_MSI) {
|
2014-02-25 11:21:03 +00:00
|
|
|
dev_info(chip->card->dev, "Disabling MSI\n");
|
2010-03-15 14:51:53 +00:00
|
|
|
chip->msi = 0;
|
2009-08-11 12:21:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-12-14 08:27:04 +00:00
|
|
|
/* check the snoop mode availability */
|
2012-12-06 17:35:10 +00:00
|
|
|
static void azx_check_snoop_available(struct azx *chip)
|
2011-12-14 08:27:04 +00:00
|
|
|
{
|
2014-11-25 11:54:16 +00:00
|
|
|
int snoop = hda_snoop;
|
2011-12-14 08:27:04 +00:00
|
|
|
|
2014-11-25 11:54:16 +00:00
|
|
|
if (snoop >= 0) {
|
|
|
|
dev_info(chip->card->dev, "Force to %s mode by module option\n",
|
|
|
|
snoop ? "snoop" : "non-snoop");
|
|
|
|
chip->snoop = snoop;
|
2018-08-11 21:33:34 +00:00
|
|
|
chip->uc_buffer = !snoop;
|
2014-11-25 11:54:16 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
snoop = true;
|
2014-11-25 10:28:07 +00:00
|
|
|
if (azx_get_snoop_type(chip) == AZX_SNOOP_TYPE_NONE &&
|
|
|
|
chip->driver_type == AZX_DRIVER_VIA) {
|
2011-12-14 08:27:04 +00:00
|
|
|
/* force to non-snoop mode for a new VIA controller
|
|
|
|
* when BIOS is set
|
|
|
|
*/
|
2014-11-25 11:54:16 +00:00
|
|
|
u8 val;
|
|
|
|
pci_read_config_byte(chip->pci, 0x42, &val);
|
2018-04-16 09:48:09 +00:00
|
|
|
if (!(val & 0x80) && (chip->pci->revision == 0x30 ||
|
|
|
|
chip->pci->revision == 0x20))
|
2014-11-25 11:54:16 +00:00
|
|
|
snoop = false;
|
2011-12-14 08:27:04 +00:00
|
|
|
}
|
|
|
|
|
2014-11-25 10:28:07 +00:00
|
|
|
if (chip->driver_caps & AZX_DCAPS_SNOOP_OFF)
|
|
|
|
snoop = false;
|
|
|
|
|
2014-11-25 11:54:16 +00:00
|
|
|
chip->snoop = snoop;
|
2018-08-11 21:33:34 +00:00
|
|
|
if (!snoop) {
|
2014-11-25 11:54:16 +00:00
|
|
|
dev_info(chip->card->dev, "Force to non-snoop mode\n");
|
2018-08-11 21:33:34 +00:00
|
|
|
/* C-Media requires non-cached pages only for CORB/RIRB */
|
|
|
|
if (chip->driver_type != AZX_DRIVER_CMEDIA)
|
|
|
|
chip->uc_buffer = true;
|
|
|
|
}
|
2011-12-14 08:27:04 +00:00
|
|
|
}
|
2007-08-17 07:17:36 +00:00
|
|
|
|
2013-05-30 14:07:10 +00:00
|
|
|
static void azx_probe_work(struct work_struct *work)
|
|
|
|
{
|
ALSA: hda: intel: Allow repeatedly probing on codec configuration errors
It seems that a few recent AMD systems show the codec configuration
errors at the early boot, while loading the driver at a later stage
works magically. Although the root cause of the error isn't clear,
it's certainly not bad to allow retrying the codec probe in such a
case if that helps.
This patch adds the capability for retrying the probe upon codec probe
errors on the certain AMD platforms. The probe_work is changed to a
delayed work, and at the secondary call, it'll jump to the codec
probing.
Note that, not only adding the re-probing, this includes the behavior
changes in the codec configuration function. Namely,
snd_hda_codec_configure() won't unregister the codec at errors any
longer. Instead, its caller, azx_codec_configure() unregisters the
codecs with the probe failures *if* any codec has been successfully
configured. If all codec probe failed, it doesn't unregister but let
it re-probed -- which is the most case we're seeing and this patch
tries to improve.
Even if the driver doesn't re-probe or give up, it will go to the
"free-all" error path, hence the leftover codecs shall be disabled /
deleted in anyway.
BugLink: https://bugzilla.suse.com/show_bug.cgi?id=1190801
Link: https://lore.kernel.org/r/20211006141940.2897-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2021-10-06 14:19:40 +00:00
|
|
|
struct hda_intel *hda = container_of(work, struct hda_intel, probe_work.work);
|
2014-06-26 15:19:20 +00:00
|
|
|
azx_probe_continue(&hda->chip);
|
2013-05-30 14:07:10 +00:00
|
|
|
}
|
|
|
|
|
2015-12-10 15:44:08 +00:00
|
|
|
static int default_bdl_pos_adj(struct azx *chip)
|
|
|
|
{
|
ALSA: hda - Increase default bdl_pos_adj for Baytrail/Braswell
Intel Atom processors seem to have a problem at recording when
bdl_pos_adj is set to an odd value. When a value like 1 is used, it
may drop the samples unexpectedly. Actually, for the old Atoms, we
used to set AZX_DRIVER_SCH type, and this assigns 32 as default.
Meanwhile the newer chips, Baytrail and Braswell, are set as
AZX_DRIVER_PCH, and the lower default value, 1, is assigned.
This patch changes the default values for these chipsets to a safer
default, 32, again. Since changing the driver type (AZX_DRIVER_XXX)
leads to the rename of the driver string, it would result in a
possible regression. So, we can't change the type. Instead, in this
patch, manual (ugly) PCI ID checks are added on top.
A drawback by this increase is the slight increase of the latency, but
it's a sub-ms order in normal situations, so mostly negligible.
Reported-and-tested-by: Jochen Henneberg <jh@henneberg-systemdesign.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2015-12-10 15:49:36 +00:00
|
|
|
/* some exceptions: Atoms seem problematic with value 1 */
|
|
|
|
if (chip->pci->vendor == PCI_VENDOR_ID_INTEL) {
|
|
|
|
switch (chip->pci->device) {
|
|
|
|
case 0x0f04: /* Baytrail */
|
|
|
|
case 0x2284: /* Braswell */
|
|
|
|
return 32;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-10 15:44:08 +00:00
|
|
|
switch (chip->driver_type) {
|
|
|
|
case AZX_DRIVER_ICH:
|
|
|
|
case AZX_DRIVER_PCH:
|
|
|
|
return 1;
|
|
|
|
default:
|
|
|
|
return 32;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
/*
|
|
|
|
* constructor
|
|
|
|
*/
|
2015-04-14 15:26:00 +00:00
|
|
|
static const struct hda_controller_ops pci_hda_ops;
|
|
|
|
|
2012-12-06 17:35:10 +00:00
|
|
|
static int azx_create(struct snd_card *card, struct pci_dev *pci,
|
|
|
|
int dev, unsigned int driver_caps,
|
|
|
|
struct azx **rchip)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
2020-01-03 08:16:24 +00:00
|
|
|
static const struct snd_device_ops ops = {
|
2015-04-14 20:13:18 +00:00
|
|
|
.dev_disconnect = azx_dev_disconnect,
|
2005-04-16 22:20:36 +00:00
|
|
|
.dev_free = azx_dev_free,
|
|
|
|
};
|
2014-06-26 10:45:16 +00:00
|
|
|
struct hda_intel *hda;
|
2012-04-26 10:23:42 +00:00
|
|
|
struct azx *chip;
|
|
|
|
int err;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
*rchip = NULL;
|
2008-01-15 10:23:55 +00:00
|
|
|
|
2021-07-15 07:58:29 +00:00
|
|
|
err = pcim_enable_device(pci);
|
2006-08-31 15:03:43 +00:00
|
|
|
if (err < 0)
|
2005-04-16 22:20:36 +00:00
|
|
|
return err;
|
|
|
|
|
ALSA: hda: Release resources at error in delayed probe
snd-hda-intel driver handles the most of its probe task in the delayed
work (either via workqueue or via firmware loader). When an error
happens in the later delayed probe, we can't deregister the device
itself because the probe callback already returned success and the
device was bound. So, for now, we set hda->init_failed flag and make
the rest untouched until the device gets really unbound.
However, this leaves the device up running, keeping the resources
without any use that prevents other operations.
In this patch, we release the resources at first when a probe error
happens in the delayed probe stage, but keeps the top-level object, so
that the PM and other ops can still refer to the object itself.
Also for simplicity, snd_hda_intel object is allocated via devm, so
that we can get rid of the explicit kfree calls.
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=207043
Link: https://lore.kernel.org/r/20200413082034.25166-4-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2020-04-13 08:20:31 +00:00
|
|
|
hda = devm_kzalloc(&pci->dev, sizeof(*hda), GFP_KERNEL);
|
2021-07-15 07:58:29 +00:00
|
|
|
if (!hda)
|
2005-04-16 22:20:36 +00:00
|
|
|
return -ENOMEM;
|
|
|
|
|
2014-06-26 10:45:16 +00:00
|
|
|
chip = &hda->chip;
|
2006-01-16 15:34:20 +00:00
|
|
|
mutex_init(&chip->open_mutex);
|
2005-04-16 22:20:36 +00:00
|
|
|
chip->card = card;
|
|
|
|
chip->pci = pci;
|
2015-04-14 15:26:00 +00:00
|
|
|
chip->ops = &pci_hda_ops;
|
2011-05-25 07:11:37 +00:00
|
|
|
chip->driver_caps = driver_caps;
|
|
|
|
chip->driver_type = driver_caps & 0xff;
|
2009-08-11 12:21:26 +00:00
|
|
|
check_msi(chip);
|
2008-06-10 15:53:34 +00:00
|
|
|
chip->dev_index = dev;
|
2018-08-30 05:58:50 +00:00
|
|
|
if (jackpoll_ms[dev] >= 50 && jackpoll_ms[dev] <= 60000)
|
|
|
|
chip->jackpoll_interval = msecs_to_jiffies(jackpoll_ms[dev]);
|
2011-11-24 13:31:46 +00:00
|
|
|
INIT_LIST_HEAD(&chip->pcm_list);
|
2014-06-26 15:19:20 +00:00
|
|
|
INIT_WORK(&hda->irq_pending_work, azx_irq_pending_work);
|
|
|
|
INIT_LIST_HEAD(&hda->list);
|
2012-04-26 10:23:42 +00:00
|
|
|
init_vga_switcheroo(chip);
|
2014-06-26 15:19:20 +00:00
|
|
|
init_completion(&hda->probe_wait);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2014-06-26 14:50:16 +00:00
|
|
|
assign_position_fix(chip, check_position_fix(chip, position_fix[dev]));
|
2012-02-28 10:58:40 +00:00
|
|
|
|
2017-01-12 16:13:21 +00:00
|
|
|
if (single_cmd < 0) /* allow fallback to single_cmd at errors */
|
|
|
|
chip->fallback_to_single_cmd = 1;
|
|
|
|
else /* explicitly set to single_cmd or not */
|
|
|
|
chip->single_cmd = single_cmd;
|
|
|
|
|
2011-12-14 08:27:04 +00:00
|
|
|
azx_check_snoop_available(chip);
|
2005-05-12 12:26:27 +00:00
|
|
|
|
2015-12-10 15:44:08 +00:00
|
|
|
if (bdl_pos_adj[dev] < 0)
|
|
|
|
chip->bdl_pos_adj = default_bdl_pos_adj(chip);
|
|
|
|
else
|
|
|
|
chip->bdl_pos_adj = bdl_pos_adj[dev];
|
2008-06-10 15:53:35 +00:00
|
|
|
|
2019-08-07 18:32:08 +00:00
|
|
|
err = azx_bus_init(chip, model[dev]);
|
2021-07-15 07:58:29 +00:00
|
|
|
if (err < 0)
|
2015-04-14 20:13:18 +00:00
|
|
|
return err;
|
|
|
|
|
2019-08-07 18:02:31 +00:00
|
|
|
/* use the non-cached pages in non-snoop mode */
|
|
|
|
if (!azx_snoop(chip))
|
2021-08-02 07:28:02 +00:00
|
|
|
azx_bus(chip)->dma_type = SNDRV_DMA_TYPE_DEV_WC;
|
2019-08-07 18:02:31 +00:00
|
|
|
|
2015-12-17 07:23:39 +00:00
|
|
|
if (chip->driver_type == AZX_DRIVER_NVIDIA) {
|
|
|
|
dev_dbg(chip->card->dev, "Enable delay in RIRB handling\n");
|
2019-12-12 19:11:01 +00:00
|
|
|
chip->bus.core.needs_damn_long_delay = 1;
|
2015-12-17 07:23:39 +00:00
|
|
|
}
|
|
|
|
|
2022-02-14 10:00:19 +00:00
|
|
|
check_probe_mask(chip, dev);
|
|
|
|
|
2012-04-26 10:23:42 +00:00
|
|
|
err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
|
|
|
|
if (err < 0) {
|
2014-02-25 11:21:03 +00:00
|
|
|
dev_err(card->dev, "Error creating device [card]!\n");
|
2012-04-26 10:23:42 +00:00
|
|
|
azx_free(chip);
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2013-05-30 14:07:10 +00:00
|
|
|
/* continue probing in work context as may trigger request module */
|
ALSA: hda: intel: Allow repeatedly probing on codec configuration errors
It seems that a few recent AMD systems show the codec configuration
errors at the early boot, while loading the driver at a later stage
works magically. Although the root cause of the error isn't clear,
it's certainly not bad to allow retrying the codec probe in such a
case if that helps.
This patch adds the capability for retrying the probe upon codec probe
errors on the certain AMD platforms. The probe_work is changed to a
delayed work, and at the secondary call, it'll jump to the codec
probing.
Note that, not only adding the re-probing, this includes the behavior
changes in the codec configuration function. Namely,
snd_hda_codec_configure() won't unregister the codec at errors any
longer. Instead, its caller, azx_codec_configure() unregisters the
codecs with the probe failures *if* any codec has been successfully
configured. If all codec probe failed, it doesn't unregister but let
it re-probed -- which is the most case we're seeing and this patch
tries to improve.
Even if the driver doesn't re-probe or give up, it will go to the
"free-all" error path, hence the leftover codecs shall be disabled /
deleted in anyway.
BugLink: https://bugzilla.suse.com/show_bug.cgi?id=1190801
Link: https://lore.kernel.org/r/20211006141940.2897-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2021-10-06 14:19:40 +00:00
|
|
|
INIT_DELAYED_WORK(&hda->probe_work, azx_probe_work);
|
2013-05-30 14:07:10 +00:00
|
|
|
|
2012-04-26 10:23:42 +00:00
|
|
|
*rchip = chip;
|
2013-05-30 14:07:10 +00:00
|
|
|
|
2012-04-26 10:23:42 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-12-07 06:40:35 +00:00
|
|
|
static int azx_first_init(struct azx *chip)
|
2012-04-26 10:23:42 +00:00
|
|
|
{
|
|
|
|
int dev = chip->dev_index;
|
|
|
|
struct pci_dev *pci = chip->pci;
|
|
|
|
struct snd_card *card = chip->card;
|
2015-04-14 20:13:18 +00:00
|
|
|
struct hdac_bus *bus = azx_bus(chip);
|
2014-02-28 23:41:23 +00:00
|
|
|
int err;
|
2012-04-26 10:23:42 +00:00
|
|
|
unsigned short gcap;
|
2014-10-01 08:30:53 +00:00
|
|
|
unsigned int dma_bits = 64;
|
2012-04-26 10:23:42 +00:00
|
|
|
|
2005-08-24 12:14:57 +00:00
|
|
|
#if BITS_PER_LONG != 64
|
|
|
|
/* Fix up base address on ULI M5461 */
|
|
|
|
if (chip->driver_type == AZX_DRIVER_ULI) {
|
|
|
|
u16 tmp3;
|
|
|
|
pci_read_config_word(pci, 0x40, &tmp3);
|
|
|
|
pci_write_config_word(pci, 0x40, tmp3 | 0x10);
|
|
|
|
pci_write_config_dword(pci, PCI_BASE_ADDRESS_1, 0);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2021-07-15 07:58:29 +00:00
|
|
|
err = pcim_iomap_regions(pci, 1 << 0, "ICH HD audio");
|
2012-04-26 10:23:42 +00:00
|
|
|
if (err < 0)
|
2005-04-16 22:20:36 +00:00
|
|
|
return err;
|
|
|
|
|
2015-04-14 20:13:18 +00:00
|
|
|
bus->addr = pci_resource_start(pci, 0);
|
2021-07-15 07:58:29 +00:00
|
|
|
bus->remap_addr = pcim_iomap_table(pci)[0];
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2017-06-14 05:26:00 +00:00
|
|
|
if (chip->driver_type == AZX_DRIVER_SKL)
|
2016-08-04 10:16:03 +00:00
|
|
|
snd_hdac_bus_parse_capabilities(bus);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Some Intel CPUs has always running timer (ART) feature and
|
|
|
|
* controller may have Global time sync reporting capability, so
|
|
|
|
* check both of these before declaring synchronized time reporting
|
|
|
|
* capability SNDRV_PCM_INFO_HAS_LINK_SYNCHRONIZED_ATIME
|
|
|
|
*/
|
|
|
|
chip->gts_present = false;
|
|
|
|
|
|
|
|
#ifdef CONFIG_X86
|
|
|
|
if (bus->ppcap && boot_cpu_has(X86_FEATURE_ART))
|
|
|
|
chip->gts_present = true;
|
|
|
|
#endif
|
|
|
|
|
2014-11-24 03:17:08 +00:00
|
|
|
if (chip->msi) {
|
|
|
|
if (chip->driver_caps & AZX_DCAPS_NO_MSI64) {
|
|
|
|
dev_dbg(card->dev, "Disabling 64bit MSI\n");
|
|
|
|
pci->no_64bit_msi = true;
|
|
|
|
}
|
2006-10-23 11:40:59 +00:00
|
|
|
if (pci_enable_msi(pci) < 0)
|
|
|
|
chip->msi = 0;
|
2014-11-24 03:17:08 +00:00
|
|
|
}
|
2006-08-21 17:17:46 +00:00
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
pci_set_master(pci);
|
|
|
|
|
2008-01-15 10:23:55 +00:00
|
|
|
gcap = azx_readw(chip, GCAP);
|
2014-02-25 11:21:03 +00:00
|
|
|
dev_dbg(card->dev, "chipset global capabilities = 0x%x\n", gcap);
|
2008-01-15 10:23:55 +00:00
|
|
|
|
2014-10-01 08:30:53 +00:00
|
|
|
/* AMD devices support 40 or 48bit DMA, take the safe one */
|
|
|
|
if (chip->pci->vendor == PCI_VENDOR_ID_AMD)
|
|
|
|
dma_bits = 40;
|
|
|
|
|
2009-07-08 05:55:31 +00:00
|
|
|
/* disable SB600 64bit support for safety */
|
2011-05-25 07:11:37 +00:00
|
|
|
if (chip->pci->vendor == PCI_VENDOR_ID_ATI) {
|
2009-07-08 05:55:31 +00:00
|
|
|
struct pci_dev *p_smbus;
|
2014-10-01 08:30:53 +00:00
|
|
|
dma_bits = 40;
|
2009-07-08 05:55:31 +00:00
|
|
|
p_smbus = pci_get_device(PCI_VENDOR_ID_ATI,
|
|
|
|
PCI_DEVICE_ID_ATI_SBX00_SMBUS,
|
|
|
|
NULL);
|
|
|
|
if (p_smbus) {
|
|
|
|
if (p_smbus->revision < 0x30)
|
2014-06-26 15:54:37 +00:00
|
|
|
gcap &= ~AZX_GCAP_64OK;
|
2009-07-08 05:55:31 +00:00
|
|
|
pci_dev_put(p_smbus);
|
|
|
|
}
|
|
|
|
}
|
2009-03-17 06:47:18 +00:00
|
|
|
|
2016-10-17 16:23:59 +00:00
|
|
|
/* NVidia hardware normally only supports up to 40 bits of DMA */
|
|
|
|
if (chip->pci->vendor == PCI_VENDOR_ID_NVIDIA)
|
|
|
|
dma_bits = 40;
|
|
|
|
|
2011-05-25 07:11:37 +00:00
|
|
|
/* disable 64bit DMA address on some devices */
|
|
|
|
if (chip->driver_caps & AZX_DCAPS_NO_64BIT) {
|
2014-02-25 11:21:03 +00:00
|
|
|
dev_dbg(card->dev, "Disabling 64bit DMA\n");
|
2014-06-26 15:54:37 +00:00
|
|
|
gcap &= ~AZX_GCAP_64OK;
|
2011-05-25 07:11:37 +00:00
|
|
|
}
|
2009-12-09 09:44:47 +00:00
|
|
|
|
2011-08-04 15:12:56 +00:00
|
|
|
/* disable buffer size rounding to 128-byte multiples if supported */
|
2012-01-23 16:53:39 +00:00
|
|
|
if (align_buffer_size >= 0)
|
|
|
|
chip->align_buffer_size = !!align_buffer_size;
|
|
|
|
else {
|
2014-12-03 08:56:20 +00:00
|
|
|
if (chip->driver_caps & AZX_DCAPS_NO_ALIGN_BUFSIZE)
|
2012-01-23 16:53:39 +00:00
|
|
|
chip->align_buffer_size = 0;
|
|
|
|
else
|
|
|
|
chip->align_buffer_size = 1;
|
|
|
|
}
|
2011-08-04 15:12:56 +00:00
|
|
|
|
2008-02-06 14:05:57 +00:00
|
|
|
/* allow 64bit DMA address if supported by H/W */
|
2014-10-01 08:30:53 +00:00
|
|
|
if (!(gcap & AZX_GCAP_64OK))
|
|
|
|
dma_bits = 32;
|
2021-01-14 12:54:11 +00:00
|
|
|
if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(dma_bits)))
|
|
|
|
dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(32));
|
2022-02-15 13:27:54 +00:00
|
|
|
dma_set_max_seg_size(&pci->dev, UINT_MAX);
|
2008-02-06 14:05:57 +00:00
|
|
|
|
2008-02-19 10:36:35 +00:00
|
|
|
/* read number of streams from GCAP register instead of using
|
|
|
|
* hardcoded value
|
|
|
|
*/
|
|
|
|
chip->capture_streams = (gcap >> 8) & 0x0f;
|
|
|
|
chip->playback_streams = (gcap >> 12) & 0x0f;
|
|
|
|
if (!chip->playback_streams && !chip->capture_streams) {
|
2008-01-15 10:23:55 +00:00
|
|
|
/* gcap didn't give any info, switching to old method */
|
|
|
|
|
|
|
|
switch (chip->driver_type) {
|
|
|
|
case AZX_DRIVER_ULI:
|
|
|
|
chip->playback_streams = ULI_NUM_PLAYBACK;
|
|
|
|
chip->capture_streams = ULI_NUM_CAPTURE;
|
|
|
|
break;
|
|
|
|
case AZX_DRIVER_ATIHDMI:
|
2011-12-14 08:10:27 +00:00
|
|
|
case AZX_DRIVER_ATIHDMI_NS:
|
2008-01-15 10:23:55 +00:00
|
|
|
chip->playback_streams = ATIHDMI_NUM_PLAYBACK;
|
|
|
|
chip->capture_streams = ATIHDMI_NUM_CAPTURE;
|
|
|
|
break;
|
2008-11-13 10:07:07 +00:00
|
|
|
case AZX_DRIVER_GENERIC:
|
2008-01-15 10:23:55 +00:00
|
|
|
default:
|
|
|
|
chip->playback_streams = ICH6_NUM_PLAYBACK;
|
|
|
|
chip->capture_streams = ICH6_NUM_CAPTURE;
|
|
|
|
break;
|
|
|
|
}
|
2005-08-24 12:14:57 +00:00
|
|
|
}
|
2008-02-19 10:36:35 +00:00
|
|
|
chip->capture_index_offset = 0;
|
|
|
|
chip->playback_index_offset = chip->capture_streams;
|
2005-08-24 12:14:57 +00:00
|
|
|
chip->num_streams = chip->playback_streams + chip->capture_streams;
|
|
|
|
|
2017-02-15 16:09:43 +00:00
|
|
|
/* sanity check for the SDxCTL.STRM field overflow */
|
|
|
|
if (chip->num_streams > 15 &&
|
|
|
|
(chip->driver_caps & AZX_DCAPS_SEPARATE_STREAM_TAG) == 0) {
|
|
|
|
dev_warn(chip->card->dev, "number of I/O streams is %d, "
|
|
|
|
"forcing separate stream tags", chip->num_streams);
|
|
|
|
chip->driver_caps |= AZX_DCAPS_SEPARATE_STREAM_TAG;
|
|
|
|
}
|
|
|
|
|
2015-04-14 20:13:18 +00:00
|
|
|
/* initialize streams */
|
|
|
|
err = azx_init_streams(chip);
|
2009-05-26 13:22:00 +00:00
|
|
|
if (err < 0)
|
2012-04-26 10:23:42 +00:00
|
|
|
return err;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2015-04-14 20:13:18 +00:00
|
|
|
err = azx_alloc_stream_pages(chip);
|
|
|
|
if (err < 0)
|
|
|
|
return err;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
/* initialize chip */
|
2007-08-10 15:21:45 +00:00
|
|
|
azx_init_pci(chip);
|
2014-07-03 09:02:23 +00:00
|
|
|
|
2018-12-09 08:57:37 +00:00
|
|
|
snd_hdac_i915_set_bclk(bus);
|
2014-07-03 09:02:23 +00:00
|
|
|
|
2015-05-05 01:05:48 +00:00
|
|
|
hda_intel_init_chip(chip, (probe_only[dev] & 2) == 0);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
/* codec detection */
|
2015-04-14 20:13:18 +00:00
|
|
|
if (!azx_bus(chip)->codec_mask) {
|
2014-02-25 11:21:03 +00:00
|
|
|
dev_err(card->dev, "no codecs found!\n");
|
2020-04-13 08:20:32 +00:00
|
|
|
/* keep running the rest for the runtime PM */
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
ALSA: hda - Register irq handler after the chip initialization
Currently the IRQ handler in HD-audio controller driver is registered
before the chip initialization. That is, we have some window opened
between the azx_acquire_irq() call and the CORB/RIRB setup. If an
interrupt is triggered in this small window, the IRQ handler may
access to the uninitialized RIRB buffer, which leads to a NULL
dereference Oops.
This is usually no big problem since most of Intel chips do register
the IRQ via MSI, and we've already fixed the order of the IRQ
enablement and the CORB/RIRB setup in the former commit b61749a89f82
("sound: enable interrupt after dma buffer initialization"), hence the
IRQ won't be triggered in that room. However, some platforms use a
shared IRQ, and this may allow the IRQ trigger by another source.
Another possibility is the kdump environment: a stale interrupt might
be present in there, the IRQ handler can be falsely triggered as well.
For covering this small race, let's move the azx_acquire_irq() call
after hda_intel_init_chip() call. Although this is a bit radical
change, it can cover more widely than checking the CORB/RIRB setup
locally in the callee side.
Reported-by: Liwei Song <liwei.song@windriver.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2019-04-30 10:18:28 +00:00
|
|
|
if (azx_acquire_irq(chip, 0) < 0)
|
|
|
|
return -EBUSY;
|
|
|
|
|
2005-08-24 12:14:57 +00:00
|
|
|
strcpy(card->driver, "HDA-Intel");
|
ALSA: Convert strlcpy to strscpy when return value is unused
strlcpy is deprecated. see: Documentation/process/deprecated.rst
Change the calls that do not use the strlcpy return value to the
preferred strscpy.
Done with cocci script:
@@
expression e1, e2, e3;
@@
- strlcpy(
+ strscpy(
e1, e2, e3);
This cocci script leaves the instances where the return value is
used unchanged.
After this patch, sound/ has 3 uses of strlcpy() that need to be
manually inspected for conversion and changed one day.
$ git grep -w strlcpy sound/
sound/usb/card.c: len = strlcpy(card->longname, s, sizeof(card->longname));
sound/usb/mixer.c: return strlcpy(buf, p->name, buflen);
sound/usb/mixer.c: return strlcpy(buf, p->names[index], buflen);
Miscellenea:
o Remove trailing whitespace in conversion of sound/core/hwdep.c
Link: https://lore.kernel.org/lkml/CAHk-=wgfRnXz0W3D37d01q3JFkr_i_uTL=V6A6G1oUZcprmknw@mail.gmail.com/
Signed-off-by: Joe Perches <joe@perches.com>
Acked-by: Mark Brown <broonie@kernel.org>
Link: https://lore.kernel.org/r/22b393d1790bb268769d0bab7bacf0866dcb0c14.camel@perches.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2021-01-04 17:17:34 +00:00
|
|
|
strscpy(card->shortname, driver_short_names[chip->driver_type],
|
2009-04-16 08:22:24 +00:00
|
|
|
sizeof(card->shortname));
|
|
|
|
snprintf(card->longname, sizeof(card->longname),
|
|
|
|
"%s at 0x%lx irq %i",
|
2015-04-14 20:13:18 +00:00
|
|
|
card->shortname, bus->addr, bus->irq);
|
2005-08-24 12:14:57 +00:00
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-08-09 15:40:46 +00:00
|
|
|
#ifdef CONFIG_SND_HDA_PATCH_LOADER
|
2012-08-09 11:49:23 +00:00
|
|
|
/* callback from request_firmware_nowait() */
|
|
|
|
static void azx_firmware_cb(const struct firmware *fw, void *context)
|
|
|
|
{
|
|
|
|
struct snd_card *card = context;
|
|
|
|
struct azx *chip = card->private_data;
|
|
|
|
|
2020-04-13 08:20:29 +00:00
|
|
|
if (fw)
|
|
|
|
chip->fw = fw;
|
|
|
|
else
|
|
|
|
dev_err(card->dev, "Cannot load firmware, continue without patching\n");
|
2012-08-09 11:49:23 +00:00
|
|
|
if (!chip->disabled) {
|
|
|
|
/* continue probing */
|
2020-04-13 08:20:29 +00:00
|
|
|
azx_probe_continue(chip);
|
2012-08-09 11:49:23 +00:00
|
|
|
}
|
|
|
|
}
|
2012-08-09 15:40:46 +00:00
|
|
|
#endif
|
2012-08-09 11:49:23 +00:00
|
|
|
|
2014-02-28 23:41:16 +00:00
|
|
|
static int disable_msi_reset_irq(struct azx *chip)
|
|
|
|
{
|
2015-04-14 20:13:18 +00:00
|
|
|
struct hdac_bus *bus = azx_bus(chip);
|
2014-02-28 23:41:16 +00:00
|
|
|
int err;
|
|
|
|
|
2015-04-14 20:13:18 +00:00
|
|
|
free_irq(bus->irq, chip);
|
|
|
|
bus->irq = -1;
|
2019-12-10 06:34:20 +00:00
|
|
|
chip->card->sync_irq = -1;
|
2014-02-28 23:41:16 +00:00
|
|
|
pci_disable_msi(chip->pci);
|
|
|
|
chip->msi = 0;
|
|
|
|
err = azx_acquire_irq(chip, 1);
|
|
|
|
if (err < 0)
|
|
|
|
return err;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-07-14 17:26:27 +00:00
|
|
|
/* Denylist for skipping the whole probe:
|
2020-04-08 14:04:49 +00:00
|
|
|
* some HD-audio PCI entries are exposed without any codecs, and such devices
|
|
|
|
* should be ignored from the beginning.
|
|
|
|
*/
|
2020-07-14 17:26:27 +00:00
|
|
|
static const struct pci_device_id driver_denylist[] = {
|
2020-04-24 06:12:22 +00:00
|
|
|
{ PCI_DEVICE_SUB(0x1022, 0x1487, 0x1043, 0x874f) }, /* ASUS ROG Zenith II / Strix */
|
|
|
|
{ PCI_DEVICE_SUB(0x1022, 0x1487, 0x1462, 0xcb59) }, /* MSI TRX40 Creator */
|
|
|
|
{ PCI_DEVICE_SUB(0x1022, 0x1487, 0x1462, 0xcb60) }, /* MSI TRX40 */
|
2020-04-08 14:04:49 +00:00
|
|
|
{}
|
|
|
|
};
|
|
|
|
|
2015-04-14 15:26:00 +00:00
|
|
|
static const struct hda_controller_ops pci_hda_ops = {
|
|
|
|
.disable_msi_reset_irq = disable_msi_reset_irq,
|
2014-02-28 23:41:28 +00:00
|
|
|
.position_check = azx_position_check,
|
2014-02-28 23:41:13 +00:00
|
|
|
};
|
|
|
|
|
2022-02-09 08:19:12 +00:00
|
|
|
static DECLARE_BITMAP(probed_devs, SNDRV_CARDS);
|
|
|
|
|
2012-12-06 17:35:10 +00:00
|
|
|
static int azx_probe(struct pci_dev *pci,
|
|
|
|
const struct pci_device_id *pci_id)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
2005-11-17 13:59:02 +00:00
|
|
|
struct snd_card *card;
|
2014-06-26 15:19:20 +00:00
|
|
|
struct hda_intel *hda;
|
2005-11-17 13:59:02 +00:00
|
|
|
struct azx *chip;
|
2013-12-02 12:33:57 +00:00
|
|
|
bool schedule_probe;
|
2022-02-09 08:19:12 +00:00
|
|
|
int dev;
|
2006-08-31 15:03:43 +00:00
|
|
|
int err;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2020-07-14 17:26:27 +00:00
|
|
|
if (pci_match_id(driver_denylist, pci)) {
|
|
|
|
dev_info(&pci->dev, "Skipping the device on the denylist\n");
|
2020-04-08 14:04:49 +00:00
|
|
|
return -ENODEV;
|
|
|
|
}
|
|
|
|
|
2022-02-09 08:19:12 +00:00
|
|
|
dev = find_first_zero_bit(probed_devs, SNDRV_CARDS);
|
2008-01-07 14:16:37 +00:00
|
|
|
if (dev >= SNDRV_CARDS)
|
|
|
|
return -ENODEV;
|
|
|
|
if (!enable[dev]) {
|
2022-02-09 08:19:12 +00:00
|
|
|
set_bit(dev, probed_devs);
|
2008-01-07 14:16:37 +00:00
|
|
|
return -ENOENT;
|
|
|
|
}
|
|
|
|
|
2019-10-22 17:43:12 +00:00
|
|
|
/*
|
|
|
|
* stop probe if another Intel's DSP driver should be activated
|
|
|
|
*/
|
2020-01-09 08:20:00 +00:00
|
|
|
if (dmic_detect) {
|
2019-10-22 17:43:12 +00:00
|
|
|
err = snd_intel_dsp_driver_probe(pci);
|
2020-09-02 15:42:39 +00:00
|
|
|
if (err != SND_INTEL_DSP_DRIVER_ANY && err != SND_INTEL_DSP_DRIVER_LEGACY) {
|
|
|
|
dev_dbg(&pci->dev, "HDAudio driver not selected, aborting probe\n");
|
2019-10-22 17:43:12 +00:00
|
|
|
return -ENODEV;
|
2020-09-02 15:42:39 +00:00
|
|
|
}
|
2020-01-09 08:20:00 +00:00
|
|
|
} else {
|
|
|
|
dev_warn(&pci->dev, "dmic_detect option is deprecated, pass snd-intel-dspcfg.dsp_driver=1 option instead\n");
|
2019-10-22 17:43:12 +00:00
|
|
|
}
|
|
|
|
|
2014-01-29 13:20:19 +00:00
|
|
|
err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
|
|
|
|
0, &card);
|
2008-12-28 15:44:30 +00:00
|
|
|
if (err < 0) {
|
2014-02-25 11:21:03 +00:00
|
|
|
dev_err(&pci->dev, "Error creating card!\n");
|
2008-12-28 15:44:30 +00:00
|
|
|
return err;
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
2015-04-14 15:26:00 +00:00
|
|
|
err = azx_create(card, pci, dev, pci_id->driver_data, &chip);
|
2008-11-20 01:24:52 +00:00
|
|
|
if (err < 0)
|
|
|
|
goto out_free;
|
2005-11-17 15:11:09 +00:00
|
|
|
card->private_data = chip;
|
2014-06-26 15:19:20 +00:00
|
|
|
hda = container_of(chip, struct hda_intel, chip);
|
2012-12-04 14:09:23 +00:00
|
|
|
|
|
|
|
pci_set_drvdata(pci, card);
|
|
|
|
|
|
|
|
err = register_vga_switcheroo(chip);
|
|
|
|
if (err < 0) {
|
2015-09-04 18:49:36 +00:00
|
|
|
dev_err(card->dev, "Error registering vga_switcheroo client\n");
|
2012-12-04 14:09:23 +00:00
|
|
|
goto out_free;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (check_hdmi_disabled(pci)) {
|
2014-02-25 11:21:03 +00:00
|
|
|
dev_info(card->dev, "VGA controller is disabled\n");
|
|
|
|
dev_info(card->dev, "Delaying initialization\n");
|
2012-12-04 14:09:23 +00:00
|
|
|
chip->disabled = true;
|
|
|
|
}
|
|
|
|
|
2013-12-02 12:33:57 +00:00
|
|
|
schedule_probe = !chip->disabled;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2012-08-09 10:33:28 +00:00
|
|
|
#ifdef CONFIG_SND_HDA_PATCH_LOADER
|
|
|
|
if (patch[dev] && *patch[dev]) {
|
2014-02-25 11:21:03 +00:00
|
|
|
dev_info(card->dev, "Applying patch firmware '%s'\n",
|
|
|
|
patch[dev]);
|
2012-08-09 11:49:23 +00:00
|
|
|
err = request_firmware_nowait(THIS_MODULE, true, patch[dev],
|
|
|
|
&pci->dev, GFP_KERNEL, card,
|
|
|
|
azx_firmware_cb);
|
2012-08-09 10:33:28 +00:00
|
|
|
if (err < 0)
|
|
|
|
goto out_free;
|
2013-12-02 12:33:57 +00:00
|
|
|
schedule_probe = false; /* continued in azx_firmware_cb() */
|
2012-08-09 10:33:28 +00:00
|
|
|
}
|
|
|
|
#endif /* CONFIG_SND_HDA_PATCH_LOADER */
|
|
|
|
|
2013-12-02 12:33:57 +00:00
|
|
|
#ifndef CONFIG_SND_HDA_I915
|
2015-12-09 06:13:48 +00:00
|
|
|
if (CONTROLLER_IN_GPU(pci))
|
|
|
|
dev_err(card->dev, "Haswell/Broadwell HDMI/DP must build in CONFIG_SND_HDA_I915\n");
|
2013-05-30 14:07:10 +00:00
|
|
|
#endif
|
|
|
|
|
2013-12-02 12:33:57 +00:00
|
|
|
if (schedule_probe)
|
ALSA: hda: intel: Allow repeatedly probing on codec configuration errors
It seems that a few recent AMD systems show the codec configuration
errors at the early boot, while loading the driver at a later stage
works magically. Although the root cause of the error isn't clear,
it's certainly not bad to allow retrying the codec probe in such a
case if that helps.
This patch adds the capability for retrying the probe upon codec probe
errors on the certain AMD platforms. The probe_work is changed to a
delayed work, and at the secondary call, it'll jump to the codec
probing.
Note that, not only adding the re-probing, this includes the behavior
changes in the codec configuration function. Namely,
snd_hda_codec_configure() won't unregister the codec at errors any
longer. Instead, its caller, azx_codec_configure() unregisters the
codecs with the probe failures *if* any codec has been successfully
configured. If all codec probe failed, it doesn't unregister but let
it re-probed -- which is the most case we're seeing and this patch
tries to improve.
Even if the driver doesn't re-probe or give up, it will go to the
"free-all" error path, hence the leftover codecs shall be disabled /
deleted in anyway.
BugLink: https://bugzilla.suse.com/show_bug.cgi?id=1190801
Link: https://lore.kernel.org/r/20211006141940.2897-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2021-10-06 14:19:40 +00:00
|
|
|
schedule_delayed_work(&hda->probe_work, 0);
|
2012-04-26 10:23:42 +00:00
|
|
|
|
2022-02-09 08:19:12 +00:00
|
|
|
set_bit(dev, probed_devs);
|
2013-12-02 10:12:28 +00:00
|
|
|
if (chip->disabled)
|
2014-06-26 15:19:20 +00:00
|
|
|
complete_all(&hda->probe_wait);
|
2012-04-26 10:23:42 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
out_free:
|
|
|
|
snd_card_free(card);
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2018-02-22 13:20:35 +00:00
|
|
|
#ifdef CONFIG_PM
|
|
|
|
/* On some boards setting power_save to a non 0 value leads to clicking /
|
|
|
|
* popping sounds when ever we enter/leave powersaving mode. Ideally we would
|
|
|
|
* figure out how to avoid these sounds, but that is not always feasible.
|
|
|
|
* So we keep a list of devices where we disable powersaving as its known
|
|
|
|
* to causes problems on these devices.
|
|
|
|
*/
|
2020-07-14 17:26:27 +00:00
|
|
|
static const struct snd_pci_quirk power_save_denylist[] = {
|
2018-02-22 13:20:35 +00:00
|
|
|
/* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */
|
2018-08-02 12:04:45 +00:00
|
|
|
SND_PCI_QUIRK(0x1849, 0xc892, "Asrock B85M-ITX", 0),
|
2018-02-22 13:20:35 +00:00
|
|
|
/* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */
|
2018-11-22 11:38:12 +00:00
|
|
|
SND_PCI_QUIRK(0x1849, 0x0397, "Asrock N68C-S UCC", 0),
|
|
|
|
/* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */
|
2018-05-23 13:27:05 +00:00
|
|
|
SND_PCI_QUIRK(0x1849, 0x7662, "Asrock H81M-HDS", 0),
|
|
|
|
/* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */
|
2018-02-22 13:20:35 +00:00
|
|
|
SND_PCI_QUIRK(0x1043, 0x8733, "Asus Prime X370-Pro", 0),
|
2018-05-23 13:27:04 +00:00
|
|
|
/* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */
|
2018-10-16 10:18:21 +00:00
|
|
|
SND_PCI_QUIRK(0x1028, 0x0497, "Dell Precision T3600", 0),
|
|
|
|
/* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */
|
2018-05-23 13:27:04 +00:00
|
|
|
/* Note the P55A-UD3 and Z87-D3HP share the subsys id for the HDA dev */
|
|
|
|
SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P55A-UD3 / Z87-D3HP", 0),
|
2018-10-16 10:18:21 +00:00
|
|
|
/* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */
|
|
|
|
SND_PCI_QUIRK(0x8086, 0x2040, "Intel DZ77BH-55K", 0),
|
2018-05-13 13:48:13 +00:00
|
|
|
/* https://bugzilla.kernel.org/show_bug.cgi?id=199607 */
|
|
|
|
SND_PCI_QUIRK(0x8086, 0x2057, "Intel NUC5i7RYB", 0),
|
2019-04-08 07:58:11 +00:00
|
|
|
/* https://bugs.launchpad.net/bugs/1821663 */
|
|
|
|
SND_PCI_QUIRK(0x8086, 0x2064, "Intel SDP 8086:2064", 0),
|
2018-05-23 13:27:02 +00:00
|
|
|
/* https://bugzilla.redhat.com/show_bug.cgi?id=1520902 */
|
|
|
|
SND_PCI_QUIRK(0x8086, 0x2068, "Intel NUC7i3BNB", 0),
|
2018-02-22 13:20:35 +00:00
|
|
|
/* https://bugzilla.kernel.org/show_bug.cgi?id=198611 */
|
|
|
|
SND_PCI_QUIRK(0x17aa, 0x2227, "Lenovo X1 Carbon 3rd Gen", 0),
|
2019-03-18 12:45:43 +00:00
|
|
|
/* https://bugzilla.redhat.com/show_bug.cgi?id=1689623 */
|
|
|
|
SND_PCI_QUIRK(0x17aa, 0x367b, "Lenovo IdeaCentre B550", 0),
|
|
|
|
/* https://bugzilla.redhat.com/show_bug.cgi?id=1572975 */
|
|
|
|
SND_PCI_QUIRK(0x17aa, 0x36a7, "Lenovo C50 All in one", 0),
|
2019-04-08 07:58:11 +00:00
|
|
|
/* https://bugs.launchpad.net/bugs/1821663 */
|
|
|
|
SND_PCI_QUIRK(0x1631, 0xe017, "Packard Bell NEC IMEDIA 5204", 0),
|
2018-02-22 13:20:35 +00:00
|
|
|
{}
|
|
|
|
};
|
|
|
|
#endif /* CONFIG_PM */
|
|
|
|
|
ALSA: hda - Enable runtime PM only for discrete GPU
The recent change of vga_switcheroo allowed the runtime PM for
HD-audio on AMD GPUs, but this also resulted in a regression. When
the HD-audio controller driver gets runtime-suspended, HD-audio link
is turned off, and the hotplug notification is ignored. This leads to
the inconsistent audio state (the connection isn't notified and ELD is
ignored).
The best fix would be to implement the proper ELD notification via the
audio component, but it's still not ready. As a quick workaround,
this patch adds the check of runtime_idle and allows the runtime
suspend only when the vga_switcheroo is bound with discrete GPU.
That is, a system with a single GPU and APU would be again without
runtime PM to keep the HD-audio link for the hotplug notification and
ELD read out.
Also, the codec->auto_runtime_pm flag is set only for the discrete GPU
at the time GPU gets bound via vga_switcheroo (i.e. only dGPU is
forcibly runtime-PM enabled), so that APU can still get the ELD
notification.
For identifying which GPU is bound, a new vga_switcheroo client
callback, gpu_bound, is implemented. The vga_switcheroo simply calls
this when GPU is bound, and tells whether it's dGPU or APU.
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=200945
Fixes: 07f4f97d7b4b ("vga_switcheroo: Use device link for HDA controller")
Reported-by: Jian-Hong Pan <jian-hong@endlessm.com>
Tested-by: Jian-Hong Pan <jian-hong@endlessm.com>
Acked-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2018-09-10 14:20:25 +00:00
|
|
|
static void set_default_power_save(struct azx *chip)
|
|
|
|
{
|
|
|
|
int val = power_save;
|
|
|
|
|
|
|
|
#ifdef CONFIG_PM
|
|
|
|
if (pm_blacklist) {
|
|
|
|
const struct snd_pci_quirk *q;
|
|
|
|
|
2020-07-14 17:26:27 +00:00
|
|
|
q = snd_pci_quirk_lookup(chip->pci, power_save_denylist);
|
ALSA: hda - Enable runtime PM only for discrete GPU
The recent change of vga_switcheroo allowed the runtime PM for
HD-audio on AMD GPUs, but this also resulted in a regression. When
the HD-audio controller driver gets runtime-suspended, HD-audio link
is turned off, and the hotplug notification is ignored. This leads to
the inconsistent audio state (the connection isn't notified and ELD is
ignored).
The best fix would be to implement the proper ELD notification via the
audio component, but it's still not ready. As a quick workaround,
this patch adds the check of runtime_idle and allows the runtime
suspend only when the vga_switcheroo is bound with discrete GPU.
That is, a system with a single GPU and APU would be again without
runtime PM to keep the HD-audio link for the hotplug notification and
ELD read out.
Also, the codec->auto_runtime_pm flag is set only for the discrete GPU
at the time GPU gets bound via vga_switcheroo (i.e. only dGPU is
forcibly runtime-PM enabled), so that APU can still get the ELD
notification.
For identifying which GPU is bound, a new vga_switcheroo client
callback, gpu_bound, is implemented. The vga_switcheroo simply calls
this when GPU is bound, and tells whether it's dGPU or APU.
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=200945
Fixes: 07f4f97d7b4b ("vga_switcheroo: Use device link for HDA controller")
Reported-by: Jian-Hong Pan <jian-hong@endlessm.com>
Tested-by: Jian-Hong Pan <jian-hong@endlessm.com>
Acked-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2018-09-10 14:20:25 +00:00
|
|
|
if (q && val) {
|
2020-07-14 17:26:27 +00:00
|
|
|
dev_info(chip->card->dev, "device %04x:%04x is on the power_save denylist, forcing power_save to 0\n",
|
ALSA: hda - Enable runtime PM only for discrete GPU
The recent change of vga_switcheroo allowed the runtime PM for
HD-audio on AMD GPUs, but this also resulted in a regression. When
the HD-audio controller driver gets runtime-suspended, HD-audio link
is turned off, and the hotplug notification is ignored. This leads to
the inconsistent audio state (the connection isn't notified and ELD is
ignored).
The best fix would be to implement the proper ELD notification via the
audio component, but it's still not ready. As a quick workaround,
this patch adds the check of runtime_idle and allows the runtime
suspend only when the vga_switcheroo is bound with discrete GPU.
That is, a system with a single GPU and APU would be again without
runtime PM to keep the HD-audio link for the hotplug notification and
ELD read out.
Also, the codec->auto_runtime_pm flag is set only for the discrete GPU
at the time GPU gets bound via vga_switcheroo (i.e. only dGPU is
forcibly runtime-PM enabled), so that APU can still get the ELD
notification.
For identifying which GPU is bound, a new vga_switcheroo client
callback, gpu_bound, is implemented. The vga_switcheroo simply calls
this when GPU is bound, and tells whether it's dGPU or APU.
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=200945
Fixes: 07f4f97d7b4b ("vga_switcheroo: Use device link for HDA controller")
Reported-by: Jian-Hong Pan <jian-hong@endlessm.com>
Tested-by: Jian-Hong Pan <jian-hong@endlessm.com>
Acked-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2018-09-10 14:20:25 +00:00
|
|
|
q->subvendor, q->subdevice);
|
|
|
|
val = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif /* CONFIG_PM */
|
|
|
|
snd_hda_set_power_save(&chip->bus, val * 1000);
|
|
|
|
}
|
|
|
|
|
2014-02-28 23:41:19 +00:00
|
|
|
/* number of codec slots for each chipset: 0 = default slots (i.e. 4) */
|
2020-01-05 14:47:24 +00:00
|
|
|
static const unsigned int azx_max_codecs[AZX_NUM_DRIVERS] = {
|
2014-02-28 23:41:19 +00:00
|
|
|
[AZX_DRIVER_NVIDIA] = 8,
|
|
|
|
[AZX_DRIVER_TERA] = 1,
|
|
|
|
};
|
|
|
|
|
2012-12-07 06:40:35 +00:00
|
|
|
static int azx_probe_continue(struct azx *chip)
|
2012-04-26 10:23:42 +00:00
|
|
|
{
|
2014-06-26 15:19:20 +00:00
|
|
|
struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
|
2015-05-19 14:29:30 +00:00
|
|
|
struct hdac_bus *bus = azx_bus(chip);
|
2013-05-30 14:07:08 +00:00
|
|
|
struct pci_dev *pci = chip->pci;
|
2012-04-26 10:23:42 +00:00
|
|
|
int dev = chip->dev_index;
|
|
|
|
int err;
|
|
|
|
|
ALSA: hda: intel: Allow repeatedly probing on codec configuration errors
It seems that a few recent AMD systems show the codec configuration
errors at the early boot, while loading the driver at a later stage
works magically. Although the root cause of the error isn't clear,
it's certainly not bad to allow retrying the codec probe in such a
case if that helps.
This patch adds the capability for retrying the probe upon codec probe
errors on the certain AMD platforms. The probe_work is changed to a
delayed work, and at the secondary call, it'll jump to the codec
probing.
Note that, not only adding the re-probing, this includes the behavior
changes in the codec configuration function. Namely,
snd_hda_codec_configure() won't unregister the codec at errors any
longer. Instead, its caller, azx_codec_configure() unregisters the
codecs with the probe failures *if* any codec has been successfully
configured. If all codec probe failed, it doesn't unregister but let
it re-probed -- which is the most case we're seeing and this patch
tries to improve.
Even if the driver doesn't re-probe or give up, it will go to the
"free-all" error path, hence the leftover codecs shall be disabled /
deleted in anyway.
BugLink: https://bugzilla.suse.com/show_bug.cgi?id=1190801
Link: https://lore.kernel.org/r/20211006141940.2897-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2021-10-06 14:19:40 +00:00
|
|
|
if (chip->disabled || hda->init_failed)
|
|
|
|
return -EIO;
|
|
|
|
if (hda->probe_retry)
|
|
|
|
goto probe_retry;
|
|
|
|
|
2019-01-30 16:46:03 +00:00
|
|
|
to_hda_bus(bus)->bus_probing = 1;
|
2015-04-14 20:13:18 +00:00
|
|
|
hda->probe_continued = 1;
|
2015-04-29 09:43:36 +00:00
|
|
|
|
2017-06-28 10:54:53 +00:00
|
|
|
/* bind with i915 if needed */
|
2017-06-29 14:18:12 +00:00
|
|
|
if (chip->driver_caps & AZX_DCAPS_I915_COMPONENT) {
|
2015-05-19 14:29:30 +00:00
|
|
|
err = snd_hdac_i915_init(bus);
|
2015-06-12 05:53:58 +00:00
|
|
|
if (err < 0) {
|
|
|
|
/* if the controller is bound only with HDMI/DP
|
|
|
|
* (for HSW and BDW), we need to abort the probe;
|
|
|
|
* for other chips, still continue probing as other
|
|
|
|
* codecs can be on the same link.
|
|
|
|
*/
|
2016-01-20 14:00:26 +00:00
|
|
|
if (CONTROLLER_IN_GPU(pci)) {
|
|
|
|
dev_err(chip->card->dev,
|
|
|
|
"HSW/BDW HD-audio HDMI/DP requires binding with gfx driver\n");
|
2015-06-12 05:53:58 +00:00
|
|
|
goto out_free;
|
2017-06-28 10:54:53 +00:00
|
|
|
} else {
|
|
|
|
/* don't bother any longer */
|
2018-12-09 08:57:37 +00:00
|
|
|
chip->driver_caps &= ~AZX_DCAPS_I915_COMPONENT;
|
2017-06-28 10:54:53 +00:00
|
|
|
}
|
2015-06-12 05:53:58 +00:00
|
|
|
}
|
2018-12-09 08:57:37 +00:00
|
|
|
|
|
|
|
/* HSW/BDW controllers need this power */
|
|
|
|
if (CONTROLLER_IN_GPU(pci))
|
2021-01-25 07:17:27 +00:00
|
|
|
hda->need_i915_power = true;
|
2017-06-28 10:54:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Request display power well for the HDA controller or codec. For
|
|
|
|
* Haswell/Broadwell, both the display HDA controller and codec need
|
|
|
|
* this power. For other platforms, like Baytrail/Braswell, only the
|
|
|
|
* display codec needs the power and it can be released after probe.
|
|
|
|
*/
|
2018-12-09 09:04:25 +00:00
|
|
|
display_power(chip, true);
|
2013-05-30 14:07:10 +00:00
|
|
|
|
2013-05-30 14:07:09 +00:00
|
|
|
err = azx_first_init(chip);
|
|
|
|
if (err < 0)
|
|
|
|
goto out_free;
|
|
|
|
|
2009-11-13 17:41:52 +00:00
|
|
|
#ifdef CONFIG_SND_HDA_INPUT_BEEP
|
|
|
|
chip->beep_mode = beep_mode[dev];
|
|
|
|
#endif
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
/* create codec instances */
|
2020-04-13 08:20:32 +00:00
|
|
|
if (bus->codec_mask) {
|
|
|
|
err = azx_probe_codecs(chip, azx_max_codecs[chip->driver_type]);
|
|
|
|
if (err < 0)
|
|
|
|
goto out_free;
|
|
|
|
}
|
2015-02-19 17:12:22 +00:00
|
|
|
|
2009-06-17 07:52:54 +00:00
|
|
|
#ifdef CONFIG_SND_HDA_PATCH_LOADER
|
2012-08-09 10:33:28 +00:00
|
|
|
if (chip->fw) {
|
2015-04-14 20:13:18 +00:00
|
|
|
err = snd_hda_load_patch(&chip->bus, chip->fw->size,
|
2012-08-09 10:33:28 +00:00
|
|
|
chip->fw->data);
|
2009-06-17 07:52:54 +00:00
|
|
|
if (err < 0)
|
|
|
|
goto out_free;
|
2012-11-22 15:18:13 +00:00
|
|
|
#ifndef CONFIG_PM
|
2012-08-09 10:33:28 +00:00
|
|
|
release_firmware(chip->fw); /* no longer needed */
|
|
|
|
chip->fw = NULL;
|
2012-11-22 15:18:13 +00:00
|
|
|
#endif
|
2009-06-17 07:52:54 +00:00
|
|
|
}
|
|
|
|
#endif
|
ALSA: hda: intel: Allow repeatedly probing on codec configuration errors
It seems that a few recent AMD systems show the codec configuration
errors at the early boot, while loading the driver at a later stage
works magically. Although the root cause of the error isn't clear,
it's certainly not bad to allow retrying the codec probe in such a
case if that helps.
This patch adds the capability for retrying the probe upon codec probe
errors on the certain AMD platforms. The probe_work is changed to a
delayed work, and at the secondary call, it'll jump to the codec
probing.
Note that, not only adding the re-probing, this includes the behavior
changes in the codec configuration function. Namely,
snd_hda_codec_configure() won't unregister the codec at errors any
longer. Instead, its caller, azx_codec_configure() unregisters the
codecs with the probe failures *if* any codec has been successfully
configured. If all codec probe failed, it doesn't unregister but let
it re-probed -- which is the most case we're seeing and this patch
tries to improve.
Even if the driver doesn't re-probe or give up, it will go to the
"free-all" error path, hence the leftover codecs shall be disabled /
deleted in anyway.
BugLink: https://bugzilla.suse.com/show_bug.cgi?id=1190801
Link: https://lore.kernel.org/r/20211006141940.2897-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2021-10-06 14:19:40 +00:00
|
|
|
|
|
|
|
probe_retry:
|
2020-04-13 08:20:32 +00:00
|
|
|
if (bus->codec_mask && !(probe_only[dev] & 1)) {
|
2009-06-17 07:33:52 +00:00
|
|
|
err = azx_codec_configure(chip);
|
ALSA: hda: intel: Allow repeatedly probing on codec configuration errors
It seems that a few recent AMD systems show the codec configuration
errors at the early boot, while loading the driver at a later stage
works magically. Although the root cause of the error isn't clear,
it's certainly not bad to allow retrying the codec probe in such a
case if that helps.
This patch adds the capability for retrying the probe upon codec probe
errors on the certain AMD platforms. The probe_work is changed to a
delayed work, and at the secondary call, it'll jump to the codec
probing.
Note that, not only adding the re-probing, this includes the behavior
changes in the codec configuration function. Namely,
snd_hda_codec_configure() won't unregister the codec at errors any
longer. Instead, its caller, azx_codec_configure() unregisters the
codecs with the probe failures *if* any codec has been successfully
configured. If all codec probe failed, it doesn't unregister but let
it re-probed -- which is the most case we're seeing and this patch
tries to improve.
Even if the driver doesn't re-probe or give up, it will go to the
"free-all" error path, hence the leftover codecs shall be disabled /
deleted in anyway.
BugLink: https://bugzilla.suse.com/show_bug.cgi?id=1190801
Link: https://lore.kernel.org/r/20211006141940.2897-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2021-10-06 14:19:40 +00:00
|
|
|
if (err) {
|
|
|
|
if ((chip->driver_caps & AZX_DCAPS_RETRY_PROBE) &&
|
|
|
|
++hda->probe_retry < 60) {
|
|
|
|
schedule_delayed_work(&hda->probe_work,
|
|
|
|
msecs_to_jiffies(1000));
|
|
|
|
return 0; /* keep things up */
|
|
|
|
}
|
|
|
|
dev_err(chip->card->dev, "Cannot probe codecs, giving up\n");
|
2009-06-17 07:33:52 +00:00
|
|
|
goto out_free;
|
ALSA: hda: intel: Allow repeatedly probing on codec configuration errors
It seems that a few recent AMD systems show the codec configuration
errors at the early boot, while loading the driver at a later stage
works magically. Although the root cause of the error isn't clear,
it's certainly not bad to allow retrying the codec probe in such a
case if that helps.
This patch adds the capability for retrying the probe upon codec probe
errors on the certain AMD platforms. The probe_work is changed to a
delayed work, and at the secondary call, it'll jump to the codec
probing.
Note that, not only adding the re-probing, this includes the behavior
changes in the codec configuration function. Namely,
snd_hda_codec_configure() won't unregister the codec at errors any
longer. Instead, its caller, azx_codec_configure() unregisters the
codecs with the probe failures *if* any codec has been successfully
configured. If all codec probe failed, it doesn't unregister but let
it re-probed -- which is the most case we're seeing and this patch
tries to improve.
Even if the driver doesn't re-probe or give up, it will go to the
"free-all" error path, hence the leftover codecs shall be disabled /
deleted in anyway.
BugLink: https://bugzilla.suse.com/show_bug.cgi?id=1190801
Link: https://lore.kernel.org/r/20211006141940.2897-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2021-10-06 14:19:40 +00:00
|
|
|
}
|
2009-06-17 07:33:52 +00:00
|
|
|
}
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2012-04-26 10:23:42 +00:00
|
|
|
err = snd_card_register(chip->card);
|
2008-11-20 01:24:52 +00:00
|
|
|
if (err < 0)
|
|
|
|
goto out_free;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
ALSA: hda - Enable runtime PM only for discrete GPU
The recent change of vga_switcheroo allowed the runtime PM for
HD-audio on AMD GPUs, but this also resulted in a regression. When
the HD-audio controller driver gets runtime-suspended, HD-audio link
is turned off, and the hotplug notification is ignored. This leads to
the inconsistent audio state (the connection isn't notified and ELD is
ignored).
The best fix would be to implement the proper ELD notification via the
audio component, but it's still not ready. As a quick workaround,
this patch adds the check of runtime_idle and allows the runtime
suspend only when the vga_switcheroo is bound with discrete GPU.
That is, a system with a single GPU and APU would be again without
runtime PM to keep the HD-audio link for the hotplug notification and
ELD read out.
Also, the codec->auto_runtime_pm flag is set only for the discrete GPU
at the time GPU gets bound via vga_switcheroo (i.e. only dGPU is
forcibly runtime-PM enabled), so that APU can still get the ELD
notification.
For identifying which GPU is bound, a new vga_switcheroo client
callback, gpu_bound, is implemented. The vga_switcheroo simply calls
this when GPU is bound, and tells whether it's dGPU or APU.
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=200945
Fixes: 07f4f97d7b4b ("vga_switcheroo: Use device link for HDA controller")
Reported-by: Jian-Hong Pan <jian-hong@endlessm.com>
Tested-by: Jian-Hong Pan <jian-hong@endlessm.com>
Acked-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2018-09-10 14:20:25 +00:00
|
|
|
setup_vga_switcheroo_runtime_pm(chip);
|
|
|
|
|
2007-08-10 15:21:45 +00:00
|
|
|
chip->running = 1;
|
2012-08-14 15:13:32 +00:00
|
|
|
azx_add_card_list(chip);
|
vga_switcheroo: Use device link for HDA controller
Back in 2013, runtime PM for GPUs with integrated HDA controller was
introduced with commits 0d69704ae348 ("gpu/vga_switcheroo: add driver
control power feature. (v3)") and 246efa4a072f ("snd/hda: add runtime
suspend/resume on optimus support (v4)").
Briefly, the idea was that the HDA controller is forced on and off in
unison with the GPU.
The original code is mostly still in place even though it was never a
100% perfect solution: E.g. on access to the HDA controller, the GPU
is powered up via vga_switcheroo_runtime_resume_hdmi_audio() but there
are no provisions to keep it resumed until access to the HDA controller
has ceased: The GPU autosuspends after 5 seconds, rendering the HDA
controller inaccessible.
Additionally, a kludge is required when hda_intel.c probes: It has to
check whether the GPU is powered down (check_hdmi_disabled()) and defer
probing if so.
However in the meantime (in v4.10) the driver core has gained a feature
called device links which promises to solve such issues in a clean way:
It allows us to declare a dependency from the HDA controller (consumer)
to the GPU (supplier). The PM core then automagically ensures that the
GPU is runtime resumed as long as the HDA controller's ->probe hook is
executed and whenever the HDA controller is accessed.
By default, the HDA controller has a dependency on its parent, a PCIe
Root Port. Adding a device link creates another dependency on its
sibling:
PCIe Root Port
^ ^
| |
| |
HDA ===> GPU
The device link is not only used for runtime PM, it also guarantees that
on system sleep, the HDA controller suspends before the GPU and resumes
after the GPU, and on system shutdown the HDA controller's ->shutdown
hook is executed before the one of the GPU. It is a complete solution.
Using this functionality is as simple as calling device_link_add(),
which results in a dmesg entry like this:
pci 0000:01:00.1: Linked as a consumer to 0000:01:00.0
The code for the GPU-governed audio power management can thus be removed
(except where it's still needed for legacy manual power control).
The device link is added in a PCI quirk rather than in hda_intel.c.
It is therefore legal for the GPU to runtime suspend to D3cold even if
the HDA controller is not bound to a driver or if CONFIG_SND_HDA_INTEL
is not enabled, for accesses to the HDA controller will cause the GPU to
wake up regardless if they're occurring outside of hda_intel.c (think
config space readout via sysfs).
Contrary to the previous implementation, the HDA controller's power
state is now self-governed, rather than GPU-governed, whereas the GPU's
power state is no longer fully self-governed. (The HDA controller needs
to runtime suspend before the GPU can.)
It is thus crucial that runtime PM is always activated on the HDA
controller even if CONFIG_SND_HDA_POWER_SAVE_DEFAULT is set to 0 (which
is the default), lest the GPU stays awake. This is achieved by setting
the auto_runtime_pm flag on every codec and the AZX_DCAPS_PM_RUNTIME
flag on the HDA controller.
A side effect is that power consumption might be reduced if the GPU is
in use but the HDA controller is not, because the HDA controller is now
allowed to go to D3hot. Before, it was forced to stay in D0 as long as
the GPU was in use. (There is no reduction in power consumption on my
Nvidia GK107, but there might be on other chips.)
The code paths for legacy manual power control are adjusted such that
runtime PM is disabled during power off, thereby preventing the PM core
from resuming the HDA controller.
Note that the device link is not only added on vga_switcheroo capable
systems, but for *any* GPU with integrated HDA controller. The idea is
that the HDA controller streams audio via connectors located on the GPU,
so the GPU needs to be on for the HDA controller to do anything useful.
This commit implicitly fixes an unbalanced runtime PM ref upon unbind of
hda_intel.c: On ->probe, a runtime PM ref was previously released under
the condition "azx_has_pm_runtime(chip) || hda->use_vga_switcheroo", but
on ->remove a runtime PM ref was only acquired under the first of those
conditions. Thus, binding and unbinding the driver twice on a
vga_switcheroo capable system caused the runtime PM refcount to drop
below zero. The issue is resolved because the AZX_DCAPS_PM_RUNTIME flag
is now always set if use_vga_switcheroo is true.
For more information on device links please refer to:
https://www.kernel.org/doc/html/latest/driver-api/device_link.html
Documentation/driver-api/device_link.rst
Cc: Dave Airlie <airlied@redhat.com>
Cc: Ben Skeggs <bskeggs@redhat.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Takashi Iwai <tiwai@suse.de>
Reviewed-by: Peter Wu <peter@lekensteyn.nl>
Tested-by: Kai Heng Feng <kai.heng.feng@canonical.com> # AMD PowerXpress
Tested-by: Mike Lothian <mike@fireburn.co.uk> # AMD PowerXpress
Tested-by: Denis Lisov <dennis.lissov@gmail.com> # Nvidia Optimus
Tested-by: Peter Wu <peter@lekensteyn.nl> # Nvidia Optimus
Tested-by: Lukas Wunner <lukas@wunner.de> # MacBook Pro
Signed-off-by: Lukas Wunner <lukas@wunner.de>
Link: https://patchwork.freedesktop.org/patch/msgid/51bd38360ff502a8c42b1ebf4405ee1d3f27118d.1520068884.git.lukas@wunner.de
2018-03-03 09:53:24 +00:00
|
|
|
|
ALSA: hda - Enable runtime PM only for discrete GPU
The recent change of vga_switcheroo allowed the runtime PM for
HD-audio on AMD GPUs, but this also resulted in a regression. When
the HD-audio controller driver gets runtime-suspended, HD-audio link
is turned off, and the hotplug notification is ignored. This leads to
the inconsistent audio state (the connection isn't notified and ELD is
ignored).
The best fix would be to implement the proper ELD notification via the
audio component, but it's still not ready. As a quick workaround,
this patch adds the check of runtime_idle and allows the runtime
suspend only when the vga_switcheroo is bound with discrete GPU.
That is, a system with a single GPU and APU would be again without
runtime PM to keep the HD-audio link for the hotplug notification and
ELD read out.
Also, the codec->auto_runtime_pm flag is set only for the discrete GPU
at the time GPU gets bound via vga_switcheroo (i.e. only dGPU is
forcibly runtime-PM enabled), so that APU can still get the ELD
notification.
For identifying which GPU is bound, a new vga_switcheroo client
callback, gpu_bound, is implemented. The vga_switcheroo simply calls
this when GPU is bound, and tells whether it's dGPU or APU.
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=200945
Fixes: 07f4f97d7b4b ("vga_switcheroo: Use device link for HDA controller")
Reported-by: Jian-Hong Pan <jian-hong@endlessm.com>
Tested-by: Jian-Hong Pan <jian-hong@endlessm.com>
Acked-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2018-09-10 14:20:25 +00:00
|
|
|
set_default_power_save(chip);
|
vga_switcheroo: Use device link for HDA controller
Back in 2013, runtime PM for GPUs with integrated HDA controller was
introduced with commits 0d69704ae348 ("gpu/vga_switcheroo: add driver
control power feature. (v3)") and 246efa4a072f ("snd/hda: add runtime
suspend/resume on optimus support (v4)").
Briefly, the idea was that the HDA controller is forced on and off in
unison with the GPU.
The original code is mostly still in place even though it was never a
100% perfect solution: E.g. on access to the HDA controller, the GPU
is powered up via vga_switcheroo_runtime_resume_hdmi_audio() but there
are no provisions to keep it resumed until access to the HDA controller
has ceased: The GPU autosuspends after 5 seconds, rendering the HDA
controller inaccessible.
Additionally, a kludge is required when hda_intel.c probes: It has to
check whether the GPU is powered down (check_hdmi_disabled()) and defer
probing if so.
However in the meantime (in v4.10) the driver core has gained a feature
called device links which promises to solve such issues in a clean way:
It allows us to declare a dependency from the HDA controller (consumer)
to the GPU (supplier). The PM core then automagically ensures that the
GPU is runtime resumed as long as the HDA controller's ->probe hook is
executed and whenever the HDA controller is accessed.
By default, the HDA controller has a dependency on its parent, a PCIe
Root Port. Adding a device link creates another dependency on its
sibling:
PCIe Root Port
^ ^
| |
| |
HDA ===> GPU
The device link is not only used for runtime PM, it also guarantees that
on system sleep, the HDA controller suspends before the GPU and resumes
after the GPU, and on system shutdown the HDA controller's ->shutdown
hook is executed before the one of the GPU. It is a complete solution.
Using this functionality is as simple as calling device_link_add(),
which results in a dmesg entry like this:
pci 0000:01:00.1: Linked as a consumer to 0000:01:00.0
The code for the GPU-governed audio power management can thus be removed
(except where it's still needed for legacy manual power control).
The device link is added in a PCI quirk rather than in hda_intel.c.
It is therefore legal for the GPU to runtime suspend to D3cold even if
the HDA controller is not bound to a driver or if CONFIG_SND_HDA_INTEL
is not enabled, for accesses to the HDA controller will cause the GPU to
wake up regardless if they're occurring outside of hda_intel.c (think
config space readout via sysfs).
Contrary to the previous implementation, the HDA controller's power
state is now self-governed, rather than GPU-governed, whereas the GPU's
power state is no longer fully self-governed. (The HDA controller needs
to runtime suspend before the GPU can.)
It is thus crucial that runtime PM is always activated on the HDA
controller even if CONFIG_SND_HDA_POWER_SAVE_DEFAULT is set to 0 (which
is the default), lest the GPU stays awake. This is achieved by setting
the auto_runtime_pm flag on every codec and the AZX_DCAPS_PM_RUNTIME
flag on the HDA controller.
A side effect is that power consumption might be reduced if the GPU is
in use but the HDA controller is not, because the HDA controller is now
allowed to go to D3hot. Before, it was forced to stay in D0 as long as
the GPU was in use. (There is no reduction in power consumption on my
Nvidia GK107, but there might be on other chips.)
The code paths for legacy manual power control are adjusted such that
runtime PM is disabled during power off, thereby preventing the PM core
from resuming the HDA controller.
Note that the device link is not only added on vga_switcheroo capable
systems, but for *any* GPU with integrated HDA controller. The idea is
that the HDA controller streams audio via connectors located on the GPU,
so the GPU needs to be on for the HDA controller to do anything useful.
This commit implicitly fixes an unbalanced runtime PM ref upon unbind of
hda_intel.c: On ->probe, a runtime PM ref was previously released under
the condition "azx_has_pm_runtime(chip) || hda->use_vga_switcheroo", but
on ->remove a runtime PM ref was only acquired under the first of those
conditions. Thus, binding and unbinding the driver twice on a
vga_switcheroo capable system caused the runtime PM refcount to drop
below zero. The issue is resolved because the AZX_DCAPS_PM_RUNTIME flag
is now always set if use_vga_switcheroo is true.
For more information on device links please refer to:
https://www.kernel.org/doc/html/latest/driver-api/device_link.html
Documentation/driver-api/device_link.rst
Cc: Dave Airlie <airlied@redhat.com>
Cc: Ben Skeggs <bskeggs@redhat.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Takashi Iwai <tiwai@suse.de>
Reviewed-by: Peter Wu <peter@lekensteyn.nl>
Tested-by: Kai Heng Feng <kai.heng.feng@canonical.com> # AMD PowerXpress
Tested-by: Mike Lothian <mike@fireburn.co.uk> # AMD PowerXpress
Tested-by: Denis Lisov <dennis.lissov@gmail.com> # Nvidia Optimus
Tested-by: Peter Wu <peter@lekensteyn.nl> # Nvidia Optimus
Tested-by: Lukas Wunner <lukas@wunner.de> # MacBook Pro
Signed-off-by: Lukas Wunner <lukas@wunner.de>
Link: https://patchwork.freedesktop.org/patch/msgid/51bd38360ff502a8c42b1ebf4405ee1d3f27118d.1520068884.git.lukas@wunner.de
2018-03-03 09:53:24 +00:00
|
|
|
|
2020-04-13 08:20:34 +00:00
|
|
|
if (azx_has_pm_runtime(chip)) {
|
|
|
|
pm_runtime_use_autosuspend(&pci->dev);
|
2020-10-27 13:00:38 +00:00
|
|
|
pm_runtime_allow(&pci->dev);
|
2016-02-26 17:39:57 +00:00
|
|
|
pm_runtime_put_autosuspend(&pci->dev);
|
2020-04-13 08:20:34 +00:00
|
|
|
}
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2008-11-20 01:24:52 +00:00
|
|
|
out_free:
|
ALSA: hda: Release resources at error in delayed probe
snd-hda-intel driver handles the most of its probe task in the delayed
work (either via workqueue or via firmware loader). When an error
happens in the later delayed probe, we can't deregister the device
itself because the probe callback already returned success and the
device was bound. So, for now, we set hda->init_failed flag and make
the rest untouched until the device gets really unbound.
However, this leaves the device up running, keeping the resources
without any use that prevents other operations.
In this patch, we release the resources at first when a probe error
happens in the delayed probe stage, but keeps the top-level object, so
that the PM and other ops can still refer to the object itself.
Also for simplicity, snd_hda_intel object is allocated via devm, so
that we can get rid of the explicit kfree calls.
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=207043
Link: https://lore.kernel.org/r/20200413082034.25166-4-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2020-04-13 08:20:31 +00:00
|
|
|
if (err < 0) {
|
2021-11-10 19:46:33 +00:00
|
|
|
pci_set_drvdata(pci, NULL);
|
|
|
|
snd_card_free(chip->card);
|
ALSA: hda: Release resources at error in delayed probe
snd-hda-intel driver handles the most of its probe task in the delayed
work (either via workqueue or via firmware loader). When an error
happens in the later delayed probe, we can't deregister the device
itself because the probe callback already returned success and the
device was bound. So, for now, we set hda->init_failed flag and make
the rest untouched until the device gets really unbound.
However, this leaves the device up running, keeping the resources
without any use that prevents other operations.
In this patch, we release the resources at first when a probe error
happens in the delayed probe stage, but keeps the top-level object, so
that the PM and other ops can still refer to the object itself.
Also for simplicity, snd_hda_intel object is allocated via devm, so
that we can get rid of the explicit kfree calls.
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=207043
Link: https://lore.kernel.org/r/20200413082034.25166-4-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2020-04-13 08:20:31 +00:00
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!hda->need_i915_power)
|
2018-12-08 16:31:49 +00:00
|
|
|
display_power(chip, false);
|
2014-06-26 15:19:20 +00:00
|
|
|
complete_all(&hda->probe_wait);
|
2019-01-30 16:46:03 +00:00
|
|
|
to_hda_bus(bus)->bus_probing = 0;
|
ALSA: hda: intel: Allow repeatedly probing on codec configuration errors
It seems that a few recent AMD systems show the codec configuration
errors at the early boot, while loading the driver at a later stage
works magically. Although the root cause of the error isn't clear,
it's certainly not bad to allow retrying the codec probe in such a
case if that helps.
This patch adds the capability for retrying the probe upon codec probe
errors on the certain AMD platforms. The probe_work is changed to a
delayed work, and at the secondary call, it'll jump to the codec
probing.
Note that, not only adding the re-probing, this includes the behavior
changes in the codec configuration function. Namely,
snd_hda_codec_configure() won't unregister the codec at errors any
longer. Instead, its caller, azx_codec_configure() unregisters the
codecs with the probe failures *if* any codec has been successfully
configured. If all codec probe failed, it doesn't unregister but let
it re-probed -- which is the most case we're seeing and this patch
tries to improve.
Even if the driver doesn't re-probe or give up, it will go to the
"free-all" error path, hence the leftover codecs shall be disabled /
deleted in anyway.
BugLink: https://bugzilla.suse.com/show_bug.cgi?id=1190801
Link: https://lore.kernel.org/r/20211006141940.2897-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2021-10-06 14:19:40 +00:00
|
|
|
hda->probe_retry = 0;
|
ALSA: hda: Release resources at error in delayed probe
snd-hda-intel driver handles the most of its probe task in the delayed
work (either via workqueue or via firmware loader). When an error
happens in the later delayed probe, we can't deregister the device
itself because the probe callback already returned success and the
device was bound. So, for now, we set hda->init_failed flag and make
the rest untouched until the device gets really unbound.
However, this leaves the device up running, keeping the resources
without any use that prevents other operations.
In this patch, we release the resources at first when a probe error
happens in the delayed probe stage, but keeps the top-level object, so
that the PM and other ops can still refer to the object itself.
Also for simplicity, snd_hda_intel object is allocated via devm, so
that we can get rid of the explicit kfree calls.
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=207043
Link: https://lore.kernel.org/r/20200413082034.25166-4-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2020-04-13 08:20:31 +00:00
|
|
|
return 0;
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
2012-12-06 17:35:10 +00:00
|
|
|
static void azx_remove(struct pci_dev *pci)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
2012-04-26 10:13:25 +00:00
|
|
|
struct snd_card *card = pci_get_drvdata(pci);
|
2016-01-20 16:19:02 +00:00
|
|
|
struct azx *chip;
|
|
|
|
struct hda_intel *hda;
|
|
|
|
|
|
|
|
if (card) {
|
2016-02-15 15:37:24 +00:00
|
|
|
/* cancel the pending probing work */
|
2016-01-20 16:19:02 +00:00
|
|
|
chip = card->private_data;
|
|
|
|
hda = container_of(chip, struct hda_intel, chip);
|
2017-01-02 10:37:04 +00:00
|
|
|
/* FIXME: below is an ugly workaround.
|
|
|
|
* Both device_release_driver() and driver_probe_device()
|
|
|
|
* take *both* the device's and its parent's lock before
|
|
|
|
* calling the remove() and probe() callbacks. The codec
|
|
|
|
* probe takes the locks of both the codec itself and its
|
|
|
|
* parent, i.e. the PCI controller dev. Meanwhile, when
|
|
|
|
* the PCI controller is unbound, it takes its lock, too
|
|
|
|
* ==> ouch, a deadlock!
|
|
|
|
* As a workaround, we unlock temporarily here the controller
|
|
|
|
* device during cancel_work_sync() call.
|
|
|
|
*/
|
|
|
|
device_unlock(&pci->dev);
|
ALSA: hda: intel: Allow repeatedly probing on codec configuration errors
It seems that a few recent AMD systems show the codec configuration
errors at the early boot, while loading the driver at a later stage
works magically. Although the root cause of the error isn't clear,
it's certainly not bad to allow retrying the codec probe in such a
case if that helps.
This patch adds the capability for retrying the probe upon codec probe
errors on the certain AMD platforms. The probe_work is changed to a
delayed work, and at the secondary call, it'll jump to the codec
probing.
Note that, not only adding the re-probing, this includes the behavior
changes in the codec configuration function. Namely,
snd_hda_codec_configure() won't unregister the codec at errors any
longer. Instead, its caller, azx_codec_configure() unregisters the
codecs with the probe failures *if* any codec has been successfully
configured. If all codec probe failed, it doesn't unregister but let
it re-probed -- which is the most case we're seeing and this patch
tries to improve.
Even if the driver doesn't re-probe or give up, it will go to the
"free-all" error path, hence the leftover codecs shall be disabled /
deleted in anyway.
BugLink: https://bugzilla.suse.com/show_bug.cgi?id=1190801
Link: https://lore.kernel.org/r/20211006141940.2897-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2021-10-06 14:19:40 +00:00
|
|
|
cancel_delayed_work_sync(&hda->probe_work);
|
2017-01-02 10:37:04 +00:00
|
|
|
device_lock(&pci->dev);
|
2012-08-23 09:32:30 +00:00
|
|
|
|
2022-02-09 08:19:12 +00:00
|
|
|
clear_bit(chip->dev_index, probed_devs);
|
2021-11-10 21:03:07 +00:00
|
|
|
pci_set_drvdata(pci, NULL);
|
2012-04-26 10:13:25 +00:00
|
|
|
snd_card_free(card);
|
2016-01-20 16:19:02 +00:00
|
|
|
}
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
2015-03-05 16:21:32 +00:00
|
|
|
static void azx_shutdown(struct pci_dev *pci)
|
|
|
|
{
|
|
|
|
struct snd_card *card = pci_get_drvdata(pci);
|
|
|
|
struct azx *chip;
|
|
|
|
|
|
|
|
if (!card)
|
|
|
|
return;
|
|
|
|
chip = card->private_data;
|
|
|
|
if (chip && chip->running)
|
2021-09-13 12:43:30 +00:00
|
|
|
__azx_shutdown_chip(chip, true);
|
2015-03-05 16:21:32 +00:00
|
|
|
}
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
/* PCI IDs */
|
2014-05-22 15:08:54 +00:00
|
|
|
static const struct pci_device_id azx_ids[] = {
|
2010-01-13 01:03:35 +00:00
|
|
|
/* CPT */
|
2011-05-25 07:11:37 +00:00
|
|
|
{ PCI_DEVICE(0x8086, 0x1c20),
|
2013-01-08 12:51:30 +00:00
|
|
|
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM },
|
2010-09-10 23:29:56 +00:00
|
|
|
/* PBG */
|
2011-05-25 07:11:37 +00:00
|
|
|
{ PCI_DEVICE(0x8086, 0x1d20),
|
2013-01-08 12:51:30 +00:00
|
|
|
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM },
|
2011-04-20 17:59:57 +00:00
|
|
|
/* Panther Point */
|
2011-05-25 07:11:37 +00:00
|
|
|
{ PCI_DEVICE(0x8086, 0x1e20),
|
2015-02-25 06:53:31 +00:00
|
|
|
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM },
|
2012-01-24 00:24:31 +00:00
|
|
|
/* Lynx Point */
|
|
|
|
{ PCI_DEVICE(0x8086, 0x8c20),
|
2012-11-19 19:03:37 +00:00
|
|
|
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
|
2014-05-23 07:02:44 +00:00
|
|
|
/* 9 Series */
|
|
|
|
{ PCI_DEVICE(0x8086, 0x8ca0),
|
|
|
|
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
|
2013-02-09 01:29:40 +00:00
|
|
|
/* Wellsburg */
|
|
|
|
{ PCI_DEVICE(0x8086, 0x8d20),
|
|
|
|
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
|
|
|
|
{ PCI_DEVICE(0x8086, 0x8d21),
|
|
|
|
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
|
2015-11-04 23:56:09 +00:00
|
|
|
/* Lewisburg */
|
|
|
|
{ PCI_DEVICE(0x8086, 0xa1f0),
|
2017-02-15 16:09:42 +00:00
|
|
|
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE },
|
2015-11-04 23:56:09 +00:00
|
|
|
{ PCI_DEVICE(0x8086, 0xa270),
|
2017-02-15 16:09:42 +00:00
|
|
|
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE },
|
2012-08-09 16:38:59 +00:00
|
|
|
/* Lynx Point-LP */
|
|
|
|
{ PCI_DEVICE(0x8086, 0x9c20),
|
2012-11-19 19:03:37 +00:00
|
|
|
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
|
2012-08-09 16:38:59 +00:00
|
|
|
/* Lynx Point-LP */
|
|
|
|
{ PCI_DEVICE(0x8086, 0x9c21),
|
2012-11-19 19:03:37 +00:00
|
|
|
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
|
2013-11-04 17:27:45 +00:00
|
|
|
/* Wildcat Point-LP */
|
|
|
|
{ PCI_DEVICE(0x8086, 0x9ca0),
|
|
|
|
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
|
2014-10-13 22:22:03 +00:00
|
|
|
/* Sunrise Point */
|
|
|
|
{ PCI_DEVICE(0x8086, 0xa170),
|
2017-06-14 05:26:00 +00:00
|
|
|
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE },
|
2014-11-07 23:02:47 +00:00
|
|
|
/* Sunrise Point-LP */
|
|
|
|
{ PCI_DEVICE(0x8086, 0x9d70),
|
2018-12-31 18:02:01 +00:00
|
|
|
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE },
|
2016-06-09 06:02:14 +00:00
|
|
|
/* Kabylake */
|
|
|
|
{ PCI_DEVICE(0x8086, 0xa171),
|
2017-06-14 05:26:00 +00:00
|
|
|
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE },
|
2016-06-09 06:02:14 +00:00
|
|
|
/* Kabylake-LP */
|
|
|
|
{ PCI_DEVICE(0x8086, 0x9d71),
|
2018-12-31 18:02:01 +00:00
|
|
|
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE },
|
2016-06-29 04:57:52 +00:00
|
|
|
/* Kabylake-H */
|
|
|
|
{ PCI_DEVICE(0x8086, 0xa2f0),
|
2017-06-14 05:26:00 +00:00
|
|
|
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE },
|
2017-06-14 04:21:56 +00:00
|
|
|
/* Coffelake */
|
|
|
|
{ PCI_DEVICE(0x8086, 0xa348),
|
2018-12-31 18:02:01 +00:00
|
|
|
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
|
2017-08-05 08:35:46 +00:00
|
|
|
/* Cannonlake */
|
|
|
|
{ PCI_DEVICE(0x8086, 0x9dc8),
|
2018-12-31 18:02:01 +00:00
|
|
|
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
|
2019-05-07 20:25:00 +00:00
|
|
|
/* CometLake-LP */
|
|
|
|
{ PCI_DEVICE(0x8086, 0x02C8),
|
|
|
|
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
|
|
|
|
/* CometLake-H */
|
|
|
|
{ PCI_DEVICE(0x8086, 0x06C8),
|
|
|
|
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
|
2021-02-12 15:10:22 +00:00
|
|
|
{ PCI_DEVICE(0x8086, 0xf1c8),
|
|
|
|
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
|
2019-11-08 07:13:49 +00:00
|
|
|
/* CometLake-S */
|
|
|
|
{ PCI_DEVICE(0x8086, 0xa3f0),
|
|
|
|
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
|
2021-01-15 03:15:15 +00:00
|
|
|
/* CometLake-R */
|
|
|
|
{ PCI_DEVICE(0x8086, 0xf0c8),
|
|
|
|
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
|
2018-03-13 11:10:08 +00:00
|
|
|
/* Icelake */
|
|
|
|
{ PCI_DEVICE(0x8086, 0x34c8),
|
2018-12-31 18:02:01 +00:00
|
|
|
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
|
2020-06-17 16:49:09 +00:00
|
|
|
/* Icelake-H */
|
|
|
|
{ PCI_DEVICE(0x8086, 0x3dc8),
|
|
|
|
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
|
2019-10-22 19:44:02 +00:00
|
|
|
/* Jasperlake */
|
|
|
|
{ PCI_DEVICE(0x8086, 0x38c8),
|
|
|
|
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
|
2020-01-31 20:40:03 +00:00
|
|
|
{ PCI_DEVICE(0x8086, 0x4dc8),
|
|
|
|
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
|
2019-10-22 19:44:02 +00:00
|
|
|
/* Tigerlake */
|
|
|
|
{ PCI_DEVICE(0x8086, 0xa0c8),
|
|
|
|
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
|
2020-06-17 16:49:09 +00:00
|
|
|
/* Tigerlake-H */
|
|
|
|
{ PCI_DEVICE(0x8086, 0x43c8),
|
|
|
|
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
|
2020-09-21 14:17:38 +00:00
|
|
|
/* DG1 */
|
|
|
|
{ PCI_DEVICE(0x8086, 0x490d),
|
|
|
|
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
|
2021-11-30 12:47:31 +00:00
|
|
|
/* DG2 */
|
|
|
|
{ PCI_DEVICE(0x8086, 0x4f90),
|
|
|
|
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
|
|
|
|
{ PCI_DEVICE(0x8086, 0x4f91),
|
|
|
|
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
|
|
|
|
{ PCI_DEVICE(0x8086, 0x4f92),
|
|
|
|
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
|
2020-11-16 14:19:55 +00:00
|
|
|
/* Alderlake-S */
|
|
|
|
{ PCI_DEVICE(0x8086, 0x7ad0),
|
|
|
|
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
|
2021-01-13 15:56:29 +00:00
|
|
|
/* Alderlake-P */
|
|
|
|
{ PCI_DEVICE(0x8086, 0x51c8),
|
|
|
|
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
|
2022-03-08 14:13:22 +00:00
|
|
|
{ PCI_DEVICE(0x8086, 0x51c9),
|
|
|
|
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
|
2021-12-23 07:34:24 +00:00
|
|
|
{ PCI_DEVICE(0x8086, 0x51cd),
|
|
|
|
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
|
2021-05-28 18:51:23 +00:00
|
|
|
/* Alderlake-M */
|
|
|
|
{ PCI_DEVICE(0x8086, 0x51cc),
|
|
|
|
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
|
2021-12-23 07:34:23 +00:00
|
|
|
/* Alderlake-N */
|
|
|
|
{ PCI_DEVICE(0x8086, 0x54c8),
|
|
|
|
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
|
2019-06-13 16:21:39 +00:00
|
|
|
/* Elkhart Lake */
|
|
|
|
{ PCI_DEVICE(0x8086, 0x4b55),
|
|
|
|
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
|
2020-06-17 16:49:09 +00:00
|
|
|
{ PCI_DEVICE(0x8086, 0x4b58),
|
|
|
|
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
|
2022-02-10 18:54:23 +00:00
|
|
|
/* Raptor Lake */
|
|
|
|
{ PCI_DEVICE(0x8086, 0x7a50),
|
|
|
|
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
|
|
|
|
{ PCI_DEVICE(0x8086, 0x51ca),
|
|
|
|
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
|
|
|
|
{ PCI_DEVICE(0x8086, 0x51cb),
|
|
|
|
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
|
|
|
|
{ PCI_DEVICE(0x8086, 0x51ce),
|
|
|
|
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
|
|
|
|
{ PCI_DEVICE(0x8086, 0x51cf),
|
|
|
|
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
|
2022-06-06 20:42:32 +00:00
|
|
|
/* Meteorlake-P */
|
|
|
|
{ PCI_DEVICE(0x8086, 0x7e28),
|
|
|
|
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
|
2015-11-19 15:25:12 +00:00
|
|
|
/* Broxton-P(Apollolake) */
|
|
|
|
{ PCI_DEVICE(0x8086, 0x5a98),
|
2018-12-31 18:02:01 +00:00
|
|
|
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_BROXTON },
|
2016-04-20 02:08:43 +00:00
|
|
|
/* Broxton-T */
|
|
|
|
{ PCI_DEVICE(0x8086, 0x1a98),
|
2017-06-14 05:26:00 +00:00
|
|
|
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_BROXTON },
|
2017-02-24 22:42:40 +00:00
|
|
|
/* Gemini-Lake */
|
|
|
|
{ PCI_DEVICE(0x8086, 0x3198),
|
2018-12-31 18:02:01 +00:00
|
|
|
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_BROXTON },
|
2012-06-13 02:23:51 +00:00
|
|
|
/* Haswell */
|
2013-02-01 14:42:19 +00:00
|
|
|
{ PCI_DEVICE(0x8086, 0x0a0c),
|
2013-11-05 16:54:05 +00:00
|
|
|
.driver_data = AZX_DRIVER_HDMI | AZX_DCAPS_INTEL_HASWELL },
|
2012-06-13 02:23:51 +00:00
|
|
|
{ PCI_DEVICE(0x8086, 0x0c0c),
|
2013-11-05 16:54:05 +00:00
|
|
|
.driver_data = AZX_DRIVER_HDMI | AZX_DCAPS_INTEL_HASWELL },
|
2012-09-17 05:10:23 +00:00
|
|
|
{ PCI_DEVICE(0x8086, 0x0d0c),
|
2013-11-05 16:54:05 +00:00
|
|
|
.driver_data = AZX_DRIVER_HDMI | AZX_DCAPS_INTEL_HASWELL },
|
2014-01-08 20:55:14 +00:00
|
|
|
/* Broadwell */
|
|
|
|
{ PCI_DEVICE(0x8086, 0x160c),
|
2014-06-09 07:28:59 +00:00
|
|
|
.driver_data = AZX_DRIVER_HDMI | AZX_DCAPS_INTEL_BROADWELL },
|
2012-09-21 23:39:07 +00:00
|
|
|
/* 5 Series/3400 */
|
|
|
|
{ PCI_DEVICE(0x8086, 0x3b56),
|
2013-02-14 08:44:55 +00:00
|
|
|
.driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_NOPM },
|
2013-01-29 09:12:23 +00:00
|
|
|
/* Poulsbo */
|
2011-05-25 07:11:37 +00:00
|
|
|
{ PCI_DEVICE(0x8086, 0x811b),
|
2015-12-01 15:49:35 +00:00
|
|
|
.driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_BASE },
|
2013-01-29 09:12:23 +00:00
|
|
|
/* Oaktrail */
|
2011-12-28 15:17:26 +00:00
|
|
|
{ PCI_DEVICE(0x8086, 0x080a),
|
2015-12-01 15:49:35 +00:00
|
|
|
.driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_BASE },
|
2013-05-16 07:36:12 +00:00
|
|
|
/* BayTrail */
|
|
|
|
{ PCI_DEVICE(0x8086, 0x0f04),
|
2015-04-21 05:12:23 +00:00
|
|
|
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_BAYTRAIL },
|
2014-08-04 01:22:44 +00:00
|
|
|
/* Braswell */
|
|
|
|
{ PCI_DEVICE(0x8086, 0x2284),
|
2015-04-07 12:32:20 +00:00
|
|
|
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_BRASWELL },
|
2014-12-03 08:47:20 +00:00
|
|
|
/* ICH6 */
|
2011-06-10 12:56:26 +00:00
|
|
|
{ PCI_DEVICE(0x8086, 0x2668),
|
2014-12-03 08:47:20 +00:00
|
|
|
.driver_data = AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH },
|
|
|
|
/* ICH7 */
|
2011-06-10 12:56:26 +00:00
|
|
|
{ PCI_DEVICE(0x8086, 0x27d8),
|
2014-12-03 08:47:20 +00:00
|
|
|
.driver_data = AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH },
|
|
|
|
/* ESB2 */
|
2011-06-10 12:56:26 +00:00
|
|
|
{ PCI_DEVICE(0x8086, 0x269a),
|
2014-12-03 08:47:20 +00:00
|
|
|
.driver_data = AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH },
|
|
|
|
/* ICH8 */
|
2011-06-10 12:56:26 +00:00
|
|
|
{ PCI_DEVICE(0x8086, 0x284b),
|
2014-12-03 08:47:20 +00:00
|
|
|
.driver_data = AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH },
|
|
|
|
/* ICH9 */
|
2011-06-10 12:56:26 +00:00
|
|
|
{ PCI_DEVICE(0x8086, 0x293e),
|
2014-12-03 08:47:20 +00:00
|
|
|
.driver_data = AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH },
|
|
|
|
/* ICH9 */
|
2011-06-10 12:56:26 +00:00
|
|
|
{ PCI_DEVICE(0x8086, 0x293f),
|
2014-12-03 08:47:20 +00:00
|
|
|
.driver_data = AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH },
|
|
|
|
/* ICH10 */
|
2011-06-10 12:56:26 +00:00
|
|
|
{ PCI_DEVICE(0x8086, 0x3a3e),
|
2014-12-03 08:47:20 +00:00
|
|
|
.driver_data = AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH },
|
|
|
|
/* ICH10 */
|
2011-06-10 12:56:26 +00:00
|
|
|
{ PCI_DEVICE(0x8086, 0x3a6e),
|
2014-12-03 08:47:20 +00:00
|
|
|
.driver_data = AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH },
|
2010-09-15 08:17:26 +00:00
|
|
|
/* Generic Intel */
|
|
|
|
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_ANY_ID),
|
|
|
|
.class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
|
|
|
|
.class_mask = 0xffffff,
|
2014-12-03 08:56:20 +00:00
|
|
|
.driver_data = AZX_DRIVER_ICH | AZX_DCAPS_NO_ALIGN_BUFSIZE },
|
2011-05-25 07:11:37 +00:00
|
|
|
/* ATI SB 450/600/700/800/900 */
|
|
|
|
{ PCI_DEVICE(0x1002, 0x437b),
|
|
|
|
.driver_data = AZX_DRIVER_ATI | AZX_DCAPS_PRESET_ATI_SB },
|
|
|
|
{ PCI_DEVICE(0x1002, 0x4383),
|
|
|
|
.driver_data = AZX_DRIVER_ATI | AZX_DCAPS_PRESET_ATI_SB },
|
|
|
|
/* AMD Hudson */
|
|
|
|
{ PCI_DEVICE(0x1022, 0x780d),
|
|
|
|
.driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_SB },
|
ALSA: hda - Workaround for crackled sound on AMD controller (1022:1457)
A long-time problem on the recent AMD chip (X370, X470, B450, etc with
PCI ID 1022:1457) with Realtek codecs is the crackled or distorted
sound for capture streams, as well as occasional playback hiccups.
After lengthy debugging sessions, the workarounds we've found are like
the following:
- Set up the proper driver caps for this controller, similar as the
other AMD controller.
- Correct the DMA position reporting with the fixed FIFO size, which
is similar like as workaround used for VIA chip set.
- Even after the position correction, PulseAudio still shows
mysterious stalls of playback streams when a capture is triggered in
timer-scheduled mode. Since we have no clear way to eliminate the
stall, pass the BATCH PCM flag for PA to suppress the tsched mode as
a temporary workaround.
This patch implements the workarounds. For the driver caps, it
defines a new preset, AXZ_DCAPS_PRESET_AMD_SB. It enables the FIFO-
corrected position reporting (corresponding to the new position_fix=6)
and enforces the SNDRV_PCM_INFO_BATCH flag.
Note that the current implementation is merely a workaround.
Hopefully we'll find a better alternative in future, especially about
removing the BATCH flag hack again.
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=195303
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2019-08-06 15:31:48 +00:00
|
|
|
/* AMD, X370 & co */
|
|
|
|
{ PCI_DEVICE(0x1022, 0x1457),
|
|
|
|
.driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_AMD_SB },
|
2019-08-09 09:23:00 +00:00
|
|
|
/* AMD, X570 & co */
|
|
|
|
{ PCI_DEVICE(0x1022, 0x1487),
|
|
|
|
.driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_AMD_SB },
|
2018-11-29 08:57:37 +00:00
|
|
|
/* AMD Stoney */
|
|
|
|
{ PCI_DEVICE(0x1022, 0x157a),
|
|
|
|
.driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_SB |
|
|
|
|
AZX_DCAPS_PM_RUNTIME },
|
2017-11-23 14:37:00 +00:00
|
|
|
/* AMD Raven */
|
|
|
|
{ PCI_DEVICE(0x1022, 0x15e3),
|
2019-09-20 07:30:40 +00:00
|
|
|
.driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_AMD_SB },
|
2008-02-21 07:13:11 +00:00
|
|
|
/* ATI HDMI */
|
2016-08-03 11:16:39 +00:00
|
|
|
{ PCI_DEVICE(0x1002, 0x0002),
|
2021-01-05 17:52:45 +00:00
|
|
|
.driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
|
|
|
|
AZX_DCAPS_PM_RUNTIME },
|
2015-06-24 18:37:18 +00:00
|
|
|
{ PCI_DEVICE(0x1002, 0x1308),
|
|
|
|
.driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
|
2015-07-20 14:26:18 +00:00
|
|
|
{ PCI_DEVICE(0x1002, 0x157a),
|
|
|
|
.driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
|
2016-07-12 10:21:28 +00:00
|
|
|
{ PCI_DEVICE(0x1002, 0x15b3),
|
|
|
|
.driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
|
2011-05-25 07:11:37 +00:00
|
|
|
{ PCI_DEVICE(0x1002, 0x793b),
|
|
|
|
.driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
|
|
|
|
{ PCI_DEVICE(0x1002, 0x7919),
|
|
|
|
.driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
|
|
|
|
{ PCI_DEVICE(0x1002, 0x960f),
|
|
|
|
.driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
|
|
|
|
{ PCI_DEVICE(0x1002, 0x970f),
|
|
|
|
.driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
|
2015-06-24 18:37:18 +00:00
|
|
|
{ PCI_DEVICE(0x1002, 0x9840),
|
|
|
|
.driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
|
2011-05-25 07:11:37 +00:00
|
|
|
{ PCI_DEVICE(0x1002, 0xaa00),
|
|
|
|
.driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
|
|
|
|
{ PCI_DEVICE(0x1002, 0xaa08),
|
|
|
|
.driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
|
|
|
|
{ PCI_DEVICE(0x1002, 0xaa10),
|
|
|
|
.driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
|
|
|
|
{ PCI_DEVICE(0x1002, 0xaa18),
|
|
|
|
.driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
|
|
|
|
{ PCI_DEVICE(0x1002, 0xaa20),
|
|
|
|
.driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
|
|
|
|
{ PCI_DEVICE(0x1002, 0xaa28),
|
|
|
|
.driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
|
|
|
|
{ PCI_DEVICE(0x1002, 0xaa30),
|
|
|
|
.driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
|
|
|
|
{ PCI_DEVICE(0x1002, 0xaa38),
|
|
|
|
.driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
|
|
|
|
{ PCI_DEVICE(0x1002, 0xaa40),
|
|
|
|
.driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
|
|
|
|
{ PCI_DEVICE(0x1002, 0xaa48),
|
|
|
|
.driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
|
2013-11-05 08:27:10 +00:00
|
|
|
{ PCI_DEVICE(0x1002, 0xaa50),
|
|
|
|
.driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
|
|
|
|
{ PCI_DEVICE(0x1002, 0xaa58),
|
|
|
|
.driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
|
|
|
|
{ PCI_DEVICE(0x1002, 0xaa60),
|
|
|
|
.driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
|
|
|
|
{ PCI_DEVICE(0x1002, 0xaa68),
|
|
|
|
.driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
|
|
|
|
{ PCI_DEVICE(0x1002, 0xaa80),
|
|
|
|
.driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
|
|
|
|
{ PCI_DEVICE(0x1002, 0xaa88),
|
|
|
|
.driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
|
|
|
|
{ PCI_DEVICE(0x1002, 0xaa90),
|
|
|
|
.driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
|
|
|
|
{ PCI_DEVICE(0x1002, 0xaa98),
|
|
|
|
.driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
|
2011-12-14 08:10:27 +00:00
|
|
|
{ PCI_DEVICE(0x1002, 0x9902),
|
2014-11-25 10:28:07 +00:00
|
|
|
.driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
|
2011-12-14 08:10:27 +00:00
|
|
|
{ PCI_DEVICE(0x1002, 0xaaa0),
|
2014-11-25 10:28:07 +00:00
|
|
|
.driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
|
2011-12-14 08:10:27 +00:00
|
|
|
{ PCI_DEVICE(0x1002, 0xaaa8),
|
2014-11-25 10:28:07 +00:00
|
|
|
.driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
|
2011-12-14 08:10:27 +00:00
|
|
|
{ PCI_DEVICE(0x1002, 0xaab0),
|
2014-11-25 10:28:07 +00:00
|
|
|
.driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
|
2015-07-20 14:26:18 +00:00
|
|
|
{ PCI_DEVICE(0x1002, 0xaac0),
|
2021-01-05 17:52:45 +00:00
|
|
|
.driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
|
|
|
|
AZX_DCAPS_PM_RUNTIME },
|
2015-05-27 14:17:19 +00:00
|
|
|
{ PCI_DEVICE(0x1002, 0xaac8),
|
2021-01-05 17:52:45 +00:00
|
|
|
.driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
|
|
|
|
AZX_DCAPS_PM_RUNTIME },
|
2015-07-20 14:26:18 +00:00
|
|
|
{ PCI_DEVICE(0x1002, 0xaad8),
|
2019-11-22 21:43:52 +00:00
|
|
|
.driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
|
|
|
|
AZX_DCAPS_PM_RUNTIME },
|
2016-03-31 12:40:03 +00:00
|
|
|
{ PCI_DEVICE(0x1002, 0xaae0),
|
2019-11-22 21:43:52 +00:00
|
|
|
.driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
|
|
|
|
AZX_DCAPS_PM_RUNTIME },
|
|
|
|
{ PCI_DEVICE(0x1002, 0xaae8),
|
|
|
|
.driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
|
|
|
|
AZX_DCAPS_PM_RUNTIME },
|
2016-03-31 12:40:03 +00:00
|
|
|
{ PCI_DEVICE(0x1002, 0xaaf0),
|
2019-11-22 21:43:52 +00:00
|
|
|
.driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
|
|
|
|
AZX_DCAPS_PM_RUNTIME },
|
2019-11-22 21:43:51 +00:00
|
|
|
{ PCI_DEVICE(0x1002, 0xaaf8),
|
2019-11-22 21:43:52 +00:00
|
|
|
.driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
|
|
|
|
AZX_DCAPS_PM_RUNTIME },
|
2019-11-22 21:43:51 +00:00
|
|
|
{ PCI_DEVICE(0x1002, 0xab00),
|
2019-11-22 21:43:52 +00:00
|
|
|
.driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
|
|
|
|
AZX_DCAPS_PM_RUNTIME },
|
2019-11-22 21:43:51 +00:00
|
|
|
{ PCI_DEVICE(0x1002, 0xab08),
|
2019-11-22 21:43:52 +00:00
|
|
|
.driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
|
|
|
|
AZX_DCAPS_PM_RUNTIME },
|
2019-11-22 21:43:51 +00:00
|
|
|
{ PCI_DEVICE(0x1002, 0xab10),
|
2019-11-22 21:43:52 +00:00
|
|
|
.driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
|
|
|
|
AZX_DCAPS_PM_RUNTIME },
|
2019-11-22 21:43:51 +00:00
|
|
|
{ PCI_DEVICE(0x1002, 0xab18),
|
2019-11-22 21:43:52 +00:00
|
|
|
.driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
|
|
|
|
AZX_DCAPS_PM_RUNTIME },
|
2019-11-22 21:43:51 +00:00
|
|
|
{ PCI_DEVICE(0x1002, 0xab20),
|
2019-11-22 21:43:52 +00:00
|
|
|
.driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
|
2020-06-03 01:31:37 +00:00
|
|
|
AZX_DCAPS_PM_RUNTIME },
|
|
|
|
{ PCI_DEVICE(0x1002, 0xab28),
|
|
|
|
.driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
|
2019-11-22 21:43:52 +00:00
|
|
|
AZX_DCAPS_PM_RUNTIME },
|
2019-11-22 21:43:51 +00:00
|
|
|
{ PCI_DEVICE(0x1002, 0xab38),
|
2019-11-22 21:43:52 +00:00
|
|
|
.driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
|
|
|
|
AZX_DCAPS_PM_RUNTIME },
|
2008-02-21 07:13:11 +00:00
|
|
|
/* VIA VT8251/VT8237A */
|
2015-12-17 07:29:53 +00:00
|
|
|
{ PCI_DEVICE(0x1106, 0x3288), .driver_data = AZX_DRIVER_VIA },
|
2012-06-08 11:18:39 +00:00
|
|
|
/* VIA GFX VT7122/VX900 */
|
|
|
|
{ PCI_DEVICE(0x1106, 0x9170), .driver_data = AZX_DRIVER_GENERIC },
|
|
|
|
/* VIA GFX VT6122/VX11 */
|
|
|
|
{ PCI_DEVICE(0x1106, 0x9140), .driver_data = AZX_DRIVER_GENERIC },
|
2008-02-21 07:13:11 +00:00
|
|
|
/* SIS966 */
|
|
|
|
{ PCI_DEVICE(0x1039, 0x7502), .driver_data = AZX_DRIVER_SIS },
|
|
|
|
/* ULI M5461 */
|
|
|
|
{ PCI_DEVICE(0x10b9, 0x5461), .driver_data = AZX_DRIVER_ULI },
|
|
|
|
/* NVIDIA MCP */
|
2009-12-18 15:41:39 +00:00
|
|
|
{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID),
|
|
|
|
.class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
|
|
|
|
.class_mask = 0xffffff,
|
2011-05-25 07:11:37 +00:00
|
|
|
.driver_data = AZX_DRIVER_NVIDIA | AZX_DCAPS_PRESET_NVIDIA },
|
2008-05-27 09:44:55 +00:00
|
|
|
/* Teradici */
|
2011-05-25 07:11:37 +00:00
|
|
|
{ PCI_DEVICE(0x6549, 0x1200),
|
|
|
|
.driver_data = AZX_DRIVER_TERA | AZX_DCAPS_NO_64BIT },
|
2012-11-02 20:10:39 +00:00
|
|
|
{ PCI_DEVICE(0x6549, 0x2200),
|
|
|
|
.driver_data = AZX_DRIVER_TERA | AZX_DCAPS_NO_64BIT },
|
2009-04-16 06:53:34 +00:00
|
|
|
/* Creative X-Fi (CA0110-IBG) */
|
2012-06-11 13:51:54 +00:00
|
|
|
/* CTHDA chips */
|
|
|
|
{ PCI_DEVICE(0x1102, 0x0010),
|
|
|
|
.driver_data = AZX_DRIVER_CTHDA | AZX_DCAPS_PRESET_CTHDA },
|
|
|
|
{ PCI_DEVICE(0x1102, 0x0012),
|
|
|
|
.driver_data = AZX_DRIVER_CTHDA | AZX_DCAPS_PRESET_CTHDA },
|
2014-02-10 08:48:47 +00:00
|
|
|
#if !IS_ENABLED(CONFIG_SND_CTXFI)
|
2009-05-18 10:40:52 +00:00
|
|
|
/* the following entry conflicts with snd-ctxfi driver,
|
|
|
|
* as ctxfi driver mutates from HD-audio to native mode with
|
|
|
|
* a special command sequence.
|
|
|
|
*/
|
2009-04-16 06:53:34 +00:00
|
|
|
{ PCI_DEVICE(PCI_VENDOR_ID_CREATIVE, PCI_ANY_ID),
|
|
|
|
.class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
|
|
|
|
.class_mask = 0xffffff,
|
2011-05-25 07:11:37 +00:00
|
|
|
.driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND |
|
2015-12-17 07:12:37 +00:00
|
|
|
AZX_DCAPS_NO_64BIT | AZX_DCAPS_POSFIX_LPIB },
|
2009-05-18 10:40:52 +00:00
|
|
|
#else
|
|
|
|
/* this entry seems still valid -- i.e. without emu20kx chip */
|
2011-05-25 07:11:37 +00:00
|
|
|
{ PCI_DEVICE(0x1102, 0x0009),
|
|
|
|
.driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND |
|
2015-12-17 07:12:37 +00:00
|
|
|
AZX_DCAPS_NO_64BIT | AZX_DCAPS_POSFIX_LPIB },
|
2009-05-18 10:40:52 +00:00
|
|
|
#endif
|
2014-08-06 12:27:42 +00:00
|
|
|
/* CM8888 */
|
|
|
|
{ PCI_DEVICE(0x13f6, 0x5011),
|
|
|
|
.driver_data = AZX_DRIVER_CMEDIA |
|
2014-11-25 10:28:07 +00:00
|
|
|
AZX_DCAPS_NO_MSI | AZX_DCAPS_POSFIX_LPIB | AZX_DCAPS_SNOOP_OFF },
|
2010-09-27 02:35:06 +00:00
|
|
|
/* Vortex86MX */
|
|
|
|
{ PCI_DEVICE(0x17f3, 0x3010), .driver_data = AZX_DRIVER_GENERIC },
|
2011-01-17 14:23:21 +00:00
|
|
|
/* VMware HDAudio */
|
|
|
|
{ PCI_DEVICE(0x15ad, 0x1977), .driver_data = AZX_DRIVER_GENERIC },
|
2009-07-17 03:32:32 +00:00
|
|
|
/* AMD/ATI Generic, PCI class code and Vendor ID for HD Audio */
|
2008-11-13 10:07:07 +00:00
|
|
|
{ PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_ANY_ID),
|
|
|
|
.class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
|
|
|
|
.class_mask = 0xffffff,
|
2011-05-25 07:11:37 +00:00
|
|
|
.driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_HDMI },
|
2009-07-17 03:32:32 +00:00
|
|
|
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_ANY_ID),
|
|
|
|
.class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
|
|
|
|
.class_mask = 0xffffff,
|
2011-05-25 07:11:37 +00:00
|
|
|
.driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_HDMI },
|
2019-08-02 03:04:08 +00:00
|
|
|
/* Zhaoxin */
|
|
|
|
{ PCI_DEVICE(0x1d17, 0x3288), .driver_data = AZX_DRIVER_ZHAOXIN },
|
2005-04-16 22:20:36 +00:00
|
|
|
{ 0, }
|
|
|
|
};
|
|
|
|
MODULE_DEVICE_TABLE(pci, azx_ids);
|
|
|
|
|
|
|
|
/* pci_driver definition */
|
2012-04-24 10:25:00 +00:00
|
|
|
static struct pci_driver azx_driver = {
|
2011-06-10 14:20:20 +00:00
|
|
|
.name = KBUILD_MODNAME,
|
2005-04-16 22:20:36 +00:00
|
|
|
.id_table = azx_ids,
|
|
|
|
.probe = azx_probe,
|
2012-12-06 17:35:10 +00:00
|
|
|
.remove = azx_remove,
|
2015-03-05 16:21:32 +00:00
|
|
|
.shutdown = azx_shutdown,
|
2012-07-02 13:20:37 +00:00
|
|
|
.driver = {
|
|
|
|
.pm = AZX_PM_OPS,
|
|
|
|
},
|
2005-04-16 22:20:36 +00:00
|
|
|
};
|
|
|
|
|
2012-04-24 10:25:00 +00:00
|
|
|
module_pci_driver(azx_driver);
|