* [PATCH 1/6] atmel-mci: Unified Atmel MCI drivers (AVR32 & AT91)
@ 2009-06-17 0:54 Rob Emanuele
2009-06-17 0:54 ` [PATCH 2/6] atmel-mci: Platform configuration to the the atmel-mci driver Rob Emanuele
` (6 more replies)
0 siblings, 7 replies; 21+ messages in thread
From: Rob Emanuele @ 2009-06-17 0:54 UTC (permalink / raw)
To: nicolas.ferre
Cc: haavard.skinnemoen, linux-arm-kernel, linux-kernel, Rob Emanuele
Unification of the atmel-mci driver to support the AT91 processors MCI interface. The atmel-mci driver currently supports the AVR32 and this patch adds AT91 support.
To use this new driver on a at91 the platform driver for your board needs to updated. See the following patch for an example of how to do that.
Signed-off-by: Rob Emanuele <rob@emanuele.us>
---
drivers/mmc/host/Kconfig | 16 ++++++++++++----
drivers/mmc/host/atmel-mci.c | 37 +++++++++++++++++++++++++++++++++----
2 files changed, 45 insertions(+), 8 deletions(-)
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 40111a6..a0eaf69 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -135,6 +135,12 @@ config MMC_AU1X
If unsure, say N.
+choice
+ prompt "Atmel MMC Driver"
+ default MMC_ATMELMCI if AVR32
+ help
+ Choose which driver to use for the Atmel MCI Silicon
+
config MMC_AT91
tristate "AT91 SD/MMC Card Interface support"
depends on ARCH_AT91
@@ -145,17 +151,19 @@ config MMC_AT91
config MMC_ATMELMCI
tristate "Atmel Multimedia Card Interface support"
- depends on AVR32
+ depends on AVR32 || ARCH_AT91
help
This selects the Atmel Multimedia Card Interface driver. If
- you have an AT32 (AVR32) platform with a Multimedia Card
- slot, say Y or M here.
+ you have an AT32 (AVR32) or AT91 platform with a Multimedia
+ Card slot, say Y or M here.
If unsure, say N.
+endchoice
+
config MMC_ATMELMCI_DMA
bool "Atmel MCI DMA support (EXPERIMENTAL)"
- depends on MMC_ATMELMCI && DMA_ENGINE && EXPERIMENTAL
+ depends on MMC_ATMELMCI && AVR32 && DMA_ENGINE && EXPERIMENTAL
help
Say Y here to have the Atmel MCI driver use a DMA engine to
do data transfers and thus increase the throughput and
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index 7b603e4..98b25de 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -30,11 +30,14 @@
#include <asm/io.h>
#include <asm/unaligned.h>
+#include <mach/cpu.h>
#include <mach/board.h>
#include "atmel-mci-regs.h"
-#define ATMCI_DATA_ERROR_FLAGS (MCI_DCRCE | MCI_DTOE | MCI_OVRE | MCI_UNRE)
+#define ATMCI_DATA_ERROR_FLAGS (MCI_RINDE | MCI_RDIRE | MCI_RCRCE \
+ | MCI_RENDE | MCI_RTOE | MCI_DCRCE \
+ | MCI_DTOE | MCI_OVRE | MCI_UNRE)
#define ATMCI_DMA_THRESHOLD 16
enum {
@@ -210,6 +213,18 @@ struct atmel_mci_slot {
set_bit(event, &host->pending_events)
/*
+ * Enable or disable features/registers based on
+ * whether the processor supports them
+ */
+static bool mci_has_rwproof(void)
+{
+ if (cpu_is_at91sam9261() || cpu_is_at91rm9200())
+ return false;
+ else
+ return true;
+}
+
+/*
* The debugfs stuff below is mostly optimized away when
* CONFIG_DEBUG_FS is not set.
*/
@@ -276,8 +291,13 @@ static void atmci_show_status_reg(struct seq_file *s,
[3] = "BLKE",
[4] = "DTIP",
[5] = "NOTBUSY",
+ [6] = "ENDRX",
+ [7] = "ENDTX",
[8] = "SDIOIRQA",
[9] = "SDIOIRQB",
+ [12] = "SDIOWAIT",
+ [14] = "RXBUFF",
+ [15] = "TXBUFE",
[16] = "RINDE",
[17] = "RDIRE",
[18] = "RCRCE",
@@ -285,6 +305,11 @@ static void atmci_show_status_reg(struct seq_file *s,
[20] = "RTOE",
[21] = "DCRCE",
[22] = "DTOE",
+ [23] = "CSTOE",
+ [24] = "BLKOVRE",
+ [25] = "DMADONE",
+ [26] = "FIFOEMPTY",
+ [27] = "XFRDONE",
[30] = "OVRE",
[31] = "UNRE",
};
@@ -849,13 +874,15 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
clkdiv = 255;
}
+ host->mode_reg = MCI_MR_CLKDIV(clkdiv);
+
/*
* WRPROOF and RDPROOF prevent overruns/underruns by
* stopping the clock when the FIFO is full/empty.
* This state is not expected to last for long.
*/
- host->mode_reg = MCI_MR_CLKDIV(clkdiv) | MCI_MR_WRPROOF
- | MCI_MR_RDPROOF;
+ if (mci_has_rwproof())
+ host->mode_reg |= (MCI_MR_WRPROOF | MCI_MR_RDPROOF);
if (list_empty(&host->queue))
mci_writel(host, MR, host->mode_reg);
@@ -1648,8 +1675,10 @@ static int __init atmci_probe(struct platform_device *pdev)
nr_slots++;
}
- if (!nr_slots)
+ if (!nr_slots) {
+ printk(KERN_ERR "Atmel MCI controller init failed. atmci_init_slot error or no slots with bus_width > 0.\n");
goto err_init_slot;
+ }
dev_info(&pdev->dev,
"Atmel MCI controller at 0x%08lx irq %d, %u slots\n",
--
1.6.0.4
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH 2/6] atmel-mci: Platform configuration to the the atmel-mci driver 2009-06-17 0:54 [PATCH 1/6] atmel-mci: Unified Atmel MCI drivers (AVR32 & AT91) Rob Emanuele @ 2009-06-17 0:54 ` Rob Emanuele 2009-06-17 10:27 ` Nicolas Ferre 2009-06-18 19:58 ` Andrew Victor 2009-06-17 0:54 ` [PATCH 3/6] atmel-mci: Optional controller reset before every command Rob Emanuele ` (5 subsequent siblings) 6 siblings, 2 replies; 21+ messages in thread From: Rob Emanuele @ 2009-06-17 0:54 UTC (permalink / raw) To: nicolas.ferre Cc: haavard.skinnemoen, linux-arm-kernel, linux-kernel, Rob Emanuele Created a modified version of the at91sam9g20 evaluation kit platform (board-sam9g20ek-2slot-mmc.c) and device support to make use of the updated atmel-mci driver. This patch shows how an AT91 developer could add support for both SD slots for their project. This requires getting the most updated arch/arm/tools/mach-types from http://www.arm.linux.org.uk/developer/machines/download.php to have the machine type for the modified at91sam9g20ek. Signed-off-by: Rob Emanuele <rob@emanuele.us> --- arch/arm/mach-at91/Kconfig | 7 + arch/arm/mach-at91/Makefile | 1 + arch/arm/mach-at91/at91sam9260_devices.c | 95 ++++++++ arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c | 277 ++++++++++++++++++++++++ arch/arm/mach-at91/include/mach/board.h | 5 + 5 files changed, 385 insertions(+), 0 deletions(-) create mode 100644 arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 323b47f..5c8d770 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -276,6 +276,13 @@ config MACH_AT91SAM9G20EK help Select this if you are using Atmel's AT91SAM9G20-EK Evaluation Kit. +config MACH_AT91SAM9G20EK_2MMC + bool "Atmel AT91SAM9G20-EK Evaluation Kit modified for 2 MMC Slots" + depends on ARCH_AT91SAM9G20 + help + Select this if you are using an Atmel AT91SAM9G20-EK Evaluation Kit + Rev A or B modified for 2 MMC Slots. + endif # ---------------------------------------------------------- diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index c69ff23..cdddba8 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile @@ -54,6 +54,7 @@ obj-$(CONFIG_MACH_AT91SAM9RLEK) += board-sam9rlek.o # AT91SAM9G20 board-specific support obj-$(CONFIG_MACH_AT91SAM9G20EK) += board-sam9g20ek.o +obj-$(CONFIG_MACH_AT91SAM9G20EK_2MMC) += board-sam9g20ek-2slot-mmc.o # AT91CAP9 board-specific support obj-$(CONFIG_MACH_AT91CAP9ADK) += board-cap9adk.o diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index d74c9ac..c372f4f 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c @@ -278,6 +278,101 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {} #endif +/* -------------------------------------------------------------------- + * MMC / SD Slot for Atmel MCI Driver + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE) +static u64 mmc_dmamask = DMA_BIT_MASK(32); +static struct mci_platform_data mmc_data; + +static struct resource mmc_resources[] = { + [0] = { + .start = AT91SAM9260_BASE_MCI, + .end = AT91SAM9260_BASE_MCI + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_MCI, + .end = AT91SAM9260_ID_MCI, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9260_mmc_device = { + .name = "atmel_mci", + .id = -1, + .dev = { + .dma_mask = &mmc_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &mmc_data, + }, + .resource = mmc_resources, + .num_resources = ARRAY_SIZE(mmc_resources), +}; + +void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data) +{ + unsigned int i; + unsigned int slot_count = 0; + + if (!data) + return; + + for (i = 0; i < ATMEL_MCI_MAX_NR_SLOTS; i++) { + if (data->slot[i].bus_width) { + /* input/irq */ + if (data->slot[i].detect_pin) { + at91_set_gpio_input(data->slot[i].detect_pin, 1); + at91_set_deglitch(data->slot[i].detect_pin, 1); + } + if (data->slot[i].wp_pin) + at91_set_gpio_input(data->slot[i].wp_pin, 1); + + switch(i) { + case 0: + /* CMD */ + at91_set_A_periph(AT91_PIN_PA7, 1); + /* DAT0, maybe DAT1..DAT3 */ + at91_set_A_periph(AT91_PIN_PA6, 1); + if (data->slot[i].bus_width == 4) { + at91_set_A_periph(AT91_PIN_PA9, 1); + at91_set_A_periph(AT91_PIN_PA10, 1); + at91_set_A_periph(AT91_PIN_PA11, 1); + } + break; + case 1: + /* CMD */ + at91_set_B_periph(AT91_PIN_PA1, 1); + /* DAT0, maybe DAT1..DAT3 */ + at91_set_B_periph(AT91_PIN_PA0, 1); + if (data->slot[i].bus_width == 4) { + at91_set_B_periph(AT91_PIN_PA5, 1); + at91_set_B_periph(AT91_PIN_PA4, 1); + at91_set_B_periph(AT91_PIN_PA3, 1); + } + break; + default: + printk("Configuration Error, No MMC Port %d\n",i); + break; + }; + slot_count++; + } + } + + if (slot_count) { + /* CLK */ + at91_set_A_periph(AT91_PIN_PA8, 0); + + mmc_data = *data; + platform_device_register(&at91sam9260_mmc_device); + } +} +#else +void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data) {} +#endif + + /* -------------------------------------------------------------------- * NAND / SmartMedia diff --git a/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c b/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c new file mode 100644 index 0000000..a28e53f --- /dev/null +++ b/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c @@ -0,0 +1,277 @@ +/* + * Copyright (C) 2005 SAN People + * Copyright (C) 2008 Atmel + * Copyright (C) 2009 Rob Emanuele + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/types.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/spi/spi.h> +#include <linux/spi/at73c213.h> +#include <linux/clk.h> + +#include <mach/hardware.h> +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/irq.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <mach/board.h> +#include <mach/gpio.h> +#include <mach/at91sam9_smc.h> + +#include "sam9_smc.h" +#include "generic.h" + + +static void __init ek_map_io(void) +{ + /* Initialize processor: 18.432 MHz crystal */ + at91sam9260_initialize(18432000); + + /* DGBU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ + at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS + | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD + | ATMEL_UART_RI); + + /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */ + at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); +} + +static void __init ek_init_irq(void) +{ + at91sam9260_init_interrupts(NULL); +} + + +/* + * USB Host port + */ +static struct at91_usbh_data __initdata ek_usbh_data = { + .ports = 2, +}; + +/* + * USB Device port + */ +static struct at91_udc_data __initdata ek_udc_data = { + .vbus_pin = AT91_PIN_PC5, + .pullup_pin = 0, /* pull-up driven by UDC */ +}; + + +/* + * SPI devices. + */ +static struct spi_board_info ek_spi_devices[] = { +#if !defined(CONFIG_MMC_ATMELMCI) + { /* DataFlash chip */ + .modalias = "mtd_dataflash", + .chip_select = 1, + .max_speed_hz = 15 * 1000 * 1000, + .bus_num = 0, + }, +#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD) + { /* DataFlash card */ + .modalias = "mtd_dataflash", + .chip_select = 0, + .max_speed_hz = 15 * 1000 * 1000, + .bus_num = 0, + }, +#endif +#endif +}; + + +/* + * MACB Ethernet device + */ +static struct at91_eth_data __initdata ek_macb_data = { + .phy_irq_pin = AT91_PIN_PC12, + .is_rmii = 1, +}; + + +/* + * NAND flash + */ +static struct mtd_partition __initdata ek_nand_partition[] = { + { + .name = "Bootstrap", + .offset = 0, + .size = 4 * SZ_1M, + }, + { + .name = "Partition 1", + .offset = MTDPART_OFS_NXTBLK, + .size = 60 * SZ_1M, + }, + { + .name = "Partition 2", + .offset = MTDPART_OFS_NXTBLK, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct mtd_partition * __init nand_partitions(int size, int *num_partitions) +{ + *num_partitions = ARRAY_SIZE(ek_nand_partition); + return ek_nand_partition; +} + +/* det_pin is not connected */ +static struct atmel_nand_data __initdata ek_nand_data = { + .ale = 21, + .cle = 22, + .rdy_pin = AT91_PIN_PC13, + .enable_pin = AT91_PIN_PC14, + .partition_info = nand_partitions, +#if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16) + .bus_width_16 = 1, +#else + .bus_width_16 = 0, +#endif +}; + +static struct sam9_smc_config __initdata ek_nand_smc_config = { + .ncs_read_setup = 0, + .nrd_setup = 2, + .ncs_write_setup = 0, + .nwe_setup = 2, + + .ncs_read_pulse = 4, + .nrd_pulse = 4, + .ncs_write_pulse = 4, + .nwe_pulse = 4, + + .read_cycle = 7, + .write_cycle = 7, + + .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE, + .tdf_cycles = 3, +}; + +static void __init ek_add_device_nand(void) +{ + /* setup bus-width (8 or 16) */ + if (ek_nand_data.bus_width_16) + ek_nand_smc_config.mode |= AT91_SMC_DBW_16; + else + ek_nand_smc_config.mode |= AT91_SMC_DBW_8; + + /* configure chip-select 3 (NAND) */ + sam9_smc_configure(3, &ek_nand_smc_config); + + at91_add_device_nand(&ek_nand_data); +} + + +/* + * MCI (SD/MMC) + * det_pin and wp_pin are not connected + */ +#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE) +static struct mci_platform_data __initdata ek_mmc_data = { + .slot[0] = { + .bus_width = 4, + .detect_pin = -ENODEV, + .wp_pin = -ENODEV, + }, + .slot[1] = { + .bus_width = 4, + .detect_pin = -ENODEV, + .wp_pin = -ENODEV, + }, + +}; +#else +static struct amci_platform_data __initdata ek_mmc_data = { +}; +#endif + +/* + * LEDs + */ +static struct gpio_led ek_leds[] = { + { /* "bottom" led, green, userled1 to be defined */ + .name = "ds5", + .gpio = AT91_PIN_PB12, + .active_low = 1, + .default_trigger = "none", + }, + { /* "power" led, yellow */ + .name = "ds1", + .gpio = AT91_PIN_PB13, + .default_trigger = "heartbeat", + } +}; + +static struct i2c_board_info __initdata ek_i2c_devices[] = { + { + I2C_BOARD_INFO("24c512", 0x50), + }, +}; + + +static void __init ek_board_init(void) +{ + /* Serial */ + at91_add_device_serial(); + /* USB Host */ + at91_add_device_usbh(&ek_usbh_data); + /* USB Device */ + at91_add_device_udc(&ek_udc_data); + /* SPI */ + at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices)); + /* NAND */ + ek_add_device_nand(); + /* Ethernet */ + at91_add_device_eth(&ek_macb_data); + /* MMC */ + at91_add_device_mci(0, &ek_mmc_data); + /* I2C */ + at91_add_device_i2c(ek_i2c_devices, ARRAY_SIZE(ek_i2c_devices)); + /* LEDs */ + at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); + /* PCK0 provides MCLK to the WM8731 */ + at91_set_B_periph(AT91_PIN_PC1, 0); + /* SSC (for WM8731) */ + at91_add_device_ssc(AT91SAM9260_ID_SSC, ATMEL_SSC_TX); +} + +MACHINE_START(AT91SAM9G20EK_2MMC, "Atmel AT91SAM9G20-EK 2 MMC Slot Mod") + /* Maintainer: Rob Emanuele */ + .phys_io = AT91_BASE_SYS, + .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, + .boot_params = AT91_SDRAM_BASE + 0x100, + .timer = &at91sam926x_timer, + .map_io = ek_map_io, + .init_irq = ek_init_irq, + .init_machine = ek_board_init, +MACHINE_END diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h index e6afff8..a635dad 100644 --- a/arch/arm/mach-at91/include/mach/board.h +++ b/arch/arm/mach-at91/include/mach/board.h @@ -37,6 +37,7 @@ #include <linux/leds.h> #include <linux/spi/spi.h> #include <linux/usb/atmel_usba_udc.h> +#include <linux/atmel-mci.h> /* USB Device */ struct at91_udc_data { @@ -63,6 +64,7 @@ struct at91_cf_data { extern void __init at91_add_device_cf(struct at91_cf_data *data); /* MMC / SD */ + /* at91_mci platform config */ struct at91_mmc_data { u8 det_pin; /* card detect IRQ */ unsigned slot_b:1; /* uses Slot B */ @@ -72,6 +74,9 @@ struct at91_mmc_data { }; extern void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data); + /* atmel-mci platform config */ +extern void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data); + /* Ethernet (EMAC & MACB) */ struct at91_eth_data { u32 phy_mask; -- 1.6.0.4 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH 2/6] atmel-mci: Platform configuration to the the atmel-mci driver 2009-06-17 0:54 ` [PATCH 2/6] atmel-mci: Platform configuration to the the atmel-mci driver Rob Emanuele @ 2009-06-17 10:27 ` Nicolas Ferre 2009-06-18 19:58 ` Andrew Victor 1 sibling, 0 replies; 21+ messages in thread From: Nicolas Ferre @ 2009-06-17 10:27 UTC (permalink / raw) To: Rob Emanuele, Andrew Victor Cc: haavard.skinnemoen, linux-arm-kernel, linux-kernel Rob Emanuele : > Created a modified version of the at91sam9g20 evaluation kit platform (board-sam9g20ek-2slot-mmc.c) and device support to make use of the updated atmel-mci driver. > > This patch shows how an AT91 developer could add support for both SD slots for their project. Comment formated. > This requires getting the most updated arch/arm/tools/mach-types from http://www.arm.linux.org.uk/developer/machines/download.php to have the machine type for the modified at91sam9g20ek. Ok moved below "---" > Signed-off-by: Rob Emanuele <rob@emanuele.us> > --- > arch/arm/mach-at91/Kconfig | 7 + > arch/arm/mach-at91/Makefile | 1 + > arch/arm/mach-at91/at91sam9260_devices.c | 95 ++++++++ > arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c | 277 ++++++++++++++++++++++++ > arch/arm/mach-at91/include/mach/board.h | 5 + > 5 files changed, 385 insertions(+), 0 deletions(-) > create mode 100644 arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c > > diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig > index 323b47f..5c8d770 100644 > --- a/arch/arm/mach-at91/Kconfig > +++ b/arch/arm/mach-at91/Kconfig > @@ -276,6 +276,13 @@ config MACH_AT91SAM9G20EK > help > Select this if you are using Atmel's AT91SAM9G20-EK Evaluation Kit. > > +config MACH_AT91SAM9G20EK_2MMC > + bool "Atmel AT91SAM9G20-EK Evaluation Kit modified for 2 MMC Slots" > + depends on ARCH_AT91SAM9G20 > + help > + Select this if you are using an Atmel AT91SAM9G20-EK Evaluation Kit > + Rev A or B modified for 2 MMC Slots. > + > endif > > # ---------------------------------------------------------- > diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile > index c69ff23..cdddba8 100644 > --- a/arch/arm/mach-at91/Makefile > +++ b/arch/arm/mach-at91/Makefile > @@ -54,6 +54,7 @@ obj-$(CONFIG_MACH_AT91SAM9RLEK) += board-sam9rlek.o > > # AT91SAM9G20 board-specific support > obj-$(CONFIG_MACH_AT91SAM9G20EK) += board-sam9g20ek.o > +obj-$(CONFIG_MACH_AT91SAM9G20EK_2MMC) += board-sam9g20ek-2slot-mmc.o > > # AT91CAP9 board-specific support > obj-$(CONFIG_MACH_AT91CAP9ADK) += board-cap9adk.o > diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c > index d74c9ac..c372f4f 100644 > --- a/arch/arm/mach-at91/at91sam9260_devices.c > +++ b/arch/arm/mach-at91/at91sam9260_devices.c > @@ -278,6 +278,101 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) > void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {} > #endif > > +/* -------------------------------------------------------------------- > + * MMC / SD Slot for Atmel MCI Driver > + * -------------------------------------------------------------------- */ > + > +#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE) > +static u64 mmc_dmamask = DMA_BIT_MASK(32); > +static struct mci_platform_data mmc_data; > + > +static struct resource mmc_resources[] = { > + [0] = { > + .start = AT91SAM9260_BASE_MCI, > + .end = AT91SAM9260_BASE_MCI + SZ_16K - 1, > + .flags = IORESOURCE_MEM, > + }, > + [1] = { > + .start = AT91SAM9260_ID_MCI, > + .end = AT91SAM9260_ID_MCI, > + .flags = IORESOURCE_IRQ, > + }, > +}; > + > +static struct platform_device at91sam9260_mmc_device = { > + .name = "atmel_mci", > + .id = -1, > + .dev = { > + .dma_mask = &mmc_dmamask, > + .coherent_dma_mask = DMA_BIT_MASK(32), > + .platform_data = &mmc_data, > + }, > + .resource = mmc_resources, > + .num_resources = ARRAY_SIZE(mmc_resources), > +}; > + > +void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data) > +{ > + unsigned int i; > + unsigned int slot_count = 0; > + > + if (!data) > + return; > + > + for (i = 0; i < ATMEL_MCI_MAX_NR_SLOTS; i++) { > + if (data->slot[i].bus_width) { Indentation. > + /* input/irq */ > + if (data->slot[i].detect_pin) { > + at91_set_gpio_input(data->slot[i].detect_pin, 1); > + at91_set_deglitch(data->slot[i].detect_pin, 1); > + } > + if (data->slot[i].wp_pin) > + at91_set_gpio_input(data->slot[i].wp_pin, 1); > + > + switch(i) { > + case 0: > + /* CMD */ > + at91_set_A_periph(AT91_PIN_PA7, 1); > + /* DAT0, maybe DAT1..DAT3 */ > + at91_set_A_periph(AT91_PIN_PA6, 1); > + if (data->slot[i].bus_width == 4) { > + at91_set_A_periph(AT91_PIN_PA9, 1); > + at91_set_A_periph(AT91_PIN_PA10, 1); > + at91_set_A_periph(AT91_PIN_PA11, 1); > + } I put slot_count here... + slot_count++; > + break; > + case 1: > + /* CMD */ > + at91_set_B_periph(AT91_PIN_PA1, 1); > + /* DAT0, maybe DAT1..DAT3 */ > + at91_set_B_periph(AT91_PIN_PA0, 1); > + if (data->slot[i].bus_width == 4) { > + at91_set_B_periph(AT91_PIN_PA5, 1); > + at91_set_B_periph(AT91_PIN_PA4, 1); > + at91_set_B_periph(AT91_PIN_PA3, 1); > + } and here... + slot_count++; > + break; > + default: > + printk("Configuration Error, No MMC Port %d\n",i); Replaced with: printk(KERN_ERR "AT91: SD/MMC slot %d not available\n", i); > + break; > + }; removed here. > + slot_count++; > + } > + } > + > + if (slot_count) { > + /* CLK */ > + at91_set_A_periph(AT91_PIN_PA8, 0); > + > + mmc_data = *data; > + platform_device_register(&at91sam9260_mmc_device); > + } > +} > +#else > +void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data) {} > +#endif > + > + > > /* -------------------------------------------------------------------- > * NAND / SmartMedia > diff --git a/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c b/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c > new file mode 100644 > index 0000000..a28e53f > --- /dev/null > +++ b/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c Ok. True that it duplicates code but it is simpler. It also can be a testbed for future -EK revision D and following. [..] > diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h > index e6afff8..a635dad 100644 > --- a/arch/arm/mach-at91/include/mach/board.h > +++ b/arch/arm/mach-at91/include/mach/board.h > @@ -37,6 +37,7 @@ > #include <linux/leds.h> > #include <linux/spi/spi.h> > #include <linux/usb/atmel_usba_udc.h> > +#include <linux/atmel-mci.h> > > /* USB Device */ > struct at91_udc_data { > @@ -63,6 +64,7 @@ struct at91_cf_data { > extern void __init at91_add_device_cf(struct at91_cf_data *data); > > /* MMC / SD */ > + /* at91_mci platform config */ > struct at91_mmc_data { > u8 det_pin; /* card detect IRQ */ > unsigned slot_b:1; /* uses Slot B */ > @@ -72,6 +74,9 @@ struct at91_mmc_data { > }; > extern void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data); > > + /* atmel-mci platform config */ > +extern void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data); > + > /* Ethernet (EMAC & MACB) */ > struct at91_eth_data { > u32 phy_mask; Ok. I post the patch to Andrew Victor with the tiny modifications above (your SOB & From: preserved of course). Thanks, Bye, -- Nicolas Ferre ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 2/6] atmel-mci: Platform configuration to the the atmel-mci driver 2009-06-17 0:54 ` [PATCH 2/6] atmel-mci: Platform configuration to the the atmel-mci driver Rob Emanuele 2009-06-17 10:27 ` Nicolas Ferre @ 2009-06-18 19:58 ` Andrew Victor 2009-06-18 20:00 ` Andrew Victor 1 sibling, 1 reply; 21+ messages in thread From: Andrew Victor @ 2009-06-18 19:58 UTC (permalink / raw) To: Rob Emanuele Cc: nicolas.ferre, haavard.skinnemoen, linux-arm-kernel, linux-kernel hi, > + if (data->slot[i].bus_width) { > + /* input/irq */ > + if (data->slot[i].detect_pin) { > + at91_set_gpio_input(data->slot[i].detect_pin, 1); > + at91_set_deglitch(data->slot[i].detect_pin, 1); > + } > + if (data->slot[i].wp_pin) > + at91_set_gpio_input(data->slot[i].wp_pin, 1); The current at91_mci also allows the driver to control the "vcc_pin". Can that functionality be merged into atmel_mci driver? Regards. Andre Victor ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 2/6] atmel-mci: Platform configuration to the the atmel-mci driver 2009-06-18 19:58 ` Andrew Victor @ 2009-06-18 20:00 ` Andrew Victor 0 siblings, 0 replies; 21+ messages in thread From: Andrew Victor @ 2009-06-18 20:00 UTC (permalink / raw) To: Rob Emanuele Cc: nicolas.ferre, haavard.skinnemoen, linux-arm-kernel, linux-kernel > The current at91_mci also allows the driver to control the "vcc_pin". > Can that functionality be merged into atmel_mci driver? Ignore that comment, I see it's in Patch 5. ^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 3/6] atmel-mci: Optional controller reset before every command 2009-06-17 0:54 [PATCH 1/6] atmel-mci: Unified Atmel MCI drivers (AVR32 & AT91) Rob Emanuele 2009-06-17 0:54 ` [PATCH 2/6] atmel-mci: Platform configuration to the the atmel-mci driver Rob Emanuele @ 2009-06-17 0:54 ` Rob Emanuele 2009-06-17 8:32 ` Marc Pignat 2009-06-17 0:54 ` [PATCH 4/6] atmel-mci: CLKDIV cap to restrict the MCI controller speed Rob Emanuele ` (4 subsequent siblings) 6 siblings, 1 reply; 21+ messages in thread From: Rob Emanuele @ 2009-06-17 0:54 UTC (permalink / raw) To: nicolas.ferre Cc: haavard.skinnemoen, linux-arm-kernel, linux-kernel, Rob Emanuele This patch adds the compile time configuration option for the atmel-mci driver to reset the Atmel MCI controller before every command. This is sometimes needed for the Atmel controller / board to function properly. Signed-off-by: Rob Emanuele <rob@emanuele.us> --- drivers/mmc/host/Kconfig | 10 ++++++++++ drivers/mmc/host/atmel-mci.c | 11 ++++++++++- 2 files changed, 20 insertions(+), 1 deletions(-) diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index a0eaf69..5875125 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -161,6 +161,16 @@ config MMC_ATMELMCI endchoice +config MMC_ATMELMCI_ALWAYS_RESET + bool "Reset before every request. Sometimes needed for buggy chips." + depends on MMC_ATMELMCI + help + There are reports that some buggy controllers work better + with a reset before every command. This may improve your + controller's reliability. + + If unsure, say N. + config MMC_ATMELMCI_DMA bool "Atmel MCI DMA support (EXPERIMENTAL)" depends on MMC_ATMELMCI && AVR32 && DMA_ENGINE && EXPERIMENTAL diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index 98b25de..e5894f6 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c @@ -63,6 +63,15 @@ struct atmel_mci_dma { #endif }; +/* + * Configuration options from the kernel config + */ +#ifdef CONFIG_MMC_ATMELMCI_ALWAYS_RESET +#define MMC_ALWAYS_RESET 1 +#else +#define MMC_ALWAYS_RESET 0 +#endif + /** * struct atmel_mci - MMC controller state shared between all slots * @lock: Spinlock protecting the queue and associated data. @@ -720,7 +729,7 @@ static void atmci_start_request(struct atmel_mci *host, host->completed_events = 0; host->data_status = 0; - if (host->need_reset) { + if (host->need_reset || MMC_ALWAYS_RESET) { mci_writel(host, CR, MCI_CR_SWRST); mci_writel(host, CR, MCI_CR_MCIEN); mci_writel(host, MR, host->mode_reg); -- 1.6.0.4 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH 3/6] atmel-mci: Optional controller reset before every command 2009-06-17 0:54 ` [PATCH 3/6] atmel-mci: Optional controller reset before every command Rob Emanuele @ 2009-06-17 8:32 ` Marc Pignat 2009-06-17 18:27 ` Robert Emanuele 0 siblings, 1 reply; 21+ messages in thread From: Marc Pignat @ 2009-06-17 8:32 UTC (permalink / raw) To: linux-arm-kernel Cc: Rob Emanuele, nicolas.ferre, haavard.skinnemoen, linux-kernel Hi! On Wednesday 17 June 2009 02:54:36 Rob Emanuele wrote: > This patch adds the compile time configuration option for the atmel-mci driver to reset the Atmel MCI controller before every command. > > This is sometimes needed for the Atmel controller / board to function properly. > > Signed-off-by: Rob Emanuele <rob@emanuele.us> > --- > drivers/mmc/host/Kconfig | 10 ++++++++++ > drivers/mmc/host/atmel-mci.c | 11 ++++++++++- > 2 files changed, 20 insertions(+), 1 deletions(-) > > diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig > index a0eaf69..5875125 100644 > --- a/drivers/mmc/host/Kconfig > +++ b/drivers/mmc/host/Kconfig > @@ -161,6 +161,16 @@ config MMC_ATMELMCI > > endchoice > > +config MMC_ATMELMCI_ALWAYS_RESET > + bool "Reset before every request. Sometimes needed for buggy chips." > + depends on MMC_ATMELMCI > + help > + There are reports that some buggy controllers work better > + with a reset before every command. This may improve your > + controller's reliability. > + > + If unsure, say N. > + > config MMC_ATMELMCI_DMA > bool "Atmel MCI DMA support (EXPERIMENTAL)" > depends on MMC_ATMELMCI && AVR32 && DMA_ENGINE && EXPERIMENTAL > diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c > index 98b25de..e5894f6 100644 > --- a/drivers/mmc/host/atmel-mci.c > +++ b/drivers/mmc/host/atmel-mci.c > @@ -63,6 +63,15 @@ struct atmel_mci_dma { > #endif > }; > > +/* > + * Configuration options from the kernel config > + */ > +#ifdef CONFIG_MMC_ATMELMCI_ALWAYS_RESET > +#define MMC_ALWAYS_RESET 1 > +#else > +#define MMC_ALWAYS_RESET 0 > +#endif Some chips are known to hang after (some) transfer. There is no need for this configuration option, I think we should just do : #define MMC_ALWAYS_RESET (cpu_is_at91rm9200() || add_your_cpu_name_here()) > + > /** > * struct atmel_mci - MMC controller state shared between all slots > * @lock: Spinlock protecting the queue and associated data. > @@ -720,7 +729,7 @@ static void atmci_start_request(struct atmel_mci *host, > host->completed_events = 0; > host->data_status = 0; > > - if (host->need_reset) { > + if (host->need_reset || MMC_ALWAYS_RESET) { > mci_writel(host, CR, MCI_CR_SWRST); > mci_writel(host, CR, MCI_CR_MCIEN); > mci_writel(host, MR, host->mode_reg); Another option is to always reset the controller. The reset operation won't hurt, it is simple and fast, and the code will be simpler and better tested. Best regards Marc ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 3/6] atmel-mci: Optional controller reset before every command 2009-06-17 8:32 ` Marc Pignat @ 2009-06-17 18:27 ` Robert Emanuele 0 siblings, 0 replies; 21+ messages in thread From: Robert Emanuele @ 2009-06-17 18:27 UTC (permalink / raw) To: Marc Pignat Cc: linux-arm-kernel, nicolas.ferre, haavard.skinnemoen, linux-kernel Marc, (This may be a resend, gmail and its fancy text hates me.) There has been debate over whether always reseting the MCI controller is the correct thing to do. I think for some platforms it is required but there is no consensus to what those platforms are. I think the config option is the best of both worlds as a user of this kernel/driver can choose to enable this or not without having to modify their source. It may even be a decent idea to enable this option if they are using certain chips that we know reseting improves their behavior. Thank you, Rob ^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 4/6] atmel-mci: CLKDIV cap to restrict the MCI controller speed 2009-06-17 0:54 [PATCH 1/6] atmel-mci: Unified Atmel MCI drivers (AVR32 & AT91) Rob Emanuele 2009-06-17 0:54 ` [PATCH 2/6] atmel-mci: Platform configuration to the the atmel-mci driver Rob Emanuele 2009-06-17 0:54 ` [PATCH 3/6] atmel-mci: Optional controller reset before every command Rob Emanuele @ 2009-06-17 0:54 ` Rob Emanuele 2009-06-17 0:54 ` [PATCH 5/6] atmel-mci: Power control option for each MMC Slot Rob Emanuele ` (3 subsequent siblings) 6 siblings, 0 replies; 21+ messages in thread From: Rob Emanuele @ 2009-06-17 0:54 UTC (permalink / raw) To: nicolas.ferre Cc: haavard.skinnemoen, linux-arm-kernel, linux-kernel, Rob Emanuele This patch adds the compile time configuration option for the atmel-mci driver to cap the MCI CLKDIV register value to a minimum value. This is useful for debugging and for boards that have a long mci clock line. Signed-off-by: Rob Emanuele <rob@emanuele.us> --- drivers/mmc/host/Kconfig | 14 ++++++++++++++ drivers/mmc/host/atmel-mci.c | 10 ++++++++++ 2 files changed, 24 insertions(+), 0 deletions(-) diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 5875125..b628037 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -161,6 +161,20 @@ config MMC_ATMELMCI endchoice +config MMC_ATMELMCI_CLKDIV_CAP + int "Cap the CLKDIV to keep the controller from going too fast." + depends on MMC_ATMELMCI + default 0 + range 0 255 + help + This is the lowest value the clock divisor for the MMC + controller can be. Value is between 0 and 255. + MCI_CK = MCK/(2*(CLKDIV+1)) + Raising this value may improve your controller's reliability + at the cost of speed. + + If unsure, leave at 0. + config MMC_ATMELMCI_ALWAYS_RESET bool "Reset before every request. Sometimes needed for buggy chips." depends on MMC_ATMELMCI diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index e5894f6..601dae7 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c @@ -72,6 +72,10 @@ struct atmel_mci_dma { #define MMC_ALWAYS_RESET 0 #endif +#ifndef CONFIG_MMC_ATMELMCI_CLKDIV_CAP +#define CONFIG_MMC_ATMELMCI_CLKDIV_CAP 0 +#endif + /** * struct atmel_mci - MMC controller state shared between all slots * @lock: Spinlock protecting the queue and associated data. @@ -882,6 +886,12 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) clock_min, host->bus_hz / (2 * 256)); clkdiv = 255; } + if (clkdiv < CONFIG_MMC_ATMELMCI_CLKDIV_CAP) { + dev_warn(&mmc->class_dev, + "clkdiv %u too fast; capped using %u\n", + clkdiv, CONFIG_MMC_ATMELMCI_CLKDIV_CAP); + clkdiv = CONFIG_MMC_ATMELMCI_CLKDIV_CAP; + } host->mode_reg = MCI_MR_CLKDIV(clkdiv); -- 1.6.0.4 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 5/6] atmel-mci: Power control option for each MMC Slot 2009-06-17 0:54 [PATCH 1/6] atmel-mci: Unified Atmel MCI drivers (AVR32 & AT91) Rob Emanuele ` (2 preceding siblings ...) 2009-06-17 0:54 ` [PATCH 4/6] atmel-mci: CLKDIV cap to restrict the MCI controller speed Rob Emanuele @ 2009-06-17 0:54 ` Rob Emanuele 2009-06-17 8:08 ` Marc Pignat 2009-06-17 0:54 ` [PATCH 6/6] atmel-mci: Platform driver MMC slot power control Rob Emanuele ` (2 subsequent siblings) 6 siblings, 1 reply; 21+ messages in thread From: Rob Emanuele @ 2009-06-17 0:54 UTC (permalink / raw) To: nicolas.ferre Cc: haavard.skinnemoen, linux-arm-kernel, linux-kernel, Rob Emanuele Add support to the atmel-mci driver for a VCC pin in order to conserve power by removing power from an MMC Slot. Signed-off-by: Rob Emanuele <rob@emanuele.us> --- drivers/mmc/host/atmel-mci.c | 33 ++++++++++++++++++++------------- include/linux/atmel-mci.h | 2 ++ 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index 601dae7..63cd5c7 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c @@ -214,6 +214,8 @@ struct atmel_mci_slot { int detect_pin; int wp_pin; bool detect_is_active_high; + int vcc_pin; + bool vcc_active_low; struct timer_list detect_timer; }; @@ -932,23 +934,19 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) } switch (ios->power_mode) { + case MMC_POWER_OFF: + if (gpio_is_valid(slot->vcc_pin)) + gpio_set_value(slot->vcc_pin, slot->vcc_active_low); + break; case MMC_POWER_UP: + if (gpio_is_valid(slot->vcc_pin)) + gpio_set_value(slot->vcc_pin, !slot->vcc_active_low); set_bit(ATMCI_CARD_NEED_INIT, &slot->flags); break; - default: - /* - * TODO: None of the currently available AVR32-based - * boards allow MMC power to be turned off. Implement - * power control when this can be tested properly. - * - * We also need to hook this into the clock management - * somehow so that newly inserted cards aren't - * subjected to a fast clock before we have a chance - * to figure out what the maximum rate is. Currently, - * there's no way to avoid this, and there never will - * be for boards that don't support power control. - */ + case MMC_POWER_ON: break; + default: + WARN_ON(1); } } @@ -1507,6 +1505,8 @@ static int __init atmci_init_slot(struct atmel_mci *host, slot->detect_pin = slot_data->detect_pin; slot->wp_pin = slot_data->wp_pin; slot->detect_is_active_high = slot_data->detect_is_active_high; + slot->vcc_pin = slot_data->vcc_pin; + slot->vcc_active_low = slot_data->vcc_active_low; slot->sdc_reg = sdc_reg; mmc->ops = &atmci_ops; @@ -1544,6 +1544,13 @@ static int __init atmci_init_slot(struct atmel_mci *host, } } + if (gpio_is_valid(slot->vcc_pin)) { + if (gpio_request(slot->vcc_pin, "mmc_pow")) { + dev_dbg(&mmc->class_dev, "no power pin available\n"); + slot->vcc_pin = -EBUSY; + } + } + host->slot[id] = slot; mmc_add_host(mmc); diff --git a/include/linux/atmel-mci.h b/include/linux/atmel-mci.h index 57b1846..7c15a7c 100644 --- a/include/linux/atmel-mci.h +++ b/include/linux/atmel-mci.h @@ -26,6 +26,8 @@ struct mci_slot_pdata { int detect_pin; int wp_pin; bool detect_is_active_high; + int vcc_pin; + unsigned vcc_active_low:1; }; /** -- 1.6.0.4 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH 5/6] atmel-mci: Power control option for each MMC Slot 2009-06-17 0:54 ` [PATCH 5/6] atmel-mci: Power control option for each MMC Slot Rob Emanuele @ 2009-06-17 8:08 ` Marc Pignat 0 siblings, 0 replies; 21+ messages in thread From: Marc Pignat @ 2009-06-17 8:08 UTC (permalink / raw) To: linux-arm-kernel Cc: Rob Emanuele, nicolas.ferre, haavard.skinnemoen, linux-kernel Hi! On Wednesday 17 June 2009 02:54:38 Rob Emanuele wrote: > Add support to the atmel-mci driver for a VCC pin in order to conserve power by removing power from an MMC Slot. ... > @@ -1544,6 +1544,13 @@ static int __init atmci_init_slot(struct atmel_mci *host, > } > } > > + if (gpio_is_valid(slot->vcc_pin)) { > + if (gpio_request(slot->vcc_pin, "mmc_pow")) { gpio_request will check for "gpio_is_valid" so this is not necessary. > + dev_dbg(&mmc->class_dev, "no power pin available\n"); > + slot->vcc_pin = -EBUSY; > + } > + } > + ... Best regards Marc ^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 6/6] atmel-mci: Platform driver MMC slot power control 2009-06-17 0:54 [PATCH 1/6] atmel-mci: Unified Atmel MCI drivers (AVR32 & AT91) Rob Emanuele ` (3 preceding siblings ...) 2009-06-17 0:54 ` [PATCH 5/6] atmel-mci: Power control option for each MMC Slot Rob Emanuele @ 2009-06-17 0:54 ` Rob Emanuele 2009-06-17 1:23 ` Ryan Mallon 2009-06-17 9:56 ` [PATCH 1/6] atmel-mci: Unified Atmel MCI drivers (AVR32 & AT91) Nicolas Ferre [not found] ` <95818a17c2b96d3769f4e1d3de26208647111758.1245778411.git.nicolas.ferre@atmel.com> 6 siblings, 1 reply; 21+ messages in thread From: Rob Emanuele @ 2009-06-17 0:54 UTC (permalink / raw) To: nicolas.ferre Cc: haavard.skinnemoen, linux-arm-kernel, linux-kernel, Rob Emanuele Add support to the at91sam9g20ek_2mmc platform (board-sam9g20ek-2slot-mmc.c) and support files for a VCC pin using the atmel-mci driver. Signed-off-by: Rob Emanuele <rob@emanuele.us> --- arch/arm/mach-at91/at91sam9260_devices.c | 2 ++ arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c | 3 +++ 2 files changed, 5 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index c372f4f..7634632 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c @@ -328,6 +328,8 @@ void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data) } if (data->slot[i].wp_pin) at91_set_gpio_input(data->slot[i].wp_pin, 1); + if (data->slot[i].vcc_pin) + at91_set_gpio_output(data->slot[i].vcc_pin, 0); switch(i) { case 0: diff --git a/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c b/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c index a28e53f..20c6738 100644 --- a/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c +++ b/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c @@ -202,11 +202,14 @@ static struct mci_platform_data __initdata ek_mmc_data = { .bus_width = 4, .detect_pin = -ENODEV, .wp_pin = -ENODEV, + .vcc_pin = AT91_PIN_PA30, + .vcc_active_low = 1, }, .slot[1] = { .bus_width = 4, .detect_pin = -ENODEV, .wp_pin = -ENODEV, + .vcc_pin = -ENODEV, }, }; -- 1.6.0.4 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH 6/6] atmel-mci: Platform driver MMC slot power control 2009-06-17 0:54 ` [PATCH 6/6] atmel-mci: Platform driver MMC slot power control Rob Emanuele @ 2009-06-17 1:23 ` Ryan Mallon 0 siblings, 0 replies; 21+ messages in thread From: Ryan Mallon @ 2009-06-17 1:23 UTC (permalink / raw) To: Rob Emanuele Cc: nicolas.ferre, haavard.skinnemoen, linux-arm-kernel, linux-kernel Rob Emanuele wrote: > Add support to the at91sam9g20ek_2mmc platform (board-sam9g20ek-2slot-mmc.c) and support files for a VCC pin using the atmel-mci driver. > > Signed-off-by: Rob Emanuele <rob@emanuele.us> > --- > arch/arm/mach-at91/at91sam9260_devices.c | 2 ++ > arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c | 3 +++ > 2 files changed, 5 insertions(+), 0 deletions(-) > > diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c > index c372f4f..7634632 100644 > --- a/arch/arm/mach-at91/at91sam9260_devices.c > +++ b/arch/arm/mach-at91/at91sam9260_devices.c > @@ -328,6 +328,8 @@ void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data) > } > if (data->slot[i].wp_pin) > at91_set_gpio_input(data->slot[i].wp_pin, 1); > + if (data->slot[i].vcc_pin) > + at91_set_gpio_output(data->slot[i].vcc_pin, 0); > Can use gpio_direction_output on these. ~Ryan -- Bluewater Systems Ltd - ARM Technology Solution Centre Ryan Mallon Unit 5, Amuri Park Phone: +64 3 3779127 404 Barbadoes St Fax: +64 3 3779135 PO Box 13 889 Email: ryan@bluewatersys.com Christchurch, 8013 Web: http://www.bluewatersys.com New Zealand Freecall Australia 1800 148 751 USA 1800 261 2934 ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 1/6] atmel-mci: Unified Atmel MCI drivers (AVR32 & AT91) 2009-06-17 0:54 [PATCH 1/6] atmel-mci: Unified Atmel MCI drivers (AVR32 & AT91) Rob Emanuele ` (4 preceding siblings ...) 2009-06-17 0:54 ` [PATCH 6/6] atmel-mci: Platform driver MMC slot power control Rob Emanuele @ 2009-06-17 9:56 ` Nicolas Ferre 2009-06-17 10:08 ` Haavard Skinnemoen [not found] ` <95818a17c2b96d3769f4e1d3de26208647111758.1245778411.git.nicolas.ferre@atmel.com> 6 siblings, 1 reply; 21+ messages in thread From: Nicolas Ferre @ 2009-06-17 9:56 UTC (permalink / raw) To: Rob Emanuele, haavard.skinnemoen; +Cc: linux-arm-kernel, linux-kernel Rob, Haavard, Rob Emanuele : > Unification of the atmel-mci driver to support the AT91 processors MCI interface. The atmel-mci driver currently supports the AVR32 and this patch adds AT91 support. > > To use this new driver on a at91 the platform driver for your board needs to updated. See the following patch for an example of how to do that. I format those lines remove last sentence and add : "Add read/write proof selection switch dependent on chip availability of this feature." > Signed-off-by: Rob Emanuele <rob@emanuele.us> > --- > drivers/mmc/host/Kconfig | 16 ++++++++++++---- > drivers/mmc/host/atmel-mci.c | 37 +++++++++++++++++++++++++++++++++---- > 2 files changed, 45 insertions(+), 8 deletions(-) > > diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig > index 40111a6..a0eaf69 100644 > --- a/drivers/mmc/host/Kconfig > +++ b/drivers/mmc/host/Kconfig > @@ -135,6 +135,12 @@ config MMC_AU1X > > If unsure, say N. > > +choice > + prompt "Atmel MMC Driver" I add SD/MMC > + default MMC_ATMELMCI if AVR32 > + help > + Choose which driver to use for the Atmel MCI Silicon > + > config MMC_AT91 > tristate "AT91 SD/MMC Card Interface support" > depends on ARCH_AT91 > @@ -145,17 +151,19 @@ config MMC_AT91 > > config MMC_ATMELMCI > tristate "Atmel Multimedia Card Interface support" > - depends on AVR32 > + depends on AVR32 || ARCH_AT91 > help > This selects the Atmel Multimedia Card Interface driver. If > - you have an AT32 (AVR32) platform with a Multimedia Card > - slot, say Y or M here. > + you have an AT32 (AVR32) or AT91 platform with a Multimedia > + Card slot, say Y or M here. > > If unsure, say N. > > +endchoice > + > config MMC_ATMELMCI_DMA > bool "Atmel MCI DMA support (EXPERIMENTAL)" > - depends on MMC_ATMELMCI && DMA_ENGINE && EXPERIMENTAL > + depends on MMC_ATMELMCI && AVR32 && DMA_ENGINE && EXPERIMENTAL > help > Say Y here to have the Atmel MCI driver use a DMA engine to > do data transfers and thus increase the throughput and > diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c > index 7b603e4..98b25de 100644 > --- a/drivers/mmc/host/atmel-mci.c > +++ b/drivers/mmc/host/atmel-mci.c > @@ -30,11 +30,14 @@ > #include <asm/io.h> > #include <asm/unaligned.h> > > +#include <mach/cpu.h> > #include <mach/board.h> > > #include "atmel-mci-regs.h" > > -#define ATMCI_DATA_ERROR_FLAGS (MCI_DCRCE | MCI_DTOE | MCI_OVRE | MCI_UNRE) > +#define ATMCI_DATA_ERROR_FLAGS (MCI_RINDE | MCI_RDIRE | MCI_RCRCE \ > + | MCI_RENDE | MCI_RTOE | MCI_DCRCE \ > + | MCI_DTOE | MCI_OVRE | MCI_UNRE) Haavard, is it ok to add those flags on an AVR32 platform for now ? > #define ATMCI_DMA_THRESHOLD 16 > > enum { > @@ -210,6 +213,18 @@ struct atmel_mci_slot { > set_bit(event, &host->pending_events) > > /* > + * Enable or disable features/registers based on > + * whether the processor supports them > + */ > +static bool mci_has_rwproof(void) > +{ > + if (cpu_is_at91sam9261() || cpu_is_at91rm9200()) > + return false; > + else > + return true; > +} > + > +/* > * The debugfs stuff below is mostly optimized away when > * CONFIG_DEBUG_FS is not set. > */ > @@ -276,8 +291,13 @@ static void atmci_show_status_reg(struct seq_file *s, > [3] = "BLKE", > [4] = "DTIP", > [5] = "NOTBUSY", > + [6] = "ENDRX", > + [7] = "ENDTX", > [8] = "SDIOIRQA", > [9] = "SDIOIRQB", > + [12] = "SDIOWAIT", > + [14] = "RXBUFF", > + [15] = "TXBUFE", > [16] = "RINDE", > [17] = "RDIRE", > [18] = "RCRCE", > @@ -285,6 +305,11 @@ static void atmci_show_status_reg(struct seq_file *s, > [20] = "RTOE", > [21] = "DCRCE", > [22] = "DTOE", > + [23] = "CSTOE", > + [24] = "BLKOVRE", > + [25] = "DMADONE", > + [26] = "FIFOEMPTY", > + [27] = "XFRDONE", Little indentation modifications. > [30] = "OVRE", > [31] = "UNRE", > }; > @@ -849,13 +874,15 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) > clkdiv = 255; > } > > + host->mode_reg = MCI_MR_CLKDIV(clkdiv); > + > /* > * WRPROOF and RDPROOF prevent overruns/underruns by > * stopping the clock when the FIFO is full/empty. > * This state is not expected to last for long. > */ > - host->mode_reg = MCI_MR_CLKDIV(clkdiv) | MCI_MR_WRPROOF > - | MCI_MR_RDPROOF; > + if (mci_has_rwproof()) > + host->mode_reg |= (MCI_MR_WRPROOF | MCI_MR_RDPROOF); > > if (list_empty(&host->queue)) > mci_writel(host, MR, host->mode_reg); > @@ -1648,8 +1675,10 @@ static int __init atmci_probe(struct platform_device *pdev) > nr_slots++; > } > > - if (!nr_slots) > + if (!nr_slots) { > + printk(KERN_ERR "Atmel MCI controller init failed. atmci_init_slot error or no slots with bus_width > 0.\n"); I change this to : dev_err(&pdev->dev, "init failed: no slot defined\n"); > goto err_init_slot; > + } > > dev_info(&pdev->dev, > "Atmel MCI controller at 0x%08lx irq %d, %u slots\n", If Haavard is ok, I post the patch to Pierre Ossman with the tiny modifications above (your SOB & From: preserved of course). Thanks, Bye, -- Nicolas Ferre ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 1/6] atmel-mci: Unified Atmel MCI drivers (AVR32 & AT91) 2009-06-17 9:56 ` [PATCH 1/6] atmel-mci: Unified Atmel MCI drivers (AVR32 & AT91) Nicolas Ferre @ 2009-06-17 10:08 ` Haavard Skinnemoen 2009-06-23 16:28 ` Nicolas Ferre 0 siblings, 1 reply; 21+ messages in thread From: Haavard Skinnemoen @ 2009-06-17 10:08 UTC (permalink / raw) To: Nicolas Ferre; +Cc: Rob Emanuele, linux-arm-kernel, linux-kernel Nicolas Ferre wrote: > > -#define ATMCI_DATA_ERROR_FLAGS (MCI_DCRCE | MCI_DTOE | MCI_OVRE | MCI_UNRE) > > +#define ATMCI_DATA_ERROR_FLAGS (MCI_RINDE | MCI_RDIRE | MCI_RCRCE \ > > + | MCI_RENDE | MCI_RTOE | MCI_DCRCE \ > > + | MCI_DTOE | MCI_OVRE | MCI_UNRE) > > Haavard, is it ok to add those flags on an AVR32 platform for now ? It probably doesn't hurt on AVR32. But I'm not a great fan since it seems like the wrong thing to do, and it may simply mask the real problem. Haavard ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 1/6] atmel-mci: Unified Atmel MCI drivers (AVR32 & AT91) 2009-06-17 10:08 ` Haavard Skinnemoen @ 2009-06-23 16:28 ` Nicolas Ferre 0 siblings, 0 replies; 21+ messages in thread From: Nicolas Ferre @ 2009-06-23 16:28 UTC (permalink / raw) To: Haavard Skinnemoen, Rob Emanuele Cc: linux-arm-kernel, linux-kernel, Pierre Ossman Haavard Skinnemoen : > Nicolas Ferre wrote: >>> -#define ATMCI_DATA_ERROR_FLAGS (MCI_DCRCE | MCI_DTOE | MCI_OVRE | MCI_UNRE) >>> +#define ATMCI_DATA_ERROR_FLAGS (MCI_RINDE | MCI_RDIRE | MCI_RCRCE \ >>> + | MCI_RENDE | MCI_RTOE | MCI_DCRCE \ >>> + | MCI_DTOE | MCI_OVRE | MCI_UNRE) >> Haavard, is it ok to add those flags on an AVR32 platform for now ? > > It probably doesn't hurt on AVR32. But I'm not a great fan since it > seems like the wrong thing to do, and it may simply mask the real > problem. Agreed. To move forward, I will submit a first patch series without those flags added. Best regards, -- Nicolas Ferre ^ permalink raw reply [flat|nested] 21+ messages in thread
[parent not found: <95818a17c2b96d3769f4e1d3de26208647111758.1245778411.git.nicolas.ferre@atmel.com>]
* [PATCH 1/2] atmel-mci: Unified Atmel MCI drivers (AVR32 & AT91) [not found] ` <95818a17c2b96d3769f4e1d3de26208647111758.1245778411.git.nicolas.ferre@atmel.com> @ 2009-06-23 17:39 ` Nicolas Ferre 2009-09-02 7:31 ` Haavard Skinnemoen [not found] ` <f8889fb59887a970581697beb313363a6a065606.1245778411.git.nicolas.ferre@atmel.com> 1 sibling, 1 reply; 21+ messages in thread From: Nicolas Ferre @ 2009-06-23 17:39 UTC (permalink / raw) To: pierre, avictor.za Cc: linux-kernel, haavard.skinnemoen, linux-arm-kernel, rob, nicolas.ferre From: Rob Emanuele <rob@emanuele.us> Unification of the atmel-mci driver to support the AT91 processors MCI interface. The atmel-mci driver currently supports the AVR32 and this patch adds AT91 support. Add read/write proof selection switch dependent on chip availability of this feature. To use this new driver on a at91 the platform driver for your board needs to updated. Signed-off-by: Rob Emanuele <rob@emanuele.us> [nicolas.ferre@atmel.com indent, Kconfig comment and one printk modification] Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com> --- drivers/mmc/host/Kconfig | 16 ++++++++++++---- drivers/mmc/host/atmel-mci.c | 33 ++++++++++++++++++++++++++++++--- 2 files changed, 42 insertions(+), 7 deletions(-) diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index b4cf691..e779049 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -124,6 +124,12 @@ config MMC_AU1X If unsure, say N. +choice + prompt "Atmel SD/MMC Driver" + default MMC_ATMELMCI if AVR32 + help + Choose which driver to use for the Atmel MCI Silicon + config MMC_AT91 tristate "AT91 SD/MMC Card Interface support" depends on ARCH_AT91 @@ -134,17 +140,19 @@ config MMC_AT91 config MMC_ATMELMCI tristate "Atmel Multimedia Card Interface support" - depends on AVR32 + depends on AVR32 || ARCH_AT91 help This selects the Atmel Multimedia Card Interface driver. If - you have an AT32 (AVR32) platform with a Multimedia Card - slot, say Y or M here. + you have an AT32 (AVR32) or AT91 platform with a Multimedia + Card slot, say Y or M here. If unsure, say N. +endchoice + config MMC_ATMELMCI_DMA bool "Atmel MCI DMA support (EXPERIMENTAL)" - depends on MMC_ATMELMCI && DMA_ENGINE && EXPERIMENTAL + depends on MMC_ATMELMCI && AVR32 && DMA_ENGINE && EXPERIMENTAL help Say Y here to have the Atmel MCI driver use a DMA engine to do data transfers and thus increase the throughput and diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index 7b603e4..065fa81 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c @@ -30,6 +30,7 @@ #include <asm/io.h> #include <asm/unaligned.h> +#include <mach/cpu.h> #include <mach/board.h> #include "atmel-mci-regs.h" @@ -210,6 +211,18 @@ struct atmel_mci_slot { set_bit(event, &host->pending_events) /* + * Enable or disable features/registers based on + * whether the processor supports them + */ +static bool mci_has_rwproof(void) +{ + if (cpu_is_at91sam9261() || cpu_is_at91rm9200()) + return false; + else + return true; +} + +/* * The debugfs stuff below is mostly optimized away when * CONFIG_DEBUG_FS is not set. */ @@ -276,8 +289,13 @@ static void atmci_show_status_reg(struct seq_file *s, [3] = "BLKE", [4] = "DTIP", [5] = "NOTBUSY", + [6] = "ENDRX", + [7] = "ENDTX", [8] = "SDIOIRQA", [9] = "SDIOIRQB", + [12] = "SDIOWAIT", + [14] = "RXBUFF", + [15] = "TXBUFE", [16] = "RINDE", [17] = "RDIRE", [18] = "RCRCE", @@ -285,6 +303,11 @@ static void atmci_show_status_reg(struct seq_file *s, [20] = "RTOE", [21] = "DCRCE", [22] = "DTOE", + [23] = "CSTOE", + [24] = "BLKOVRE", + [25] = "DMADONE", + [26] = "FIFOEMPTY", + [27] = "XFRDONE", [30] = "OVRE", [31] = "UNRE", }; @@ -849,13 +872,15 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) clkdiv = 255; } + host->mode_reg = MCI_MR_CLKDIV(clkdiv); + /* * WRPROOF and RDPROOF prevent overruns/underruns by * stopping the clock when the FIFO is full/empty. * This state is not expected to last for long. */ - host->mode_reg = MCI_MR_CLKDIV(clkdiv) | MCI_MR_WRPROOF - | MCI_MR_RDPROOF; + if (mci_has_rwproof()) + host->mode_reg |= (MCI_MR_WRPROOF | MCI_MR_RDPROOF); if (list_empty(&host->queue)) mci_writel(host, MR, host->mode_reg); @@ -1648,8 +1673,10 @@ static int __init atmci_probe(struct platform_device *pdev) nr_slots++; } - if (!nr_slots) + if (!nr_slots) { + dev_err(&pdev->dev, "init failed: no slot defined\n"); goto err_init_slot; + } dev_info(&pdev->dev, "Atmel MCI controller at 0x%08lx irq %d, %u slots\n", -- 1.5.3.7 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH 1/2] atmel-mci: Unified Atmel MCI drivers (AVR32 & AT91) 2009-06-23 17:39 ` [PATCH 1/2] " Nicolas Ferre @ 2009-09-02 7:31 ` Haavard Skinnemoen 0 siblings, 0 replies; 21+ messages in thread From: Haavard Skinnemoen @ 2009-09-02 7:31 UTC (permalink / raw) To: Nicolas Ferre Cc: pierre, avictor.za, linux-kernel, linux-arm-kernel, rob, nicolas.ferre Nicolas Ferre <nicolas.ferre@atmel.com> wrote: > From: Rob Emanuele <rob@emanuele.us> > > Unification of the atmel-mci driver to support the AT91 processors MCI > interface. The atmel-mci driver currently supports the AVR32 and this patch > adds AT91 support. > Add read/write proof selection switch dependent on chip availability of this > feature. > > To use this new driver on a at91 the platform driver for your board needs to > updated. > > Signed-off-by: Rob Emanuele <rob@emanuele.us> > [nicolas.ferre@atmel.com indent, Kconfig comment and one printk modification] > Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com> Acked-by: Haavard Skinnemoen <haavard.skinnemoen@atmel.com> ^ permalink raw reply [flat|nested] 21+ messages in thread
[parent not found: <f8889fb59887a970581697beb313363a6a065606.1245778411.git.nicolas.ferre@atmel.com>]
* [PATCH 2/2] AT91: atmel-mci: Platform configuration to the the atmel-mci driver [not found] ` <f8889fb59887a970581697beb313363a6a065606.1245778411.git.nicolas.ferre@atmel.com> @ 2009-06-23 17:39 ` Nicolas Ferre 2009-06-23 21:36 ` Jean-Christophe PLAGNIOL-VILLARD 1 sibling, 0 replies; 21+ messages in thread From: Nicolas Ferre @ 2009-06-23 17:39 UTC (permalink / raw) To: pierre, avictor.za Cc: linux-kernel, haavard.skinnemoen, linux-arm-kernel, rob, nicolas.ferre From: Rob Emanuele <rob@emanuele.us> Created a modified version of the at91sam9g20 evaluation kit platform (board-sam9g20ek-2slot-mmc.c) and device support to make use of the updated atmel-mci driver. As the use of two slots modify GPIO pin allocation, we create another board file. Signed-off-by: Rob Emanuele <rob@emanuele.us> [nicolas.ferre@atmel.com: printk, slot_count modification in at91sam9260_devices.c file] Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com> --- This requires getting the most updated arch/arm/tools/mach-types from http://www.arm.linux.org.uk/developer/machines/download.php to have the machine type for the at91sam9g20ek-2slot-mmc board. arch/arm/mach-at91/Kconfig | 7 + arch/arm/mach-at91/Makefile | 1 + arch/arm/mach-at91/at91sam9260_devices.c | 96 ++++++++ arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c | 277 ++++++++++++++++++++++++ arch/arm/mach-at91/include/mach/board.h | 5 + 5 files changed, 386 insertions(+), 0 deletions(-) create mode 100644 arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 323b47f..5c8d770 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -276,6 +276,13 @@ config MACH_AT91SAM9G20EK help Select this if you are using Atmel's AT91SAM9G20-EK Evaluation Kit. +config MACH_AT91SAM9G20EK_2MMC + bool "Atmel AT91SAM9G20-EK Evaluation Kit modified for 2 MMC Slots" + depends on ARCH_AT91SAM9G20 + help + Select this if you are using an Atmel AT91SAM9G20-EK Evaluation Kit + Rev A or B modified for 2 MMC Slots. + endif # ---------------------------------------------------------- diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index c69ff23..cdddba8 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile @@ -54,6 +54,7 @@ obj-$(CONFIG_MACH_AT91SAM9RLEK) += board-sam9rlek.o # AT91SAM9G20 board-specific support obj-$(CONFIG_MACH_AT91SAM9G20EK) += board-sam9g20ek.o +obj-$(CONFIG_MACH_AT91SAM9G20EK_2MMC) += board-sam9g20ek-2slot-mmc.o # AT91CAP9 board-specific support obj-$(CONFIG_MACH_AT91CAP9ADK) += board-cap9adk.o diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index d74c9ac..86a29bf 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c @@ -278,6 +278,102 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {} #endif +/* -------------------------------------------------------------------- + * MMC / SD Slot for Atmel MCI Driver + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE) +static u64 mmc_dmamask = DMA_BIT_MASK(32); +static struct mci_platform_data mmc_data; + +static struct resource mmc_resources[] = { + [0] = { + .start = AT91SAM9260_BASE_MCI, + .end = AT91SAM9260_BASE_MCI + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_MCI, + .end = AT91SAM9260_ID_MCI, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9260_mmc_device = { + .name = "atmel_mci", + .id = -1, + .dev = { + .dma_mask = &mmc_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &mmc_data, + }, + .resource = mmc_resources, + .num_resources = ARRAY_SIZE(mmc_resources), +}; + +void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data) +{ + unsigned int i; + unsigned int slot_count = 0; + + if (!data) + return; + + for (i = 0; i < ATMEL_MCI_MAX_NR_SLOTS; i++) { + if (data->slot[i].bus_width) { + /* input/irq */ + if (data->slot[i].detect_pin) { + at91_set_gpio_input(data->slot[i].detect_pin, 1); + at91_set_deglitch(data->slot[i].detect_pin, 1); + } + if (data->slot[i].wp_pin) + at91_set_gpio_input(data->slot[i].wp_pin, 1); + + switch(i) { + case 0: + /* CMD */ + at91_set_A_periph(AT91_PIN_PA7, 1); + /* DAT0, maybe DAT1..DAT3 */ + at91_set_A_periph(AT91_PIN_PA6, 1); + if (data->slot[i].bus_width == 4) { + at91_set_A_periph(AT91_PIN_PA9, 1); + at91_set_A_periph(AT91_PIN_PA10, 1); + at91_set_A_periph(AT91_PIN_PA11, 1); + } + slot_count++; + break; + case 1: + /* CMD */ + at91_set_B_periph(AT91_PIN_PA1, 1); + /* DAT0, maybe DAT1..DAT3 */ + at91_set_B_periph(AT91_PIN_PA0, 1); + if (data->slot[i].bus_width == 4) { + at91_set_B_periph(AT91_PIN_PA5, 1); + at91_set_B_periph(AT91_PIN_PA4, 1); + at91_set_B_periph(AT91_PIN_PA3, 1); + } + slot_count++; + break; + default: + printk(KERN_ERR + "AT91: SD/MMC slot %d not available\n", i); + break; + } + } + } + + if (slot_count) { + /* CLK */ + at91_set_A_periph(AT91_PIN_PA8, 0); + + mmc_data = *data; + platform_device_register(&at91sam9260_mmc_device); + } +} +#else +void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data) {} +#endif + /* -------------------------------------------------------------------- * NAND / SmartMedia diff --git a/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c b/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c new file mode 100644 index 0000000..a28e53f --- /dev/null +++ b/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c @@ -0,0 +1,277 @@ +/* + * Copyright (C) 2005 SAN People + * Copyright (C) 2008 Atmel + * Copyright (C) 2009 Rob Emanuele + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/types.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/spi/spi.h> +#include <linux/spi/at73c213.h> +#include <linux/clk.h> + +#include <mach/hardware.h> +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/irq.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <mach/board.h> +#include <mach/gpio.h> +#include <mach/at91sam9_smc.h> + +#include "sam9_smc.h" +#include "generic.h" + + +static void __init ek_map_io(void) +{ + /* Initialize processor: 18.432 MHz crystal */ + at91sam9260_initialize(18432000); + + /* DGBU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ + at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS + | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD + | ATMEL_UART_RI); + + /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */ + at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); +} + +static void __init ek_init_irq(void) +{ + at91sam9260_init_interrupts(NULL); +} + + +/* + * USB Host port + */ +static struct at91_usbh_data __initdata ek_usbh_data = { + .ports = 2, +}; + +/* + * USB Device port + */ +static struct at91_udc_data __initdata ek_udc_data = { + .vbus_pin = AT91_PIN_PC5, + .pullup_pin = 0, /* pull-up driven by UDC */ +}; + + +/* + * SPI devices. + */ +static struct spi_board_info ek_spi_devices[] = { +#if !defined(CONFIG_MMC_ATMELMCI) + { /* DataFlash chip */ + .modalias = "mtd_dataflash", + .chip_select = 1, + .max_speed_hz = 15 * 1000 * 1000, + .bus_num = 0, + }, +#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD) + { /* DataFlash card */ + .modalias = "mtd_dataflash", + .chip_select = 0, + .max_speed_hz = 15 * 1000 * 1000, + .bus_num = 0, + }, +#endif +#endif +}; + + +/* + * MACB Ethernet device + */ +static struct at91_eth_data __initdata ek_macb_data = { + .phy_irq_pin = AT91_PIN_PC12, + .is_rmii = 1, +}; + + +/* + * NAND flash + */ +static struct mtd_partition __initdata ek_nand_partition[] = { + { + .name = "Bootstrap", + .offset = 0, + .size = 4 * SZ_1M, + }, + { + .name = "Partition 1", + .offset = MTDPART_OFS_NXTBLK, + .size = 60 * SZ_1M, + }, + { + .name = "Partition 2", + .offset = MTDPART_OFS_NXTBLK, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct mtd_partition * __init nand_partitions(int size, int *num_partitions) +{ + *num_partitions = ARRAY_SIZE(ek_nand_partition); + return ek_nand_partition; +} + +/* det_pin is not connected */ +static struct atmel_nand_data __initdata ek_nand_data = { + .ale = 21, + .cle = 22, + .rdy_pin = AT91_PIN_PC13, + .enable_pin = AT91_PIN_PC14, + .partition_info = nand_partitions, +#if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16) + .bus_width_16 = 1, +#else + .bus_width_16 = 0, +#endif +}; + +static struct sam9_smc_config __initdata ek_nand_smc_config = { + .ncs_read_setup = 0, + .nrd_setup = 2, + .ncs_write_setup = 0, + .nwe_setup = 2, + + .ncs_read_pulse = 4, + .nrd_pulse = 4, + .ncs_write_pulse = 4, + .nwe_pulse = 4, + + .read_cycle = 7, + .write_cycle = 7, + + .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE, + .tdf_cycles = 3, +}; + +static void __init ek_add_device_nand(void) +{ + /* setup bus-width (8 or 16) */ + if (ek_nand_data.bus_width_16) + ek_nand_smc_config.mode |= AT91_SMC_DBW_16; + else + ek_nand_smc_config.mode |= AT91_SMC_DBW_8; + + /* configure chip-select 3 (NAND) */ + sam9_smc_configure(3, &ek_nand_smc_config); + + at91_add_device_nand(&ek_nand_data); +} + + +/* + * MCI (SD/MMC) + * det_pin and wp_pin are not connected + */ +#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE) +static struct mci_platform_data __initdata ek_mmc_data = { + .slot[0] = { + .bus_width = 4, + .detect_pin = -ENODEV, + .wp_pin = -ENODEV, + }, + .slot[1] = { + .bus_width = 4, + .detect_pin = -ENODEV, + .wp_pin = -ENODEV, + }, + +}; +#else +static struct amci_platform_data __initdata ek_mmc_data = { +}; +#endif + +/* + * LEDs + */ +static struct gpio_led ek_leds[] = { + { /* "bottom" led, green, userled1 to be defined */ + .name = "ds5", + .gpio = AT91_PIN_PB12, + .active_low = 1, + .default_trigger = "none", + }, + { /* "power" led, yellow */ + .name = "ds1", + .gpio = AT91_PIN_PB13, + .default_trigger = "heartbeat", + } +}; + +static struct i2c_board_info __initdata ek_i2c_devices[] = { + { + I2C_BOARD_INFO("24c512", 0x50), + }, +}; + + +static void __init ek_board_init(void) +{ + /* Serial */ + at91_add_device_serial(); + /* USB Host */ + at91_add_device_usbh(&ek_usbh_data); + /* USB Device */ + at91_add_device_udc(&ek_udc_data); + /* SPI */ + at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices)); + /* NAND */ + ek_add_device_nand(); + /* Ethernet */ + at91_add_device_eth(&ek_macb_data); + /* MMC */ + at91_add_device_mci(0, &ek_mmc_data); + /* I2C */ + at91_add_device_i2c(ek_i2c_devices, ARRAY_SIZE(ek_i2c_devices)); + /* LEDs */ + at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); + /* PCK0 provides MCLK to the WM8731 */ + at91_set_B_periph(AT91_PIN_PC1, 0); + /* SSC (for WM8731) */ + at91_add_device_ssc(AT91SAM9260_ID_SSC, ATMEL_SSC_TX); +} + +MACHINE_START(AT91SAM9G20EK_2MMC, "Atmel AT91SAM9G20-EK 2 MMC Slot Mod") + /* Maintainer: Rob Emanuele */ + .phys_io = AT91_BASE_SYS, + .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, + .boot_params = AT91_SDRAM_BASE + 0x100, + .timer = &at91sam926x_timer, + .map_io = ek_map_io, + .init_irq = ek_init_irq, + .init_machine = ek_board_init, +MACHINE_END diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h index e6afff8..a635dad 100644 --- a/arch/arm/mach-at91/include/mach/board.h +++ b/arch/arm/mach-at91/include/mach/board.h @@ -37,6 +37,7 @@ #include <linux/leds.h> #include <linux/spi/spi.h> #include <linux/usb/atmel_usba_udc.h> +#include <linux/atmel-mci.h> /* USB Device */ struct at91_udc_data { @@ -63,6 +64,7 @@ struct at91_cf_data { extern void __init at91_add_device_cf(struct at91_cf_data *data); /* MMC / SD */ + /* at91_mci platform config */ struct at91_mmc_data { u8 det_pin; /* card detect IRQ */ unsigned slot_b:1; /* uses Slot B */ @@ -72,6 +74,9 @@ struct at91_mmc_data { }; extern void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data); + /* atmel-mci platform config */ +extern void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data); + /* Ethernet (EMAC & MACB) */ struct at91_eth_data { u32 phy_mask; -- 1.5.3.7 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH 2/2] AT91: atmel-mci: Platform configuration to the the atmel-mci driver [not found] ` <f8889fb59887a970581697beb313363a6a065606.1245778411.git.nicolas.ferre@atmel.com> 2009-06-23 17:39 ` [PATCH 2/2] AT91: atmel-mci: Platform configuration to the the atmel-mci driver Nicolas Ferre @ 2009-06-23 21:36 ` Jean-Christophe PLAGNIOL-VILLARD 2009-06-26 19:26 ` Robert Emanuele 1 sibling, 1 reply; 21+ messages in thread From: Jean-Christophe PLAGNIOL-VILLARD @ 2009-06-23 21:36 UTC (permalink / raw) To: Nicolas Ferre Cc: pierre, avictor.za, linux-kernel, haavard.skinnemoen, linux-arm-kernel, rob On 19:39 Tue 23 Jun , Nicolas Ferre wrote: > From: Rob Emanuele <rob@emanuele.us> > > Created a modified version of the at91sam9g20 evaluation kit platform > (board-sam9g20ek-2slot-mmc.c) and device support to make use of the updated > atmel-mci driver. > As the use of two slots modify GPIO pin allocation, we create another board > file. > > Signed-off-by: Rob Emanuele <rob@emanuele.us> > [nicolas.ferre@atmel.com: printk, slot_count modification in at91sam9260_devices.c file] > Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com> > --- > This requires getting the most updated arch/arm/tools/mach-types from > http://www.arm.linux.org.uk/developer/machines/download.php to have the machine > type for the at91sam9g20ek-2slot-mmc board. > > arch/arm/mach-at91/Kconfig | 7 + > arch/arm/mach-at91/Makefile | 1 + > arch/arm/mach-at91/at91sam9260_devices.c | 96 ++++++++ > arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c | 277 ++++++++++++++++++++++++ > arch/arm/mach-at91/include/mach/board.h | 5 + > 5 files changed, 386 insertions(+), 0 deletions(-) > create mode 100644 arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c > > diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig > index 323b47f..5c8d770 100644 > --- a/arch/arm/mach-at91/Kconfig > +++ b/arch/arm/mach-at91/Kconfig > @@ -276,6 +276,13 @@ config MACH_AT91SAM9G20EK > help > Select this if you are using Atmel's AT91SAM9G20-EK Evaluation Kit. > > +config MACH_AT91SAM9G20EK_2MMC > + bool "Atmel AT91SAM9G20-EK Evaluation Kit modified for 2 MMC Slots" > + depends on ARCH_AT91SAM9G20 > + help > + Select this if you are using an Atmel AT91SAM9G20-EK Evaluation Kit > + Rev A or B modified for 2 MMC Slots. create a new machine id for just such update :( is this not possible to detect it and use the same machine? Best Regards, J. ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 2/2] AT91: atmel-mci: Platform configuration to the the atmel-mci driver 2009-06-23 21:36 ` Jean-Christophe PLAGNIOL-VILLARD @ 2009-06-26 19:26 ` Robert Emanuele 0 siblings, 0 replies; 21+ messages in thread From: Robert Emanuele @ 2009-06-26 19:26 UTC (permalink / raw) To: Jean-Christophe PLAGNIOL-VILLARD Cc: Nicolas Ferre, pierre, avictor.za, linux-kernel, haavard.skinnemoen, linux-arm-kernel After talking with Nicholas Ferre, we decided there were enough changes made to the at91sam9g20-ek (eval kit) that it warranted its own machine and related board-xxx.c file. In addition, Atmel has released schematics for its newest revision of the at91sam9g20-ek (rev. D) which will go into production once their supply of rev. C boards is sufficiently small. The rev. D board is much different than the previous revisions. The new machine with its board file is an excellent base to build on once the rev. D board is released. Thank you, Rob Emanuele ^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2009-09-02 7:31 UTC | newest]
Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-06-17 0:54 [PATCH 1/6] atmel-mci: Unified Atmel MCI drivers (AVR32 & AT91) Rob Emanuele
2009-06-17 0:54 ` [PATCH 2/6] atmel-mci: Platform configuration to the the atmel-mci driver Rob Emanuele
2009-06-17 10:27 ` Nicolas Ferre
2009-06-18 19:58 ` Andrew Victor
2009-06-18 20:00 ` Andrew Victor
2009-06-17 0:54 ` [PATCH 3/6] atmel-mci: Optional controller reset before every command Rob Emanuele
2009-06-17 8:32 ` Marc Pignat
2009-06-17 18:27 ` Robert Emanuele
2009-06-17 0:54 ` [PATCH 4/6] atmel-mci: CLKDIV cap to restrict the MCI controller speed Rob Emanuele
2009-06-17 0:54 ` [PATCH 5/6] atmel-mci: Power control option for each MMC Slot Rob Emanuele
2009-06-17 8:08 ` Marc Pignat
2009-06-17 0:54 ` [PATCH 6/6] atmel-mci: Platform driver MMC slot power control Rob Emanuele
2009-06-17 1:23 ` Ryan Mallon
2009-06-17 9:56 ` [PATCH 1/6] atmel-mci: Unified Atmel MCI drivers (AVR32 & AT91) Nicolas Ferre
2009-06-17 10:08 ` Haavard Skinnemoen
2009-06-23 16:28 ` Nicolas Ferre
[not found] ` <95818a17c2b96d3769f4e1d3de26208647111758.1245778411.git.nicolas.ferre@atmel.com>
2009-06-23 17:39 ` [PATCH 1/2] " Nicolas Ferre
2009-09-02 7:31 ` Haavard Skinnemoen
[not found] ` <f8889fb59887a970581697beb313363a6a065606.1245778411.git.nicolas.ferre@atmel.com>
2009-06-23 17:39 ` [PATCH 2/2] AT91: atmel-mci: Platform configuration to the the atmel-mci driver Nicolas Ferre
2009-06-23 21:36 ` Jean-Christophe PLAGNIOL-VILLARD
2009-06-26 19:26 ` Robert Emanuele
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox