public inbox for alsa-devel@alsa-project.org
 help / color / mirror / Atom feed
From: Sasha Levin <sashal@kernel.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: Chen Li <licheng0822@thundersoft.com>,
	Sasha Levin <sashal@kernel.org>,
	alsa-devel@alsa-project.org,
	Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>,
	Mark Brown <broonie@kernel.org>,
	Yongbo Zhang <giraffesnn123@gmail.com>
Subject: [PATCH AUTOSEL 5.4 134/266] SoC: rsnd: add interrupt support for SSI BUSIF buffer
Date: Wed, 17 Jun 2020 21:14:19 -0400	[thread overview]
Message-ID: <20200618011631.604574-134-sashal@kernel.org> (raw)
In-Reply-To: <20200618011631.604574-1-sashal@kernel.org>

From: Yongbo Zhang <giraffesnn123@gmail.com>

[ Upstream commit 66c705d07d784fb6b4622c6e47b6acae357472db ]

SSI BUSIF buffer is possible to overflow or underflow, especially in a
hypervisor environment. If there is no interrupt support, it will eventually
lead to errors in pcm data.
This patch adds overflow and underflow interrupt support for SSI BUSIF buffer.

Reported-by: Chen Li <licheng0822@thundersoft.com>
Signed-off-by: Yongbo Zhang <giraffesnn123@gmail.com>
Tested-by: Chen Li <licheng0822@thundersoft.com>
Acked-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/20200512093003.28332-1-giraffesnn123@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 sound/soc/sh/rcar/gen.c  |   8 +++
 sound/soc/sh/rcar/rsnd.h |   9 +++
 sound/soc/sh/rcar/ssi.c  | 145 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 162 insertions(+)

diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c
index af19010b9d88..8bd49c8a9517 100644
--- a/sound/soc/sh/rcar/gen.c
+++ b/sound/soc/sh/rcar/gen.c
@@ -224,6 +224,14 @@ static int rsnd_gen2_probe(struct rsnd_priv *priv)
 		RSND_GEN_S_REG(SSI_SYS_STATUS5,	0x884),
 		RSND_GEN_S_REG(SSI_SYS_STATUS6,	0x888),
 		RSND_GEN_S_REG(SSI_SYS_STATUS7,	0x88c),
+		RSND_GEN_S_REG(SSI_SYS_INT_ENABLE0, 0x850),
+		RSND_GEN_S_REG(SSI_SYS_INT_ENABLE1, 0x854),
+		RSND_GEN_S_REG(SSI_SYS_INT_ENABLE2, 0x858),
+		RSND_GEN_S_REG(SSI_SYS_INT_ENABLE3, 0x85c),
+		RSND_GEN_S_REG(SSI_SYS_INT_ENABLE4, 0x890),
+		RSND_GEN_S_REG(SSI_SYS_INT_ENABLE5, 0x894),
+		RSND_GEN_S_REG(SSI_SYS_INT_ENABLE6, 0x898),
+		RSND_GEN_S_REG(SSI_SYS_INT_ENABLE7, 0x89c),
 		RSND_GEN_S_REG(HDMI0_SEL,	0x9e0),
 		RSND_GEN_S_REG(HDMI1_SEL,	0x9e4),
 
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index ea6cbaa9743e..d47608ff5fac 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -189,6 +189,14 @@ enum rsnd_reg {
 	SSI_SYS_STATUS5,
 	SSI_SYS_STATUS6,
 	SSI_SYS_STATUS7,
+	SSI_SYS_INT_ENABLE0,
+	SSI_SYS_INT_ENABLE1,
+	SSI_SYS_INT_ENABLE2,
+	SSI_SYS_INT_ENABLE3,
+	SSI_SYS_INT_ENABLE4,
+	SSI_SYS_INT_ENABLE5,
+	SSI_SYS_INT_ENABLE6,
+	SSI_SYS_INT_ENABLE7,
 	HDMI0_SEL,
 	HDMI1_SEL,
 	SSI9_BUSIF0_MODE,
@@ -237,6 +245,7 @@ enum rsnd_reg {
 #define SSI9_BUSIF_ADINR(i)	(SSI9_BUSIF0_ADINR + (i))
 #define SSI9_BUSIF_DALIGN(i)	(SSI9_BUSIF0_DALIGN + (i))
 #define SSI_SYS_STATUS(i)	(SSI_SYS_STATUS0 + (i))
+#define SSI_SYS_INT_ENABLE(i) (SSI_SYS_INT_ENABLE0 + (i))
 
 
 struct rsnd_priv;
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index 4a7d3413917f..47d5ddb526f2 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -372,6 +372,9 @@ static void rsnd_ssi_config_init(struct rsnd_mod *mod,
 	u32 wsr		= ssi->wsr;
 	int width;
 	int is_tdm, is_tdm_split;
+	int id = rsnd_mod_id(mod);
+	int i;
+	u32 sys_int_enable = 0;
 
 	is_tdm		= rsnd_runtime_is_tdm(io);
 	is_tdm_split	= rsnd_runtime_is_tdm_split(io);
@@ -447,6 +450,38 @@ static void rsnd_ssi_config_init(struct rsnd_mod *mod,
 		cr_mode = DIEN;		/* PIO : enable Data interrupt */
 	}
 
+	/* enable busif buffer over/under run interrupt. */
+	if (is_tdm || is_tdm_split) {
+		switch (id) {
+		case 0:
+		case 1:
+		case 2:
+		case 3:
+		case 4:
+			for (i = 0; i < 4; i++) {
+				sys_int_enable = rsnd_mod_read(mod,
+					SSI_SYS_INT_ENABLE(i * 2));
+				sys_int_enable |= 0xf << (id * 4);
+				rsnd_mod_write(mod,
+					       SSI_SYS_INT_ENABLE(i * 2),
+					       sys_int_enable);
+			}
+
+			break;
+		case 9:
+			for (i = 0; i < 4; i++) {
+				sys_int_enable = rsnd_mod_read(mod,
+					SSI_SYS_INT_ENABLE((i * 2) + 1));
+				sys_int_enable |= 0xf << 4;
+				rsnd_mod_write(mod,
+					       SSI_SYS_INT_ENABLE((i * 2) + 1),
+					       sys_int_enable);
+			}
+
+			break;
+		}
+	}
+
 init_end:
 	ssi->cr_own	= cr_own;
 	ssi->cr_mode	= cr_mode;
@@ -496,6 +531,13 @@ static int rsnd_ssi_quit(struct rsnd_mod *mod,
 {
 	struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
 	struct device *dev = rsnd_priv_to_dev(priv);
+	int is_tdm, is_tdm_split;
+	int id = rsnd_mod_id(mod);
+	int i;
+	u32 sys_int_enable = 0;
+
+	is_tdm		= rsnd_runtime_is_tdm(io);
+	is_tdm_split	= rsnd_runtime_is_tdm_split(io);
 
 	if (!rsnd_ssi_is_run_mods(mod, io))
 		return 0;
@@ -517,6 +559,38 @@ static int rsnd_ssi_quit(struct rsnd_mod *mod,
 		ssi->wsr	= 0;
 	}
 
+	/* disable busif buffer over/under run interrupt. */
+	if (is_tdm || is_tdm_split) {
+		switch (id) {
+		case 0:
+		case 1:
+		case 2:
+		case 3:
+		case 4:
+			for (i = 0; i < 4; i++) {
+				sys_int_enable = rsnd_mod_read(mod,
+						SSI_SYS_INT_ENABLE(i * 2));
+				sys_int_enable &= ~(0xf << (id * 4));
+				rsnd_mod_write(mod,
+					       SSI_SYS_INT_ENABLE(i * 2),
+					       sys_int_enable);
+			}
+
+			break;
+		case 9:
+			for (i = 0; i < 4; i++) {
+				sys_int_enable = rsnd_mod_read(mod,
+					SSI_SYS_INT_ENABLE((i * 2) + 1));
+				sys_int_enable &= ~(0xf << 4);
+				rsnd_mod_write(mod,
+					       SSI_SYS_INT_ENABLE((i * 2) + 1),
+					       sys_int_enable);
+			}
+
+			break;
+		}
+	}
+
 	return 0;
 }
 
@@ -622,6 +696,11 @@ static int rsnd_ssi_irq(struct rsnd_mod *mod,
 			int enable)
 {
 	u32 val = 0;
+	int is_tdm, is_tdm_split;
+	int id = rsnd_mod_id(mod);
+
+	is_tdm		= rsnd_runtime_is_tdm(io);
+	is_tdm_split	= rsnd_runtime_is_tdm_split(io);
 
 	if (rsnd_is_gen1(priv))
 		return 0;
@@ -635,6 +714,19 @@ static int rsnd_ssi_irq(struct rsnd_mod *mod,
 	if (enable)
 		val = rsnd_ssi_is_dma_mode(mod) ? 0x0e000000 : 0x0f000000;
 
+	if (is_tdm || is_tdm_split) {
+		switch (id) {
+		case 0:
+		case 1:
+		case 2:
+		case 3:
+		case 4:
+		case 9:
+			val |= 0x0000ff00;
+			break;
+		}
+	}
+
 	rsnd_mod_write(mod, SSI_INT_ENABLE, val);
 
 	return 0;
@@ -651,6 +743,12 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod,
 	u32 status;
 	bool elapsed = false;
 	bool stop = false;
+	int id = rsnd_mod_id(mod);
+	int i;
+	int is_tdm, is_tdm_split;
+
+	is_tdm		= rsnd_runtime_is_tdm(io);
+	is_tdm_split	= rsnd_runtime_is_tdm_split(io);
 
 	spin_lock(&priv->lock);
 
@@ -672,6 +770,53 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod,
 		stop = true;
 	}
 
+	status = 0;
+
+	if (is_tdm || is_tdm_split) {
+		switch (id) {
+		case 0:
+		case 1:
+		case 2:
+		case 3:
+		case 4:
+			for (i = 0; i < 4; i++) {
+				status = rsnd_mod_read(mod,
+						       SSI_SYS_STATUS(i * 2));
+				status &= 0xf << (id * 4);
+
+				if (status) {
+					rsnd_dbg_irq_status(dev,
+						"%s err status : 0x%08x\n",
+						rsnd_mod_name(mod), status);
+					rsnd_mod_write(mod,
+						       SSI_SYS_STATUS(i * 2),
+						       0xf << (id * 4));
+					stop = true;
+					break;
+				}
+			}
+			break;
+		case 9:
+			for (i = 0; i < 4; i++) {
+				status = rsnd_mod_read(mod,
+						SSI_SYS_STATUS((i * 2) + 1));
+				status &= 0xf << 4;
+
+				if (status) {
+					rsnd_dbg_irq_status(dev,
+						"%s err status : 0x%08x\n",
+						rsnd_mod_name(mod), status);
+					rsnd_mod_write(mod,
+						SSI_SYS_STATUS((i * 2) + 1),
+						0xf << 4);
+					stop = true;
+					break;
+				}
+			}
+			break;
+		}
+	}
+
 	rsnd_ssi_status_clear(mod);
 rsnd_ssi_interrupt_out:
 	spin_unlock(&priv->lock);
-- 
2.25.1


  parent reply	other threads:[~2020-06-18  1:42 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20200618011631.604574-1-sashal@kernel.org>
2020-06-18  1:12 ` [PATCH AUTOSEL 5.4 003/266] ASoC: tegra: tegra_wm8903: Support nvidia, headset property Sasha Levin
2020-06-18  1:12 ` [PATCH AUTOSEL 5.4 005/266] ASoC: SOF: imx8: Fix randbuild error Sasha Levin
2020-06-18  1:12 ` [PATCH AUTOSEL 5.4 010/266] ASoC: fsl_esai: Disable exception interrupt before scheduling tasklet Sasha Levin
2020-06-18  1:12 ` [PATCH AUTOSEL 5.4 013/266] ASoC: davinci-mcasp: Fix dma_chan refcnt leak when getting dma type Sasha Levin
2020-06-18  1:12 ` [PATCH AUTOSEL 5.4 019/266] ALSA: hda/realtek - Introduce polarity for micmute LED GPIO Sasha Levin
2020-06-18  1:12 ` [PATCH AUTOSEL 5.4 020/266] ALSA: isa/wavefront: prevent out of bounds write in ioctl Sasha Levin
2020-06-18  1:12 ` [PATCH AUTOSEL 5.4 041/266] ASoC: SOF: Do nothing when DSP PM callbacks are not set Sasha Levin
2020-06-18  1:13 ` [PATCH AUTOSEL 5.4 067/266] ASoC: qcom: q6asm-dai: kCFI fix Sasha Levin
2020-06-18  1:13 ` [PATCH AUTOSEL 5.4 079/266] ASoC: meson: add missing free_irq() in error path Sasha Levin
2020-06-18  1:13 ` [PATCH AUTOSEL 5.4 101/266] ALSA: usb-audio: Improve frames size computation Sasha Levin
2020-06-18  1:13 ` [PATCH AUTOSEL 5.4 102/266] ALSA: usb-audio: Fix racy list management in output queue Sasha Levin
2020-06-18  1:13 ` [PATCH AUTOSEL 5.4 106/266] slimbus: ngd: get drvdata from correct device Sasha Levin
2020-06-18  1:13 ` [PATCH AUTOSEL 5.4 113/266] ASoC: max98373: reorder max98373_reset() in resume Sasha Levin
2020-06-18  1:13 ` [PATCH AUTOSEL 5.4 114/266] soundwire: slave: don't init debugfs on device registration error Sasha Levin
2020-06-18  1:14 ` [PATCH AUTOSEL 5.4 127/266] ALSA: firewire-lib: fix invalid assignment to union data for directional parameter Sasha Levin
2020-06-18  1:14 ` [PATCH AUTOSEL 5.4 130/266] ASoC: SOF: core: fix error return code in sof_probe_continue() Sasha Levin
2020-06-18  1:14 ` Sasha Levin [this message]
2020-06-18  1:14 ` [PATCH AUTOSEL 5.4 135/266] ASoC: ux500: mop500: Fix some refcounted resources issues Sasha Levin
2020-06-18  1:14 ` [PATCH AUTOSEL 5.4 136/266] ASoC: ti: omap-mcbsp: Fix an error handling path in 'asoc_mcbsp_probe()' Sasha Levin
2020-06-18  1:14 ` [PATCH AUTOSEL 5.4 145/266] ALSA: usb-audio: Add duplex sound support for USB devices using implicit feedback Sasha Levin
2020-06-18  1:14 ` [PATCH AUTOSEL 5.4 157/266] ASoC: Intel: bytcr_rt5640: Add quirk for Toshiba Encore WT8-A tablet Sasha Levin
2020-06-18  1:15 ` [PATCH AUTOSEL 5.4 190/266] ASoC: fix incomplete error-handling in img_i2s_in_probe Sasha Levin
2020-06-18  1:15 ` [PATCH AUTOSEL 5.4 209/266] ASoC: fsl_asrc_dma: Fix dma_chan leak when config DMA channel failed Sasha Levin
2020-06-18  1:16 ` [PATCH AUTOSEL 5.4 250/266] ASoC: core: only convert non DPCM link to DPCM link Sasha Levin
2020-06-18  1:16 ` [PATCH AUTOSEL 5.4 251/266] ASoC: SOF: nocodec: conditionally set dpcm_capture/dpcm_playback flags Sasha Levin
2020-06-18  1:16 ` [PATCH AUTOSEL 5.4 252/266] ASoC: Intel: bytcr_rt5640: Add quirk for Toshiba Encore WT10-A tablet Sasha Levin
2020-06-18  1:16 ` [PATCH AUTOSEL 5.4 253/266] ASoC: rt5645: Add platform-data for Asus T101HA Sasha Levin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200618011631.604574-134-sashal@kernel.org \
    --to=sashal@kernel.org \
    --cc=alsa-devel@alsa-project.org \
    --cc=broonie@kernel.org \
    --cc=giraffesnn123@gmail.com \
    --cc=kuninori.morimoto.gx@renesas.com \
    --cc=licheng0822@thundersoft.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox