summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2018-08-08 16:31:52 -0400
committerTakashi Iwai <tiwai@suse.de>2018-08-28 07:56:48 -0400
commit4985ddbf1edb06f0dc4ae22e9886bde267925e6c (patch)
tree5dfd255e8643f2eff2504bc62e926db20db6e780
parent193c7e14762a58003af7914183f9b963c0267788 (diff)
ALSA: intel8x0: Use the new non-cached allocation for 440MX workaround
intel8x0 driver requires the non-cached pages for 440MX workaround, and this can be implemented more easily with the new memalloc type, SNDRV_DMA_TYPE_DEV_UC. This allows us to reduce lots of code. Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/pci/intel8x0.c89
1 files changed, 12 insertions, 77 deletions
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index 5ee468d1aefe..9517f9b8f1d4 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -38,11 +38,6 @@
38#include <sound/ac97_codec.h> 38#include <sound/ac97_codec.h>
39#include <sound/info.h> 39#include <sound/info.h>
40#include <sound/initval.h> 40#include <sound/initval.h>
41/* for 440MX workaround */
42#include <asm/pgtable.h>
43#ifdef CONFIG_X86
44#include <asm/set_memory.h>
45#endif
46 41
47MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); 42MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
48MODULE_DESCRIPTION("Intel 82801AA,82901AB,i810,i820,i830,i840,i845,MX440; SiS 7012; Ali 5455"); 43MODULE_DESCRIPTION("Intel 82801AA,82901AB,i810,i820,i830,i840,i845,MX440; SiS 7012; Ali 5455");
@@ -374,7 +369,6 @@ struct ichdev {
374 unsigned int ali_slot; /* ALI DMA slot */ 369 unsigned int ali_slot; /* ALI DMA slot */
375 struct ac97_pcm *pcm; 370 struct ac97_pcm *pcm;
376 int pcm_open_flag; 371 int pcm_open_flag;
377 unsigned int page_attr_changed: 1;
378 unsigned int suspended: 1; 372 unsigned int suspended: 1;
379}; 373};
380 374
@@ -724,25 +718,6 @@ static void snd_intel8x0_setup_periods(struct intel8x0 *chip, struct ichdev *ich
724 iputbyte(chip, port + ichdev->roff_sr, ICH_FIFOE | ICH_BCIS | ICH_LVBCI); 718 iputbyte(chip, port + ichdev->roff_sr, ICH_FIFOE | ICH_BCIS | ICH_LVBCI);
725} 719}
726 720
727#ifdef __i386__
728/*
729 * Intel 82443MX running a 100MHz processor system bus has a hardware bug,
730 * which aborts PCI busmaster for audio transfer. A workaround is to set
731 * the pages as non-cached. For details, see the errata in
732 * http://download.intel.com/design/chipsets/specupdt/24505108.pdf
733 */
734static void fill_nocache(void *buf, int size, int nocache)
735{
736 size = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
737 if (nocache)
738 set_pages_uc(virt_to_page(buf), size);
739 else
740 set_pages_wb(virt_to_page(buf), size);
741}
742#else
743#define fill_nocache(buf, size, nocache) do { ; } while (0)
744#endif
745
746/* 721/*
747 * Interrupt handler 722 * Interrupt handler
748 */ 723 */
@@ -938,23 +913,12 @@ static int snd_intel8x0_hw_params(struct snd_pcm_substream *substream,
938{ 913{
939 struct intel8x0 *chip = snd_pcm_substream_chip(substream); 914 struct intel8x0 *chip = snd_pcm_substream_chip(substream);
940 struct ichdev *ichdev = get_ichdev(substream); 915 struct ichdev *ichdev = get_ichdev(substream);
941 struct snd_pcm_runtime *runtime = substream->runtime;
942 int dbl = params_rate(hw_params) > 48000; 916 int dbl = params_rate(hw_params) > 48000;
943 int err; 917 int err;
944 918
945 if (chip->fix_nocache && ichdev->page_attr_changed) {
946 fill_nocache(runtime->dma_area, runtime->dma_bytes, 0); /* clear */
947 ichdev->page_attr_changed = 0;
948 }
949 err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); 919 err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
950 if (err < 0) 920 if (err < 0)
951 return err; 921 return err;
952 if (chip->fix_nocache) {
953 if (runtime->dma_area && ! ichdev->page_attr_changed) {
954 fill_nocache(runtime->dma_area, runtime->dma_bytes, 1);
955 ichdev->page_attr_changed = 1;
956 }
957 }
958 if (ichdev->pcm_open_flag) { 922 if (ichdev->pcm_open_flag) {
959 snd_ac97_pcm_close(ichdev->pcm); 923 snd_ac97_pcm_close(ichdev->pcm);
960 ichdev->pcm_open_flag = 0; 924 ichdev->pcm_open_flag = 0;
@@ -974,17 +938,12 @@ static int snd_intel8x0_hw_params(struct snd_pcm_substream *substream,
974 938
975static int snd_intel8x0_hw_free(struct snd_pcm_substream *substream) 939static int snd_intel8x0_hw_free(struct snd_pcm_substream *substream)
976{ 940{
977 struct intel8x0 *chip = snd_pcm_substream_chip(substream);
978 struct ichdev *ichdev = get_ichdev(substream); 941 struct ichdev *ichdev = get_ichdev(substream);
979 942
980 if (ichdev->pcm_open_flag) { 943 if (ichdev->pcm_open_flag) {
981 snd_ac97_pcm_close(ichdev->pcm); 944 snd_ac97_pcm_close(ichdev->pcm);
982 ichdev->pcm_open_flag = 0; 945 ichdev->pcm_open_flag = 0;
983 } 946 }
984 if (chip->fix_nocache && ichdev->page_attr_changed) {
985 fill_nocache(substream->runtime->dma_area, substream->runtime->dma_bytes, 0);
986 ichdev->page_attr_changed = 0;
987 }
988 return snd_pcm_lib_free_pages(substream); 947 return snd_pcm_lib_free_pages(substream);
989} 948}
990 949
@@ -1510,6 +1469,9 @@ struct ich_pcm_table {
1510 int ac97_idx; 1469 int ac97_idx;
1511}; 1470};
1512 1471
1472#define intel8x0_dma_type(chip) \
1473 ((chip)->fix_nocache ? SNDRV_DMA_TYPE_DEV_UC : SNDRV_DMA_TYPE_DEV)
1474
1513static int snd_intel8x0_pcm1(struct intel8x0 *chip, int device, 1475static int snd_intel8x0_pcm1(struct intel8x0 *chip, int device,
1514 struct ich_pcm_table *rec) 1476 struct ich_pcm_table *rec)
1515{ 1477{
@@ -1540,7 +1502,7 @@ static int snd_intel8x0_pcm1(struct intel8x0 *chip, int device,
1540 strcpy(pcm->name, chip->card->shortname); 1502 strcpy(pcm->name, chip->card->shortname);
1541 chip->pcm[device] = pcm; 1503 chip->pcm[device] = pcm;
1542 1504
1543 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, 1505 snd_pcm_lib_preallocate_pages_for_all(pcm, intel8x0_dma_type(chip),
1544 snd_dma_pci_data(chip->pci), 1506 snd_dma_pci_data(chip->pci),
1545 rec->prealloc_size, rec->prealloc_max_size); 1507 rec->prealloc_size, rec->prealloc_max_size);
1546 1508
@@ -2629,11 +2591,8 @@ static int snd_intel8x0_free(struct intel8x0 *chip)
2629 __hw_end: 2591 __hw_end:
2630 if (chip->irq >= 0) 2592 if (chip->irq >= 0)
2631 free_irq(chip->irq, chip); 2593 free_irq(chip->irq, chip);
2632 if (chip->bdbars.area) { 2594 if (chip->bdbars.area)
2633 if (chip->fix_nocache)
2634 fill_nocache(chip->bdbars.area, chip->bdbars.bytes, 0);
2635 snd_dma_free_pages(&chip->bdbars); 2595 snd_dma_free_pages(&chip->bdbars);
2636 }
2637 if (chip->addr) 2596 if (chip->addr)
2638 pci_iounmap(chip->pci, chip->addr); 2597 pci_iounmap(chip->pci, chip->addr);
2639 if (chip->bmaddr) 2598 if (chip->bmaddr)
@@ -2657,17 +2616,6 @@ static int intel8x0_suspend(struct device *dev)
2657 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 2616 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
2658 for (i = 0; i < chip->pcm_devs; i++) 2617 for (i = 0; i < chip->pcm_devs; i++)
2659 snd_pcm_suspend_all(chip->pcm[i]); 2618 snd_pcm_suspend_all(chip->pcm[i]);
2660 /* clear nocache */
2661 if (chip->fix_nocache) {
2662 for (i = 0; i < chip->bdbars_count; i++) {
2663 struct ichdev *ichdev = &chip->ichd[i];
2664 if (ichdev->substream && ichdev->page_attr_changed) {
2665 struct snd_pcm_runtime *runtime = ichdev->substream->runtime;
2666 if (runtime->dma_area)
2667 fill_nocache(runtime->dma_area, runtime->dma_bytes, 0);
2668 }
2669 }
2670 }
2671 for (i = 0; i < chip->ncodecs; i++) 2619 for (i = 0; i < chip->ncodecs; i++)
2672 snd_ac97_suspend(chip->ac97[i]); 2620 snd_ac97_suspend(chip->ac97[i]);
2673 if (chip->device_type == DEVICE_INTEL_ICH4) 2621 if (chip->device_type == DEVICE_INTEL_ICH4)
@@ -2708,25 +2656,9 @@ static int intel8x0_resume(struct device *dev)
2708 ICH_PCM_SPDIF_1011); 2656 ICH_PCM_SPDIF_1011);
2709 } 2657 }
2710 2658
2711 /* refill nocache */
2712 if (chip->fix_nocache)
2713 fill_nocache(chip->bdbars.area, chip->bdbars.bytes, 1);
2714
2715 for (i = 0; i < chip->ncodecs; i++) 2659 for (i = 0; i < chip->ncodecs; i++)
2716 snd_ac97_resume(chip->ac97[i]); 2660 snd_ac97_resume(chip->ac97[i]);
2717 2661
2718 /* refill nocache */
2719 if (chip->fix_nocache) {
2720 for (i = 0; i < chip->bdbars_count; i++) {
2721 struct ichdev *ichdev = &chip->ichd[i];
2722 if (ichdev->substream && ichdev->page_attr_changed) {
2723 struct snd_pcm_runtime *runtime = ichdev->substream->runtime;
2724 if (runtime->dma_area)
2725 fill_nocache(runtime->dma_area, runtime->dma_bytes, 1);
2726 }
2727 }
2728 }
2729
2730 /* resume status */ 2662 /* resume status */
2731 for (i = 0; i < chip->bdbars_count; i++) { 2663 for (i = 0; i < chip->bdbars_count; i++) {
2732 struct ichdev *ichdev = &chip->ichd[i]; 2664 struct ichdev *ichdev = &chip->ichd[i];
@@ -3057,6 +2989,12 @@ static int snd_intel8x0_create(struct snd_card *card,
3057 2989
3058 chip->inside_vm = snd_intel8x0_inside_vm(pci); 2990 chip->inside_vm = snd_intel8x0_inside_vm(pci);
3059 2991
2992 /*
2993 * Intel 82443MX running a 100MHz processor system bus has a hardware
2994 * bug, which aborts PCI busmaster for audio transfer. A workaround
2995 * is to set the pages as non-cached. For details, see the errata in
2996 * http://download.intel.com/design/chipsets/specupdt/24505108.pdf
2997 */
3060 if (pci->vendor == PCI_VENDOR_ID_INTEL && 2998 if (pci->vendor == PCI_VENDOR_ID_INTEL &&
3061 pci->device == PCI_DEVICE_ID_INTEL_440MX) 2999 pci->device == PCI_DEVICE_ID_INTEL_440MX)
3062 chip->fix_nocache = 1; /* enable workaround */ 3000 chip->fix_nocache = 1; /* enable workaround */
@@ -3128,7 +3066,7 @@ static int snd_intel8x0_create(struct snd_card *card,
3128 3066
3129 /* allocate buffer descriptor lists */ 3067 /* allocate buffer descriptor lists */
3130 /* the start of each lists must be aligned to 8 bytes */ 3068 /* the start of each lists must be aligned to 8 bytes */
3131 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), 3069 if (snd_dma_alloc_pages(intel8x0_dma_type(chip), snd_dma_pci_data(pci),
3132 chip->bdbars_count * sizeof(u32) * ICH_MAX_FRAGS * 2, 3070 chip->bdbars_count * sizeof(u32) * ICH_MAX_FRAGS * 2,
3133 &chip->bdbars) < 0) { 3071 &chip->bdbars) < 0) {
3134 snd_intel8x0_free(chip); 3072 snd_intel8x0_free(chip);
@@ -3137,9 +3075,6 @@ static int snd_intel8x0_create(struct snd_card *card,
3137 } 3075 }
3138 /* tables must be aligned to 8 bytes here, but the kernel pages 3076 /* tables must be aligned to 8 bytes here, but the kernel pages
3139 are much bigger, so we don't care (on i386) */ 3077 are much bigger, so we don't care (on i386) */
3140 /* workaround for 440MX */
3141 if (chip->fix_nocache)
3142 fill_nocache(chip->bdbars.area, chip->bdbars.bytes, 1);
3143 int_sta_masks = 0; 3078 int_sta_masks = 0;
3144 for (i = 0; i < chip->bdbars_count; i++) { 3079 for (i = 0; i < chip->bdbars_count; i++) {
3145 ichdev = &chip->ichd[i]; 3080 ichdev = &chip->ichd[i];