From patchwork Fri Jan 8 23:22:11 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Deucher X-Patchwork-Id: 7991231 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 5295C9F38D for ; Fri, 8 Jan 2016 23:26:59 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 4E056201C7 for ; Fri, 8 Jan 2016 23:26:58 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.kernel.org (Postfix) with ESMTP id 07E09200D4 for ; Fri, 8 Jan 2016 23:26:57 +0000 (UTC) Received: by alsa0.perex.cz (Postfix, from userid 1000) id 32CC1265E3F; Sat, 9 Jan 2016 00:26:56 +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=-1.8 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, NO_DNS_FOR_FROM, RCVD_IN_DNSWL_NONE, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=no version=3.3.1 Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id 095DC265FCF; Sat, 9 Jan 2016 00:23:14 +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 CE90F265EB5; Sat, 9 Jan 2016 00:23:12 +0100 (CET) Received: from mail-qg0-f65.google.com (mail-qg0-f65.google.com [209.85.192.65]) by alsa0.perex.cz (Postfix) with ESMTP id 9841D2604EF for ; Sat, 9 Jan 2016 00:22:28 +0100 (CET) Received: by mail-qg0-f65.google.com with SMTP id b35so35353609qge.2 for ; Fri, 08 Jan 2016 15:22:28 -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=inereTDW2ugOAnMExLlXRuNYoJYua4ElUFu/esH80Mw=; b=rgZNH117yvTz6rcUqL5FRjwz2b8Bl75WclHox/ZV0gE19vdMOrJXa+IV9ytDkISrQP x3BROx5/CWCRVjNx/ZLux3m7BLIrrKONZ5TdgSvYAzdXkv4uBlMcWU30kKpVOMhKGjVW +qhZILzsGM94GAuwgl0g1JYdkmCR/51awmwCx4YINLaOwM7cl56ubPNfjb2sxyxcDj8m 3isGbwBs6/eHEC0BXievesTpsiNQ7+bRidH/NXx6HD7gEsXIMjDWz8TDa7tgKYbqJtU7 3PKkShnrB7X7xayzsqoR+C7Mv4QjBbjowTqla68ob6zzIC7kJ6CA0eMGazSBSX4d62rV 2QDw== X-Received: by 10.140.232.78 with SMTP id d75mr139752285qhc.27.1452295347931; Fri, 08 Jan 2016 15:22:27 -0800 (PST) Received: from cm.localdomain (static-74-96-105-49.washdc.fios.verizon.net. [74.96.105.49]) by smtp.gmail.com with ESMTPSA id f83sm43834730qkb.25.2016.01.08.15.22.27 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 08 Jan 2016 15:22:27 -0800 (PST) From: Alex Deucher X-Google-Original-From: Alex Deucher To: airlied@gmail.com, dri-devel@lists.freedesktop.org, broonie@kernel.org, alsa-devel@alsa-project.org, maruthi.bayyavarapu@amd.com, rajeevkumar.linux@gmail.com Date: Fri, 8 Jan 2016 18:22:11 -0500 Message-Id: <1452295331-28476-10-git-send-email-alexander.deucher@amd.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1452295331-28476-1-git-send-email-alexander.deucher@amd.com> References: <1452295331-28476-1-git-send-email-alexander.deucher@amd.com> Cc: tiwai@suse.de, Alex Deucher , Maruthi Srinivas Bayyavarapu , lgirdwood@gmail.com Subject: [alsa-devel] [PATCH 9/9] 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 --- v2: Changes: 1. Clean up sram bank handling to clarify operation 2. Add timeout to loop sound/soc/amd/acp-pcm-dma.c | 94 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 87 insertions(+), 7 deletions(-) diff --git a/sound/soc/amd/acp-pcm-dma.c b/sound/soc/amd/acp-pcm-dma.c index c0819b5..cc8b841 100644 --- a/sound/soc/amd/acp-pcm-dma.c +++ b/sound/soc/amd/acp-pcm-dma.c @@ -376,9 +376,57 @@ static int acp_dma_stop(void __iomem *acp_mmio, u8 ch_num) return 0; } +static void acp_set_sram_bank_state(void __iomem *acp_mmio, u16 bank, + bool power_on) +{ + u32 val, req_reg, sts_reg, sts_reg_mask; + u32 loops = 1000; + + if (bank < 32) { + req_reg = mmACP_MEM_SHUT_DOWN_REQ_LO; + sts_reg = mmACP_MEM_SHUT_DOWN_STS_LO; + sts_reg_mask = 0xFFFFFFFF; + + } else { + bank -= 32; + req_reg = mmACP_MEM_SHUT_DOWN_REQ_HI; + sts_reg = mmACP_MEM_SHUT_DOWN_STS_HI; + sts_reg_mask = 0x0000FFFF; + } + + val = acp_reg_read(acp_mmio, req_reg); + if (val & (1 << bank)) { + /* bank is in off state */ + if (power_on == true) + /* request to on */ + val &= ~(1 << bank); + else + /* request to off */ + return; + } else { + /* bank is in on state */ + if (power_on == false) + /* request to off */ + val |= 1 << bank; + else + /* request to on */ + return; + } + acp_reg_write(val, acp_mmio, req_reg); + + while (acp_reg_read(acp_mmio, sts_reg) != sts_reg_mask) { + if (!loops--) { + pr_err("ACP SRAM bank %d state change failed\n", bank); + break; + } + cpu_relax(); + } +} + /* Initialize and bring ACP hardware to default state. */ static int acp_init(void __iomem *acp_mmio) { + u16 bank; u32 val, count, sram_pte_offset; /* Assert Soft reset of ACP */ @@ -447,6 +495,13 @@ static 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 < 48; bank++) + acp_set_sram_bank_state(acp_mmio, bank, false); + return 0; } @@ -559,6 +614,7 @@ static irqreturn_t dma_irq_handler(int irq, void *arg) static int acp_dma_open(struct snd_pcm_substream *substream) { + u16 bank; int ret = 0; struct snd_pcm_runtime *runtime = substream->runtime; struct snd_soc_pcm_runtime *prtd = substream->private_data; @@ -592,10 +648,17 @@ static int acp_dma_open(struct snd_pcm_substream *substream) if (!intr_data->play_stream && !intr_data->capture_stream) acp_reg_write(1, adata->acp_mmio, mmACP_EXTERNAL_INTR_ENB); - 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_set_sram_bank_state(intr_data->acp_mmio, bank, + true); + } else { intr_data->capture_stream = substream; + for (bank = 5; bank <= 8; bank++) + acp_set_sram_bank_state(intr_data->acp_mmio, bank, + true); + } return 0; } @@ -627,6 +690,7 @@ static int acp_dma_hw_params(struct snd_pcm_substream *substream, pg = virt_to_page(substream->dma_buffer.area); if (pg != NULL) { + acp_set_sram_bank_state(rtd->acp_mmio, 0, true); /* Save for runtime private data */ rtd->pg = pg; rtd->order = get_order(size); @@ -802,6 +866,7 @@ static int acp_dma_new(struct snd_soc_pcm_runtime *rtd) static int acp_dma_close(struct snd_pcm_substream *substream) { + u16 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; @@ -809,10 +874,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_set_sram_bank_state(adata->acp_mmio, bank, + false); + } else { adata->capture_stream = NULL; + for (bank = 5; bank <= 8; bank++) + acp_set_sram_bank_state(adata->acp_mmio, bank, + false); + } /* Disable ACP irq, when the current stream is being closed and * another stream is also not active. @@ -906,17 +978,25 @@ static int acp_audio_remove(struct platform_device *pdev) static int acp_pcm_resume(struct device *dev) { + u16 bank; struct audio_drv_data *adata = dev_get_drvdata(dev); acp_init(adata->acp_mmio); - if (adata->play_stream && adata->play_stream->runtime) + if (adata->play_stream && adata->play_stream->runtime) { + for (bank = 1; bank <= 4; bank++) + acp_set_sram_bank_state(adata->acp_mmio, bank, + true); config_acp_dma(adata->acp_mmio, adata->play_stream->runtime->private_data); - if (adata->capture_stream && adata->capture_stream->runtime) + } + if (adata->capture_stream && adata->capture_stream->runtime) { + for (bank = 5; bank <= 8; bank++) + acp_set_sram_bank_state(adata->acp_mmio, bank, + true); config_acp_dma(adata->acp_mmio, adata->capture_stream->runtime->private_data); - + } acp_reg_write(1, adata->acp_mmio, mmACP_EXTERNAL_INTR_ENB); return 0; }