diff options
Diffstat (limited to 'sound/pci/hda/hda_intel.c')
-rw-r--r-- | sound/pci/hda/hda_intel.c | 225 |
1 files changed, 188 insertions, 37 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 191284a1c0ae..bd7fc99af187 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" |
@@ -116,6 +121,22 @@ module_param(power_save_controller, bool, 0644); | |||
116 | MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode."); | 121 | MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode."); |
117 | #endif | 122 | #endif |
118 | 123 | ||
124 | static int align_buffer_size = 1; | ||
125 | module_param(align_buffer_size, bool, 0644); | ||
126 | MODULE_PARM_DESC(align_buffer_size, | ||
127 | "Force buffer and period sizes to be multiple of 128 bytes."); | ||
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 | |||
119 | MODULE_LICENSE("GPL"); | 140 | MODULE_LICENSE("GPL"); |
120 | MODULE_SUPPORTED_DEVICE("{{Intel, ICH6}," | 141 | MODULE_SUPPORTED_DEVICE("{{Intel, ICH6}," |
121 | "{Intel, ICH6M}," | 142 | "{Intel, ICH6M}," |
@@ -360,7 +381,7 @@ struct azx_dev { | |||
360 | */ | 381 | */ |
361 | unsigned char stream_tag; /* assigned stream */ | 382 | unsigned char stream_tag; /* assigned stream */ |
362 | unsigned char index; /* stream index */ | 383 | unsigned char index; /* stream index */ |
363 | int device; /* last device number assigned to */ | 384 | int assigned_key; /* last device# key assigned to */ |
364 | 385 | ||
365 | unsigned int opened :1; | 386 | unsigned int opened :1; |
366 | unsigned int running :1; | 387 | unsigned int running :1; |
@@ -371,6 +392,7 @@ struct azx_dev { | |||
371 | * when link position is not greater than FIFO size | 392 | * when link position is not greater than FIFO size |
372 | */ | 393 | */ |
373 | unsigned int insufficient :1; | 394 | unsigned int insufficient :1; |
395 | unsigned int wc_marked:1; | ||
374 | }; | 396 | }; |
375 | 397 | ||
376 | /* CORB/RIRB */ | 398 | /* CORB/RIRB */ |
@@ -438,6 +460,7 @@ struct azx { | |||
438 | unsigned int msi :1; | 460 | unsigned int msi :1; |
439 | unsigned int irq_pending_warned :1; | 461 | unsigned int irq_pending_warned :1; |
440 | unsigned int probing :1; /* codec probing phase */ | 462 | unsigned int probing :1; /* codec probing phase */ |
463 | unsigned int snoop:1; | ||
441 | 464 | ||
442 | /* for debugging */ | 465 | /* for debugging */ |
443 | unsigned int last_cmd[AZX_MAX_CODECS]; | 466 | unsigned int last_cmd[AZX_MAX_CODECS]; |
@@ -481,6 +504,7 @@ enum { | |||
481 | #define AZX_DCAPS_NO_64BIT (1 << 18) /* No 64bit address */ | 504 | #define AZX_DCAPS_NO_64BIT (1 << 18) /* No 64bit address */ |
482 | #define AZX_DCAPS_SYNC_WRITE (1 << 19) /* sync each cmd write */ | 505 | #define AZX_DCAPS_SYNC_WRITE (1 << 19) /* sync each cmd write */ |
483 | #define AZX_DCAPS_OLD_SSYNC (1 << 20) /* Old SSYNC reg for ICH */ | 506 | #define AZX_DCAPS_OLD_SSYNC (1 << 20) /* Old SSYNC reg for ICH */ |
507 | #define AZX_DCAPS_BUFSIZE (1 << 21) /* no buffer size alignment */ | ||
484 | 508 | ||
485 | /* quirks for ATI SB / AMD Hudson */ | 509 | /* quirks for ATI SB / AMD Hudson */ |
486 | #define AZX_DCAPS_PRESET_ATI_SB \ | 510 | #define AZX_DCAPS_PRESET_ATI_SB \ |
@@ -542,6 +566,45 @@ static char *driver_short_names[] __devinitdata = { | |||
542 | /* for pcm support */ | 566 | /* for pcm support */ |
543 | #define get_azx_dev(substream) (substream->runtime->private_data) | 567 | #define get_azx_dev(substream) (substream->runtime->private_data) |
544 | 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 | |||
545 | static int azx_acquire_irq(struct azx *chip, int do_disconnect); | 608 | static int azx_acquire_irq(struct azx *chip, int do_disconnect); |
546 | 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); |
547 | /* | 610 | /* |
@@ -563,6 +626,7 @@ static int azx_alloc_cmd_io(struct azx *chip) | |||
563 | snd_printk(KERN_ERR SFX "cannot allocate CORB/RIRB\n"); | 626 | snd_printk(KERN_ERR SFX "cannot allocate CORB/RIRB\n"); |
564 | return err; | 627 | return err; |
565 | } | 628 | } |
629 | mark_pages_wc(chip, &chip->rb, true); | ||
566 | return 0; | 630 | return 0; |
567 | } | 631 | } |
568 | 632 | ||
@@ -1079,7 +1143,15 @@ static void update_pci_byte(struct pci_dev *pci, unsigned int reg, | |||
1079 | 1143 | ||
1080 | static void azx_init_pci(struct azx *chip) | 1144 | static void azx_init_pci(struct azx *chip) |
1081 | { | 1145 | { |
1082 | 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 | } | ||
1083 | 1155 | ||
1084 | /* Clear bits 0-2 of PCI register TCSEL (at offset 0x44) | 1156 | /* Clear bits 0-2 of PCI register TCSEL (at offset 0x44) |
1085 | * TCSEL == Traffic Class Select Register, which sets PCI express QOS | 1157 | * TCSEL == Traffic Class Select Register, which sets PCI express QOS |
@@ -1096,15 +1168,15 @@ static void azx_init_pci(struct azx *chip) | |||
1096 | * we need to enable snoop. | 1168 | * we need to enable snoop. |
1097 | */ | 1169 | */ |
1098 | if (chip->driver_caps & AZX_DCAPS_ATI_SNOOP) { | 1170 | if (chip->driver_caps & AZX_DCAPS_ATI_SNOOP) { |
1099 | snd_printdd(SFX "Enabling ATI snoop\n"); | 1171 | snd_printdd(SFX "Setting ATI snoop: %d\n", azx_snoop(chip)); |
1100 | update_pci_byte(chip->pci, | 1172 | update_pci_byte(chip->pci, |
1101 | ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, | 1173 | ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, 0x07, |
1102 | 0x07, ATI_SB450_HDAUDIO_ENABLE_SNOOP); | 1174 | azx_snoop(chip) ? ATI_SB450_HDAUDIO_ENABLE_SNOOP : 0); |
1103 | } | 1175 | } |
1104 | 1176 | ||
1105 | /* For NVIDIA HDA, enable snoop */ | 1177 | /* For NVIDIA HDA, enable snoop */ |
1106 | if (chip->driver_caps & AZX_DCAPS_NVIDIA_SNOOP) { | 1178 | if (chip->driver_caps & AZX_DCAPS_NVIDIA_SNOOP) { |
1107 | snd_printdd(SFX "Enabling Nvidia snoop\n"); | 1179 | snd_printdd(SFX "Setting Nvidia snoop: %d\n", azx_snoop(chip)); |
1108 | update_pci_byte(chip->pci, | 1180 | update_pci_byte(chip->pci, |
1109 | NVIDIA_HDA_TRANSREG_ADDR, | 1181 | NVIDIA_HDA_TRANSREG_ADDR, |
1110 | 0x0f, NVIDIA_HDA_ENABLE_COHBITS); | 1182 | 0x0f, NVIDIA_HDA_ENABLE_COHBITS); |
@@ -1118,16 +1190,20 @@ static void azx_init_pci(struct azx *chip) | |||
1118 | 1190 | ||
1119 | /* Enable SCH/PCH snoop if needed */ | 1191 | /* Enable SCH/PCH snoop if needed */ |
1120 | if (chip->driver_caps & AZX_DCAPS_SCH_SNOOP) { | 1192 | if (chip->driver_caps & AZX_DCAPS_SCH_SNOOP) { |
1193 | unsigned short snoop; | ||
1121 | pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop); | 1194 | pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop); |
1122 | if (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) { | 1195 | if ((!azx_snoop(chip) && !(snoop & INTEL_SCH_HDA_DEVC_NOSNOOP)) || |
1123 | pci_write_config_word(chip->pci, INTEL_SCH_HDA_DEVC, | 1196 | (azx_snoop(chip) && (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP))) { |
1124 | 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); | ||
1125 | pci_read_config_word(chip->pci, | 1201 | pci_read_config_word(chip->pci, |
1126 | INTEL_SCH_HDA_DEVC, &snoop); | 1202 | INTEL_SCH_HDA_DEVC, &snoop); |
1127 | snd_printdd(SFX "HDA snoop disabled, enabling ... %s\n", | ||
1128 | (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) | ||
1129 | ? "Failed" : "OK"); | ||
1130 | } | 1203 | } |
1204 | snd_printdd(SFX "SCH snoop: %s\n", | ||
1205 | (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) | ||
1206 | ? "Disabled" : "Enabled"); | ||
1131 | } | 1207 | } |
1132 | } | 1208 | } |
1133 | 1209 | ||
@@ -1334,12 +1410,16 @@ static void azx_stream_reset(struct azx *chip, struct azx_dev *azx_dev) | |||
1334 | */ | 1410 | */ |
1335 | 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) |
1336 | { | 1412 | { |
1413 | unsigned int val; | ||
1337 | /* make sure the run bit is zero for SD */ | 1414 | /* make sure the run bit is zero for SD */ |
1338 | azx_stream_clear(chip, azx_dev); | 1415 | azx_stream_clear(chip, azx_dev); |
1339 | /* program the stream_tag */ | 1416 | /* program the stream_tag */ |
1340 | azx_sd_writel(azx_dev, SD_CTL, | 1417 | val = azx_sd_readl(azx_dev, SD_CTL); |
1341 | (azx_sd_readl(azx_dev, SD_CTL) & ~SD_CTL_STREAM_TAG_MASK)| | 1418 | val = (val & ~SD_CTL_STREAM_TAG_MASK) | |
1342 | (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); | ||
1343 | 1423 | ||
1344 | /* program the length of samples in cyclic buffer */ | 1424 | /* program the length of samples in cyclic buffer */ |
1345 | azx_sd_writel(azx_dev, SD_CBL, azx_dev->bufsize); | 1425 | azx_sd_writel(azx_dev, SD_CBL, azx_dev->bufsize); |
@@ -1533,6 +1613,9 @@ azx_assign_device(struct azx *chip, struct snd_pcm_substream *substream) | |||
1533 | { | 1613 | { |
1534 | int dev, i, nums; | 1614 | int dev, i, nums; |
1535 | struct azx_dev *res = NULL; | 1615 | struct azx_dev *res = NULL; |
1616 | /* make a non-zero unique key for the substream */ | ||
1617 | int key = (substream->pcm->device << 16) | (substream->number << 2) | | ||
1618 | (substream->stream + 1); | ||
1536 | 1619 | ||
1537 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 1620 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
1538 | dev = chip->playback_index_offset; | 1621 | dev = chip->playback_index_offset; |
@@ -1544,12 +1627,12 @@ azx_assign_device(struct azx *chip, struct snd_pcm_substream *substream) | |||
1544 | for (i = 0; i < nums; i++, dev++) | 1627 | for (i = 0; i < nums; i++, dev++) |
1545 | if (!chip->azx_dev[dev].opened) { | 1628 | if (!chip->azx_dev[dev].opened) { |
1546 | res = &chip->azx_dev[dev]; | 1629 | res = &chip->azx_dev[dev]; |
1547 | if (res->device == substream->pcm->device) | 1630 | if (res->assigned_key == key) |
1548 | break; | 1631 | break; |
1549 | } | 1632 | } |
1550 | if (res) { | 1633 | if (res) { |
1551 | res->opened = 1; | 1634 | res->opened = 1; |
1552 | res->device = substream->pcm->device; | 1635 | res->assigned_key = key; |
1553 | } | 1636 | } |
1554 | return res; | 1637 | return res; |
1555 | } | 1638 | } |
@@ -1599,6 +1682,7 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) | |||
1599 | struct snd_pcm_runtime *runtime = substream->runtime; | 1682 | struct snd_pcm_runtime *runtime = substream->runtime; |
1600 | unsigned long flags; | 1683 | unsigned long flags; |
1601 | int err; | 1684 | int err; |
1685 | int buff_step; | ||
1602 | 1686 | ||
1603 | mutex_lock(&chip->open_mutex); | 1687 | mutex_lock(&chip->open_mutex); |
1604 | azx_dev = azx_assign_device(chip, substream); | 1688 | azx_dev = azx_assign_device(chip, substream); |
@@ -1613,10 +1697,25 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) | |||
1613 | runtime->hw.rates = hinfo->rates; | 1697 | runtime->hw.rates = hinfo->rates; |
1614 | snd_pcm_limit_hw_rates(runtime); | 1698 | snd_pcm_limit_hw_rates(runtime); |
1615 | snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); | 1699 | snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); |
1700 | if (align_buffer_size) | ||
1701 | /* constrain buffer sizes to be multiple of 128 | ||
1702 | bytes. This is more efficient in terms of memory | ||
1703 | access but isn't required by the HDA spec and | ||
1704 | prevents users from specifying exact period/buffer | ||
1705 | sizes. For example for 44.1kHz, a period size set | ||
1706 | to 20ms will be rounded to 19.59ms. */ | ||
1707 | buff_step = 128; | ||
1708 | else | ||
1709 | /* Don't enforce steps on buffer sizes, still need to | ||
1710 | be multiple of 4 bytes (HDA spec). Tested on Intel | ||
1711 | HDA controllers, may not work on all devices where | ||
1712 | option needs to be disabled */ | ||
1713 | buff_step = 4; | ||
1714 | |||
1616 | snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, | 1715 | snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, |
1617 | 128); | 1716 | buff_step); |
1618 | snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, | 1717 | snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, |
1619 | 128); | 1718 | buff_step); |
1620 | snd_hda_power_up(apcm->codec); | 1719 | snd_hda_power_up(apcm->codec); |
1621 | err = hinfo->ops.open(hinfo, apcm->codec, substream); | 1720 | err = hinfo->ops.open(hinfo, apcm->codec, substream); |
1622 | if (err < 0) { | 1721 | if (err < 0) { |
@@ -1671,19 +1770,30 @@ static int azx_pcm_close(struct snd_pcm_substream *substream) | |||
1671 | static int azx_pcm_hw_params(struct snd_pcm_substream *substream, | 1770 | static int azx_pcm_hw_params(struct snd_pcm_substream *substream, |
1672 | struct snd_pcm_hw_params *hw_params) | 1771 | struct snd_pcm_hw_params *hw_params) |
1673 | { | 1772 | { |
1773 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); | ||
1774 | struct azx *chip = apcm->chip; | ||
1775 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
1674 | struct azx_dev *azx_dev = get_azx_dev(substream); | 1776 | struct azx_dev *azx_dev = get_azx_dev(substream); |
1777 | int ret; | ||
1675 | 1778 | ||
1779 | mark_runtime_wc(chip, azx_dev, runtime, false); | ||
1676 | azx_dev->bufsize = 0; | 1780 | azx_dev->bufsize = 0; |
1677 | azx_dev->period_bytes = 0; | 1781 | azx_dev->period_bytes = 0; |
1678 | azx_dev->format_val = 0; | 1782 | azx_dev->format_val = 0; |
1679 | return snd_pcm_lib_malloc_pages(substream, | 1783 | ret = snd_pcm_lib_malloc_pages(substream, |
1680 | params_buffer_bytes(hw_params)); | 1784 | params_buffer_bytes(hw_params)); |
1785 | if (ret < 0) | ||
1786 | return ret; | ||
1787 | mark_runtime_wc(chip, azx_dev, runtime, true); | ||
1788 | return ret; | ||
1681 | } | 1789 | } |
1682 | 1790 | ||
1683 | static int azx_pcm_hw_free(struct snd_pcm_substream *substream) | 1791 | static int azx_pcm_hw_free(struct snd_pcm_substream *substream) |
1684 | { | 1792 | { |
1685 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); | 1793 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); |
1686 | struct azx_dev *azx_dev = get_azx_dev(substream); | 1794 | struct azx_dev *azx_dev = get_azx_dev(substream); |
1795 | struct azx *chip = apcm->chip; | ||
1796 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
1687 | struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream]; | 1797 | struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream]; |
1688 | 1798 | ||
1689 | /* reset BDL address */ | 1799 | /* reset BDL address */ |
@@ -1696,6 +1806,7 @@ static int azx_pcm_hw_free(struct snd_pcm_substream *substream) | |||
1696 | 1806 | ||
1697 | snd_hda_codec_cleanup(apcm->codec, hinfo, substream); | 1807 | snd_hda_codec_cleanup(apcm->codec, hinfo, substream); |
1698 | 1808 | ||
1809 | mark_runtime_wc(chip, azx_dev, runtime, false); | ||
1699 | return snd_pcm_lib_free_pages(substream); | 1810 | return snd_pcm_lib_free_pages(substream); |
1700 | } | 1811 | } |
1701 | 1812 | ||
@@ -2055,6 +2166,20 @@ static void azx_clear_irq_pending(struct azx *chip) | |||
2055 | spin_unlock_irq(&chip->reg_lock); | 2166 | spin_unlock_irq(&chip->reg_lock); |
2056 | } | 2167 | } |
2057 | 2168 | ||
2169 | #ifdef CONFIG_X86 | ||
2170 | static int azx_pcm_mmap(struct snd_pcm_substream *substream, | ||
2171 | struct vm_area_struct *area) | ||
2172 | { | ||
2173 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); | ||
2174 | struct azx *chip = apcm->chip; | ||
2175 | if (!azx_snoop(chip)) | ||
2176 | area->vm_page_prot = pgprot_writecombine(area->vm_page_prot); | ||
2177 | return snd_pcm_lib_default_mmap(substream, area); | ||
2178 | } | ||
2179 | #else | ||
2180 | #define azx_pcm_mmap NULL | ||
2181 | #endif | ||
2182 | |||
2058 | static struct snd_pcm_ops azx_pcm_ops = { | 2183 | static struct snd_pcm_ops azx_pcm_ops = { |
2059 | .open = azx_pcm_open, | 2184 | .open = azx_pcm_open, |
2060 | .close = azx_pcm_close, | 2185 | .close = azx_pcm_close, |
@@ -2064,6 +2189,7 @@ static struct snd_pcm_ops azx_pcm_ops = { | |||
2064 | .prepare = azx_pcm_prepare, | 2189 | .prepare = azx_pcm_prepare, |
2065 | .trigger = azx_pcm_trigger, | 2190 | .trigger = azx_pcm_trigger, |
2066 | .pointer = azx_pcm_pointer, | 2191 | .pointer = azx_pcm_pointer, |
2192 | .mmap = azx_pcm_mmap, | ||
2067 | .page = snd_pcm_sgbuf_ops_page, | 2193 | .page = snd_pcm_sgbuf_ops_page, |
2068 | }; | 2194 | }; |
2069 | 2195 | ||
@@ -2344,13 +2470,19 @@ static int azx_free(struct azx *chip) | |||
2344 | 2470 | ||
2345 | if (chip->azx_dev) { | 2471 | if (chip->azx_dev) { |
2346 | for (i = 0; i < chip->num_streams; i++) | 2472 | for (i = 0; i < chip->num_streams; i++) |
2347 | if (chip->azx_dev[i].bdl.area) | 2473 | if (chip->azx_dev[i].bdl.area) { |
2474 | mark_pages_wc(chip, &chip->azx_dev[i].bdl, false); | ||
2348 | snd_dma_free_pages(&chip->azx_dev[i].bdl); | 2475 | snd_dma_free_pages(&chip->azx_dev[i].bdl); |
2476 | } | ||
2349 | } | 2477 | } |
2350 | if (chip->rb.area) | 2478 | if (chip->rb.area) { |
2479 | mark_pages_wc(chip, &chip->rb, false); | ||
2351 | snd_dma_free_pages(&chip->rb); | 2480 | snd_dma_free_pages(&chip->rb); |
2352 | if (chip->posbuf.area) | 2481 | } |
2482 | if (chip->posbuf.area) { | ||
2483 | mark_pages_wc(chip, &chip->posbuf, false); | ||
2353 | snd_dma_free_pages(&chip->posbuf); | 2484 | snd_dma_free_pages(&chip->posbuf); |
2485 | } | ||
2354 | pci_release_regions(chip->pci); | 2486 | pci_release_regions(chip->pci); |
2355 | pci_disable_device(chip->pci); | 2487 | pci_disable_device(chip->pci); |
2356 | kfree(chip->azx_dev); | 2488 | kfree(chip->azx_dev); |
@@ -2546,6 +2678,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
2546 | check_probe_mask(chip, dev); | 2678 | check_probe_mask(chip, dev); |
2547 | 2679 | ||
2548 | chip->single_cmd = single_cmd; | 2680 | chip->single_cmd = single_cmd; |
2681 | chip->snoop = hda_snoop; | ||
2549 | 2682 | ||
2550 | if (bdl_pos_adj[dev] < 0) { | 2683 | if (bdl_pos_adj[dev] < 0) { |
2551 | switch (chip->driver_type) { | 2684 | switch (chip->driver_type) { |
@@ -2618,6 +2751,10 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
2618 | gcap &= ~ICH6_GCAP_64OK; | 2751 | gcap &= ~ICH6_GCAP_64OK; |
2619 | } | 2752 | } |
2620 | 2753 | ||
2754 | /* disable buffer size rounding to 128-byte multiples if supported */ | ||
2755 | if (chip->driver_caps & AZX_DCAPS_BUFSIZE) | ||
2756 | align_buffer_size = 0; | ||
2757 | |||
2621 | /* allow 64bit DMA address if supported by H/W */ | 2758 | /* allow 64bit DMA address if supported by H/W */ |
2622 | if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64))) | 2759 | if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64))) |
2623 | pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(64)); | 2760 | pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(64)); |
@@ -2669,6 +2806,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
2669 | snd_printk(KERN_ERR SFX "cannot allocate BDL\n"); | 2806 | snd_printk(KERN_ERR SFX "cannot allocate BDL\n"); |
2670 | goto errout; | 2807 | goto errout; |
2671 | } | 2808 | } |
2809 | mark_pages_wc(chip, &chip->azx_dev[i].bdl, true); | ||
2672 | } | 2810 | } |
2673 | /* allocate memory for the position buffer */ | 2811 | /* allocate memory for the position buffer */ |
2674 | err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, | 2812 | err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, |
@@ -2678,6 +2816,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
2678 | snd_printk(KERN_ERR SFX "cannot allocate posbuf\n"); | 2816 | snd_printk(KERN_ERR SFX "cannot allocate posbuf\n"); |
2679 | goto errout; | 2817 | goto errout; |
2680 | } | 2818 | } |
2819 | mark_pages_wc(chip, &chip->posbuf, true); | ||
2681 | /* allocate CORB/RIRB */ | 2820 | /* allocate CORB/RIRB */ |
2682 | err = azx_alloc_cmd_io(chip); | 2821 | err = azx_alloc_cmd_io(chip); |
2683 | if (err < 0) | 2822 | if (err < 0) |
@@ -2819,37 +2958,49 @@ static void __devexit azx_remove(struct pci_dev *pci) | |||
2819 | static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { | 2958 | static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { |
2820 | /* CPT */ | 2959 | /* CPT */ |
2821 | { PCI_DEVICE(0x8086, 0x1c20), | 2960 | { PCI_DEVICE(0x8086, 0x1c20), |
2822 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP }, | 2961 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | |
2962 | AZX_DCAPS_BUFSIZE }, | ||
2823 | /* PBG */ | 2963 | /* PBG */ |
2824 | { PCI_DEVICE(0x8086, 0x1d20), | 2964 | { PCI_DEVICE(0x8086, 0x1d20), |
2825 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP }, | 2965 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | |
2966 | AZX_DCAPS_BUFSIZE}, | ||
2826 | /* Panther Point */ | 2967 | /* Panther Point */ |
2827 | { PCI_DEVICE(0x8086, 0x1e20), | 2968 | { PCI_DEVICE(0x8086, 0x1e20), |
2828 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP }, | 2969 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | |
2970 | AZX_DCAPS_BUFSIZE}, | ||
2829 | /* SCH */ | 2971 | /* SCH */ |
2830 | { PCI_DEVICE(0x8086, 0x811b), | 2972 | { PCI_DEVICE(0x8086, 0x811b), |
2831 | .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP }, | 2973 | .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | |
2974 | AZX_DCAPS_BUFSIZE}, | ||
2832 | { PCI_DEVICE(0x8086, 0x2668), | 2975 | { PCI_DEVICE(0x8086, 0x2668), |
2833 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH6 */ | 2976 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC | |
2977 | AZX_DCAPS_BUFSIZE }, /* ICH6 */ | ||
2834 | { PCI_DEVICE(0x8086, 0x27d8), | 2978 | { PCI_DEVICE(0x8086, 0x27d8), |
2835 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH7 */ | 2979 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC | |
2980 | AZX_DCAPS_BUFSIZE }, /* ICH7 */ | ||
2836 | { PCI_DEVICE(0x8086, 0x269a), | 2981 | { PCI_DEVICE(0x8086, 0x269a), |
2837 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ESB2 */ | 2982 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC | |
2983 | AZX_DCAPS_BUFSIZE }, /* ESB2 */ | ||
2838 | { PCI_DEVICE(0x8086, 0x284b), | 2984 | { PCI_DEVICE(0x8086, 0x284b), |
2839 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH8 */ | 2985 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC | |
2986 | AZX_DCAPS_BUFSIZE }, /* ICH8 */ | ||
2840 | { PCI_DEVICE(0x8086, 0x293e), | 2987 | { PCI_DEVICE(0x8086, 0x293e), |
2841 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH9 */ | 2988 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC | |
2989 | AZX_DCAPS_BUFSIZE }, /* ICH9 */ | ||
2842 | { PCI_DEVICE(0x8086, 0x293f), | 2990 | { PCI_DEVICE(0x8086, 0x293f), |
2843 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH9 */ | 2991 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC | |
2992 | AZX_DCAPS_BUFSIZE }, /* ICH9 */ | ||
2844 | { PCI_DEVICE(0x8086, 0x3a3e), | 2993 | { PCI_DEVICE(0x8086, 0x3a3e), |
2845 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH10 */ | 2994 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC | |
2995 | AZX_DCAPS_BUFSIZE }, /* ICH10 */ | ||
2846 | { PCI_DEVICE(0x8086, 0x3a6e), | 2996 | { PCI_DEVICE(0x8086, 0x3a6e), |
2847 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH10 */ | 2997 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC | |
2998 | AZX_DCAPS_BUFSIZE }, /* ICH10 */ | ||
2848 | /* Generic Intel */ | 2999 | /* Generic Intel */ |
2849 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_ANY_ID), | 3000 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_ANY_ID), |
2850 | .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, | 3001 | .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, |
2851 | .class_mask = 0xffffff, | 3002 | .class_mask = 0xffffff, |
2852 | .driver_data = AZX_DRIVER_ICH }, | 3003 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_BUFSIZE }, |
2853 | /* ATI SB 450/600/700/800/900 */ | 3004 | /* ATI SB 450/600/700/800/900 */ |
2854 | { PCI_DEVICE(0x1002, 0x437b), | 3005 | { PCI_DEVICE(0x1002, 0x437b), |
2855 | .driver_data = AZX_DRIVER_ATI | AZX_DCAPS_PRESET_ATI_SB }, | 3006 | .driver_data = AZX_DRIVER_ATI | AZX_DCAPS_PRESET_ATI_SB }, |