Merge branch 'for-linus' into for-next
[deliverable/linux.git] / sound / pci / hda / hda_intel.c
index 963f82430938a976826074bfe41f33f286e3fbe1..83800ac6ebd782512d004311ee5004dc4fa097de 100644 (file)
@@ -284,13 +284,19 @@ enum {
        (AZX_DCAPS_OLD_SSYNC | AZX_DCAPS_NO_ALIGN_BUFSIZE)
 
 /* quirks for Intel PCH */
-#define AZX_DCAPS_INTEL_PCH_NOPM \
+#define AZX_DCAPS_INTEL_PCH_BASE \
        (AZX_DCAPS_NO_ALIGN_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY |\
-        AZX_DCAPS_REVERSE_ASSIGN | AZX_DCAPS_SNOOP_TYPE(SCH))
+        AZX_DCAPS_SNOOP_TYPE(SCH))
+
+/* PCH up to IVB; no runtime PM */
+#define AZX_DCAPS_INTEL_PCH_NOPM \
+       (AZX_DCAPS_INTEL_PCH_BASE)
 
+/* PCH for HSW/BDW; with runtime PM */
 #define AZX_DCAPS_INTEL_PCH \
-       (AZX_DCAPS_INTEL_PCH_NOPM | AZX_DCAPS_PM_RUNTIME)
+       (AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_PM_RUNTIME)
 
+/* HSW HDMI */
 #define AZX_DCAPS_INTEL_HASWELL \
        (/*AZX_DCAPS_ALIGN_BUFSIZE |*/ AZX_DCAPS_COUNT_LPIB_DELAY |\
         AZX_DCAPS_PM_RUNTIME | AZX_DCAPS_I915_POWERWELL |\
@@ -332,7 +338,7 @@ enum {
 
 /* quirks for Nvidia */
 #define AZX_DCAPS_PRESET_NVIDIA \
-       (AZX_DCAPS_RIRB_DELAY | AZX_DCAPS_NO_MSI | /*AZX_DCAPS_ALIGN_BUFSIZE |*/ \
+       (AZX_DCAPS_NO_MSI | /*AZX_DCAPS_ALIGN_BUFSIZE |*/ \
         AZX_DCAPS_NO_64BIT | AZX_DCAPS_CORBRP_SELF_CLEAR |\
         AZX_DCAPS_SNOOP_TYPE(NVIDIA))
 
@@ -355,6 +361,8 @@ enum {
                                        ((pci)->device == 0x0d0c) || \
                                        ((pci)->device == 0x160c))
 
+#define IS_BROXTON(pci)        ((pci)->device == 0x5a98)
+
 static char *driver_short_names[] = {
        [AZX_DRIVER_ICH] = "HDA Intel",
        [AZX_DRIVER_PCH] = "HDA Intel PCH",
@@ -506,15 +514,36 @@ 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;
 
        if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
                snd_hdac_set_codec_wakeup(bus, true);
        azx_init_chip(chip, full_reset);
        if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
                snd_hdac_set_codec_wakeup(bus, false);
+
+       /* reduce dma latency to avoid noise */
+       if (IS_BROXTON(pci))
+               bxt_reduce_dma_latency(chip);
 }
 
 /* calculate runtime delay from LPIB */
@@ -626,7 +655,7 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev)
        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;
+               return chip->bdl_pos_adj ? 0 : -1;
        azx_dev->core.start_wallclk += wallclk;
        return 1; /* OK, it's fine */
 }
@@ -931,6 +960,36 @@ static int azx_resume(struct device *dev)
 }
 #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
+ */
+#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 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)
 {
@@ -1040,6 +1099,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)
 };
 
@@ -1319,7 +1382,7 @@ static int check_position_fix(struct azx *chip, int fix)
        }
 
        /* Check VIA/ATI HD Audio Controller exist */
-       if (chip->driver_caps & AZX_DCAPS_POSFIX_VIA) {
+       if (chip->driver_type == AZX_DRIVER_VIA) {
                dev_dbg(chip->card->dev, "Using VIACOMBO position fix\n");
                return POS_FIX_VIACOMBO;
        }
@@ -1482,6 +1545,26 @@ static void azx_probe_work(struct work_struct *work)
        azx_probe_continue(&hda->chip);
 }
 
+static int default_bdl_pos_adj(struct azx *chip)
+{
+       /* 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;
+               }
+       }
+
+       switch (chip->driver_type) {
+       case AZX_DRIVER_ICH:
+       case AZX_DRIVER_PCH:
+               return 1;
+       default:
+               return 32;
+       }
+}
+
 /*
  * constructor
  */
@@ -1535,18 +1618,10 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
        chip->single_cmd = single_cmd;
        azx_check_snoop_available(chip);
 
-       if (bdl_pos_adj[dev] < 0) {
-               switch (chip->driver_type) {
-               case AZX_DRIVER_ICH:
-               case AZX_DRIVER_PCH:
-                       bdl_pos_adj[dev] = 1;
-                       break;
-               default:
-                       bdl_pos_adj[dev] = 32;
-                       break;
-               }
-       }
-       chip->bdl_pos_adj = bdl_pos_adj;
+       if (bdl_pos_adj[dev] < 0)
+               chip->bdl_pos_adj = default_bdl_pos_adj(chip);
+       else
+               chip->bdl_pos_adj = bdl_pos_adj[dev];
 
        err = azx_bus_init(chip, model[dev], &pci_hda_io_ops);
        if (err < 0) {
@@ -1555,6 +1630,11 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
                return err;
        }
 
+       if (chip->driver_type == AZX_DRIVER_NVIDIA) {
+               dev_dbg(chip->card->dev, "Enable delay in RIRB handling\n");
+               chip->bus.needs_damn_long_delay = 1;
+       }
+
        err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
        if (err < 0) {
                dev_err(card->dev, "Error creating device [card]!\n");
@@ -1948,8 +2028,8 @@ static int azx_probe(struct pci_dev *pci,
 #endif /* CONFIG_SND_HDA_PATCH_LOADER */
 
 #ifndef CONFIG_SND_HDA_I915
-       if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
-               dev_err(card->dev, "Haswell must build in CONFIG_SND_HDA_I915\n");
+       if (CONTROLLER_IN_GPU(pci))
+               dev_err(card->dev, "Haswell/Broadwell HDMI/DP must build in CONFIG_SND_HDA_I915\n");
 #endif
 
        if (schedule_probe)
@@ -2146,10 +2226,10 @@ static const struct pci_device_id azx_ids[] = {
          .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_NOPM },
        /* Poulsbo */
        { PCI_DEVICE(0x8086, 0x811b),
-         .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_NOPM },
+         .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_BASE },
        /* Oaktrail */
        { PCI_DEVICE(0x8086, 0x080a),
-         .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_NOPM },
+         .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_BASE },
        /* BayTrail */
        { PCI_DEVICE(0x8086, 0x0f04),
          .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_BAYTRAIL },
@@ -2261,8 +2341,7 @@ static const struct pci_device_id azx_ids[] = {
        { PCI_DEVICE(0x1002, 0xaae8),
          .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
        /* VIA VT8251/VT8237A */
-       { PCI_DEVICE(0x1106, 0x3288),
-         .driver_data = AZX_DRIVER_VIA | AZX_DCAPS_POSFIX_VIA },
+       { PCI_DEVICE(0x1106, 0x3288), .driver_data = AZX_DRIVER_VIA },
        /* VIA GFX VT7122/VX900 */
        { PCI_DEVICE(0x1106, 0x9170), .driver_data = AZX_DRIVER_GENERIC },
        /* VIA GFX VT6122/VX11 */
@@ -2296,14 +2375,12 @@ 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 },
+         AZX_DCAPS_NO_64BIT | 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 },
+         AZX_DCAPS_NO_64BIT | AZX_DCAPS_POSFIX_LPIB },
 #endif
        /* CM8888 */
        { PCI_DEVICE(0x13f6, 0x5011),
This page took 0.029043 seconds and 5 git commands to generate.