LS1043 i2c dma problem

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

LS1043 i2c dma problem

ソリューションへジャンプ
2,517件の閲覧回数
thorstenpohlman
Contributor II

Hi,

Custom LS1043 Board

Linux version 5.4.47-2.3 (NXP-SDK 2.2 dunfell)

 

i've got a weird I2C problem:

Everything is working quite fine, reading temperature-sensors, reading/setting rtcs (all transfers < 16 bytes)...

But I need to transmit 4kB of data to a I2C slave, so the drivers/i2c/busses/i2c-imx.c  driver selects DMA ( i2c_imx_xfer line 1171).

The problem: DMA transfer just transmits garbarge over i2c, some unknown part of memory to be precise. I saw parts of the boot-message (klog), different contents on every transfer. I tracked down to the dma_map_single()  (i2c_imx_dma_xfer line 457), everything seems to be correct (msgs->buf contains the correct data).

If i increase the DMA_THRESHOLD so dma isnt used, everything works fine.

 

Its also reproducable with the i2ctransfer tool, e.g. i2ctransfer -y 0 w10@0x12 0+ sends incremental data, i2ctransfer -y 0 w4000@0x12 0+ sends complete nonsense.

(Nonsense sent is validated with a DigiView probe)

Any suggestions?

0 件の賞賛
返信
1 解決策
2,485件の閲覧回数
thorstenpohlman
Contributor II

Hi,

obviously the LS1043/1046 don't provide cache/DMA coherency for I2C device DMA?!

So the write buffer stays in cpu cache and is not visible to DMA.

Who is the maintainer for this driver now?

This patch is working for me now (altough i could only test the write-part)

diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index af352886ef6f..54e2a7b88f0a 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -441,6 +441,9 @@ static void i2c_imx_dma_callback(void *arg)
struct imx_i2c_struct *i2c_imx = (struct imx_i2c_struct *)arg;
struct imx_i2c_dma *dma = i2c_imx->dma;

+ if(dma->dma_transfer_dir == DMA_DEV_TO_MEM)
+ dma_sync_single_for_device(&i2c_imx->adapter.dev, dma->dma_buf, dma->dma_len, dma->dma_transfer_dir);
+
dma_unmap_single(dma->chan_using->device->dev, dma->dma_buf,
dma->dma_len, dma->dma_data_dir);
complete(&dma->cmd_complete);
@@ -461,7 +464,8 @@ static int i2c_imx_dma_xfer(struct imx_i2c_struct *i2c_imx,
goto err_map;
}

+ if(dma->dma_transfer_dir == DMA_MEM_TO_DEV)
+ dma_sync_single_for_device(dev, dma->dma_buf, dma->dma_len, dma->dma_transfer_dir);

txdesc = dmaengine_prep_slave_single(dma->chan_using, dma->dma_buf,
dma->dma_len, dma->dma_transfer_dir,

 

元の投稿で解決策を見る

0 件の賞賛
返信
2 返答(返信)
2,486件の閲覧回数
thorstenpohlman
Contributor II

Hi,

obviously the LS1043/1046 don't provide cache/DMA coherency for I2C device DMA?!

So the write buffer stays in cpu cache and is not visible to DMA.

Who is the maintainer for this driver now?

This patch is working for me now (altough i could only test the write-part)

diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index af352886ef6f..54e2a7b88f0a 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -441,6 +441,9 @@ static void i2c_imx_dma_callback(void *arg)
struct imx_i2c_struct *i2c_imx = (struct imx_i2c_struct *)arg;
struct imx_i2c_dma *dma = i2c_imx->dma;

+ if(dma->dma_transfer_dir == DMA_DEV_TO_MEM)
+ dma_sync_single_for_device(&i2c_imx->adapter.dev, dma->dma_buf, dma->dma_len, dma->dma_transfer_dir);
+
dma_unmap_single(dma->chan_using->device->dev, dma->dma_buf,
dma->dma_len, dma->dma_data_dir);
complete(&dma->cmd_complete);
@@ -461,7 +464,8 @@ static int i2c_imx_dma_xfer(struct imx_i2c_struct *i2c_imx,
goto err_map;
}

+ if(dma->dma_transfer_dir == DMA_MEM_TO_DEV)
+ dma_sync_single_for_device(dev, dma->dma_buf, dma->dma_len, dma->dma_transfer_dir);

txdesc = dmaengine_prep_slave_single(dma->chan_using, dma->dma_buf,
dma->dma_len, dma->dma_transfer_dir,

 

0 件の賞賛
返信
2,476件の閲覧回数
thorstenpohlman
Contributor II

Wow,

 

all reply i got fom NXP was an automatic email if the answer (that i provided myself) "did solve your problem"...

0 件の賞賛
返信