I've been working on adding Rust support for the i.MX 8M nano and managed to get the board up and running along with a working uart driver - code here
The next step in my plan is to add a uSDHC driver for the nano. Here's a link to the initial implementation
The implementation keeps throwing some i.MX specific uSDHC command errors. I was hoping someone here can shed some light on this.
The sequence of steps I used are as follows
So far, steps 1 and 2 seem to work (i think)
Here's the debug log output. From what I gather by looking at the contents of the uSDHC's interrupt status field (i.e. a value of 0x00048001), the command (i.e. SEND_IF_CMD) was successfully sent and a response was received, however the response returned contains an error - command end bit error. Not entirely sure why this is happening.
Also the present status register has the SDOFF bit set (SD clock gated off internally). Again not sure why this is happening. The reference manual doesn't provide more information about these bits or the errors.
Any inputs would be greatly appreciated. Please let me know if more information is required.
[ 0.000004] imx8mn-rs version 0.1.0
[ 0.003516] Booting on: i.MX 8M Nano EVK
[ 0.007340] Current privilege level: EL3
[ 0.011254] Exception handling state:
[ 0.014966] Debug: Masked
[ 0.018166] SError: Unmasked
[ 0.021464] IRQ: Masked
[ 0.024758] FIQ: Masked
[ 0.027968] Drivers loaded:
[ 0.030739] 1. i.MX8M Uart2
[ 0.034045] Chars written: 382
[ 0.036995] Sd host circuit reset..
[ 0.040462] Prescaler = 4, Divisor = 15, Freq Set = 400000
[ 0.045966] Sd: sending command, CMD_NAME: "GO_IDLE_STATE", CMD_CODE: 0x00000000, CMD_ARG: 0x00000000
[ 0.056378] Sd: sending command, CMD_NAME: "SEND_IF_COND", CMD_CODE: 0x08020000, CMD_ARG: 0x000001aa
[ 0.066602] Sd Error: Cmd response returned an error, PresentStatus: 0xf0048088, intStatus: 0x00048001, Resp0: 0x00000000, timeDiff: 0
[ 0.078923] Sd host circuit reset..
[ 0.082293] Prescaler = 4, Divisor = 15, Freq Set = 400000
[ 0.087788] Sd: sending command, CMD_NAME: "GO_IDLE_STATE", CMD_CODE: 0x00000000, CMD_ARG: 0x00000000
[ 0.098218] Sd: sending command, CMD_NAME: "APP_CMD", CMD_CODE: 0x17000000, CMD_ARG: 0x00000000
[ 0.108176] Sd: sending command, CMD_NAME: "APP_SEND_OP_COND", CMD_CODE: 0x09020000, CMD_ARG: 0x00ff8000
[ 0.119630] Sd Error: Cmd response returned an error, PresentStatus: 0xf0048088, intStatus: 0x00048001, Resp0: 0x00000000, timeDiff: 0
[ 0.131839] Sd Error: ACMD41 returned non-timeout error SdError
[ 0.137829] uSDHC: PRES_STATE: 0xf0048088, SYS_CTRL: 0x000e02e0, INT_STATUS: 0x00048001
[ 0.146063] uSDHC: CMD "APP_SEND_OP_COND", resp: SdError, CMD_RSP3: 0x00000000, CMD_RSP2: 0x00000000, CMD_RSP1: 0x00000000, CMD_RSP0: 0x00000000
[ 0.159382] failed to initialize
[ 0.162494]
[ 0.164107] ... wait forever
Update:
Just thought I'd add this here, in case anyone finds this useful or can figure out what I'm missing.
During uSDHC initialization, I use an identification clock of 400Khz and a 3.3 volts setting. I'm currently testing an 8GB card.
Here is the list of steps in my initialization routine
For pinmux settings - I use the values from the imx8mn nano device-tree, as listed below
with some modifications.
I think I may have (finally) found the fix. I had to remove the entire reset logic for it to work i.e.
and it magically started working.
I still have to no idea why this works? I hope NXP can explain why this works? But until then, my best guess is that the i.MX 8M Nano EVK board deviates from both the SD spec and the reference manual.
If anyone wants to test this. Please clone the latest (master) commit, build and flash. You should see debug output below
[ 0.000005] imx8mn-rs version 0.1.0
[ 0.003617] Booting on: [i.MX](https://i.mx/) 8M Nano EVK
[ 0.007682] Current privilege level: EL3
[ 0.011755] Exception handling state:
[ 0.015561] Debug: Masked
[ 0.018894] SError: Unmasked
[ 0.022413] IRQ: Masked
[ 0.025746] FIQ: Masked
[ 0.028993] Drivers loaded:
[ 0.031841] 1. i.MX8M Uart2
[ 0.035289] Chars written: 382
[ 0.038436] uSDHC2 supports 1.8v, 3.0v, 3.3v ...
[ 0.043311] NO RESET, PRES_STAT: 0xff8d8088
...
[ 0.050676] NO RSTA, PRES_STAT: 0xff8d8088
...
[ 0.082844] Sd clock stablized in 37us
[ 0.086777] Prescaler = 64, Divisor = 16, Freq = 390625 Hz
...
[ 0.108591] before CMD0 sent, PRES_STAT: 0xff8d8088
[ 0.113783] Sd: sending command, CMD_NAME: "GO_IDLE_STATE", CMD_CODE: 0x00000000, CMD_ARG: 0x00000000
[ 0.126803] Sd: sending command, CMD_NAME: "SEND_IF_COND", CMD_CODE: 0x081a0000, CMD_ARG: 0x000001aa
[ 0.137920] Sd: sending command, CMD_NAME: "APP_CMD", CMD_CODE: 0x371a0000, CMD_ARG: 0x00000000
[ 0.148645] Sd: sending command, CMD_NAME: "APP_SEND_OP_COND", CMD_CODE: 0x29020000, CMD_ARG: 0x50ff8000
[ 0.560598] Sd: sending command, CMD_NAME: "APP_CMD", CMD_CODE: 0x371a0000, CMD_ARG: 0x00000000
[ 0.571475] Sd: sending command, CMD_NAME: "APP_SEND_OP_COND", CMD_CODE: 0x29020000, CMD_ARG: 0x50ff8000
[ 0.583475] Sd: sending command, CMD_NAME: "ALL_SEND_CID", CMD_CODE: 0x02090000, CMD_ARG: 0x00000000
[ 0.595085] Sd: sending command, CMD_NAME: "SEND_REL_ADDR", CMD_CODE: 0x03020000, CMD_ARG: 0x00000000
[ 0.606431] Sd: sending command, CMD_NAME: "SEND_CSD", CMD_CODE: 0x09010000, CMD_ARG: 0x00010000
[ 0.617763] CSD Contents : 00 40 0e 00 32 5b 59 00 003b 83 7f 80 0a 40 00
[ 0.624947] 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_mi
salign=0b, dsr_imp=0b, sector_size =0x7F, erase_blk_en=1b
[ 0.645753] CSD 2.0: ver2_c_size = 0x3BFF, card capacity: 7987527680 bytes or 7.99GiB
[ 0.654006] wp_grp_size=0x0000000b, wp_grp_enable=0b, default_ecc=00b, r2w_factor=010b, write_bl_len=0x09, write_bl_partial=0b, file_format_grp=0, copy=0b, perm_writ
e_protect=0b, tmp_write_protect=0b, file_format=0b ecc=00b
Some context for why the (above) fix works: I zeroed-in on the issue with the following observation which was consistent across multiple rounds of testing
[ 0.000005] imx8mn-rs version 0.1.0
[ 0.003618] Booting on: i.MX 8M Nano EVK
[ 0.007667] Current privilege level: EL3
[ 0.011687] Exception handling state:
[ 0.015349] Debug: Masked
[ 0.018745] SError: Unmasked
[ 0.022187] IRQ: Masked
[ 0.025411] FIQ: Masked
[ 0.028761] Drivers loaded:
[ 0.031530] 1. i.MX8M Uart2
[ 0.034922] Chars written: 382
[ 0.038160] uSDHC2 has support for 1.8v, 3.0v, 3.3v ...
[ 0.044572] after HW RESET, PRES_STAT: 0xff8d8088
[ 0.049441] checking register value
[ 0.051909] after RSTA cleared, PRES_STAT: 0xf40d8088
[ 0.057188] Sd host circuit reset in 3us
[ 0.061136] after Sd host cicuit reset, PRES_STAT: 0xf00d8088
...
[ 0.087812] Sd clock stablized in 38us
[ 0.091674] Prescaler = 64, Divisor = 16, Freq = 390625 Hz
...
[ 0.118224] Sd: sending command, CMD_NAME: "GO_IDLE_STATE", CMD_CODE: 0x00000000, CMD_ARG: 0x00000000
[ 0.131208] Sd: sending command, CMD_NAME: "SEND_IF_COND", CMD_CODE: 0x081a0000, CMD_ARG: 0x000001aa
[ 0.145884] Error: we got a response for the last cmd but it contains errors, decode contents of interrupt status register for details
VendSpec: 0x30007809, SysCtrl: 0x000f20ff, ProtCtrl: 0x08800022, PresentStatus: 0xf00d8088, intStatus: 0x000c8001, Resp0: 0x00000000, Resp1: 0x00000000, Resp2: 0x00000000, Resp3: 0x00000000, CC_bit set in 4131us
[ 0.177955] SdError: Send interface condition command (CMD8) returned an error
[ 0.185646] failed to initialize
[ 0.189029]
[ 0.190608] ... wait forever
Update:
Given the above - I can summarise the issue as the following (with some degree of certainty)
Some extra context: just in case this is required
[ 71.987092] imx8mn-rs version 0.1.0
[ 71.990506] Booting on: i.MX 8M Nano EVK
[ 71.994481] Current privilege level: EL3
[ 71.998294] Exception handling state:
[ 72.002008] Debug: Masked
[ 72.005139] SError: Unmasked
[ 72.008524] IRQ: Masked
[ 72.011811] FIQ: Masked
[ 72.014926] Drivers loaded:
[ 72.017677] 1. i.MX8M Uart2
[ 72.020958] Chars written: 382
[ 72.023983] Sd host circuit reset..
[ 72.027439] card inserted...
[ 72.030367] Prescaler = 4, Divisor = 15, Freq Set = 400000
[ 72.035865] Sd: sending command, CMD_NAME: "GO_IDLE_STATE", CMD_CODE: 0x00000000, CMD_ARG: 0x00000000
[ 72.049859] Sd: sending command, CMD_NAME: "ALL_SEND_CID", CMD_CODE: 0x02010000, CMD_ARG: 0x00000000
[ 72.065140] Sd Error: Cmd response returned an error, VendSpec: 0x2000f800, ProtCtrl: 0x00800040, PresentStatus: 0xf00d8088, intStatus: 0x00048001, Re
sp0: 0x00000000, timeDiff: 5062
[ 72.081495] uSDHC: PRES_STATE: 0xf00d8088, SYS_CTRL: 0x000e02ef, INT_STATUS: 0x00048001
[ 72.089641] uSDHC: CMD "ALL_SEND_CID", resp: SdError, CMD_RSP3: 0x00000000, CMD_RSP2: 0x00000000, CMD_RSP1: 0x00000000, CMD_RSP0: 0x00000000
[ 72.102677] failed to initialize
[ 72.105781]
[ 72.107302] ... wait forever
reg_usdhc2_vmmc: regulator-usdhc2 {
compatible = "regulator-fixed";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_reg_usdhc2_vmmc>;
regulator-name = "VSD_3V3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
gpio = <&gpio2 19 GPIO_ACTIVE_HIGH>;
off-on-delay-us = <12000>;
enable-active-high;
};
&usdhc2 {
assigned-clock-rates = <200000000>;
assigned-clocks = <&clk IMX8MN_CLK_USDHC2>;
pinctrl-names = "default", "state_100mhz", "state_200mhz";
pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>;
pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>;
cd-gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
bus-width = <4>;
vmmc-supply = <®_usdhc2_vmmc>;
status = "okay";
};
pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp {
fsl,pins = <MX8MN_IOMUXC_SD2_RESET_B_GPIO2_IO19 0x41>;
};
regusdhc2vmmcgrp {
fsl,pins = <0xec 0x354 0x00 0x05 0x00 0x41>;
u-boot,dm-spl;
phandle = <0x42>;
};
regulator-usdhc2 {
compatible = "regulator-fixed";
pinctrl-names = "default";
pinctrl-0 = <0x42>;
regulator-name = "VSD_3V3";
regulator-min-microvolt = <0x325aa0>;
regulator-max-microvolt = <0x325aa0>;
gpio = <0x26 0x13 0x00>;
enable-active-high;
u-boot,off-on-delay-us = <0x4e20>;
phandle = <0x2d>;
};
mmc@30b50000 {
compatible = "fsl,imx8mn-usdhc\0fsl,imx8mm-usdhc\0fsl,imx7d-usdhc";
reg = <0x30b50000 0x10000>;
interrupts = <0x00 0x17 0x04>;
clocks = <0x02 0x56 0x02 0x4d 0x02 0xaf>;
clock-names = "ipg\0ahb\0per";
fsl,tuning-start-tap = <0x14>;
fsl,tuning-step = <0x02>;
bus-width = <0x04>;
status = "okay";
assigned-clocks = <0x02 0x68>;
assigned-clock-rates = <0xbebc200>;
pinctrl-names = "default\0state_100mhz\0state_200mhz";
pinctrl-0 = <0x29 0x2a>;
pinctrl-1 = <0x2b 0x2a>;
pinctrl-2 = <0x2c 0x2a>;
cd-gpios = <0x23 0x0f 0x01>;
vmmc-supply = <0x2d>;
u-boot,dm-spl;
sd-uhs-sdr104;
sd-uhs-ddr50;
};