i.MX535 SDMA not starting

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

i.MX535 SDMA not starting

Jump to solution
2,105 Views
RickBall
Contributor II

I have a custom board containing an i.MX535 device, and it needs to use Linux to talk to a codec with data connected (through the AUDMUX) to SSI2 (in I2S mode).

I'm working with the BSP from 01/11 (11.01.00), but I've also seen the same behavior with 11.09.01. Both are using Linux 2.6.35.3, plus lots of Freescale patches (via LTIB).

For now, I'm just trying to get the DMA running - I can tell it isn't, because when I test with 'speaker-test' (from alsa-utils), the buffers fill up and eventually report an overrun (return code -5, I/O error).

I've added trace printk's so I can see that all the right routines are being called (and it looks like they are), but nothing happens when mxc_dma_enable() is called - seems like I should start getting interrupts and the 'hw_ptr' should move forward. When I check the interrupt status by cat'ing /proc/interrupts I can see that I'm getting some interrupts on INT 6 (SDMA), but I believe these are occurring when I setup the channel (before the callback is 'set') - see the printk from 'sdma_int_handler' in the log below.

Is there anything special that needs to be done to get the SDMA engine going? I think I must be missing some init somewhere in my code/machine driver, since all this DMA code is supposed to already work, right? But as you can see from the log below, it looks like it chose a valid DMA channel (31, it seems to like to start with the highest number), and it has configured the correct 'event' (25, which according to the TRM Table 3.2 is SSI2 Transmit 1 (first FIFO) Request.

Any hints/help would be much appreciated.

-------------------------------------------------------------------

root@freescale ~$ speaker-test -Dhw:0

speaker-test 1.0.11rc2

Playback device is hw:0

Stream parameters are 48000Hz, S16_LE, 1 channels

Using 16 octaves of pink noise

Rate set to 48000Hz (requested 48000Hz)

Buffer size range from 2048 to 12288

Period size range from 1024 to 3072

Buffer time size 2525

To choose buffer_size = 12288

To choose period_size = 3072

was set period_size = 3072

was set buffer_size = 12288

RDB: mxc_dma_request_ext ENTRY, name=ALSA TX SDMA

RDB: imx_get_sdma_transfer ENTRY format=2, dai_port=2

RDB: imx_get_sdma_transfer EXIT transfer=31

RDB: mxc_dma_request_ext channel_num = 31

RDB: mxc_dma_request_ext EXIT

RDB: imx_pcm_prepare ENTRY

RDB: mxc_dma_setup_channel : name=ALSA TX SDMA, event=25

RDB: sdma_int_handler irq 6, dev @ (null)

RDB: Setting callback to audio_dma_irq @ 8033bba0

RDB: mxc_dma_callback_set chan=31, callback=8033bba0

RDB: imx_pcm_prepare EXIT

0 - Front Left

RDB: snd_pcm_lib_write

RDB: state = 2, avail = 12288

RDB: state = 2, buffered = 3072, threshold = 6144

RDB: snd_pcm_lib_write

RDB: state = 2, avail = 9216

RDB: state = 2, buffered = 6144, threshold = 6144

RDB: snd_pcm_start

RDB: imx_pcm_trigger ENTRY cmd=1

RDB: dma_new_period ENTRY

RDB: mxc_dma_config ENTRY chan=31, buf=df52be14, nbuf=1, mode=1

RDB: mxc_dma_enable ENTRY chan=31

RDB: mxc_dma_start ENTRY (chan=31, running=0)

RDB: dma_new_period ENTRY

RDB: mxc_dma_config ENTRY chan=31, buf=df52be24, nbuf=1, mode=1

RDB: mxc_dma_enable ENTRY chan=31

RDB: mxc_dma_start ENTRY (chan=31, running=1)

RDB: snd_pcm_lib_write

RDB: snd_pcm_update_hw_ptr0 ENTRY

RDB: snd_pcm_update_hw_ptr0 EXIT (no change to hw_ptr = 0)

RDB: state = 3, avail = 6144

RDB: state = 3, buffered = 9216, threshold = 6144

RDB: snd_pcm_lib_write

RDB: snd_pcm_update_hw_ptr0 ENTRY

RDB: snd_pcm_update_hw_ptr0 EXIT (no change to hw_ptr = 0)

RDB: state = 3, avail = 3072

RDB: state = 3, buffered = 12288, threshold = 6144

RDB: snd_pcm_lib_write

RDB: snd_pcm_update_hw_ptr0 ENTRY

RDB: snd_pcm_update_hw_ptr0 EXIT (no change to hw_ptr = 0)

RDB: state = 3, avail = 0

... (I press ctrl-c to exit)

RDB: wait_for_avail_min returned -512, avail now 0

RDB: imx_pcm_trigger ENTRY cmd=0

Labels (1)
0 Kudos
1 Solution
1,362 Views
RickBall
Contributor II

I found and fixed the issue – it wasn’t with the DMA at all, but rather with the setup of the SSI device.

The machine file normally has a ‘hw_params’ function that is called during ALSA setup for the device (when getting reading to output some sound). In my case, I copied the ‘imx_3stack_surround_hw_params’ function from sound/soc/imx/imx-3stack-cs42888.c, since this was similar to my setup.

The problem was in the call:

snd_soc_dai_set_tdm_slot(cpu_dai, 0x3, 0x3, 2, 32);

The cs42888 machine file was using an ESAI to talk to the codec, but I am using an SSI port – although the function name doesn’t indicate that it is interface-specific, there is a level of indirection inherent in the DAI (the ‘struct snd_soc_dai_link’ contains a pointer to a set of interface-specific functions, this structure is in turn pointed to by the snd_soc_card structure, which is pointed to by the snd_soc_device structure, which is passed to platform_set_drvdata during init).

At the hardware level, an SSI device needs channel masks (parameters 2 and 3, set to 0x3 in the call above) where 0 indicates ‘active’, but the values I passed (correct for an ESAI) had ones for the active channels (0 and 1). Therefore, the SSI code didn’t see any active channel data coming in, so it never triggered the DMA. I inverted the mask values and everything started working.

It seems to me that this function (snd_soc_dai_set_tdm_slot) should have a defined API (probably the ESAI version, where 1-bits in the mask mean ‘active’), and the lower-level functions should handle the differences in h/w (i.e., the ssi version would invert the masks). Perhaps one of the maintainers would be willing to make this change and correct the existing machine files as needed?

Rick

View solution in original post

0 Kudos
10 Replies
1,362 Views
fabio_estevam
NXP Employee
NXP Employee

Rick,

Make sure the mx53 SDMA firmware binary is being correctly provided to the kernel.

Regards,

Fabio Estevam

0 Kudos
1,362 Views
RickBall
Contributor II

Fabio,

I think I figured out how the SDMA firmware is being loaded – I believe it is loaded to the SDMA core by the sdma_probe function, which calls iapi_Init with the address of a const array defined in sdma_script_code_mx53.h. So as long as the pre-compiled code defined in this array is correct (and I have no reason to doubt that it is), the SDMA scripts/firmware should be present and working – there’s no need for the binaries to reside on the target filesystem.

Rick

0 Kudos
1,363 Views
RickBall
Contributor II

I found and fixed the issue – it wasn’t with the DMA at all, but rather with the setup of the SSI device.

The machine file normally has a ‘hw_params’ function that is called during ALSA setup for the device (when getting reading to output some sound). In my case, I copied the ‘imx_3stack_surround_hw_params’ function from sound/soc/imx/imx-3stack-cs42888.c, since this was similar to my setup.

The problem was in the call:

snd_soc_dai_set_tdm_slot(cpu_dai, 0x3, 0x3, 2, 32);

The cs42888 machine file was using an ESAI to talk to the codec, but I am using an SSI port – although the function name doesn’t indicate that it is interface-specific, there is a level of indirection inherent in the DAI (the ‘struct snd_soc_dai_link’ contains a pointer to a set of interface-specific functions, this structure is in turn pointed to by the snd_soc_card structure, which is pointed to by the snd_soc_device structure, which is passed to platform_set_drvdata during init).

At the hardware level, an SSI device needs channel masks (parameters 2 and 3, set to 0x3 in the call above) where 0 indicates ‘active’, but the values I passed (correct for an ESAI) had ones for the active channels (0 and 1). Therefore, the SSI code didn’t see any active channel data coming in, so it never triggered the DMA. I inverted the mask values and everything started working.

It seems to me that this function (snd_soc_dai_set_tdm_slot) should have a defined API (probably the ESAI version, where 1-bits in the mask mean ‘active’), and the lower-level functions should handle the differences in h/w (i.e., the ssi version would invert the masks). Perhaps one of the maintainers would be willing to make this change and correct the existing machine files as needed?

Rick

0 Kudos
1,362 Views
RickBall
Contributor II

Hi Fabio,

Can you tell me how to tell if this is true? I have the bin files stored in /lib/firmware/sdma on the target system, but I don’t see anywhere in the kernel code that this directory is being referenced, and I don’t see any messages that indicate the file for MX53 is being loaded.

Thanks,

Rick Ball

0 Kudos
1,362 Views
Sasamy
Contributor IV

Hi Rick.

If you are using a different external port instead ext_port = 5  check pin multiplexing file

arch/arm/plat-mxc/include/mach/iomux-mx53.h

this file contains some critical errors, for example

ext_port = 4

-#define _MX53_PAD_SD2_DATA1__AUDMUX_AUD4_TXFS  IOMUX_PAD(0x698, 0x30C, 3, 0x744, 0, 0)

+#define _MX53_PAD_SD2_DATA1__AUDMUX_AUD4_TXFS  IOMUX_PAD(0x698, 0x30C, 3, 0x744, 1, 0)




0 Kudos
1,362 Views
OtavioSalvador
Senior Contributor II

Please give a try to last 11.09.01 branch for 2.6.35 kernel as it has many fixes.

It might be a good test and might help.

http://git.freescale.com/git/cgit.cgi/imx/linux-2.6-imx.git/log/?h=imx_2.6.35_11.09.01

0 Kudos
1,362 Views
RickBall
Contributor II

Thanks, but as I mentioned in the original post, I already tried 11.09.01 and saw the same behavior.

One odd thing I noticed about the build with 11.09.01 was that my console baud rate changed from 115200 to 57600 when it switched to the ‘real’ console – not sure why, as I think I have everything configured for 115200. But that’s a minor issue compared to the DMA not working!

0 Kudos
1,362 Views
OtavioSalvador
Senior Contributor II

I had the impression you've tested the 11.09.01 release as provided by LTIB. This branch has many fixes not included in 11.09.01 LTIB release so the mention of it.

If you really gave a try to the GIT tip of this branch, than I have no other hint without debugging the issue.

Regards,

0 Kudos
1,362 Views
RickBall
Contributor II

OK, thanks, I didn’t realize that newer code was available – I’ll download and give it a try.

Assuming it doesn’t work, is there anything I can do to help debug the issue? Add more prink’s to dump some SDMA state variables, or something like that? I’ve checked everything that I can think of, what I’m looking for is some suggestions for ‘other things to check’.

0 Kudos
1,362 Views
lily_zhang
NXP Employee
NXP Employee

Because you are porting the audio codec on customer's board, suggest that you refer to chapter "

Chapter 21Porting Audio Codecs to a Custom Board" in "i.MX53 System Development User’s Guide". Ensure all porting works are done - configuraiton, clock, power, IO configurations are ported well. Then see detailed failure one step by one step.


0 Kudos