All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] ASoC: davinci-mcasp: Improved suspend/resume support
@ 2014-10-01 13:02 Peter Ujfalusi
  2014-10-01 13:02 ` [PATCH 1/2] ASoC: davinci-mcasp: Convert the context save/restore to use array Peter Ujfalusi
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Peter Ujfalusi @ 2014-10-01 13:02 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood; +Cc: alsa-devel, jsarha, zonque

Hi,

With this series the McASP will continue to work after deep sleep during audio
activity.
Without these changes the ongoing audio will not resume and it will time out,
but streams started after resume were worked correctly.

Regards,
Peter
---
Peter Ujfalusi (2):
  ASoC: davinci-mcasp: Convert the context save/restore to use array
  ASoC: davinvi-mcasp: Proper suspend/resume support while audio is
    active

 sound/soc/davinci/davinci-mcasp.c | 79 ++++++++++++++++++++++++++++-----------
 1 file changed, 58 insertions(+), 21 deletions(-)

-- 
2.1.0

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/2] ASoC: davinci-mcasp: Convert the context save/restore to use array
  2014-10-01 13:02 [PATCH 0/2] ASoC: davinci-mcasp: Improved suspend/resume support Peter Ujfalusi
@ 2014-10-01 13:02 ` Peter Ujfalusi
  2014-10-01 13:02 ` [PATCH 2/2] ASoC: davinvi-mcasp: Proper suspend/resume support while audio is active Peter Ujfalusi
  2014-10-01 16:02 ` [PATCH 0/2] ASoC: davinci-mcasp: Improved suspend/resume support Mark Brown
  2 siblings, 0 replies; 6+ messages in thread
From: Peter Ujfalusi @ 2014-10-01 13:02 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood; +Cc: alsa-devel, jsarha, zonque

Instead of individual values use an array to store the registers need to be
saved on suspend and restored on resume.
It is going to be easier to add more registers to save and restore.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 sound/soc/davinci/davinci-mcasp.c | 38 +++++++++++++++++---------------------
 1 file changed, 17 insertions(+), 21 deletions(-)

diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index 68347b55f6e1..ccf2f3920a20 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -42,14 +42,18 @@
 
 #define MCASP_MAX_AFIFO_DEPTH	64
 
+static u32 context_regs[] = {
+	DAVINCI_MCASP_TXFMCTL_REG,
+	DAVINCI_MCASP_RXFMCTL_REG,
+	DAVINCI_MCASP_TXFMT_REG,
+	DAVINCI_MCASP_RXFMT_REG,
+	DAVINCI_MCASP_ACLKXCTL_REG,
+	DAVINCI_MCASP_ACLKRCTL_REG,
+	DAVINCI_MCASP_PDIR_REG,
+};
+
 struct davinci_mcasp_context {
-	u32	txfmtctl;
-	u32	rxfmtctl;
-	u32	txfmt;
-	u32	rxfmt;
-	u32	aclkxctl;
-	u32	aclkrctl;
-	u32	pdir;
+	u32	config_regs[ARRAY_SIZE(context_regs)];
 };
 
 struct davinci_mcasp {
@@ -874,14 +878,10 @@ static int davinci_mcasp_suspend(struct snd_soc_dai *dai)
 {
 	struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai);
 	struct davinci_mcasp_context *context = &mcasp->context;
+	int i;
 
-	context->txfmtctl = mcasp_get_reg(mcasp, DAVINCI_MCASP_TXFMCTL_REG);
-	context->rxfmtctl = mcasp_get_reg(mcasp, DAVINCI_MCASP_RXFMCTL_REG);
-	context->txfmt = mcasp_get_reg(mcasp, DAVINCI_MCASP_TXFMT_REG);
-	context->rxfmt = mcasp_get_reg(mcasp, DAVINCI_MCASP_RXFMT_REG);
-	context->aclkxctl = mcasp_get_reg(mcasp, DAVINCI_MCASP_ACLKXCTL_REG);
-	context->aclkrctl = mcasp_get_reg(mcasp, DAVINCI_MCASP_ACLKRCTL_REG);
-	context->pdir = mcasp_get_reg(mcasp, DAVINCI_MCASP_PDIR_REG);
+	for (i = 0; i < ARRAY_SIZE(context_regs); i++)
+		context->config_regs[i] = mcasp_get_reg(mcasp, context_regs[i]);
 
 	return 0;
 }
@@ -890,14 +890,10 @@ static int davinci_mcasp_resume(struct snd_soc_dai *dai)
 {
 	struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai);
 	struct davinci_mcasp_context *context = &mcasp->context;
+	int i;
 
-	mcasp_set_reg(mcasp, DAVINCI_MCASP_TXFMCTL_REG, context->txfmtctl);
-	mcasp_set_reg(mcasp, DAVINCI_MCASP_RXFMCTL_REG, context->rxfmtctl);
-	mcasp_set_reg(mcasp, DAVINCI_MCASP_TXFMT_REG, context->txfmt);
-	mcasp_set_reg(mcasp, DAVINCI_MCASP_RXFMT_REG, context->rxfmt);
-	mcasp_set_reg(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, context->aclkxctl);
-	mcasp_set_reg(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, context->aclkrctl);
-	mcasp_set_reg(mcasp, DAVINCI_MCASP_PDIR_REG, context->pdir);
+	for (i = 0; i < ARRAY_SIZE(context_regs); i++)
+		mcasp_set_reg(mcasp, context_regs[i], context->config_regs[i]);
 
 	return 0;
 }
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/2] ASoC: davinvi-mcasp: Proper suspend/resume support while audio is active
  2014-10-01 13:02 [PATCH 0/2] ASoC: davinci-mcasp: Improved suspend/resume support Peter Ujfalusi
  2014-10-01 13:02 ` [PATCH 1/2] ASoC: davinci-mcasp: Convert the context save/restore to use array Peter Ujfalusi
@ 2014-10-01 13:02 ` Peter Ujfalusi
  2014-10-01 16:02 ` [PATCH 0/2] ASoC: davinci-mcasp: Improved suspend/resume support Mark Brown
  2 siblings, 0 replies; 6+ messages in thread
From: Peter Ujfalusi @ 2014-10-01 13:02 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood; +Cc: alsa-devel, jsarha, zonque

If the board is sent to suspend (deep sleep) the McASP context will be lost.
In case when suspend happens during active audio we need to save and restore
more registers, which was configured during hw_param times as well.
We need to add more config registers, AFIFO control registers and we also
need to save and restore the serializer configuration as well.
Since the number of serializers depends on the SoC we need to allocate the
memory for it based on the num_serializer for the given McASP instance.

With this patch the ongoing stream will resume after resuming from deep
sleep.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 sound/soc/davinci/davinci-mcasp.c | 41 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index ccf2f3920a20..0eed9b1b24e1 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -49,11 +49,19 @@ static u32 context_regs[] = {
 	DAVINCI_MCASP_RXFMT_REG,
 	DAVINCI_MCASP_ACLKXCTL_REG,
 	DAVINCI_MCASP_ACLKRCTL_REG,
+	DAVINCI_MCASP_AHCLKXCTL_REG,
+	DAVINCI_MCASP_AHCLKRCTL_REG,
 	DAVINCI_MCASP_PDIR_REG,
+	DAVINCI_MCASP_RXMASK_REG,
+	DAVINCI_MCASP_TXMASK_REG,
+	DAVINCI_MCASP_RXTDM_REG,
+	DAVINCI_MCASP_TXTDM_REG,
 };
 
 struct davinci_mcasp_context {
 	u32	config_regs[ARRAY_SIZE(context_regs)];
+	u32	afifo_regs[2]; /* for read/write fifo control registers */
+	u32	*xrsr_regs; /* for serializer configuration */
 };
 
 struct davinci_mcasp {
@@ -878,11 +886,25 @@ static int davinci_mcasp_suspend(struct snd_soc_dai *dai)
 {
 	struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai);
 	struct davinci_mcasp_context *context = &mcasp->context;
+	u32 reg;
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(context_regs); i++)
 		context->config_regs[i] = mcasp_get_reg(mcasp, context_regs[i]);
 
+	if (mcasp->txnumevt) {
+		reg = mcasp->fifo_base + MCASP_WFIFOCTL_OFFSET;
+		context->afifo_regs[0] = mcasp_get_reg(mcasp, reg);
+	}
+	if (mcasp->rxnumevt) {
+		reg = mcasp->fifo_base + MCASP_RFIFOCTL_OFFSET;
+		context->afifo_regs[1] = mcasp_get_reg(mcasp, reg);
+	}
+
+	for (i = 0; i < mcasp->num_serializer; i++)
+		context->xrsr_regs[i] = mcasp_get_reg(mcasp,
+						DAVINCI_MCASP_XRSRCTL_REG(i));
+
 	return 0;
 }
 
@@ -890,11 +912,25 @@ static int davinci_mcasp_resume(struct snd_soc_dai *dai)
 {
 	struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai);
 	struct davinci_mcasp_context *context = &mcasp->context;
+	u32 reg;
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(context_regs); i++)
 		mcasp_set_reg(mcasp, context_regs[i], context->config_regs[i]);
 
+	if (mcasp->txnumevt) {
+		reg = mcasp->fifo_base + MCASP_WFIFOCTL_OFFSET;
+		mcasp_set_reg(mcasp, reg, context->afifo_regs[0]);
+	}
+	if (mcasp->rxnumevt) {
+		reg = mcasp->fifo_base + MCASP_RFIFOCTL_OFFSET;
+		mcasp_set_reg(mcasp, reg, context->afifo_regs[1]);
+	}
+
+	for (i = 0; i < mcasp->num_serializer; i++)
+		mcasp_set_reg(mcasp, DAVINCI_MCASP_XRSRCTL_REG(i),
+			      context->xrsr_regs[i]);
+
 	return 0;
 }
 #else
@@ -1212,6 +1248,11 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
 	mcasp->op_mode = pdata->op_mode;
 	mcasp->tdm_slots = pdata->tdm_slots;
 	mcasp->num_serializer = pdata->num_serializer;
+#ifdef CONFIG_PM_SLEEP
+	mcasp->context.xrsr_regs = devm_kzalloc(&pdev->dev,
+					sizeof(u32) * mcasp->num_serializer,
+					GFP_KERNEL);
+#endif
 	mcasp->serial_dir = pdata->serial_dir;
 	mcasp->version = pdata->version;
 	mcasp->txnumevt = pdata->txnumevt;
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 0/2] ASoC: davinci-mcasp: Improved suspend/resume support
  2014-10-01 13:02 [PATCH 0/2] ASoC: davinci-mcasp: Improved suspend/resume support Peter Ujfalusi
  2014-10-01 13:02 ` [PATCH 1/2] ASoC: davinci-mcasp: Convert the context save/restore to use array Peter Ujfalusi
  2014-10-01 13:02 ` [PATCH 2/2] ASoC: davinvi-mcasp: Proper suspend/resume support while audio is active Peter Ujfalusi
@ 2014-10-01 16:02 ` Mark Brown
  2014-10-02  7:21   ` Peter Ujfalusi
  2 siblings, 1 reply; 6+ messages in thread
From: Mark Brown @ 2014-10-01 16:02 UTC (permalink / raw)
  To: Peter Ujfalusi; +Cc: alsa-devel, Liam Girdwood, jsarha, zonque


[-- Attachment #1.1: Type: text/plain, Size: 400 bytes --]

On Wed, Oct 01, 2014 at 04:02:10PM +0300, Peter Ujfalusi wrote:
> Hi,
> 
> With this series the McASP will continue to work after deep sleep during audio
> activity.
> Without these changes the ongoing audio will not resume and it will time out,
> but streams started after resume were worked correctly.

Applied both, thanks.  Might be worth converting to regmap and using the
cache code?

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 0/2] ASoC: davinci-mcasp: Improved suspend/resume support
  2014-10-01 16:02 ` [PATCH 0/2] ASoC: davinci-mcasp: Improved suspend/resume support Mark Brown
@ 2014-10-02  7:21   ` Peter Ujfalusi
  2014-10-02 10:56     ` Mark Brown
  0 siblings, 1 reply; 6+ messages in thread
From: Peter Ujfalusi @ 2014-10-02  7:21 UTC (permalink / raw)
  To: Mark Brown; +Cc: alsa-devel, Liam Girdwood, jsarha, zonque

On 10/01/2014 07:02 PM, Mark Brown wrote:
> On Wed, Oct 01, 2014 at 04:02:10PM +0300, Peter Ujfalusi wrote:
>> Hi,
>>
>> With this series the McASP will continue to work after deep sleep during audio
>> activity.
>> Without these changes the ongoing audio will not resume and it will time out,
>> but streams started after resume were worked correctly.
> 
> Applied both, thanks.  Might be worth converting to regmap and using the
> cache code?

Yes, it is in my to-do list. One thing I'm a bit puzzled currently is on how
to handle the serializer registers. Depending on the SoC the McASP is
integrated in we can have different number of serializers, also in some SoC
different McASP ports have different number of serializers. I do not want to
have separate regmap struct for all of these (which would most probably means
different compatible flag in DT). I also want to avoid wiring in some max
limit of the serializer registers. But probably I need to do this at the end.

-- 
Péter

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 0/2] ASoC: davinci-mcasp: Improved suspend/resume support
  2014-10-02  7:21   ` Peter Ujfalusi
@ 2014-10-02 10:56     ` Mark Brown
  0 siblings, 0 replies; 6+ messages in thread
From: Mark Brown @ 2014-10-02 10:56 UTC (permalink / raw)
  To: Peter Ujfalusi; +Cc: alsa-devel, Liam Girdwood, jsarha, zonque


[-- Attachment #1.1: Type: text/plain, Size: 938 bytes --]

On Thu, Oct 02, 2014 at 10:21:31AM +0300, Peter Ujfalusi wrote:
> On 10/01/2014 07:02 PM, Mark Brown wrote:

> > Applied both, thanks.  Might be worth converting to regmap and using the
> > cache code?

> Yes, it is in my to-do list. One thing I'm a bit puzzled currently is on how
> to handle the serializer registers. Depending on the SoC the McASP is
> integrated in we can have different number of serializers, also in some SoC
> different McASP ports have different number of serializers. I do not want to
> have separate regmap struct for all of these (which would most probably means
> different compatible flag in DT). I also want to avoid wiring in some max
> limit of the serializer registers. But probably I need to do this at the end.

This sort of thing is why the access stuff is done with functions and
get the device passed in, though max_register is still just a number.
I don't know if that'll particularly help or not.

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2014-10-02 10:57 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-10-01 13:02 [PATCH 0/2] ASoC: davinci-mcasp: Improved suspend/resume support Peter Ujfalusi
2014-10-01 13:02 ` [PATCH 1/2] ASoC: davinci-mcasp: Convert the context save/restore to use array Peter Ujfalusi
2014-10-01 13:02 ` [PATCH 2/2] ASoC: davinvi-mcasp: Proper suspend/resume support while audio is active Peter Ujfalusi
2014-10-01 16:02 ` [PATCH 0/2] ASoC: davinci-mcasp: Improved suspend/resume support Mark Brown
2014-10-02  7:21   ` Peter Ujfalusi
2014-10-02 10:56     ` Mark Brown

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.