Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Question - help, porting an EMMC driver over torust#134

nihalpasham started this conversation inGeneral
Discussion options

Hi,

Firstly, thank you for putting this repo together. Its been quite useful. I just wanted to check to see if someone's already solved this problem.

Context: I'm working on porting aSD/EMMC driverwritten inC, managed to put together an initial implementation but I seem to have hit a roadblock. I assumed the rpi4 would have sufficient documentation but I guess not (at least when it comes to the onboard SD/EMMC controllers). Rpi4 has 3 of them usually referred to as

  • SDHOST: this is accessible via GPIO pins but isn't connected to the onboard micro-SD slot.
  • EMMC: accessible via GPIO pins but we cant use GPIO to connect to the on-board micro-SD slot. Although, this interface can be routed to the micro-SD slot via dedicated pins.
  • EMMC2: is a new piece of IP (available on the rpi4) that doesn't appear on the GPIOs i.e. its the default MMC controller with dedicated pins connecting it to the micro-SD slot.

So, the port works so far in as I can

  • get a stable clock, reset the EMMC controller etc.
  • but fails when attempting to perform a full initialization
  • more specifically, it fails when I issue aCMD to an SDcard in the on-board microSD slot.
  • I get a command timeout and command CRC error almost immediately.

For now I'm relying onprint-f style debugging; as I was hoping to avoid a full debugging workflow (i.e. JTAG and all), assuming this was going to be a straightforward port but it didn't quite turn out that way (I'm quite sure I'm missing something). So, I'm hoping someone here has more insight into therpi and its inner workings; if yes, would appreciate it if you provide some pointers on what I'm missing here.

Here's the output you should get when you compile and run the impl on real hardware (i.e. rpi4)

[    0.001629] EMMC: reset card.[W   0.001984] EMMC_CONTROL1, from emmc_reset2: 0[    0.002550] EMMC: setting clock speed to 400000.[    0.003124] Divisor = 105, Freq Set = 396825[W   0.003653] EMMC_CONTROL1, from emmc_set_clock1: 944391[W   0.004291] EMMC_CONTROL1::CLK_STABLE, from emmc_set_clock: 1[W   0.005007] EMMC_CONTROL1, from emmc_set_clock2: 944391[W   0.005657] from emmc_set_clock, set_clock_success[W   0.006242] from_emmc_reset_card, interrupt: 0x00000000[W   0.006881] from_emmc_reset_card, interrupt_en: 0x00000000[W   0.007552] from_emmc_reset_card, interrupt_mask: 0x00000000[W   0.008246] from_emmc_reset_card, interrupt_en: 0x37ff7fff[W   0.008918] from_emmc_reset_card, interrupt_mask: 0x37ff7fff[W   0.009611] from_emmc_reset_card, interrupt: 0x00000140[W   0.010250] from emmc_reset, just before emmc_send_command:[W   0.010933] from_emmc_send_command1,false[W   0.011432] from_emmc_send_command2[W   0.011854] from emmc_wait_for_command, cmd_inhibit:false[W   0.012525] from emmc_wait_for_command1, interrupt: 0x00000140[W   0.013239] from emmc_wait_for_command1, int_error_mask: 0x017e8000[W   0.014009] from emmc_wait_for_command1, interrupt& mask: 0x00000000[W   0.014800] from emmc_wait_for_command, cmd_inhibit:false[W   0.015471] from emmc_wait_for_command2, interrupt: 0x00000140[W   0.016186] from emmc_wait_for_command2, int_error_mask: 0x017e8000[W   0.016955] from emmc_wait_for_command2, interrupt& mask: 0x00000000[W   0.017746] from_emmc_wait_for_command, td: 0[    0.018277] EMMC: Sending command, CMD_NAME:"GO_IDLE_STATE", CMD_CODE: 0x00000000, CMD_ARG: 0x00000000[W   0.019448] from_emmc_send_command_p, interrupt: 0x00000100[W   0.020130] from_emmc_send_command_p, before wait_for_interrupt[W   0.020867] from_emmc_wait_for_interrupt, interrupt_en: 0x37ff7fff[W   0.021625] from_emmc_wait_for_interrupt, interrupt_mask: 0x37ff7fff[W   0.022405] from_emmc_wait_for_interrupt, interrupt: 0x00038100[W   0.023131] from_emmc_wait_for_interrupt, mask: 0x00000001, t_mask: 0x017e8001, int_error_mask: 0x017e8000[W   0.024322] from_emmc_wait_for_interrupt, interrupt& t_mask: 0x00028000[W   0.025146] from_emmc_wait_for_interrupt: td: 0[W   0.025698] from_emmc_wait_for_interrupt, interrupt_en: 0x37ff7fff[W   0.026456] from_emmc_wait_for_interrupt, interrupt_mask: 0x37ff7fff[W   0.027236] from_emmc_wait_for_interrupt, ival: 0x00038100[W   0.027908] from_emmc_wait_for_interrupt, ival& INT_CMD_TIMEOUT: 0x00010000[W   0.028775] from_emmc_wait_for_interrupt, ival& INT_DATA_TIMEOUT: 0x00000000[    0.029653] EMMC: Waitfor interrupt MASK: 0x00000001, STATUS: 0x000f0001, iVAL: 0x00038100, RESP0: 0x00000000[W   0.030902] from emmc_reset, emmc_send_command resp: EMMC_TIMEOUT[    0.031646] from emmc_init, emmc_reset_card: EMMC_TIMEOUT[    0.032307] failed to initialize EMMC2[    0.032763] rpi4 version 0.1.0[    0.033129] Booting on: Raspberry Pi 4[    0.033584] Architectural timer resolution: 18 ns[    0.034159] Drivers loaded:[    0.034494]       1. BCM GPIO[    0.034852]       2. BCM PL011 UART[    0.035275] Chars written: 3287[W   0.035656]wait duration smaller than architecturally supported, skipping[    0.036499] waitingfor 1 second[    1.037147]read 20 blocks: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ............ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0][    1.369945] waitingfor 1 second
You must be logged in to vote

Replies: 2 comments

Comment options

Forgot to mention, you can compile, build and extract thekernel binary with a single command -

cargo xtask build rustBoot-only rpi4

which you can then drop onto an SD card.

You must be logged in to vote
0 replies
Comment options

So, I managed to fix it i.e. its working now. I switched to using the EMMC2.

A couple of changes to the original implementation. So basically, thecard_reset routine for the pi4 needed these changes.

  • change base clock settings (to 50Mhz) and logic used to compute the clock divider value.
  • while enabling interrupts and setting the interrupt mask, disableCARD_INTERRUPT (this one was quite important).
  • lastly, configure CONTROL0 to enable/set SD bus power (or VDD) to 3.3V.

and a few other minor details

Here's the output I get.

[    0.000026] EMMC: reset card.[    0.000141] Divisor = 63, Freq Set = 396825[    0.000571] EMMC: Sending command, CMD_NAME:"GO_IDLE_STATE", CMD_CODE: 0x00000000, CMD_ARG: 0x00000000[    0.001803] EMMC: Sending command, CMD_NAME:"SEND_IF_COND", CMD_CODE: 0x08020000, CMD_ARG: 0x000001aa[    0.003032] EMMC: Sending command, CMD_NAME:"APP_CMD", CMD_CODE: 0x37000000, CMD_ARG: 0x00000000[    0.004078] EMMC: Sending command, CMD_NAME:"APP_SEND_OP_COND", CMD_CODE: 0x29020000, CMD_ARG: 0x50ff8000[    0.406173] EMMC: Sending command, CMD_NAME:"APP_CMD", CMD_CODE: 0x37000000, CMD_ARG: 0x00000000[    0.407028] EMMC: Sending command, CMD_NAME:"APP_SEND_OP_COND", CMD_CODE: 0x29020000, CMD_ARG: 0x00000000[    0.409122] EMMC: Sending command, CMD_NAME:"ALL_SEND_CID", CMD_CODE: 0x02010000, CMD_ARG: 0x00000000[    0.410182] EMMC: Sending command, CMD_NAME:"SEND_REL_ADDR", CMD_CODE: 0x03020000, CMD_ARG: 0x00000000[    0.411239] EMMC: Sending command, CMD_NAME:"SEND_CSD", CMD_CODE: 0x09010000, CMD_ARG: 0xaaaa0000[    0.412445] CSD Contents: 00 40 0e 00 32 5b 59 00 00ed c8 7f 80 0a 40 40[    0.413023] cemmc_structure=1, spec_vers=0, taac=0x0E, nsac=0x00, tran_speed=0x32,ccc=0x05B5, read_bl_len=0x09,read_bl_partial=0b, write_blk_misalign=0b,read_blk_misalign=0b, dsr_imp=0b, sector_size =0x7F, erase_blk_en=1b[    0.415458] CSD 2.0: ver2_c_size = 0xEFFC card capacity: 31914459136 bytes or 31.91GiB[    0.416433] wp_grp_size=0x0000000b wp_grp_enable=0b default_ecc=00b r2w_factor=010b write_bl_len=0x09write_bl_partial=0b file_format_grp=0 copy=1b perm_write_protect=0b tmp_write_protect=0bfile_format=0b ecc=00b[    0.418765] Divisor = 1, Freq Set = 25000000[    0.419296] EMMC: Sending command, CMD_NAME:"CARD_SELECT", CMD_CODE: 0x07030000, CMD_ARG: 0xaaaa0000[    0.420443] EMMC: Sending command, CMD_NAME:"APP_CMD_RCA", CMD_CODE: 0x37020000, CMD_ARG: 0xaaaa0000[    0.421579] EMMC: Sending command, CMD_NAME:"SEND_SCR", CMD_CODE: 0x33220010, CMD_ARG: 0x00000000[    0.422857] EMMC: Sending command, CMD_NAME:"SET_BLOCKLEN", CMD_CODE: 0x10000000, CMD_ARG: 0x00000200[    0.423827] EMMC: SD Card Type 2 HC, 30436Mb, mfr_id: 3,'SD:SD32G', r8.5, mfr_date: 1/2021,  serial: 0x427f3942, RCA: 0xaaaa[    0.424949] rpi4 version 0.1.0[    0.425315] Booting on: Raspberry Pi 4[    0.425771] Architectural timer resolution: 18 ns[    0.426345] Drivers loaded:[    0.426681]       1. BCM GPIO[    0.427038]       2. BCM PL011 UART[    0.427461] Chars written: 2442[W   0.427842]wait duration smaller than architecturally supported, skipping[    0.428685] waitingfor 1 second[    1.429077] waitingfor 1 second[    2.429149] waitingfor 1 second[    3.429215] waitingfor 1 second

PS: I'm actually a bit surprised. I hope documentation for the raspberry-pi gets better (at least for its core-peripherals).

You must be logged in to vote
0 replies
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Category
General
Labels
None yet
1 participant
@nihalpasham
Converted from issue

This discussion was converted from issue #133 on December 19, 2021 14:03.


[8]ページ先頭

©2009-2025 Movatter.jp