LAN969x SDMMC

1. LAN969x SDMMC

1.1. SoC Resources

LAN969x SDMMC controller supports the embedded Multimedia Card (e.MMC) Specification (v5.01) and the SD Memory Card(v3.0).

LAN969x has two SDMMC controller instances.

SDMMC controller 0 can operate in 4bit or 8bit wide bus mode, and controller 1 can operate in 4 bit mode.

It is only possible t use both controllers at the same time if they are both configured for 4bit wide mode as some of the pins would overlap otherwise.

1.2. Kernel configurations

Following kernel config options should be enabled to use LAN969x 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.

1.3. Devicetree Configuration

To use SDMMC interface, following configurations are required in device tree.

  • reg property must be set with register address and length. Refer table below:

FLEXCOM ID

Flexcom base registers map

sdmmc0

<0xe0830000 0x00000300>

sdmmc1

<0xe0838000 0x00000300>

  • compatible string must be set to microchip,lan966x-sdhci.

  • pinctrl-0 property 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_pins includes CMD, CLK, D0, D1, D2, D3, RSTN pins for both SD and eMMC, sdmmc_pins includes VSEL, WP, CD, LED pins for SD interface only and emmc_pins includes D4, D5, D6, D7 pins for eMMC interface only. sdmmc_pins and emmc_pins pin 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

GPIO14

GPIO15

GPIO16

GPIO17

GPIO18

GPIO19

GPIO24

pinctrl node DT Func VSEL pin WP pin CD pin LED pin

sdmmc_pins

sd

GPIO20

GPIO21

GPIO22

GPIO23

pinctrl node DT Func D4 D5 D6 D7

emmc_pins

emmc

GPIO20

GPIO21

GPIO22

GPIO23

  • interrupts property 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

96

64

sdmmc1

82

50

Note

Shared peripheral interrupt lines start at index ID32. So, CPU INTR must be calculated as [Shared peripheral interrupt number - 32].

  • Input clock clocks property must be set to GCK clock using phandle and GCK ID as <&clk GCK_ID_SDMMC0>.

  • clock-names must be set to hclock and multclk

  • assigned-clocks must be set to <&clks GCK_ID_SDMMC0>.

  • assigned-clock-rates must be set to 45Mhz.

Note

While operating as eMMC interface, tx-phase property must be set to zero. Possible phase shift values are 0 for 180degrees, c for 90 degrees, 4 for 270 degrees, 8 for 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.

1.3.2. Example

Following example shows how a 8bit bus eMMC should be defined in DT:

dtsi file:

sdmmc0: sdhci-host@e0830000 {
	compatible = "microchip,lan966x-sdhci";
	reg = <0xe0830000 0x00000300>;
	interrupts = <GIC_SPI 64 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:

&gpio {
	emmc_sd_pins: emmc-sd-pins {
		/* eMMC_SD - CMD, CLK, D0, D1, D2, D3, D4, D5, D6, D7, RSTN */
		pins = "GPIO_14", "GPIO_15", "GPIO_16", "GPIO_17",
		       "GPIO_18", "GPIO_19", "GPIO_20", "GPIO_21",
		       "GPIO_22", "GPIO_23", "GPIO_24";
		function = "emmc_sd";
	};
};

&sdmmc0 {
	pinctrl-0 = <&emmc_sd_pins>;
	pinctrl-names = "default";
	max-frequency = <100000000>;
	bus-width = <8>;
	non-removable;
	no-1-8-v;
	disable-wp;
	status = "okay";
};

1.4. UserSpace

1.4.1. Confirm instances are created

To confirm if mmc device is created:

  • Check if a mmc device is created in /dev directory.

  • To check card details, mount debugfs using command mount -t debugfs none /sys/kernel/debug/ and then use command cat /sys/kernel/debug/mmc0/ios to get IOs debugging information.

1.4.2. 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
brw-------    1 root     root      179,   1 Jan  1 00:00 /dev/mmcblk0p1
brw-------    1 root     root      179,   2 Jan  1 00:00 /dev/mmcblk0p2
brw-------    1 root     root      179,   3 Jan  1 00:00 /dev/mmcblk0p3
brw-------    1 root     root      179,   4 Jan  1 00:00 /dev/mmcblk0p4
brw-------    1 root     root      179,   5 Jan  1 00:00 /dev/mmcblk0p5
brw-------    1 root     root      179,   6 Jan  1 00:00 /dev/mmcblk0p6
brw-------    1 root     root      179,   7 Jan  1 00:00 /dev/mmcblk0p7
crw-------    1 root     root      247,   0 Jan  1 00:00 /dev/mmcblk0rpmb
# dmesg | grep mmc
[    0.000000] Kernel command line: console=ttyAT0,115200 root=/dev/mmcblk0p5 noinitrd rootwait rw loglevel=9 uio_pdrv_genirq.of_id=generic-uio
[    2.396863] mmc0: SDHCI controller on e0830000.sdhci-host [e0830000.sdhci-host] using ADMA
[    2.534391] Waiting for root device /dev/mmcblk0p5...
[    2.537072] mmc0: new high speed MMC card at address 0001
[    2.542775] mmcblk0: mmc0:0001 eMMC   3.63 GiB
[    2.550291]  mmcblk0: p1 p2 p3 p4 p5 p6 p7
[    2.552831] mmcblk0boot0: mmc0:0001 eMMC   16.0 MiB
[    2.557425] mmcblk0boot1: mmc0:0001 eMMC   16.0 MiB
[    2.562100] mmcblk0rpmb: mmc0:0001 eMMC   512 KiB, chardev (247:0)
[    2.620999] EXT4-fs (mmcblk0p5): recovery complete
[    2.623655] EXT4-fs (mmcblk0p5): mounted filesystem with ordered data mode. Quota mode: disabled.
[    2.738213] EXT4-fs (mmcblk0p5): re-mounted. Quota mode: disabled.
# mount -t debugfs none /sys/kernel/debug/
# cat /sys/kernel/debug/mmc0/ios
clock:          44000000 Hz
actual clock:   44000000 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/
Note

Enable e2fsprogs utility from buildroot to use ext2,ext3,ext4 filesystems.