link もっと前
   2018年 12月 23日 -
      2018年 12月 14日  
link もっと後

link 未来から過去へ表示(*)
link 過去から未来へ表示

日々

link permalink

linux-next で ROCK64 のオーディオが動かない、その 6

  • 2018年 10月 14日 - I2S と クロックレジスタ
  • 2018年 11月 10日 - I2S の DMA 問題と、残りの 3つの問題
  • 2018年 11月 11日 - I2S2 を認識しない問題解決(DMA チャネル数の問題だった)
  • 2018年 11月 28日 - I2S1 が動かない問題解決(クロックゲート定義のバグを直した)
  • 2018年 11月 29日 - アナログオーディオが動かない問題解決(ACODEC ドライバがなかったから移植)
  • 2018年 12月 23日 - 44.1kHz の PCM を再生できない問題解決(GPLL クロック定義のバグを直した)
  • 2019年 1月 5日 - 32kHz → 44.1kHz の順で PCM を再生できない問題解決(fractional divider の実装を変えた)

RK3328 の GPLL

RK3288 の GPLL 系のクロック周波数が、49151999 のようなおかしな値になってしまう問題も、追ってみたら意外と簡単だったのでパッチを作りました。取り込まれることを祈っておきましょう。

たぶん誰も興味が無いと思いますが、下記は RK3328 GPLL 系のクロック周波数がおかしくなる問題の詳細です。

RK3328 の PLL 周波数の決め方

まず Rock64 には 24MHz の水晶が載っていて、RK3328 の XIN24M に入力されています。これが FREF になります。

PLL 周波数は仕様書(RK3328 TRM)によると、
FOUTVCO = FREF / REFDIV * (FBDIV + FRAC / 224)
と書かれています。

しかしこれはおそらく誤記で正しくは、
FOUTVCO = FREF / REFDIV * (FBDIV + FRAC / 2^24)
だと思われます。

クロックドライバの実装も後者でしたし、hdk さんに教えてもらった他の Rockchip の仕様書でも 2^24 になっていましたから、RK3328 の仕様書にある 224 は 2^24 の誤記とみて問題ないでしょう。

最終的な PLL 周波数は、
FOUTPOSTDIV = FOUTVCO / POSTDIV1 / POSTDIV2
となります。

クロックドライバの実装

REFDIV, FBDIV, POSTDIV1, POSTDIV2, FRAC に設定される値は、クロックドライバで下記のように定義されています。

RK3328 のクロックドライバ

//drivers/clk/rockchip/clk-rk3328.c

static struct rockchip_pll_rate_table rk3328_pll_frac_rates[] = {
	/* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
	RK3036_PLL_RATE(1016064000, 3, 127, 1, 1, 0, 134217),
	/* vco = 1016064000 */
	RK3036_PLL_RATE(983040000, 24, 983, 1, 1, 0, 671088),
	/* vco = 983040000 */
	RK3036_PLL_RATE(491520000, 24, 983, 2, 1, 0, 671088),
	/* vco = 983040000 */
	RK3036_PLL_RATE(61440000, 6, 215, 7, 2, 0, 671088),
	/* vco = 860156000 */
	RK3036_PLL_RATE(56448000, 12, 451, 4, 4, 0, 9797894),
	/* vco = 903168000 */
	RK3036_PLL_RATE(40960000, 12, 409, 4, 5, 0, 10066329),
	/* vco = 819200000 */
	{ /* sentinel */ },
};

このコードの何がおかしいのかお見せするため、試しに先頭の行の値を使って PLL 周波数を計算してみます。PLL 周波数の目標値である rate は 1016064000 です。その他の設定値は、

  • refdiv : 3
  • fbdiv : 127
  • frac : 134217
  • postdiv1: 1
  • postdiv2: 1

です。この設定値に基づいて各設定値を計算してみると、

  • FREF * FBDIV / REFDIV = 24000000 * 127 / 3 = 1016000000
  • (FREF * FRAC / REFDIV) >> 24 = 24000000 * 134217 / 3 / 2^24 = 63999
  • FOUTVCO = 1016063999
  • FOUTPOSTDIV = 1016063999 / 1 / 1

となってしまい、1足りない変な値になります。1足りない原因は 2項目の計算結果が 63999 になってしまうことですから、直すには frac の値を 1 増せば良いです。frac を 134218 にすると、

  • (FREF * FRAC / REFDIV) >> 24 = 24000000 * 134218 / 3 / 2^24 = 64000

となって、めでたしめでたしです。

以上の解析結果に基づいて frac の値を 1増やすパッチを Linux ML に送りました。英語がイマイチで、うまく説明できず、原始人のような「これ値違う、俺直す」になってしまっていますが……。

Rockchip のアーキメンテナの Heiko さんは、コミットメッセージがあまりにもひどいと直してくれる(昔も修正されたことがある)みたいなので、そこに甘えておきます。原始人英語がそのまま取り込まれても別に構いませんし。

[編集者: すずき]
[更新: 2019年 2月 13日 00:26]
link 編集する

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link permalink

RK3328 の ACODEC

RK3328 の ACODEC パッチを ALSA ML に送ったところ、すんなり取り込まれました。やった。作者が自分ではないドライバを投稿したのは初めてかもしれません。それでも取り込まれるんですね。

あと 48kHz → 44.1kHz 系に切り替えたときに音が出なくなってしまう病気の応急処置パッチも取り込まれました。素早く切り替えるとやっぱり音が鳴らなくなるんですが、これ以上追う手段が無いので(2018年 12月 19日の日記参照)諦めています。できれば Rockchip の中の人に直してほしいね…。

メモ: 技術系の話は Facebook から転記しておくことにした。

[編集者: すずき]
[更新: 2018年 12月 23日 19:51]
link 編集する

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link permalink

手ごわい 44.1kHz 系のオーディオ

RK3328 の I2S1 で 44.1kHz 系を再生すると EINVAL エラーになってしまう問題は、I2S のマスタークロック周波数が 11289600 ではなく 11289599 などという変な値が渡されて、マスタークロックとビットクロックが整数比ではなくなることが原因でした。

エラーを無視して処理を流してみると、分周比がおかしくなります。本来 11289600 / 2822400 = 4 にならなければいけないのですが、11289599 / 2822400 = 3 になって、周波数が高めに設定されてしまい、異常に音が高くなります。

Rockchip Linux はどうやって解決しているのか見ると DIV_ROUND_CLOSEST というマクロで割り算の結果を 4 側に丸めていました。本当の原因は変な端数の値を返すクロックドライバだと思うので、この対応はちょっとイケてないですね……。

ACODEC にも 2つほど問題があって、完全には解決できていません。

44.1kHz 系に切り替えると ACODEC が動かなくなる問題

問題 1つ目は、44.1kHz 系を再生すると、全く音が出なくなる症状です。これはコアのリセットで直るようです

リセットを掛けないと、切り替え以降、何をしても全く音が出ません。しかし Rockchip Linux のコードは全くリセットを掛けておらず、なぜこれで動くのか理解できません……。

気になる点としては、リセットすることで dai_set_fmtで設定された I2S のマスタースレーブ設定が吹き飛んでしまうことです。しかし ACODEC はなぜかマスタースレーブ設定が間違っていても動いてしまいます。ハードが設定値を無視しているか、Rockchip Linux のドライバが間違っているかどちらかでしょう。真相はわかりません。

44.1kHz 系に切り替えると音が異常に小さくなる問題

問題 2つ目は、48kHz 系 → 44.1kHz 系への切り替え時、たまに音が異常に小さくなる症状です。これは直せそうにないです。

  • おそらく影響しているのは DAC_PRECHARGE_CTRL レジスタの値だろう
  • 48kHz の再生終了から、44.1kHz 系の再生まで、ある程度時間を空けると鳴る
  • 鳴らなかったときもう一度同じ設定で叩くと鳴る

これくらいまではわかりましたが、鳴るとき or 鳴らないときの法則が全くわからないので、これ以上追うのは厳しいです。

体感では、クロック系の切り替えが早すぎると(1秒くらい?)症状が出やすいです。何でだろう??

while :; do aplay -D hw:0,0 48k.wav ; aplay -D hw:0,0 44k.wav ; done

こんなスクリプトをグルグル回すと、44kHz 系は全く音が出ません。待ち時間が足りないのかと思い PRECHARGE の後に 500ms のウェイトを入れましたが、結果は変わらず音が出ません。。。

[編集者: すずき]
[更新: 2018年 12月 20日 03:13]
link 編集する

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link permalink

ARM ワンボード PC のネットワーク

Raspberry Pi 対抗ボードの多くは Raspberry Pi 3 の Ethernet が遅いこと(USB 接続らしい)を引き合いに出し、ネットワークが速いことを宣伝文句にしています。

宣伝文句自体は疑っていませんが、どの程度の差があるかは知らないので、測定してみました。ちょうど Tinker Board も購入しましたし、Rockchip 同士の比較もしてみたいと思います。

測定方法

測定は簡単です。受信側の PC で下記を実行します。

$ iperf3 -s -p 11111

送信側の各種ボードで下記を実行します。

$ iperf3 -c (PC の IP アドレス) -p 11111

受信側の PC の CPU は Ryzen 7 2700 で、マザーボードは ASUS B450-F GAMING です。OS は Debian GNU/Linux amd64 の Testing 版です。測定時点でのカーネルは 4.18.0-2-amd64 というバージョンになっていました。

測定結果

結果だけ先に言うと Tinker Board(RK3288)の方が速いです。ROCK64(RK3328)の方が後発の SoC なのですが、Ethernet は遅いみたいですね。

ちなみに Raspberry Pi 3 は 94Mbps でした。そもそも Gigabit Ether じゃないので、比べ物になりません。

  • Tinker Board: 942Mbits/sec
  • ROCK64: 805Mbits/sec
  • Raspberry Pi 3 Model B: 94Mbits/sec

念のため各ボードの Ethernet ケーブルを入れ替えてみましたが、結果は変わりませんでした。

参考までにファイルサーバとして使っている Pentium J のマシンから、同様の計測を行ったところ 942Mbits/sec でした。

測定のログ

結果はこんな感じでした。

Tinker Board (RK3288) での iperf3 実行結果
katsuhiro@linaro-alip:~$ iperf3 -c 192.168.1.2 -p 11111
Connecting to host 192.168.1.2, port 11111
[  4] local 192.168.1.16 port 58608 connected to 192.168.1.2 port 11111
[ ID] Interval           Transfer     Bandwidth       Retr  Cwnd
[  4]   0.00-1.00   sec   113 MBytes   950 Mbits/sec    0    358 KBytes
[  4]   1.00-2.00   sec   112 MBytes   942 Mbits/sec    0    358 KBytes
[  4]   2.00-3.00   sec   112 MBytes   941 Mbits/sec    0    358 KBytes
[  4]   3.00-4.00   sec   112 MBytes   941 Mbits/sec    0    358 KBytes
[  4]   4.00-5.00   sec   112 MBytes   941 Mbits/sec    0    358 KBytes
[  4]   5.00-6.00   sec   112 MBytes   943 Mbits/sec    0    406 KBytes
[  4]   6.00-7.00   sec   112 MBytes   941 Mbits/sec    0    406 KBytes
[  4]   7.00-8.00   sec   112 MBytes   941 Mbits/sec    0    406 KBytes
[  4]   8.00-9.00   sec   112 MBytes   941 Mbits/sec    0    406 KBytes
[  4]   9.00-10.00  sec   112 MBytes   941 Mbits/sec    0    406 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bandwidth       Retr
[  4]   0.00-10.00  sec  1.10 GBytes   942 Mbits/sec    0             sender
[  4]   0.00-10.00  sec  1.10 GBytes   942 Mbits/sec                  receiver

iperf Done.
Rock64 (RK3328) での iperf3 実行結果
katsuhiro@rock64:~$ iperf3 -c 192.168.1.2 -p 11111
Connecting to host 192.168.1.2, port 11111
[  4] local 192.168.1.102 port 54768 connected to 192.168.1.2 port 11111
[ ID] Interval           Transfer     Bandwidth       Retr  Cwnd
[  4]   0.00-1.00   sec  97.6 MBytes   819 Mbits/sec    0    356 KBytes
[  4]   1.00-2.00   sec  96.4 MBytes   808 Mbits/sec    0    395 KBytes
[  4]   2.00-3.00   sec  95.8 MBytes   804 Mbits/sec    0    395 KBytes
[  4]   3.00-4.00   sec  95.7 MBytes   803 Mbits/sec    0    395 KBytes
[  4]   4.00-5.00   sec  95.8 MBytes   803 Mbits/sec    0    395 KBytes
[  4]   5.00-6.00   sec  95.8 MBytes   804 Mbits/sec    0    395 KBytes
[  4]   6.00-7.00   sec  95.8 MBytes   804 Mbits/sec    0    395 KBytes
[  4]   7.00-8.00   sec  95.7 MBytes   803 Mbits/sec    0    395 KBytes
[  4]   8.00-9.00   sec  95.8 MBytes   804 Mbits/sec    0    395 KBytes
[  4]   9.00-10.00  sec  95.8 MBytes   803 Mbits/sec    0    395 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bandwidth       Retr
[  4]   0.00-10.00  sec   960 MBytes   805 Mbits/sec    0             sender
[  4]   0.00-10.00  sec   958 MBytes   804 Mbits/sec                  receiver

iperf Done.
Raspberry Pi 3 Model B での iperf3 実行結果
katsuhiro@raspberrypi:~ $ iperf3 -c 192.168.1.2 -p 11111
Connecting to host 192.168.1.2, port 11111
[  4] local 192.168.1.105 port 46476 connected to 192.168.1.2 port 11111
[ ID] Interval           Transfer     Bandwidth       Retr  Cwnd
[  4]   0.00-1.00   sec  11.3 MBytes  94.6 Mbits/sec    0   29.7 KBytes
[  4]   1.00-2.00   sec  11.2 MBytes  94.1 Mbits/sec    0   29.7 KBytes
[  4]   2.00-3.00   sec  11.2 MBytes  94.1 Mbits/sec    0   29.7 KBytes
[  4]   3.00-4.00   sec  11.2 MBytes  94.2 Mbits/sec    0   29.7 KBytes
[  4]   4.00-5.00   sec  11.2 MBytes  94.1 Mbits/sec    0   29.7 KBytes
[  4]   5.00-6.00   sec  11.2 MBytes  94.2 Mbits/sec    0   29.7 KBytes
[  4]   6.00-7.00   sec  11.2 MBytes  94.2 Mbits/sec    0   29.7 KBytes
[  4]   7.00-8.00   sec  11.2 MBytes  94.1 Mbits/sec    0   29.7 KBytes
[  4]   8.00-9.00   sec  11.2 MBytes  94.2 Mbits/sec    0   29.7 KBytes
[  4]   9.00-10.00  sec  11.2 MBytes  94.1 Mbits/sec    0   29.7 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bandwidth       Retr
[  4]   0.00-10.00  sec   112 MBytes  94.2 Mbits/sec    0             sender
[  4]   0.00-10.00  sec   112 MBytes  94.2 Mbits/sec                  receiver

iperf Done.
[編集者: すずき]
[更新: 2018年 12月 16日 01:11]
link 編集する

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link permalink

不具合再現せず

Tinker Board でサウンド周りを有効にして linux-next を動かしてみたものの、指摘された不具合(2018年 12月 5日の日記参照)が出ません。

メールでは DMA ドライバのどこかでクラッシュした、と言われました。サウンド周りのハードウェアは I2S とコーデックが居ますが、DMA を使うのは I2S だけです。コーデック max98090 は SoC 外部に居ますから、SoC 内部の DMA を使う術がありません。

I2S が原因ならば、SoC 内部のハードウェア起因ですから、Tinker Board だろうが Chromebook C201 だろうが、ボードに関わらず現象が再現しても良さそうなのに。

Chromebook で使われているグルードライバ rockchip-snd-max98090 の影響も疑って、Chromebook C201 のデバイスツリー(rk3288-veyron-speedy.dts)からデバイスノードの設定をパクってきて、max98090 を spdif-transimtter に差し替えて(Tinker Board に max98090 は搭載されていない)、無理やり動かしてみましたが、特に何事も無く動いてしまいました。

どうやっても Chromebook C201 じゃないと再現しないのかな?良くわからないバグだ……。

Tinker Board のアナログオーディオ出力

ROCK64 のときはアナログオーディオ出力でも HDMI 出力でも、SoC 内蔵の I2S ハードが動作しましたが、Tinker Board はちょっと事情が違います。

Tinker Board にもアナログオーディオ端子は付いていますが、接続先は RK3288 ではなくオンボードの USB Audio(Realtek ALC4040)です。アナログオーディオのためにわざわざ専用 USB デバイスを載せるとは、豪華なボードだなあ〜。

というわけで、Tinker Board で SoC 内蔵の I2S が動くかどうか試すには、アナログオーディオ端子ではダメで、HDMI 出力じゃないと本当に動作しているかどうかわからないです。我が家にはデジタルテレビならありますが、ボードからケーブルが届かないですね。

できれば HDMI が映せて、音も出せて、ボードの隣に置いても邪魔にならないくらい小さいモニタがあるとベストですが、我が家にそんなもんは無い……。

メモ: 技術系の話は Facebook から転記しておくことにした。少し加筆した。

[編集者: すずき]
[更新: 2018年 12月 16日 00:37]
link 編集する

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link もっと前
   2018年 12月 23日 -
      2018年 12月 14日  
link もっと後

管理用メニュー

link 記事を新規作成

合計:  counter total
本日:  counter today

link About www.katsuster.net
RDF ファイル RSS 1.0
QR コード QR コード

最終更新: 3/20 21:30

カレンダー

<2018>
<<<12>>>
------1
2345678
9101112131415
16171819202122
23242526272829
3031-----

最近のコメント 5件

  • link 19年03月05日
    kml 「> 自分が持っている RockPr...」
    (更新:03/20 21:30)
  • link 19年03月10日
    すずき 「ありがとー!!」
    (更新:03/13 09:46)
  • link 19年03月10日
    hdk 「誕生日おめでとー!」
    (更新:03/13 01:14)
  • link 18年12月11日
    すずき 「確認いただいてありがとうございます。直っ...」
    (更新:12/27 00:22)
  • link 18年12月11日
    T4 「再現しませんね\n\n確かに、過去にそう...」
    (更新:12/25 12:45)

最近の記事 3件

link もっとみる
  • link 19年03月11日
    すずき 「[Linux をデグレさせたらしい] 昔、私が投稿したパッチが L...」
    (更新:03/14 00:24)
  • link 19年03月06日
    すずき 「[TinkerBoard の HDMI 出力] せっかく HDMI...」
    (更新:03/13 09:51)
  • link 19年03月10日
    すずき 「[誕生日] 干支を 3周しました。もう完全におじさんの仲間入りです...」
    (更新:03/13 00:10)

こんてんつ

open/close wiki
open/close Java API

過去の日記

open/close 2002年
open/close 2003年
open/close 2004年
open/close 2005年
open/close 2006年
open/close 2007年
open/close 2008年
open/close 2009年
open/close 2010年
open/close 2011年
open/close 2012年
open/close 2013年
open/close 2014年
open/close 2015年
open/close 2016年
open/close 2017年
open/close 2018年
open/close 2019年
open/close 過去日記について

その他の情報

open/close アクセス統計
open/close サーバ一覧
open/close サイトの情報