Merge tag 'ras_for_3.20' of git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp into...
[cascardo/linux.git] / sound / pci / hda / hda_intel.c
index 243ffad..d426a0b 100644 (file)
@@ -196,8 +196,8 @@ MODULE_PARM_DESC(align_buffer_size,
                "Force buffer and period sizes to be multiple of 128 bytes.");
 
 #ifdef CONFIG_X86
-static bool hda_snoop = true;
-module_param_named(snoop, hda_snoop, bool, 0444);
+static int hda_snoop = -1;
+module_param_named(snoop, hda_snoop, bint, 0444);
 MODULE_PARM_DESC(snoop, "Enable/disable snooping");
 #else
 #define hda_snoop              true
@@ -272,43 +272,59 @@ enum {
        AZX_NUM_DRIVERS, /* keep this as last entry */
 };
 
+#define azx_get_snoop_type(chip) \
+       (((chip)->driver_caps & AZX_DCAPS_SNOOP_MASK) >> 10)
+#define AZX_DCAPS_SNOOP_TYPE(type) ((AZX_SNOOP_TYPE_ ## type) << 10)
+
+/* quirks for old Intel chipsets */
+#define AZX_DCAPS_INTEL_ICH \
+       (AZX_DCAPS_OLD_SSYNC | AZX_DCAPS_NO_ALIGN_BUFSIZE)
+
 /* quirks for Intel PCH */
 #define AZX_DCAPS_INTEL_PCH_NOPM \
-       (AZX_DCAPS_SCH_SNOOP | AZX_DCAPS_BUFSIZE | \
-        AZX_DCAPS_COUNT_LPIB_DELAY | AZX_DCAPS_REVERSE_ASSIGN)
+       (AZX_DCAPS_NO_ALIGN_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY |\
+        AZX_DCAPS_REVERSE_ASSIGN | AZX_DCAPS_SNOOP_TYPE(SCH))
 
 #define AZX_DCAPS_INTEL_PCH \
        (AZX_DCAPS_INTEL_PCH_NOPM | AZX_DCAPS_PM_RUNTIME)
 
 #define AZX_DCAPS_INTEL_HASWELL \
-       (AZX_DCAPS_SCH_SNOOP | AZX_DCAPS_ALIGN_BUFSIZE | \
-        AZX_DCAPS_COUNT_LPIB_DELAY | AZX_DCAPS_PM_RUNTIME | \
-        AZX_DCAPS_I915_POWERWELL)
+       (/*AZX_DCAPS_ALIGN_BUFSIZE |*/ AZX_DCAPS_COUNT_LPIB_DELAY |\
+        AZX_DCAPS_PM_RUNTIME | AZX_DCAPS_I915_POWERWELL |\
+        AZX_DCAPS_SNOOP_TYPE(SCH))
 
 /* Broadwell HDMI can't use position buffer reliably, force to use LPIB */
 #define AZX_DCAPS_INTEL_BROADWELL \
-       (AZX_DCAPS_SCH_SNOOP | AZX_DCAPS_ALIGN_BUFSIZE | \
-        AZX_DCAPS_POSFIX_LPIB | AZX_DCAPS_PM_RUNTIME | \
-        AZX_DCAPS_I915_POWERWELL)
+       (/*AZX_DCAPS_ALIGN_BUFSIZE |*/ AZX_DCAPS_POSFIX_LPIB |\
+        AZX_DCAPS_PM_RUNTIME | AZX_DCAPS_I915_POWERWELL |\
+        AZX_DCAPS_SNOOP_TYPE(SCH))
+
+#define AZX_DCAPS_INTEL_SKYLAKE \
+       (AZX_DCAPS_INTEL_PCH | AZX_DCAPS_SEPARATE_STREAM_TAG)
 
 /* quirks for ATI SB / AMD Hudson */
 #define AZX_DCAPS_PRESET_ATI_SB \
-       (AZX_DCAPS_ATI_SNOOP | AZX_DCAPS_NO_TCSEL | \
-        AZX_DCAPS_SYNC_WRITE | AZX_DCAPS_POSFIX_LPIB)
+       (AZX_DCAPS_NO_TCSEL | AZX_DCAPS_SYNC_WRITE | AZX_DCAPS_POSFIX_LPIB |\
+        AZX_DCAPS_SNOOP_TYPE(ATI))
 
 /* quirks for ATI/AMD HDMI */
 #define AZX_DCAPS_PRESET_ATI_HDMI \
        (AZX_DCAPS_NO_TCSEL | AZX_DCAPS_SYNC_WRITE | AZX_DCAPS_POSFIX_LPIB|\
         AZX_DCAPS_NO_MSI64)
 
+/* quirks for ATI HDMI with snoop off */
+#define AZX_DCAPS_PRESET_ATI_HDMI_NS \
+       (AZX_DCAPS_PRESET_ATI_HDMI | AZX_DCAPS_SNOOP_OFF)
+
 /* quirks for Nvidia */
 #define AZX_DCAPS_PRESET_NVIDIA \
-       (AZX_DCAPS_NVIDIA_SNOOP | AZX_DCAPS_RIRB_DELAY | AZX_DCAPS_NO_MSI |\
-        AZX_DCAPS_ALIGN_BUFSIZE | AZX_DCAPS_NO_64BIT |\
-        AZX_DCAPS_CORBRP_SELF_CLEAR)
+       (AZX_DCAPS_RIRB_DELAY | AZX_DCAPS_NO_MSI | /*AZX_DCAPS_ALIGN_BUFSIZE |*/ \
+        AZX_DCAPS_NO_64BIT | AZX_DCAPS_CORBRP_SELF_CLEAR |\
+        AZX_DCAPS_SNOOP_TYPE(NVIDIA))
 
 #define AZX_DCAPS_PRESET_CTHDA \
-       (AZX_DCAPS_NO_MSI | AZX_DCAPS_POSFIX_LPIB | AZX_DCAPS_4K_BDLE_BOUNDARY)
+       (AZX_DCAPS_NO_MSI | AZX_DCAPS_POSFIX_LPIB |\
+        AZX_DCAPS_4K_BDLE_BOUNDARY | AZX_DCAPS_SNOOP_OFF)
 
 /*
  * VGA-switcher support
@@ -437,6 +453,8 @@ static void update_pci_byte(struct pci_dev *pci, unsigned int reg,
 
 static void azx_init_pci(struct azx *chip)
 {
+       int snoop_type = azx_get_snoop_type(chip);
+
        /* Clear bits 0-2 of PCI register TCSEL (at offset 0x44)
         * TCSEL == Traffic Class Select Register, which sets PCI express QOS
         * Ensuring these bits are 0 clears playback static on some HD Audio
@@ -451,7 +469,7 @@ static void azx_init_pci(struct azx *chip)
        /* For ATI SB450/600/700/800/900 and AMD Hudson azalia HD audio,
         * we need to enable snoop.
         */
-       if (chip->driver_caps & AZX_DCAPS_ATI_SNOOP) {
+       if (snoop_type == AZX_SNOOP_TYPE_ATI) {
                dev_dbg(chip->card->dev, "Setting ATI snoop: %d\n",
                        azx_snoop(chip));
                update_pci_byte(chip->pci,
@@ -460,7 +478,7 @@ static void azx_init_pci(struct azx *chip)
        }
 
        /* For NVIDIA HDA, enable snoop */
-       if (chip->driver_caps & AZX_DCAPS_NVIDIA_SNOOP) {
+       if (snoop_type == AZX_SNOOP_TYPE_NVIDIA) {
                dev_dbg(chip->card->dev, "Setting Nvidia snoop: %d\n",
                        azx_snoop(chip));
                update_pci_byte(chip->pci,
@@ -475,7 +493,7 @@ static void azx_init_pci(struct azx *chip)
        }
 
        /* Enable SCH/PCH snoop if needed */
-       if (chip->driver_caps & AZX_DCAPS_SCH_SNOOP) {
+       if (snoop_type == AZX_SNOOP_TYPE_SCH) {
                unsigned short snoop;
                pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop);
                if ((!azx_snoop(chip) && !(snoop & INTEL_SCH_HDA_DEVC_NOSNOOP)) ||
@@ -1129,8 +1147,7 @@ static int azx_free(struct azx *chip)
        pci_disable_device(chip->pci);
        kfree(chip->azx_dev);
 #ifdef CONFIG_SND_HDA_PATCH_LOADER
-       if (chip->fw)
-               release_firmware(chip->fw);
+       release_firmware(chip->fw);
 #endif
        if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
                hda_display_power(false);
@@ -1358,35 +1375,33 @@ static void check_msi(struct azx *chip)
 /* check the snoop mode availability */
 static void azx_check_snoop_available(struct azx *chip)
 {
-       bool snoop = chip->snoop;
+       int snoop = hda_snoop;
+
+       if (snoop >= 0) {
+               dev_info(chip->card->dev, "Force to %s mode by module option\n",
+                        snoop ? "snoop" : "non-snoop");
+               chip->snoop = snoop;
+               return;
+       }
 
-       switch (chip->driver_type) {
-       case AZX_DRIVER_VIA:
+       snoop = true;
+       if (azx_get_snoop_type(chip) == AZX_SNOOP_TYPE_NONE &&
+           chip->driver_type == AZX_DRIVER_VIA) {
                /* force to non-snoop mode for a new VIA controller
                 * when BIOS is set
                 */
-               if (snoop) {
-                       u8 val;
-                       pci_read_config_byte(chip->pci, 0x42, &val);
-                       if (!(val & 0x80) && chip->pci->revision == 0x30)
-                               snoop = false;
-               }
-               break;
-       case AZX_DRIVER_ATIHDMI_NS:
-               /* new ATI HDMI requires non-snoop */
-               snoop = false;
-               break;
-       case AZX_DRIVER_CTHDA:
-       case AZX_DRIVER_CMEDIA:
-               snoop = false;
-               break;
+               u8 val;
+               pci_read_config_byte(chip->pci, 0x42, &val);
+               if (!(val & 0x80) && chip->pci->revision == 0x30)
+                       snoop = false;
        }
 
-       if (snoop != chip->snoop) {
-               dev_info(chip->card->dev, "Force to %s mode\n",
-                        snoop ? "snoop" : "non-snoop");
-               chip->snoop = snoop;
-       }
+       if (chip->driver_caps & AZX_DCAPS_SNOOP_OFF)
+               snoop = false;
+
+       chip->snoop = snoop;
+       if (!snoop)
+               dev_info(chip->card->dev, "Force to non-snoop mode\n");
 }
 
 static void azx_probe_work(struct work_struct *work)
@@ -1446,7 +1461,6 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
        check_probe_mask(chip, dev);
 
        chip->single_cmd = single_cmd;
-       chip->snoop = hda_snoop;
        azx_check_snoop_available(chip);
 
        if (bdl_pos_adj[dev] < 0) {
@@ -1554,10 +1568,8 @@ static int azx_first_init(struct azx *chip)
        if (align_buffer_size >= 0)
                chip->align_buffer_size = !!align_buffer_size;
        else {
-               if (chip->driver_caps & AZX_DCAPS_BUFSIZE)
+               if (chip->driver_caps & AZX_DCAPS_NO_ALIGN_BUFSIZE)
                        chip->align_buffer_size = 0;
-               else if (chip->driver_caps & AZX_DCAPS_ALIGN_BUFSIZE)
-                       chip->align_buffer_size = 1;
                else
                        chip->align_buffer_size = 1;
        }
@@ -2018,7 +2030,7 @@ static const struct pci_device_id azx_ids[] = {
          .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
        /* Sunrise Point-LP */
        { PCI_DEVICE(0x8086, 0x9d70),
-         .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
+         .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE },
        /* Haswell */
        { PCI_DEVICE(0x8086, 0x0a0c),
          .driver_data = AZX_DRIVER_HDMI | AZX_DCAPS_INTEL_HASWELL },
@@ -2044,36 +2056,35 @@ static const struct pci_device_id azx_ids[] = {
        /* Braswell */
        { PCI_DEVICE(0x8086, 0x2284),
          .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
-       /* ICH */
+       /* ICH6 */
        { PCI_DEVICE(0x8086, 0x2668),
-         .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
-         AZX_DCAPS_BUFSIZE },  /* ICH6 */
+         .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH },
+       /* ICH7 */
        { PCI_DEVICE(0x8086, 0x27d8),
-         .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
-         AZX_DCAPS_BUFSIZE },  /* ICH7 */
+         .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH },
+       /* ESB2 */
        { PCI_DEVICE(0x8086, 0x269a),
-         .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
-         AZX_DCAPS_BUFSIZE },  /* ESB2 */
+         .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH },
+       /* ICH8 */
        { PCI_DEVICE(0x8086, 0x284b),
-         .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
-         AZX_DCAPS_BUFSIZE },  /* ICH8 */
+         .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH },
+       /* ICH9 */
        { PCI_DEVICE(0x8086, 0x293e),
-         .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
-         AZX_DCAPS_BUFSIZE },  /* ICH9 */
+         .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH },
+       /* ICH9 */
        { PCI_DEVICE(0x8086, 0x293f),
-         .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
-         AZX_DCAPS_BUFSIZE },  /* ICH9 */
+         .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH },
+       /* ICH10 */
        { PCI_DEVICE(0x8086, 0x3a3e),
-         .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
-         AZX_DCAPS_BUFSIZE },  /* ICH10 */
+         .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH },
+       /* ICH10 */
        { PCI_DEVICE(0x8086, 0x3a6e),
-         .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
-         AZX_DCAPS_BUFSIZE },  /* ICH10 */
+         .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH },
        /* Generic Intel */
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_ANY_ID),
          .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
          .class_mask = 0xffffff,
-         .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_BUFSIZE },
+         .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_NO_ALIGN_BUFSIZE },
        /* ATI SB 450/600/700/800/900 */
        { PCI_DEVICE(0x1002, 0x437b),
          .driver_data = AZX_DRIVER_ATI | AZX_DCAPS_PRESET_ATI_SB },
@@ -2128,13 +2139,13 @@ static const struct pci_device_id azx_ids[] = {
        { PCI_DEVICE(0x1002, 0xaa98),
          .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
        { PCI_DEVICE(0x1002, 0x9902),
-         .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI },
+         .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
        { PCI_DEVICE(0x1002, 0xaaa0),
-         .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI },
+         .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
        { PCI_DEVICE(0x1002, 0xaaa8),
-         .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI },
+         .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
        { PCI_DEVICE(0x1002, 0xaab0),
-         .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI },
+         .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 },
@@ -2181,7 +2192,7 @@ static const struct pci_device_id azx_ids[] = {
        /* CM8888 */
        { PCI_DEVICE(0x13f6, 0x5011),
          .driver_data = AZX_DRIVER_CMEDIA |
-         AZX_DCAPS_NO_MSI | AZX_DCAPS_POSFIX_LPIB },
+         AZX_DCAPS_NO_MSI | AZX_DCAPS_POSFIX_LPIB | AZX_DCAPS_SNOOP_OFF },
        /* Vortex86MX */
        { PCI_DEVICE(0x17f3, 0x3010), .driver_data = AZX_DRIVER_GENERIC },
        /* VMware HDAudio */