diff options
-rw-r--r-- | Documentation/sound/alsa/ALSA-Configuration.txt | 1 | ||||
-rw-r--r-- | sound/pci/hda/hda_intel.c | 148 |
2 files changed, 130 insertions, 19 deletions
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index 27126c469f70..936699e4f04b 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt | |||
@@ -891,6 +891,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
891 | access but isn't required by the HDA spec and prevents | 891 | access but isn't required by the HDA spec and prevents |
892 | users from specifying exact period/buffer sizes. | 892 | users from specifying exact period/buffer sizes. |
893 | (default = on) | 893 | (default = on) |
894 | snoop - Enable/disable snooping (default = on) | ||
894 | 895 | ||
895 | This module supports multiple cards and autoprobe. | 896 | This module supports multiple cards and autoprobe. |
896 | 897 | ||
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 2a8bed94d4fa..fbf5cfc9b2be 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -34,7 +34,6 @@ | |||
34 | * | 34 | * |
35 | */ | 35 | */ |
36 | 36 | ||
37 | #include <asm/io.h> | ||
38 | #include <linux/delay.h> | 37 | #include <linux/delay.h> |
39 | #include <linux/interrupt.h> | 38 | #include <linux/interrupt.h> |
40 | #include <linux/kernel.h> | 39 | #include <linux/kernel.h> |
@@ -46,6 +45,12 @@ | |||
46 | #include <linux/pci.h> | 45 | #include <linux/pci.h> |
47 | #include <linux/mutex.h> | 46 | #include <linux/mutex.h> |
48 | #include <linux/reboot.h> | 47 | #include <linux/reboot.h> |
48 | #include <linux/io.h> | ||
49 | #ifdef CONFIG_X86 | ||
50 | /* for snoop control */ | ||
51 | #include <asm/pgtable.h> | ||
52 | #include <asm/cacheflush.h> | ||
53 | #endif | ||
49 | #include <sound/core.h> | 54 | #include <sound/core.h> |
50 | #include <sound/initval.h> | 55 | #include <sound/initval.h> |
51 | #include "hda_codec.h" | 56 | #include "hda_codec.h" |
@@ -121,6 +126,17 @@ module_param(align_buffer_size, bool, 0644); | |||
121 | MODULE_PARM_DESC(align_buffer_size, | 126 | MODULE_PARM_DESC(align_buffer_size, |
122 | "Force buffer and period sizes to be multiple of 128 bytes."); | 127 | "Force buffer and period sizes to be multiple of 128 bytes."); |
123 | 128 | ||
129 | #ifdef CONFIG_X86 | ||
130 | static bool hda_snoop = true; | ||
131 | module_param_named(snoop, hda_snoop, bool, 0444); | ||
132 | MODULE_PARM_DESC(snoop, "Enable/disable snooping"); | ||
133 | #define azx_snoop(chip) (chip)->snoop | ||
134 | #else | ||
135 | #define hda_snoop true | ||
136 | #define azx_snoop(chip) true | ||
137 | #endif | ||
138 | |||
139 | |||
124 | MODULE_LICENSE("GPL"); | 140 | MODULE_LICENSE("GPL"); |
125 | MODULE_SUPPORTED_DEVICE("{{Intel, ICH6}," | 141 | MODULE_SUPPORTED_DEVICE("{{Intel, ICH6}," |
126 | "{Intel, ICH6M}," | 142 | "{Intel, ICH6M}," |
@@ -376,6 +392,7 @@ struct azx_dev { | |||
376 | * when link position is not greater than FIFO size | 392 | * when link position is not greater than FIFO size |
377 | */ | 393 | */ |
378 | unsigned int insufficient :1; | 394 | unsigned int insufficient :1; |
395 | unsigned int wc_marked:1; | ||
379 | }; | 396 | }; |
380 | 397 | ||
381 | /* CORB/RIRB */ | 398 | /* CORB/RIRB */ |
@@ -443,6 +460,7 @@ struct azx { | |||
443 | unsigned int msi :1; | 460 | unsigned int msi :1; |
444 | unsigned int irq_pending_warned :1; | 461 | unsigned int irq_pending_warned :1; |
445 | unsigned int probing :1; /* codec probing phase */ | 462 | unsigned int probing :1; /* codec probing phase */ |
463 | unsigned int snoop:1; | ||
446 | 464 | ||
447 | /* for debugging */ | 465 | /* for debugging */ |
448 | unsigned int last_cmd[AZX_MAX_CODECS]; | 466 | unsigned int last_cmd[AZX_MAX_CODECS]; |
@@ -548,6 +566,45 @@ static char *driver_short_names[] __devinitdata = { | |||
548 | /* for pcm support */ | 566 | /* for pcm support */ |
549 | #define get_azx_dev(substream) (substream->runtime->private_data) | 567 | #define get_azx_dev(substream) (substream->runtime->private_data) |
550 | 568 | ||
569 | #ifdef CONFIG_X86 | ||
570 | static void __mark_pages_wc(struct azx *chip, void *addr, size_t size, bool on) | ||
571 | { | ||
572 | if (azx_snoop(chip)) | ||
573 | return; | ||
574 | if (addr && size) { | ||
575 | int pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; | ||
576 | if (on) | ||
577 | set_memory_wc((unsigned long)addr, pages); | ||
578 | else | ||
579 | set_memory_wb((unsigned long)addr, pages); | ||
580 | } | ||
581 | } | ||
582 | |||
583 | static inline void mark_pages_wc(struct azx *chip, struct snd_dma_buffer *buf, | ||
584 | bool on) | ||
585 | { | ||
586 | __mark_pages_wc(chip, buf->area, buf->bytes, on); | ||
587 | } | ||
588 | static inline void mark_runtime_wc(struct azx *chip, struct azx_dev *azx_dev, | ||
589 | struct snd_pcm_runtime *runtime, bool on) | ||
590 | { | ||
591 | if (azx_dev->wc_marked != on) { | ||
592 | __mark_pages_wc(chip, runtime->dma_area, runtime->dma_bytes, on); | ||
593 | azx_dev->wc_marked = on; | ||
594 | } | ||
595 | } | ||
596 | #else | ||
597 | /* NOP for other archs */ | ||
598 | static inline void mark_pages_wc(struct azx *chip, struct snd_dma_buffer *buf, | ||
599 | bool on) | ||
600 | { | ||
601 | } | ||
602 | static inline void mark_runtime_wc(struct azx *chip, struct azx_dev *azx_dev, | ||
603 | struct snd_pcm_runtime *runtime, bool on) | ||
604 | { | ||
605 | } | ||
606 | #endif | ||
607 | |||
551 | static int azx_acquire_irq(struct azx *chip, int do_disconnect); | 608 | static int azx_acquire_irq(struct azx *chip, int do_disconnect); |
552 | static int azx_send_cmd(struct hda_bus *bus, unsigned int val); | 609 | static int azx_send_cmd(struct hda_bus *bus, unsigned int val); |
553 | /* | 610 | /* |
@@ -569,6 +626,7 @@ static int azx_alloc_cmd_io(struct azx *chip) | |||
569 | snd_printk(KERN_ERR SFX "cannot allocate CORB/RIRB\n"); | 626 | snd_printk(KERN_ERR SFX "cannot allocate CORB/RIRB\n"); |
570 | return err; | 627 | return err; |
571 | } | 628 | } |
629 | mark_pages_wc(chip, &chip->rb, true); | ||
572 | return 0; | 630 | return 0; |
573 | } | 631 | } |
574 | 632 | ||
@@ -1085,7 +1143,15 @@ static void update_pci_byte(struct pci_dev *pci, unsigned int reg, | |||
1085 | 1143 | ||
1086 | static void azx_init_pci(struct azx *chip) | 1144 | static void azx_init_pci(struct azx *chip) |
1087 | { | 1145 | { |
1088 | unsigned short snoop; | 1146 | /* force to non-snoop mode for a new VIA controller when BIOS is set */ |
1147 | if (chip->snoop && chip->driver_type == AZX_DRIVER_VIA) { | ||
1148 | u8 snoop; | ||
1149 | pci_read_config_byte(chip->pci, 0x42, &snoop); | ||
1150 | if (!(snoop & 0x80) && chip->pci->revision == 0x30) { | ||
1151 | chip->snoop = 0; | ||
1152 | snd_printdd(SFX "Force to non-snoop mode\n"); | ||
1153 | } | ||
1154 | } | ||
1089 | 1155 | ||
1090 | /* Clear bits 0-2 of PCI register TCSEL (at offset 0x44) | 1156 | /* Clear bits 0-2 of PCI register TCSEL (at offset 0x44) |
1091 | * TCSEL == Traffic Class Select Register, which sets PCI express QOS | 1157 | * TCSEL == Traffic Class Select Register, which sets PCI express QOS |
@@ -1102,15 +1168,15 @@ static void azx_init_pci(struct azx *chip) | |||
1102 | * we need to enable snoop. | 1168 | * we need to enable snoop. |
1103 | */ | 1169 | */ |
1104 | if (chip->driver_caps & AZX_DCAPS_ATI_SNOOP) { | 1170 | if (chip->driver_caps & AZX_DCAPS_ATI_SNOOP) { |
1105 | snd_printdd(SFX "Enabling ATI snoop\n"); | 1171 | snd_printdd(SFX "Setting ATI snoop: %d\n", azx_snoop(chip)); |
1106 | update_pci_byte(chip->pci, | 1172 | update_pci_byte(chip->pci, |
1107 | ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, | 1173 | ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, 0x07, |
1108 | 0x07, ATI_SB450_HDAUDIO_ENABLE_SNOOP); | 1174 | azx_snoop(chip) ? ATI_SB450_HDAUDIO_ENABLE_SNOOP : 0); |
1109 | } | 1175 | } |
1110 | 1176 | ||
1111 | /* For NVIDIA HDA, enable snoop */ | 1177 | /* For NVIDIA HDA, enable snoop */ |
1112 | if (chip->driver_caps & AZX_DCAPS_NVIDIA_SNOOP) { | 1178 | if (chip->driver_caps & AZX_DCAPS_NVIDIA_SNOOP) { |
1113 | snd_printdd(SFX "Enabling Nvidia snoop\n"); | 1179 | snd_printdd(SFX "Setting Nvidia snoop: %d\n", azx_snoop(chip)); |
1114 | update_pci_byte(chip->pci, | 1180 | update_pci_byte(chip->pci, |
1115 | NVIDIA_HDA_TRANSREG_ADDR, | 1181 | NVIDIA_HDA_TRANSREG_ADDR, |
1116 | 0x0f, NVIDIA_HDA_ENABLE_COHBITS); | 1182 | 0x0f, NVIDIA_HDA_ENABLE_COHBITS); |
@@ -1124,16 +1190,20 @@ static void azx_init_pci(struct azx *chip) | |||
1124 | 1190 | ||
1125 | /* Enable SCH/PCH snoop if needed */ | 1191 | /* Enable SCH/PCH snoop if needed */ |
1126 | if (chip->driver_caps & AZX_DCAPS_SCH_SNOOP) { | 1192 | if (chip->driver_caps & AZX_DCAPS_SCH_SNOOP) { |
1193 | unsigned short snoop; | ||
1127 | pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop); | 1194 | pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop); |
1128 | if (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) { | 1195 | if ((!azx_snoop(chip) && !(snoop & INTEL_SCH_HDA_DEVC_NOSNOOP)) || |
1129 | pci_write_config_word(chip->pci, INTEL_SCH_HDA_DEVC, | 1196 | (azx_snoop(chip) && (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP))) { |
1130 | snoop & (~INTEL_SCH_HDA_DEVC_NOSNOOP)); | 1197 | snoop &= ~INTEL_SCH_HDA_DEVC_NOSNOOP; |
1198 | if (!azx_snoop(chip)) | ||
1199 | snoop |= INTEL_SCH_HDA_DEVC_NOSNOOP; | ||
1200 | pci_write_config_word(chip->pci, INTEL_SCH_HDA_DEVC, snoop); | ||
1131 | pci_read_config_word(chip->pci, | 1201 | pci_read_config_word(chip->pci, |
1132 | INTEL_SCH_HDA_DEVC, &snoop); | 1202 | INTEL_SCH_HDA_DEVC, &snoop); |
1133 | snd_printdd(SFX "HDA snoop disabled, enabling ... %s\n", | ||
1134 | (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) | ||
1135 | ? "Failed" : "OK"); | ||
1136 | } | 1203 | } |
1204 | snd_printdd(SFX "SCH snoop: %s\n", | ||
1205 | (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) | ||
1206 | ? "Disabled" : "Enabled"); | ||
1137 | } | 1207 | } |
1138 | } | 1208 | } |
1139 | 1209 | ||
@@ -1340,12 +1410,16 @@ static void azx_stream_reset(struct azx *chip, struct azx_dev *azx_dev) | |||
1340 | */ | 1410 | */ |
1341 | static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev) | 1411 | static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev) |
1342 | { | 1412 | { |
1413 | unsigned int val; | ||
1343 | /* make sure the run bit is zero for SD */ | 1414 | /* make sure the run bit is zero for SD */ |
1344 | azx_stream_clear(chip, azx_dev); | 1415 | azx_stream_clear(chip, azx_dev); |
1345 | /* program the stream_tag */ | 1416 | /* program the stream_tag */ |
1346 | azx_sd_writel(azx_dev, SD_CTL, | 1417 | val = azx_sd_readl(azx_dev, SD_CTL); |
1347 | (azx_sd_readl(azx_dev, SD_CTL) & ~SD_CTL_STREAM_TAG_MASK)| | 1418 | val = (val & ~SD_CTL_STREAM_TAG_MASK) | |
1348 | (azx_dev->stream_tag << SD_CTL_STREAM_TAG_SHIFT)); | 1419 | (azx_dev->stream_tag << SD_CTL_STREAM_TAG_SHIFT); |
1420 | if (!azx_snoop(chip)) | ||
1421 | val |= SD_CTL_TRAFFIC_PRIO; | ||
1422 | azx_sd_writel(azx_dev, SD_CTL, val); | ||
1349 | 1423 | ||
1350 | /* program the length of samples in cyclic buffer */ | 1424 | /* program the length of samples in cyclic buffer */ |
1351 | azx_sd_writel(azx_dev, SD_CBL, azx_dev->bufsize); | 1425 | azx_sd_writel(azx_dev, SD_CBL, azx_dev->bufsize); |
@@ -1693,19 +1767,30 @@ static int azx_pcm_close(struct snd_pcm_substream *substream) | |||
1693 | static int azx_pcm_hw_params(struct snd_pcm_substream *substream, | 1767 | static int azx_pcm_hw_params(struct snd_pcm_substream *substream, |
1694 | struct snd_pcm_hw_params *hw_params) | 1768 | struct snd_pcm_hw_params *hw_params) |
1695 | { | 1769 | { |
1770 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); | ||
1771 | struct azx *chip = apcm->chip; | ||
1772 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
1696 | struct azx_dev *azx_dev = get_azx_dev(substream); | 1773 | struct azx_dev *azx_dev = get_azx_dev(substream); |
1774 | int ret; | ||
1697 | 1775 | ||
1776 | mark_runtime_wc(chip, azx_dev, runtime, false); | ||
1698 | azx_dev->bufsize = 0; | 1777 | azx_dev->bufsize = 0; |
1699 | azx_dev->period_bytes = 0; | 1778 | azx_dev->period_bytes = 0; |
1700 | azx_dev->format_val = 0; | 1779 | azx_dev->format_val = 0; |
1701 | return snd_pcm_lib_malloc_pages(substream, | 1780 | ret = snd_pcm_lib_malloc_pages(substream, |
1702 | params_buffer_bytes(hw_params)); | 1781 | params_buffer_bytes(hw_params)); |
1782 | if (ret < 0) | ||
1783 | return ret; | ||
1784 | mark_runtime_wc(chip, azx_dev, runtime, true); | ||
1785 | return ret; | ||
1703 | } | 1786 | } |
1704 | 1787 | ||
1705 | static int azx_pcm_hw_free(struct snd_pcm_substream *substream) | 1788 | static int azx_pcm_hw_free(struct snd_pcm_substream *substream) |
1706 | { | 1789 | { |
1707 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); | 1790 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); |
1708 | struct azx_dev *azx_dev = get_azx_dev(substream); | 1791 | struct azx_dev *azx_dev = get_azx_dev(substream); |
1792 | struct azx *chip = apcm->chip; | ||
1793 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
1709 | struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream]; | 1794 | struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream]; |
1710 | 1795 | ||
1711 | /* reset BDL address */ | 1796 | /* reset BDL address */ |
@@ -1718,6 +1803,7 @@ static int azx_pcm_hw_free(struct snd_pcm_substream *substream) | |||
1718 | 1803 | ||
1719 | snd_hda_codec_cleanup(apcm->codec, hinfo, substream); | 1804 | snd_hda_codec_cleanup(apcm->codec, hinfo, substream); |
1720 | 1805 | ||
1806 | mark_runtime_wc(chip, azx_dev, runtime, false); | ||
1721 | return snd_pcm_lib_free_pages(substream); | 1807 | return snd_pcm_lib_free_pages(substream); |
1722 | } | 1808 | } |
1723 | 1809 | ||
@@ -2076,6 +2162,20 @@ static void azx_clear_irq_pending(struct azx *chip) | |||
2076 | spin_unlock_irq(&chip->reg_lock); | 2162 | spin_unlock_irq(&chip->reg_lock); |
2077 | } | 2163 | } |
2078 | 2164 | ||
2165 | #ifdef CONFIG_X86 | ||
2166 | static int azx_pcm_mmap(struct snd_pcm_substream *substream, | ||
2167 | struct vm_area_struct *area) | ||
2168 | { | ||
2169 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); | ||
2170 | struct azx *chip = apcm->chip; | ||
2171 | if (!azx_snoop(chip)) | ||
2172 | area->vm_page_prot = pgprot_writecombine(area->vm_page_prot); | ||
2173 | return snd_pcm_lib_default_mmap(substream, area); | ||
2174 | } | ||
2175 | #else | ||
2176 | #define azx_pcm_mmap NULL | ||
2177 | #endif | ||
2178 | |||
2079 | static struct snd_pcm_ops azx_pcm_ops = { | 2179 | static struct snd_pcm_ops azx_pcm_ops = { |
2080 | .open = azx_pcm_open, | 2180 | .open = azx_pcm_open, |
2081 | .close = azx_pcm_close, | 2181 | .close = azx_pcm_close, |
@@ -2085,6 +2185,7 @@ static struct snd_pcm_ops azx_pcm_ops = { | |||
2085 | .prepare = azx_pcm_prepare, | 2185 | .prepare = azx_pcm_prepare, |
2086 | .trigger = azx_pcm_trigger, | 2186 | .trigger = azx_pcm_trigger, |
2087 | .pointer = azx_pcm_pointer, | 2187 | .pointer = azx_pcm_pointer, |
2188 | .mmap = azx_pcm_mmap, | ||
2088 | .page = snd_pcm_sgbuf_ops_page, | 2189 | .page = snd_pcm_sgbuf_ops_page, |
2089 | }; | 2190 | }; |
2090 | 2191 | ||
@@ -2365,13 +2466,19 @@ static int azx_free(struct azx *chip) | |||
2365 | 2466 | ||
2366 | if (chip->azx_dev) { | 2467 | if (chip->azx_dev) { |
2367 | for (i = 0; i < chip->num_streams; i++) | 2468 | for (i = 0; i < chip->num_streams; i++) |
2368 | if (chip->azx_dev[i].bdl.area) | 2469 | if (chip->azx_dev[i].bdl.area) { |
2470 | mark_pages_wc(chip, &chip->azx_dev[i].bdl, false); | ||
2369 | snd_dma_free_pages(&chip->azx_dev[i].bdl); | 2471 | snd_dma_free_pages(&chip->azx_dev[i].bdl); |
2472 | } | ||
2370 | } | 2473 | } |
2371 | if (chip->rb.area) | 2474 | if (chip->rb.area) { |
2475 | mark_pages_wc(chip, &chip->rb, false); | ||
2372 | snd_dma_free_pages(&chip->rb); | 2476 | snd_dma_free_pages(&chip->rb); |
2373 | if (chip->posbuf.area) | 2477 | } |
2478 | if (chip->posbuf.area) { | ||
2479 | mark_pages_wc(chip, &chip->posbuf, false); | ||
2374 | snd_dma_free_pages(&chip->posbuf); | 2480 | snd_dma_free_pages(&chip->posbuf); |
2481 | } | ||
2375 | pci_release_regions(chip->pci); | 2482 | pci_release_regions(chip->pci); |
2376 | pci_disable_device(chip->pci); | 2483 | pci_disable_device(chip->pci); |
2377 | kfree(chip->azx_dev); | 2484 | kfree(chip->azx_dev); |
@@ -2566,6 +2673,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
2566 | check_probe_mask(chip, dev); | 2673 | check_probe_mask(chip, dev); |
2567 | 2674 | ||
2568 | chip->single_cmd = single_cmd; | 2675 | chip->single_cmd = single_cmd; |
2676 | chip->snoop = hda_snoop; | ||
2569 | 2677 | ||
2570 | if (bdl_pos_adj[dev] < 0) { | 2678 | if (bdl_pos_adj[dev] < 0) { |
2571 | switch (chip->driver_type) { | 2679 | switch (chip->driver_type) { |
@@ -2693,6 +2801,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
2693 | snd_printk(KERN_ERR SFX "cannot allocate BDL\n"); | 2801 | snd_printk(KERN_ERR SFX "cannot allocate BDL\n"); |
2694 | goto errout; | 2802 | goto errout; |
2695 | } | 2803 | } |
2804 | mark_pages_wc(chip, &chip->azx_dev[i].bdl, true); | ||
2696 | } | 2805 | } |
2697 | /* allocate memory for the position buffer */ | 2806 | /* allocate memory for the position buffer */ |
2698 | err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, | 2807 | err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, |
@@ -2702,6 +2811,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
2702 | snd_printk(KERN_ERR SFX "cannot allocate posbuf\n"); | 2811 | snd_printk(KERN_ERR SFX "cannot allocate posbuf\n"); |
2703 | goto errout; | 2812 | goto errout; |
2704 | } | 2813 | } |
2814 | mark_pages_wc(chip, &chip->posbuf, true); | ||
2705 | /* allocate CORB/RIRB */ | 2815 | /* allocate CORB/RIRB */ |
2706 | err = azx_alloc_cmd_io(chip); | 2816 | err = azx_alloc_cmd_io(chip); |
2707 | if (err < 0) | 2817 | if (err < 0) |