Hi Manuel, On Mon, Nov 20, 2006 at 01:01:48PM +0100, Manuel Lauss wrote: > On Mon, Nov 20, 2006 at 11:49:22AM +0100, Freddy Spierenburg wrote: > > Are you working with a real MMC card or with an SD-card? > > SD cards so far. MMC seems broken in a different way. Broke in a different way? I can positively confirm that I have a 512MB and 1GB MMC-card working with the patch I hereby send to you. I've also tried a DaneElec 1GB and Kingston 1GB SD-card and SanDisk 128MB MicroSD-card. All failed. > Yes, please. I'd like to give it a spin Please find it attached. -- $ cat ~/.signature Freddy Spierenburg <freddy@xxxxxxxxxxxxxxx> http://freddy.snarl.nl/ GnuPG: 0x7941D1E1=C948 5851 26D2 FA5C 39F1 E588 6F17 FD5D 7941 D1E1 $ # Please read http://www.ietf.org/rfc/rfc2015.txt before complain!
diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 7bddcc4..328039d 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -22,7 +22,7 @@ # # Select the object file format to substitute into the linker script. # ifdef CONFIG_CPU_LITTLE_ENDIAN -32bit-tool-prefix = mipsel-linux- +32bit-tool-prefix = mipsel-linux-gnu- 64bit-tool-prefix = mips64el-linux- 32bit-bfd = elf32-tradlittlemips 64bit-bfd = elf64-tradlittlemips diff --git a/arch/mips/au1000/common/clocks.c b/arch/mips/au1000/common/clocks.c index 3ce6cac..b1f5524 100644 --- a/arch/mips/au1000/common/clocks.c +++ b/arch/mips/au1000/common/clocks.c @@ -46,6 +46,7 @@ unsigned int get_au1x00_speed(void) { return au1x00_clock; } +EXPORT_SYMBOL(get_au1x00_speed); diff --git a/arch/mips/au1000/common/platform.c b/arch/mips/au1000/common/platform.c index 48d3f54..65376ef 100644 --- a/arch/mips/au1000/common/platform.c +++ b/arch/mips/au1000/common/platform.c @@ -72,6 +72,38 @@ static struct platform_device au1100_lcd .num_resources = ARRAY_SIZE(au1100_lcd_resources), .resource = au1100_lcd_resources, }; + +static struct resource au1xxx_mmc_resources[] = { + [0] = { + .start = SD0_PHYS_ADDR, + .end = SD0_PHYS_ADDR + 0x40, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = SD1_PHYS_ADDR, + .end = SD1_PHYS_ADDR + 0x40, + .flags = IORESOURCE_MEM, + }, + [2] = { + .start = AU1100_SD_INT, + .end = AU1100_SD_INT, + .flags = IORESOURCE_IRQ, + } +}; + +static u64 au1xxx_mmc_dmamask = ~(u32)0; + +static struct platform_device au1xxx_mmc_device = { + .name = "au1xxx-mmc", + .id = 0, + .dev = { + .dma_mask = &au1xxx_mmc_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(au1xxx_mmc_resources), + .resource = au1xxx_mmc_resources, +}; + #endif #ifdef CONFIG_SOC_AU1200 @@ -276,6 +308,7 @@ static struct platform_device *au1xxx_pl &au1x00_pcmcia_device, #ifdef CONFIG_FB_AU1100 &au1100_lcd_device, + &au1xxx_mmc_device, #endif #ifdef CONFIG_SOC_AU1200 #if 0 /* fixme */ diff --git a/drivers/mmc/au1xmmc.c b/drivers/mmc/au1xmmc.c index 8d84b04..be21e7c 100644 --- a/drivers/mmc/au1xmmc.c +++ b/drivers/mmc/au1xmmc.c @@ -47,6 +47,7 @@ #include <linux/mmc/protocol.h> #include <asm/io.h> #include <asm/mach-au1x00/au1000.h> #include <asm/mach-au1x00/au1xxx_dbdma.h> +#include <asm/mach-au1x00/au1xxx_gpio.h> #include <asm/mach-au1x00/au1100_mmc.h> #include <asm/scatterlist.h> @@ -55,8 +56,13 @@ #include "au1xmmc.h" #define DRIVER_NAME "au1xxx-mmc" +/* Set this for Dare processor board adjustments */ +//#define MMC_DARE_PROCESSOR_BOARD +/* DMA isn't implemented yet: */ +//#define MMC_DARE_DMA_IMPLEMENTED + /* Set this to enable special debugging macros */ -/* #define MMC_DEBUG */ +#define MMC_DEBUG #ifdef MMC_DEBUG #define DEBUG(fmt, idx, args...) printk("au1xx(%d): DEBUG: " fmt, idx, ##args) @@ -66,17 +72,9 @@ #endif const struct { u32 iobase; - u32 tx_devid, rx_devid; - u16 bcsrpwr; - u16 bcsrstatus; u16 wpstatus; } au1xmmc_card_table[] = { - { SD0_BASE, DSCR_CMD0_SDMS_TX0, DSCR_CMD0_SDMS_RX0, - BCSR_BOARD_SD0PWR, BCSR_INT_SD0INSERT, BCSR_STATUS_SD0WP }, -#ifndef CONFIG_MIPS_DB1200 - { SD1_BASE, DSCR_CMD0_SDMS_TX1, DSCR_CMD0_SDMS_RX1, - BCSR_BOARD_DS1PWR, BCSR_INT_SD1INSERT, BCSR_STATUS_SD1WP } -#endif + { SD0_BASE, BCSR_BOARD_SD0_WP }, }; #define AU1XMMC_CONTROLLER_COUNT \ @@ -84,7 +82,11 @@ #define AU1XMMC_CONTROLLER_COUNT \ /* This array stores pointers for the hosts (used by the IRQ handler) */ struct au1xmmc_host *au1xmmc_hosts[AU1XMMC_CONTROLLER_COUNT]; +#ifdef MMC_DARE_DMA_IMPLEMENTED static int dma = 1; +#else +static int dma = 0; /* DMA isn't implemented yet in this driver */ +#endif #ifdef MODULE MODULE_PARM(dma, "i"); @@ -139,25 +141,33 @@ static inline void SEND_STOP(struct au1x static void au1xmmc_set_power(struct au1xmmc_host *host, int state) { - - u32 val = au1xmmc_card_table[host->id].bcsrpwr; - - bcsr->board &= ~val; - if (state) bcsr->board |= val; - - au_sync_delay(1); +#ifdef MMC_DARE_PROCESSOR_BOARD + state = 1; /* Force gpio high for card detection */ + au1xxx_gpio_write(19, state ? 1 : 0); +#else /* db1100 board */ + mmc_power(host->id, state); +#endif } static inline int au1xmmc_card_inserted(struct au1xmmc_host *host) { - return (bcsr->sig_status & au1xmmc_card_table[host->id].bcsrstatus) - ? 1 : 0; + int res = 0; + /* Note: card inserted checks at read-only switch, + * if a card is set to read-only, it won't be recognized */ +#ifdef MMC_DARE_PROCESSOR_BOARD + /* Note: removing power (gpio19 low), makes it look like + * the card has been removed */ + res = au1xxx_gpio_read(19); +#else /* db1100 board */ + mmc_card_inserted(host->id, &res); +#endif + return res; } static inline int au1xmmc_card_readonly(struct au1xmmc_host *host) { - return (bcsr->status & au1xmmc_card_table[host->id].wpstatus) - ? 1 : 0; + /* Not implemented */ + return 0; } static void au1xmmc_finish_request(struct au1xmmc_host *host) @@ -177,8 +187,6 @@ static void au1xmmc_finish_request(struc host->status = HOST_S_IDLE; - bcsr->disk_leds |= (1 << 8); - mmc_request_done(host->mmc, mrq); } @@ -531,6 +539,7 @@ static void au1xmmc_cmd_complete(struct host->status = HOST_S_DATA; + #ifdef MMC_DARE_DMA_IMPLEMENTED if (host->flags & HOST_F_DMA) { u32 channel = DMA_CHANNEL(host); @@ -545,6 +554,7 @@ static void au1xmmc_cmd_complete(struct au1xxx_dbdma_start(channel); } + #endif } static void au1xmmc_set_clock(struct au1xmmc_host *host, int rate) @@ -599,6 +609,7 @@ au1xmmc_prepare_data(struct au1xmmc_host au_writel((1 << data->blksz_bits) - 1, HOST_BLKSIZE(host)); + #ifdef MMC_DARE_DMA_IMPLEMENTED if (host->flags & HOST_F_DMA) { int i; u32 channel = DMA_CHANNEL(host); @@ -616,12 +627,14 @@ au1xmmc_prepare_data(struct au1xmmc_host flags = DDMA_FLAGS_IE; if (host->flags & HOST_F_XMIT){ + ret = 0; ret = au1xxx_dbdma_put_source_flags(channel, (void *) (page_address(sg->page) + sg->offset), len, flags); } else { + ret = 0; ret = au1xxx_dbdma_put_dest_flags(channel, (void *) (page_address(sg->page) + sg->offset), @@ -634,7 +647,9 @@ au1xmmc_prepare_data(struct au1xmmc_host datalen -= len; } } - else { + else + #endif + { host->pio.index = 0; host->pio.offset = 0; host->pio.len = datalen; @@ -648,9 +663,11 @@ au1xmmc_prepare_data(struct au1xmmc_host return MMC_ERR_NONE; +#ifdef MMC_DARE_DMA_IMPLEMENTED dataerr: dma_unmap_sg(mmc_dev(host->mmc),data->sg,data->sg_len,host->dma.dir); return MMC_ERR_TIMEOUT; +#endif } /* static void au1xmmc_request @@ -669,8 +686,6 @@ static void au1xmmc_request(struct mmc_h host->mrq = mrq; host->status = HOST_S_CMD; - bcsr->disk_leds &= ~(1 << 8); - if (mrq->data) { FLUSH_FIFO(host); ret = au1xmmc_prepare_data(host, mrq->data); @@ -737,6 +752,7 @@ static void au1xmmc_set_ios(struct mmc_h } } +#ifdef MMC_DARE_DMA_IMPLEMENTED static void au1xmmc_dma_callback(int irq, void *dev_id, struct pt_regs *regs) { struct au1xmmc_host *host = (struct au1xmmc_host *) dev_id; @@ -751,6 +767,7 @@ static void au1xmmc_dma_callback(int irq tasklet_schedule(&host->data_task); } +#endif #define STATUS_TIMEOUT (SD_STATUS_RAT | SD_STATUS_DT) #define STATUS_DATA_IN (SD_STATUS_NE) @@ -845,14 +862,16 @@ static void au1xmmc_poll_event(unsigned mod_timer(&host->timer, jiffies + AU1XMMC_DETECT_TIMEOUT); } +#ifdef MMC_DARE_DMA_IMPLEMENTED static dbdev_tab_t au1xmmc_mem_dbdev = { DSCR_CMD0_ALWAYS, DEV_FLAGS_ANYUSE, 0, 8, 0x00000000, 0, 0 }; +#endif static void au1xmmc_init_dma(struct au1xmmc_host *host) { - +#ifdef MMC_DARE_DMA_IMPLEMENTED u32 rxchan, txchan; int txid = au1xmmc_card_table[host->id].tx_devid; @@ -879,6 +898,7 @@ static void au1xmmc_init_dma(struct au1x host->tx_chan = txchan; host->rx_chan = rxchan; +#endif } struct mmc_host_ops au1xmmc_ops = { @@ -985,8 +1005,10 @@ static int __devexit au1xmmc_remove(stru mmc_remove_host(host->mmc); + #ifdef MMC_DARE_DMA_IMPLEMENTED au1xxx_dbdma_chan_free(host->tx_chan); au1xxx_dbdma_chan_free(host->rx_chan); + #endif au_writel(0x0, HOST_ENABLE(host)); au_sync(); diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c diff --git a/include/asm-mips/mach-au1x00/au1xxx.h b/include/asm-mips/mach-au1x00/au1xxx.h diff --git a/include/asm-mips/mach-db1x00/db1x00.h b/include/asm-mips/mach-db1x00/db1x00.h index 7b28b23..5912361 100644 --- a/include/asm-mips/mach-db1x00/db1x00.h +++ b/include/asm-mips/mach-db1x00/db1x00.h @@ -177,6 +177,24 @@ #define mmc_power_on(_n_) \ } \ } while (0) +/* + * Remove power from card slot(s). + */ +#define mmc_power(_n_, state) \ + do { \ + BCSR * const bcsr = (BCSR *)0xAE000000; \ + unsigned long mmc_pwr, board_specific; \ + if ((_n_)) { \ + mmc_pwr = BCSR_BOARD_SD1_PWR; \ + } else { \ + mmc_pwr = BCSR_BOARD_SD0_PWR; \ + } \ + board_specific = au_readl((unsigned long)(&bcsr->specific)); \ + board_specific &= ~mmc_pwr; \ + board_specific |= (state ? mmc_pwr : 0); \ + au_writel(board_specific, (int)(&bcsr->specific)); \ + au_sync(); \ + } while (0) /* NAND defines */ /* Timing values as described in databook, * ns value stripped of diff --git a/include/asm-mips/mach-pb1x00/pb1100.h b/include/asm-mips/mach-pb1x00/pb1100.h
Attachment:
signature.asc
Description: Digital signature