[PATCH 00/15] ASoC: rsnd: cleanup add R-Car Gen4 Sound support
Hi Mark
This patch-set adds R-Car Gen4 support on Renesas sound driver. To add it, it needs some cleanups / prepares which makes easy to review the patch.
Kuninori Morimoto (15): ASoC: rsnd: check whether playback/capture property exists ASoC: rsnd: fixup #endif position ASoC: rsnd: Remove unnecessary rsnd_dbg_dai_call() ASoC: rsnd: indicate necessary error when clock start failed ASoC: rsnd: indicate warning once if it can't handle requested rule ASoC: rsnd: use same debug message format on clkout ASoC: rsnd: remove unnecessary ADG flags ASoC: rsnd: rename clk to clkin ASoC: rsnd: moves clkout_name to top of the file ASoC: rsnd: use clkin/out_size ASoC: rsnd: use array for 44.1kHz/48kHz rate handling ASoC: rsnd: tidyup rsnd_dma_addr() ASoC: rsnd: dma.c: tidyup rsnd_dma_probe() ASoC: dt-bindings: renesas: add R8A779G0 V4H ASoC: rsnd: add R-Car Gen4 Sound support
.../bindings/sound/renesas,rsnd.yaml | 4 + sound/soc/sh/rcar/adg.c | 169 ++++++++++-------- sound/soc/sh/rcar/core.c | 66 ++++--- sound/soc/sh/rcar/dma.c | 57 +++++- sound/soc/sh/rcar/gen.c | 70 ++++++++ sound/soc/sh/rcar/rsnd.h | 23 ++- sound/soc/sh/rcar/ssi.c | 13 +- sound/soc/sh/rcar/ssiu.c | 15 +- 8 files changed, 289 insertions(+), 128 deletions(-)
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
Current rsnd sets "channels_min" which is used from snd_soc_dai_stream_valid() without checking DT playback/capture property. Thus, "aplay -l" or "arecord -l" will indicate un-exising device. This patch checks DT proerty and do nothing playback/capture settings if not exist.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/sh/rcar/core.c | 42 +++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 16 deletions(-)
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 2d269ac8c137..ca3a0f285092 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -1343,6 +1343,7 @@ static void __rsnd_dai_probe(struct rsnd_priv *priv, struct snd_soc_dai_driver *drv; struct rsnd_dai *rdai; struct device *dev = rsnd_priv_to_dev(priv); + int playback_exist = 0, capture_exist = 0; int io_i;
rdai = rsnd_rdai_get(priv, dai_i); @@ -1357,22 +1358,6 @@ static void __rsnd_dai_probe(struct rsnd_priv *priv, drv->ops = &rsnd_soc_dai_ops; drv->pcm_new = rsnd_pcm_new;
- snprintf(io_playback->name, RSND_DAI_NAME_SIZE, - "DAI%d Playback", dai_i); - drv->playback.rates = RSND_RATES; - drv->playback.formats = RSND_FMTS; - drv->playback.channels_min = 2; - drv->playback.channels_max = 8; - drv->playback.stream_name = io_playback->name; - - snprintf(io_capture->name, RSND_DAI_NAME_SIZE, - "DAI%d Capture", dai_i); - drv->capture.rates = RSND_RATES; - drv->capture.formats = RSND_FMTS; - drv->capture.channels_min = 2; - drv->capture.channels_max = 8; - drv->capture.stream_name = io_capture->name; - io_playback->rdai = rdai; io_capture->rdai = rdai; rsnd_rdai_channels_set(rdai, 2); /* default 2ch */ @@ -1386,6 +1371,14 @@ static void __rsnd_dai_probe(struct rsnd_priv *priv, if (!playback && !capture) break;
+ if (io_i == 0) { + /* check whether playback/capture property exists */ + if (playback) + playback_exist = 1; + if (capture) + capture_exist = 1; + } + rsnd_parse_connect_ssi(rdai, playback, capture); rsnd_parse_connect_ssiu(rdai, playback, capture); rsnd_parse_connect_src(rdai, playback, capture); @@ -1397,6 +1390,23 @@ static void __rsnd_dai_probe(struct rsnd_priv *priv, of_node_put(capture); }
+ if (playback_exist) { + snprintf(io_playback->name, RSND_DAI_NAME_SIZE, "DAI%d Playback", dai_i); + drv->playback.rates = RSND_RATES; + drv->playback.formats = RSND_FMTS; + drv->playback.channels_min = 2; + drv->playback.channels_max = 8; + drv->playback.stream_name = io_playback->name; + } + if (capture_exist) { + snprintf(io_capture->name, RSND_DAI_NAME_SIZE, "DAI%d Capture", dai_i); + drv->capture.rates = RSND_RATES; + drv->capture.formats = RSND_FMTS; + drv->capture.channels_min = 2; + drv->capture.channels_max = 8; + drv->capture.stream_name = io_capture->name; + } + if (rsnd_ssi_is_pin_sharing(io_capture) || rsnd_ssi_is_pin_sharing(io_playback)) { /* should have symmetric_rate if pin sharing */
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
commit 1f9c82b5ab83ff2 ("ASoC: rsnd: add debugfs support") added CONFIG_DEBUG_FS related definitions on rsnd.h, but it should be added inside of RSND_H. This patch fixup it.
Fixes: 1f9c82b5ab83 ("ASoC: rsnd: add debugfs support") Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/sh/rcar/rsnd.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index d9cd190d7e19..f8ef6836ef84 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -901,8 +901,6 @@ void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type); if (!IS_BUILTIN(RSND_DEBUG_NO_DAI_CALL)) \ dev_dbg(dev, param)
-#endif - #ifdef CONFIG_DEBUG_FS int rsnd_debugfs_probe(struct snd_soc_component *component); void rsnd_debugfs_reg_show(struct seq_file *m, phys_addr_t _addr, @@ -913,3 +911,5 @@ void rsnd_debugfs_mod_reg_show(struct seq_file *m, struct rsnd_mod *mod, #else #define rsnd_debugfs_probe NULL #endif + +#endif /* RSND_H */
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
commit b43b8ae87c8e0a8 ("ASoC: rsnd: protect mod->status") removed RSND_DEBUG_NO_DAI_CALL and rsnd_dbg_dai_call(), but these are still exist on rsnd.h. This patch removes it.
Fixes: b43b8ae87c8e ("ASoC: rsnd: protect mod->status") Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/sh/rcar/rsnd.h | 10 ---------- 1 file changed, 10 deletions(-)
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index f8ef6836ef84..a09b3612b7f9 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -891,16 +891,6 @@ void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type); dev_info(dev, param); \ } while (0)
-/* - * If you don't need rsnd_dai_call debug message, - * define RSND_DEBUG_NO_DAI_CALL as 1 on top of core.c - * - * #define RSND_DEBUG_NO_DAI_CALL 1 - */ -#define rsnd_dbg_dai_call(dev, param...) \ - if (!IS_BUILTIN(RSND_DEBUG_NO_DAI_CALL)) \ - dev_dbg(dev, param) - #ifdef CONFIG_DEBUG_FS int rsnd_debugfs_probe(struct snd_soc_component *component); void rsnd_debugfs_reg_show(struct seq_file *m, phys_addr_t _addr,
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
rsnd_ssi_master_clk_start() indicates error message if it couldn't handle requested clock/rate, but it is not caring all cases. This patch cares it.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/sh/rcar/ssi.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 7ade6c5ed96f..8ddee5b03ece 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -303,15 +303,14 @@ static int rsnd_ssi_master_clk_start(struct rsnd_mod *mod, return 0; }
+ ret = -EIO; main_rate = rsnd_ssi_clk_query(rdai, rate, chan, &idx); - if (!main_rate) { - dev_err(dev, "unsupported clock rate\n"); - return -EIO; - } + if (!main_rate) + goto rate_err;
ret = rsnd_adg_ssi_clk_try_start(mod, main_rate); if (ret < 0) - return ret; + goto rate_err;
/* * SSI clock will be output contiguously @@ -333,6 +332,10 @@ static int rsnd_ssi_master_clk_start(struct rsnd_mod *mod, rsnd_mod_name(mod), chan, rate);
return 0; + +rate_err: + dev_err(dev, "unsupported clock rate\n"); + return ret; }
static void rsnd_ssi_master_clk_stop(struct rsnd_mod *mod,
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
Some SoC can't handle all requested hw rule. In such case, it will indicate like below, but it is unclear why it didn't work to user. This patch indicates warning in such case once, because player will try to similar rule many times.
# aplay sound.wav Playing WAVE 'sound.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo aplay: aplay.c: 1359: set_params: Assertion `err >= 0' failed. Aborted by signal Aborted...
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/sh/rcar/core.c | 19 ++++++++++++++++--- sound/soc/sh/rcar/rsnd.h | 1 + 2 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index ca3a0f285092..3de81af41ffc 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -869,7 +869,8 @@ static unsigned int rsnd_soc_hw_rate_list[] = {
static int rsnd_soc_hw_rule(struct rsnd_dai *rdai, unsigned int *list, int list_num, - struct snd_interval *baseline, struct snd_interval *iv) + struct snd_interval *baseline, struct snd_interval *iv, + struct rsnd_dai_stream *io, char *unit) { struct snd_interval p; unsigned int rate; @@ -899,6 +900,16 @@ static int rsnd_soc_hw_rule(struct rsnd_dai *rdai, } }
+ /* Indicate error once if it can't handle */ + if (!rsnd_flags_has(io, RSND_HW_RULE_ERR) && (p.min > p.max)) { + struct rsnd_priv *priv = rsnd_rdai_to_priv(rdai); + struct device *dev = rsnd_priv_to_dev(priv); + + dev_warn(dev, "It can't handle %d %s <-> %d %s\n", + baseline->min, unit, baseline->max, unit); + rsnd_flags_set(io, RSND_HW_RULE_ERR); + } + return snd_interval_refine(iv, &p); }
@@ -922,7 +933,7 @@ static int rsnd_soc_hw_rule_rate(struct snd_pcm_hw_params *params,
return rsnd_soc_hw_rule(rdai, rsnd_soc_hw_rate_list, ARRAY_SIZE(rsnd_soc_hw_rate_list), - &ic, ir); + &ic, ir, io, "ch"); }
static int rsnd_soc_hw_rule_channels(struct snd_pcm_hw_params *params, @@ -945,7 +956,7 @@ static int rsnd_soc_hw_rule_channels(struct snd_pcm_hw_params *params,
return rsnd_soc_hw_rule(rdai, rsnd_soc_hw_channels_list, ARRAY_SIZE(rsnd_soc_hw_channels_list), - ir, &ic); + ir, &ic, io, "Hz"); }
static const struct snd_pcm_hardware rsnd_pcm_hardware = { @@ -970,6 +981,8 @@ static int rsnd_soc_dai_startup(struct snd_pcm_substream *substream, unsigned int max_channels = rsnd_rdai_channels_get(rdai); int i;
+ rsnd_flags_del(io, RSND_HW_RULE_ERR); + rsnd_dai_stream_init(io, substream);
/* diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index a09b3612b7f9..3e1184f56ffd 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -513,6 +513,7 @@ struct rsnd_dai_stream { #define RSND_STREAM_HDMI0 (1 << 0) /* for HDMI0 */ #define RSND_STREAM_HDMI1 (1 << 1) /* for HDMI1 */ #define RSND_STREAM_TDM_SPLIT (1 << 2) /* for TDM split mode */ +#define RSND_HW_RULE_ERR (1 << 3) /* hw_rule error */
#define rsnd_io_to_mod(io, i) ((i) < RSND_MOD_MAX ? (io)->mod[(i)] : NULL) #define rsnd_io_to_mod_ssi(io) rsnd_io_to_mod((io), RSND_MOD_SSI)
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
This patch follows clkin debug message style on clkout.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/sh/rcar/adg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c index ca1e1281cefa..2c7958620524 100644 --- a/sound/soc/sh/rcar/adg.c +++ b/sound/soc/sh/rcar/adg.c @@ -661,8 +661,8 @@ void rsnd_adg_clk_dbg_info(struct rsnd_priv *priv, struct seq_file *m) * by BRGCKR::BRGCKR_31 */ for_each_rsnd_clkout(clk, adg, i) - dbg_msg(dev, m, "clkout %d : %pa : %ld\n", i, - clk, clk_get_rate(clk)); + dbg_msg(dev, m, "%-18s : %pa : %ld\n", + __clk_get_name(clk), clk, clk_get_rate(clk)); } #else #define rsnd_adg_clk_dbg_info(priv, m)
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
The flag LRCLK_ASYNC / AUDIO_OUT_48 had been added to handling special case of Salvator-X board, but it is not used on upstream. It makes code complex today, let's remove these.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/sh/rcar/adg.c | 25 ++++--------------------- 1 file changed, 4 insertions(+), 21 deletions(-)
diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c index 2c7958620524..776dfff8016b 100644 --- a/sound/soc/sh/rcar/adg.c +++ b/sound/soc/sh/rcar/adg.c @@ -32,7 +32,6 @@ struct rsnd_adg { struct clk_onecell_data onecell; struct rsnd_mod mod; int clk_rate[CLKMAX]; - u32 flags; u32 ckr; u32 rbga; u32 rbgb; @@ -41,9 +40,6 @@ struct rsnd_adg { int rbgb_rate_for_48khz; /* RBGB */ };
-#define LRCLK_ASYNC (1 << 0) -#define AUDIO_OUT_48 (1 << 1) - #define for_each_rsnd_clk(pos, adg, i) \ for (i = 0; \ (i < CLKMAX) && \ @@ -341,13 +337,8 @@ int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *ssi_mod, unsigned int rate)
rsnd_adg_set_ssi_clk(ssi_mod, data);
- if (rsnd_flags_has(adg, LRCLK_ASYNC)) { - if (rsnd_flags_has(adg, AUDIO_OUT_48)) - ckr = 0x80000000; - } else { - if (0 == (rate % 8000)) - ckr = 0x80000000; - } + if (0 == (rate % 8000)) + ckr = 0x80000000; /* BRGB output = 48kHz */
rsnd_mod_bset(adg_mod, BRGCKR, 0x80770000, adg->ckr | ckr); rsnd_mod_write(adg_mod, BRRA, adg->rbga); @@ -514,12 +505,6 @@ static int rsnd_adg_get_clkout(struct rsnd_priv *priv) req_48kHz_rate = req_rate[i]; }
- if (req_rate[0] % 48000 == 0) - rsnd_flags_set(adg, AUDIO_OUT_48); - - if (of_get_property(np, "clkout-lr-asynchronous", NULL)) - rsnd_flags_set(adg, LRCLK_ASYNC); - /* * This driver is assuming that AUDIO_CLKA/AUDIO_CLKB/AUDIO_CLKC * have 44.1kHz or 48kHz base clocks for now. @@ -547,8 +532,7 @@ static int rsnd_adg_get_clkout(struct rsnd_priv *priv) rbga = rbgx; adg->rbga_rate_for_441khz = rate / div; ckr |= brg_table[i] << 20; - if (req_441kHz_rate && - !rsnd_flags_has(adg, AUDIO_OUT_48)) + if (req_441kHz_rate) parent_clk_name = __clk_get_name(clk); } } @@ -563,8 +547,7 @@ static int rsnd_adg_get_clkout(struct rsnd_priv *priv) rbgb = rbgx; adg->rbgb_rate_for_48khz = rate / div; ckr |= brg_table[i] << 16; - if (req_48kHz_rate && - rsnd_flags_has(adg, AUDIO_OUT_48)) + if (req_48kHz_rate) parent_clk_name = __clk_get_name(clk); } }
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
Current adg.c is usig "clk" as clock IN, but is using "clkout" for clock OUT. This patch arranges "clk" to "clkin".
This is prepare for R-Car Gen4 support.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/sh/rcar/adg.c | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-)
diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c index 776dfff8016b..6392d20ad4a3 100644 --- a/sound/soc/sh/rcar/adg.c +++ b/sound/soc/sh/rcar/adg.c @@ -11,7 +11,7 @@ #define CLKB 1 #define CLKC 2 #define CLKI 3 -#define CLKMAX 4 +#define CLKINMAX 4
#define CLKOUT 0 #define CLKOUT1 1 @@ -26,12 +26,12 @@ static struct rsnd_mod_ops adg_ops = { };
struct rsnd_adg { - struct clk *clk[CLKMAX]; + struct clk *clkin[CLKINMAX]; struct clk *clkout[CLKOUTMAX]; struct clk *null_clk; struct clk_onecell_data onecell; struct rsnd_mod mod; - int clk_rate[CLKMAX]; + int clkin_rate[CLKINMAX]; u32 ckr; u32 rbga; u32 rbgb; @@ -40,10 +40,10 @@ struct rsnd_adg { int rbgb_rate_for_48khz; /* RBGB */ };
-#define for_each_rsnd_clk(pos, adg, i) \ +#define for_each_rsnd_clkin(pos, adg, i) \ for (i = 0; \ - (i < CLKMAX) && \ - ((pos) = adg->clk[i]); \ + (i < CLKINMAX) && \ + ((pos) = adg->clkin[i]); \ i++) #define for_each_rsnd_clkout(pos, adg, i) \ for (i = 0; \ @@ -52,7 +52,7 @@ struct rsnd_adg { i++) #define rsnd_priv_to_adg(priv) ((struct rsnd_adg *)(priv)->adg)
-static const char * const clk_name[] = { +static const char * const clkin_name[] = { [CLKA] = "clk_a", [CLKB] = "clk_b", [CLKC] = "clk_c", @@ -112,9 +112,9 @@ static void __rsnd_adg_get_timesel_ratio(struct rsnd_priv *priv, unsigned int val, en; unsigned int min, diff; unsigned int sel_rate[] = { - adg->clk_rate[CLKA], /* 0000: CLKA */ - adg->clk_rate[CLKB], /* 0001: CLKB */ - adg->clk_rate[CLKC], /* 0010: CLKC */ + adg->clkin_rate[CLKA], /* 0000: CLKA */ + adg->clkin_rate[CLKB], /* 0001: CLKB */ + adg->clkin_rate[CLKC], /* 0010: CLKC */ adg->rbga_rate_for_441khz, /* 0011: RBGA */ adg->rbgb_rate_for_48khz, /* 0100: RBGB */ }; @@ -287,6 +287,7 @@ static void rsnd_adg_set_ssi_clk(struct rsnd_mod *ssi_mod, u32 val) int rsnd_adg_clk_query(struct rsnd_priv *priv, unsigned int rate) { struct rsnd_adg *adg = rsnd_priv_to_adg(priv); + struct clk *clk; int i; int sel_table[] = { [CLKA] = 0x1, @@ -299,8 +300,8 @@ int rsnd_adg_clk_query(struct rsnd_priv *priv, unsigned int rate) * find suitable clock from * AUDIO_CLKA/AUDIO_CLKB/AUDIO_CLKC/AUDIO_CLKI. */ - for (i = 0; i < CLKMAX; i++) - if (rate == adg->clk_rate[i]) + for_each_rsnd_clkin(clk, adg, i) + if (rate == adg->clkin_rate[i]) return sel_table[i];
/* @@ -358,7 +359,7 @@ void rsnd_adg_clk_control(struct rsnd_priv *priv, int enable) struct clk *clk; int i;
- for_each_rsnd_clk(clk, adg, i) { + for_each_rsnd_clkin(clk, adg, i) { if (enable) { clk_prepare_enable(clk);
@@ -367,7 +368,7 @@ void rsnd_adg_clk_control(struct rsnd_priv *priv, int enable) * atomic context. Let's keep it when * rsnd_adg_clk_enable() was called */ - adg->clk_rate[i] = clk_get_rate(clk); + adg->clkin_rate[i] = clk_get_rate(clk); } else { clk_disable_unprepare(clk); } @@ -418,15 +419,15 @@ static int rsnd_adg_get_clkin(struct rsnd_priv *priv) struct clk *clk; int i;
- for (i = 0; i < CLKMAX; i++) { - clk = devm_clk_get(dev, clk_name[i]); + for (i = 0; i < CLKINMAX; i++) { + clk = devm_clk_get(dev, clkin_name[i]);
if (IS_ERR_OR_NULL(clk)) clk = rsnd_adg_null_clk_get(priv); if (IS_ERR_OR_NULL(clk)) goto err;
- adg->clk[i] = clk; + adg->clkin[i] = clk; }
return 0; @@ -516,7 +517,7 @@ static int rsnd_adg_get_clkout(struct rsnd_priv *priv) */ adg->rbga_rate_for_441khz = 0; adg->rbgb_rate_for_48khz = 0; - for_each_rsnd_clk(clk, adg, i) { + for_each_rsnd_clkin(clk, adg, i) { rate = clk_get_rate(clk);
if (0 == rate) /* not used */ @@ -630,7 +631,7 @@ void rsnd_adg_clk_dbg_info(struct rsnd_priv *priv, struct seq_file *m) struct clk *clk; int i;
- for_each_rsnd_clk(clk, adg, i) + for_each_rsnd_clkin(clk, adg, i) dbg_msg(dev, m, "%-18s : %pa : %ld\n", __clk_get_name(clk), clk, clk_get_rate(clk));
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
This patch moves clkout_name to top of the file to handling both clkin/clkout in the same place.
This is prepare for R-Car Gen4 support.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/sh/rcar/adg.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c index 6392d20ad4a3..f937cd4fe09e 100644 --- a/sound/soc/sh/rcar/adg.c +++ b/sound/soc/sh/rcar/adg.c @@ -59,6 +59,13 @@ static const char * const clkin_name[] = { [CLKI] = "clk_i", };
+static const char * const clkout_name[] = { + [CLKOUT] = "audio_clkout", + [CLKOUT1] = "audio_clkout1", + [CLKOUT2] = "audio_clkout2", + [CLKOUT3] = "audio_clkout3", +}; + static u32 rsnd_adg_calculate_rbgx(unsigned long div) { int i; @@ -465,12 +472,6 @@ static int rsnd_adg_get_clkout(struct rsnd_priv *priv) unsigned long req_48kHz_rate, req_441kHz_rate; int i, req_size; const char *parent_clk_name = NULL; - static const char * const clkout_name[] = { - [CLKOUT] = "audio_clkout", - [CLKOUT1] = "audio_clkout1", - [CLKOUT2] = "audio_clkout2", - [CLKOUT3] = "audio_clkout3", - }; int brg_table[] = { [CLKA] = 0x0, [CLKB] = 0x1,
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
Current adg.c is assuming number of clkin/clkout are fixed, but it is not correct on Gen4. This patch uses clkin/out_size to handling it.
This is prepare for R-Car Gen4 support.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/sh/rcar/adg.c | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-)
diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c index f937cd4fe09e..ff8e8318edb0 100644 --- a/sound/soc/sh/rcar/adg.c +++ b/sound/soc/sh/rcar/adg.c @@ -32,6 +32,8 @@ struct rsnd_adg { struct clk_onecell_data onecell; struct rsnd_mod mod; int clkin_rate[CLKINMAX]; + int clkin_size; + int clkout_size; u32 ckr; u32 rbga; u32 rbgb; @@ -42,24 +44,24 @@ struct rsnd_adg {
#define for_each_rsnd_clkin(pos, adg, i) \ for (i = 0; \ - (i < CLKINMAX) && \ + (i < adg->clkin_size) && \ ((pos) = adg->clkin[i]); \ i++) #define for_each_rsnd_clkout(pos, adg, i) \ for (i = 0; \ - (i < CLKOUTMAX) && \ + (i < adg->clkout_size) && \ ((pos) = adg->clkout[i]); \ i++) #define rsnd_priv_to_adg(priv) ((struct rsnd_adg *)(priv)->adg)
-static const char * const clkin_name[] = { +static const char * const clkin_name_gen2[] = { [CLKA] = "clk_a", [CLKB] = "clk_b", [CLKC] = "clk_c", [CLKI] = "clk_i", };
-static const char * const clkout_name[] = { +static const char * const clkout_name_gen2[] = { [CLKOUT] = "audio_clkout", [CLKOUT1] = "audio_clkout1", [CLKOUT2] = "audio_clkout2", @@ -424,9 +426,14 @@ static int rsnd_adg_get_clkin(struct rsnd_priv *priv) struct rsnd_adg *adg = priv->adg; struct device *dev = rsnd_priv_to_dev(priv); struct clk *clk; + const char * const *clkin_name; + int clkin_size; int i;
- for (i = 0; i < CLKINMAX; i++) { + clkin_name = clkin_name_gen2; + clkin_size = ARRAY_SIZE(clkin_name_gen2); + + for (i = 0; i < clkin_size; i++) { clk = devm_clk_get(dev, clkin_name[i]);
if (IS_ERR_OR_NULL(clk)) @@ -437,6 +444,8 @@ static int rsnd_adg_get_clkin(struct rsnd_priv *priv) adg->clkin[i] = clk; }
+ adg->clkin_size = clkin_size; + return 0;
err: @@ -470,8 +479,10 @@ static int rsnd_adg_get_clkout(struct rsnd_priv *priv) u32 req_rate[REQ_SIZE] = {}; uint32_t count = 0; unsigned long req_48kHz_rate, req_441kHz_rate; + int clkout_size; int i, req_size; const char *parent_clk_name = NULL; + const char * const *clkout_name; int brg_table[] = { [CLKA] = 0x0, [CLKB] = 0x1, @@ -555,6 +566,9 @@ static int rsnd_adg_get_clkout(struct rsnd_priv *priv) } }
+ clkout_name = clkout_name_gen2; + clkout_size = ARRAY_SIZE(clkout_name_gen2); + /* * ADG supports BRRA/BRRB output only. * this means all clkout0/1/2/3 will be * same rate @@ -571,13 +585,14 @@ static int rsnd_adg_get_clkout(struct rsnd_priv *priv) goto err;
adg->clkout[CLKOUT] = clk; + adg->clkout_size = 1; of_clk_add_provider(np, of_clk_src_simple_get, clk); } /* * for clkout0/1/2/3 */ else { - for (i = 0; i < CLKOUTMAX; i++) { + for (i = 0; i < clkout_size; i++) { clk = clk_register_fixed_rate(dev, clkout_name[i], parent_clk_name, 0, req_rate[0]); @@ -587,7 +602,8 @@ static int rsnd_adg_get_clkout(struct rsnd_priv *priv) adg->clkout[i] = clk; } adg->onecell.clks = adg->clkout; - adg->onecell.clk_num = CLKOUTMAX; + adg->onecell.clk_num = clkout_size; + adg->clkout_size = clkout_size; of_clk_add_provider(np, of_clk_src_onecell_get, &adg->onecell); }
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
ADG need to know output rate of 44.1kHz/48kHz. It is using single variable for each, but this patch changes it to array. Nothing is changed by this patch.
This is prepare for R-Car Gen4 support.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/sh/rcar/adg.c | 60 ++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 30 deletions(-)
diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c index ff8e8318edb0..00df32be4a4a 100644 --- a/sound/soc/sh/rcar/adg.c +++ b/sound/soc/sh/rcar/adg.c @@ -25,6 +25,10 @@ static struct rsnd_mod_ops adg_ops = { .name = "adg", };
+#define ADG_HZ_441 0 +#define ADG_HZ_48 1 +#define ADG_HZ_SIZE 2 + struct rsnd_adg { struct clk *clkin[CLKINMAX]; struct clk *clkout[CLKOUTMAX]; @@ -38,8 +42,7 @@ struct rsnd_adg { u32 rbga; u32 rbgb;
- int rbga_rate_for_441khz; /* RBGA */ - int rbgb_rate_for_48khz; /* RBGB */ + int rbg_rate[ADG_HZ_SIZE]; /* RBGA / RBGB */ };
#define for_each_rsnd_clkin(pos, adg, i) \ @@ -124,8 +127,8 @@ static void __rsnd_adg_get_timesel_ratio(struct rsnd_priv *priv, adg->clkin_rate[CLKA], /* 0000: CLKA */ adg->clkin_rate[CLKB], /* 0001: CLKB */ adg->clkin_rate[CLKC], /* 0010: CLKC */ - adg->rbga_rate_for_441khz, /* 0011: RBGA */ - adg->rbgb_rate_for_48khz, /* 0100: RBGB */ + adg->rbg_rate[ADG_HZ_441], /* 0011: RBGA */ + adg->rbg_rate[ADG_HZ_48], /* 0100: RBGB */ };
min = ~0; @@ -316,10 +319,10 @@ int rsnd_adg_clk_query(struct rsnd_priv *priv, unsigned int rate) /* * find divided clock from BRGA/BRGB */ - if (rate == adg->rbga_rate_for_441khz) + if (rate == adg->rbg_rate[ADG_HZ_441]) return 0x10;
- if (rate == adg->rbgb_rate_for_48khz) + if (rate == adg->rbg_rate[ADG_HZ_48]) return 0x20;
return -EIO; @@ -356,8 +359,8 @@ int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *ssi_mod, unsigned int rate)
dev_dbg(dev, "CLKOUT is based on BRG%c (= %dHz)\n", (ckr) ? 'B' : 'A', - (ckr) ? adg->rbgb_rate_for_48khz : - adg->rbga_rate_for_441khz); + (ckr) ? adg->rbg_rate[ADG_HZ_48] : + adg->rbg_rate[ADG_HZ_441]);
return 0; } @@ -475,10 +478,9 @@ static int rsnd_adg_get_clkout(struct rsnd_priv *priv) struct property *prop; u32 ckr, rbgx, rbga, rbgb; u32 rate, div; -#define REQ_SIZE 2 - u32 req_rate[REQ_SIZE] = {}; + u32 req_rate[ADG_HZ_SIZE] = {}; uint32_t count = 0; - unsigned long req_48kHz_rate, req_441kHz_rate; + unsigned long req_Hz[ADG_HZ_SIZE]; int clkout_size; int i, req_size; const char *parent_clk_name = NULL; @@ -503,19 +505,19 @@ static int rsnd_adg_get_clkout(struct rsnd_priv *priv) goto rsnd_adg_get_clkout_end;
req_size = prop->length / sizeof(u32); - if (req_size > REQ_SIZE) { + if (req_size > ADG_HZ_SIZE) { dev_err(dev, "too many clock-frequency\n"); return -EINVAL; }
of_property_read_u32_array(np, "clock-frequency", req_rate, req_size); - req_48kHz_rate = 0; - req_441kHz_rate = 0; + req_Hz[ADG_HZ_48] = 0; + req_Hz[ADG_HZ_441] = 0; for (i = 0; i < req_size; i++) { if (0 == (req_rate[i] % 44100)) - req_441kHz_rate = req_rate[i]; + req_Hz[ADG_HZ_441] = req_rate[i]; if (0 == (req_rate[i] % 48000)) - req_48kHz_rate = req_rate[i]; + req_Hz[ADG_HZ_48] = req_rate[i]; }
/* @@ -527,8 +529,6 @@ static int rsnd_adg_get_clkout(struct rsnd_priv *priv) * rsnd_adg_ssi_clk_try_start() * rsnd_ssi_master_clk_start() */ - adg->rbga_rate_for_441khz = 0; - adg->rbgb_rate_for_48khz = 0; for_each_rsnd_clkin(clk, adg, i) { rate = clk_get_rate(clk);
@@ -536,31 +536,31 @@ static int rsnd_adg_get_clkout(struct rsnd_priv *priv) continue;
/* RBGA */ - if (!adg->rbga_rate_for_441khz && (0 == rate % 44100)) { + if (!adg->rbg_rate[ADG_HZ_441] && (0 == rate % 44100)) { div = 6; - if (req_441kHz_rate) - div = rate / req_441kHz_rate; + if (req_Hz[ADG_HZ_441]) + div = rate / req_Hz[ADG_HZ_441]; rbgx = rsnd_adg_calculate_rbgx(div); if (BRRx_MASK(rbgx) == rbgx) { rbga = rbgx; - adg->rbga_rate_for_441khz = rate / div; + adg->rbg_rate[ADG_HZ_441] = rate / div; ckr |= brg_table[i] << 20; - if (req_441kHz_rate) + if (req_Hz[ADG_HZ_441]) parent_clk_name = __clk_get_name(clk); } }
/* RBGB */ - if (!adg->rbgb_rate_for_48khz && (0 == rate % 48000)) { + if (!adg->rbg_rate[ADG_HZ_48] && (0 == rate % 48000)) { div = 6; - if (req_48kHz_rate) - div = rate / req_48kHz_rate; + if (req_Hz[ADG_HZ_48]) + div = rate / req_Hz[ADG_HZ_48]; rbgx = rsnd_adg_calculate_rbgx(div); if (BRRx_MASK(rbgx) == rbgx) { rbgb = rbgx; - adg->rbgb_rate_for_48khz = rate / div; + adg->rbg_rate[ADG_HZ_48] = rate / div; ckr |= brg_table[i] << 16; - if (req_48kHz_rate) + if (req_Hz[ADG_HZ_48]) parent_clk_name = __clk_get_name(clk); } } @@ -654,8 +654,8 @@ void rsnd_adg_clk_dbg_info(struct rsnd_priv *priv, struct seq_file *m)
dbg_msg(dev, m, "BRGCKR = 0x%08x, BRRA/BRRB = 0x%x/0x%x\n", adg->ckr, adg->rbga, adg->rbgb); - dbg_msg(dev, m, "BRGA (for 44100 base) = %d\n", adg->rbga_rate_for_441khz); - dbg_msg(dev, m, "BRGB (for 48000 base) = %d\n", adg->rbgb_rate_for_48khz); + dbg_msg(dev, m, "BRGA (for 44100 base) = %d\n", adg->rbg_rate[ADG_HZ_441]); + dbg_msg(dev, m, "BRGB (for 48000 base) = %d\n", adg->rbg_rate[ADG_HZ_48]);
/* * Actual CLKOUT will be exchanged in rsnd_adg_ssi_clk_try_start()
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
This patch tidyups rsnd_dma_addr(), but there is no effect.
This is prepare for Gen4 support.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/sh/rcar/dma.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c index 463ab237d7bd..b422c3bd34de 100644 --- a/sound/soc/sh/rcar/dma.c +++ b/sound/soc/sh/rcar/dma.c @@ -659,16 +659,16 @@ static dma_addr_t rsnd_dma_addr(struct rsnd_dai_stream *io, { struct rsnd_priv *priv = rsnd_io_to_priv(io);
+ if (!mod) + return 0; + /* * gen1 uses default DMA addr */ if (rsnd_is_gen1(priv)) return 0; - - if (!mod) - return 0; - - return rsnd_gen2_dma_addr(io, mod, is_play, is_from); + else + return rsnd_gen2_dma_addr(io, mod, is_play, is_from); }
#define MOD_MAX (RSND_MOD_MAX + 1) /* +Memory */
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
This patch tidyups rsnd_dma_probe(), but there is no effect.
This is prepare for Gen4 support.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/sh/rcar/dma.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c index b422c3bd34de..9aca5ff791a3 100644 --- a/sound/soc/sh/rcar/dma.c +++ b/sound/soc/sh/rcar/dma.c @@ -885,13 +885,18 @@ int rsnd_dma_probe(struct rsnd_priv *priv) /* * for Gen2 or later */ - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "audmapp"); dmac = devm_kzalloc(dev, sizeof(*dmac), GFP_KERNEL); - if (!dmac || !res) { + if (!dmac) { dev_err(dev, "dma allocate failed\n"); return 0; /* it will be PIO mode */ }
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "audmapp"); + if (!res) { + dev_err(dev, "lack of audmapp in DT\n"); + return 0; /* it will be PIO mode */ + } + dmac->dmapp_num = 0; dmac->ppres = res->start; dmac->ppbase = devm_ioremap_resource(dev, res);
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
Document R-Car V4H (R8A779G0), and R-Car Gen4 SoC bindings.
Link: https://lore.kernel.org/r/87zga6t5r4.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- Documentation/devicetree/bindings/sound/renesas,rsnd.yaml | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/Documentation/devicetree/bindings/sound/renesas,rsnd.yaml b/Documentation/devicetree/bindings/sound/renesas,rsnd.yaml index 66175aeba7a7..d106de00c6b2 100644 --- a/Documentation/devicetree/bindings/sound/renesas,rsnd.yaml +++ b/Documentation/devicetree/bindings/sound/renesas,rsnd.yaml @@ -46,6 +46,10 @@ properties: - renesas,rcar_sound-r8a77990 # R-Car E3 - renesas,rcar_sound-r8a77995 # R-Car D3 - const: renesas,rcar_sound-gen3 + # for Gen4 SoC + - items: + - const: renesas,rcar_sound-r8a779g0 # R-Car V4H + - const: renesas,rcar_sound-gen4 # for Generic - enum: - renesas,rcar_sound-gen1
On 01/02/2023 03:02, Kuninori Morimoto wrote:
Blank line above From?
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
Document R-Car V4H (R8A779G0), and R-Car Gen4 SoC bindings.
Link: https://lore.kernel.org/r/87zga6t5r4.wl-kuninori.morimoto.gx@renesas.com
The Link is a tag added by maintainers pointing to applied version of the patch. This does not look correct...
Don't you wanted to just reference v1 under ---?
Best regards, Krzysztof
On Wed, Feb 01, 2023 at 08:11:48AM +0100, Krzysztof Kozlowski wrote:
On 01/02/2023 03:02, Kuninori Morimoto wrote:
Link: https://lore.kernel.org/r/87zga6t5r4.wl-kuninori.morimoto.gx@renesas.com
The Link is a tag added by maintainers pointing to applied version of the patch. This does not look correct...
It's just a general thing for linking to relevant information, it can be used for linking to other things too.
Hi Morimoto-san,
On Wed, Feb 1, 2023 at 3:11 AM Kuninori Morimoto kuninori.morimoto.gx@renesas.com wrote:
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
Document R-Car V4H (R8A779G0), and R-Car Gen4 SoC bindings.
Link: https://lore.kernel.org/r/87zga6t5r4.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
Thanks for your patch, which is now commit f76fec606d07b43d ("ASoC: dt-bindings: renesas: add R8A779G0 V4H") in sound-asoc/for-next
--- a/Documentation/devicetree/bindings/sound/renesas,rsnd.yaml +++ b/Documentation/devicetree/bindings/sound/renesas,rsnd.yaml @@ -46,6 +46,10 @@ properties: - renesas,rcar_sound-r8a77990 # R-Car E3 - renesas,rcar_sound-r8a77995 # R-Car D3 - const: renesas,rcar_sound-gen3
# for Gen4 SoC
- items:
- const: renesas,rcar_sound-r8a779g0 # R-Car V4H
- const: renesas,rcar_sound-gen4 # for Generic - enum: - renesas,rcar_sound-gen1
I think you forgot to update the reg-names section below, as it doesn't match its user in https://lore.kernel.org/all/877cx0anfe.wl-kuninori.morimoto.gx@renesas.com
Gr{oetje,eeting}s,
Geert
-- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Hi Geert
I think you forgot to update the reg-names section below, as it doesn't match its user in
Oops, yes indeed. Thank you for pointing it. Will send the patch
Thank you for your help !!
Best regards --- Kuninori Morimoto
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
This patch is tested on V4H White Hawk + ARD-AUDIO-DA7212
Signed-off-by: Linh Phung linh.phung.jy@renesas.com Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/sh/rcar/adg.c | 10 ++++++ sound/soc/sh/rcar/core.c | 5 +-- sound/soc/sh/rcar/dma.c | 38 +++++++++++++++++++++- sound/soc/sh/rcar/gen.c | 70 ++++++++++++++++++++++++++++++++++++++++ sound/soc/sh/rcar/rsnd.h | 8 +++++ sound/soc/sh/rcar/ssiu.c | 15 +++++++-- 6 files changed, 140 insertions(+), 6 deletions(-)
diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c index 00df32be4a4a..7bc4421835d7 100644 --- a/sound/soc/sh/rcar/adg.c +++ b/sound/soc/sh/rcar/adg.c @@ -57,6 +57,10 @@ struct rsnd_adg { i++) #define rsnd_priv_to_adg(priv) ((struct rsnd_adg *)(priv)->adg)
+static const char * const clkin_name_gen4[] = { + [CLKA] = "clkin", +}; + static const char * const clkin_name_gen2[] = { [CLKA] = "clk_a", [CLKB] = "clk_b", @@ -435,6 +439,10 @@ static int rsnd_adg_get_clkin(struct rsnd_priv *priv)
clkin_name = clkin_name_gen2; clkin_size = ARRAY_SIZE(clkin_name_gen2); + if (rsnd_is_gen4(priv)) { + clkin_name = clkin_name_gen4; + clkin_size = ARRAY_SIZE(clkin_name_gen4); + }
for (i = 0; i < clkin_size; i++) { clk = devm_clk_get(dev, clkin_name[i]); @@ -568,6 +576,8 @@ static int rsnd_adg_get_clkout(struct rsnd_priv *priv)
clkout_name = clkout_name_gen2; clkout_size = ARRAY_SIZE(clkout_name_gen2); + if (rsnd_is_gen4(priv)) + clkout_size = 1; /* reuse clkout_name_gen2[] */
/* * ADG supports BRRA/BRRB output only. diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 3de81af41ffc..a9125c1ff75a 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -102,6 +102,7 @@ static const struct of_device_id rsnd_of_match[] = { { .compatible = "renesas,rcar_sound-gen1", .data = (void *)RSND_GEN1 }, { .compatible = "renesas,rcar_sound-gen2", .data = (void *)RSND_GEN2 }, { .compatible = "renesas,rcar_sound-gen3", .data = (void *)RSND_GEN3 }, + { .compatible = "renesas,rcar_sound-gen4", .data = (void *)RSND_GEN4 }, /* Special Handling */ { .compatible = "renesas,rcar_sound-r8a77990", .data = (void *)(RSND_GEN3 | RSND_SOC_E) }, {}, @@ -1467,7 +1468,7 @@ static int rsnd_dai_probe(struct rsnd_priv *priv) if (is_graph) { for_each_endpoint_of_node(dai_node, dai_np) { __rsnd_dai_probe(priv, dai_np, dai_i); - if (rsnd_is_gen3(priv)) { + if (rsnd_is_gen3(priv) || rsnd_is_gen4(priv)) { rdai = rsnd_rdai_get(priv, dai_i);
rsnd_parse_connect_graph(priv, &rdai->playback, dai_np); @@ -1478,7 +1479,7 @@ static int rsnd_dai_probe(struct rsnd_priv *priv) } else { for_each_child_of_node(dai_node, dai_np) { __rsnd_dai_probe(priv, dai_np, dai_i); - if (rsnd_is_gen3(priv)) { + if (rsnd_is_gen3(priv) || rsnd_is_gen4(priv)) { rdai = rsnd_rdai_get(priv, dai_i);
rsnd_parse_connect_simple(priv, &rdai->playback, dai_np); diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c index 9aca5ff791a3..1c494e521463 100644 --- a/sound/soc/sh/rcar/dma.c +++ b/sound/soc/sh/rcar/dma.c @@ -653,6 +653,36 @@ rsnd_gen2_dma_addr(struct rsnd_dai_stream *io, dma_addrs[is_ssi][is_play][use_src + use_cmd].in_addr; }
+/* + * Gen4 DMA read/write register offset + * + * ex) R-Car V4H case + * mod / SYS-DMAC in / SYS-DMAC out + * SSI_SDMC: 0xec400000 / 0xec400000 / 0xec400000 + */ +#define RDMA_SSI_SDMC(addr, i) (addr + (0x8000 * i)) +static dma_addr_t +rsnd_gen4_dma_addr(struct rsnd_dai_stream *io, struct rsnd_mod *mod, + int is_play, int is_from) +{ + struct rsnd_priv *priv = rsnd_io_to_priv(io); + phys_addr_t addr = rsnd_gen_get_phy_addr(priv, RSND_GEN4_SDMC); + int id = rsnd_mod_id(mod); + int busif = rsnd_mod_id_sub(mod); + + /* + * SSI0 only is supported + */ + if (id != 0) { + struct device *dev = rsnd_priv_to_dev(priv); + + dev_err(dev, "This driver doesn't support non SSI0"); + return -EINVAL; + } + + return RDMA_SSI_SDMC(addr, busif); +} + static dma_addr_t rsnd_dma_addr(struct rsnd_dai_stream *io, struct rsnd_mod *mod, int is_play, int is_from) @@ -667,6 +697,8 @@ static dma_addr_t rsnd_dma_addr(struct rsnd_dai_stream *io, */ if (rsnd_is_gen1(priv)) return 0; + else if (rsnd_is_gen4(priv)) + return rsnd_gen4_dma_addr(io, mod, is_play, is_from); else return rsnd_gen2_dma_addr(io, mod, is_play, is_from); } @@ -891,6 +923,10 @@ int rsnd_dma_probe(struct rsnd_priv *priv) return 0; /* it will be PIO mode */ }
+ /* for Gen4 doesn't have DMA-pp */ + if (rsnd_is_gen4(priv)) + goto audmapp_end; + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "audmapp"); if (!res) { dev_err(dev, "lack of audmapp in DT\n"); @@ -902,7 +938,7 @@ int rsnd_dma_probe(struct rsnd_priv *priv) dmac->ppbase = devm_ioremap_resource(dev, res); if (IS_ERR(dmac->ppbase)) return PTR_ERR(dmac->ppbase); - +audmapp_end: priv->dma = dmac;
/* dummy mem mod for debug */ diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c index 925565baaa41..86bdecc24956 100644 --- a/sound/soc/sh/rcar/gen.c +++ b/sound/soc/sh/rcar/gen.c @@ -215,6 +215,74 @@ static int _rsnd_gen_regmap_init(struct rsnd_priv *priv, return 0; }
+/* + * Gen4 + */ +static int rsnd_gen4_probe(struct rsnd_priv *priv) +{ + static const struct rsnd_regmap_field_conf conf_ssiu[] = { + RSND_GEN_S_REG(SSI_SYS_INT_ENABLE0, 0x850), + RSND_GEN_S_REG(SSI_SYS_INT_ENABLE2, 0x858), + RSND_GEN_S_REG(SSI_SYS_INT_ENABLE4, 0x890), + RSND_GEN_S_REG(SSI_SYS_INT_ENABLE6, 0x898), + RSND_GEN_S_REG(SSI_SYS_STATUS0, 0x840), + RSND_GEN_S_REG(SSI_SYS_STATUS2, 0x848), + RSND_GEN_S_REG(SSI_SYS_STATUS4, 0x880), + RSND_GEN_S_REG(SSI_SYS_STATUS6, 0x888), + + RSND_GEN_S_REG(SSI_BUSIF0_MODE, 0x0), + RSND_GEN_S_REG(SSI_BUSIF0_ADINR, 0x4), + RSND_GEN_S_REG(SSI_BUSIF0_DALIGN, 0x8), + RSND_GEN_S_REG(SSI_BUSIF1_MODE, 0x20), + RSND_GEN_S_REG(SSI_BUSIF1_ADINR, 0x24), + RSND_GEN_S_REG(SSI_BUSIF1_DALIGN, 0x28), + RSND_GEN_S_REG(SSI_BUSIF2_MODE, 0x40), + RSND_GEN_S_REG(SSI_BUSIF2_ADINR, 0x44), + RSND_GEN_S_REG(SSI_BUSIF2_DALIGN, 0x48), + RSND_GEN_S_REG(SSI_BUSIF3_MODE, 0x60), + RSND_GEN_S_REG(SSI_BUSIF3_ADINR, 0x64), + RSND_GEN_S_REG(SSI_BUSIF3_DALIGN, 0x68), + RSND_GEN_S_REG(SSI_BUSIF4_MODE, 0x500), + RSND_GEN_S_REG(SSI_BUSIF4_ADINR, 0x504), + RSND_GEN_S_REG(SSI_BUSIF4_DALIGN, 0x508), + RSND_GEN_S_REG(SSI_BUSIF5_MODE, 0x520), + RSND_GEN_S_REG(SSI_BUSIF5_ADINR, 0x524), + RSND_GEN_S_REG(SSI_BUSIF5_DALIGN, 0x528), + RSND_GEN_S_REG(SSI_BUSIF6_MODE, 0x540), + RSND_GEN_S_REG(SSI_BUSIF6_ADINR, 0x544), + RSND_GEN_S_REG(SSI_BUSIF6_DALIGN, 0x548), + RSND_GEN_S_REG(SSI_BUSIF7_MODE, 0x560), + RSND_GEN_S_REG(SSI_BUSIF7_ADINR, 0x564), + RSND_GEN_S_REG(SSI_BUSIF7_DALIGN, 0x568), + RSND_GEN_S_REG(SSI_CTRL, 0x010), + RSND_GEN_S_REG(SSI_INT_ENABLE, 0x018), + RSND_GEN_S_REG(SSI_MODE, 0x00c), + RSND_GEN_S_REG(SSI_MODE2, 0xa0c), + }; + static const struct rsnd_regmap_field_conf conf_adg[] = { + RSND_GEN_S_REG(BRRA, 0x00), + RSND_GEN_S_REG(BRRB, 0x04), + RSND_GEN_S_REG(BRGCKR, 0x08), + RSND_GEN_S_REG(AUDIO_CLK_SEL0, 0x0c), + }; + static const struct rsnd_regmap_field_conf conf_ssi[] = { + RSND_GEN_S_REG(SSICR, 0x00), + RSND_GEN_S_REG(SSISR, 0x04), + RSND_GEN_S_REG(SSITDR, 0x08), + RSND_GEN_S_REG(SSIRDR, 0x0c), + RSND_GEN_S_REG(SSIWSR, 0x20), + }; + static const struct rsnd_regmap_field_conf conf_sdmc[] = { + RSND_GEN_M_REG(SSI_BUSIF, 0x0, 0x8000), + }; + int ret_adg = rsnd_gen_regmap_init(priv, 10, RSND_GEN4_ADG, "adg", conf_adg); + int ret_ssiu = rsnd_gen_regmap_init(priv, 10, RSND_GEN4_SSIU, "ssiu", conf_ssiu); + int ret_ssi = rsnd_gen_regmap_init(priv, 10, RSND_GEN4_SSI, "ssi", conf_ssi); + int ret_sdmc = rsnd_gen_regmap_init(priv, 10, RSND_GEN4_SDMC, "sdmc", conf_sdmc); + + return ret_adg | ret_ssiu | ret_ssi | ret_sdmc; +} + /* * Gen2 */ @@ -484,6 +552,8 @@ int rsnd_gen_probe(struct rsnd_priv *priv) else if (rsnd_is_gen2(priv) || rsnd_is_gen3(priv)) ret = rsnd_gen2_probe(priv); + else if (rsnd_is_gen4(priv)) + ret = rsnd_gen4_probe(priv);
if (ret < 0) dev_err(dev, "unknown generation R-Car sound device\n"); diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 3e1184f56ffd..239705d52517 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -31,6 +31,11 @@ #define RSND_GEN2_SSIU 2 #define RSND_GEN2_SSI 3
+#define RSND_GEN4_ADG 0 +#define RSND_GEN4_SSIU 1 +#define RSND_GEN4_SSI 2 +#define RSND_GEN4_SDMC 3 + #define RSND_BASE_MAX 4
/* @@ -197,6 +202,7 @@ enum rsnd_reg { SSI_SYS_INT_ENABLE5, SSI_SYS_INT_ENABLE6, SSI_SYS_INT_ENABLE7, + SSI_BUSIF, HDMI0_SEL, HDMI1_SEL, SSI9_BUSIF0_MODE, @@ -629,6 +635,7 @@ struct rsnd_priv { #define RSND_GEN1 (1 << 0) #define RSND_GEN2 (2 << 0) #define RSND_GEN3 (3 << 0) +#define RSND_GEN4 (4 << 0) #define RSND_SOC_MASK (0xFF << 4) #define RSND_SOC_E (1 << 4) /* E1/E2/E3 */
@@ -703,6 +710,7 @@ struct rsnd_priv { #define rsnd_is_gen1(priv) (((priv)->flags & RSND_GEN_MASK) == RSND_GEN1) #define rsnd_is_gen2(priv) (((priv)->flags & RSND_GEN_MASK) == RSND_GEN2) #define rsnd_is_gen3(priv) (((priv)->flags & RSND_GEN_MASK) == RSND_GEN3) +#define rsnd_is_gen4(priv) (((priv)->flags & RSND_GEN_MASK) == RSND_GEN4) #define rsnd_is_e3(priv) (((priv)->flags & \ (RSND_GEN_MASK | RSND_SOC_MASK)) == \ (RSND_GEN3 | RSND_SOC_E)) diff --git a/sound/soc/sh/rcar/ssiu.c b/sound/soc/sh/rcar/ssiu.c index 281bc20d4c5d..17bd8cc86dd0 100644 --- a/sound/soc/sh/rcar/ssiu.c +++ b/sound/soc/sh/rcar/ssiu.c @@ -29,8 +29,8 @@ struct rsnd_ssiu { i++)
/* - * SSI Gen2 Gen3 - * 0 BUSIF0-3 BUSIF0-7 + * SSI Gen2 Gen3 Gen4 + * 0 BUSIF0-3 BUSIF0-7 BUSIF0-7 * 1 BUSIF0-3 BUSIF0-7 * 2 BUSIF0-3 BUSIF0-7 * 3 BUSIF0 BUSIF0-7 @@ -40,10 +40,11 @@ struct rsnd_ssiu { * 7 BUSIF0 BUSIF0 * 8 BUSIF0 BUSIF0 * 9 BUSIF0-3 BUSIF0-7 - * total 22 52 + * total 22 52 8 */ static const int gen2_id[] = { 0, 4, 8, 12, 13, 14, 15, 16, 17, 18 }; static const int gen3_id[] = { 0, 8, 16, 24, 32, 40, 41, 42, 43, 44 }; +static const int gen4_id[] = { 0 };
/* enable busif buffer over/under run interrupt. */ #define rsnd_ssiu_busif_err_irq_enable(mod) rsnd_ssiu_busif_err_irq_ctrl(mod, 1) @@ -152,6 +153,10 @@ static int rsnd_ssiu_init(struct rsnd_mod *mod, /* clear status */ rsnd_ssiu_busif_err_status_clear(mod);
+ /* Gen4 doesn't have SSI_MODE */ + if (rsnd_is_gen4(priv)) + goto ssi_mode_setting_end; + /* * SSI_MODE0 */ @@ -206,6 +211,7 @@ static int rsnd_ssiu_init(struct rsnd_mod *mod, rsnd_mod_bset(mod, SSI_MODE1, 0x0013001f, val1); rsnd_mod_bset(mod, SSI_MODE2, 0x00000017, val2);
+ssi_mode_setting_end: /* * Enable busif buffer over/under run interrupt. * It will be handled from ssi.c @@ -553,6 +559,9 @@ int rsnd_ssiu_probe(struct rsnd_priv *priv) } else if (rsnd_is_gen3(priv)) { list = gen3_id; nr = ARRAY_SIZE(gen3_id); + } else if (rsnd_is_gen4(priv)) { + list = gen4_id; + nr = ARRAY_SIZE(gen4_id); } else { dev_err(dev, "unknown SSIU\n"); return -ENODEV;
On Wed, 01 Feb 2023 01:59:29 +0000, Kuninori Morimoto wrote:
This patch-set adds R-Car Gen4 support on Renesas sound driver. To add it, it needs some cleanups / prepares which makes easy to review the patch.
Kuninori Morimoto (15): ASoC: rsnd: check whether playback/capture property exists ASoC: rsnd: fixup #endif position ASoC: rsnd: Remove unnecessary rsnd_dbg_dai_call() ASoC: rsnd: indicate necessary error when clock start failed ASoC: rsnd: indicate warning once if it can't handle requested rule ASoC: rsnd: use same debug message format on clkout ASoC: rsnd: remove unnecessary ADG flags ASoC: rsnd: rename clk to clkin ASoC: rsnd: moves clkout_name to top of the file ASoC: rsnd: use clkin/out_size ASoC: rsnd: use array for 44.1kHz/48kHz rate handling ASoC: rsnd: tidyup rsnd_dma_addr() ASoC: rsnd: dma.c: tidyup rsnd_dma_probe() ASoC: dt-bindings: renesas: add R8A779G0 V4H ASoC: rsnd: add R-Car Gen4 Sound support
[...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
Thanks!
[01/15] ASoC: rsnd: check whether playback/capture property exists commit: 68a410aff971e59b9e94aa22c4c5cb6a6af30729 [02/15] ASoC: rsnd: fixup #endif position commit: 49123b51cd896e00b256a27c2ce9e6bfe1bbc22f [03/15] ASoC: rsnd: Remove unnecessary rsnd_dbg_dai_call() commit: e5a3c491e194768f4899e8d1746301542cd7c1e8 [04/15] ASoC: rsnd: indicate necessary error when clock start failed commit: c12dc0f6655bbf41d32a863b8e314f18f746fb0b [05/15] ASoC: rsnd: indicate warning once if it can't handle requested rule commit: 6d612f67a8d430ab1905f795fb440e6e3545d94f [06/15] ASoC: rsnd: use same debug message format on clkout commit: 3e262e9592bb18c4f491c2db8fd6cc49d9e23c38 [07/15] ASoC: rsnd: remove unnecessary ADG flags commit: 184d82e142eeb0a741ba9335601c075fc45b34aa [08/15] ASoC: rsnd: rename clk to clkin commit: 4bbff16d26e83a150851e19a1e24f4ee71125863 [09/15] ASoC: rsnd: moves clkout_name to top of the file commit: da2f9e859413465c11d8aff01ff6f112d516c58e [10/15] ASoC: rsnd: use clkin/out_size commit: efaab61588c4a85814ebf1fe983710bceb662d58 [11/15] ASoC: rsnd: use array for 44.1kHz/48kHz rate handling commit: 662721ece4f0146a09a0fe4108e7a05274723d7e [12/15] ASoC: rsnd: tidyup rsnd_dma_addr() commit: c20bc7c9ce3a3ad8d51b26823e2ad2ba9b8bb447 [13/15] ASoC: rsnd: dma.c: tidyup rsnd_dma_probe() commit: beab0aad7276795952d4bb52f88fe6bd2406404c [14/15] ASoC: dt-bindings: renesas: add R8A779G0 V4H commit: f76fec606d07b43d21475a0dda6294613379e224 [15/15] ASoC: rsnd: add R-Car Gen4 Sound support commit: c2bc65274a307e11743d0f56a762f8e57f279b9e
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
participants (4)
-
Geert Uytterhoeven
-
Krzysztof Kozlowski
-
Kuninori Morimoto
-
Mark Brown