Commit ceaa57fe authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://bk.arm.linux.org.uk/linux-2.6-mmc

into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents e527f34c 1ca3acaf
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <asm/arch/lubbock.h> #include <asm/arch/lubbock.h>
#include <asm/arch/udc.h> #include <asm/arch/udc.h>
#include <asm/arch/pxafb.h> #include <asm/arch/pxafb.h>
#include <asm/arch/mmc.h>
#include <asm/hardware/sa1111.h> #include <asm/hardware/sa1111.h>
#include "generic.h" #include "generic.h"
...@@ -183,10 +184,25 @@ static struct pxafb_mach_info sharp_lm8v31 __initdata = { ...@@ -183,10 +184,25 @@ static struct pxafb_mach_info sharp_lm8v31 __initdata = {
.lccr3 = LCCR3_PCP | LCCR3_Acb(255), .lccr3 = LCCR3_PCP | LCCR3_Acb(255),
}; };
static int lubbock_mci_init(struct device *dev, irqreturn_t (*lubbock_detect_int)(int, void *, struct pt_regs *), void *data)
{
/* setup GPIO for PXA25x MMC controller */
pxa_gpio_mode(GPIO6_MMCCLK_MD);
pxa_gpio_mode(GPIO8_MMCCS0_MD);
return 0;
}
static struct pxamci_platform_data lubbock_mci_platform_data = {
.ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
.init = lubbock_mci_init,
};
static void __init lubbock_init(void) static void __init lubbock_init(void)
{ {
pxa_set_udc_info(&udc_info); pxa_set_udc_info(&udc_info);
set_pxa_fb_info(&sharp_lm8v31); set_pxa_fb_info(&sharp_lm8v31);
pxa_set_mci_info(&lubbock_mci_platform_data);
(void) platform_add_devices(devices, ARRAY_SIZE(devices)); (void) platform_add_devices(devices, ARRAY_SIZE(devices));
} }
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include <asm/arch/pxa-regs.h> #include <asm/arch/pxa-regs.h>
#include <asm/arch/mainstone.h> #include <asm/arch/mainstone.h>
#include <asm/arch/pxafb.h> #include <asm/arch/pxafb.h>
#include <asm/arch/mmc.h>
#include "generic.h" #include "generic.h"
...@@ -170,6 +171,61 @@ static struct pxafb_mach_info toshiba_ltm035a776c __initdata = { ...@@ -170,6 +171,61 @@ static struct pxafb_mach_info toshiba_ltm035a776c __initdata = {
.pxafb_backlight_power = mainstone_backlight_power, .pxafb_backlight_power = mainstone_backlight_power,
}; };
static int mainstone_mci_init(struct device *dev, irqreturn_t (*mstone_detect_int)(int, void *, struct pt_regs *), void *data)
{
int err;
/*
* setup GPIO for PXA27x MMC controller
*/
pxa_gpio_mode(GPIO32_MMCCLK_MD);
pxa_gpio_mode(GPIO112_MMCCMD_MD);
pxa_gpio_mode(GPIO92_MMCDAT0_MD);
pxa_gpio_mode(GPIO109_MMCDAT1_MD);
pxa_gpio_mode(GPIO110_MMCDAT2_MD);
pxa_gpio_mode(GPIO111_MMCDAT3_MD);
/* make sure SD/Memory Stick multiplexer's signals
* are routed to MMC controller
*/
MST_MSCWR1 &= ~MST_MSCWR1_MS_SEL;
err = request_irq(MAINSTONE_MMC_IRQ, mstone_detect_int, SA_INTERRUPT,
"MMC card detect", data);
if (err) {
printk(KERN_ERR "mainstone_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
return -1;
}
return 0;
}
static void mainstone_mci_setpower(struct device *dev, unsigned int vdd)
{
struct pxamci_platform_data* p_d = dev->platform_data;
if (( 1 << vdd) & p_d->ocr_mask) {
printk(KERN_DEBUG "%s: on\n", __FUNCTION__);
MST_MSCWR1 |= MST_MSCWR1_MMC_ON;
MST_MSCWR1 &= ~MST_MSCWR1_MS_SEL;
} else {
printk(KERN_DEBUG "%s: off\n", __FUNCTION__);
MST_MSCWR1 &= ~MST_MSCWR1_MMC_ON;
}
}
static void mainstone_mci_exit(struct device *dev, void *data)
{
free_irq(MAINSTONE_MMC_IRQ, data);
}
static struct pxamci_platform_data mainstone_mci_platform_data = {
.ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
.init = mainstone_mci_init,
.setpower = mainstone_mci_setpower,
.exit = mainstone_mci_exit,
};
static void __init mainstone_init(void) static void __init mainstone_init(void)
{ {
platform_device_register(&smc91x_device); platform_device_register(&smc91x_device);
...@@ -180,6 +236,8 @@ static void __init mainstone_init(void) ...@@ -180,6 +236,8 @@ static void __init mainstone_init(void)
set_pxa_fb_info(&toshiba_ltm04c380k); set_pxa_fb_info(&toshiba_ltm04c380k);
else else
set_pxa_fb_info(&toshiba_ltm035a776c); set_pxa_fb_info(&toshiba_ltm035a776c);
pxa_set_mci_info(&mainstone_mci_platform_data);
} }
......
...@@ -72,11 +72,6 @@ struct pxamci_host { ...@@ -72,11 +72,6 @@ struct pxamci_host {
unsigned int dma_dir; unsigned int dma_dir;
}; };
/*
* The base MMC clock rate
*/
#define CLOCKRATE 20000000
static inline unsigned int ns_to_clocks(unsigned int ns) static inline unsigned int ns_to_clocks(unsigned int ns)
{ {
return (ns * (CLOCKRATE / 1000000) + 999) / 1000; return (ns * (CLOCKRATE / 1000000) + 999) / 1000;
...@@ -244,7 +239,24 @@ static int pxamci_cmd_done(struct pxamci_host *host, unsigned int stat) ...@@ -244,7 +239,24 @@ static int pxamci_cmd_done(struct pxamci_host *host, unsigned int stat)
if (stat & STAT_TIME_OUT_RESPONSE) { if (stat & STAT_TIME_OUT_RESPONSE) {
cmd->error = MMC_ERR_TIMEOUT; cmd->error = MMC_ERR_TIMEOUT;
} else if (stat & STAT_RES_CRC_ERR && cmd->flags & MMC_RSP_CRC) { } else if (stat & STAT_RES_CRC_ERR && cmd->flags & MMC_RSP_CRC) {
#ifdef CONFIG_PXA27x
/*
* workaround for erratum #42:
* Intel PXA27x Family Processor Specification Update Rev 001
*/
if (cmd->opcode == MMC_ALL_SEND_CID ||
cmd->opcode == MMC_SEND_CSD ||
cmd->opcode == MMC_SEND_CID) {
/* a bogus CRC error can appear if the msb of
the 15 byte response is a one */
if ((cmd->resp[0] & 0x80000000) == 0)
cmd->error = MMC_ERR_BADCRC;
} else {
DBG("ignoring CRC from command %d - *risky*\n",cmd->opcode);
}
#else
cmd->error = MMC_ERR_BADCRC; cmd->error = MMC_ERR_BADCRC;
#endif
} }
pxamci_disable_irq(host, END_CMD_RES); pxamci_disable_irq(host, END_CMD_RES);
...@@ -429,8 +441,8 @@ static int pxamci_probe(struct device *dev) ...@@ -429,8 +441,8 @@ static int pxamci_probe(struct device *dev)
} }
mmc->ops = &pxamci_ops; mmc->ops = &pxamci_ops;
mmc->f_min = 312500; mmc->f_min = CLOCKRATE_MIN;
mmc->f_max = 20000000; mmc->f_max = CLOCKRATE_MAX;
/* /*
* We can do SG-DMA, but we don't because we never know how much * We can do SG-DMA, but we don't because we never know how much
...@@ -460,8 +472,7 @@ static int pxamci_probe(struct device *dev) ...@@ -460,8 +472,7 @@ static int pxamci_probe(struct device *dev)
spin_lock_init(&host->lock); spin_lock_init(&host->lock);
host->res = r; host->res = r;
host->irq = irq; host->irq = irq;
host->imask = TXFIFO_WR_REQ|RXFIFO_RD_REQ|CLK_IS_OFF|STOP_CMD| host->imask = MMC_I_MASK_ALL;
END_CMD_RES|PRG_DONE|DATA_TRAN_DONE;
host->base = ioremap(r->start, SZ_4K); host->base = ioremap(r->start, SZ_4K);
if (!host->base) { if (!host->base) {
...@@ -478,10 +489,6 @@ static int pxamci_probe(struct device *dev) ...@@ -478,10 +489,6 @@ static int pxamci_probe(struct device *dev)
writel(64, host->base + MMC_RESTO); writel(64, host->base + MMC_RESTO);
writel(host->imask, host->base + MMC_I_MASK); writel(host->imask, host->base + MMC_I_MASK);
pxa_gpio_mode(GPIO6_MMCCLK_MD);
pxa_gpio_mode(GPIO8_MMCCS0_MD);
pxa_set_cken(CKEN12_MMC, 1);
host->dma = pxa_request_dma(DRIVER_NAME, DMA_PRIO_LOW, host->dma = pxa_request_dma(DRIVER_NAME, DMA_PRIO_LOW,
pxamci_dma_irq, host); pxamci_dma_irq, host);
if (host->dma < 0) { if (host->dma < 0) {
...@@ -498,6 +505,8 @@ static int pxamci_probe(struct device *dev) ...@@ -498,6 +505,8 @@ static int pxamci_probe(struct device *dev)
if (host->pdata && host->pdata->init) if (host->pdata && host->pdata->init)
host->pdata->init(dev, pxamci_detect_irq, mmc); host->pdata->init(dev, pxamci_detect_irq, mmc);
pxa_set_cken(CKEN12_MMC, 1);
mmc_add_host(mmc); mmc_add_host(mmc);
return 0; return 0;
......
...@@ -70,6 +70,16 @@ ...@@ -70,6 +70,16 @@
#define BUF_PART_FULL (1 << 0) #define BUF_PART_FULL (1 << 0)
#define MMC_I_MASK 0x0028 #define MMC_I_MASK 0x0028
/*PXA27x MMC interrupts*/
#define SDIO_SUSPEND_ACK (1 << 12)
#define SDIO_INT (1 << 11)
#define RD_STALLED (1 << 10)
#define RES_ERR (1 << 9)
#define DAT_ERR (1 << 8)
#define TINT (1 << 7)
/*PXA2xx MMC interrupts*/
#define TXFIFO_WR_REQ (1 << 6) #define TXFIFO_WR_REQ (1 << 6)
#define RXFIFO_RD_REQ (1 << 5) #define RXFIFO_RD_REQ (1 << 5)
#define CLK_IS_OFF (1 << 4) #define CLK_IS_OFF (1 << 4)
...@@ -78,6 +88,12 @@ ...@@ -78,6 +88,12 @@
#define PRG_DONE (1 << 1) #define PRG_DONE (1 << 1)
#define DATA_TRAN_DONE (1 << 0) #define DATA_TRAN_DONE (1 << 0)
#ifdef CONFIG_PXA27x
#define MMC_I_MASK_ALL 0x00001fff
#else
#define MMC_I_MASK_ALL 0x0000007f
#endif
#define MMC_I_REG 0x002c #define MMC_I_REG 0x002c
/* same as MMC_I_MASK */ /* same as MMC_I_MASK */
...@@ -92,3 +108,17 @@ ...@@ -92,3 +108,17 @@
#define MMC_RXFIFO 0x0040 /* 8 bit */ #define MMC_RXFIFO 0x0040 /* 8 bit */
#define MMC_TXFIFO 0x0044 /* 8 bit */ #define MMC_TXFIFO 0x0044 /* 8 bit */
/*
* The base MMC clock rate
*/
#ifdef CONFIG_PXA27x
#define CLOCKRATE_MIN 304688
#define CLOCKRATE_MAX 19500000
#else
#define CLOCKRATE_MIN 312500
#define CLOCKRATE_MAX 20000000
#endif
#define CLOCKRATE CLOCKRATE_MAX
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment