Ralinkのspi

Ralink(Mediatek)のSOCのSPIのOpenWRTでの拡張利用は下記の二人の方が試していました。

http://continue-to-challenge.blogspot.com/2018/02/fon2405eledeopenwrtspi.html

RT3050にST7735Sを使った液晶を接続しています。

http://www.zopfco.de/entry/2018/12/24/162811

MT7628ANにST7735を使った液晶を接続しています。

RalinkのSPIは以下のような変遷がありました。

|chip||
|:--|:--|
|RT2880|Ralink最初のMIPS SOCでSPIのサポート有り|
|RT3050|SPI Flashからのブートが可能になる|
|RT5350|CS1がサポートされ2つのスレーブがサポートされる|
|RT6855|FIFOがサポートされる|
|MT7620|GDMAにSPIサポートが入る|
|MT7621|レジスタの構成が変わっているようです|

OpenWRTのコードはGPIOをCSとして使うこともできるようになっていて、RT3050でも複数のスレーブがサポートできるようです。

RT2880の頃はCFIなFlashがストレージだったのでSPIはあまり使われないことを想定してDMAがなかったのかもしれません。

RT3050のSPI IPにはFlash用の機構が入っていて、純粋なSPI BusのIPではありません。

GDMAはRT3050にもあったのですが、SPIのサポートがありませんでした。

DMAがないRT3050でも、SPI Flashでもそんなに遅い感じはしません。RT3050が成功できたのはSPI Flashをブートデバイスにできたのも一つの要因だった気がします。

レジスタの構成からGDMAのSPIサポートとFIFOは同時だったのかもしれません。買収のどたばたで、RT6855はほどんど出荷されず、MT7620が同等の仕様だったのかもしれません。

OpenwrtもDMAのサポートは実装されてないようです。

RalinkのRalink_ApSoC_SDK_3600の中のralink_spi.cはCS1の定義があるのでRT5350もサポートされていると思われますが、複数のスレーブをサポートしたコードには見えません。

DR-QFNなパッケージのチップはパターンが追いやすくCS1の位置が確認できる可能性がありますが、TFBGAなパッケージはかなり厳しいです。

我らがFreeBSDのMediatek(Ralink)のspiのコードはFDT対応のmediatekを作ったStanislav Galabovさんはちょっと調整しただけで、rt3050時代のrayのコードが使われているようです。このためCS1には対応してませんし、modeやclockも決め打ちになっていて、プロトタイプ的な状態です。mtk_spi_v1.cがMT7620以前でmtk_spi_v2.cがそれ以降になっているようです。

なぜこれを調べたかというとOnion Omegaにつないだ液晶がGPIOのBitbangでのSPIを使っていたので、ちょっと遅かったのでハードウエアサポートがあるとどれくらいパフォーマンスが改善できるか確認したかったからです。もちろん愛しのRalinkというのもありますが。

ST7789という液晶コントローラーを使ったモジュールでCSがないものがあるようです。このようなモジュールはSPIバスの拡張では使えないと思います。

すっかり忘れていたのですが、GPIOのCS対応してました。

https://svnweb.freebsd.org/base?view=revision&revision=347998

![IMG_20231016_112756.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/a9e42fdc-0829-72e0-974b-ca57ac6f6f1c.jpeg)

またFlash以外のデバイスでも使えるようにflashの設定をパスする機構が入っています。

SPIのクロックはdtsのspi-max-frequencyを元に設定さて、RT3050の場合、最高でCPUクロックの半分になります。

# FIFOサポート

MT7620にはDMAとFIFOのサポートがあります。これはおそらくRT6855に入っていたものと同じではないかと思われRalink時代に開発したものではないかと思われます。

DMAは元々あったGDMAにSPIサポートが追加された形になります。GDMAはpcmやI2Sのサポートがありました。

GDAMをサポートするためにbusdmaのメモリを確保するコードを書いてみたのですが、肝心のGDAMの使い方がわかりません。githubを探してもまったく動くコードが見つかりません。

いろいろためしても動かないので、方針転換してFIFOを使うコードを作る事にしました。

sys/mips/mediatekはチップの仕様が違うものはv1,v2などと区別してファイルが作成されています。ifdefで分かりにくくなるより良いかもしれません。

spiはすでにv2があるのでMT7620対応のv1のコードをコピーしてv3を作ります。

MT7620はデーターシートが手に入るので、データーシートにあわせてヘッダーにレジスタやフィールドを追加します。

USERというレジスタがFIFOのために追加されていて、これを操作してデータをやり取りします。

とりあえずflashのREADの部分だけFIFOにしてみました。

https://github.com/ZRouter/freebsd-src/tree/zrouter_yamori813/sys/mips/mediatek

起動時間がv1が42秒に対しv3が36秒だったので、効果があるようです。

本来busドライバはぶら下がるdeviceに依存してはいけないと思うのだが、ハードがdeviceを前提に作られている場合は仕方ないのかもしれない。

DMAだとキャッシュの操作が必要になり、複雑になるので付けてはみたけど、利用価値が無かったという事でしょうか。

バイトアクセス(v1)

```
# dd if=/dev/flash/spi1 of=/dev/null
4096+0 records in
4096+0 records out
2097152 bytes transferred in 2.390855 secs (877156 bytes/sec)
# dd if=/dev/flash/spi1 of=/dev/null
4096+0 records in
4096+0 records out
2097152 bytes transferred in 2.389815 secs (877537 bytes/sec)
# dd if=/dev/flash/spi1 of=/dev/null
4096+0 records in
4096+0 records out
2097152 bytes transferred in 2.390076 secs (877442 bytes/sec)
```

FIFO使用(v3)

```
# dd if=/dev/flash/spi1 of=/dev/null
4096+0 records in
4096+0 records out
2097152 bytes transferred in 1.179504 secs (1777995 bytes/sec)
# dd if=/dev/flash/spi1 of=/dev/null
4096+0 records in
4096+0 records out
2097152 bytes transferred in 1.177890 secs (1780431 bytes/sec)
# dd if=/dev/flash/spi1 of=/dev/null
4096+0 records in
4096+0 records out
2097152 bytes transferred in 1.178753 secs (1779127 bytes/sec)
```