xref: /openbmc/u-boot/doc/README.atmel_mci (revision 1592ef85)
1*1592ef85SReinhard MeyerHow to use SD/MMC cards with Atmel SoCs having MCI hardware
2*1592ef85SReinhard Meyer-----------------------------------------------------------
3*1592ef85SReinhard Meyer2010-08-16 Reinhard Meyer <reinhard.meyer@emk-elektronik.de>
4*1592ef85SReinhard Meyer
5*1592ef85SReinhard MeyerThis is a new approach to use Atmel MCI hardware with the
6*1592ef85SReinhard Meyergeneral MMC framework. Therefore it benefits from that
7*1592ef85SReinhard Meyerframework's abilities to handle SDHC Cards and the ability
8*1592ef85SReinhard Meyerto write blocks.
9*1592ef85SReinhard Meyer
10*1592ef85SReinhard Meyer- AT91SAM9XE512 (tested, will definitely work with XE128 and XE256)
11*1592ef85SReinhard Meyer- AT91SAM9260 (not tested, but MCI is to AT91SAM9XE)
12*1592ef85SReinhard Meyer- AT91SAM9G20 (not tested, should work)
13*1592ef85SReinhard Meyer
14*1592ef85SReinhard MeyerIt should work with all other ATMEL devices that have MCI,
15*1592ef85SReinhard Meyerincluding AVR32.
16*1592ef85SReinhard Meyer
17*1592ef85SReinhard MeyerThe generic driver does NOT assign port pins to the MCI block
18*1592ef85SReinhard Meyernor does it start the MCI clock. This has to be handled in a
19*1592ef85SReinhard Meyerboard/SoC specific manner before the driver is initialized:
20*1592ef85SReinhard Meyer
21*1592ef85SReinhard Meyerexample: this is added to at91sam9260_devices.c:
22*1592ef85SReinhard Meyer
23*1592ef85SReinhard Meyer#if defined(CONFIG_ATMEL_MCI) || defined(CONFIG_GENERIC_ATMEL_MCI)
24*1592ef85SReinhard Meyervoid at91_mci_hw_init(void)
25*1592ef85SReinhard Meyer{
26*1592ef85SReinhard Meyer	at91_set_a_periph(AT91_PIO_PORTA, 8, PUP);	/* MCCK */
27*1592ef85SReinhard Meyer#if defined(CONFIG_ATMEL_MCI_PORTB)
28*1592ef85SReinhard Meyer	at91_set_b_periph(AT91_PIO_PORTA, 1, PUP);	/* MCCDB */
29*1592ef85SReinhard Meyer	at91_set_b_periph(AT91_PIO_PORTA, 0, PUP);	/* MCDB0 */
30*1592ef85SReinhard Meyer	at91_set_b_periph(AT91_PIO_PORTA, 5, PUP);	/* MCDB1 */
31*1592ef85SReinhard Meyer	at91_set_b_periph(AT91_PIO_PORTA, 4, PUP);	/* MCDB2 */
32*1592ef85SReinhard Meyer	at91_set_b_periph(AT91_PIO_PORTA, 3, PUP);	/* MCDB3 */
33*1592ef85SReinhard Meyer#else
34*1592ef85SReinhard Meyer	at91_set_a_periph(AT91_PIO_PORTA, 7, PUP);	/* MCCDA */
35*1592ef85SReinhard Meyer	at91_set_a_periph(AT91_PIO_PORTA, 6, PUP);	/* MCDA0 */
36*1592ef85SReinhard Meyer	at91_set_a_periph(AT91_PIO_PORTA, 9, PUP);	/* MCDA1 */
37*1592ef85SReinhard Meyer	at91_set_a_periph(AT91_PIO_PORTA, 10, PUP);	/* MCDA2 */
38*1592ef85SReinhard Meyer	at91_set_a_periph(AT91_PIO_PORTA, 11, PUP);	/* MCDA3 */
39*1592ef85SReinhard Meyer#endif
40*1592ef85SReinhard Meyer}
41*1592ef85SReinhard Meyer#endif
42*1592ef85SReinhard Meyer
43*1592ef85SReinhard Meyerthe board specific file need added:
44*1592ef85SReinhard Meyer...
45*1592ef85SReinhard Meyer#ifdef CONFIG_GENERIC_ATMEL_MCI
46*1592ef85SReinhard Meyer# include <mmc.h>
47*1592ef85SReinhard Meyer#endif
48*1592ef85SReinhard Meyer...
49*1592ef85SReinhard Meyer#ifdef CONFIG_GENERIC_ATMEL_MCI
50*1592ef85SReinhard Meyer/* this is a weak define that we are overriding */
51*1592ef85SReinhard Meyerint board_mmc_init(bd_t *bd)
52*1592ef85SReinhard Meyer{
53*1592ef85SReinhard Meyer	/* Enable clock */
54*1592ef85SReinhard Meyer	at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9260_ID_MCI);
55*1592ef85SReinhard Meyer	at91_mci_hw_init();
56*1592ef85SReinhard Meyer
57*1592ef85SReinhard Meyer	/* This calls the atmel_mci_init in gen_atmel_mci.c */
58*1592ef85SReinhard Meyer	return atmel_mci_init((void *)AT91_BASE_MCI);
59*1592ef85SReinhard Meyer}
60*1592ef85SReinhard Meyer
61*1592ef85SReinhard Meyer/* this is a weak define that we are overriding */
62*1592ef85SReinhard Meyerint board_mmc_getcd(u8 *cd, struct mmc *mmc)
63*1592ef85SReinhard Meyer{
64*1592ef85SReinhard Meyer	/*
65*1592ef85SReinhard Meyer	 * the only currently existing use of this function
66*1592ef85SReinhard Meyer	 * (fsl_esdhc.c) suggests this function must return
67*1592ef85SReinhard Meyer	 * *cs = TRUE if a card is NOT detected -> in most
68*1592ef85SReinhard Meyer	 * cases the value of the pin when the detect switch
69*1592ef85SReinhard Meyer	 * closes to GND
70*1592ef85SReinhard Meyer	 */
71*1592ef85SReinhard Meyer	*cd = at91_get_gpio_value (CONFIG_SYS_MMC_CD_PIN) ? 1 : 0;
72*1592ef85SReinhard Meyer	return 0;
73*1592ef85SReinhard Meyer}
74*1592ef85SReinhard Meyer
75*1592ef85SReinhard Meyer#endif
76*1592ef85SReinhard Meyer
77*1592ef85SReinhard Meyerand the board definition files needs:
78*1592ef85SReinhard Meyer
79*1592ef85SReinhard Meyer/* SD/MMC card */
80*1592ef85SReinhard Meyer#define CONFIG_MMC			1
81*1592ef85SReinhard Meyer#define CONFIG_GENERIC_MMC		1
82*1592ef85SReinhard Meyer#define CONFIG_GENERIC_ATMEL_MCI	1
83*1592ef85SReinhard Meyer#define CONFIG_ATMEL_MCI_PORTB		1	/* Atmel XE-EK uses port B */
84*1592ef85SReinhard Meyer#define CONFIG_SYS_MMC_CD_PIN		AT91_PIN_PC9
85*1592ef85SReinhard Meyer#define CONFIG_CMD_MMC			1
86*1592ef85SReinhard Meyer
87