···91919292 If unsure, say N.93939494+config MMC_AT91RM92009595+ tristate "AT91RM9200 SD/MMC Card Interface support"9696+ depends on ARCH_AT91RM9200 && MMC9797+ help9898+ This selects the AT91RM9200 MCI controller.9999+100100+ If unsure, say N.101101+102102+config MMC_IMX103103+ tristate "Motorola i.MX Multimedia Card Interface support"104104+ depends on ARCH_IMX && MMC105105+ help106106+ This selects the Motorola i.MX Multimedia card Interface.107107+ If you have a i.MX platform with a Multimedia Card slot,108108+ say Y or M here.109109+110110+ If unsure, say N.111111+94112endmenu
···11+/*22+ * linux/drivers/mmc/at91_mci.c - ATMEL AT91RM9200 MCI Driver33+ *44+ * Copyright (C) 2005 Cougar Creek Computing Devices Ltd, All Rights Reserved55+ *66+ * Copyright (C) 2006 Malcolm Noyes77+ *88+ * This program is free software; you can redistribute it and/or modify99+ * it under the terms of the GNU General Public License version 2 as1010+ * published by the Free Software Foundation.1111+ */1212+1313+/*1414+ This is the AT91RM9200 MCI driver that has been tested with both MMC cards1515+ and SD-cards. Boards that support write protect are now supported.1616+ The CCAT91SBC001 board does not support SD cards.1717+1818+ The three entry points are at91_mci_request, at91_mci_set_ios1919+ and at91_mci_get_ro.2020+2121+ SET IOS2222+ This configures the device to put it into the correct mode and clock speed2323+ required.2424+2525+ MCI REQUEST2626+ MCI request processes the commands sent in the mmc_request structure. This2727+ can consist of a processing command and a stop command in the case of2828+ multiple block transfers.2929+3030+ There are three main types of request, commands, reads and writes.3131+3232+ Commands are straight forward. The command is submitted to the controller and3333+ the request function returns. When the controller generates an interrupt to indicate3434+ the command is finished, the response to the command are read and the mmc_request_done3535+ function called to end the request.3636+3737+ Reads and writes work in a similar manner to normal commands but involve the PDC (DMA)3838+ controller to manage the transfers.3939+4040+ A read is done from the controller directly to the scatterlist passed in from the request.4141+ Due to a bug in the controller, when a read is completed, all the words are byte4242+ swapped in the scatterlist buffers.4343+4444+ The sequence of read interrupts is: ENDRX, RXBUFF, CMDRDY4545+4646+ A write is slightly different in that the bytes to write are read from the scatterlist4747+ into a dma memory buffer (this is in case the source buffer should be read only). The4848+ entire write buffer is then done from this single dma memory buffer.4949+5050+ The sequence of write interrupts is: ENDTX, TXBUFE, NOTBUSY, CMDRDY5151+5252+ GET RO5353+ Gets the status of the write protect pin, if available.5454+*/5555+5656+#include <linux/config.h>5757+#include <linux/module.h>5858+#include <linux/moduleparam.h>5959+#include <linux/init.h>6060+#include <linux/ioport.h>6161+#include <linux/platform_device.h>6262+#include <linux/interrupt.h>6363+#include <linux/blkdev.h>6464+#include <linux/delay.h>6565+#include <linux/err.h>6666+#include <linux/dma-mapping.h>6767+#include <linux/clk.h>6868+6969+#include <linux/mmc/host.h>7070+#include <linux/mmc/protocol.h>7171+7272+#include <asm/io.h>7373+#include <asm/irq.h>7474+#include <asm/mach/mmc.h>7575+#include <asm/arch/board.h>7676+#include <asm/arch/gpio.h>7777+#include <asm/arch/at91rm9200_mci.h>7878+#include <asm/arch/at91rm9200_pdc.h>7979+8080+#define DRIVER_NAME "at91_mci"8181+8282+#undef SUPPORT_4WIRE8383+8484+#ifdef CONFIG_MMC_DEBUG8585+#define DBG(fmt...) \8686+ printk(fmt)8787+#else8888+#define DBG(fmt...) do { } while (0)8989+#endif9090+9191+static struct clk *mci_clk;9292+9393+#define FL_SENT_COMMAND (1 << 0)9494+#define FL_SENT_STOP (1 << 1)9595+9696+9797+9898+/*9999+ * Read from a MCI register.100100+ */101101+static inline unsigned long at91_mci_read(unsigned int reg)102102+{103103+ void __iomem *mci_base = (void __iomem *)AT91_VA_BASE_MCI;104104+105105+ return __raw_readl(mci_base + reg);106106+}107107+108108+/*109109+ * Write to a MCI register.110110+ */111111+static inline void at91_mci_write(unsigned int reg, unsigned long value)112112+{113113+ void __iomem *mci_base = (void __iomem *)AT91_VA_BASE_MCI;114114+115115+ __raw_writel(value, mci_base + reg);116116+}117117+118118+/*119119+ * Low level type for this driver120120+ */121121+struct at91mci_host122122+{123123+ struct mmc_host *mmc;124124+ struct mmc_command *cmd;125125+ struct mmc_request *request;126126+127127+ struct at91_mmc_data *board;128128+ int present;129129+130130+ /*131131+ * Flag indicating when the command has been sent. This is used to132132+ * work out whether or not to send the stop133133+ */134134+ unsigned int flags;135135+ /* flag for current bus settings */136136+ u32 bus_mode;137137+138138+ /* DMA buffer used for transmitting */139139+ unsigned int* buffer;140140+ dma_addr_t physical_address;141141+ unsigned int total_length;142142+143143+ /* Latest in the scatterlist that has been enabled for transfer, but not freed */144144+ int in_use_index;145145+146146+ /* Latest in the scatterlist that has been enabled for transfer */147147+ int transfer_index;148148+};149149+150150+/*151151+ * Copy from sg to a dma block - used for transfers152152+ */153153+static inline void at91mci_sg_to_dma(struct at91mci_host *host, struct mmc_data *data)154154+{155155+ unsigned int len, i, size;156156+ unsigned *dmabuf = host->buffer;157157+158158+ size = host->total_length;159159+ len = data->sg_len;160160+161161+ /*162162+ * Just loop through all entries. Size might not163163+ * be the entire list though so make sure that164164+ * we do not transfer too much.165165+ */166166+ for (i = 0; i < len; i++) {167167+ struct scatterlist *sg;168168+ int amount;169169+ int index;170170+ unsigned int *sgbuffer;171171+172172+ sg = &data->sg[i];173173+174174+ sgbuffer = kmap_atomic(sg->page, KM_BIO_SRC_IRQ) + sg->offset;175175+ amount = min(size, sg->length);176176+ size -= amount;177177+ amount /= 4;178178+179179+ for (index = 0; index < amount; index++)180180+ *dmabuf++ = swab32(sgbuffer[index]);181181+182182+ kunmap_atomic(sgbuffer, KM_BIO_SRC_IRQ);183183+184184+ if (size == 0)185185+ break;186186+ }187187+188188+ /*189189+ * Check that we didn't get a request to transfer190190+ * more data than can fit into the SG list.191191+ */192192+ BUG_ON(size != 0);193193+}194194+195195+/*196196+ * Prepare a dma read197197+ */198198+static void at91mci_pre_dma_read(struct at91mci_host *host)199199+{200200+ int i;201201+ struct scatterlist *sg;202202+ struct mmc_command *cmd;203203+ struct mmc_data *data;204204+205205+ DBG("pre dma read\n");206206+207207+ cmd = host->cmd;208208+ if (!cmd) {209209+ DBG("no command\n");210210+ return;211211+ }212212+213213+ data = cmd->data;214214+ if (!data) {215215+ DBG("no data\n");216216+ return;217217+ }218218+219219+ for (i = 0; i < 2; i++) {220220+ /* nothing left to transfer */221221+ if (host->transfer_index >= data->sg_len) {222222+ DBG("Nothing left to transfer (index = %d)\n", host->transfer_index);223223+ break;224224+ }225225+226226+ /* Check to see if this needs filling */227227+ if (i == 0) {228228+ if (at91_mci_read(AT91_PDC_RCR) != 0) {229229+ DBG("Transfer active in current\n");230230+ continue;231231+ }232232+ }233233+ else {234234+ if (at91_mci_read(AT91_PDC_RNCR) != 0) {235235+ DBG("Transfer active in next\n");236236+ continue;237237+ }238238+ }239239+240240+ /* Setup the next transfer */241241+ DBG("Using transfer index %d\n", host->transfer_index);242242+243243+ sg = &data->sg[host->transfer_index++];244244+ DBG("sg = %p\n", sg);245245+246246+ sg->dma_address = dma_map_page(NULL, sg->page, sg->offset, sg->length, DMA_FROM_DEVICE);247247+248248+ DBG("dma address = %08X, length = %d\n", sg->dma_address, sg->length);249249+250250+ if (i == 0) {251251+ at91_mci_write(AT91_PDC_RPR, sg->dma_address);252252+ at91_mci_write(AT91_PDC_RCR, sg->length / 4);253253+ }254254+ else {255255+ at91_mci_write(AT91_PDC_RNPR, sg->dma_address);256256+ at91_mci_write(AT91_PDC_RNCR, sg->length / 4);257257+ }258258+ }259259+260260+ DBG("pre dma read done\n");261261+}262262+263263+/*264264+ * Handle after a dma read265265+ */266266+static void at91mci_post_dma_read(struct at91mci_host *host)267267+{268268+ struct mmc_command *cmd;269269+ struct mmc_data *data;270270+271271+ DBG("post dma read\n");272272+273273+ cmd = host->cmd;274274+ if (!cmd) {275275+ DBG("no command\n");276276+ return;277277+ }278278+279279+ data = cmd->data;280280+ if (!data) {281281+ DBG("no data\n");282282+ return;283283+ }284284+285285+ while (host->in_use_index < host->transfer_index) {286286+ unsigned int *buffer;287287+ int index;288288+ int len;289289+290290+ struct scatterlist *sg;291291+292292+ DBG("finishing index %d\n", host->in_use_index);293293+294294+ sg = &data->sg[host->in_use_index++];295295+296296+ DBG("Unmapping page %08X\n", sg->dma_address);297297+298298+ dma_unmap_page(NULL, sg->dma_address, sg->length, DMA_FROM_DEVICE);299299+300300+ /* Swap the contents of the buffer */301301+ buffer = kmap_atomic(sg->page, KM_BIO_SRC_IRQ) + sg->offset;302302+ DBG("buffer = %p, length = %d\n", buffer, sg->length);303303+304304+ data->bytes_xfered += sg->length;305305+306306+ len = sg->length / 4;307307+308308+ for (index = 0; index < len; index++) {309309+ buffer[index] = swab32(buffer[index]);310310+ }311311+ kunmap_atomic(buffer, KM_BIO_SRC_IRQ);312312+ flush_dcache_page(sg->page);313313+ }314314+315315+ /* Is there another transfer to trigger? */316316+ if (host->transfer_index < data->sg_len)317317+ at91mci_pre_dma_read(host);318318+ else {319319+ at91_mci_write(AT91_MCI_IER, AT91_MCI_RXBUFF);320320+ at91_mci_write(AT91_PDC_PTCR, AT91_PDC_RXTDIS | AT91_PDC_TXTDIS);321321+ }322322+323323+ DBG("post dma read done\n");324324+}325325+326326+/*327327+ * Handle transmitted data328328+ */329329+static void at91_mci_handle_transmitted(struct at91mci_host *host)330330+{331331+ struct mmc_command *cmd;332332+ struct mmc_data *data;333333+334334+ DBG("Handling the transmit\n");335335+336336+ /* Disable the transfer */337337+ at91_mci_write(AT91_PDC_PTCR, AT91_PDC_RXTDIS | AT91_PDC_TXTDIS);338338+339339+ /* Now wait for cmd ready */340340+ at91_mci_write(AT91_MCI_IDR, AT91_MCI_TXBUFE);341341+ at91_mci_write(AT91_MCI_IER, AT91_MCI_NOTBUSY);342342+343343+ cmd = host->cmd;344344+ if (!cmd) return;345345+346346+ data = cmd->data;347347+ if (!data) return;348348+349349+ data->bytes_xfered = host->total_length;350350+}351351+352352+/*353353+ * Enable the controller354354+ */355355+static void at91_mci_enable(void)356356+{357357+ at91_mci_write(AT91_MCI_CR, AT91_MCI_MCIEN);358358+ at91_mci_write(AT91_MCI_IDR, 0xFFFFFFFF);359359+ at91_mci_write(AT91_MCI_DTOR, AT91_MCI_DTOMUL_1M | AT91_MCI_DTOCYC);360360+ at91_mci_write(AT91_MCI_MR, 0x834A);361361+ at91_mci_write(AT91_MCI_SDCR, 0x0);362362+}363363+364364+/*365365+ * Disable the controller366366+ */367367+static void at91_mci_disable(void)368368+{369369+ at91_mci_write(AT91_MCI_CR, AT91_MCI_MCIDIS | AT91_MCI_SWRST);370370+}371371+372372+/*373373+ * Send a command374374+ * return the interrupts to enable375375+ */376376+static unsigned int at91_mci_send_command(struct at91mci_host *host, struct mmc_command *cmd)377377+{378378+ unsigned int cmdr, mr;379379+ unsigned int block_length;380380+ struct mmc_data *data = cmd->data;381381+382382+ unsigned int blocks;383383+ unsigned int ier = 0;384384+385385+ host->cmd = cmd;386386+387387+ /* Not sure if this is needed */388388+#if 0389389+ if ((at91_mci_read(AT91_MCI_SR) & AT91_MCI_RTOE) && (cmd->opcode == 1)) {390390+ DBG("Clearing timeout\n");391391+ at91_mci_write(AT91_MCI_ARGR, 0);392392+ at91_mci_write(AT91_MCI_CMDR, AT91_MCI_OPDCMD);393393+ while (!(at91_mci_read(AT91_MCI_SR) & AT91_MCI_CMDRDY)) {394394+ /* spin */395395+ DBG("Clearing: SR = %08X\n", at91_mci_read(AT91_MCI_SR));396396+ }397397+ }398398+#endif399399+ cmdr = cmd->opcode;400400+401401+ if (mmc_resp_type(cmd) == MMC_RSP_NONE)402402+ cmdr |= AT91_MCI_RSPTYP_NONE;403403+ else {404404+ /* if a response is expected then allow maximum response latancy */405405+ cmdr |= AT91_MCI_MAXLAT;406406+ /* set 136 bit response for R2, 48 bit response otherwise */407407+ if (mmc_resp_type(cmd) == MMC_RSP_R2)408408+ cmdr |= AT91_MCI_RSPTYP_136;409409+ else410410+ cmdr |= AT91_MCI_RSPTYP_48;411411+ }412412+413413+ if (data) {414414+ block_length = 1 << data->blksz_bits;415415+ blocks = data->blocks;416416+417417+ /* always set data start - also set direction flag for read */418418+ if (data->flags & MMC_DATA_READ)419419+ cmdr |= (AT91_MCI_TRDIR | AT91_MCI_TRCMD_START);420420+ else if (data->flags & MMC_DATA_WRITE)421421+ cmdr |= AT91_MCI_TRCMD_START;422422+423423+ if (data->flags & MMC_DATA_STREAM)424424+ cmdr |= AT91_MCI_TRTYP_STREAM;425425+ if (data->flags & MMC_DATA_MULTI)426426+ cmdr |= AT91_MCI_TRTYP_MULTIPLE;427427+ }428428+ else {429429+ block_length = 0;430430+ blocks = 0;431431+ }432432+433433+ if (cmd->opcode == MMC_STOP_TRANSMISSION)434434+ cmdr |= AT91_MCI_TRCMD_STOP;435435+436436+ if (host->bus_mode == MMC_BUSMODE_OPENDRAIN)437437+ cmdr |= AT91_MCI_OPDCMD;438438+439439+ /*440440+ * Set the arguments and send the command441441+ */442442+ DBG("Sending command %d as %08X, arg = %08X, blocks = %d, length = %d (MR = %08lX)\n",443443+ cmd->opcode, cmdr, cmd->arg, blocks, block_length, at91_mci_read(AT91_MCI_MR));444444+445445+ if (!data) {446446+ at91_mci_write(AT91_PDC_PTCR, AT91_PDC_TXTDIS | AT91_PDC_RXTDIS);447447+ at91_mci_write(AT91_PDC_RPR, 0);448448+ at91_mci_write(AT91_PDC_RCR, 0);449449+ at91_mci_write(AT91_PDC_RNPR, 0);450450+ at91_mci_write(AT91_PDC_RNCR, 0);451451+ at91_mci_write(AT91_PDC_TPR, 0);452452+ at91_mci_write(AT91_PDC_TCR, 0);453453+ at91_mci_write(AT91_PDC_TNPR, 0);454454+ at91_mci_write(AT91_PDC_TNCR, 0);455455+456456+ at91_mci_write(AT91_MCI_ARGR, cmd->arg);457457+ at91_mci_write(AT91_MCI_CMDR, cmdr);458458+ return AT91_MCI_CMDRDY;459459+ }460460+461461+ mr = at91_mci_read(AT91_MCI_MR) & 0x7fff; /* zero block length and PDC mode */462462+ at91_mci_write(AT91_MCI_MR, mr | (block_length << 16) | AT91_MCI_PDCMODE);463463+464464+ /*465465+ * Disable the PDC controller466466+ */467467+ at91_mci_write(AT91_PDC_PTCR, AT91_PDC_RXTDIS | AT91_PDC_TXTDIS);468468+469469+ if (cmdr & AT91_MCI_TRCMD_START) {470470+ data->bytes_xfered = 0;471471+ host->transfer_index = 0;472472+ host->in_use_index = 0;473473+ if (cmdr & AT91_MCI_TRDIR) {474474+ /*475475+ * Handle a read476476+ */477477+ host->buffer = NULL;478478+ host->total_length = 0;479479+480480+ at91mci_pre_dma_read(host);481481+ ier = AT91_MCI_ENDRX /* | AT91_MCI_RXBUFF */;482482+ }483483+ else {484484+ /*485485+ * Handle a write486486+ */487487+ host->total_length = block_length * blocks;488488+ host->buffer = dma_alloc_coherent(NULL,489489+ host->total_length,490490+ &host->physical_address, GFP_KERNEL);491491+492492+ at91mci_sg_to_dma(host, data);493493+494494+ DBG("Transmitting %d bytes\n", host->total_length);495495+496496+ at91_mci_write(AT91_PDC_TPR, host->physical_address);497497+ at91_mci_write(AT91_PDC_TCR, host->total_length / 4);498498+ ier = AT91_MCI_TXBUFE;499499+ }500500+ }501501+502502+ /*503503+ * Send the command and then enable the PDC - not the other way round as504504+ * the data sheet says505505+ */506506+507507+ at91_mci_write(AT91_MCI_ARGR, cmd->arg);508508+ at91_mci_write(AT91_MCI_CMDR, cmdr);509509+510510+ if (cmdr & AT91_MCI_TRCMD_START) {511511+ if (cmdr & AT91_MCI_TRDIR)512512+ at91_mci_write(AT91_PDC_PTCR, AT91_PDC_RXTEN);513513+ else514514+ at91_mci_write(AT91_PDC_PTCR, AT91_PDC_TXTEN);515515+ }516516+ return ier;517517+}518518+519519+/*520520+ * Wait for a command to complete521521+ */522522+static void at91mci_process_command(struct at91mci_host *host, struct mmc_command *cmd)523523+{524524+ unsigned int ier;525525+526526+ ier = at91_mci_send_command(host, cmd);527527+528528+ DBG("setting ier to %08X\n", ier);529529+530530+ /* Stop on errors or the required value */531531+ at91_mci_write(AT91_MCI_IER, 0xffff0000 | ier);532532+}533533+534534+/*535535+ * Process the next step in the request536536+ */537537+static void at91mci_process_next(struct at91mci_host *host)538538+{539539+ if (!(host->flags & FL_SENT_COMMAND)) {540540+ host->flags |= FL_SENT_COMMAND;541541+ at91mci_process_command(host, host->request->cmd);542542+ }543543+ else if ((!(host->flags & FL_SENT_STOP)) && host->request->stop) {544544+ host->flags |= FL_SENT_STOP;545545+ at91mci_process_command(host, host->request->stop);546546+ }547547+ else548548+ mmc_request_done(host->mmc, host->request);549549+}550550+551551+/*552552+ * Handle a command that has been completed553553+ */554554+static void at91mci_completed_command(struct at91mci_host *host)555555+{556556+ struct mmc_command *cmd = host->cmd;557557+ unsigned int status;558558+559559+ at91_mci_write(AT91_MCI_IDR, 0xffffffff);560560+561561+ cmd->resp[0] = at91_mci_read(AT91_MCI_RSPR(0));562562+ cmd->resp[1] = at91_mci_read(AT91_MCI_RSPR(1));563563+ cmd->resp[2] = at91_mci_read(AT91_MCI_RSPR(2));564564+ cmd->resp[3] = at91_mci_read(AT91_MCI_RSPR(3));565565+566566+ if (host->buffer) {567567+ dma_free_coherent(NULL, host->total_length, host->buffer, host->physical_address);568568+ host->buffer = NULL;569569+ }570570+571571+ status = at91_mci_read(AT91_MCI_SR);572572+573573+ DBG("Status = %08X [%08X %08X %08X %08X]\n",574574+ status, cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]);575575+576576+ if (status & (AT91_MCI_RINDE | AT91_MCI_RDIRE | AT91_MCI_RCRCE |577577+ AT91_MCI_RENDE | AT91_MCI_RTOE | AT91_MCI_DCRCE |578578+ AT91_MCI_DTOE | AT91_MCI_OVRE | AT91_MCI_UNRE)) {579579+ if ((status & AT91_MCI_RCRCE) &&580580+ ((cmd->opcode == MMC_SEND_OP_COND) || (cmd->opcode == SD_APP_OP_COND))) {581581+ cmd->error = MMC_ERR_NONE;582582+ }583583+ else {584584+ if (status & (AT91_MCI_RTOE | AT91_MCI_DTOE))585585+ cmd->error = MMC_ERR_TIMEOUT;586586+ else if (status & (AT91_MCI_RCRCE | AT91_MCI_DCRCE))587587+ cmd->error = MMC_ERR_BADCRC;588588+ else if (status & (AT91_MCI_OVRE | AT91_MCI_UNRE))589589+ cmd->error = MMC_ERR_FIFO;590590+ else591591+ cmd->error = MMC_ERR_FAILED;592592+593593+ DBG("Error detected and set to %d (cmd = %d, retries = %d)\n",594594+ cmd->error, cmd->opcode, cmd->retries);595595+ }596596+ }597597+ else598598+ cmd->error = MMC_ERR_NONE;599599+600600+ at91mci_process_next(host);601601+}602602+603603+/*604604+ * Handle an MMC request605605+ */606606+static void at91_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)607607+{608608+ struct at91mci_host *host = mmc_priv(mmc);609609+ host->request = mrq;610610+ host->flags = 0;611611+612612+ at91mci_process_next(host);613613+}614614+615615+/*616616+ * Set the IOS617617+ */618618+static void at91_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)619619+{620620+ int clkdiv;621621+ struct at91mci_host *host = mmc_priv(mmc);622622+ unsigned long at91_master_clock = clk_get_rate(mci_clk);623623+624624+ DBG("Clock %uHz, busmode %u, powermode %u, Vdd %u\n",625625+ ios->clock, ios->bus_mode, ios->power_mode, ios->vdd);626626+627627+ if (host)628628+ host->bus_mode = ios->bus_mode;629629+ else630630+ printk("MMC: No host for bus_mode\n");631631+632632+ if (ios->clock == 0) {633633+ /* Disable the MCI controller */634634+ at91_mci_write(AT91_MCI_CR, AT91_MCI_MCIDIS);635635+ clkdiv = 0;636636+ }637637+ else {638638+ /* Enable the MCI controller */639639+ at91_mci_write(AT91_MCI_CR, AT91_MCI_MCIEN);640640+641641+ if ((at91_master_clock % (ios->clock * 2)) == 0)642642+ clkdiv = ((at91_master_clock / ios->clock) / 2) - 1;643643+ else644644+ clkdiv = (at91_master_clock / ios->clock) / 2;645645+646646+ DBG("clkdiv = %d. mcck = %ld\n", clkdiv,647647+ at91_master_clock / (2 * (clkdiv + 1)));648648+ }649649+ if (ios->bus_width == MMC_BUS_WIDTH_4 && host->board->wire4) {650650+ DBG("MMC: Setting controller bus width to 4\n");651651+ at91_mci_write(AT91_MCI_SDCR, at91_mci_read(AT91_MCI_SDCR) | AT91_MCI_SDCBUS);652652+ }653653+ else {654654+ DBG("MMC: Setting controller bus width to 1\n");655655+ at91_mci_write(AT91_MCI_SDCR, at91_mci_read(AT91_MCI_SDCR) & ~AT91_MCI_SDCBUS);656656+ }657657+658658+ /* Set the clock divider */659659+ at91_mci_write(AT91_MCI_MR, (at91_mci_read(AT91_MCI_MR) & ~AT91_MCI_CLKDIV) | clkdiv);660660+661661+ /* maybe switch power to the card */662662+ if (host && host->board->vcc_pin) {663663+ switch (ios->power_mode) {664664+ case MMC_POWER_OFF:665665+ at91_set_gpio_output(host->board->vcc_pin, 0);666666+ break;667667+ case MMC_POWER_UP:668668+ case MMC_POWER_ON:669669+ at91_set_gpio_output(host->board->vcc_pin, 1);670670+ break;671671+ }672672+ }673673+}674674+675675+/*676676+ * Handle an interrupt677677+ */678678+static irqreturn_t at91_mci_irq(int irq, void *devid, struct pt_regs *regs)679679+{680680+ struct at91mci_host *host = devid;681681+ int completed = 0;682682+683683+ unsigned int int_status;684684+685685+ if (host == NULL)686686+ return IRQ_HANDLED;687687+688688+ int_status = at91_mci_read(AT91_MCI_SR);689689+ DBG("MCI irq: status = %08X, %08lX, %08lX\n", int_status, at91_mci_read(AT91_MCI_IMR),690690+ int_status & at91_mci_read(AT91_MCI_IMR));691691+692692+ if ((int_status & at91_mci_read(AT91_MCI_IMR)) & 0xffff0000)693693+ completed = 1;694694+695695+ int_status &= at91_mci_read(AT91_MCI_IMR);696696+697697+ if (int_status & AT91_MCI_UNRE)698698+ DBG("MMC: Underrun error\n");699699+ if (int_status & AT91_MCI_OVRE)700700+ DBG("MMC: Overrun error\n");701701+ if (int_status & AT91_MCI_DTOE)702702+ DBG("MMC: Data timeout\n");703703+ if (int_status & AT91_MCI_DCRCE)704704+ DBG("MMC: CRC error in data\n");705705+ if (int_status & AT91_MCI_RTOE)706706+ DBG("MMC: Response timeout\n");707707+ if (int_status & AT91_MCI_RENDE)708708+ DBG("MMC: Response end bit error\n");709709+ if (int_status & AT91_MCI_RCRCE)710710+ DBG("MMC: Response CRC error\n");711711+ if (int_status & AT91_MCI_RDIRE)712712+ DBG("MMC: Response direction error\n");713713+ if (int_status & AT91_MCI_RINDE)714714+ DBG("MMC: Response index error\n");715715+716716+ /* Only continue processing if no errors */717717+ if (!completed) {718718+ if (int_status & AT91_MCI_TXBUFE) {719719+ DBG("TX buffer empty\n");720720+ at91_mci_handle_transmitted(host);721721+ }722722+723723+ if (int_status & AT91_MCI_RXBUFF) {724724+ DBG("RX buffer full\n");725725+ at91_mci_write(AT91_MCI_IER, AT91_MCI_CMDRDY);726726+ }727727+728728+ if (int_status & AT91_MCI_ENDTX) {729729+ DBG("Transmit has ended\n");730730+ }731731+732732+ if (int_status & AT91_MCI_ENDRX) {733733+ DBG("Receive has ended\n");734734+ at91mci_post_dma_read(host);735735+ }736736+737737+ if (int_status & AT91_MCI_NOTBUSY) {738738+ DBG("Card is ready\n");739739+ at91_mci_write(AT91_MCI_IER, AT91_MCI_CMDRDY);740740+ }741741+742742+ if (int_status & AT91_MCI_DTIP) {743743+ DBG("Data transfer in progress\n");744744+ }745745+746746+ if (int_status & AT91_MCI_BLKE) {747747+ DBG("Block transfer has ended\n");748748+ }749749+750750+ if (int_status & AT91_MCI_TXRDY) {751751+ DBG("Ready to transmit\n");752752+ }753753+754754+ if (int_status & AT91_MCI_RXRDY) {755755+ DBG("Ready to receive\n");756756+ }757757+758758+ if (int_status & AT91_MCI_CMDRDY) {759759+ DBG("Command ready\n");760760+ completed = 1;761761+ }762762+ }763763+ at91_mci_write(AT91_MCI_IDR, int_status);764764+765765+ if (completed) {766766+ DBG("Completed command\n");767767+ at91_mci_write(AT91_MCI_IDR, 0xffffffff);768768+ at91mci_completed_command(host);769769+ }770770+771771+ return IRQ_HANDLED;772772+}773773+774774+static irqreturn_t at91_mmc_det_irq(int irq, void *_host, struct pt_regs *regs)775775+{776776+ struct at91mci_host *host = _host;777777+ int present = !at91_get_gpio_value(irq);778778+779779+ /*780780+ * we expect this irq on both insert and remove,781781+ * and use a short delay to debounce.782782+ */783783+ if (present != host->present) {784784+ host->present = present;785785+ DBG("%s: card %s\n", mmc_hostname(host->mmc),786786+ present ? "insert" : "remove");787787+ if (!present) {788788+ DBG("****** Resetting SD-card bus width ******\n");789789+ at91_mci_write(AT91_MCI_SDCR, 0);790790+ }791791+ mmc_detect_change(host->mmc, msecs_to_jiffies(100));792792+ }793793+ return IRQ_HANDLED;794794+}795795+796796+int at91_mci_get_ro(struct mmc_host *mmc)797797+{798798+ int read_only = 0;799799+ struct at91mci_host *host = mmc_priv(mmc);800800+801801+ if (host->board->wp_pin) {802802+ read_only = at91_get_gpio_value(host->board->wp_pin);803803+ printk(KERN_WARNING "%s: card is %s\n", mmc_hostname(mmc),804804+ (read_only ? "read-only" : "read-write") );805805+ }806806+ else {807807+ printk(KERN_WARNING "%s: host does not support reading read-only "808808+ "switch. Assuming write-enable.\n", mmc_hostname(mmc));809809+ }810810+ return read_only;811811+}812812+813813+static struct mmc_host_ops at91_mci_ops = {814814+ .request = at91_mci_request,815815+ .set_ios = at91_mci_set_ios,816816+ .get_ro = at91_mci_get_ro,817817+};818818+819819+/*820820+ * Probe for the device821821+ */822822+static int at91_mci_probe(struct platform_device *pdev)823823+{824824+ struct mmc_host *mmc;825825+ struct at91mci_host *host;826826+ int ret;827827+828828+ DBG("Probe MCI devices\n");829829+ at91_mci_disable();830830+ at91_mci_enable();831831+832832+ mmc = mmc_alloc_host(sizeof(struct at91mci_host), &pdev->dev);833833+ if (!mmc) {834834+ DBG("Failed to allocate mmc host\n");835835+ return -ENOMEM;836836+ }837837+838838+ mmc->ops = &at91_mci_ops;839839+ mmc->f_min = 375000;840840+ mmc->f_max = 25000000;841841+ mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;842842+843843+ host = mmc_priv(mmc);844844+ host->mmc = mmc;845845+ host->buffer = NULL;846846+ host->bus_mode = 0;847847+ host->board = pdev->dev.platform_data;848848+ if (host->board->wire4) {849849+#ifdef SUPPORT_4WIRE850850+ mmc->caps |= MMC_CAP_4_BIT_DATA;851851+#else852852+ printk("MMC: 4 wire bus mode not supported by this driver - using 1 wire\n");853853+#endif854854+ }855855+856856+ /*857857+ * Get Clock858858+ */859859+ mci_clk = clk_get(&pdev->dev, "mci_clk");860860+ if (!mci_clk) {861861+ printk(KERN_ERR "AT91 MMC: no clock defined.\n");862862+ return -ENODEV;863863+ }864864+ clk_enable(mci_clk); /* Enable the peripheral clock */865865+866866+ /*867867+ * Allocate the MCI interrupt868868+ */869869+ ret = request_irq(AT91_ID_MCI, at91_mci_irq, SA_SHIRQ, DRIVER_NAME, host);870870+ if (ret) {871871+ DBG("Failed to request MCI interrupt\n");872872+ return ret;873873+ }874874+875875+ platform_set_drvdata(pdev, mmc);876876+877877+ /*878878+ * Add host to MMC layer879879+ */880880+ if (host->board->det_pin)881881+ host->present = !at91_get_gpio_value(host->board->det_pin);882882+ else883883+ host->present = -1;884884+885885+ mmc_add_host(mmc);886886+887887+ /*888888+ * monitor card insertion/removal if we can889889+ */890890+ if (host->board->det_pin) {891891+ ret = request_irq(host->board->det_pin, at91_mmc_det_irq,892892+ SA_SAMPLE_RANDOM, DRIVER_NAME, host);893893+ if (ret)894894+ DBG("couldn't allocate MMC detect irq\n");895895+ }896896+897897+ DBG(KERN_INFO "Added MCI driver\n");898898+899899+ return 0;900900+}901901+902902+/*903903+ * Remove a device904904+ */905905+static int at91_mci_remove(struct platform_device *pdev)906906+{907907+ struct mmc_host *mmc = platform_get_drvdata(pdev);908908+ struct at91mci_host *host;909909+910910+ if (!mmc)911911+ return -1;912912+913913+ host = mmc_priv(mmc);914914+915915+ if (host->present != -1) {916916+ free_irq(host->board->det_pin, host);917917+ cancel_delayed_work(&host->mmc->detect);918918+ }919919+920920+ mmc_remove_host(mmc);921921+ at91_mci_disable();922922+ free_irq(AT91_ID_MCI, host);923923+ mmc_free_host(mmc);924924+925925+ clk_disable(mci_clk); /* Disable the peripheral clock */926926+ clk_put(mci_clk);927927+928928+ platform_set_drvdata(pdev, NULL);929929+930930+ DBG("Removed\n");931931+932932+ return 0;933933+}934934+935935+#ifdef CONFIG_PM936936+static int at91_mci_suspend(struct platform_device *pdev, pm_message_t state)937937+{938938+ struct mmc_host *mmc = platform_get_drvdata(pdev);939939+ int ret = 0;940940+941941+ if (mmc)942942+ ret = mmc_suspend_host(mmc, state);943943+944944+ return ret;945945+}946946+947947+static int at91_mci_resume(struct platform_device *pdev)948948+{949949+ struct mmc_host *mmc = platform_get_drvdata(pdev);950950+ int ret = 0;951951+952952+ if (mmc)953953+ ret = mmc_resume_host(mmc);954954+955955+ return ret;956956+}957957+#else958958+#define at91_mci_suspend NULL959959+#define at91_mci_resume NULL960960+#endif961961+962962+static struct platform_driver at91_mci_driver = {963963+ .probe = at91_mci_probe,964964+ .remove = at91_mci_remove,965965+ .suspend = at91_mci_suspend,966966+ .resume = at91_mci_resume,967967+ .driver = {968968+ .name = DRIVER_NAME,969969+ .owner = THIS_MODULE,970970+ },971971+};972972+973973+static int __init at91_mci_init(void)974974+{975975+ return platform_driver_register(&at91_mci_driver);976976+}977977+978978+static void __exit at91_mci_exit(void)979979+{980980+ platform_driver_unregister(&at91_mci_driver);981981+}982982+983983+module_init(at91_mci_init);984984+module_exit(at91_mci_exit);985985+986986+MODULE_DESCRIPTION("AT91 Multimedia Card Interface driver");987987+MODULE_AUTHOR("Nick Randell");988988+MODULE_LICENSE("GPL");
+1096
drivers/mmc/imxmmc.c
···11+/*22+ * linux/drivers/mmc/imxmmc.c - Motorola i.MX MMCI driver33+ *44+ * Copyright (C) 2004 Sascha Hauer, Pengutronix <sascha@saschahauer.de>55+ * Copyright (C) 2006 Pavel Pisa, PiKRON <ppisa@pikron.com>66+ *77+ * derived from pxamci.c by Russell King88+ *99+ * This program is free software; you can redistribute it and/or modify1010+ * it under the terms of the GNU General Public License version 2 as1111+ * published by the Free Software Foundation.1212+ *1313+ * 2005-04-17 Pavel Pisa <pisa@cmp.felk.cvut.cz>1414+ * Changed to conform redesigned i.MX scatter gather DMA interface1515+ *1616+ * 2005-11-04 Pavel Pisa <pisa@cmp.felk.cvut.cz>1717+ * Updated for 2.6.14 kernel1818+ *1919+ * 2005-12-13 Jay Monkman <jtm@smoothsmoothie.com>2020+ * Found and corrected problems in the write path2121+ *2222+ * 2005-12-30 Pavel Pisa <pisa@cmp.felk.cvut.cz>2323+ * The event handling rewritten right way in softirq.2424+ * Added many ugly hacks and delays to overcome SDHC2525+ * deficiencies2626+ *2727+ */2828+#include <linux/config.h>2929+3030+#ifdef CONFIG_MMC_DEBUG3131+#define DEBUG3232+#else3333+#undef DEBUG3434+#endif3535+3636+#include <linux/module.h>3737+#include <linux/init.h>3838+#include <linux/ioport.h>3939+#include <linux/platform_device.h>4040+#include <linux/interrupt.h>4141+#include <linux/blkdev.h>4242+#include <linux/dma-mapping.h>4343+#include <linux/mmc/host.h>4444+#include <linux/mmc/card.h>4545+#include <linux/mmc/protocol.h>4646+#include <linux/delay.h>4747+4848+#include <asm/dma.h>4949+#include <asm/io.h>5050+#include <asm/irq.h>5151+#include <asm/sizes.h>5252+#include <asm/arch/mmc.h>5353+#include <asm/arch/imx-dma.h>5454+5555+#include "imxmmc.h"5656+5757+#define DRIVER_NAME "imx-mmc"5858+5959+#define IMXMCI_INT_MASK_DEFAULT (INT_MASK_BUF_READY | INT_MASK_DATA_TRAN | \6060+ INT_MASK_WRITE_OP_DONE | INT_MASK_END_CMD_RES | \6161+ INT_MASK_AUTO_CARD_DETECT | INT_MASK_DAT0_EN | INT_MASK_SDIO)6262+6363+struct imxmci_host {6464+ struct mmc_host *mmc;6565+ spinlock_t lock;6666+ struct resource *res;6767+ int irq;6868+ imx_dmach_t dma;6969+ unsigned int clkrt;7070+ unsigned int cmdat;7171+ volatile unsigned int imask;7272+ unsigned int power_mode;7373+ unsigned int present;7474+ struct imxmmc_platform_data *pdata;7575+7676+ struct mmc_request *req;7777+ struct mmc_command *cmd;7878+ struct mmc_data *data;7979+8080+ struct timer_list timer;8181+ struct tasklet_struct tasklet;8282+ unsigned int status_reg;8383+ unsigned long pending_events;8484+ /* Next to fields are there for CPU driven transfers to overcome SDHC deficiencies */8585+ u16 *data_ptr;8686+ unsigned int data_cnt;8787+ atomic_t stuck_timeout;8888+8989+ unsigned int dma_nents;9090+ unsigned int dma_size;9191+ unsigned int dma_dir;9292+ int dma_allocated;9393+9494+ unsigned char actual_bus_width;9595+};9696+9797+#define IMXMCI_PEND_IRQ_b 09898+#define IMXMCI_PEND_DMA_END_b 19999+#define IMXMCI_PEND_DMA_ERR_b 2100100+#define IMXMCI_PEND_WAIT_RESP_b 3101101+#define IMXMCI_PEND_DMA_DATA_b 4102102+#define IMXMCI_PEND_CPU_DATA_b 5103103+#define IMXMCI_PEND_CARD_XCHG_b 6104104+#define IMXMCI_PEND_SET_INIT_b 7105105+106106+#define IMXMCI_PEND_IRQ_m (1 << IMXMCI_PEND_IRQ_b)107107+#define IMXMCI_PEND_DMA_END_m (1 << IMXMCI_PEND_DMA_END_b)108108+#define IMXMCI_PEND_DMA_ERR_m (1 << IMXMCI_PEND_DMA_ERR_b)109109+#define IMXMCI_PEND_WAIT_RESP_m (1 << IMXMCI_PEND_WAIT_RESP_b)110110+#define IMXMCI_PEND_DMA_DATA_m (1 << IMXMCI_PEND_DMA_DATA_b)111111+#define IMXMCI_PEND_CPU_DATA_m (1 << IMXMCI_PEND_CPU_DATA_b)112112+#define IMXMCI_PEND_CARD_XCHG_m (1 << IMXMCI_PEND_CARD_XCHG_b)113113+#define IMXMCI_PEND_SET_INIT_m (1 << IMXMCI_PEND_SET_INIT_b)114114+115115+static void imxmci_stop_clock(struct imxmci_host *host)116116+{117117+ int i = 0;118118+ MMC_STR_STP_CLK &= ~STR_STP_CLK_START_CLK;119119+ while(i < 0x1000) {120120+ if(!(i & 0x7f))121121+ MMC_STR_STP_CLK |= STR_STP_CLK_STOP_CLK;122122+123123+ if(!(MMC_STATUS & STATUS_CARD_BUS_CLK_RUN)) {124124+ /* Check twice before cut */125125+ if(!(MMC_STATUS & STATUS_CARD_BUS_CLK_RUN))126126+ return;127127+ }128128+129129+ i++;130130+ }131131+ dev_dbg(mmc_dev(host->mmc), "imxmci_stop_clock blocked, no luck\n");132132+}133133+134134+static void imxmci_start_clock(struct imxmci_host *host)135135+{136136+ int i = 0;137137+ MMC_STR_STP_CLK &= ~STR_STP_CLK_STOP_CLK;138138+ while(i < 0x1000) {139139+ if(!(i & 0x7f))140140+ MMC_STR_STP_CLK |= STR_STP_CLK_START_CLK;141141+142142+ if(MMC_STATUS & STATUS_CARD_BUS_CLK_RUN) {143143+ /* Check twice before cut */144144+ if(MMC_STATUS & STATUS_CARD_BUS_CLK_RUN)145145+ return;146146+ }147147+148148+ i++;149149+ }150150+ dev_dbg(mmc_dev(host->mmc), "imxmci_start_clock blocked, no luck\n");151151+}152152+153153+static void imxmci_softreset(void)154154+{155155+ /* reset sequence */156156+ MMC_STR_STP_CLK = 0x8;157157+ MMC_STR_STP_CLK = 0xD;158158+ MMC_STR_STP_CLK = 0x5;159159+ MMC_STR_STP_CLK = 0x5;160160+ MMC_STR_STP_CLK = 0x5;161161+ MMC_STR_STP_CLK = 0x5;162162+ MMC_STR_STP_CLK = 0x5;163163+ MMC_STR_STP_CLK = 0x5;164164+ MMC_STR_STP_CLK = 0x5;165165+ MMC_STR_STP_CLK = 0x5;166166+167167+ MMC_RES_TO = 0xff;168168+ MMC_BLK_LEN = 512;169169+ MMC_NOB = 1;170170+}171171+172172+static int imxmci_busy_wait_for_status(struct imxmci_host *host,173173+ unsigned int *pstat, unsigned int stat_mask,174174+ int timeout, const char *where)175175+{176176+ int loops=0;177177+ while(!(*pstat & stat_mask)) {178178+ loops+=2;179179+ if(loops >= timeout) {180180+ dev_dbg(mmc_dev(host->mmc), "busy wait timeout in %s, STATUS = 0x%x (0x%x)\n",181181+ where, *pstat, stat_mask);182182+ return -1;183183+ }184184+ udelay(2);185185+ *pstat |= MMC_STATUS;186186+ }187187+ if(!loops)188188+ return 0;189189+190190+ dev_info(mmc_dev(host->mmc), "busy wait for %d usec in %s, STATUS = 0x%x (0x%x)\n",191191+ loops, where, *pstat, stat_mask);192192+ return loops;193193+}194194+195195+static void imxmci_setup_data(struct imxmci_host *host, struct mmc_data *data)196196+{197197+ unsigned int nob = data->blocks;198198+ unsigned int blksz = 1 << data->blksz_bits;199199+ unsigned int datasz = nob * blksz;200200+ int i;201201+202202+ if (data->flags & MMC_DATA_STREAM)203203+ nob = 0xffff;204204+205205+ host->data = data;206206+ data->bytes_xfered = 0;207207+208208+ MMC_NOB = nob;209209+ MMC_BLK_LEN = blksz;210210+211211+ /*212212+ * DMA cannot be used for small block sizes, we have to use CPU driven transfers otherwise.213213+ * We are in big troubles for non-512 byte transfers according to note in the paragraph214214+ * 20.6.7 of User Manual anyway, but we need to be able to transfer SCR at least.215215+ * The situation is even more complex in reality. The SDHC in not able to handle wll216216+ * partial FIFO fills and reads. The length has to be rounded up to burst size multiple.217217+ * This is required for SCR read at least.218218+ */219219+ if (datasz < 64) {220220+ host->dma_size = datasz;221221+ if (data->flags & MMC_DATA_READ) {222222+ host->dma_dir = DMA_FROM_DEVICE;223223+224224+ /* Hack to enable read SCR */225225+ if(datasz < 16) {226226+ MMC_NOB = 1;227227+ MMC_BLK_LEN = 16;228228+ }229229+ } else {230230+ host->dma_dir = DMA_TO_DEVICE;231231+ }232232+233233+ /* Convert back to virtual address */234234+ host->data_ptr = (u16*)(page_address(data->sg->page) + data->sg->offset);235235+ host->data_cnt = 0;236236+237237+ clear_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events);238238+ set_bit(IMXMCI_PEND_CPU_DATA_b, &host->pending_events);239239+240240+ return;241241+ }242242+243243+ if (data->flags & MMC_DATA_READ) {244244+ host->dma_dir = DMA_FROM_DEVICE;245245+ host->dma_nents = dma_map_sg(mmc_dev(host->mmc), data->sg,246246+ data->sg_len, host->dma_dir);247247+248248+ imx_dma_setup_sg(host->dma, data->sg, data->sg_len, datasz,249249+ host->res->start + MMC_BUFFER_ACCESS_OFS, DMA_MODE_READ);250250+251251+ /*imx_dma_setup_mem2dev_ccr(host->dma, DMA_MODE_READ, IMX_DMA_WIDTH_16, CCR_REN);*/252252+ CCR(host->dma) = CCR_DMOD_LINEAR | CCR_DSIZ_32 | CCR_SMOD_FIFO | CCR_SSIZ_16 | CCR_REN;253253+ } else {254254+ host->dma_dir = DMA_TO_DEVICE;255255+256256+ host->dma_nents = dma_map_sg(mmc_dev(host->mmc), data->sg,257257+ data->sg_len, host->dma_dir);258258+259259+ imx_dma_setup_sg(host->dma, data->sg, data->sg_len, datasz,260260+ host->res->start + MMC_BUFFER_ACCESS_OFS, DMA_MODE_WRITE);261261+262262+ /*imx_dma_setup_mem2dev_ccr(host->dma, DMA_MODE_WRITE, IMX_DMA_WIDTH_16, CCR_REN);*/263263+ CCR(host->dma) = CCR_SMOD_LINEAR | CCR_SSIZ_32 | CCR_DMOD_FIFO | CCR_DSIZ_16 | CCR_REN;264264+ }265265+266266+#if 1 /* This code is there only for consistency checking and can be disabled in future */267267+ host->dma_size = 0;268268+ for(i=0; i<host->dma_nents; i++)269269+ host->dma_size+=data->sg[i].length;270270+271271+ if (datasz > host->dma_size) {272272+ dev_err(mmc_dev(host->mmc), "imxmci_setup_data datasz 0x%x > 0x%x dm_size\n",273273+ datasz, host->dma_size);274274+ }275275+#endif276276+277277+ host->dma_size = datasz;278278+279279+ wmb();280280+281281+ if(host->actual_bus_width == MMC_BUS_WIDTH_4)282282+ BLR(host->dma) = 0; /* burst 64 byte read / 64 bytes write */283283+ else284284+ BLR(host->dma) = 16; /* burst 16 byte read / 16 bytes write */285285+286286+ RSSR(host->dma) = DMA_REQ_SDHC;287287+288288+ set_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events);289289+ clear_bit(IMXMCI_PEND_CPU_DATA_b, &host->pending_events);290290+291291+ /* start DMA engine for read, write is delayed after initial response */292292+ if (host->dma_dir == DMA_FROM_DEVICE) {293293+ imx_dma_enable(host->dma);294294+ }295295+}296296+297297+static void imxmci_start_cmd(struct imxmci_host *host, struct mmc_command *cmd, unsigned int cmdat)298298+{299299+ unsigned long flags;300300+ u32 imask;301301+302302+ WARN_ON(host->cmd != NULL);303303+ host->cmd = cmd;304304+305305+ if (cmd->flags & MMC_RSP_BUSY)306306+ cmdat |= CMD_DAT_CONT_BUSY;307307+308308+ switch (mmc_resp_type(cmd)) {309309+ case MMC_RSP_R1: /* short CRC, OPCODE */310310+ case MMC_RSP_R1B:/* short CRC, OPCODE, BUSY */311311+ cmdat |= CMD_DAT_CONT_RESPONSE_FORMAT_R1;312312+ break;313313+ case MMC_RSP_R2: /* long 136 bit + CRC */314314+ cmdat |= CMD_DAT_CONT_RESPONSE_FORMAT_R2;315315+ break;316316+ case MMC_RSP_R3: /* short */317317+ cmdat |= CMD_DAT_CONT_RESPONSE_FORMAT_R3;318318+ break;319319+ case MMC_RSP_R6: /* short CRC */320320+ cmdat |= CMD_DAT_CONT_RESPONSE_FORMAT_R6;321321+ break;322322+ default:323323+ break;324324+ }325325+326326+ if ( test_and_clear_bit(IMXMCI_PEND_SET_INIT_b, &host->pending_events) )327327+ cmdat |= CMD_DAT_CONT_INIT; /* This command needs init */328328+329329+ if ( host->actual_bus_width == MMC_BUS_WIDTH_4 )330330+ cmdat |= CMD_DAT_CONT_BUS_WIDTH_4;331331+332332+ MMC_CMD = cmd->opcode;333333+ MMC_ARGH = cmd->arg >> 16;334334+ MMC_ARGL = cmd->arg & 0xffff;335335+ MMC_CMD_DAT_CONT = cmdat;336336+337337+ atomic_set(&host->stuck_timeout, 0);338338+ set_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events);339339+340340+341341+ imask = IMXMCI_INT_MASK_DEFAULT;342342+ imask &= ~INT_MASK_END_CMD_RES;343343+ if ( cmdat & CMD_DAT_CONT_DATA_ENABLE ) {344344+ /*imask &= ~INT_MASK_BUF_READY;*/345345+ imask &= ~INT_MASK_DATA_TRAN;346346+ if ( cmdat & CMD_DAT_CONT_WRITE )347347+ imask &= ~INT_MASK_WRITE_OP_DONE;348348+ if(test_bit(IMXMCI_PEND_CPU_DATA_b, &host->pending_events))349349+ imask &= ~INT_MASK_BUF_READY;350350+ }351351+352352+ spin_lock_irqsave(&host->lock, flags);353353+ host->imask = imask;354354+ MMC_INT_MASK = host->imask;355355+ spin_unlock_irqrestore(&host->lock, flags);356356+357357+ dev_dbg(mmc_dev(host->mmc), "CMD%02d (0x%02x) mask set to 0x%04x\n",358358+ cmd->opcode, cmd->opcode, imask);359359+360360+ imxmci_start_clock(host);361361+}362362+363363+static void imxmci_finish_request(struct imxmci_host *host, struct mmc_request *req)364364+{365365+ unsigned long flags;366366+367367+ spin_lock_irqsave(&host->lock, flags);368368+369369+ host->pending_events &= ~(IMXMCI_PEND_WAIT_RESP_m | IMXMCI_PEND_DMA_END_m |370370+ IMXMCI_PEND_DMA_DATA_m | IMXMCI_PEND_CPU_DATA_m);371371+372372+ host->imask = IMXMCI_INT_MASK_DEFAULT;373373+ MMC_INT_MASK = host->imask;374374+375375+ spin_unlock_irqrestore(&host->lock, flags);376376+377377+ host->req = NULL;378378+ host->cmd = NULL;379379+ host->data = NULL;380380+ mmc_request_done(host->mmc, req);381381+}382382+383383+static int imxmci_finish_data(struct imxmci_host *host, unsigned int stat)384384+{385385+ struct mmc_data *data = host->data;386386+ int data_error;387387+388388+ if(test_and_clear_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events)){389389+ imx_dma_disable(host->dma);390390+ dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->dma_nents,391391+ host->dma_dir);392392+ }393393+394394+ if ( stat & STATUS_ERR_MASK ) {395395+ dev_dbg(mmc_dev(host->mmc), "request failed. status: 0x%08x\n",stat);396396+ if(stat & (STATUS_CRC_READ_ERR | STATUS_CRC_WRITE_ERR))397397+ data->error = MMC_ERR_BADCRC;398398+ else if(stat & STATUS_TIME_OUT_READ)399399+ data->error = MMC_ERR_TIMEOUT;400400+ else401401+ data->error = MMC_ERR_FAILED;402402+ } else {403403+ data->bytes_xfered = host->dma_size;404404+ }405405+406406+ data_error = data->error;407407+408408+ host->data = NULL;409409+410410+ return data_error;411411+}412412+413413+static int imxmci_cmd_done(struct imxmci_host *host, unsigned int stat)414414+{415415+ struct mmc_command *cmd = host->cmd;416416+ int i;417417+ u32 a,b,c;418418+ struct mmc_data *data = host->data;419419+420420+ if (!cmd)421421+ return 0;422422+423423+ host->cmd = NULL;424424+425425+ if (stat & STATUS_TIME_OUT_RESP) {426426+ dev_dbg(mmc_dev(host->mmc), "CMD TIMEOUT\n");427427+ cmd->error = MMC_ERR_TIMEOUT;428428+ } else if (stat & STATUS_RESP_CRC_ERR && cmd->flags & MMC_RSP_CRC) {429429+ dev_dbg(mmc_dev(host->mmc), "cmd crc error\n");430430+ cmd->error = MMC_ERR_BADCRC;431431+ }432432+433433+ if(cmd->flags & MMC_RSP_PRESENT) {434434+ if(cmd->flags & MMC_RSP_136) {435435+ for (i = 0; i < 4; i++) {436436+ u32 a = MMC_RES_FIFO & 0xffff;437437+ u32 b = MMC_RES_FIFO & 0xffff;438438+ cmd->resp[i] = a<<16 | b;439439+ }440440+ } else {441441+ a = MMC_RES_FIFO & 0xffff;442442+ b = MMC_RES_FIFO & 0xffff;443443+ c = MMC_RES_FIFO & 0xffff;444444+ cmd->resp[0] = a<<24 | b<<8 | c>>8;445445+ }446446+ }447447+448448+ dev_dbg(mmc_dev(host->mmc), "RESP 0x%08x, 0x%08x, 0x%08x, 0x%08x, error %d\n",449449+ cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3], cmd->error);450450+451451+ if (data && (cmd->error == MMC_ERR_NONE) && !(stat & STATUS_ERR_MASK)) {452452+ if (host->req->data->flags & MMC_DATA_WRITE) {453453+454454+ /* Wait for FIFO to be empty before starting DMA write */455455+456456+ stat = MMC_STATUS;457457+ if(imxmci_busy_wait_for_status(host, &stat,458458+ STATUS_APPL_BUFF_FE,459459+ 40, "imxmci_cmd_done DMA WR") < 0) {460460+ cmd->error = MMC_ERR_FIFO;461461+ imxmci_finish_data(host, stat);462462+ if(host->req)463463+ imxmci_finish_request(host, host->req);464464+ dev_warn(mmc_dev(host->mmc), "STATUS = 0x%04x\n",465465+ stat);466466+ return 0;467467+ }468468+469469+ if(test_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events)) {470470+ imx_dma_enable(host->dma);471471+ }472472+ }473473+ } else {474474+ struct mmc_request *req;475475+ imxmci_stop_clock(host);476476+ req = host->req;477477+478478+ if(data)479479+ imxmci_finish_data(host, stat);480480+481481+ if( req ) {482482+ imxmci_finish_request(host, req);483483+ } else {484484+ dev_warn(mmc_dev(host->mmc), "imxmci_cmd_done: no request to finish\n");485485+ }486486+ }487487+488488+ return 1;489489+}490490+491491+static int imxmci_data_done(struct imxmci_host *host, unsigned int stat)492492+{493493+ struct mmc_data *data = host->data;494494+ int data_error;495495+496496+ if (!data)497497+ return 0;498498+499499+ data_error = imxmci_finish_data(host, stat);500500+501501+ if (host->req->stop && (data_error == MMC_ERR_NONE)) {502502+ imxmci_stop_clock(host);503503+ imxmci_start_cmd(host, host->req->stop, 0);504504+ } else {505505+ struct mmc_request *req;506506+ req = host->req;507507+ if( req ) {508508+ imxmci_finish_request(host, req);509509+ } else {510510+ dev_warn(mmc_dev(host->mmc), "imxmci_data_done: no request to finish\n");511511+ }512512+ }513513+514514+ return 1;515515+}516516+517517+static int imxmci_cpu_driven_data(struct imxmci_host *host, unsigned int *pstat)518518+{519519+ int i;520520+ int burst_len;521521+ int flush_len;522522+ int trans_done = 0;523523+ unsigned int stat = *pstat;524524+525525+ if(host->actual_bus_width == MMC_BUS_WIDTH_4)526526+ burst_len = 16;527527+ else528528+ burst_len = 64;529529+530530+ /* This is unfortunately required */531531+ dev_dbg(mmc_dev(host->mmc), "imxmci_cpu_driven_data running STATUS = 0x%x\n",532532+ stat);533533+534534+ if(host->dma_dir == DMA_FROM_DEVICE) {535535+ imxmci_busy_wait_for_status(host, &stat,536536+ STATUS_APPL_BUFF_FF | STATUS_DATA_TRANS_DONE,537537+ 20, "imxmci_cpu_driven_data read");538538+539539+ while((stat & (STATUS_APPL_BUFF_FF | STATUS_DATA_TRANS_DONE)) &&540540+ (host->data_cnt < host->dma_size)) {541541+ if(burst_len >= host->dma_size - host->data_cnt) {542542+ flush_len = burst_len;543543+ burst_len = host->dma_size - host->data_cnt;544544+ flush_len -= burst_len;545545+ host->data_cnt = host->dma_size;546546+ trans_done = 1;547547+ } else {548548+ flush_len = 0;549549+ host->data_cnt += burst_len;550550+ }551551+552552+ for(i = burst_len; i>=2 ; i-=2) {553553+ *(host->data_ptr++) = MMC_BUFFER_ACCESS;554554+ udelay(20); /* required for clocks < 8MHz*/555555+ }556556+557557+ if(i == 1)558558+ *(u8*)(host->data_ptr) = MMC_BUFFER_ACCESS;559559+560560+ stat = MMC_STATUS;561561+562562+ /* Flush extra bytes from FIFO */563563+ while(flush_len >= 2){564564+ flush_len -= 2;565565+ i = MMC_BUFFER_ACCESS;566566+ stat = MMC_STATUS;567567+ stat &= ~STATUS_CRC_READ_ERR; /* Stupid but required there */568568+ }569569+570570+ dev_dbg(mmc_dev(host->mmc), "imxmci_cpu_driven_data read burst %d STATUS = 0x%x\n",571571+ burst_len, stat);572572+ }573573+ } else {574574+ imxmci_busy_wait_for_status(host, &stat,575575+ STATUS_APPL_BUFF_FE,576576+ 20, "imxmci_cpu_driven_data write");577577+578578+ while((stat & STATUS_APPL_BUFF_FE) &&579579+ (host->data_cnt < host->dma_size)) {580580+ if(burst_len >= host->dma_size - host->data_cnt) {581581+ burst_len = host->dma_size - host->data_cnt;582582+ host->data_cnt = host->dma_size;583583+ trans_done = 1;584584+ } else {585585+ host->data_cnt += burst_len;586586+ }587587+588588+ for(i = burst_len; i>0 ; i-=2)589589+ MMC_BUFFER_ACCESS = *(host->data_ptr++);590590+591591+ stat = MMC_STATUS;592592+593593+ dev_dbg(mmc_dev(host->mmc), "imxmci_cpu_driven_data write burst %d STATUS = 0x%x\n",594594+ burst_len, stat);595595+ }596596+ }597597+598598+ *pstat = stat;599599+600600+ return trans_done;601601+}602602+603603+static void imxmci_dma_irq(int dma, void *devid, struct pt_regs *regs)604604+{605605+ struct imxmci_host *host = devid;606606+ uint32_t stat = MMC_STATUS;607607+608608+ atomic_set(&host->stuck_timeout, 0);609609+ host->status_reg = stat;610610+ set_bit(IMXMCI_PEND_DMA_END_b, &host->pending_events);611611+ tasklet_schedule(&host->tasklet);612612+}613613+614614+static irqreturn_t imxmci_irq(int irq, void *devid, struct pt_regs *regs)615615+{616616+ struct imxmci_host *host = devid;617617+ uint32_t stat = MMC_STATUS;618618+ int handled = 1;619619+620620+ MMC_INT_MASK = host->imask | INT_MASK_SDIO | INT_MASK_AUTO_CARD_DETECT;621621+622622+ atomic_set(&host->stuck_timeout, 0);623623+ host->status_reg = stat;624624+ set_bit(IMXMCI_PEND_IRQ_b, &host->pending_events);625625+ tasklet_schedule(&host->tasklet);626626+627627+ return IRQ_RETVAL(handled);;628628+}629629+630630+static void imxmci_tasklet_fnc(unsigned long data)631631+{632632+ struct imxmci_host *host = (struct imxmci_host *)data;633633+ u32 stat;634634+ unsigned int data_dir_mask = 0; /* STATUS_WR_CRC_ERROR_CODE_MASK */635635+ int timeout = 0;636636+637637+ if(atomic_read(&host->stuck_timeout) > 4) {638638+ char *what;639639+ timeout = 1;640640+ stat = MMC_STATUS;641641+ host->status_reg = stat;642642+ if (test_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events))643643+ if (test_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events))644644+ what = "RESP+DMA";645645+ else646646+ what = "RESP";647647+ else648648+ if (test_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events))649649+ if(test_bit(IMXMCI_PEND_DMA_END_b, &host->pending_events))650650+ what = "DATA";651651+ else652652+ what = "DMA";653653+ else654654+ what = "???";655655+656656+ dev_err(mmc_dev(host->mmc), "%s TIMEOUT, hardware stucked STATUS = 0x%04x IMASK = 0x%04x\n",657657+ what, stat, MMC_INT_MASK);658658+ dev_err(mmc_dev(host->mmc), "CMD_DAT_CONT = 0x%04x, MMC_BLK_LEN = 0x%04x, MMC_NOB = 0x%04x, DMA_CCR = 0x%08x\n",659659+ MMC_CMD_DAT_CONT, MMC_BLK_LEN, MMC_NOB, CCR(host->dma));660660+ dev_err(mmc_dev(host->mmc), "CMD%d, bus %d-bit, dma_size = 0x%x\n",661661+ host->cmd?host->cmd->opcode:0, 1<<host->actual_bus_width, host->dma_size);662662+ }663663+664664+ if(!host->present || timeout)665665+ host->status_reg = STATUS_TIME_OUT_RESP | STATUS_TIME_OUT_READ |666666+ STATUS_CRC_READ_ERR | STATUS_CRC_WRITE_ERR;667667+668668+ if(test_bit(IMXMCI_PEND_IRQ_b, &host->pending_events) || timeout) {669669+ clear_bit(IMXMCI_PEND_IRQ_b, &host->pending_events);670670+671671+ stat = MMC_STATUS;672672+ /*673673+ * This is not required in theory, but there is chance to miss some flag674674+ * which clears automatically by mask write, FreeScale original code keeps675675+ * stat from IRQ time so do I676676+ */677677+ stat |= host->status_reg;678678+679679+ if(test_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events)) {680680+ imxmci_busy_wait_for_status(host, &stat,681681+ STATUS_END_CMD_RESP | STATUS_ERR_MASK,682682+ 20, "imxmci_tasklet_fnc resp (ERRATUM #4)");683683+ }684684+685685+ if(stat & (STATUS_END_CMD_RESP | STATUS_ERR_MASK)) {686686+ if(test_and_clear_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events))687687+ imxmci_cmd_done(host, stat);688688+ if(host->data && (stat & STATUS_ERR_MASK))689689+ imxmci_data_done(host, stat);690690+ }691691+692692+ if(test_bit(IMXMCI_PEND_CPU_DATA_b, &host->pending_events)) {693693+ stat |= MMC_STATUS;694694+ if(imxmci_cpu_driven_data(host, &stat)){695695+ if(test_and_clear_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events))696696+ imxmci_cmd_done(host, stat);697697+ atomic_clear_mask(IMXMCI_PEND_IRQ_m|IMXMCI_PEND_CPU_DATA_m,698698+ &host->pending_events);699699+ imxmci_data_done(host, stat);700700+ }701701+ }702702+ }703703+704704+ if(test_bit(IMXMCI_PEND_DMA_END_b, &host->pending_events) &&705705+ !test_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events)) {706706+707707+ stat = MMC_STATUS;708708+ /* Same as above */709709+ stat |= host->status_reg;710710+711711+ if(host->dma_dir == DMA_TO_DEVICE) {712712+ data_dir_mask = STATUS_WRITE_OP_DONE;713713+ } else {714714+ data_dir_mask = STATUS_DATA_TRANS_DONE;715715+ }716716+717717+ imxmci_busy_wait_for_status(host, &stat,718718+ data_dir_mask,719719+ 50, "imxmci_tasklet_fnc data");720720+721721+ if(stat & data_dir_mask) {722722+ clear_bit(IMXMCI_PEND_DMA_END_b, &host->pending_events);723723+ imxmci_data_done(host, stat);724724+ }725725+ }726726+727727+ if(test_and_clear_bit(IMXMCI_PEND_CARD_XCHG_b, &host->pending_events)) {728728+729729+ if(host->cmd)730730+ imxmci_cmd_done(host, STATUS_TIME_OUT_RESP);731731+732732+ if(host->data)733733+ imxmci_data_done(host, STATUS_TIME_OUT_READ |734734+ STATUS_CRC_READ_ERR | STATUS_CRC_WRITE_ERR);735735+736736+ if(host->req)737737+ imxmci_finish_request(host, host->req);738738+739739+ mmc_detect_change(host->mmc, msecs_to_jiffies(100));740740+741741+ }742742+}743743+744744+static void imxmci_request(struct mmc_host *mmc, struct mmc_request *req)745745+{746746+ struct imxmci_host *host = mmc_priv(mmc);747747+ unsigned int cmdat;748748+749749+ WARN_ON(host->req != NULL);750750+751751+ host->req = req;752752+753753+ cmdat = 0;754754+755755+ if (req->data) {756756+ imxmci_setup_data(host, req->data);757757+758758+ cmdat |= CMD_DAT_CONT_DATA_ENABLE;759759+760760+ if (req->data->flags & MMC_DATA_WRITE)761761+ cmdat |= CMD_DAT_CONT_WRITE;762762+763763+ if (req->data->flags & MMC_DATA_STREAM) {764764+ cmdat |= CMD_DAT_CONT_STREAM_BLOCK;765765+ }766766+ }767767+768768+ imxmci_start_cmd(host, req->cmd, cmdat);769769+}770770+771771+#define CLK_RATE 19200000772772+773773+static void imxmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)774774+{775775+ struct imxmci_host *host = mmc_priv(mmc);776776+ int prescaler;777777+778778+ dev_dbg(mmc_dev(host->mmc), "clock %u power %u vdd %u width %u\n",779779+ ios->clock, ios->power_mode, ios->vdd,780780+ (ios->bus_width==MMC_BUS_WIDTH_4)?4:1);781781+782782+ if( ios->bus_width==MMC_BUS_WIDTH_4 ) {783783+ host->actual_bus_width = MMC_BUS_WIDTH_4;784784+ imx_gpio_mode(PB11_PF_SD_DAT3);785785+ }else{786786+ host->actual_bus_width = MMC_BUS_WIDTH_1;787787+ imx_gpio_mode(GPIO_PORTB | GPIO_IN | GPIO_PUEN | 11);788788+ }789789+790790+ if ( host->power_mode != ios->power_mode ) {791791+ switch (ios->power_mode) {792792+ case MMC_POWER_OFF:793793+ break;794794+ case MMC_POWER_UP:795795+ set_bit(IMXMCI_PEND_SET_INIT_b, &host->pending_events);796796+ break;797797+ case MMC_POWER_ON:798798+ break;799799+ }800800+ host->power_mode = ios->power_mode;801801+ }802802+803803+ if ( ios->clock ) {804804+ unsigned int clk;805805+806806+ /* The prescaler is 5 for PERCLK2 equal to 96MHz807807+ * then 96MHz / 5 = 19.2 MHz808808+ */809809+ clk=imx_get_perclk2();810810+ prescaler=(clk+(CLK_RATE*7)/8)/CLK_RATE;811811+ switch(prescaler) {812812+ case 0:813813+ case 1: prescaler = 0;814814+ break;815815+ case 2: prescaler = 1;816816+ break;817817+ case 3: prescaler = 2;818818+ break;819819+ case 4: prescaler = 4;820820+ break;821821+ default:822822+ case 5: prescaler = 5;823823+ break;824824+ }825825+826826+ dev_dbg(mmc_dev(host->mmc), "PERCLK2 %d MHz -> prescaler %d\n",827827+ clk, prescaler);828828+829829+ for(clk=0; clk<8; clk++) {830830+ int x;831831+ x = CLK_RATE / (1<<clk);832832+ if( x <= ios->clock)833833+ break;834834+ }835835+836836+ MMC_STR_STP_CLK |= STR_STP_CLK_ENABLE; /* enable controller */837837+838838+ imxmci_stop_clock(host);839839+ MMC_CLK_RATE = (prescaler<<3) | clk;840840+ imxmci_start_clock(host);841841+842842+ dev_dbg(mmc_dev(host->mmc), "MMC_CLK_RATE: 0x%08x\n", MMC_CLK_RATE);843843+ } else {844844+ imxmci_stop_clock(host);845845+ }846846+}847847+848848+static struct mmc_host_ops imxmci_ops = {849849+ .request = imxmci_request,850850+ .set_ios = imxmci_set_ios,851851+};852852+853853+static struct resource *platform_device_resource(struct platform_device *dev, unsigned int mask, int nr)854854+{855855+ int i;856856+857857+ for (i = 0; i < dev->num_resources; i++)858858+ if (dev->resource[i].flags == mask && nr-- == 0)859859+ return &dev->resource[i];860860+ return NULL;861861+}862862+863863+static int platform_device_irq(struct platform_device *dev, int nr)864864+{865865+ int i;866866+867867+ for (i = 0; i < dev->num_resources; i++)868868+ if (dev->resource[i].flags == IORESOURCE_IRQ && nr-- == 0)869869+ return dev->resource[i].start;870870+ return NO_IRQ;871871+}872872+873873+static void imxmci_check_status(unsigned long data)874874+{875875+ struct imxmci_host *host = (struct imxmci_host *)data;876876+877877+ if( host->pdata->card_present() != host->present ) {878878+ host->present ^= 1;879879+ dev_info(mmc_dev(host->mmc), "card %s\n",880880+ host->present ? "inserted" : "removed");881881+882882+ set_bit(IMXMCI_PEND_CARD_XCHG_b, &host->pending_events);883883+ tasklet_schedule(&host->tasklet);884884+ }885885+886886+ if(test_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events) ||887887+ test_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events)) {888888+ atomic_inc(&host->stuck_timeout);889889+ if(atomic_read(&host->stuck_timeout) > 4)890890+ tasklet_schedule(&host->tasklet);891891+ } else {892892+ atomic_set(&host->stuck_timeout, 0);893893+894894+ }895895+896896+ mod_timer(&host->timer, jiffies + (HZ>>1));897897+}898898+899899+static int imxmci_probe(struct platform_device *pdev)900900+{901901+ struct mmc_host *mmc;902902+ struct imxmci_host *host = NULL;903903+ struct resource *r;904904+ int ret = 0, irq;905905+906906+ printk(KERN_INFO "i.MX mmc driver\n");907907+908908+ r = platform_device_resource(pdev, IORESOURCE_MEM, 0);909909+ irq = platform_device_irq(pdev, 0);910910+ if (!r || irq == NO_IRQ)911911+ return -ENXIO;912912+913913+ r = request_mem_region(r->start, 0x100, "IMXMCI");914914+ if (!r)915915+ return -EBUSY;916916+917917+ mmc = mmc_alloc_host(sizeof(struct imxmci_host), &pdev->dev);918918+ if (!mmc) {919919+ ret = -ENOMEM;920920+ goto out;921921+ }922922+923923+ mmc->ops = &imxmci_ops;924924+ mmc->f_min = 150000;925925+ mmc->f_max = CLK_RATE/2;926926+ mmc->ocr_avail = MMC_VDD_32_33;927927+ mmc->caps |= MMC_CAP_4_BIT_DATA;928928+929929+ /* MMC core transfer sizes tunable parameters */930930+ mmc->max_hw_segs = 64;931931+ mmc->max_phys_segs = 64;932932+ mmc->max_sectors = 64; /* default 1 << (PAGE_CACHE_SHIFT - 9) */933933+ mmc->max_seg_size = 64*512; /* default PAGE_CACHE_SIZE */934934+935935+ host = mmc_priv(mmc);936936+ host->mmc = mmc;937937+ host->dma_allocated = 0;938938+ host->pdata = pdev->dev.platform_data;939939+940940+ spin_lock_init(&host->lock);941941+ host->res = r;942942+ host->irq = irq;943943+944944+ imx_gpio_mode(PB8_PF_SD_DAT0);945945+ imx_gpio_mode(PB9_PF_SD_DAT1);946946+ imx_gpio_mode(PB10_PF_SD_DAT2);947947+ /* Configured as GPIO with pull-up to ensure right MCC card mode */948948+ /* Switched to PB11_PF_SD_DAT3 if 4 bit bus is configured */949949+ imx_gpio_mode(GPIO_PORTB | GPIO_IN | GPIO_PUEN | 11);950950+ /* imx_gpio_mode(PB11_PF_SD_DAT3); */951951+ imx_gpio_mode(PB12_PF_SD_CLK);952952+ imx_gpio_mode(PB13_PF_SD_CMD);953953+954954+ imxmci_softreset();955955+956956+ if ( MMC_REV_NO != 0x390 ) {957957+ dev_err(mmc_dev(host->mmc), "wrong rev.no. 0x%08x. aborting.\n",958958+ MMC_REV_NO);959959+ goto out;960960+ }961961+962962+ MMC_READ_TO = 0x2db4; /* recommended in data sheet */963963+964964+ host->imask = IMXMCI_INT_MASK_DEFAULT;965965+ MMC_INT_MASK = host->imask;966966+967967+968968+ if(imx_dma_request_by_prio(&host->dma, DRIVER_NAME, DMA_PRIO_LOW)<0){969969+ dev_err(mmc_dev(host->mmc), "imx_dma_request_by_prio failed\n");970970+ ret = -EBUSY;971971+ goto out;972972+ }973973+ host->dma_allocated=1;974974+ imx_dma_setup_handlers(host->dma, imxmci_dma_irq, NULL, host);975975+976976+ tasklet_init(&host->tasklet, imxmci_tasklet_fnc, (unsigned long)host);977977+ host->status_reg=0;978978+ host->pending_events=0;979979+980980+ ret = request_irq(host->irq, imxmci_irq, 0, DRIVER_NAME, host);981981+ if (ret)982982+ goto out;983983+984984+ host->present = host->pdata->card_present();985985+ init_timer(&host->timer);986986+ host->timer.data = (unsigned long)host;987987+ host->timer.function = imxmci_check_status;988988+ add_timer(&host->timer);989989+ mod_timer(&host->timer, jiffies + (HZ>>1));990990+991991+ platform_set_drvdata(pdev, mmc);992992+993993+ mmc_add_host(mmc);994994+995995+ return 0;996996+997997+out:998998+ if (host) {999999+ if(host->dma_allocated){10001000+ imx_dma_free(host->dma);10011001+ host->dma_allocated=0;10021002+ }10031003+ }10041004+ if (mmc)10051005+ mmc_free_host(mmc);10061006+ release_resource(r);10071007+ return ret;10081008+}10091009+10101010+static int imxmci_remove(struct platform_device *pdev)10111011+{10121012+ struct mmc_host *mmc = platform_get_drvdata(pdev);10131013+10141014+ platform_set_drvdata(pdev, NULL);10151015+10161016+ if (mmc) {10171017+ struct imxmci_host *host = mmc_priv(mmc);10181018+10191019+ tasklet_disable(&host->tasklet);10201020+10211021+ del_timer_sync(&host->timer);10221022+ mmc_remove_host(mmc);10231023+10241024+ free_irq(host->irq, host);10251025+ if(host->dma_allocated){10261026+ imx_dma_free(host->dma);10271027+ host->dma_allocated=0;10281028+ }10291029+10301030+ tasklet_kill(&host->tasklet);10311031+10321032+ release_resource(host->res);10331033+10341034+ mmc_free_host(mmc);10351035+ }10361036+ return 0;10371037+}10381038+10391039+#ifdef CONFIG_PM10401040+static int imxmci_suspend(struct platform_device *dev, pm_message_t state)10411041+{10421042+ struct mmc_host *mmc = platform_get_drvdata(dev);10431043+ int ret = 0;10441044+10451045+ if (mmc)10461046+ ret = mmc_suspend_host(mmc, state);10471047+10481048+ return ret;10491049+}10501050+10511051+static int imxmci_resume(struct platform_device *dev)10521052+{10531053+ struct mmc_host *mmc = platform_get_drvdata(dev);10541054+ struct imxmci_host *host;10551055+ int ret = 0;10561056+10571057+ if (mmc) {10581058+ host = mmc_priv(mmc);10591059+ if(host)10601060+ set_bit(IMXMCI_PEND_SET_INIT_b, &host->pending_events);10611061+ ret = mmc_resume_host(mmc);10621062+ }10631063+10641064+ return ret;10651065+}10661066+#else10671067+#define imxmci_suspend NULL10681068+#define imxmci_resume NULL10691069+#endif /* CONFIG_PM */10701070+10711071+static struct platform_driver imxmci_driver = {10721072+ .probe = imxmci_probe,10731073+ .remove = imxmci_remove,10741074+ .suspend = imxmci_suspend,10751075+ .resume = imxmci_resume,10761076+ .driver = {10771077+ .name = DRIVER_NAME,10781078+ }10791079+};10801080+10811081+static int __init imxmci_init(void)10821082+{10831083+ return platform_driver_register(&imxmci_driver);10841084+}10851085+10861086+static void __exit imxmci_exit(void)10871087+{10881088+ platform_driver_unregister(&imxmci_driver);10891089+}10901090+10911091+module_init(imxmci_init);10921092+module_exit(imxmci_exit);10931093+10941094+MODULE_DESCRIPTION("i.MX Multimedia Card Interface Driver");10951095+MODULE_AUTHOR("Sascha Hauer, Pengutronix");10961096+MODULE_LICENSE("GPL");