From patchwork Fri Dec 4 23:40:40 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Deucher X-Patchwork-Id: 7773271 Return-Path: X-Original-To: patchwork-alsa-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 38CA9BEEE1 for ; Fri, 4 Dec 2015 23:49:33 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 28B6720270 for ; Fri, 4 Dec 2015 23:49:32 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.kernel.org (Postfix) with ESMTP id AEB602045E for ; Fri, 4 Dec 2015 23:49:30 +0000 (UTC) Received: by alsa0.perex.cz (Postfix, from userid 1000) id B1A64265A69; Sat, 5 Dec 2015 00:49:29 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-2.5 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id 8ADE62667DA; Sat, 5 Dec 2015 00:43:01 +0100 (CET) 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 3DEF02667DD; Sat, 5 Dec 2015 00:43:00 +0100 (CET) Received: from mail-qk0-f180.google.com (mail-qk0-f180.google.com [209.85.220.180]) by alsa0.perex.cz (Postfix) with ESMTP id DC35E265885 for ; Sat, 5 Dec 2015 00:41:13 +0100 (CET) Received: by qkdb5 with SMTP id b5so10123214qkd.0 for ; Fri, 04 Dec 2015 15:41:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=OyarAVqe8CSq8yMyiLD3d3985+YcDjdsNtMrXvORPWw=; b=naExGuw7Rhe8C6LPQpZYH25MdpxPCxl+JkBscPGmFdhh2/ijofN7PYen2tb/Khd+Iq SJVpBOrfcG81FgwOuYOTn2dqVyOoUc2jPPGtwDzbDidV0KmOzTdyyxHpcCl2BAj1DxCy XIfh14Bc1QfSpgysrcf+48raOEqwGLZ4wIhbbHn1J9Uk7GxSiqxfkldVxXinm7Aog2F4 +03fJiTyhLnTQh9Yn7XJ/W8am2pIH7zT2DUOM+QTvzPeKsQU4y3PFjN9uWX0ItDGbcol ibBoglDv+veqm8GAlRl4pIZLs0MmUEtVS3GvshGCA458Euuju2ceHzNkiW2hf1mDwrld bVCw== X-Received: by 10.55.72.143 with SMTP id v137mr21935632qka.73.1449272473356; Fri, 04 Dec 2015 15:41:13 -0800 (PST) Received: from localhost.localdomain (static-74-96-105-49.washdc.fios.verizon.net. [74.96.105.49]) by smtp.gmail.com with ESMTPSA id e127sm5556698qkb.34.2015.12.04.15.41.12 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 04 Dec 2015 15:41:13 -0800 (PST) From: Alex Deucher X-Google-Original-From: Alex Deucher To: broonie@kernel.org, airlied@gmail.com, dri-devel@lists.freedesktop.org, alsa-devel@alsa-project.org, maruthi.bayyavarapu@amd.com, rajeevkumar.linux@gmail.com Date: Fri, 4 Dec 2015 18:40:40 -0500 Message-Id: <1449272440-8735-13-git-send-email-alexander.deucher@amd.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1449272440-8735-1-git-send-email-alexander.deucher@amd.com> References: <1449272440-8735-1-git-send-email-alexander.deucher@amd.com> Cc: tiwai@suse.de, Alex Deucher , Maruthi Srinivas Bayyavarapu , lgirdwood@gmail.com Subject: [alsa-devel] [PATCH 13/13] ASoC: AMD: Manage ACP 2.x SRAM banks power 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 From: Maruthi Srinivas Bayyavarapu ACP SRAM banks gets turned on when ACP is powered on. Not all banks are used for playback/capture. So, power on required banks during audio device open and power off during audio device close. Signed-off-by: Maruthi Bayyavarapu Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- sound/soc/amd/acp-pcm-dma.c | 25 +++++++++++--- sound/soc/amd/acp.c | 81 ++++++++++++++++++++++++++++++++++++++++++++- sound/soc/amd/acp.h | 3 +- 3 files changed, 103 insertions(+), 6 deletions(-) diff --git a/sound/soc/amd/acp-pcm-dma.c b/sound/soc/amd/acp-pcm-dma.c index 07a26e5..daba64a 100644 --- a/sound/soc/amd/acp-pcm-dma.c +++ b/sound/soc/amd/acp-pcm-dma.c @@ -133,6 +133,7 @@ static irqreturn_t dma_irq_handler(int irq, void *arg) static int acp_dma_open(struct snd_pcm_substream *substream) { + u32 bank; int ret = 0; struct snd_pcm_runtime *runtime = substream->runtime; struct snd_soc_pcm_runtime *prtd = substream->private_data; @@ -166,10 +167,17 @@ static int acp_dma_open(struct snd_pcm_substream *substream) if (!intr_data->play_stream && !intr_data->capture_stream) acp_enable_external_interrupts(adata->acp_mmio, 1); - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { intr_data->play_stream = substream; - else + for (bank = 1; bank <= 4; bank++) + acp_turnonoff_lower_sram_bank(intr_data->acp_mmio, bank, + true); + } else { intr_data->capture_stream = substream; + for (bank = 5; bank <= 8; bank++) + acp_turnonoff_lower_sram_bank(intr_data->acp_mmio, bank, + true); + } return 0; } @@ -201,6 +209,7 @@ static int acp_dma_hw_params(struct snd_pcm_substream *substream, pg = virt_to_page(substream->dma_buffer.area); if (pg != NULL) { + acp_turnonoff_lower_sram_bank(rtd->acp_mmio, 0, true); /* Save for runtime private data */ rtd->pg = pg; rtd->order = get_order(size); @@ -364,6 +373,7 @@ static int acp_dma_new(struct snd_soc_pcm_runtime *rtd) static int acp_dma_close(struct snd_pcm_substream *substream) { + u32 bank; struct snd_pcm_runtime *runtime = substream->runtime; struct audio_substream_data *rtd = runtime->private_data; struct snd_soc_pcm_runtime *prtd = substream->private_data; @@ -371,10 +381,17 @@ static int acp_dma_close(struct snd_pcm_substream *substream) kfree(rtd); - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { adata->play_stream = NULL; - else + for (bank = 1; bank <= 4; bank++) + acp_turnonoff_lower_sram_bank(adata->acp_mmio, bank, + false); + } else { adata->capture_stream = NULL; + for (bank = 5; bank <= 8; bank++) + acp_turnonoff_lower_sram_bank(adata->acp_mmio, bank, + false); + } /* Disable ACP irq, when the current stream is being closed and * another stream is also not active. diff --git a/sound/soc/amd/acp.c b/sound/soc/amd/acp.c index 0d59be4..ed3f83f 100644 --- a/sound/soc/amd/acp.c +++ b/sound/soc/amd/acp.c @@ -462,10 +462,79 @@ int acp_dma_stop(void __iomem *acp_mmio, u8 ch_num) return 0; } +void acp_turnonoff_lower_sram_bank(void __iomem *acp_mmio, u16 bank, + bool turnon) +{ + u32 val; + + val = acp_reg_read(acp_mmio, mmACP_MEM_SHUT_DOWN_REQ_LO); + if (val & (1 << bank)) { + /* bank is in off state */ + if (turnon == true) + /* request to on */ + val &= ~(1 << bank); + else + /* request to off */ + return; + } else { + /* bank is in on state */ + if (turnon == false) + /* request to off */ + val |= 1 << bank; + else + /* request to on */ + return; + } + acp_reg_write(val, acp_mmio, + mmACP_MEM_SHUT_DOWN_REQ_LO); + /* If ACP_MEM_SHUT_DOWN_STS_LO is 0xFFFFFFFF, then + * shutdown sequence is complete. + */ + while (acp_reg_read(acp_mmio, + mmACP_MEM_SHUT_DOWN_STS_LO) + != 0xFFFFFFFF) + cpu_relax(); +} + +void acp_turnonoff_higher_sram_bank(void __iomem *acp_mmio, u16 bank, + bool turnon) +{ + u32 val; + + bank -= 32; + val = acp_reg_read(acp_mmio, mmACP_MEM_SHUT_DOWN_REQ_HI); + if (val & (1 << bank)) { + /* bank is in off state */ + if (turnon == true) + /* request to on */ + val &= ~(1 << bank); + else + /* request to off */ + return; + } else { + /* bank is in on state */ + if (turnon == false) + /* request to off */ + val |= 1 << bank; + else + /* request to on */ + return; + } + acp_reg_write(val, acp_mmio, + mmACP_MEM_SHUT_DOWN_REQ_HI); + /* If ACP_MEM_SHUT_DOWN_STS_LO is 0xFFFFFFFF, then + * shutdown sequence is complete. + */ + while (acp_reg_read(acp_mmio, + mmACP_MEM_SHUT_DOWN_STS_HI) + != 0x0000FFFF) + cpu_relax(); +} + /* Initialize and bring ACP hardware to default state. */ int acp_init(void __iomem *acp_mmio) { - u32 val; + u32 val, bank; u32 count; /* Assert Soft reset of ACP */ @@ -527,6 +596,16 @@ int acp_init(void __iomem *acp_mmio) acp_reg_write(ACP_EXTERNAL_INTR_CNTL__DMAIOCMask_MASK, acp_mmio, mmACP_EXTERNAL_INTR_CNTL); + /* When ACP_TILE_P1 is turned on, all SRAM banks get turned on. + * Now, turn off all of them. This can't be done in 'poweron' of + * ACP pm domain, as this requires ACP to be initialized. + */ + for (bank = 1; bank < 32; bank++) + acp_turnonoff_lower_sram_bank(acp_mmio, bank, false); + + for (bank = 32; bank < 48; bank++) + acp_turnonoff_higher_sram_bank(acp_mmio, bank, false); + /* Designware I2S driver requries proper capabilities * from mmACP_I2SMICSP_COMP_PARAM_1 register. The register * reports playback and capture capabilities though the diff --git a/sound/soc/amd/acp.h b/sound/soc/amd/acp.h index 53c30ea..a2f3762 100644 --- a/sound/soc/amd/acp.h +++ b/sound/soc/amd/acp.h @@ -135,5 +135,6 @@ extern void acp_enable_external_interrupts(void __iomem *acp_mmio, extern u32 acp_get_intr_flag(void __iomem *acp_mmio); extern u16 get_dscr_idx(void __iomem *acp_mmio, int direction); extern void acp_ext_stat_clear_dmaioc(void __iomem *acp_mmio, u8 ch_num); - +extern void acp_turnonoff_lower_sram_bank(void __iomem *acp_mmio, u16 bank, + bool turnon); #endif /*__ACP_HW_H */