From patchwork Wed Apr 1 11:31:02 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vinod Koul X-Patchwork-Id: 6139631 Return-Path: X-Original-To: patchwork-alsa-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 358EE9F350 for ; Wed, 1 Apr 2015 11:39:11 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 419B4202D1 for ; Wed, 1 Apr 2015 11:39:10 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.kernel.org (Postfix) with ESMTP id D60CC202BE for ; Wed, 1 Apr 2015 11:39:08 +0000 (UTC) Received: by alsa0.perex.cz (Postfix, from userid 1000) id F41CF26535C; Wed, 1 Apr 2015 13:39:07 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,NO_DNS_FOR_FROM, UNPARSEABLE_RELAY autolearn=no version=3.3.1 Received: from alsa0.perex.cz (localhost [IPv6:::1]) by alsa0.perex.cz (Postfix) with ESMTP id 7C48726545D; Wed, 1 Apr 2015 13:37:08 +0200 (CEST) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa0.perex.cz (Postfix, from userid 1000) id 87C94265453; Wed, 1 Apr 2015 13:37:06 +0200 (CEST) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by alsa0.perex.cz (Postfix) with ESMTP id 6B7D82652AE for ; Wed, 1 Apr 2015 13:35:42 +0200 (CEST) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga103.fm.intel.com with ESMTP; 01 Apr 2015 04:35:42 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.11,503,1422950400"; d="scan'208";a="701473379" Received: from vkoul-udesk3.iind.intel.com ([10.223.84.65]) by fmsmga002.fm.intel.com with ESMTP; 01 Apr 2015 04:35:39 -0700 From: Vinod Koul To: alsa-devel@alsa-project.org Date: Wed, 1 Apr 2015 17:01:02 +0530 Message-Id: <1427887862-29054-6-git-send-email-vinod.koul@intel.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1427887862-29054-1-git-send-email-vinod.koul@intel.com> References: <1427887862-29054-1-git-send-email-vinod.koul@intel.com> Cc: tiwai@suse.de, patches.audio@intel.com, Vinod Koul , lgirdwood@gmail.com, Jeeja KP Subject: [alsa-devel] [PATCH v3 5/5] ALSA: hda - add the DSP loader code X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org X-Virus-Scanned: ClamAV using ClamSMTP This will be used by SKL controller Signed-off-by: Jeeja KP Signed-off-by: Vinod Koul --- include/sound/hdaudio.h | 15 ++++++++ sound/hda/hdac_stream.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h index df4033fc864d..9aeede3c8ea1 100644 --- a/include/sound/hdaudio.h +++ b/include/sound/hdaudio.h @@ -153,6 +153,13 @@ struct hdac_bus_ops { u16 (*reg_readw)(u16 __iomem *addr); void (*reg_writeb)(u8 value, u8 __iomem *addr); u8 (*reg_readb)(u8 __iomem *addr); + + /* Allocation ops */ + int (*dma_alloc_pages)(struct hdac_bus *bus, + int type, + size_t size, + struct snd_dma_buffer *buf); + void (*dma_free_pages)(struct hdac_bus *bus, struct snd_dma_buffer *buf); }; #define HDA_UNSOL_QUEUE_SIZE 64 @@ -330,6 +337,14 @@ void snd_hdac_stream_sync(struct hdac_stream *azx_dev, bool start, unsigned int streams); void snd_hdac_stream_timecounter_init(struct hdac_stream *azx_dev, unsigned int streams); +/*DSP loader functions */ +int snd_hdac_load_dsp_prepare(struct hdac_stream *azx_dev, unsigned int format, + unsigned int byte_size, + struct snd_dma_buffer *bufp); + +void snd_hdac_load_dsp_trigger(struct hdac_stream *azx_dev, bool start); +void snd_hdac_load_dsp_cleanup(struct hdac_stream *azx_dev, + struct snd_dma_buffer *dmab); /* * helpers to read the stream position diff --git a/sound/hda/hdac_stream.c b/sound/hda/hdac_stream.c index 541648c84bd7..394fd15de420 100644 --- a/sound/hda/hdac_stream.c +++ b/sound/hda/hdac_stream.c @@ -471,3 +471,95 @@ void snd_hdac_stream_sync(struct hdac_stream *azx_dev, bool start, } } EXPORT_SYMBOL_GPL(snd_hdac_stream_sync); + +int snd_hdac_load_dsp_prepare(struct hdac_stream *azx_dev, unsigned int format, + unsigned int byte_size, + struct snd_dma_buffer *bufp) +{ + struct hdac_bus *bus = azx_dev->bus; + u32 *bdl; + int err; + + dsp_lock(azx_dev); + spin_lock_irq(&bus->reg_lock); + if (azx_dev->running || azx_dev->locked) { + spin_unlock_irq(&bus->reg_lock); + err = -EBUSY; + goto unlock; + } + azx_dev->locked = 1; + spin_unlock_irq(&bus->reg_lock); + + err = bus->ops->dma_alloc_pages(bus, SNDRV_DMA_TYPE_DEV_SG, + byte_size, bufp); + if (err < 0) + goto err_alloc; + + azx_dev->bufsize = byte_size; + azx_dev->period_bytes = byte_size; + azx_dev->format_val = format; + + snd_hdac_stream_reset(azx_dev); + + /* reset BDL address */ + azx_sd_writel(bus, azx_dev, SD_BDLPL, 0); + azx_sd_writel(bus, azx_dev, SD_BDLPU, 0); + + azx_dev->frags = 0; + bdl = (u32 *)azx_dev->bdl.area; + err = setup_bdle(bus, bufp, azx_dev, &bdl, 0, byte_size, 0); + if (err < 0) + goto error; + + snd_hdac_stream_setup(azx_dev); + dsp_unlock(azx_dev); + return azx_dev->stream_tag; + + error: + bus->ops->dma_free_pages(bus, bufp); + err_alloc: + spin_lock_irq(&bus->reg_lock); + azx_dev->locked = 0; + spin_unlock_irq(&bus->reg_lock); + unlock: + dsp_unlock(azx_dev); + return err; +} +EXPORT_SYMBOL_GPL(snd_hdac_load_dsp_prepare); + +void snd_hdac_load_dsp_trigger(struct hdac_stream *azx_dev, bool start) +{ + if (start) + snd_hdac_stream_start(azx_dev, true); + else + snd_hdac_stream_stop(azx_dev); + azx_dev->running = start; +} +EXPORT_SYMBOL_GPL(snd_hdac_load_dsp_trigger); + +void snd_hdac_load_dsp_cleanup(struct hdac_stream *azx_dev, + struct snd_dma_buffer *dmab) +{ + struct hdac_bus *bus = azx_dev->bus; + + if (!dmab->area || !azx_dev->locked) + return; + + dsp_lock(azx_dev); + /* reset BDL address */ + azx_sd_writel(bus, azx_dev, SD_BDLPL, 0); + azx_sd_writel(bus, azx_dev, SD_BDLPU, 0); + azx_sd_writel(bus, azx_dev, SD_CTL, 0); + azx_dev->bufsize = 0; + azx_dev->period_bytes = 0; + azx_dev->format_val = 0; + + bus->ops->dma_free_pages(bus, dmab); + dmab->area = NULL; + + spin_lock_irq(&bus->reg_lock); + azx_dev->locked = 0; + spin_unlock_irq(&bus->reg_lock); + dsp_unlock(azx_dev); +} +EXPORT_SYMBOL_GPL(snd_hdac_load_dsp_cleanup);