i.MX6 i.MX7 I2C使用dma传输数据

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

i.MX6 i.MX7 I2C使用dma传输数据

1,225 Views
864535720
Contributor II

大家好:

我们使用的芯片是i.MX6Dual和i.MX7Dual。

Linux内核版本对应为:i.MX6Dual-Linux3.14.52    i.MX7Dual-Linux4.9.88

我们在使用过程中,发现I2C传输数据时,并没有用到DMA来传输数据。
查看数据手册后发现:
i.MX7Dual I2C DMA通道对应如下:
image_imx7_i2c.png

在i.MX7Dual上面一个I2C通道只有一个dma通道。请问一个DMA通道如何进行收发?如果即做收,又做发,在DMA通道申请的时候不会冲突吗?同时我在设备树里面配置了I2C-DMA的相关信息,但是驱动里面申请失败。设备树配置信息如下:

 

i2c1: i2c@30a20000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,imx7d-i2c", "fsl,imx21-i2c";
reg = <0x30a20000 0x10000>;
interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX7D_I2C1_ROOT_CLK>;

//dmas = <&sdma 18 4 0>, <&sdma 18 4 0>;
//dma-names = "rx", "tx";

dmas = <&sdma 18 4 0>;

dma-names = "tx";
status = "disabled";
};

不管我配置一个通道还是2个通道,dma通道都不能申请成功。一个通道都不能申请成功。

同时我已经确保我的GPR0对应的DMA通道复用配置成复用给I2C功能。

 

i.MX6Dual I2C DMA通道对应如下:

image_imx6_i2c.png

i.MX6Dual上面,I2C1和I2C3有2个dma通道,但是i2c2只有一个DMA通道。同时我尝试类似i.MX7Dual同样的方式去为I2C申请DMA。都失败了。

在这里想咨询一下,i.MX6Dual和i.MX7Dual上面的I2C是否支持dma传输?如果支持,需要怎么配置?

期待你们的回复,谢谢。

 

Labels (2)
0 Kudos
4 Replies

1,212 Views
ceggers1
Contributor IV

Hi,

I used Google for translating your question to English. So I hope I got your question correctly.

Hello everyone:

The chips we use are i.MX6Dual and i.MX7Dual.

The Linux kernel version corresponds to: i.MX6Dual-Linux3.14.52 i.MX7Dual-Linux4.9.88

During our use, we found that DMA was not used to transfer data when I2C was transmitting data.

In my opinion, you have the following situation:

  1. Most / all i.MX processors have dedicated DMA request lines for I2C.
  2. The Linux i2c-imx driver has support for DMA.
  3. Both do not fit together!

While most i.MX processors (i.MX25/31/35/51/53/6) uses the SDMA controller for DMA operations, one series (i.MX 28x) uses a different DMA engine. I guess that the DMA support in i2c-imx has been written for this (old) series.

Compared to most other DMA engines, the SDMA is more or less a CPU itself. That means that all DMA operations are defined in software, not in hardware. This is required as not all peripherals in the i.MX processors are as uniform as they should be in order to be serviced by a "stupid" DMA engine.

The SDMA contains a ROM and a RAM with DMA routines for different types of peripherals (like UART, SPI, SAI, ...). But support for other peripherals like ADC or I2C has never been published by NXP.

After checking the data sheet, I found:
The i.MX7Dual I2C DMA channel corresponds to the following:

<Table 7-3 – SDMA channel mapping>

There is only one dma channel for one I2C channel on i.MX7Dual. How to send and receive a DMA channel? If you receive and send at the same time, will there be conflicts when applying for DMA channels?

Most peripherals use dedicated DMA requests (and channels) for RX and TX. But this is not strictly required, as the (S)DMA routines are purely defined in software. As I2C transfers usually consist of a combination of transmit and receive, putting everything into a single channel does probably simplify the transfer routine.

2c1: i2c@30a20000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,imx7d-i2c", "fsl,imx21-i2c";
reg = <0x30a20000 0x10000>;
interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX7D_I2C1_ROOT_CLK>;

//dmas = <&sdma 18 4 0>, <&sdma 18 4 0>;
//dma-names = "rx", "tx";

dmas = <&sdma 18 4 0>;

dma-names = "tx";
status = "disabled";
};

If the i2c-imx driver supported DMA transfers using the SDMA engine, it would probably use only a single SDMA channel like this:

 

Spoiler
dmas = <&sdma 18 4 0>;
dma-names = "rxtx";

 

No matter if I configure one channel or two channels, the DMA channel cannot be successfully applied. No channel can be successfully applied.

The first number (18) is the SDMA channel number (correct) while the 2nd number (4) is the peripheral type. Peripheral type 4 means "UART connected via AP bus". The exists no peripheral type for I2C!

At the same time, I have ensured that the DMA channel multiplexing corresponding to my GPR0 is configured to be multiplexed to the I2C function.

The i.MX6Dual I2C DMA channel corresponds to the following:

<Table 3-2 – SDMA event mapping>

On i.MX6Dual, I2C1 and I2C3 have 2 dma channels, but i2c2 has only one DMA channel. At the same time, I tried to apply for DMA for I2C in the same way as i.MX7Dual. All failed.

I think that also I2C1 and I2C3 have only a single DMA request. But there are 2 possible SDMA event lines they can be multiplexed to (through GPR).

I would like to ask here, does the I2C on i.MX6Dual and i.MX7Dual support dma transmission? If it is supported, how to configure it?

I think you have set up everything correctly (according to the available documentation). But a working implementation would need:

  1. A custom SDMA script for I2C.
  2. A modified i2c-imx driver which fits to the custom SDMA routine (probably using only a single SDMA channel for RX and TX).

In theory, you could write your own (custom) SDMA routine for I2C. But writing custom SDMA scripts requires:

  1. An assembler for SDMA (two are available for free on the internet), I have (internally) ported the GNU assembler for my projects.
  2. Probably a debugger for SDMA (for getting your code working). I have written a plugin for Lauterbach Trace32. Lauterbach itself also sells an own debugger for SDMA, but I consider my plugin as superior.
  3. Knowledge about how to write SDMA routines. There is a good introduction from Eli Billauer, but I think that this is not sufficient for writing an I2C script.
  4. Knowledge about the existing SDMA ROM routines. They are required for interchanging SDMA buffer descriptors with the ARM CPU. These routines are not documented anywhere!

If you only want to get I2C working, it may be easier/faster not trying this yourself!

Looking forward to your reply, thank you.

regards
Christian
SDMA developer

 

0 Kudos

1,190 Views
ceggers1
Contributor IV

If you are satisfied with my answer, I would like to encourage you to either ...

  • mark the answer as correct, or
  • give a kudo, or
  • write a small comment

Please note that I am not paid by NXP. Many SDMA related questions would never be answered if I didn't take the time.

thanks,
Christian

0 Kudos

1,180 Views
864535720
Contributor II

Hi, Christian

Sorry, I only reply to your message now.
Thank you very much for your reply. Based on your reply, I tried again by myself, but the I2C-DMA function was still not successfully configured.
Please ask, dmas = <&sdma 24 4 0> The dma of the UART is 4, then what should be the dma of the I2C?
Then I configured dma-names = "rxtx"; when applying for a dma channel, the channel application still failed. What other issues do I need to pay attention to?

0 Kudos

1,172 Views
ceggers1
Contributor IV

It seems that I failed to provide an easy understandable description of the technical details. English is not my primary language...

Unfortunately I2C+SDMA do not fit together on i.MX6/7/8. This would require a custom firmware for the SDMA controller.

I you are interested, I can try to implement this as a contract work for you. Please write me a private message for further details. Alternatively, NXP offers "professional services" (paid) for such tasks.

regards
Christian

0 Kudos