AT91: MCI: add SD/MMC driver using mmc framework
[oweals/u-boot.git] / doc / README.atmel_mci
diff --git a/doc/README.atmel_mci b/doc/README.atmel_mci
new file mode 100644 (file)
index 0000000..18b1bdf
--- /dev/null
@@ -0,0 +1,86 @@
+How to use SD/MMC cards with Atmel SoCs having MCI hardware
+-----------------------------------------------------------
+2010-08-16 Reinhard Meyer <reinhard.meyer@emk-elektronik.de>
+
+This is a new approach to use Atmel MCI hardware with the
+general MMC framework. Therefore it benefits from that
+framework's abilities to handle SDHC Cards and the ability
+to write blocks.
+
+- AT91SAM9XE512 (tested, will definitely work with XE128 and XE256)
+- AT91SAM9260 (not tested, but MCI is to AT91SAM9XE)
+- AT91SAM9G20 (not tested, should work)
+
+It should work with all other ATMEL devices that have MCI,
+including AVR32.
+
+The generic driver does NOT assign port pins to the MCI block
+nor does it start the MCI clock. This has to be handled in a
+board/SoC specific manner before the driver is initialized:
+
+example: this is added to at91sam9260_devices.c:
+
+#if defined(CONFIG_ATMEL_MCI) || defined(CONFIG_GENERIC_ATMEL_MCI)
+void at91_mci_hw_init(void)
+{
+       at91_set_a_periph(AT91_PIO_PORTA, 8, PUP);      /* MCCK */
+#if defined(CONFIG_ATMEL_MCI_PORTB)
+       at91_set_b_periph(AT91_PIO_PORTA, 1, PUP);      /* MCCDB */
+       at91_set_b_periph(AT91_PIO_PORTA, 0, PUP);      /* MCDB0 */
+       at91_set_b_periph(AT91_PIO_PORTA, 5, PUP);      /* MCDB1 */
+       at91_set_b_periph(AT91_PIO_PORTA, 4, PUP);      /* MCDB2 */
+       at91_set_b_periph(AT91_PIO_PORTA, 3, PUP);      /* MCDB3 */
+#else
+       at91_set_a_periph(AT91_PIO_PORTA, 7, PUP);      /* MCCDA */
+       at91_set_a_periph(AT91_PIO_PORTA, 6, PUP);      /* MCDA0 */
+       at91_set_a_periph(AT91_PIO_PORTA, 9, PUP);      /* MCDA1 */
+       at91_set_a_periph(AT91_PIO_PORTA, 10, PUP);     /* MCDA2 */
+       at91_set_a_periph(AT91_PIO_PORTA, 11, PUP);     /* MCDA3 */
+#endif
+}
+#endif
+
+the board specific file need added:
+...
+#ifdef CONFIG_GENERIC_ATMEL_MCI
+# include <mmc.h>
+#endif
+...
+#ifdef CONFIG_GENERIC_ATMEL_MCI
+/* this is a weak define that we are overriding */
+int board_mmc_init(bd_t *bd)
+{
+       /* Enable clock */
+       at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9260_ID_MCI);
+       at91_mci_hw_init();
+
+       /* This calls the atmel_mci_init in gen_atmel_mci.c */
+       return atmel_mci_init((void *)AT91_BASE_MCI);
+}
+
+/* this is a weak define that we are overriding */
+int board_mmc_getcd(u8 *cd, struct mmc *mmc)
+{
+       /*
+        * the only currently existing use of this function
+        * (fsl_esdhc.c) suggests this function must return
+        * *cs = TRUE if a card is NOT detected -> in most
+        * cases the value of the pin when the detect switch
+        * closes to GND
+        */
+       *cd = at91_get_gpio_value (CONFIG_SYS_MMC_CD_PIN) ? 1 : 0;
+       return 0;
+}
+
+#endif
+
+and the board definition files needs:
+
+/* SD/MMC card */
+#define CONFIG_MMC                     1
+#define CONFIG_GENERIC_MMC             1
+#define CONFIG_GENERIC_ATMEL_MCI       1
+#define CONFIG_ATMEL_MCI_PORTB         1       /* Atmel XE-EK uses port B */
+#define CONFIG_SYS_MMC_CD_PIN          AT91_PIN_PC9
+#define CONFIG_CMD_MMC                 1
+