ALSA: HDA: Support for playback from VPR
Rahul Mittal [Tue, 26 Jun 2012 09:22:02 +0000 (14:22 +0530)]
Bug 966763

Support for HDaudio playback from video protected region

Change-Id: I053d055305b1f11643c4f8cc7a5c848015950b0a
Signed-off-by: Rahul Mittal <rmittal@nvidia.com>
Reviewed-on: http://git-master/r/102002
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Reviewed-by: Varun Wadekar <vwadekar@nvidia.com>
(cherry picked from commit 4dc95c8646a581dca8c089621be549ac634a1fef)

sound/pci/hda/Kconfig
sound/pci/hda/hda_intel.c

index 9e209ef..5bb9444 100644 (file)
@@ -99,6 +99,13 @@ config SND_HDA_PLATFORM_NVIDIA_TEGRA
          Say Y here to build NVIDIA Tegra platform driver interface for
          HD-audio driver.
 
+config SND_HDA_VPR
+       bool "Allocate PCM DMA buffer in video protected region"
+       depends on ARCH_TEGRA_11x_SOC && SND_HDA_PLATFORM_NVIDIA_TEGRA
+       depends on TEGRA_NVMAP
+       help
+         Say Y here to allocate PCM DMA buffer in video protected region
+
 config SND_HDA_CODEC_REALTEK
        bool "Build Realtek HD-audio codec support"
        default y
index 554c4a2..1ac4ca1 100644 (file)
@@ -56,6 +56,9 @@
 #include <sound/initval.h>
 #include "hda_codec.h"
 
+#ifdef CONFIG_SND_HDA_VPR
+#include <linux/nvmap.h>
+#endif
 
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
@@ -476,6 +479,13 @@ struct azx {
        int platform_clk_enable;
 #endif
 
+#ifdef CONFIG_SND_HDA_VPR
+       struct nvmap_client *hda_vpr;
+       struct nvmap_handle_ref *handle_ref;
+       unsigned char *vaddr;
+       phys_addr_t paddr;
+#endif
+
        /* locks */
        spinlock_t reg_lock;
        struct mutex open_mutex;
@@ -2413,9 +2423,35 @@ azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
        size = CONFIG_SND_HDA_PREALLOC_SIZE * 1024;
        if (size > MAX_PREALLOC_SIZE)
                size = MAX_PREALLOC_SIZE;
+#ifdef CONFIG_SND_HDA_VPR
+       chip->hda_vpr = nvmap_create_client(nvmap_dev, "hda_vpr");
+       for (s = 0; s < 2; s++) {
+               struct snd_pcm_substream *substream;
+               for (substream = pcm->streams[s].substream;
+                 substream; substream = substream->next) {
+                       chip->handle_ref = nvmap_alloc(chip->hda_vpr, size, 32,
+                         NVMAP_HANDLE_WRITE_COMBINE, NVMAP_HEAP_CARVEOUT_VPR);
+                       chip->vaddr =
+                         (unsigned char *) nvmap_mmap(chip->handle_ref);
+                       chip->paddr =
+                         nvmap_pin(chip->hda_vpr, chip->handle_ref);
+                       snd_printk(KERN_DEBUG SFX
+                         "paddr=%08x vaddr=%08x\n", chip->paddr, chip->vaddr);
+                       substream->dma_buffer.area = chip->vaddr;
+                       substream->dma_buffer.addr = chip->paddr;
+                       substream->dma_buffer.bytes = size;
+                       substream->dma_buffer.dev.dev = chip->dev;
+                       if (substream->dma_buffer.bytes > 0)
+                               substream->buffer_bytes_max =
+                                  substream->dma_buffer.bytes;
+                       substream->dma_max = MAX_PREALLOC_SIZE;
+               }
+       }
+#else
        snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
                                              chip->dev,
                                              size, MAX_PREALLOC_SIZE);
+#endif
        return 0;
 }
 
@@ -2755,6 +2791,13 @@ static int azx_free(struct azx *chip)
        }
        kfree(chip->azx_dev);
        kfree(chip);
+#ifdef CONFIG_SND_HDA_VPR
+       if(chip->handle_ref) {
+               nvmap_unpin(chip->hda_vpr, chip->handle_ref);
+               nvmap_munmap(chip->handle_ref, chip->vaddr);
+               nvmap_free(chip->hda_vpr, chip->handle_ref);
+       }
+#endif
 
        return 0;
 }