From patchwork Mon Jun 23 00:56:23 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuninori Morimoto X-Patchwork-Id: 4397071 Return-Path: X-Original-To: patchwork-linux-sh@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id E82269F26E for ; Mon, 23 Jun 2014 00:56:28 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id A9EBE2021A for ; Mon, 23 Jun 2014 00:56:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C148B20268 for ; Mon, 23 Jun 2014 00:56:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751616AbaFWA4Z (ORCPT ); Sun, 22 Jun 2014 20:56:25 -0400 Received: from mail-pa0-f45.google.com ([209.85.220.45]:43474 "EHLO mail-pa0-f45.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751406AbaFWA4Y (ORCPT ); Sun, 22 Jun 2014 20:56:24 -0400 Received: by mail-pa0-f45.google.com with SMTP id rd3so5168743pab.4 for ; Sun, 22 Jun 2014 17:56:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=date:sender:message-id:from:subject:user-agent:to:cc:in-reply-to :references:mime-version:content-type; bh=svwnMnmkFQXILPoZgW1qzmkTQa/q32QgLZkl5LIZjJU=; b=L93+aBgKQw1R6f8E2smhyWmEedYm+VH+N6FNMuh8NF/pxwURbZ7kTu7woVaIJPuI6B C8UghbzzebLT8hwPYGT3zW0KTO+hSJ8Pch1UAAP4VcvnApyNpWU3Q0uI0On71nm/P8eN Uk7eJh8guLqEgWAh+1VBW3IrYaGodTHrKGvO+lH7GFShyo41kDSmP97fAa6VNETePBov TGNq4R7rxHKPDel7n3TZJwpyDX/buaYrjm4e8ocD+LeNa5xAU5PgsWTIPRERffulmqV0 tF3YxexWk92TFHCn1YMz3b/Iudrm2t0ENDJBMNu3Zs7tadtczUSLkuvKpC6NUaL4ZbxB 7nPQ== X-Received: by 10.68.132.68 with SMTP id os4mr24218257pbb.129.1403484984306; Sun, 22 Jun 2014 17:56:24 -0700 (PDT) Received: from remon.gmail.com (49.14.32.202.bf.2iij.net. [202.32.14.49]) by mx.google.com with ESMTPSA id by1sm23894282pbb.75.2014.06.22.17.56.22 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Sun, 22 Jun 2014 17:56:23 -0700 (PDT) Date: Sun, 22 Jun 2014 17:56:23 -0700 (PDT) Message-ID: <87zjh4satf.wl%kuninori.morimoto.gx@renesas.com> From: Kuninori Morimoto Subject: [PATCH 04/10 v2] ASoC: rsnd: SSI + DMA can select BUSIF User-Agent: Wanderlust/2.14.0 Emacs/23.3 Mule/6.0 To: Mark Brown Cc: Kuninori Morimoto , Linux-ALSA , Liam Girdwood , Simon , linux-sh@vger.kernel.org In-Reply-To: <8761jstphc.wl%kuninori.morimoto.gx@gmail.com> References: <87d2e6zjhf.wl%kuninori.morimoto.gx@gmail.com> <8761jstphc.wl%kuninori.morimoto.gx@gmail.com> MIME-Version: 1.0 (generated by SEMI 1.14.6 - "Maruoka") Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID,T_RP_MATCHES_RCVD,UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Kuninori Morimoto Sound data needs to be sent to R-Car sound SSI when playback. But, there are 2 interfaces for it. 1st is SSITDR/SSIRDR which are mapped on SSI. 2nd is SSIn_BUSIF which are mapped on SSIU. 2nd SSIn_BUSIF is used when DMA transfer, and it is always used if sound data came from via SRC. But, we can use it when SSI+DMA case too. (Current driver is assuming 1st SSITDR/SSIRDR for it) 2nd SSIn_BUSIF can be used as FIFO. This is very helpful/useful for SSI+DMA. But DMA address / DMA ID are not same between 1st/2nd cases. This patch care about these settings. Signed-off-by: Kuninori Morimoto --- v1 -> v2 - no change .../devicetree/bindings/sound/renesas,rsnd.txt | 1 + include/sound/rcar_snd.h | 1 + sound/soc/sh/rcar/core.c | 22 ++++--- sound/soc/sh/rcar/gen.c | 64 +++++++++++++------- sound/soc/sh/rcar/rsnd.h | 10 ++- sound/soc/sh/rcar/src.c | 37 ++++++++--- sound/soc/sh/rcar/ssi.c | 33 +++++++++- 7 files changed, 123 insertions(+), 45 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/renesas,rsnd.txt b/Documentation/devicetree/bindings/sound/renesas,rsnd.txt index 8346cab..41a120c 100644 --- a/Documentation/devicetree/bindings/sound/renesas,rsnd.txt +++ b/Documentation/devicetree/bindings/sound/renesas,rsnd.txt @@ -21,6 +21,7 @@ SSI subnode properties: - interrupts : Should contain SSI interrupt for PIO transfer - shared-pin : if shared clock pin - pio-transfer : use PIO transfer mode +- no-busif : BUSIF is not ussed when [mem -> SSI] via DMA case SRC subnode properties: no properties at this point diff --git a/include/sound/rcar_snd.h b/include/sound/rcar_snd.h index f4a706f..d76412b 100644 --- a/include/sound/rcar_snd.h +++ b/include/sound/rcar_snd.h @@ -34,6 +34,7 @@ * B : SSI direction */ #define RSND_SSI_CLK_PIN_SHARE (1 << 31) +#define RSND_SSI_NO_BUSIF (1 << 30) /* SSI+DMA without BUSIF */ #define RSND_SSI(_dma_id, _pio_irq, _flags) \ { .dma_id = _dma_id, .pio_irq = _pio_irq, .flags = _flags } diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 7f68b33..8c3707a 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -138,6 +138,17 @@ char *rsnd_mod_name(struct rsnd_mod *mod) return mod->ops->name; } +char *rsnd_mod_dma_name(struct rsnd_mod *mod) +{ + if (!mod || !mod->ops) + return "unknown"; + + if (!mod->ops->dma_name) + return mod->ops->name; + + return mod->ops->dma_name(mod); +} + void rsnd_mod_init(struct rsnd_priv *priv, struct rsnd_mod *mod, struct rsnd_mod_ops *ops, @@ -261,7 +272,7 @@ static int _rsnd_dma_of_name(char *dma_name, struct rsnd_mod *mod) { if (mod) return snprintf(dma_name, DMA_NAME_SIZE / 2, "%s%d", - rsnd_mod_name(mod), rsnd_mod_id(mod)); + rsnd_mod_dma_name(mod), rsnd_mod_id(mod)); else return snprintf(dma_name, DMA_NAME_SIZE / 2, "mem"); @@ -343,11 +354,8 @@ int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, dma_cap_zero(mask); dma_cap_set(DMA_SLAVE, mask); - if (dev->of_node) - rsnd_dma_of_name(dma, is_play, dma_name); - else - snprintf(dma_name, DMA_NAME_SIZE, - is_play ? "tx" : "rx"); + rsnd_dma_of_name(dma, is_play, dma_name); + rsnd_gen_dma_addr(priv, dma, &cfg, is_play, id); dev_dbg(dev, "dma name : %s\n", dma_name); @@ -359,8 +367,6 @@ int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, return -EIO; } - rsnd_gen_dma_addr(priv, dma, &cfg, is_play, id); - ret = dmaengine_slave_config(dma->chan, &cfg); if (ret < 0) goto rsnd_dma_init_err; diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c index 0280a11..46677af 100644 --- a/sound/soc/sh/rcar/gen.c +++ b/sound/soc/sh/rcar/gen.c @@ -165,15 +165,19 @@ static int rsnd_gen_regmap_init(struct rsnd_priv *priv, * * ex) R-Car H2 case * mod / DMAC in / DMAC out / DMAC PP in / DMAC pp out - * SSI : 0xec541000 / 0xec241008 / 0xec24100c / 0xec400000 / 0xec400000 + * SSI : 0xec541000 / 0xec241008 / 0xec24100c + * SSIU: 0xec541000 / 0xec100000 / 0xec100000 / 0xec400000 / 0xec400000 * SCU : 0xec500000 / 0xec000000 / 0xec004000 / 0xec300000 / 0xec304000 * CMD : 0xec500000 / 0xec008000 0xec308000 */ #define RDMA_SSI_I_N(addr, i) (addr ##_reg - 0x00300000 + (0x40 * i) + 0x8) #define RDMA_SSI_O_N(addr, i) (addr ##_reg - 0x00300000 + (0x40 * i) + 0xc) -#define RDMA_SSI_I_P(addr, i) (addr ##_reg - 0x00141000 + (0x1000 * i)) -#define RDMA_SSI_O_P(addr, i) (addr ##_reg - 0x00141000 + (0x1000 * i)) +#define RDMA_SSIU_I_N(addr, i) (addr ##_reg - 0x00441000 + (0x1000 * i)) +#define RDMA_SSIU_O_N(addr, i) (addr ##_reg - 0x00441000 + (0x1000 * i)) + +#define RDMA_SSIU_I_P(addr, i) (addr ##_reg - 0x00141000 + (0x1000 * i)) +#define RDMA_SSIU_O_P(addr, i) (addr ##_reg - 0x00141000 + (0x1000 * i)) #define RDMA_SRC_I_N(addr, i) (addr ##_reg - 0x00500000 + (0x400 * i)) #define RDMA_SRC_O_N(addr, i) (addr ##_reg - 0x004fc000 + (0x400 * i)) @@ -204,26 +208,36 @@ static void rsnd_gen2_dma_addr(struct rsnd_priv *priv, struct dma_addr { dma_addr_t src_addr; dma_addr_t dst_addr; - } dma_addrs[2][2][3] = { - { /* SRC */ - /* Capture */ - {{ 0, 0 }, - { RDMA_SRC_O_N(src, id), 0 }, - { RDMA_CMD_O_N(src, id), 0 }}, - /* Playback */ - {{ 0, 0, }, - { 0, RDMA_SRC_I_N(src, id) }, - { 0, RDMA_SRC_I_N(src, id) }} - }, { /* SSI */ - /* Capture */ - {{ RDMA_SSI_O_N(ssi, id), 0 }, - { RDMA_SSI_O_P(ssi, id), RDMA_SRC_I_P(src, id) }, - { RDMA_SSI_O_P(ssi, id), RDMA_SRC_I_P(src, id) }}, - /* Playback */ - {{ 0, RDMA_SSI_I_N(ssi, id) }, - { RDMA_SRC_O_P(src, id), RDMA_SSI_I_P(ssi, id) }, - { RDMA_CMD_O_P(src, id), RDMA_SSI_I_P(ssi, id) }} - } + } dma_addrs[3][2][3] = { + /* SRC */ + {{{ 0, 0 }, + /* Capture */ + { RDMA_SRC_O_N(src, id), 0 }, + { RDMA_CMD_O_N(src, id), 0 } }, + /* Playback */ + {{ 0, 0, }, + { 0, RDMA_SRC_I_N(src, id) }, + { 0, RDMA_SRC_I_N(src, id) } } + }, + /* SSI */ + /* Capture */ + {{{ RDMA_SSI_O_N(ssi, id), 0 }, + { 0, 0 }, + { 0, 0 } }, + /* Playback */ + {{ 0, RDMA_SSI_I_N(ssi, id) }, + { 0, 0 }, + { 0, 0 } } + }, + /* SSIU */ + /* Capture */ + {{{ RDMA_SSIU_O_N(ssi, id), 0 }, + { RDMA_SSIU_O_P(ssi, id), RDMA_SRC_I_P(src, id) }, + { RDMA_SSIU_O_P(ssi, id), RDMA_SRC_I_P(src, id) } }, + /* Playback */ + {{ 0, RDMA_SSIU_I_N(ssi, id) }, + { RDMA_SRC_O_P(src, id), RDMA_SSIU_I_P(ssi, id) }, + { RDMA_CMD_O_P(src, id), RDMA_SSIU_I_P(ssi, id) } } }, }; /* it shouldn't happen */ @@ -232,6 +246,10 @@ static void rsnd_gen2_dma_addr(struct rsnd_priv *priv, return; } + /* use SSIU or SSI ? */ + if (is_ssi && (0 == strcmp(rsnd_mod_dma_name(mod), "ssiu"))) + is_ssi++; + cfg->src_addr = dma_addrs[is_ssi][is_play][use_src + use_dvc].src_addr; cfg->dst_addr = dma_addrs[is_ssi][is_play][use_src + use_dvc].dst_addr; diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 067a89e..a1466c1 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -185,6 +185,7 @@ enum rsnd_mod_type { struct rsnd_mod_ops { char *name; + char* (*dma_name)(struct rsnd_mod *mod); int (*probe)(struct rsnd_mod *mod, struct rsnd_dai *rdai); int (*remove)(struct rsnd_mod *mod, @@ -224,6 +225,7 @@ void rsnd_mod_init(struct rsnd_priv *priv, enum rsnd_mod_type type, int id); char *rsnd_mod_name(struct rsnd_mod *mod); +char *rsnd_mod_dma_name(struct rsnd_mod *mod); /* * R-Car sound DAI @@ -391,8 +393,12 @@ struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id); unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv, struct rsnd_dai_stream *io, struct snd_pcm_runtime *runtime); -int rsnd_src_ssi_mode_init(struct rsnd_mod *ssi_mod, - struct rsnd_dai *rdai); +int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod, + struct rsnd_dai *rdai, + int use_busif); +int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod, + struct rsnd_dai *rdai, + int use_busif); int rsnd_src_enable_ssi_irq(struct rsnd_mod *ssi_mod, struct rsnd_dai *rdai); diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index 200eda0..4d39505 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -106,18 +106,17 @@ struct rsnd_src { /* * Gen1/Gen2 common functions */ -int rsnd_src_ssi_mode_init(struct rsnd_mod *ssi_mod, - struct rsnd_dai *rdai) +int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod, + struct rsnd_dai *rdai, + int use_busif) { - struct rsnd_dai_stream *io = rsnd_mod_to_io(ssi_mod); - struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io); int ssi_id = rsnd_mod_id(ssi_mod); /* * SSI_MODE0 */ rsnd_mod_bset(ssi_mod, SSI_MODE0, (1 << ssi_id), - src_mod ? 0 : (1 << ssi_id)); + !use_busif << ssi_id); /* * SSI_MODE1 @@ -143,6 +142,29 @@ int rsnd_src_ssi_mode_init(struct rsnd_mod *ssi_mod, 0x2 << shift : 0x1 << shift); } + /* + * DMA settings for SSIU + */ + if (use_busif) { + rsnd_mod_write(ssi_mod, SSI_BUSIF_ADINR, + rsnd_get_adinr(ssi_mod)); + rsnd_mod_write(ssi_mod, SSI_BUSIF_MODE, 1); + rsnd_mod_write(ssi_mod, SSI_CTRL, 0x1); + } + + return 0; +} + +int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod, + struct rsnd_dai *rdai, + int use_busif) +{ + /* + * DMA settings for SSIU + */ + if (use_busif) + rsnd_mod_write(ssi_mod, SSI_CTRL, 0); + return 0; } @@ -467,9 +489,6 @@ static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod, if (ret < 0) return ret; - rsnd_mod_write(mod, SSI_BUSIF_ADINR, rsnd_get_adinr(mod)); - rsnd_mod_write(mod, SSI_BUSIF_MODE, 1); - rsnd_mod_write(mod, SRC_SRCCR, 0x00011110); rsnd_mod_write(mod, SRC_BSDSR, 0x01800000); @@ -554,7 +573,6 @@ static int rsnd_src_start_gen2(struct rsnd_mod *mod, rsnd_dma_start(rsnd_mod_to_dma(&src->mod)); - rsnd_mod_write(mod, SSI_CTRL, 0x1); rsnd_mod_write(mod, SRC_CTRL, val); return rsnd_src_start(mod, rdai); @@ -565,7 +583,6 @@ static int rsnd_src_stop_gen2(struct rsnd_mod *mod, { struct rsnd_src *src = rsnd_mod_to_src(mod); - rsnd_mod_write(mod, SSI_CTRL, 0); rsnd_mod_write(mod, SRC_CTRL, 0); rsnd_dma_stop(rsnd_mod_to_dma(&src->mod)); diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 2df723d..34e8400 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -90,6 +90,20 @@ struct rsnd_ssi { #define rsnd_ssi_mode_flags(p) ((p)->info->flags) #define rsnd_ssi_dai_id(ssi) ((ssi)->info->dai_id) +static int rsnd_ssi_use_busif(struct rsnd_mod *mod) +{ + struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); + struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); + int use_busif = 0; + + if (!(rsnd_ssi_mode_flags(ssi) & RSND_SSI_NO_BUSIF)) + use_busif = 1; + if (rsnd_io_to_mod_src(io)) + use_busif = 1; + + return use_busif; +} + static void rsnd_ssi_status_check(struct rsnd_mod *mod, u32 bit) { @@ -289,8 +303,6 @@ static int rsnd_ssi_init(struct rsnd_mod *mod, ssi->cr_own = cr; ssi->err = -1; /* ignore 1st error */ - rsnd_src_ssi_mode_init(mod, rdai); - return 0; } @@ -389,6 +401,8 @@ static int rsnd_ssi_pio_start(struct rsnd_mod *mod, /* enable PIO IRQ */ ssi->cr_etc = UIEN | OIEN | DIEN; + rsnd_src_ssiu_start(mod, rdai, 0); + rsnd_src_enable_ssi_irq(mod, rdai); rsnd_ssi_hw_start(ssi, rdai, io); @@ -405,6 +419,8 @@ static int rsnd_ssi_pio_stop(struct rsnd_mod *mod, rsnd_ssi_hw_stop(ssi, rdai); + rsnd_src_ssiu_stop(mod, rdai, 0); + return 0; } @@ -457,6 +473,8 @@ static int rsnd_ssi_dma_start(struct rsnd_mod *mod, /* enable DMA transfer */ ssi->cr_etc = DMEN; + rsnd_src_ssiu_start(mod, rdai, rsnd_ssi_use_busif(mod)); + rsnd_dma_start(dma); rsnd_ssi_hw_start(ssi, ssi->rdai, io); @@ -482,11 +500,19 @@ static int rsnd_ssi_dma_stop(struct rsnd_mod *mod, rsnd_dma_stop(dma); + rsnd_src_ssiu_stop(mod, rdai, 1); + return 0; } +static char *rsnd_ssi_dma_name(struct rsnd_mod *mod) +{ + return rsnd_ssi_use_busif(mod) ? "ssiu" : SSI_NAME; +} + static struct rsnd_mod_ops rsnd_ssi_dma_ops = { .name = SSI_NAME, + .dma_name = rsnd_ssi_dma_name, .probe = rsnd_ssi_dma_probe, .remove = rsnd_ssi_dma_remove, .init = rsnd_ssi_init, @@ -595,6 +621,9 @@ static void rsnd_of_parse_ssi(struct platform_device *pdev, */ ssi_info->dma_id = of_get_property(np, "pio-transfer", NULL) ? 0 : 1; + + if (of_get_property(np, "no-busif", NULL)) + ssi_info->flags |= RSND_SSI_NO_BUSIF; } rsnd_of_parse_ssi_end: