[PATCH] dmaengine: ti: omap-dma: Block PM if SDMA is busy to fix audio

Peter Ujfalusi peter.ujfalusi at ti.com
Tue Nov 10 03:00:32 EST 2020


Hi,

On 10/11/2020 9.58, Peter Ujfalusi wrote:
> Hi Tony,
> 
> On 09/11/2020 17.40, Tony Lindgren wrote:
>> We now use cpu_pm for saving and restoring device context for deeper SoC
>> idle states. But for omap3, we must also block idle if SDMA is busy.
>>
>> If we don't block idle when SDMA is busy, we eventually end up saving and
>> restoring SDMA register state on PER domain idle while SDMA is active and
>> that causes at least audio playback to fail.
> 
> Thanks for the fix!
> 
> Tested-by: Peter Ujfalusi <peter.ujfalusi at ti.com>
> Acked-by: Peter Ujfalusi <peter.ujfalusi at ti.com>
> 
> Vinod: Can you take this for 5.10 as a fix? The off mode got enabled by
> default in 5.10-rc1 and audio got broken out of box.

to Vinod with corrected email address..

> Thanks,
> - Péter
> 
>> Fixes: 4c74ecf79227 ("dmaengine: ti: omap-dma: Add device tree match data and use it for cpu_pm")
>> Reported-by: Peter Ujfalusi <peter.ujfalusi at ti.com>
>> Signed-off-by: Tony Lindgren <tony at atomide.com>
>> ---
>>  drivers/dma/ti/omap-dma.c | 37 ++++++++++++++++++++++++-------------
>>  1 file changed, 24 insertions(+), 13 deletions(-)
>>
>> diff --git a/drivers/dma/ti/omap-dma.c b/drivers/dma/ti/omap-dma.c
>> --- a/drivers/dma/ti/omap-dma.c
>> +++ b/drivers/dma/ti/omap-dma.c
>> @@ -1522,29 +1522,38 @@ static void omap_dma_free(struct omap_dmadev *od)
>>  	}
>>  }
>>  
>> +/* Currently used by omap2 & 3 to block deeper SoC idle states */
>> +static bool omap_dma_busy(struct omap_dmadev *od)
>> +{
>> +	struct omap_chan *c;
>> +	int lch = -1;
>> +
>> +	while (1) {
>> +		lch = find_next_bit(od->lch_bitmap, od->lch_count, lch + 1);
>> +		if (lch >= od->lch_count)
>> +			break;
>> +		c = od->lch_map[lch];
>> +		if (!c)
>> +			continue;
>> +		if (omap_dma_chan_read(c, CCR) & CCR_ENABLE)
>> +			return true;
>> +	}
>> +
>> +	return false;
>> +}
>> +
>>  /* Currently only used for omap2. For omap1, also a check for lcd_dma is needed */
>>  static int omap_dma_busy_notifier(struct notifier_block *nb,
>>  				  unsigned long cmd, void *v)
>>  {
>>  	struct omap_dmadev *od;
>> -	struct omap_chan *c;
>> -	int lch = -1;
>>  
>>  	od = container_of(nb, struct omap_dmadev, nb);
>>  
>>  	switch (cmd) {
>>  	case CPU_CLUSTER_PM_ENTER:
>> -		while (1) {
>> -			lch = find_next_bit(od->lch_bitmap, od->lch_count,
>> -					    lch + 1);
>> -			if (lch >= od->lch_count)
>> -				break;
>> -			c = od->lch_map[lch];
>> -			if (!c)
>> -				continue;
>> -			if (omap_dma_chan_read(c, CCR) & CCR_ENABLE)
>> -				return NOTIFY_BAD;
>> -		}
>> +		if (omap_dma_busy(od))
>> +			return NOTIFY_BAD;
>>  		break;
>>  	case CPU_CLUSTER_PM_ENTER_FAILED:
>>  	case CPU_CLUSTER_PM_EXIT:
>> @@ -1595,6 +1604,8 @@ static int omap_dma_context_notifier(struct notifier_block *nb,
>>  
>>  	switch (cmd) {
>>  	case CPU_CLUSTER_PM_ENTER:
>> +		if (omap_dma_busy(od))
>> +			return NOTIFY_BAD;
>>  		omap_dma_context_save(od);
>>  		break;
>>  	case CPU_CLUSTER_PM_ENTER_FAILED:
>>
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
> Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
> 

- Péter

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki



More information about the linux-arm-kernel mailing list