From: John Madieu Date: Mon, 25 May 2026 11:02:22 +0000 (+0000) Subject: ASoC: rsnd: ssiu: Add RZ/G3E BUSIF support X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=80f43c5217715641a3147eb223677e3c1600e65b;p=thirdparty%2Fkernel%2Flinux.git ASoC: rsnd: ssiu: Add RZ/G3E BUSIF support Add support for the SSIU found on the Renesas RZ/G3E SoC, which provides a different BUSIF layout compared to earlier generations: - SSI0-SSI4: 4 BUSIF instances each (BUSIF0-3) - SSI5-SSI8: 1 BUSIF instance each (BUSIF0 only) - SSI9: 4 BUSIF instances (BUSIF0-3) - Total: 28 BUSIFs The RZ/G3E also has only two pairs of BUSIF error-status registers instead of four, and the SSI always operates in BUSIF mode: the SSI_MODE0 BUSIF/PIO select bit is not implemented and must not be written. While at it, add RSND_SSIU_BUSIF_STATUS_COUNT_2 as a capability flag in the match data, consumed via struct rsnd_ssiu_ctrl, to parametrise the two BUSIF error-status loops. Signed-off-by: John Madieu Acked-by: Kuninori Morimoto Link: https://patch.msgid.link/20260525110230.4014435-11-john.madieu.xa@bp.renesas.com Signed-off-by: Mark Brown --- diff --git a/sound/soc/renesas/rcar/core.c b/sound/soc/renesas/rcar/core.c index 7169d0ef8f900..f5c8ba8c5d565 100644 --- a/sound/soc/renesas/rcar/core.c +++ b/sound/soc/renesas/rcar/core.c @@ -106,7 +106,8 @@ static const struct of_device_id rsnd_of_match[] = { { .compatible = "renesas,rcar_sound-gen4", .data = (void *)RSND_GEN4 }, /* Special Handling */ { .compatible = "renesas,rcar_sound-r8a77990", .data = (void *)(RSND_GEN3 | RSND_SOC_E) }, - { .compatible = "renesas,r9a09g047-sound", .data = (void *)(RSND_RZ3 | RSND_RZG3E) }, + { .compatible = "renesas,r9a09g047-sound", + .data = (void *)(RSND_RZ3 | RSND_RZG3E | RSND_SSIU_BUSIF_STATUS_COUNT_2) }, {}, }; MODULE_DEVICE_TABLE(of, rsnd_of_match); diff --git a/sound/soc/renesas/rcar/rsnd.h b/sound/soc/renesas/rcar/rsnd.h index e917aa12fa80c..95843a20c43cc 100644 --- a/sound/soc/renesas/rcar/rsnd.h +++ b/sound/soc/renesas/rcar/rsnd.h @@ -666,6 +666,7 @@ struct rsnd_priv { #define RSND_RZ3 (3 << 8) #define RSND_RZ_ID_MASK (0xF << 12) /* nibble D */ #define RSND_RZG3E (1 << 12) +#define RSND_SSIU_BUSIF_STATUS_COUNT_2 BIT(16) /* Only 2 BUSIF error-status register pairs */ /* * below value will be filled on rsnd_gen_probe() */ @@ -690,6 +691,7 @@ struct rsnd_priv { /* * below value will be filled on rsnd_ssiu_probe() */ + void *ssiu_ctrl; void *ssiu; int ssiu_nr; diff --git a/sound/soc/renesas/rcar/ssiu.c b/sound/soc/renesas/rcar/ssiu.c index 2b922ead62d09..8d4ce9d35e9e7 100644 --- a/sound/soc/renesas/rcar/ssiu.c +++ b/sound/soc/renesas/rcar/ssiu.c @@ -29,31 +29,39 @@ struct rsnd_ssiu { i++) /* - * 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 - * 4 BUSIF0 BUSIF0-7 - * 5 BUSIF0 BUSIF0 - * 6 BUSIF0 BUSIF0 - * 7 BUSIF0 BUSIF0 - * 8 BUSIF0 BUSIF0 - * 9 BUSIF0-3 BUSIF0-7 - * total 22 52 8 + * SSI Gen2 Gen3 Gen4 RZ/G3E + * 0 BUSIF0-3 BUSIF0-7 BUSIF0-7 BUSIF0-3 + * 1 BUSIF0-3 BUSIF0-7 BUSIF0-3 + * 2 BUSIF0-3 BUSIF0-7 BUSIF0-3 + * 3 BUSIF0 BUSIF0-7 BUSIF0-3 + * 4 BUSIF0 BUSIF0-7 BUSIF0-3 + * 5 BUSIF0 BUSIF0 BUSIF0 + * 6 BUSIF0 BUSIF0 BUSIF0 + * 7 BUSIF0 BUSIF0 BUSIF0 + * 8 BUSIF0 BUSIF0 BUSIF0 + * 9 BUSIF0-3 BUSIF0-7 BUSIF0-3 + * total 22 52 8 28 */ 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 }; +static const int rzg3e_id[] = { 0, 4, 8, 12, 16, 20, 21, 22, 23, 24 }; + +struct rsnd_ssiu_ctrl { + unsigned int busif_status_count; +}; + +#define rsnd_priv_to_ssiu_ctrl(priv) \ + ((struct rsnd_ssiu_ctrl *)(priv)->ssiu_ctrl) /* enable busif buffer over/under run interrupt. */ #define rsnd_ssiu_busif_err_irq_enable(mod) rsnd_ssiu_busif_err_irq_ctrl(mod, 1) #define rsnd_ssiu_busif_err_irq_disable(mod) rsnd_ssiu_busif_err_irq_ctrl(mod, 0) static void rsnd_ssiu_busif_err_irq_ctrl(struct rsnd_mod *mod, int enable) { + struct rsnd_priv *priv = rsnd_mod_to_priv(mod); int id = rsnd_mod_id(mod); int shift, offset; - int i; switch (id) { case 0: @@ -72,7 +80,7 @@ static void rsnd_ssiu_busif_err_irq_ctrl(struct rsnd_mod *mod, int enable) return; } - for (i = 0; i < 4; i++) { + for (unsigned int i = 0; i < rsnd_priv_to_ssiu_ctrl(priv)->busif_status_count; i++) { enum rsnd_reg reg = SSI_SYS_INT_ENABLE((i * 2) + offset); u32 val = 0xf << (shift * 4); u32 sys_int_enable = rsnd_mod_read(mod, reg); @@ -87,10 +95,10 @@ static void rsnd_ssiu_busif_err_irq_ctrl(struct rsnd_mod *mod, int enable) bool rsnd_ssiu_busif_err_status_clear(struct rsnd_mod *mod) { + struct rsnd_priv *priv = rsnd_mod_to_priv(mod); bool error = false; int id = rsnd_mod_id(mod); int shift, offset; - int i; switch (id) { case 0: @@ -109,14 +117,13 @@ bool rsnd_ssiu_busif_err_status_clear(struct rsnd_mod *mod) goto out; } - for (i = 0; i < 4; i++) { + for (unsigned int i = 0; i < rsnd_priv_to_ssiu_ctrl(priv)->busif_status_count; i++) { u32 reg = SSI_SYS_STATUS(i * 2) + offset; u32 status = rsnd_mod_read(mod, reg); u32 val = 0xf << (shift * 4); status &= val; if (status) { - struct rsnd_priv *priv = rsnd_mod_to_priv(mod); struct device *dev = rsnd_priv_to_dev(priv); rsnd_print_irq_status(dev, "%s err status : 0x%08x\n", @@ -160,7 +167,8 @@ static int rsnd_ssiu_init(struct rsnd_mod *mod, /* * SSI_MODE0 */ - rsnd_mod_bset(mod, SSI_MODE0, (1 << id), !use_busif << id); + if (!rsnd_is_rzg3e(priv)) + rsnd_mod_bset(mod, SSI_MODE0, (1 << id), !use_busif << id); /* * SSI_MODE1 / SSI_MODE2 @@ -511,6 +519,7 @@ int rsnd_ssiu_probe(struct rsnd_priv *priv) struct device *dev = rsnd_priv_to_dev(priv); struct device_node *node __free(device_node) = rsnd_ssiu_of_node(priv); struct reset_control *rstc; + struct rsnd_ssiu_ctrl *ctrl; struct rsnd_ssiu *ssiu; struct rsnd_mod_ops *ops; const int *list = NULL; @@ -535,8 +544,15 @@ int rsnd_ssiu_probe(struct rsnd_priv *priv) if (!ssiu) return -ENOMEM; + ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL); + if (!ctrl) + return -ENOMEM; + + ctrl->busif_status_count = rsnd_flags_has(priv, RSND_SSIU_BUSIF_STATUS_COUNT_2) ? 2 : 4; + priv->ssiu = ssiu; priv->ssiu_nr = nr; + priv->ssiu_ctrl = ctrl; if (rsnd_is_gen1(priv)) ops = &rsnd_ssiu_ops_gen1; @@ -559,6 +575,9 @@ int rsnd_ssiu_probe(struct rsnd_priv *priv) } else if (rsnd_is_gen4(priv)) { list = gen4_id; nr = ARRAY_SIZE(gen4_id); + } else if (rsnd_is_rzg3e(priv)) { + list = rzg3e_id; + nr = ARRAY_SIZE(rzg3e_id); } else { dev_err(dev, "unknown SSIU\n"); return -ENODEV;