LAN966x SDMMC
SoC Resources
LAN966x SDMMC controller supports the embedded Multimedia Card (e.MMC) Specification (v5.01) and the SD Memory Card(v3.0).
Kernel configurations
Following kernel config options should be enabled to use LAN966x SDMMC:
-
CONFIG_MMC_SDHCI- SD Host controller config option. -
CONDFIG_MMC- MMC interface config option -
CONFIG_MMC_SDHCI_OF_AT91- SDHCI OF support (for the Atmel SDMMC controller) config option.
Devicetree Configuration
To use SDMMC interface, following configurations are required in device tree.
-
compatiblestring must be set tomicrochip,lan966x-sdhci. -
regproperty must be set with base register address and length. -
pinctrl-0property must be set to-
<&emmc_sd_pins>, <&sdmmc_pins>to use SD Card interface. -
<&emmc_sd_pins>, <&emmc_pins>to use eMMC interface.- Note
-
emmc_sd_pinsincludes CMD, CLK, D0, D1, D2, D3, RSTN pins for both SD and eMMC,sdmmc_pinsincludes VSEL, WP, CD, LED pins for SD interface only andemmc_pinsincludes D4, D5, D6, D7 pins for eMMC interface only.sdmmc_pinsandemmc_pinspin numbers are same but driver will take care of configuring different ALT modes for SD and eMMC pins.
-
| pinctrl node | CMD pin | CLK pin | D0 | D1 | D2 | D3 | RSTN |
|---|---|---|---|---|---|---|---|
emmc_sd_pins |
GPIO67 |
GPIO68 |
GPIO69 |
GPIO70 |
GPIO71 |
GPIO72 |
GPIO77 |
| pinctrl node | DT Func | VSEL pin | WP pin | CD pin | LED pin |
|---|---|---|---|---|---|
sdmmc_pins |
sd |
GPIO73 |
GPIO74 |
GPIO75 |
GPIO76 |
| pinctrl node | DT Func | D4 | D5 | D6 | D7 |
|---|---|---|---|---|---|
emmc_pins |
emmc |
GPIO73 |
GPIO74 |
GPIO75 |
GPIO76 |
-
interruptsproperty must set with interrupt details. Interrupt number[CPU INTR] corresponding to a sdmmc must be configured as defined below:
| SDMMC ID | Shared Peripheral Interrupt | CPU INTR |
|---|---|---|
sdmmc0 |
98 |
66 |
- Note
-
Shared peripheral interrupt lines start at index ID32. So, CPU INTR must be calculated as [Shared peripheral interrupt number - 32].
-
Input clock
clocksproperty must be set to GCK clock using phandle and GCK ID as<&clk GCK_ID_SDMMC0>. -
clock-namesmust be set tohclockandmultclk -
assigned-clocksmust be set to<&clks GCK_ID_SDMMC0>. -
assigned-clock-ratesmust be set to 45Mhz.
-
- Note
-
While operating as eMMC interface,
tx-phaseproperty must be set to zero. Possible phase shift values are0for 180degrees,cfor 90 degrees,4for 270 degrees,8for 360 degrees. 180 degress phase shift is considered as best chioce for generating phase difference between data/command bus and output clock. It provides sufficient time limit to compensate for any board delays/skew and provides sufficient time margin for setup/hold time requirements.
Example
Following example shows how a SD/eMMC should be defined in DT:
dtsi file:
sdmmc0: sdio-host@e0830000 {
compatible = "microchip,lan966x-sdhci";
reg = <SDMMC_ADDR SDMMC_SIZE>;
interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks GCK_ID_SDMMC0>, <&clks GCK_ID_SDMMC0>;
clock-names = "hclock", "multclk";
assigned-clocks = <&clks GCK_ID_SDMMC0>;
assigned-clock-rates = <45000000>;
status = "disabled";
};
dts file changes for eMMC:
&sdmmc0 {
bus-width = <8>;
cap-mmc-highspeed;
cap-mmc-hw-reset;
non-removable;
pinctrl-0 = <&emmc_sd_pins>, <&emmc_pins>;
pinctrl-names = "default";
no-1-8-v;
tx-phase = <0>; /* 180 degrees phase shift */
status = "okay";
};
dts file changes for SD Card:
&sdmmc0 {
bus-width = <8>;
pinctrl-0 = <&emmc_sd_pins>, <&sdmmc_pins>;
pinctrl-names = "default";
no-1-8-v;
status = "okay";
};
UserSpace
Confirm instances are created
To confirm if mmc device is created:
-
Check if a mmc device is created in
/devdirectory. -
To check card details, mount debugfs using command
mount -t debugfs none /sys/kernel/debug/and then use commandcat /sys/kernel/debug/mmc0/iosto get IOs debugging information.
Example on how to use
eMMC Interface testing:
# ls -l /dev/mmc*
brw------- 1 root root 179, 0 Jan 1 00:00 /dev/mmcblk0
brw------- 1 root root 179, 8 Jan 1 00:00 /dev/mmcblk0boot0
brw------- 1 root root 179, 16 Jan 1 00:00 /dev/mmcblk0boot1
crw------- 1 root root 247, 0 Jan 1 00:00 /dev/mmcblk0rpmb
#
#
# dmesg | grep mmc
[ 3.154864] mmc0: SDHCI controller on e0830000.sdio-host [e0830000.sdio-host] using ADMA
[ 3.355470] mmc0: new high speed MMC card at address 0001
[ 3.365870] mmcblk0: mmc0:0001 IS004G 3.64 GiB
[ 3.369463] mmcblk0boot0: mmc0:0001 IS004G partition 1 2.00 MiB
[ 3.373726] mmcblk0boot1: mmc0:0001 IS004G partition 2 2.00 MiB
[ 3.386894] mmcblk0rpmb: mmc0:0001 IS004G partition 3 512 KiB, chardev (247:0)
[ 3.397439] mmcblk0: p1 p2
#
# mount -t debugfs none /sys/kernel/debug/
# cat /sys/kernel/debug/mmc0/ios
clock: 46000000 Hz
actual clock: 46000000 Hz
vdd: 21 (3.3 ~ 3.4 V)
bus mode: 2 (push-pull)
chip select: 0 (don't care)
power mode: 2 (on)
bus width: 3 (8 bits)
timing spec: 1 (mmc high-speed)
signal voltage: 0 (3.30 V)
driver type: 0 (driver type B)
# dd if=/dev/zero of=/dev/mmcblk0 bs=10M count=1
1+0 records in
1+0 records out
#
# fdisk /dev/mmcblk0
Device contains neither a valid DOS partition table, nor Sun, SGI, OSF or GPT disklabel
Building a new DOS disklabel. Changes will remain in memory only,
until you decide to write them. After that the previous content
won't be recoverable.
The number of cylinders for this disk is set to 119296.
There is nothing wrong with that, but this is larger than 1024,
and could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of LILO)
2) booting and partitioning software from other OSs
(e.g., DOS FDISK, OS/2 FDISK)
Command (m for help): p
Disk /dev/mmcblk0: 3728 MB, 3909091328 bytes, 7634944 sectors
119296 cylinders, 4 heads, 16 sectors/track
Units: sectors of 1 * 512 = 512 bytes
Device Boot StartCHS EndCHS StartLBA EndLBA Sectors Size Id Type
Command (m for help): n
Partition type
p primary partition (1-4)
e extended
1
Invalid partition number for type '1'
Partition type
p primary partition (1-4)
e extended
p
Partition number (1-4): 1
First sector (16-7634943, default 16):
Using default value 16
Last sector or +size{,K,M,G,T} (16-7634943, default 7634943): +64M
Command (m for help): t
Selected partition 1
Hex code (type L to list codes): 6
Changed system type of partition 1 to 6 (FAT16)
Command (m for help): n
Partition type
p primary partition (1-4)
e extended
p
Partition number (1-4): 2
First sector (131088-7634943, default 131088):
Using default value 131088
Last sector or +size{,K,M,G,T} (131088-7634943, default 7634943): +1500M
Command (m for help): p
Disk /dev/mmcblk0: 3728 MB, 3909091328 bytes, 7634944 sectors
119296 cylinders, 4 heads, 16 sectors/track
Units: sectors of 1 * 512 = 512 bytes
Device Boot StartCHS EndCHS StartLBA EndLBA Sectors Size Id Type
/dev/mmcblk0p1 0,1,1 1023,3,16 16 131087 131072 64.0M 6 FAT16
/dev/mmcblk0p2 1023,3,16 1023,3,16 131088 3203087 3072000 1500M 83 Linux
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table
[ 44.720213] mmcblk0: p1 p2
#
# mkdir /tmp/ext
# mkfs.ext2 /dev/mmcblk0p2
mke2fs 1.45.5 (07-Jan-2020)
/dev/mmcblk0p2 contains a ext2 file system
last mounted on /tmp/ext on Thu Jan 1 00:02:16 1970
Proceed anyway? (y,N)
# mount -t ext2 /dev/mmcblk0p2 /tmp/ext
#
#
# echo "Hello_World: Welcome" > /tmp/ext/t6.txt
#
# cat /tmp/ext/t6.txt
Hello_World: Welcome
#
#
# umount /tmp/ext/
SD Card Interface testing:
# dmesg | grep mmc
[ 1.305841] mmc0: SDHCI controller on e0830000.sdio-host [e0830000.sdio-host] using ADMA
[ 1.459624] mmc0: new ultra high speed DDR50 SDHC card at address aaaa
[ 1.610121] mmcblk0: mmc0:aaaa SC32G 29.7 GiB
[ 1.683630] mmcblk0: p1 p2
#
#
# mount -t debugfs none /sys/kernel/debug/
# cat /sys/kernel/debug/mmc0/ios
clock: 50000000 Hz
actual clock: 50000000 Hz
vdd: 21 (3.3 ~ 3.4 V)
bus mode: 2 (push-pull)
chip select: 0 (don't care)
power mode: 2 (on)
bus width: 2 (4 bits)
timing spec: 7 (sd uhs DDR50)
signal voltage: 1 (1.80 V)
driver type: 0 (driver type B)
#
# ls -l /dev/mmc*
brw------- 1 root root 179, 0 Jan 1 00:00 /dev/mmcblk0
brw------- 1 root root 179, 1 Jan 1 00:00 /dev/mmcblk0p1
brw------- 1 root root 179, 2 Jan 1 00:00 /dev/mmcblk0p2
#
# cat /proc/interrupts | grep mmc
43: 89 GIC-0 98 Level mmc0
#
# dd if=/dev/zero of=/dev/mmcblk0 bs=10M count=1
1+0 records in
1+0 records out
# fdisk /dev/mmcblk0
Device contains neither a valid DOS partition table, nor Sun, SGI, OSF or GPT disklabel
Building a new DOS disklabel. Changes will remain in memory only,
until you decide to write them. After that the previous content
won't be recoverable.
The number of cylinders for this disk is set to 973968.
There is nothing wrong with that, but this is larger than 1024,
and could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of LILO)
2) booting and partitioning software from other OSs
(e.g., DOS FDISK, OS/2 FDISK)
Command (m for help): p
Disk /dev/mmcblk0: 30 GB, 31914983424 bytes, 62333952 sectors
973968 cylinders, 4 heads, 16 sectors/track
Units: sectors of 1 * 512 = 512 bytes
Device Boot StartCHS EndCHS StartLBA EndLBA Sectors Size Id Type
Command (m for help): n
Partition type
p primary partition (1-4)
e extended
p
Partition number (1-4): 1
First sector (16-62333951, default 16):
Using default value 16
Last sector or +size{,K,M,G,T} (16-62333951, default 62333951): +64M
Command (m for help): t
Selected partition 1
Hex code (type L to list codes): 6
Changed system type of partition 1 to 6 (FAT16)
Command (m for help): n
Partition type
p primary partition (1-4)
e extended
p
Partition number (1-4): 2
First sector (131088-62333951, default 131088):
Using default value 131088
Last sector or +size{,K,M,G,T} (131088-62333951, default 62333951): +1500M
Command (m for help): p
Disk /dev/mmcblk0: 30 GB, 31914983424 bytes, 62333952 sectors
973968 cylinders, 4 heads, 16 sectors/track
Units: sectors of 1 * 512 = 512 bytes
Device Boot StartCHS EndCHS StartLBA EndLBA Sectors Size Id Type
/dev/mmcblk0p1 0,1,1 1023,3,16 16 131087 131072 64.0M 6 FAT16
/dev/mmcblk0p2 1023,3,16 1023,3,16 131088 3203087 3072000 1500M 83 Linux
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table
[ 63.250316] mmcblk0: p1 p2
#
# ls -l /dev/mmc*
brw------- 1 root root 179, 0 Jan 1 00:01 /dev/mmcblk0
brw------- 1 root root 179, 1 Jan 1 00:01 /dev/mmcblk0p1
brw------- 1 root root 179, 2 Jan 1 00:01 /dev/mmcblk0p2
# mkdir /tmp/ext
# mount -t ext2 /dev/mmcblk0p2 /tmp/ext
#
# mkfs.ext2 /dev/mmcblk0p2
mke2fs 1.45.6 (20-Mar-2020)
/dev/mmcblk0p2 contains a ext2 file system
last mounted on /media/vishnu/842a0c11-7809-4b40-a98f-25bae7c7d16c on Thu Aug 5 11:23:26 2021
Proceed anyway? (y,N) y
Discarding device blocks: done
Creating filesystem with 384000 4k blocks and 96000 inodes
Filesystem UUID: b2dde0d3-5b02-458d-9893-07a876e5a6bf
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912
Allocating group tables: done
Writing inode tables: done
Writing superblocks and filesystem accounting information: done
#
#
#
#
# mkdir /tmp/ext
#
# mount -t ext2 /dev/mmcblk0p2 /tmp/ext
# ls -l /tmp/ext/
total 16
drwx------ 2 root root 16384 Jan 1 00:02 lost+found
#
#
#
# echo "3-9-2021: Testing SD card at HS 50Mhz" > /tmp/ext/t1.txt
#
#
#
# cat /tmp/ext/t1.txt
3-9-2021: Testing SD card at HS 50Mhz
#
#
# umount /tmp/ext/
- Note
-
Enable
e2fsprogsutility from buildroot to use ext2,ext3,ext4 filesystems.