diff options
author | José Pekkarinen <jose.pekkarinen@nokia.com> | 2016-04-11 10:41:07 +0300 |
---|---|---|
committer | José Pekkarinen <jose.pekkarinen@nokia.com> | 2016-04-13 08:17:18 +0300 |
commit | e09b41010ba33a20a87472ee821fa407a5b8da36 (patch) | |
tree | d10dc367189862e7ca5c592f033dc3726e1df4e3 /kernel/sound/pci/hda/hda_intel.c | |
parent | f93b97fd65072de626c074dbe099a1fff05ce060 (diff) |
These changes are the raw update to linux-4.4.6-rt14. Kernel sources
are taken from kernel.org, and rt patch from the rt wiki download page.
During the rebasing, the following patch collided:
Force tick interrupt and get rid of softirq magic(I70131fb85).
Collisions have been removed because its logic was found on the
source already.
Change-Id: I7f57a4081d9deaa0d9ccfc41a6c8daccdee3b769
Signed-off-by: José Pekkarinen <jose.pekkarinen@nokia.com>
Diffstat (limited to 'kernel/sound/pci/hda/hda_intel.c')
-rw-r--r-- | kernel/sound/pci/hda/hda_intel.c | 496 |
1 files changed, 357 insertions, 139 deletions
diff --git a/kernel/sound/pci/hda/hda_intel.c b/kernel/sound/pci/hda/hda_intel.c index 44dfc7b92..2ff692dd2 100644 --- a/kernel/sound/pci/hda/hda_intel.c +++ b/kernel/sound/pci/hda/hda_intel.c @@ -57,6 +57,8 @@ #endif #include <sound/core.h> #include <sound/initval.h> +#include <sound/hdaudio.h> +#include <sound/hda_i915.h> #include <linux/vgaarb.h> #include <linux/vga_switcheroo.h> #include <linux/firmware.h> @@ -64,6 +66,9 @@ #include "hda_controller.h" #include "hda_intel.h" +#define CREATE_TRACE_POINTS +#include "hda_intel_trace.h" + /* position fix mode */ enum { POS_FIX_AUTO, @@ -85,6 +90,8 @@ enum { #define NVIDIA_HDA_ENABLE_COHBIT 0x01 /* Defines for Intel SCH HDA snoop control */ +#define INTEL_HDA_CGCTL 0x48 +#define INTEL_HDA_CGCTL_MISCBDCGE (0x1 << 6) #define INTEL_SCH_HDA_DEVC 0x78 #define INTEL_SCH_HDA_DEVC_NOSNOOP (0x1<<11) @@ -166,7 +173,7 @@ MODULE_PARM_DESC(beep_mode, "Select HDA Beep registration mode " #ifdef CONFIG_PM static int param_set_xint(const char *val, const struct kernel_param *kp); -static struct kernel_param_ops param_ops_xint = { +static const struct kernel_param_ops param_ops_xint = { .set = param_set_xint, .get = param_get_int, }; @@ -307,6 +314,10 @@ enum { (AZX_DCAPS_INTEL_PCH | AZX_DCAPS_SEPARATE_STREAM_TAG |\ AZX_DCAPS_I915_POWERWELL) +#define AZX_DCAPS_INTEL_BROXTON \ + (AZX_DCAPS_INTEL_PCH | AZX_DCAPS_SEPARATE_STREAM_TAG |\ + AZX_DCAPS_I915_POWERWELL) + /* quirks for ATI SB / AMD Hudson */ #define AZX_DCAPS_PRESET_ATI_SB \ (AZX_DCAPS_NO_TCSEL | AZX_DCAPS_SYNC_WRITE | AZX_DCAPS_POSFIX_LPIB |\ @@ -329,10 +340,11 @@ enum { #define AZX_DCAPS_PRESET_CTHDA \ (AZX_DCAPS_NO_MSI | AZX_DCAPS_POSFIX_LPIB |\ + AZX_DCAPS_NO_64BIT |\ AZX_DCAPS_4K_BDLE_BOUNDARY | AZX_DCAPS_SNOOP_OFF) /* - * VGA-switcher support + * vga_switcheroo support */ #ifdef SUPPORT_VGA_SWITCHEROO #define use_vga_switcheroo(chip) ((chip)->use_vga_switcheroo) @@ -345,6 +357,11 @@ enum { ((pci)->device == 0x0d0c) || \ ((pci)->device == 0x160c)) +#define IS_SKL(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa170) +#define IS_SKL_LP(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x9d70) +#define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98) +#define IS_SKL_PLUS(pci) (IS_SKL(pci) || IS_SKL_LP(pci) || IS_BXT(pci)) + static char *driver_short_names[] = { [AZX_DRIVER_ICH] = "HDA Intel", [AZX_DRIVER_PCH] = "HDA Intel PCH", @@ -496,11 +513,54 @@ static void azx_init_pci(struct azx *chip) } } +/* + * In BXT-P A0, HD-Audio DMA requests is later than expected, + * and makes an audio stream sensitive to system latencies when + * 24/32 bits are playing. + * Adjusting threshold of DMA fifo to force the DMA request + * sooner to improve latency tolerance at the expense of power. + */ +static void bxt_reduce_dma_latency(struct azx *chip) +{ + u32 val; + + val = azx_readl(chip, SKL_EM4L); + val &= (0x3 << 20); + azx_writel(chip, SKL_EM4L, val); +} + +static void hda_intel_init_chip(struct azx *chip, bool full_reset) +{ + struct hdac_bus *bus = azx_bus(chip); + struct pci_dev *pci = chip->pci; + u32 val; + + if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) + snd_hdac_set_codec_wakeup(bus, true); + if (IS_SKL_PLUS(pci)) { + pci_read_config_dword(pci, INTEL_HDA_CGCTL, &val); + val = val & ~INTEL_HDA_CGCTL_MISCBDCGE; + pci_write_config_dword(pci, INTEL_HDA_CGCTL, val); + } + azx_init_chip(chip, full_reset); + if (IS_SKL_PLUS(pci)) { + pci_read_config_dword(pci, INTEL_HDA_CGCTL, &val); + val = val | INTEL_HDA_CGCTL_MISCBDCGE; + pci_write_config_dword(pci, INTEL_HDA_CGCTL, val); + } + if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) + snd_hdac_set_codec_wakeup(bus, false); + + /* reduce dma latency to avoid noise */ + if (IS_BXT(pci)) + bxt_reduce_dma_latency(chip); +} + /* calculate runtime delay from LPIB */ static int azx_get_delay_from_lpib(struct azx *chip, struct azx_dev *azx_dev, unsigned int pos) { - struct snd_pcm_substream *substream = azx_dev->substream; + struct snd_pcm_substream *substream = azx_dev->core.substream; int stream = substream->stream; unsigned int lpib_pos = azx_get_pos_lpib(chip, azx_dev); int delay; @@ -510,16 +570,16 @@ static int azx_get_delay_from_lpib(struct azx *chip, struct azx_dev *azx_dev, else delay = lpib_pos - pos; if (delay < 0) { - if (delay >= azx_dev->delay_negative_threshold) + if (delay >= azx_dev->core.delay_negative_threshold) delay = 0; else - delay += azx_dev->bufsize; + delay += azx_dev->core.bufsize; } - if (delay >= azx_dev->period_bytes) { + if (delay >= azx_dev->core.period_bytes) { dev_info(chip->card->dev, "Unstable LPIB (%d >= %d); disabling LPIB delay counting\n", - delay, azx_dev->period_bytes); + delay, azx_dev->core.period_bytes); delay = 0; chip->driver_caps &= ~AZX_DCAPS_COUNT_LPIB_DELAY; chip->get_delay[stream] = NULL; @@ -548,6 +608,14 @@ static int azx_position_check(struct azx *chip, struct azx_dev *azx_dev) return 0; } +/* Enable/disable i915 display power for the link */ +static int azx_intel_link_power(struct azx *chip, bool enable) +{ + struct hdac_bus *bus = azx_bus(chip); + + return snd_hdac_display_power(bus, enable); +} + /* * Check whether the current DMA position is acceptable for updating * periods. Returns non-zero if it's OK. @@ -559,13 +627,13 @@ static int azx_position_check(struct azx *chip, struct azx_dev *azx_dev) */ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev) { - struct snd_pcm_substream *substream = azx_dev->substream; + struct snd_pcm_substream *substream = azx_dev->core.substream; int stream = substream->stream; u32 wallclk; unsigned int pos; - wallclk = azx_readl(chip, WALLCLK) - azx_dev->start_wallclk; - if (wallclk < (azx_dev->period_wallclk * 2) / 3) + wallclk = azx_readl(chip, WALLCLK) - azx_dev->core.start_wallclk; + if (wallclk < (azx_dev->core.period_wallclk * 2) / 3) return -1; /* bogus (too early) interrupt */ if (chip->get_position[stream]) @@ -576,6 +644,9 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev) dev_info(chip->card->dev, "Invalid position buffer, using LPIB read method instead.\n"); chip->get_position[stream] = azx_get_pos_lpib; + if (chip->get_position[0] == azx_get_pos_lpib && + chip->get_position[1] == azx_get_pos_lpib) + azx_bus(chip)->use_posbuf = false; pos = azx_get_pos_lpib(chip, azx_dev); chip->get_delay[stream] = NULL; } else { @@ -585,17 +656,17 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev) } } - if (pos >= azx_dev->bufsize) + if (pos >= azx_dev->core.bufsize) pos = 0; - if (WARN_ONCE(!azx_dev->period_bytes, + if (WARN_ONCE(!azx_dev->core.period_bytes, "hda-intel: zero azx_dev->period_bytes")) return -1; /* this shouldn't happen! */ - if (wallclk < (azx_dev->period_wallclk * 5) / 4 && - pos % azx_dev->period_bytes > azx_dev->period_bytes / 2) + if (wallclk < (azx_dev->core.period_wallclk * 5) / 4 && + pos % azx_dev->core.period_bytes > azx_dev->core.period_bytes / 2) /* NG - it's below the first next period boundary */ return chip->bdl_pos_adj[chip->dev_index] ? 0 : -1; - azx_dev->start_wallclk += wallclk; + azx_dev->core.start_wallclk += wallclk; return 1; /* OK, it's fine */ } @@ -606,7 +677,9 @@ static void azx_irq_pending_work(struct work_struct *work) { struct hda_intel *hda = container_of(work, struct hda_intel, irq_pending_work); struct azx *chip = &hda->chip; - int i, pending, ok; + struct hdac_bus *bus = azx_bus(chip); + struct hdac_stream *s; + int pending, ok; if (!hda->irq_pending_warned) { dev_info(chip->card->dev, @@ -617,25 +690,25 @@ static void azx_irq_pending_work(struct work_struct *work) for (;;) { pending = 0; - spin_lock_irq(&chip->reg_lock); - for (i = 0; i < chip->num_streams; i++) { - struct azx_dev *azx_dev = &chip->azx_dev[i]; + spin_lock_irq(&bus->reg_lock); + list_for_each_entry(s, &bus->stream_list, list) { + struct azx_dev *azx_dev = stream_to_azx_dev(s); if (!azx_dev->irq_pending || - !azx_dev->substream || - !azx_dev->running) + !s->substream || + !s->running) continue; ok = azx_position_ok(chip, azx_dev); if (ok > 0) { azx_dev->irq_pending = 0; - spin_unlock(&chip->reg_lock); - snd_pcm_period_elapsed(azx_dev->substream); - spin_lock(&chip->reg_lock); + spin_unlock(&bus->reg_lock); + snd_pcm_period_elapsed(s->substream); + spin_lock(&bus->reg_lock); } else if (ok < 0) { pending = 0; /* too early */ } else pending++; } - spin_unlock_irq(&chip->reg_lock); + spin_unlock_irq(&bus->reg_lock); if (!pending) return; msleep(1); @@ -645,16 +718,21 @@ static void azx_irq_pending_work(struct work_struct *work) /* clear irq_pending flags and assure no on-going workq */ static void azx_clear_irq_pending(struct azx *chip) { - int i; + struct hdac_bus *bus = azx_bus(chip); + struct hdac_stream *s; - spin_lock_irq(&chip->reg_lock); - for (i = 0; i < chip->num_streams; i++) - chip->azx_dev[i].irq_pending = 0; - spin_unlock_irq(&chip->reg_lock); + spin_lock_irq(&bus->reg_lock); + list_for_each_entry(s, &bus->stream_list, list) { + struct azx_dev *azx_dev = stream_to_azx_dev(s); + azx_dev->irq_pending = 0; + } + spin_unlock_irq(&bus->reg_lock); } static int azx_acquire_irq(struct azx *chip, int do_disconnect) { + struct hdac_bus *bus = azx_bus(chip); + if (request_irq(chip->pci->irq, azx_interrupt, chip->msi ? 0 : IRQF_SHARED, KBUILD_MODNAME, chip)) { @@ -665,7 +743,7 @@ static int azx_acquire_irq(struct azx *chip, int do_disconnect) snd_card_disconnect(chip->card); return -1; } - chip->irq = chip->pci->irq; + bus->irq = chip->pci->irq; pci_intx(chip->pci, !chip->msi); return 0; } @@ -678,8 +756,8 @@ static unsigned int azx_via_get_position(struct azx *chip, unsigned int mod_link_pos, mod_dma_pos, mod_mini_pos; unsigned int fifo_size; - link_pos = azx_sd_readl(chip, azx_dev, SD_LPIB); - if (azx_dev->substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + link_pos = snd_hdac_stream_get_pos_lpib(azx_stream(azx_dev)); + if (azx_dev->core.substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { /* Playback, no problem using link position */ return link_pos; } @@ -688,13 +766,14 @@ static unsigned int azx_via_get_position(struct azx *chip, /* For new chipset, * use mod to get the DMA position just like old chipset */ - mod_dma_pos = le32_to_cpu(*azx_dev->posbuf); - mod_dma_pos %= azx_dev->period_bytes; + mod_dma_pos = le32_to_cpu(*azx_dev->core.posbuf); + mod_dma_pos %= azx_dev->core.period_bytes; /* azx_dev->fifo_size can't get FIFO size of in stream. * Get from base address + offset. */ - fifo_size = readw(chip->remap_addr + VIA_IN_STREAM0_FIFO_SIZE_OFFSET); + fifo_size = readw(azx_bus(chip)->remap_addr + + VIA_IN_STREAM0_FIFO_SIZE_OFFSET); if (azx_dev->insufficient) { /* Link position never gather than FIFO size */ @@ -705,20 +784,20 @@ static unsigned int azx_via_get_position(struct azx *chip, } if (link_pos <= fifo_size) - mini_pos = azx_dev->bufsize + link_pos - fifo_size; + mini_pos = azx_dev->core.bufsize + link_pos - fifo_size; else mini_pos = link_pos - fifo_size; /* Find nearest previous boudary */ - mod_mini_pos = mini_pos % azx_dev->period_bytes; - mod_link_pos = link_pos % azx_dev->period_bytes; + mod_mini_pos = mini_pos % azx_dev->core.period_bytes; + mod_link_pos = link_pos % azx_dev->core.period_bytes; 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 { - bound_pos = mini_pos - mod_mini_pos + azx_dev->period_bytes; - if (bound_pos >= azx_dev->bufsize) + bound_pos = mini_pos - mod_mini_pos + azx_dev->core.period_bytes; + if (bound_pos >= azx_dev->core.bufsize) bound_pos = 0; } @@ -760,9 +839,9 @@ static int param_set_xint(const char *val, const struct kernel_param *kp) mutex_lock(&card_list_lock); list_for_each_entry(hda, &card_list, list) { chip = &hda->chip; - if (!chip->bus || chip->disabled) + if (!hda->probe_continued || chip->disabled) continue; - snd_hda_set_power_save(chip->bus, power_save * 1000); + snd_hda_set_power_save(&chip->bus, power_save * 1000); } mutex_unlock(&card_list_lock); return 0; @@ -772,6 +851,50 @@ static int param_set_xint(const char *val, const struct kernel_param *kp) #define azx_del_card_list(chip) /* NOP */ #endif /* CONFIG_PM */ +/* Intel HSW/BDW display HDA controller is in GPU. Both its power and link BCLK + * depends on GPU. Two Extended Mode registers EM4 (M value) and EM5 (N Value) + * are used to convert CDClk (Core Display Clock) to 24MHz BCLK: + * BCLK = CDCLK * M / N + * The values will be lost when the display power well is disabled and need to + * be restored to avoid abnormal playback speed. + */ +static void haswell_set_bclk(struct hda_intel *hda) +{ + struct azx *chip = &hda->chip; + int cdclk_freq; + unsigned int bclk_m, bclk_n; + + if (!hda->need_i915_power) + return; + + cdclk_freq = snd_hdac_get_display_clk(azx_bus(chip)); + switch (cdclk_freq) { + case 337500: + bclk_m = 16; + bclk_n = 225; + break; + + case 450000: + default: /* default CDCLK 450MHz */ + bclk_m = 4; + bclk_n = 75; + break; + + case 540000: + bclk_m = 4; + bclk_n = 90; + break; + + case 675000: + bclk_m = 8; + bclk_n = 225; + break; + } + + azx_writew(chip, HSW_EM4, bclk_m); + azx_writew(chip, HSW_EM5, bclk_n); +} + #if defined(CONFIG_PM_SLEEP) || defined(SUPPORT_VGA_SWITCHEROO) /* * power management @@ -781,28 +904,33 @@ static int azx_suspend(struct device *dev) struct snd_card *card = dev_get_drvdata(dev); struct azx *chip; struct hda_intel *hda; + struct hdac_bus *bus; if (!card) return 0; chip = card->private_data; hda = container_of(chip, struct hda_intel, chip); - if (chip->disabled || hda->init_failed) + if (chip->disabled || hda->init_failed || !chip->running) return 0; + bus = azx_bus(chip); snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); azx_clear_irq_pending(chip); azx_stop_chip(chip); azx_enter_link_reset(chip); - if (chip->irq >= 0) { - free_irq(chip->irq, chip); - chip->irq = -1; + if (bus->irq >= 0) { + free_irq(bus->irq, chip); + bus->irq = -1; } if (chip->msi) pci_disable_msi(chip->pci); - if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) - hda_display_power(hda, false); + if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL + && hda->need_i915_power) + snd_hdac_display_power(bus, false); + + trace_azx_suspend(chip); return 0; } @@ -818,11 +946,12 @@ static int azx_resume(struct device *dev) chip = card->private_data; hda = container_of(chip, struct hda_intel, chip); - if (chip->disabled || hda->init_failed) + if (chip->disabled || hda->init_failed || !chip->running) return 0; - if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) { - hda_display_power(hda, true); + if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL + && hda->need_i915_power) { + snd_hdac_display_power(azx_bus(chip), true); haswell_set_bclk(hda); } if (chip->msi) @@ -832,13 +961,40 @@ static int azx_resume(struct device *dev) return -EIO; azx_init_pci(chip); - azx_init_chip(chip, true); + hda_intel_init_chip(chip, true); snd_power_change_state(card, SNDRV_CTL_POWER_D0); + + trace_azx_resume(chip); return 0; } #endif /* CONFIG_PM_SLEEP || SUPPORT_VGA_SWITCHEROO */ +#ifdef CONFIG_PM_SLEEP +/* 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) +{ + struct pci_dev *pci = to_pci_dev(dev); + + if (IS_SKL_PLUS(pci)) + pci_set_power_state(pci, PCI_D3hot); + + return 0; +} + +static int azx_thaw_noirq(struct device *dev) +{ + struct pci_dev *pci = to_pci_dev(dev); + + if (IS_SKL_PLUS(pci)) + pci_set_power_state(pci, PCI_D0); + + return 0; +} +#endif /* CONFIG_PM_SLEEP */ + #ifdef CONFIG_PM static int azx_runtime_suspend(struct device *dev) { @@ -864,9 +1020,11 @@ static int azx_runtime_suspend(struct device *dev) azx_stop_chip(chip); azx_enter_link_reset(chip); azx_clear_irq_pending(chip); - if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) - hda_display_power(hda, false); + if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL + && hda->need_i915_power) + snd_hdac_display_power(azx_bus(chip), false); + trace_azx_runtime_suspend(chip); return 0; } @@ -875,7 +1033,7 @@ static int azx_runtime_resume(struct device *dev) struct snd_card *card = dev_get_drvdata(dev); struct azx *chip; struct hda_intel *hda; - struct hda_bus *bus; + struct hdac_bus *bus; struct hda_codec *codec; int status; @@ -891,19 +1049,25 @@ static int azx_runtime_resume(struct device *dev) return 0; if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) { - hda_display_power(hda, true); - haswell_set_bclk(hda); + bus = azx_bus(chip); + if (hda->need_i915_power) { + snd_hdac_display_power(bus, true); + haswell_set_bclk(hda); + } else { + /* toggle codec wakeup bit for STATESTS read */ + snd_hdac_set_codec_wakeup(bus, true); + snd_hdac_set_codec_wakeup(bus, false); + } } /* Read STATESTS before controller reset */ status = azx_readw(chip, STATESTS); azx_init_pci(chip); - azx_init_chip(chip, true); + hda_intel_init_chip(chip, true); - bus = chip->bus; - if (status && bus) { - list_for_each_codec(codec, bus) + if (status) { + list_for_each_codec(codec, &chip->bus) if (status & (1 << codec->addr)) schedule_delayed_work(&codec->jackpoll_work, codec->jackpoll_interval); @@ -913,6 +1077,7 @@ static int azx_runtime_resume(struct device *dev) azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) & ~STATESTS_INT_MASK); + trace_azx_runtime_resume(chip); return 0; } @@ -931,7 +1096,7 @@ static int azx_runtime_idle(struct device *dev) return 0; if (!power_save_controller || !azx_has_pm_runtime(chip) || - chip->bus->core.codec_powered) + azx_bus(chip)->codec_powered || !chip->running) return -EBUSY; return 0; @@ -939,6 +1104,10 @@ static int azx_runtime_idle(struct device *dev) static const struct dev_pm_ops azx_pm = { SET_SYSTEM_SLEEP_PM_OPS(azx_suspend, azx_resume) +#ifdef CONFIG_PM_SLEEP + .freeze_noirq = azx_freeze_noirq, + .thaw_noirq = azx_thaw_noirq, +#endif SET_RUNTIME_PM_OPS(azx_runtime_suspend, azx_runtime_resume, azx_runtime_idle) }; @@ -969,7 +1138,7 @@ static void azx_vs_set_state(struct pci_dev *pci, if (chip->disabled == disabled) return; - if (!chip->bus) { + if (!hda->probe_continued) { chip->disabled = disabled; if (!disabled) { dev_info(chip->card->dev, @@ -980,21 +1149,21 @@ static void azx_vs_set_state(struct pci_dev *pci, } } } else { - dev_info(chip->card->dev, "%s via VGA-switcheroo\n", + dev_info(chip->card->dev, "%s via vga_switcheroo\n", disabled ? "Disabling" : "Enabling"); if (disabled) { pm_runtime_put_sync_suspend(card->dev); azx_suspend(card->dev); - /* when we get suspended by vga switcheroo we end up in D3cold, + /* when we get suspended by vga_switcheroo we end up in D3cold, * however we have no ACPI handle, so pci/acpi can't put us there, * put ourselves there */ pci->current_state = PCI_D3cold; chip->disabled = true; - if (snd_hda_lock_devices(chip->bus)) + if (snd_hda_lock_devices(&chip->bus)) dev_warn(chip->card->dev, "Cannot lock devices!\n"); } else { - snd_hda_unlock_devices(chip->bus); + snd_hda_unlock_devices(&chip->bus); pm_runtime_get_noresume(card->dev); chip->disabled = false; azx_resume(card->dev); @@ -1011,11 +1180,11 @@ static bool azx_vs_can_switch(struct pci_dev *pci) wait_for_completion(&hda->probe_wait); if (hda->init_failed) return false; - if (chip->disabled || !chip->bus) + if (chip->disabled || !hda->probe_continued) return true; - if (snd_hda_lock_devices(chip->bus)) + if (snd_hda_lock_devices(&chip->bus)) return false; - snd_hda_unlock_devices(chip->bus); + snd_hda_unlock_devices(&chip->bus); return true; } @@ -1025,7 +1194,7 @@ static void init_vga_switcheroo(struct azx *chip) struct pci_dev *p = get_bound_vga(chip->pci); if (p) { dev_info(chip->card->dev, - "Handle VGA-switcheroo audio client\n"); + "Handle vga_switcheroo audio client\n"); hda->use_vga_switcheroo = 1; pci_dev_put(p); } @@ -1047,8 +1216,7 @@ static int register_vga_switcheroo(struct azx *chip) * is there any machine with two switchable HDMI audio controllers? */ err = vga_switcheroo_register_audio_client(chip->pci, &azx_vs_ops, - VGA_SWITCHEROO_DIS, - chip->bus != NULL); + VGA_SWITCHEROO_DIS); if (err < 0) return err; hda->vga_switcheroo_registered = 1; @@ -1071,7 +1239,7 @@ static int azx_free(struct azx *chip) { struct pci_dev *pci = chip->pci; struct hda_intel *hda = container_of(chip, struct hda_intel, chip); - int i; + struct hdac_bus *bus = azx_bus(chip); if (azx_has_pm_runtime(chip) && chip->running) pm_runtime_get_noresume(&pci->dev); @@ -1082,42 +1250,54 @@ static int azx_free(struct azx *chip) complete_all(&hda->probe_wait); if (use_vga_switcheroo(hda)) { - if (chip->disabled && chip->bus) - snd_hda_unlock_devices(chip->bus); + if (chip->disabled && hda->probe_continued) + snd_hda_unlock_devices(&chip->bus); if (hda->vga_switcheroo_registered) vga_switcheroo_unregister_client(chip->pci); } - if (chip->initialized) { + if (bus->chip_init) { azx_clear_irq_pending(chip); - for (i = 0; i < chip->num_streams; i++) - azx_stream_stop(chip, &chip->azx_dev[i]); + azx_stop_all_streams(chip); azx_stop_chip(chip); } - if (chip->irq >= 0) - free_irq(chip->irq, (void*)chip); + if (bus->irq >= 0) + free_irq(bus->irq, (void*)chip); if (chip->msi) pci_disable_msi(chip->pci); - iounmap(chip->remap_addr); + iounmap(bus->remap_addr); azx_free_stream_pages(chip); + azx_free_streams(chip); + snd_hdac_bus_exit(bus); + if (chip->region_requested) pci_release_regions(chip->pci); + pci_disable_device(chip->pci); - kfree(chip->azx_dev); #ifdef CONFIG_SND_HDA_PATCH_LOADER release_firmware(chip->fw); #endif + if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) { - hda_display_power(hda, false); - hda_i915_exit(hda); + if (hda->need_i915_power) + snd_hdac_display_power(bus, false); + snd_hdac_i915_exit(bus); } kfree(hda); return 0; } +static int azx_dev_disconnect(struct snd_device *device) +{ + struct azx *chip = device->device_data; + + chip->bus.shutdown = 1; + return 0; +} + static int azx_dev_free(struct snd_device *device) { return azx_free(device->device_data); @@ -1125,7 +1305,7 @@ static int azx_dev_free(struct snd_device *device) #ifdef SUPPORT_VGA_SWITCHEROO /* - * Check of disabled HDMI controller by vga-switcheroo + * Check of disabled HDMI controller by vga_switcheroo */ static struct pci_dev *get_bound_vga(struct pci_dev *pci) { @@ -1284,9 +1464,9 @@ static void check_probe_mask(struct azx *chip, int dev) /* check forced option */ if (chip->codec_probe_mask != -1 && (chip->codec_probe_mask & AZX_FORCE_CODEC_MASK)) { - chip->codec_mask = chip->codec_probe_mask & 0xff; + azx_bus(chip)->codec_mask = chip->codec_probe_mask & 0xff; dev_info(chip->card->dev, "codec_mask forced to 0x%x\n", - chip->codec_mask); + (int)azx_bus(chip)->codec_mask); } } @@ -1373,12 +1553,15 @@ static void azx_probe_work(struct work_struct *work) /* * constructor */ +static const struct hdac_io_ops pci_hda_io_ops; +static const struct hda_controller_ops pci_hda_ops; + static int azx_create(struct snd_card *card, struct pci_dev *pci, int dev, unsigned int driver_caps, - const struct hda_controller_ops *hda_ops, struct azx **rchip) { static struct snd_device_ops ops = { + .dev_disconnect = azx_dev_disconnect, .dev_free = azx_dev_free, }; struct hda_intel *hda; @@ -1398,12 +1581,10 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci, } chip = &hda->chip; - spin_lock_init(&chip->reg_lock); mutex_init(&chip->open_mutex); chip->card = card; chip->pci = pci; - chip->ops = hda_ops; - chip->irq = -1; + chip->ops = &pci_hda_ops; chip->driver_caps = driver_caps; chip->driver_type = driver_caps & 0xff; check_msi(chip); @@ -1435,6 +1616,13 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci, } chip->bdl_pos_adj = bdl_pos_adj; + err = azx_bus_init(chip, model[dev], &pci_hda_io_ops); + if (err < 0) { + kfree(hda); + pci_disable_device(pci); + return err; + } + err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); if (err < 0) { dev_err(card->dev, "Error creating device [card]!\n"); @@ -1455,6 +1643,7 @@ static int azx_first_init(struct azx *chip) int dev = chip->dev_index; struct pci_dev *pci = chip->pci; struct snd_card *card = chip->card; + struct hdac_bus *bus = azx_bus(chip); int err; unsigned short gcap; unsigned int dma_bits = 64; @@ -1474,9 +1663,9 @@ static int azx_first_init(struct azx *chip) return err; chip->region_requested = 1; - chip->addr = pci_resource_start(pci, 0); - chip->remap_addr = pci_ioremap_bar(pci, 0); - if (chip->remap_addr == NULL) { + bus->addr = pci_resource_start(pci, 0); + bus->remap_addr = pci_ioremap_bar(pci, 0); + if (bus->remap_addr == NULL) { dev_err(card->dev, "ioremap error\n"); return -ENXIO; } @@ -1494,7 +1683,7 @@ static int azx_first_init(struct azx *chip) return -EBUSY; pci_set_master(pci); - synchronize_irq(chip->irq); + synchronize_irq(bus->irq); gcap = azx_readw(chip, GCAP); dev_dbg(card->dev, "chipset global capabilities = 0x%x\n", gcap); @@ -1536,11 +1725,11 @@ static int azx_first_init(struct azx *chip) /* allow 64bit DMA address if supported by H/W */ if (!(gcap & AZX_GCAP_64OK)) dma_bits = 32; - if (!pci_set_dma_mask(pci, DMA_BIT_MASK(dma_bits))) { - pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(dma_bits)); + if (!dma_set_mask(&pci->dev, DMA_BIT_MASK(dma_bits))) { + dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(dma_bits)); } else { - pci_set_dma_mask(pci, DMA_BIT_MASK(32)); - pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(32)); + dma_set_mask(&pci->dev, DMA_BIT_MASK(32)); + dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(32)); } /* read number of streams from GCAP register instead of using @@ -1571,17 +1760,15 @@ static int azx_first_init(struct azx *chip) chip->capture_index_offset = 0; chip->playback_index_offset = chip->capture_streams; chip->num_streams = chip->playback_streams + chip->capture_streams; - chip->azx_dev = kcalloc(chip->num_streams, sizeof(*chip->azx_dev), - GFP_KERNEL); - if (!chip->azx_dev) - return -ENOMEM; - err = azx_alloc_stream_pages(chip); + /* initialize streams */ + err = azx_init_streams(chip); if (err < 0) return err; - /* initialize streams */ - azx_init_stream(chip); + err = azx_alloc_stream_pages(chip); + if (err < 0) + return err; /* initialize chip */ azx_init_pci(chip); @@ -1593,10 +1780,10 @@ static int azx_first_init(struct azx *chip) haswell_set_bclk(hda); } - azx_init_chip(chip, (probe_only[dev] & 2) == 0); + hda_intel_init_chip(chip, (probe_only[dev] & 2) == 0); /* codec detection */ - if (!chip->codec_mask) { + if (!azx_bus(chip)->codec_mask) { dev_err(card->dev, "no codecs found!\n"); return -ENODEV; } @@ -1606,7 +1793,7 @@ static int azx_first_init(struct azx *chip) sizeof(card->shortname)); snprintf(card->longname, sizeof(card->longname), "%s at 0x%lx irq %i", - card->shortname, chip->addr, chip->irq); + card->shortname, bus->addr, bus->irq); return 0; } @@ -1675,10 +1862,11 @@ static u8 pci_azx_readb(u8 __iomem *addr) static int disable_msi_reset_irq(struct azx *chip) { + struct hdac_bus *bus = azx_bus(chip); int err; - free_irq(chip->irq, chip); - chip->irq = -1; + free_irq(bus->irq, chip); + bus->irq = -1; pci_disable_msi(chip->pci); chip->msi = 0; err = azx_acquire_irq(chip, 1); @@ -1689,15 +1877,16 @@ static int disable_msi_reset_irq(struct azx *chip) } /* DMA page allocation helpers. */ -static int dma_alloc_pages(struct azx *chip, +static int dma_alloc_pages(struct hdac_bus *bus, int type, size_t size, struct snd_dma_buffer *buf) { + struct azx *chip = bus_to_azx(bus); int err; err = snd_dma_alloc_pages(type, - chip->card->dev, + bus->dev, size, buf); if (err < 0) return err; @@ -1705,8 +1894,10 @@ static int dma_alloc_pages(struct azx *chip, return 0; } -static void dma_free_pages(struct azx *chip, struct snd_dma_buffer *buf) +static void dma_free_pages(struct hdac_bus *bus, struct snd_dma_buffer *buf) { + struct azx *chip = bus_to_azx(bus); + mark_pages_wc(chip, buf, false); snd_dma_free_pages(buf); } @@ -1719,9 +1910,6 @@ static int substream_alloc_pages(struct azx *chip, int ret; mark_runtime_wc(chip, azx_dev, substream, false); - azx_dev->bufsize = 0; - azx_dev->period_bytes = 0; - azx_dev->format_val = 0; ret = snd_pcm_lib_malloc_pages(substream, size); if (ret < 0) return ret; @@ -1748,20 +1936,24 @@ static void pcm_mmap_prepare(struct snd_pcm_substream *substream, #endif } -static const struct hda_controller_ops pci_hda_ops = { +static const struct hdac_io_ops pci_hda_io_ops = { .reg_writel = pci_azx_writel, .reg_readl = pci_azx_readl, .reg_writew = pci_azx_writew, .reg_readw = pci_azx_readw, .reg_writeb = pci_azx_writeb, .reg_readb = pci_azx_readb, - .disable_msi_reset_irq = disable_msi_reset_irq, .dma_alloc_pages = dma_alloc_pages, .dma_free_pages = dma_free_pages, +}; + +static const struct hda_controller_ops pci_hda_ops = { + .disable_msi_reset_irq = disable_msi_reset_irq, .substream_alloc_pages = substream_alloc_pages, .substream_free_pages = substream_free_pages, .pcm_mmap_prepare = pcm_mmap_prepare, .position_check = azx_position_check, + .link_power = azx_intel_link_power, }; static int azx_probe(struct pci_dev *pci, @@ -1788,8 +1980,7 @@ static int azx_probe(struct pci_dev *pci, return err; } - err = azx_create(card, pci, dev, pci_id->driver_data, - &pci_hda_ops, &chip); + err = azx_create(card, pci, dev, pci_id->driver_data, &chip); if (err < 0) goto out_free; card->private_data = chip; @@ -1799,7 +1990,7 @@ static int azx_probe(struct pci_dev *pci, err = register_vga_switcheroo(chip); if (err < 0) { - dev_err(card->dev, "Error registering VGA-switcheroo client\n"); + dev_err(card->dev, "Error registering vga_switcheroo client\n"); goto out_free; } @@ -1851,14 +2042,24 @@ static unsigned int azx_max_codecs[AZX_NUM_DRIVERS] = { static int azx_probe_continue(struct azx *chip) { struct hda_intel *hda = container_of(chip, struct hda_intel, chip); + struct hdac_bus *bus = azx_bus(chip); struct pci_dev *pci = chip->pci; int dev = chip->dev_index; int err; - /* Request power well for Haswell HDA controller and codec */ + hda->probe_continued = 1; + + /* 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. + */ if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) { -#ifdef CONFIG_SND_HDA_I915 - err = hda_i915_init(hda); + /* HSW/BDW controllers need this power */ + if (CONTROLLER_IN_GPU(pci)) + hda->need_i915_power = 1; + + err = snd_hdac_i915_init(bus); if (err < 0) { /* if the controller is bound only with HDMI/DP * (for HSW and BDW), we need to abort the probe; @@ -1870,18 +2071,16 @@ static int azx_probe_continue(struct azx *chip) else goto skip_i915; } - err = hda_display_power(hda, true); + + err = snd_hdac_display_power(bus, true); if (err < 0) { dev_err(chip->card->dev, "Cannot turn on display power on i915\n"); - goto out_free; + goto i915_power_fail; } -#endif } -#ifdef CONFIG_SND_HDA_I915 skip_i915: -#endif err = azx_first_init(chip); if (err < 0) goto out_free; @@ -1891,17 +2090,13 @@ static int azx_probe_continue(struct azx *chip) #endif /* create codec instances */ - err = azx_bus_create(chip, model[dev]); - if (err < 0) - goto out_free; - err = azx_probe_codecs(chip, azx_max_codecs[chip->driver_type]); if (err < 0) goto out_free; #ifdef CONFIG_SND_HDA_PATCH_LOADER if (chip->fw) { - err = snd_hda_load_patch(chip->bus, chip->fw->size, + err = snd_hda_load_patch(&chip->bus, chip->fw->size, chip->fw->data); if (err < 0) goto out_free; @@ -1923,11 +2118,16 @@ static int azx_probe_continue(struct azx *chip) chip->running = 1; azx_add_card_list(chip); - snd_hda_set_power_save(chip->bus, power_save * 1000); + snd_hda_set_power_save(&chip->bus, power_save * 1000); if (azx_has_pm_runtime(chip) || hda->use_vga_switcheroo) pm_runtime_put_noidle(&pci->dev); out_free: + if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL + && !hda->need_i915_power) + snd_hdac_display_power(bus, false); + +i915_power_fail: if (err < 0) hda->init_failed = 1; complete_all(&hda->probe_wait); @@ -1937,9 +2137,17 @@ out_free: static void azx_remove(struct pci_dev *pci) { struct snd_card *card = pci_get_drvdata(pci); + struct azx *chip; + struct hda_intel *hda; + + if (card) { + /* cancel the pending probing work */ + chip = card->private_data; + hda = container_of(chip, struct hda_intel, chip); + cancel_work_sync(&hda->probe_work); - if (card) snd_card_free(card); + } } static void azx_shutdown(struct pci_dev *pci) @@ -1976,6 +2184,11 @@ static const struct pci_device_id azx_ids[] = { .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, { PCI_DEVICE(0x8086, 0x8d21), .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, + /* Lewisburg */ + { PCI_DEVICE(0x8086, 0xa1f0), + .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, + { PCI_DEVICE(0x8086, 0xa270), + .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, /* Lynx Point-LP */ { PCI_DEVICE(0x8086, 0x9c20), .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, @@ -1991,6 +2204,9 @@ static const struct pci_device_id azx_ids[] = { /* Sunrise Point-LP */ { PCI_DEVICE(0x8086, 0x9d70), .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE }, + /* Broxton-P(Apollolake) */ + { PCI_DEVICE(0x8086, 0x5a98), + .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_BROXTON }, /* Haswell */ { PCI_DEVICE(0x8086, 0x0a0c), .driver_data = AZX_DRIVER_HDMI | AZX_DCAPS_INTEL_HASWELL }, @@ -2156,11 +2372,13 @@ static const struct pci_device_id azx_ids[] = { .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, .class_mask = 0xffffff, .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND | + AZX_DCAPS_NO_64BIT | AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_POSFIX_LPIB }, #else /* this entry seems still valid -- i.e. without emu20kx chip */ { PCI_DEVICE(0x1102, 0x0009), .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND | + AZX_DCAPS_NO_64BIT | AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_POSFIX_LPIB }, #endif /* CM8888 */ |