Armadilloフォーラム

Armadillo-X1 ECSPIのDMA転送について

k-tsuru

2017年5月26日 16時45分

お世話になっております。

現在、Armadillo-X1にて、ECSPIのDMA転送を行おうとしております。

i.MX7dualでは、リファレンスマニュアルに記載されている、
10.1.6 Applicationsのフローの手順に従ってDMA転送が可能だと思います。
ですが、具体的にどの様な動作させれば良いのか、詳細が解っておりません。

また、実際にDMA転送を使用する場合、linux-3.14-x1-atの/drivers/spi/spi-imx.cに
それらしいコードと思われるものがありますので、ここに手を加えれば、
SPIのDMA用ドライバを実装出来るのでしょうか。

デバイスドライバの実装、及び、DMAの手順にて、何か参考に出来るサンプルなどありませんでしょうか。

ご教示お願い致します。

コメント

溝渕です。

> また、実際にDMA転送を使用する場合、linux-3.14-x1-atの/drivers/spi/spi-imx.cに
> それらしいコードと思われるものがありますので、ここに手を加えれば、
> SPIのDMA用ドライバを実装出来るのでしょうか。

drivers/spi/spi-imx.cがECSPIのデバイスドライバです。すでにDMAを利用す
る実装があるように見えます。

Device Tree Sourceに(例えば arch/arm/boot/dts/imx7d-sdb-touch.dts など
を参考にして)ecspiのノードを変更すると、DMAを利用したSPI通信が可能のよ
うに思います。

「XXXのような動作を期待して、YYYしたが、ZZZになってしまった。」のよう
な状況を教えていただけると、もう少し的確なアドバイスが可能かと思います。

以上です。

溝渕様

いつもお世話になっております。
都留と申します。

回答いただき、ありがとうございます。
返信が遅れて申し訳ありません。

---

> > また、実際にDMA転送を使用する場合、linux-3.14-x1-atの/drivers/spi/spi-imx.cに
> > それらしいコードと思われるものがありますので、ここに手を加えれば、
> > SPIのDMA用ドライバを実装出来るのでしょうか。
>
> drivers/spi/spi-imx.cがECSPIのデバイスドライバです。すでにDMAを利用す
> る実装があるように見えます。
>
> Device Tree Sourceに(例えば arch/arm/boot/dts/imx7d-sdb-touch.dts など
> を参考にして)ecspiのノードを変更すると、DMAを利用したSPI通信が可能のよ
> うに思います。

Device Treeを用いたドライバの開発経験がないため、drivers/spi/spi-imx.cに手を加え、
ユーザーランド側でDMA転送を操作できるようにするソースの修正を考えておりました。
(spidev.cライクな、キャラクタ型ドライバとしての制御)

不勉強で大変申し訳ありませんが、これはspi-imx.c内に記述されている
module_platform_driverで定義されたものを、DTSにて紐付けることで、
ユーザーランドでのドライバ制御が可能になるということでしょうか。

---

> 「XXXのような動作を期待して、YYYしたが、ZZZになってしまった。」のよう
> な状況を教えていただけると、もう少し的確なアドバイスが可能かと思います。

SPIのDMA動作確認のための質問でしたので、具体的な動作を挙げる事が出来ず、
大変申し訳ありませんでした。

ECSPIのDMA転送としてのサンプルが無く、動かし方が解らなかったため、
ドライバ、及び、ユーザーランド側でDMAを操作するアプリケーションのサンプルを求めておりました。

---

DMAの動作的には、i.mx7 dualのリファレンスマニュアルにあるフローチャートに沿い、
spi-imx.cに用意されている関数を順にコールすればよいのかなと考えております。

実際に製造し、動作を確認してみようと思いますので、
不明な点が発生次第、上記回答に沿い再度投稿させていただきます。

溝渕です。

> 不勉強で大変申し訳ありませんが、これはspi-imx.c内に記述されている
> module_platform_driverで定義されたものを、DTSにて紐付けることで、
> ユーザーランドでのドライバ制御が可能になるということでしょうか。

そうですね。

DTSにハードウェアの構成情報(ECSPIの有効化やピン設定, SPI接続のデバイス
等)を追加するとユーザーランドから利用可能になるかと思います。

> 実際に製造し、動作を確認してみようと思いますので、
> 不明な点が発生次第、上記回答に沿い再度投稿させていただきます。

はい。もし問題が出たらまた質問してください。

いつもお世話になっております。

SPI利用の設定に関しまして、
spidevの使い方は下記をベースにしております。
https://users.atmark-techno.com/blog/615/2577

ベースとしました、armadillo_x1-ecspi4_user1.dtsでは、
起動時、spi-imx.cのprobeにて、DMA部分でのエラーが発生しておりました。
--------------------------------
...
of_dma_request_slave_channel: dma-names property of node '/soc/aips-bus@30400000/ecspi@30630000' missing or empty
spi_imx 30630000.ecspi: cannot get the TX DMA channel!
spi_imx 30630000.ecspi: dma setup error,use pio instead
spi_imx 30630000.ecspi: probed
...
--------------------------------

DTSの編集を、ご紹介いただいたソースや、
/arch/arm/boot/dts/imx7d.dtsiのECSPI(1~3)等を参考に、
添付ファイル(Line43, 44)の修正を追加しました。

この追加にて、エラーコードなくドライバが起動し、
SPIにて64byte以上のデータを書き込みに行くと、DMAが動くようになりました。

しかし、64byte以上のデータをioctlにてリードしに行く場合、
spi-imx.cの、関数spi_imx_dma_transfer()、
Line989のエラーコードが表示されておりました。

事前のWait関数にて、タイムアウトが発生していると思いますが、
この原因は何によるものなのでしょうか。
(CON8の対向側なしでデバッグしているため、それが原因でしょうか)

なお、64byte以下のSPI R/Wの場合は、問題なくioctlが動作しております。

設定が足りない、間違っている、そもそも使い方を勘違いしている等、ご助言いただけませんでしょうか。
以上、よろしくお願い致します、

ファイル ファイルの説明
armadillo_x1-ecspi4_user1.dts

溝渕です。

> この追加にて、エラーコードなくドライバが起動し、
> SPIにて64byte以上のデータを書き込みに行くと、DMAが動くようになりました。
>
> しかし、64byte以上のデータをioctlにてリードしに行く場合、
> spi-imx.cの、関数spi_imx_dma_transfer()、
> Line989のエラーコードが表示されておりました。
>
> 事前のWait関数にて、タイムアウトが発生していると思いますが、
> この原因は何によるものなのでしょうか。
> (CON8の対向側なしでデバッグしているため、それが原因でしょうか)

SPIなので対向の有り無しでは通信エラーにはならないと思います。

気になる点は本当にDMAが動作しているかです。

>&ecspi4 {
> :snip
> dmas = <&sdma 3 7 1>, <&sdma 4 7 2> /* ADD */
> dma-names = "rx", "tx" /* ADD */

ecspi4なので、6,7番を使うべきところと思います。

詳しくは、i.MX 7Dualリファレンスマニュアル(IMX7DRM.pdf)の以下の章を参
照してください。
Table 7-3. SDMA event mapping

ちなみに第2フィールドはペリフェラルタイプ, 第3フィールドは優先度を示しています。

ペリフェラルタイプは、include/linux/platform_data/dma-imx.hの"enum
sdma_peripheral_type"を参照してください。

優先度は、Documentation/devicetree/bindings/dma/fsl-imx-sdma.txtに記載
の通りです。
> ID transfer priority
> -------------------------
> 0 High
> 1 Medium
> 2 Low

溝渕様

いつもお世話になっております。

返信が遅れて大変申し訳ありません。
無事DMAの設定、及び、動作の確認が出来ました。

> >&ecspi4 {
> > :snip
> > dmas = <&sdma 3 7 1>, <&sdma 4 7 2> /* ADD */
> > dma-names = "rx", "tx" /* ADD */
>
> ecspi4なので、6,7番を使うべきところと思います。
>
> 詳しくは、i.MX 7Dualリファレンスマニュアル(IMX7DRM.pdf)の以下の章を参
> 照してください。
> Table 7-3. SDMA event mapping
>
> ちなみに第2フィールドはペリフェラルタイプ, 第3フィールドは優先度を示しています。
>
> ペリフェラルタイプは、include/linux/platform_data/dma-imx.hの"enum
> sdma_peripheral_type"を参照してください。

include/linux/platform_data/dma-imx.hの構造体
struct imx_dma_data {
...
}
で、そのまま"dmas"の値が使用されるのですね。
(使用されているドライバのソースはdrivers/dma/imx-sdma.cでしょうか)

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

別件になりますが、
動作確認をしていたところ、SPIのデータ間に5CLKのWAITが入っているように見えました。

i.mx7dのリファレンスマニュアル、P.2610
"Sample Period Control Register"
の「SAMPLE_PERIOD」が5の設定になっているのでしょうか。

現在、データ間のWait=0を検討しております。

上記レジスタの設定を行っている箇所を、
ドライバソース上で見つけられませんでしたので、
データ間のWait設定方法をご教授いただけませんでしょうか。

以上、よろしくお願い致します。

溝渕です。

> i.mx7dのリファレンスマニュアル、P.2610
> "Sample Period Control Register"
> の「SAMPLE_PERIOD」が5の設定になっているのでしょうか。

いえ。上記レジスタはドライバから触っていないので、デフォルト値の"0"に
設定されていると思います。

> データ間のWait設定方法をご教授いただけませんでしょうか。

mx51_ecspi_config()の中で明示的なdelayを行っていますが、5CLKのWAITの原
因であるかどうか確信は持てません。