y.nakamura
2014年3月22日 23時08分
中村です。
4x0の話です。
SDHC2からブート・・・・・・・・・できないんですね。
hermit-atのソースで
target/driver/mmcsd.c
int mmcsd_load_kernel(char *device) { .... if (strncmp(device, "mmcblk", 6) != 0) .... drive = device[6] - '0'; .... ret = dev->probe(dev, drive); .... }
というように"mmcblk"の次の数字をprobeに渡してるのに、
target/driver/mx25_esdhc.cのprobe関数がそれを使ってくれてない。
使ってないというより、0以外をエラーにしてる。
static int mx25_mmcsd_probe(struct mmcsd_device *dev, int port) { .... if (port != 0) return -H_EINVAL; .... }
できるものと思い込んでいた私が悪いのですけど、
SDHC2から起動できるようにするのは大変でしょうか?
SDHC1を無視してSDHC2決め打ちでもいいです。
--
なかむら
#本番の基板が出来上がるまでしばらく時間がかかるので、
#サンハヤトのSDカードの基板を使ってA440やA410でSDHC2を
#試しているのですが、この試験環境だと、かなり(数100分の1まで)
#クロックを落とさないとデータエラーだらけでまともに動かないし・・・
コメント
y.nakamura
y.nakamura
中村です。
nakaiさんのおかげで、SDHC2から起動できるようになりました。
ありがとうございました。
iomuxの切り替えで、SW_SELECT_INPUTレジスタを設定する必要があることに
気づくのに時間がかかってしまいました。
それとALT2のときにSIONビットをどうすればいいか、データシートを読んでも
よくわからなかったので、linuxカーネルソースを見て同じように設定したら
動いてくれました。
linuxカーネルの方では、MX25_PAD_CTL_GRP_DSE_CSIで
DSEをHIGHにしているのですけど、とりあえずはやらなくても
大丈夫なようです。
修正箇所を書いておきます。
手元のソースはSDHC2起動とは別の修正やKconfig対応のif文なんかも
入っていたりするので、diff出力でなく、ポイント部分のみ抜き出しました。
SDHC2決め打ちの修正です。
target/armadillo4x0/board.c
struct iomux_info mmcsd_pins[] = { { MX25_PIN_CSI_D6, SION(MUX_ALT2), SION(MUX_ALT2), 0x0001, 0x0001 }, // CMD { MX25_PIN_CSI_D7, SION(MUX_ALT2), MUX_ALT5, 0x0001, 0x0001 }, // CLK { MX25_PIN_CSI_MCLK, MUX_ALT2, MUX_ALT2, 0x0001, 0x0001 }, // DAT0 { MX25_PIN_CSI_VSYNC, MUX_ALT2, MUX_ALT2, 0x0001, 0x0001 }, // DAT1 { MX25_PIN_CSI_HSYNC, MUX_ALT2, MUX_ALT2, 0x0001, 0x0001 }, // DAT2 { MX25_PIN_CSI_PIXCLK, MUX_ALT2, MUX_ALT2, 0x0101, 0x0101 }, // DAT3 { }, }; struct iomux_info mmcsd_cd_pin[] = { { MX25_PIN_CSI_D9, MUX_ALT5, MUX_ALT5, 0x01e0, 0x01e0 }, // CON9_17 { }, }; struct iomux_info mmcsd_pwren_pin[] = { { MX25_PIN_VSTBY_REQ, MUX_ALT5, MUX_ALT5, 0x01e0, 0x01e0 }, // CON9_1 { }, }; static void armadillo4x0_setup_iomux(struct platform_info *pinfo) { .... write32(IOMUXC_ESDHC2_IPP_CMD_IN_SELECT_INPUT, 1); write32(IOMUXC_ESDHC2_IPP_CARD_CLK_IN_SELECT_INPUT, 1); write32(IOMUXC_ESDHC2_IPP_DAT0_IN_SELECT_INPUT, 1); write32(IOMUXC_ESDHC2_IPP_DAT1_IN_SELECT_INPUT, 1); write32(IOMUXC_ESDHC2_IPP_DAT2_IN_SELECT_INPUT, 1); write32(IOMUXC_ESDHC2_IPP_DAT3_IN_SELECT_INPUT, 1); .... }
target/driver/mx25_esdhc.c
static int mx25_mmcsd_probe(struct mmcsd_device *dev, int port) { .... if (port != 1) return -H_EINVAL; .... mx25_ahb_clock_enable(6); mx25_per_clock_enable(4); mx25_ipg_clock_enable(14); .... dev->host->base = ESDHC2_BASE_ADDR; .... }
クロックenableの引数は、nakaiさんに教えていただいたarch/arm/mach-mx25/clock.cを
調べてこの値にしたのですが、最終的には、データシートの
Table 15-9. AHB Clock Gating
Table 15-10. PER Clock Gating
Table 15-13. IPG Clock Gating
で確認しました。
--
なかむら
y.nakamura
中村です。
ソース修正箇所で、書き忘れがありました。
(diffの出力そのままなら書き忘れなんてことは起きないのですが)
次の部分を無効にした方がいいです。
これをやらなくてもmmcsdのprobeで最初期化されるので、
動作上は問題は起きないと思いますが・・・
static struct iomux_info gpio_pins[] = { .... // { MX25_PIN_CSI_MCLK, MUX_ALT5, MUX_ALT5, 0x00e0, 0x00e0 }, // { MX25_PIN_CSI_VSYNC, MUX_ALT5, MUX_ALT5, 0x00e0, 0x00e0 }, // { MX25_PIN_CSI_HSYNC, MUX_ALT5, MUX_ALT5, 0x00e0, 0x00e0 }, // { MX25_PIN_CSI_PIXCLK, MUX_ALT5, MUX_ALT5, 0x01e0, 0x01e0 }, .... // { MX25_PIN_CSI_D6, MUX_ALT5, MUX_ALT5, 0x00e0, 0x00e0 }, // { MX25_PIN_CSI_D9, MUX_ALT5, MUX_ALT5, 0x00e0, 0x00e0 }, // { MX25_PIN_CSI_D7, MUX_ALT5, MUX_ALT5, 0x01e0, 0x01e0 }, // { MX25_PIN_VSTBY_REQ, MUX_ALT5, MUX_ALT5, 0x0080, 0x0080 }, .... }
--
なかむら
y.nakamura
中村です。
たびたびスミマセン。
SDHC1からのブートを生かしたままSDHC2からのブートができるようにしました。
トリッキーというほどではないですが、実行中に配列の差し替えをしてます。
今回はパッチの形にしました。添付します。
(diffを出した後にエディタで関係のない部分を削っていますので、diffの行番号が
元にしたソースと異なってますが、パッチ当てはできるはずです)
元ソースはhermit-at-2.2.0。
CONFIG_ENABLE_SDHC2_BOOTでないときにはオリジナルのソースコードに
なるようにしてあります。
Rev.Bのボードは無視してます。
オリジナルコードで、エラーメッセージ出力にバグがあったので修正しておきました。
--
なかむら
ファイル | ファイルの説明 |
---|---|
hermit-at-2.2.0_SDHC2-boot.patch | SDHC2ブートパッチ |
y.nakamura
中村です。
少し前のSDHC2からのブートのときに
> #本番の基板が出来上がるまでしばらく時間がかかるので、
> #サンハヤトのSDカードの基板を使ってA440やA410でSDHC2を
> #試しているのですが、この試験環境だと、かなり(数100分の1まで)
> #クロックを落とさないとデータエラーだらけでまともに動かないし・・・
と書いていましたが、先ほど(4月11日夜)にリリースされた
at19のカーネルを使ったところ、解消されました(ようです)。
時々こんなメッセージが出ますが、死ななくなりました。
mmcblk0: data error detected. retrying block read. Retry 1
mmcblk0になってますが、A-410本体のmicroSDにカードを
入れてないので、これがSDHC2です。
自分で対処するには、重いな~と思っていたところなので、
とても助かります。
(対応をお願いしていたわけではないですけど)
どうもありがとうございました。
--
なかむら
at_nakai
2014年3月24日 11時48分
nakaiです。
> SDHC2からブート・・・・・・・・・できないんですね。
できないようになってますね。
> SDHC1を無視してSDHC2決め打ちでもいいです。
決め打ちなら比較的簡単にできると思います。
ポイントは次のとおりです。
1. ESDHC2で利用するクロックの有効化
2. ESDHC2のベースアドレスを設定
3. ピンマルチプレクスでESDHC2をアクティベート
■1. ESDHC2で利用するクロックの有効化
src/target/driver/mx25_esdhc.c::mx25_mmcsd_probe()
mx25_ahb_clock_enable(5);
mx25_per_clock_enable(3);
mx25_ipg_clock_enable(13);
ここで行っています。カーネルでは、
arch/arm/mach-mx25/clock.c::struct clk esdhc1_clk[]
arch/arm/mach-mx25/clock.c::struct clk esdhc2_clk[]
に記載されているので、そこら辺を参考にしてください。
■2. ESDHC2のベースアドレスを設定
src/target/driver/mx25_esdhc.c::mx25_mmcsd_probe()
dev->host->base = ESDHC1_BASE_ADDR;
ここをESDHC2_BASE_ADDRに変更すればよさそうです。
■3. ピンマルチプレクスでESDHC2をアクティベート
src/target/armadillo4x0/board.c::
struct iomux_info mmcsd_pins[]
struct iomux_info mmcsd_cd_pin[]
struct iomux_info mmcsd_pwren_pin[]
ここでマルチプレクスを設定しているので、
ここをハードに合わせて変更する必要がありそうです。
残りは、中村さんが示しているところですね。
> static int mx25_mmcsd_probe(struct mmcsd_device *dev, int port)
> {
> ....
> if (port != 0)
> return -H_EINVAL;
> ....
> }
参考になれば幸いです。
--
nakai
> 中村です。
>
> 4x0の話です。
> SDHC2からブート・・・・・・・・・できないんですね。
>
> hermit-atのソースで
> target/driver/mmcsd.c
>
> というように"mmcblk"の次の数字をprobeに渡してるのに、
> target/driver/mx25_esdhc.cのprobe関数がそれを使ってくれてない。
> 使ってないというより、0以外をエラーにしてる。
>
>
> できるものと思い込んでいた私が悪いのですけど、
> SDHC2から起動できるようにするのは大変でしょうか?
> SDHC1を無視してSDHC2決め打ちでもいいです。
>
> --
> なかむら
> #本番の基板が出来上がるまでしばらく時間がかかるので、
> #サンハヤトのSDカードの基板を使ってA440やA410でSDHC2を
> #試しているのですが、この試験環境だと、かなり(数100分の1まで)
> #クロックを落とさないとデータエラーだらけでまともに動かないし・・・
>