blob: dee0cf0a9b3d0230538b0b5692f9135edf676d7b [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
14It should work with all other ATMEL devices that have MCI,
15including AVR32.
16
17The generic driver does NOT assign port pins to the MCI block
18nor does it start the MCI clock. This has to be handled in a
19board/SoC specific manner before the driver is initialized:
20
21example: this is added to at91sam9260_devices.c:
22
23#if defined(CONFIG_ATMEL_MCI) || defined(CONFIG_GENERIC_ATMEL_MCI)
24void at91_mci_hw_init(void)
25{
26 at91_set_a_periph(AT91_PIO_PORTA, 8, PUP); /* MCCK */
27#if defined(CONFIG_ATMEL_MCI_PORTB)
28 at91_set_b_periph(AT91_PIO_PORTA, 1, PUP); /* MCCDB */
29 at91_set_b_periph(AT91_PIO_PORTA, 0, PUP); /* MCDB0 */
30 at91_set_b_periph(AT91_PIO_PORTA, 5, PUP); /* MCDB1 */
31 at91_set_b_periph(AT91_PIO_PORTA, 4, PUP); /* MCDB2 */
32 at91_set_b_periph(AT91_PIO_PORTA, 3, PUP); /* MCDB3 */
33#else
34 at91_set_a_periph(AT91_PIO_PORTA, 7, PUP); /* MCCDA */
35 at91_set_a_periph(AT91_PIO_PORTA, 6, PUP); /* MCDA0 */
36 at91_set_a_periph(AT91_PIO_PORTA, 9, PUP); /* MCDA1 */
37 at91_set_a_periph(AT91_PIO_PORTA, 10, PUP); /* MCDA2 */
38 at91_set_a_periph(AT91_PIO_PORTA, 11, PUP); /* MCDA3 */
39#endif
40}
41#endif
42
43the board specific file need added:
44...
45#ifdef CONFIG_GENERIC_ATMEL_MCI
46# include <mmc.h>
47#endif
48...
49#ifdef CONFIG_GENERIC_ATMEL_MCI
50/* this is a weak define that we are overriding */
51int board_mmc_init(bd_t *bd)
52{
53 /* Enable clock */
54 at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9260_ID_MCI);
55 at91_mci_hw_init();
56
57 /* This calls the atmel_mci_init in gen_atmel_mci.c */
58 return atmel_mci_init((void *)AT91_BASE_MCI);
59}
60
61/* this is a weak define that we are overriding */
62int board_mmc_getcd(u8 *cd, struct mmc *mmc)
63{
64 /*
65 * the only currently existing use of this function
66 * (fsl_esdhc.c) suggests this function must return
67 * *cs = TRUE if a card is NOT detected -> in most
68 * cases the value of the pin when the detect switch
69 * closes to GND
70 */
71 *cd = at91_get_gpio_value (CONFIG_SYS_MMC_CD_PIN) ? 1 : 0;
72 return 0;
73}
74
75#endif
76
77and the board definition files needs:
78
79/* SD/MMC card */
80#define CONFIG_MMC 1
81#define CONFIG_GENERIC_MMC 1
82#define CONFIG_GENERIC_ATMEL_MCI 1
83#define CONFIG_ATMEL_MCI_PORTB 1 /* Atmel XE-EK uses port B */
84#define CONFIG_SYS_MMC_CD_PIN AT91_PIN_PC9
85#define CONFIG_CMD_MMC 1