Commit 1ca3acaf authored by Nicolas Pitre's avatar Nicolas Pitre Committed by Russell King

[ARM PATCH] 2271/3: MMC for Mainstone/PXA27x

Patch from Nicolas Pitre

... with a bit of reorg to make the core code a bit more generic too.

Signed-off-by: Nicolas Pitre
Signed-off-by: Russell King
parent 38838b73
......@@ -33,6 +33,7 @@
#include <asm/arch/lubbock.h>
#include <asm/arch/udc.h>
#include <asm/arch/pxafb.h>
#include <asm/arch/mmc.h>
#include <asm/hardware/sa1111.h>
#include "generic.h"
......@@ -183,10 +184,25 @@ static struct pxafb_mach_info sharp_lm8v31 __initdata = {
.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)
{
pxa_set_udc_info(&udc_info);
set_pxa_fb_info(&sharp_lm8v31);
pxa_set_mci_info(&lubbock_mci_platform_data);
(void) platform_add_devices(devices, ARRAY_SIZE(devices));
}
......
......@@ -34,6 +34,7 @@
#include <asm/arch/pxa-regs.h>
#include <asm/arch/mainstone.h>
#include <asm/arch/pxafb.h>
#include <asm/arch/mmc.h>
#include "generic.h"
......@@ -170,6 +171,61 @@ static struct pxafb_mach_info toshiba_ltm035a776c __initdata = {
.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)
{
platform_device_register(&smc91x_device);
......@@ -180,6 +236,8 @@ static void __init mainstone_init(void)
set_pxa_fb_info(&toshiba_ltm04c380k);
else
set_pxa_fb_info(&toshiba_ltm035a776c);
pxa_set_mci_info(&mainstone_mci_platform_data);
}
......
......@@ -72,11 +72,6 @@ struct pxamci_host {
unsigned int dma_dir;
};
/*
* The base MMC clock rate
*/
#define CLOCKRATE 20000000
static inline unsigned int ns_to_clocks(unsigned int ns)
{
return (ns * (CLOCKRATE / 1000000) + 999) / 1000;
......@@ -244,7 +239,24 @@ static int pxamci_cmd_done(struct pxamci_host *host, unsigned int stat)
if (stat & STAT_TIME_OUT_RESPONSE) {
cmd->error = MMC_ERR_TIMEOUT;
} 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;
#endif
}
pxamci_disable_irq(host, END_CMD_RES);
......@@ -429,8 +441,8 @@ static int pxamci_probe(struct device *dev)
}
mmc->ops = &pxamci_ops;
mmc->f_min = 312500;
mmc->f_max = 20000000;
mmc->f_min = CLOCKRATE_MIN;
mmc->f_max = CLOCKRATE_MAX;
/*
* 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)
spin_lock_init(&host->lock);
host->res = r;
host->irq = irq;
host->imask = TXFIFO_WR_REQ|RXFIFO_RD_REQ|CLK_IS_OFF|STOP_CMD|
END_CMD_RES|PRG_DONE|DATA_TRAN_DONE;
host->imask = MMC_I_MASK_ALL;
host->base = ioremap(r->start, SZ_4K);
if (!host->base) {
......@@ -478,10 +489,6 @@ static int pxamci_probe(struct device *dev)
writel(64, host->base + MMC_RESTO);
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,
pxamci_dma_irq, host);
if (host->dma < 0) {
......@@ -498,6 +505,8 @@ static int pxamci_probe(struct device *dev)
if (host->pdata && host->pdata->init)
host->pdata->init(dev, pxamci_detect_irq, mmc);
pxa_set_cken(CKEN12_MMC, 1);
mmc_add_host(mmc);
return 0;
......
......@@ -70,6 +70,16 @@
#define BUF_PART_FULL (1 << 0)
#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 RXFIFO_RD_REQ (1 << 5)
#define CLK_IS_OFF (1 << 4)
......@@ -78,6 +88,12 @@
#define PRG_DONE (1 << 1)
#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
/* same as MMC_I_MASK */
......@@ -92,3 +108,17 @@
#define MMC_RXFIFO 0x0040 /* 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