blob: 0b6d2c53db742c1e443a976c48f84e2af517ac09 [file] [log] [blame]
Reinhard Meyerc718a562010-08-13 10:31:06 +02001How to use SD/MMC cards with Atmel SoCs having MCI hardware
2-----------------------------------------------------------
32010-08-16 Reinhard Meyer <reinhard.meyer@emk-elektronik.de>
4
5This is a new approach to use Atmel MCI hardware with the
6general MMC framework. Therefore it benefits from that
7framework's abilities to handle SDHC Cards and the ability
8to write blocks.
9
10- AT91SAM9XE512 (tested, will definitely work with XE128 and XE256)
11- AT91SAM9260 (not tested, but MCI is to AT91SAM9XE)
12- AT91SAM9G20 (not tested, should work)
13
Andy Shevchenko8cb5cdd2017-07-05 16:25:22 +030014It should work with all other ATMEL devices that have MCI.
Reinhard Meyerc718a562010-08-13 10:31:06 +020015
16The generic driver does NOT assign port pins to the MCI block
17nor does it start the MCI clock. This has to be handled in a
18board/SoC specific manner before the driver is initialized:
19
20example: this is added to at91sam9260_devices.c:
21
Sven Schnelle69df6de2011-10-21 14:49:26 +020022#if defined(CONFIG_GENERIC_ATMEL_MCI)
Reinhard Meyerc718a562010-08-13 10:31:06 +020023void at91_mci_hw_init(void)
24{
25 at91_set_a_periph(AT91_PIO_PORTA, 8, PUP); /* MCCK */
26#if defined(CONFIG_ATMEL_MCI_PORTB)
27 at91_set_b_periph(AT91_PIO_PORTA, 1, PUP); /* MCCDB */
28 at91_set_b_periph(AT91_PIO_PORTA, 0, PUP); /* MCDB0 */
29 at91_set_b_periph(AT91_PIO_PORTA, 5, PUP); /* MCDB1 */
30 at91_set_b_periph(AT91_PIO_PORTA, 4, PUP); /* MCDB2 */
31 at91_set_b_periph(AT91_PIO_PORTA, 3, PUP); /* MCDB3 */
32#else
33 at91_set_a_periph(AT91_PIO_PORTA, 7, PUP); /* MCCDA */
34 at91_set_a_periph(AT91_PIO_PORTA, 6, PUP); /* MCDA0 */
35 at91_set_a_periph(AT91_PIO_PORTA, 9, PUP); /* MCDA1 */
36 at91_set_a_periph(AT91_PIO_PORTA, 10, PUP); /* MCDA2 */
37 at91_set_a_periph(AT91_PIO_PORTA, 11, PUP); /* MCDA3 */
38#endif
39}
40#endif
41
42the board specific file need added:
43...
44#ifdef CONFIG_GENERIC_ATMEL_MCI
45# include <mmc.h>
46#endif
47...
48#ifdef CONFIG_GENERIC_ATMEL_MCI
49/* this is a weak define that we are overriding */
Masahiro Yamada940a9222020-06-26 15:13:34 +090050int board_mmc_init(struct bd_info *bd)
Reinhard Meyerc718a562010-08-13 10:31:06 +020051{
52 /* Enable clock */
53 at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9260_ID_MCI);
54 at91_mci_hw_init();
55
56 /* This calls the atmel_mci_init in gen_atmel_mci.c */
57 return atmel_mci_init((void *)AT91_BASE_MCI);
58}
59
60/* this is a weak define that we are overriding */
Thierry Redingd7aebf42012-01-02 01:15:36 +000061int board_mmc_getcd(struct mmc *mmc)
Reinhard Meyerc718a562010-08-13 10:31:06 +020062{
Tom Rini6a5dccc2022-11-16 13:10:41 -050063 return !at91_get_gpio_value(CFG_SYS_MMC_CD_PIN);
Reinhard Meyerc718a562010-08-13 10:31:06 +020064}
65
66#endif
67
68and the board definition files needs:
69
70/* SD/MMC card */
Reinhard Meyerc718a562010-08-13 10:31:06 +020071#define CONFIG_GENERIC_ATMEL_MCI 1
72#define CONFIG_ATMEL_MCI_PORTB 1 /* Atmel XE-EK uses port B */
Tom Rini6a5dccc2022-11-16 13:10:41 -050073#define CFG_SYS_MMC_CD_PIN AT91_PIN_PC9
Reinhard Meyerc718a562010-08-13 10:31:06 +020074#define CONFIG_CMD_MMC 1