SDMA custom script: DMA Memory Map to access peripherals?

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

SDMA custom script: DMA Memory Map to access peripherals?

Jump to solution
2,625 Views
elibil
Contributor II

Hello,

I'm working on an SDMA script of my own for i.MX6, which is intended to read from the eCSPI's registers and copy the data into memory. I know this can be done with the standard scripts based upon buffer descriptors, but I need the SDMA script to do a bit of other housekeeping as well. Hence the custom script.

So the relevant assembly snippet (using a non-standard assembler) is

69c3 (0110100111000011) |     stf    r1, 0xc3    # PSA = r1 for 32-bit frozen peripheral read
62c8 (0110001011001000) |     ldf    r2, 0xc8    # Read peripheral register into r2

The question is about the assignment of PSA, which is the value of r1 in the example above. Looking at the Linux driver for eCSPI (spi-imx.c, kernel 4.1.15), the source address used is the physical address as seen by the ARM (application) processor. That is, 0x2008000 for eCSPI1 on i.MX6. And indeed, when using this address, a valid value is read into r2 in the code snippet above.

But the Reference Manual [1] section 2.4, DMA Memory Map, says that eCSPI1 should be accessed at 0x2000. I tried that too, and got rubbish.

So my question is: If 0x2008000 is the correct address, what is the DMA Memory Map about?

I could, of course, forget all about this and use the address that seems to work ("you don't argue with something that works", I've been told a few times), and still I'd like to sort this out. Have I missed anything?

Thanks in advance,

   Eli

[1] http://www.nxp.com/docs/en/reference-manual/IMX6SDLRM.pdf

0 Kudos
1 Solution
2,050 Views
elibil
Contributor II

Hi,

So I end up answering myself.

After some investigation and speed tests, it turns out that accessing a peripheral through the addresses in the DMA memory mapping is significantly faster, and that it's done with plain ld and st commands, and not with the DMA units.

I've written down my findings in my own blog, in case someone's interested.

Regards,

   Eli

View solution in original post

0 Kudos
7 Replies
2,051 Views
elibil
Contributor II

Hi,

So I end up answering myself.

After some investigation and speed tests, it turns out that accessing a peripheral through the addresses in the DMA memory mapping is significantly faster, and that it's done with plain ld and st commands, and not with the DMA units.

I've written down my findings in my own blog, in case someone's interested.

Regards,

   Eli

0 Kudos
2,050 Views
igorpadykov
NXP Employee
NXP Employee

Hi Eli

scripts are run by sdma core (depicted on Figure 55-1) which has own memory map,

so correct is section 2.4, DMA Memory Map. Also may be useful to look at

some sdma examples in Github SDK
https://github.com/backenklee/swp-report/tree/master/iMX6_Platform_SDK

MX6UL  FreeRTOS  SDK2.2
Board Support Packages (7)
SDK2.2_iMX6UL_WIN(REV SDK2.2)
http://www.nxp.com/products/microcontrollers-and-processors/arm-processors/i.mx-processors/i.mx-6-pr...

CodeWarrior for StarCore and SDMA|NXP 

Best regards
igor
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
2,050 Views
elibil
Contributor II

Hi Igor,

I'll try to clarify my question.

I'm aware of the memory map and the documented internal bus structure. However my personal experience shows the opposite, and I wonder why

(1) reading from the "correct" (?) address, 0x2000, gave me rubbish, while using the Application Processor address (0x2008000) worked correctly, and

(2) why the Linux driver (from NXP's repository) uses the 0x2008000 address, and seems to ignore the whole thing about DMA Memory Map.

As for the list of references, could you please be more specific? Telling me to download full SDKs and look for something that might help isn't very helpful. Besides, even if I find an example in some SDK, why would it be more convincing than the practical solution chosen my NXP in the official Linux driver?

Thanks in advance,

   Eli

0 Kudos
2,050 Views
igorpadykov
NXP Employee
NXP Employee

Hi Eli

seems address, like 0x2000 are for shared peripherals connected to spba, depicted

on Figure 2. i.MX 6Dual/6Quad Consumer Grade System Block Diagram i.MX6DQ Datasheet

http://cache.freescale.com/files/32bit/doc/data_sheet/IMX6DQCEC.pdf

There are scripts for "shared peipherals, they are different from "ap" peripherals (AP Domain on Figure 2) scripts.

>As for the list of references, could you please be more specific?

unfortunately creating sdma custom scripts is not supported by nxp, recommended to

apply to NXP Professional Services:

http://www.nxp.com/support/nxp-professional-services:PROFESSIONAL-SERVICE

Best regards
igor

0 Kudos
2,050 Views
elibil
Contributor II

Hi,

Indeed, eCSPI1 (and the other eSPCIs, and UARTs etc.) is a shared peripheral. Looking at the same Figure 2 you pointed at, there is only one set of eCSPI peripherals, and they are behind the SPBA.

This is exactly why 0x2000 was my first choice. Only this address seems unrelated.

My full test script was simply:

                             | start:
0000 1801 (0001100000000001) |     addi r0, 1
0001 69c3 (0110100111000011) |     stf    r1, 0xc3    # PSA = r1 for 32-bit frozen periheral read
0002 62c8 (0110001011001000) |     ldf    r2, 0xc8    # Read peripheral register into r2
0003 0401 (0000010000000001) |     notify 4       # Turn off event, don't reschedule
0004 0300 (0000001100000000) |     done 3         # Quit MCU execution
0005 7cfa (0111110011111010) |     bf start       # One of these will branch
0006 7df9 (0111110111111001) |     bt start

I set the context before enabling it, so r1 is either 0x2000 or 0x2008000, and then configured SDMA to trigger this script on an event. Then sent some data to the SPI (which acts as a slave, by the way). Later on, I disabled the script, and fetched the context.

r0 gave me the number of script executions

r1 stayed the same as I configured it: The address loaded to PSA (and PSA carried this address indeed)

r2 had the result. When r1 was set to 0x2008000, I had some reasonable input data there. When it was set to 0x2000, it was always 0x5c29e003, which has nothing to do with the data on the SPI bus. I also had other indications that the SPI's data register wasn't read from by the SDMA.

So we're still on square one: Why is there a DMA address at all, and why does the (NXP official) kernel driver not use it?

This isn't a question about custom scripts. The same issue exactly arises when using the scripts on the ROM, as done by the kernel driver. You still need to choose the source address.

Regards,

   Eli

0 Kudos
2,050 Views
igorpadykov
NXP Employee
NXP Employee

addresses, like 0x2000 are for shared peripherals connected to spba, depicted
on Figure 2 should be accessed using :
DDA - DSP destination address register
DSA - DSP source address register
More fully they are described in Table 40-39. Layout of a Channel Context in Memory for SDMA
i.MX31 Reference Manual, sect.40.16.3 BP DMA Unit
http://www.freescale.com/files/32bit/doc/ref_manual/MCIMX31RM.pdf
However these peripherals may be accessed also through AIPS1-SPBA using addresses of AP Domain,
so it works too, as 0x2008000 address.

Best regards
igor

0 Kudos
2,050 Views
elibil
Contributor II

Hello,

I don't quite follow. Looking at the reference manual you pointed at (for i.MX31, even though the discussion is on i.MX6), it says (section 40.16.3, "BP DMA Unit"):

"The BP DMA is not connected on this device, but its registers are still accessible. An attempt to initiate a BP DMA memory read or write might hang the SDMA since the access cannot be completed. The SDMA core must avoid accessing the DSA, DDA, DD and DS registers to avoid situations that can cause the SDMA to hang".

OK, that's i.MX31. What about i.MX6? Searching for "DDA" and "DSA" in i.MX6's manual yielded almost nothing, except for being DSA being listed as one of the possible sources for an ldf instruction. In the same list, DDA was erased, comparing with the ldf instruction from i.MX31. So it looks like the DSA entry shouldn't be there either. Otherwise, there is no DSA or DDA mentioned in the document (for i.MX6) at all.

Given this, I don't quite understand what you meant with 0x2000 being used with DDA and DSA. Could you please clarify that?

Thanks,

    Eli

0 Kudos