mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
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 <john.madieu.xa@bp.renesas.com> Acked-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Link: https://patch.msgid.link/20260525110230.4014435-11-john.madieu.xa@bp.renesas.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
b4ef837a28
commit
80f43c5217
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user