blob: 53e30b0504b5d8bb150c00f3ba4595476970f7dc [file] [log] [blame]
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001/*
2 * Atmel MultiMedia Card Interface driver
3 *
4 * Copyright (C) 2004-2008 Atmel Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/blkdev.h>
11#include <linux/clk.h>
Haavard Skinnemoendeec9ae2008-07-24 14:18:59 +020012#include <linux/debugfs.h>
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +020013#include <linux/device.h>
Haavard Skinnemoen65e8b082008-07-30 20:29:03 +020014#include <linux/dmaengine.h>
15#include <linux/dma-mapping.h>
Ben Nizettefbfca4b2008-07-18 16:48:09 +100016#include <linux/err.h>
David Brownell3c26e172008-07-27 02:34:45 -070017#include <linux/gpio.h>
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +020018#include <linux/init.h>
19#include <linux/interrupt.h>
Pramod Gurav7bca6462014-09-23 18:21:48 +053020#include <linux/io.h>
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +020021#include <linux/ioport.h>
22#include <linux/module.h>
Ludovic Desrochese919fd22012-07-24 15:30:03 +020023#include <linux/of.h>
24#include <linux/of_device.h>
25#include <linux/of_gpio.h>
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +020026#include <linux/platform_device.h>
27#include <linux/scatterlist.h>
Haavard Skinnemoendeec9ae2008-07-24 14:18:59 +020028#include <linux/seq_file.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090029#include <linux/slab.h>
Haavard Skinnemoendeec9ae2008-07-24 14:18:59 +020030#include <linux/stat.h>
Viresh Kumare2b35f32012-02-01 16:12:27 +053031#include <linux/types.h>
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +020032
33#include <linux/mmc/host.h>
Nicolas Ferre2f1d7912010-12-10 19:14:32 +010034#include <linux/mmc/sdio.h>
Nicolas Ferre2635d1b2009-12-14 18:01:30 -080035
Nicolas Ferrec42aa772008-11-20 15:59:12 +010036#include <linux/atmel-mci.h>
Ludovic Desroches796211b2011-08-11 15:25:44 +000037#include <linux/atmel_pdc.h>
Wenyou Yangae552ab2014-10-30 12:00:41 +080038#include <linux/pm.h>
39#include <linux/pm_runtime.h>
Wenyou Yangb5b64fa2014-11-07 08:48:13 +080040#include <linux/pinctrl/consumer.h>
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +020041
Arnd Bergmannbf614c72014-06-05 23:14:38 +020042#include <asm/cacheflush.h>
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +020043#include <asm/io.h>
44#include <asm/unaligned.h>
45
ludovic.desroches@atmel.comec8fc9c2015-11-23 16:27:30 +010046/*
Andy Shevchenkoef4b1602017-05-09 20:21:17 +030047 * Superset of MCI IP registers integrated in Atmel AT91 Processor
ludovic.desroches@atmel.comec8fc9c2015-11-23 16:27:30 +010048 * Registers and bitfields marked with [2] are only available in MCI2
49 */
50
51/* MCI Register Definitions */
52#define ATMCI_CR 0x0000 /* Control */
53#define ATMCI_CR_MCIEN BIT(0) /* MCI Enable */
54#define ATMCI_CR_MCIDIS BIT(1) /* MCI Disable */
55#define ATMCI_CR_PWSEN BIT(2) /* Power Save Enable */
56#define ATMCI_CR_PWSDIS BIT(3) /* Power Save Disable */
57#define ATMCI_CR_SWRST BIT(7) /* Software Reset */
58#define ATMCI_MR 0x0004 /* Mode */
59#define ATMCI_MR_CLKDIV(x) ((x) << 0) /* Clock Divider */
60#define ATMCI_MR_PWSDIV(x) ((x) << 8) /* Power Saving Divider */
61#define ATMCI_MR_RDPROOF BIT(11) /* Read Proof */
62#define ATMCI_MR_WRPROOF BIT(12) /* Write Proof */
63#define ATMCI_MR_PDCFBYTE BIT(13) /* Force Byte Transfer */
64#define ATMCI_MR_PDCPADV BIT(14) /* Padding Value */
65#define ATMCI_MR_PDCMODE BIT(15) /* PDC-oriented Mode */
66#define ATMCI_MR_CLKODD(x) ((x) << 16) /* LSB of Clock Divider */
67#define ATMCI_DTOR 0x0008 /* Data Timeout */
68#define ATMCI_DTOCYC(x) ((x) << 0) /* Data Timeout Cycles */
69#define ATMCI_DTOMUL(x) ((x) << 4) /* Data Timeout Multiplier */
70#define ATMCI_SDCR 0x000c /* SD Card / SDIO */
71#define ATMCI_SDCSEL_SLOT_A (0 << 0) /* Select SD slot A */
72#define ATMCI_SDCSEL_SLOT_B (1 << 0) /* Select SD slot A */
73#define ATMCI_SDCSEL_MASK (3 << 0)
74#define ATMCI_SDCBUS_1BIT (0 << 6) /* 1-bit data bus */
75#define ATMCI_SDCBUS_4BIT (2 << 6) /* 4-bit data bus */
76#define ATMCI_SDCBUS_8BIT (3 << 6) /* 8-bit data bus[2] */
77#define ATMCI_SDCBUS_MASK (3 << 6)
78#define ATMCI_ARGR 0x0010 /* Command Argument */
79#define ATMCI_CMDR 0x0014 /* Command */
80#define ATMCI_CMDR_CMDNB(x) ((x) << 0) /* Command Opcode */
81#define ATMCI_CMDR_RSPTYP_NONE (0 << 6) /* No response */
82#define ATMCI_CMDR_RSPTYP_48BIT (1 << 6) /* 48-bit response */
83#define ATMCI_CMDR_RSPTYP_136BIT (2 << 6) /* 136-bit response */
84#define ATMCI_CMDR_SPCMD_INIT (1 << 8) /* Initialization command */
85#define ATMCI_CMDR_SPCMD_SYNC (2 << 8) /* Synchronized command */
86#define ATMCI_CMDR_SPCMD_INT (4 << 8) /* Interrupt command */
87#define ATMCI_CMDR_SPCMD_INTRESP (5 << 8) /* Interrupt response */
88#define ATMCI_CMDR_OPDCMD (1 << 11) /* Open Drain */
89#define ATMCI_CMDR_MAXLAT_5CYC (0 << 12) /* Max latency 5 cycles */
90#define ATMCI_CMDR_MAXLAT_64CYC (1 << 12) /* Max latency 64 cycles */
91#define ATMCI_CMDR_START_XFER (1 << 16) /* Start data transfer */
92#define ATMCI_CMDR_STOP_XFER (2 << 16) /* Stop data transfer */
93#define ATMCI_CMDR_TRDIR_WRITE (0 << 18) /* Write data */
94#define ATMCI_CMDR_TRDIR_READ (1 << 18) /* Read data */
95#define ATMCI_CMDR_BLOCK (0 << 19) /* Single-block transfer */
96#define ATMCI_CMDR_MULTI_BLOCK (1 << 19) /* Multi-block transfer */
97#define ATMCI_CMDR_STREAM (2 << 19) /* MMC Stream transfer */
98#define ATMCI_CMDR_SDIO_BYTE (4 << 19) /* SDIO Byte transfer */
99#define ATMCI_CMDR_SDIO_BLOCK (5 << 19) /* SDIO Block transfer */
100#define ATMCI_CMDR_SDIO_SUSPEND (1 << 24) /* SDIO Suspend Command */
101#define ATMCI_CMDR_SDIO_RESUME (2 << 24) /* SDIO Resume Command */
102#define ATMCI_BLKR 0x0018 /* Block */
103#define ATMCI_BCNT(x) ((x) << 0) /* Data Block Count */
104#define ATMCI_BLKLEN(x) ((x) << 16) /* Data Block Length */
105#define ATMCI_CSTOR 0x001c /* Completion Signal Timeout[2] */
106#define ATMCI_CSTOCYC(x) ((x) << 0) /* CST cycles */
107#define ATMCI_CSTOMUL(x) ((x) << 4) /* CST multiplier */
108#define ATMCI_RSPR 0x0020 /* Response 0 */
109#define ATMCI_RSPR1 0x0024 /* Response 1 */
110#define ATMCI_RSPR2 0x0028 /* Response 2 */
111#define ATMCI_RSPR3 0x002c /* Response 3 */
112#define ATMCI_RDR 0x0030 /* Receive Data */
113#define ATMCI_TDR 0x0034 /* Transmit Data */
114#define ATMCI_SR 0x0040 /* Status */
115#define ATMCI_IER 0x0044 /* Interrupt Enable */
116#define ATMCI_IDR 0x0048 /* Interrupt Disable */
117#define ATMCI_IMR 0x004c /* Interrupt Mask */
118#define ATMCI_CMDRDY BIT(0) /* Command Ready */
119#define ATMCI_RXRDY BIT(1) /* Receiver Ready */
120#define ATMCI_TXRDY BIT(2) /* Transmitter Ready */
121#define ATMCI_BLKE BIT(3) /* Data Block Ended */
122#define ATMCI_DTIP BIT(4) /* Data Transfer In Progress */
123#define ATMCI_NOTBUSY BIT(5) /* Data Not Busy */
124#define ATMCI_ENDRX BIT(6) /* End of RX Buffer */
125#define ATMCI_ENDTX BIT(7) /* End of TX Buffer */
126#define ATMCI_SDIOIRQA BIT(8) /* SDIO IRQ in slot A */
127#define ATMCI_SDIOIRQB BIT(9) /* SDIO IRQ in slot B */
128#define ATMCI_SDIOWAIT BIT(12) /* SDIO Read Wait Operation Status */
129#define ATMCI_CSRCV BIT(13) /* CE-ATA Completion Signal Received */
130#define ATMCI_RXBUFF BIT(14) /* RX Buffer Full */
131#define ATMCI_TXBUFE BIT(15) /* TX Buffer Empty */
132#define ATMCI_RINDE BIT(16) /* Response Index Error */
133#define ATMCI_RDIRE BIT(17) /* Response Direction Error */
134#define ATMCI_RCRCE BIT(18) /* Response CRC Error */
135#define ATMCI_RENDE BIT(19) /* Response End Bit Error */
136#define ATMCI_RTOE BIT(20) /* Response Time-Out Error */
137#define ATMCI_DCRCE BIT(21) /* Data CRC Error */
138#define ATMCI_DTOE BIT(22) /* Data Time-Out Error */
139#define ATMCI_CSTOE BIT(23) /* Completion Signal Time-out Error */
140#define ATMCI_BLKOVRE BIT(24) /* DMA Block Overrun Error */
141#define ATMCI_DMADONE BIT(25) /* DMA Transfer Done */
142#define ATMCI_FIFOEMPTY BIT(26) /* FIFO Empty Flag */
143#define ATMCI_XFRDONE BIT(27) /* Transfer Done Flag */
144#define ATMCI_ACKRCV BIT(28) /* Boot Operation Acknowledge Received */
145#define ATMCI_ACKRCVE BIT(29) /* Boot Operation Acknowledge Error */
146#define ATMCI_OVRE BIT(30) /* RX Overrun Error */
147#define ATMCI_UNRE BIT(31) /* TX Underrun Error */
148#define ATMCI_DMA 0x0050 /* DMA Configuration[2] */
149#define ATMCI_DMA_OFFSET(x) ((x) << 0) /* DMA Write Buffer Offset */
150#define ATMCI_DMA_CHKSIZE(x) ((x) << 4) /* DMA Channel Read and Write Chunk Size */
151#define ATMCI_DMAEN BIT(8) /* DMA Hardware Handshaking Enable */
152#define ATMCI_CFG 0x0054 /* Configuration[2] */
153#define ATMCI_CFG_FIFOMODE_1DATA BIT(0) /* MCI Internal FIFO control mode */
154#define ATMCI_CFG_FERRCTRL_COR BIT(4) /* Flow Error flag reset control mode */
155#define ATMCI_CFG_HSMODE BIT(8) /* High Speed Mode */
156#define ATMCI_CFG_LSYNC BIT(12) /* Synchronize on the last block */
157#define ATMCI_WPMR 0x00e4 /* Write Protection Mode[2] */
158#define ATMCI_WP_EN BIT(0) /* WP Enable */
159#define ATMCI_WP_KEY (0x4d4349 << 8) /* WP Key */
160#define ATMCI_WPSR 0x00e8 /* Write Protection Status[2] */
161#define ATMCI_GET_WP_VS(x) ((x) & 0x0f)
162#define ATMCI_GET_WP_VSRC(x) (((x) >> 8) & 0xffff)
163#define ATMCI_VERSION 0x00FC /* Version */
164#define ATMCI_FIFO_APERTURE 0x0200 /* FIFO Aperture[2] */
165
166/* This is not including the FIFO Aperture on MCI2 */
167#define ATMCI_REGS_SIZE 0x100
168
169/* Register access macros */
170#define atmci_readl(port, reg) \
171 __raw_readl((port)->regs + reg)
172#define atmci_writel(port, reg, value) \
173 __raw_writel((value), (port)->regs + reg)
174
Wenyou Yangae552ab2014-10-30 12:00:41 +0800175#define AUTOSUSPEND_DELAY 50
176
Ludovic Desroches2c96a292011-08-11 15:25:41 +0000177#define ATMCI_DATA_ERROR_FLAGS (ATMCI_DCRCE | ATMCI_DTOE | ATMCI_OVRE | ATMCI_UNRE)
Haavard Skinnemoen65e8b082008-07-30 20:29:03 +0200178#define ATMCI_DMA_THRESHOLD 16
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +0200179
180enum {
Ludovic Desrochesf5177542012-05-16 15:25:59 +0200181 EVENT_CMD_RDY = 0,
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +0200182 EVENT_XFER_COMPLETE,
Ludovic Desrochesf5177542012-05-16 15:25:59 +0200183 EVENT_NOTBUSY,
Haavard Skinnemoenc06ad252008-07-31 14:49:16 +0200184 EVENT_DATA_ERROR,
185};
186
187enum atmel_mci_state {
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +0200188 STATE_IDLE = 0,
189 STATE_SENDING_CMD,
Ludovic Desrochesf5177542012-05-16 15:25:59 +0200190 STATE_DATA_XFER,
191 STATE_WAITING_NOTBUSY,
Haavard Skinnemoenc06ad252008-07-31 14:49:16 +0200192 STATE_SENDING_STOP,
Ludovic Desrochesf5177542012-05-16 15:25:59 +0200193 STATE_END_REQUEST,
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +0200194};
195
Ludovic Desroches796211b2011-08-11 15:25:44 +0000196enum atmci_xfer_dir {
197 XFER_RECEIVE = 0,
198 XFER_TRANSMIT,
199};
200
201enum atmci_pdc_buf {
202 PDC_FIRST_BUF = 0,
203 PDC_SECOND_BUF,
204};
205
206struct atmel_mci_caps {
Hein_Tiboschccdfe612012-08-30 16:34:38 +0000207 bool has_dma_conf_reg;
Ludovic Desroches796211b2011-08-11 15:25:44 +0000208 bool has_pdc;
209 bool has_cfg_reg;
210 bool has_cstor_reg;
211 bool has_highspeed;
212 bool has_rwproof;
Ludovic Desrochesfaf81802012-03-21 16:41:23 +0100213 bool has_odd_clk_div;
Ludovic Desroches24011f32012-05-16 15:26:00 +0200214 bool has_bad_data_ordering;
215 bool need_reset_after_xfer;
216 bool need_blksz_mul_4;
Ludovic Desroches077d4072012-07-24 11:42:04 +0200217 bool need_notbusy_for_read_ops;
Ludovic Desroches796211b2011-08-11 15:25:44 +0000218};
219
Haavard Skinnemoen65e8b082008-07-30 20:29:03 +0200220struct atmel_mci_dma {
Haavard Skinnemoen65e8b082008-07-30 20:29:03 +0200221 struct dma_chan *chan;
222 struct dma_async_tx_descriptor *data_desc;
Haavard Skinnemoen65e8b082008-07-30 20:29:03 +0200223};
224
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +0200225/**
226 * struct atmel_mci - MMC controller state shared between all slots
227 * @lock: Spinlock protecting the queue and associated data.
228 * @regs: Pointer to MMIO registers.
Ludovic Desroches796211b2011-08-11 15:25:44 +0000229 * @sg: Scatterlist entry currently being processed by PIO or PDC code.
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +0200230 * @pio_offset: Offset into the current scatterlist entry.
Ludovic Desroches7a90dcc2012-05-16 15:25:58 +0200231 * @buffer: Buffer used if we don't have the r/w proof capability. We
232 * don't have the time to switch pdc buffers so we have to use only
233 * one buffer for the full transaction.
234 * @buf_size: size of the buffer.
235 * @phys_buf_addr: buffer address needed for pdc.
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +0200236 * @cur_slot: The slot which is currently using the controller.
237 * @mrq: The request currently being processed on @cur_slot,
238 * or NULL if the controller is idle.
239 * @cmd: The command currently being sent to the card, or NULL.
240 * @data: The data currently being transferred, or NULL if no data
241 * transfer is in progress.
Ludovic Desroches796211b2011-08-11 15:25:44 +0000242 * @data_size: just data->blocks * data->blksz.
Haavard Skinnemoen65e8b082008-07-30 20:29:03 +0200243 * @dma: DMA client state.
244 * @data_chan: DMA channel being used for the current data transfer.
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +0200245 * @cmd_status: Snapshot of SR taken upon completion of the current
246 * command. Only valid when EVENT_CMD_COMPLETE is pending.
247 * @data_status: Snapshot of SR taken upon completion of the current
248 * data transfer. Only valid when EVENT_DATA_COMPLETE or
249 * EVENT_DATA_ERROR is pending.
250 * @stop_cmdr: Value to be loaded into CMDR when the stop command is
251 * to be sent.
252 * @tasklet: Tasklet running the request state machine.
253 * @pending_events: Bitmask of events flagged by the interrupt handler
254 * to be processed by the tasklet.
255 * @completed_events: Bitmask of events which the state machine has
256 * processed.
257 * @state: Tasklet state.
258 * @queue: List of slots waiting for access to the controller.
259 * @need_clock_update: Update the clock rate before the next request.
260 * @need_reset: Reset controller before next request.
Ludovic Desroches24011f32012-05-16 15:26:00 +0200261 * @timer: Timer to balance the data timeout error flag which cannot rise.
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +0200262 * @mode_reg: Value of the MR register.
Nicolas Ferre74791a22009-12-14 18:01:31 -0800263 * @cfg_reg: Value of the CFG register.
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +0200264 * @bus_hz: The rate of @mck in Hz. This forms the basis for MMC bus
265 * rate and timeout calculations.
266 * @mapbase: Physical address of the MMIO registers.
267 * @mck: The peripheral bus clock hooked up to the MMC controller.
268 * @pdev: Platform device associated with the MMC controller.
269 * @slot: Slots sharing this MMC controller.
Ludovic Desroches796211b2011-08-11 15:25:44 +0000270 * @caps: MCI capabilities depending on MCI version.
271 * @prepare_data: function to setup MCI before data transfer which
272 * depends on MCI capabilities.
273 * @submit_data: function to start data transfer which depends on MCI
274 * capabilities.
275 * @stop_transfer: function to stop data transfer which depends on MCI
276 * capabilities.
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +0200277 *
278 * Locking
279 * =======
280 *
281 * @lock is a softirq-safe spinlock protecting @queue as well as
282 * @cur_slot, @mrq and @state. These must always be updated
283 * at the same time while holding @lock.
284 *
285 * @lock also protects mode_reg and need_clock_update since these are
286 * used to synchronize mode register updates with the queue
287 * processing.
288 *
289 * The @mrq field of struct atmel_mci_slot is also protected by @lock,
290 * and must always be written at the same time as the slot is added to
291 * @queue.
292 *
293 * @pending_events and @completed_events are accessed using atomic bit
294 * operations, so they don't need any locking.
295 *
296 * None of the fields touched by the interrupt handler need any
297 * locking. However, ordering is important: Before EVENT_DATA_ERROR or
298 * EVENT_DATA_COMPLETE is set in @pending_events, all data-related
299 * interrupts must be disabled and @data_status updated with a
300 * snapshot of SR. Similarly, before EVENT_CMD_COMPLETE is set, the
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300301 * CMDRDY interrupt must be disabled and @cmd_status updated with a
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +0200302 * snapshot of SR, and before EVENT_XFER_COMPLETE can be set, the
303 * bytes_xfered field of @data must be written. This is ensured by
304 * using barriers.
305 */
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +0200306struct atmel_mci {
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +0200307 spinlock_t lock;
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +0200308 void __iomem *regs;
309
310 struct scatterlist *sg;
Terry Barnabybdbc5d02013-04-08 12:05:47 -0400311 unsigned int sg_len;
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +0200312 unsigned int pio_offset;
Ludovic Desroches7a90dcc2012-05-16 15:25:58 +0200313 unsigned int *buffer;
314 unsigned int buf_size;
315 dma_addr_t buf_phys_addr;
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +0200316
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +0200317 struct atmel_mci_slot *cur_slot;
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +0200318 struct mmc_request *mrq;
319 struct mmc_command *cmd;
320 struct mmc_data *data;
Ludovic Desroches796211b2011-08-11 15:25:44 +0000321 unsigned int data_size;
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +0200322
Haavard Skinnemoen65e8b082008-07-30 20:29:03 +0200323 struct atmel_mci_dma dma;
324 struct dma_chan *data_chan;
Viresh Kumare2b35f32012-02-01 16:12:27 +0530325 struct dma_slave_config dma_conf;
Haavard Skinnemoen65e8b082008-07-30 20:29:03 +0200326
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +0200327 u32 cmd_status;
328 u32 data_status;
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +0200329 u32 stop_cmdr;
330
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +0200331 struct tasklet_struct tasklet;
332 unsigned long pending_events;
333 unsigned long completed_events;
Haavard Skinnemoenc06ad252008-07-31 14:49:16 +0200334 enum atmel_mci_state state;
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +0200335 struct list_head queue;
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +0200336
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +0200337 bool need_clock_update;
338 bool need_reset;
Ludovic Desroches24011f32012-05-16 15:26:00 +0200339 struct timer_list timer;
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +0200340 u32 mode_reg;
Nicolas Ferre74791a22009-12-14 18:01:31 -0800341 u32 cfg_reg;
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +0200342 unsigned long bus_hz;
343 unsigned long mapbase;
344 struct clk *mck;
345 struct platform_device *pdev;
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +0200346
Ludovic Desroches2c96a292011-08-11 15:25:41 +0000347 struct atmel_mci_slot *slot[ATMCI_MAX_NR_SLOTS];
Ludovic Desroches796211b2011-08-11 15:25:44 +0000348
349 struct atmel_mci_caps caps;
350
351 u32 (*prepare_data)(struct atmel_mci *host, struct mmc_data *data);
352 void (*submit_data)(struct atmel_mci *host, struct mmc_data *data);
353 void (*stop_transfer)(struct atmel_mci *host);
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +0200354};
355
356/**
357 * struct atmel_mci_slot - MMC slot state
358 * @mmc: The mmc_host representing this slot.
359 * @host: The MMC controller this slot is using.
360 * @sdc_reg: Value of SDCR to be written before using this slot.
Anders Grahn88ff82e2010-05-26 14:42:01 -0700361 * @sdio_irq: SDIO irq mask for this slot.
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +0200362 * @mrq: mmc_request currently being processed or waiting to be
363 * processed, or NULL when the slot is idle.
364 * @queue_node: List node for placing this node in the @queue list of
365 * &struct atmel_mci.
366 * @clock: Clock rate configured by set_ios(). Protected by host->lock.
367 * @flags: Random state bits associated with the slot.
368 * @detect_pin: GPIO pin used for card detection, or negative if not
369 * available.
370 * @wp_pin: GPIO pin used for card write protect sending, or negative
371 * if not available.
Jonas Larsson1c1452b2009-03-31 11:16:48 +0200372 * @detect_is_active_high: The state of the detect pin when it is active.
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +0200373 * @detect_timer: Timer used for debouncing @detect_pin interrupts.
374 */
375struct atmel_mci_slot {
376 struct mmc_host *mmc;
377 struct atmel_mci *host;
378
379 u32 sdc_reg;
Anders Grahn88ff82e2010-05-26 14:42:01 -0700380 u32 sdio_irq;
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +0200381
382 struct mmc_request *mrq;
383 struct list_head queue_node;
384
385 unsigned int clock;
386 unsigned long flags;
387#define ATMCI_CARD_PRESENT 0
388#define ATMCI_CARD_NEED_INIT 1
389#define ATMCI_SHUTDOWN 2
390
391 int detect_pin;
392 int wp_pin;
Jonas Larsson1c1452b2009-03-31 11:16:48 +0200393 bool detect_is_active_high;
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +0200394
395 struct timer_list detect_timer;
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +0200396};
397
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +0200398#define atmci_test_and_clear_pending(host, event) \
399 test_and_clear_bit(event, &host->pending_events)
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +0200400#define atmci_set_completed(host, event) \
401 set_bit(event, &host->completed_events)
402#define atmci_set_pending(host, event) \
403 set_bit(event, &host->pending_events)
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +0200404
Haavard Skinnemoendeec9ae2008-07-24 14:18:59 +0200405/*
406 * The debugfs stuff below is mostly optimized away when
407 * CONFIG_DEBUG_FS is not set.
408 */
409static int atmci_req_show(struct seq_file *s, void *v)
410{
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +0200411 struct atmel_mci_slot *slot = s->private;
412 struct mmc_request *mrq;
Haavard Skinnemoendeec9ae2008-07-24 14:18:59 +0200413 struct mmc_command *cmd;
414 struct mmc_command *stop;
415 struct mmc_data *data;
416
417 /* Make sure we get a consistent snapshot */
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +0200418 spin_lock_bh(&slot->host->lock);
419 mrq = slot->mrq;
Haavard Skinnemoendeec9ae2008-07-24 14:18:59 +0200420
421 if (mrq) {
422 cmd = mrq->cmd;
423 data = mrq->data;
424 stop = mrq->stop;
425
426 if (cmd)
427 seq_printf(s,
428 "CMD%u(0x%x) flg %x rsp %x %x %x %x err %d\n",
429 cmd->opcode, cmd->arg, cmd->flags,
430 cmd->resp[0], cmd->resp[1], cmd->resp[2],
Nicolas Ferred586ebb2010-05-11 14:06:50 -0700431 cmd->resp[3], cmd->error);
Haavard Skinnemoendeec9ae2008-07-24 14:18:59 +0200432 if (data)
433 seq_printf(s, "DATA %u / %u * %u flg %x err %d\n",
434 data->bytes_xfered, data->blocks,
435 data->blksz, data->flags, data->error);
436 if (stop)
437 seq_printf(s,
438 "CMD%u(0x%x) flg %x rsp %x %x %x %x err %d\n",
439 stop->opcode, stop->arg, stop->flags,
440 stop->resp[0], stop->resp[1], stop->resp[2],
Nicolas Ferred586ebb2010-05-11 14:06:50 -0700441 stop->resp[3], stop->error);
Haavard Skinnemoendeec9ae2008-07-24 14:18:59 +0200442 }
443
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +0200444 spin_unlock_bh(&slot->host->lock);
Haavard Skinnemoendeec9ae2008-07-24 14:18:59 +0200445
446 return 0;
447}
448
449static int atmci_req_open(struct inode *inode, struct file *file)
450{
451 return single_open(file, atmci_req_show, inode->i_private);
452}
453
454static const struct file_operations atmci_req_fops = {
455 .owner = THIS_MODULE,
456 .open = atmci_req_open,
457 .read = seq_read,
458 .llseek = seq_lseek,
459 .release = single_release,
460};
461
462static void atmci_show_status_reg(struct seq_file *s,
463 const char *regname, u32 value)
464{
465 static const char *sr_bit[] = {
466 [0] = "CMDRDY",
467 [1] = "RXRDY",
468 [2] = "TXRDY",
469 [3] = "BLKE",
470 [4] = "DTIP",
471 [5] = "NOTBUSY",
Rob Emanuele04d699c2009-09-22 16:45:19 -0700472 [6] = "ENDRX",
473 [7] = "ENDTX",
Haavard Skinnemoendeec9ae2008-07-24 14:18:59 +0200474 [8] = "SDIOIRQA",
475 [9] = "SDIOIRQB",
Rob Emanuele04d699c2009-09-22 16:45:19 -0700476 [12] = "SDIOWAIT",
477 [14] = "RXBUFF",
478 [15] = "TXBUFE",
Haavard Skinnemoendeec9ae2008-07-24 14:18:59 +0200479 [16] = "RINDE",
480 [17] = "RDIRE",
481 [18] = "RCRCE",
482 [19] = "RENDE",
483 [20] = "RTOE",
484 [21] = "DCRCE",
485 [22] = "DTOE",
Rob Emanuele04d699c2009-09-22 16:45:19 -0700486 [23] = "CSTOE",
487 [24] = "BLKOVRE",
488 [25] = "DMADONE",
489 [26] = "FIFOEMPTY",
490 [27] = "XFRDONE",
Haavard Skinnemoendeec9ae2008-07-24 14:18:59 +0200491 [30] = "OVRE",
492 [31] = "UNRE",
493 };
494 unsigned int i;
495
496 seq_printf(s, "%s:\t0x%08x", regname, value);
497 for (i = 0; i < ARRAY_SIZE(sr_bit); i++) {
498 if (value & (1 << i)) {
499 if (sr_bit[i])
500 seq_printf(s, " %s", sr_bit[i]);
501 else
502 seq_puts(s, " UNKNOWN");
503 }
504 }
505 seq_putc(s, '\n');
506}
507
508static int atmci_regs_show(struct seq_file *s, void *v)
509{
510 struct atmel_mci *host = s->private;
511 u32 *buf;
Boris BREZILLONb3894f22013-07-18 09:38:52 +0200512 int ret = 0;
513
Haavard Skinnemoendeec9ae2008-07-24 14:18:59 +0200514
Ludovic Desroches2c96a292011-08-11 15:25:41 +0000515 buf = kmalloc(ATMCI_REGS_SIZE, GFP_KERNEL);
Haavard Skinnemoendeec9ae2008-07-24 14:18:59 +0200516 if (!buf)
517 return -ENOMEM;
518
Wenyou Yangae552ab2014-10-30 12:00:41 +0800519 pm_runtime_get_sync(&host->pdev->dev);
520
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +0200521 /*
522 * Grab a more or less consistent snapshot. Note that we're
523 * not disabling interrupts, so IMR and SR may not be
524 * consistent.
525 */
526 spin_lock_bh(&host->lock);
Ludovic Desroches2c96a292011-08-11 15:25:41 +0000527 memcpy_fromio(buf, host->regs, ATMCI_REGS_SIZE);
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +0200528 spin_unlock_bh(&host->lock);
Haavard Skinnemoendeec9ae2008-07-24 14:18:59 +0200529
Wenyou Yangae552ab2014-10-30 12:00:41 +0800530 pm_runtime_mark_last_busy(&host->pdev->dev);
531 pm_runtime_put_autosuspend(&host->pdev->dev);
Boris BREZILLONb3894f22013-07-18 09:38:52 +0200532
Nicolas Ferre8a4de072012-07-06 12:11:51 +0200533 seq_printf(s, "MR:\t0x%08x%s%s ",
Ludovic Desroches2c96a292011-08-11 15:25:41 +0000534 buf[ATMCI_MR / 4],
535 buf[ATMCI_MR / 4] & ATMCI_MR_RDPROOF ? " RDPROOF" : "",
Nicolas Ferre8a4de072012-07-06 12:11:51 +0200536 buf[ATMCI_MR / 4] & ATMCI_MR_WRPROOF ? " WRPROOF" : "");
537 if (host->caps.has_odd_clk_div)
538 seq_printf(s, "{CLKDIV,CLKODD}=%u\n",
539 ((buf[ATMCI_MR / 4] & 0xff) << 1)
540 | ((buf[ATMCI_MR / 4] >> 16) & 1));
541 else
542 seq_printf(s, "CLKDIV=%u\n",
543 (buf[ATMCI_MR / 4] & 0xff));
Ludovic Desroches2c96a292011-08-11 15:25:41 +0000544 seq_printf(s, "DTOR:\t0x%08x\n", buf[ATMCI_DTOR / 4]);
545 seq_printf(s, "SDCR:\t0x%08x\n", buf[ATMCI_SDCR / 4]);
546 seq_printf(s, "ARGR:\t0x%08x\n", buf[ATMCI_ARGR / 4]);
Haavard Skinnemoendeec9ae2008-07-24 14:18:59 +0200547 seq_printf(s, "BLKR:\t0x%08x BCNT=%u BLKLEN=%u\n",
Ludovic Desroches2c96a292011-08-11 15:25:41 +0000548 buf[ATMCI_BLKR / 4],
549 buf[ATMCI_BLKR / 4] & 0xffff,
550 (buf[ATMCI_BLKR / 4] >> 16) & 0xffff);
Ludovic Desroches796211b2011-08-11 15:25:44 +0000551 if (host->caps.has_cstor_reg)
Ludovic Desroches2c96a292011-08-11 15:25:41 +0000552 seq_printf(s, "CSTOR:\t0x%08x\n", buf[ATMCI_CSTOR / 4]);
Haavard Skinnemoendeec9ae2008-07-24 14:18:59 +0200553
554 /* Don't read RSPR and RDR; it will consume the data there */
555
Ludovic Desroches2c96a292011-08-11 15:25:41 +0000556 atmci_show_status_reg(s, "SR", buf[ATMCI_SR / 4]);
557 atmci_show_status_reg(s, "IMR", buf[ATMCI_IMR / 4]);
Haavard Skinnemoendeec9ae2008-07-24 14:18:59 +0200558
Hein_Tiboschccdfe612012-08-30 16:34:38 +0000559 if (host->caps.has_dma_conf_reg) {
Nicolas Ferre74791a22009-12-14 18:01:31 -0800560 u32 val;
561
Ludovic Desroches2c96a292011-08-11 15:25:41 +0000562 val = buf[ATMCI_DMA / 4];
Nicolas Ferre74791a22009-12-14 18:01:31 -0800563 seq_printf(s, "DMA:\t0x%08x OFFSET=%u CHKSIZE=%u%s\n",
564 val, val & 3,
565 ((val >> 4) & 3) ?
566 1 << (((val >> 4) & 3) + 1) : 1,
Ludovic Desroches2c96a292011-08-11 15:25:41 +0000567 val & ATMCI_DMAEN ? " DMAEN" : "");
Ludovic Desroches796211b2011-08-11 15:25:44 +0000568 }
569 if (host->caps.has_cfg_reg) {
570 u32 val;
Nicolas Ferre74791a22009-12-14 18:01:31 -0800571
Ludovic Desroches2c96a292011-08-11 15:25:41 +0000572 val = buf[ATMCI_CFG / 4];
Nicolas Ferre74791a22009-12-14 18:01:31 -0800573 seq_printf(s, "CFG:\t0x%08x%s%s%s%s\n",
574 val,
Ludovic Desroches2c96a292011-08-11 15:25:41 +0000575 val & ATMCI_CFG_FIFOMODE_1DATA ? " FIFOMODE_ONE_DATA" : "",
576 val & ATMCI_CFG_FERRCTRL_COR ? " FERRCTRL_CLEAR_ON_READ" : "",
577 val & ATMCI_CFG_HSMODE ? " HSMODE" : "",
578 val & ATMCI_CFG_LSYNC ? " LSYNC" : "");
Nicolas Ferre74791a22009-12-14 18:01:31 -0800579 }
580
Haavard Skinnemoenb17339a2008-09-19 21:09:28 +0200581 kfree(buf);
582
Boris BREZILLONb3894f22013-07-18 09:38:52 +0200583 return ret;
Haavard Skinnemoendeec9ae2008-07-24 14:18:59 +0200584}
585
586static int atmci_regs_open(struct inode *inode, struct file *file)
587{
588 return single_open(file, atmci_regs_show, inode->i_private);
589}
590
591static const struct file_operations atmci_regs_fops = {
592 .owner = THIS_MODULE,
593 .open = atmci_regs_open,
594 .read = seq_read,
595 .llseek = seq_lseek,
596 .release = single_release,
597};
598
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +0200599static void atmci_init_debugfs(struct atmel_mci_slot *slot)
Haavard Skinnemoendeec9ae2008-07-24 14:18:59 +0200600{
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +0200601 struct mmc_host *mmc = slot->mmc;
602 struct atmel_mci *host = slot->host;
603 struct dentry *root;
604 struct dentry *node;
Haavard Skinnemoendeec9ae2008-07-24 14:18:59 +0200605
Haavard Skinnemoendeec9ae2008-07-24 14:18:59 +0200606 root = mmc->debugfs_root;
607 if (!root)
608 return;
609
610 node = debugfs_create_file("regs", S_IRUSR, root, host,
611 &atmci_regs_fops);
612 if (IS_ERR(node))
613 return;
614 if (!node)
615 goto err;
616
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +0200617 node = debugfs_create_file("req", S_IRUSR, root, slot, &atmci_req_fops);
Haavard Skinnemoendeec9ae2008-07-24 14:18:59 +0200618 if (!node)
619 goto err;
620
Haavard Skinnemoenc06ad252008-07-31 14:49:16 +0200621 node = debugfs_create_u32("state", S_IRUSR, root, (u32 *)&host->state);
622 if (!node)
623 goto err;
624
Haavard Skinnemoendeec9ae2008-07-24 14:18:59 +0200625 node = debugfs_create_x32("pending_events", S_IRUSR, root,
626 (u32 *)&host->pending_events);
627 if (!node)
628 goto err;
629
630 node = debugfs_create_x32("completed_events", S_IRUSR, root,
631 (u32 *)&host->completed_events);
632 if (!node)
633 goto err;
634
635 return;
636
637err:
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +0200638 dev_err(&mmc->class_dev, "failed to initialize debugfs for slot\n");
Haavard Skinnemoendeec9ae2008-07-24 14:18:59 +0200639}
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +0200640
Ludovic Desrochese919fd22012-07-24 15:30:03 +0200641#if defined(CONFIG_OF)
642static const struct of_device_id atmci_dt_ids[] = {
643 { .compatible = "atmel,hsmci" },
644 { /* sentinel */ }
645};
646
647MODULE_DEVICE_TABLE(of, atmci_dt_ids);
648
Bill Pembertonc3be1ef2012-11-19 13:23:06 -0500649static struct mci_platform_data*
Ludovic Desrochese919fd22012-07-24 15:30:03 +0200650atmci_of_init(struct platform_device *pdev)
651{
652 struct device_node *np = pdev->dev.of_node;
653 struct device_node *cnp;
654 struct mci_platform_data *pdata;
655 u32 slot_id;
656
657 if (!np) {
658 dev_err(&pdev->dev, "device node not found\n");
659 return ERR_PTR(-EINVAL);
660 }
661
662 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
Markus Elfring9b344ba2017-05-13 15:05:28 +0200663 if (!pdata)
Ludovic Desrochese919fd22012-07-24 15:30:03 +0200664 return ERR_PTR(-ENOMEM);
Ludovic Desrochese919fd22012-07-24 15:30:03 +0200665
666 for_each_child_of_node(np, cnp) {
667 if (of_property_read_u32(cnp, "reg", &slot_id)) {
668 dev_warn(&pdev->dev, "reg property is missing for %s\n",
669 cnp->full_name);
670 continue;
671 }
672
673 if (slot_id >= ATMCI_MAX_NR_SLOTS) {
674 dev_warn(&pdev->dev, "can't have more than %d slots\n",
675 ATMCI_MAX_NR_SLOTS);
676 break;
677 }
678
679 if (of_property_read_u32(cnp, "bus-width",
680 &pdata->slot[slot_id].bus_width))
681 pdata->slot[slot_id].bus_width = 1;
682
683 pdata->slot[slot_id].detect_pin =
684 of_get_named_gpio(cnp, "cd-gpios", 0);
685
686 pdata->slot[slot_id].detect_is_active_high =
687 of_property_read_bool(cnp, "cd-inverted");
688
Timo Kokkonen76d55562014-11-03 13:12:59 +0200689 pdata->slot[slot_id].non_removable =
690 of_property_read_bool(cnp, "non-removable");
691
Ludovic Desrochese919fd22012-07-24 15:30:03 +0200692 pdata->slot[slot_id].wp_pin =
693 of_get_named_gpio(cnp, "wp-gpios", 0);
694 }
695
696 return pdata;
697}
698#else /* CONFIG_OF */
699static inline struct mci_platform_data*
700atmci_of_init(struct platform_device *dev)
701{
702 return ERR_PTR(-EINVAL);
703}
704#endif
705
Ludovic Desroches7a90dcc2012-05-16 15:25:58 +0200706static inline unsigned int atmci_get_version(struct atmel_mci *host)
707{
708 return atmci_readl(host, ATMCI_VERSION) & 0x00000fff;
709}
710
ludovic.desroches@atmel.com447dc0d2015-11-23 16:27:32 +0100711/*
712 * Fix sconfig's burst size according to atmel MCI. We need to convert them as:
713 * 1 -> 0, 4 -> 1, 8 -> 2, 16 -> 3.
714 * With version 0x600, we need to convert them as: 1 -> 0, 2 -> 1, 4 -> 2,
715 * 8 -> 3, 16 -> 4.
716 *
717 * This can be done by finding most significant bit set.
718 */
719static inline unsigned int atmci_convert_chksize(struct atmel_mci *host,
720 unsigned int maxburst)
721{
722 unsigned int version = atmci_get_version(host);
723 unsigned int offset = 2;
724
725 if (version >= 0x600)
726 offset = 1;
727
728 if (maxburst > 1)
729 return fls(maxburst) - offset;
730 else
731 return 0;
732}
733
Ludovic Desroches24011f32012-05-16 15:26:00 +0200734static void atmci_timeout_timer(unsigned long data)
735{
736 struct atmel_mci *host;
737
738 host = (struct atmel_mci *)data;
739
740 dev_dbg(&host->pdev->dev, "software timeout\n");
741
742 if (host->mrq->cmd->data) {
743 host->mrq->cmd->data->error = -ETIMEDOUT;
744 host->data = NULL;
Ludovic Desrochesc1fa3422013-09-09 17:29:56 +0200745 /*
746 * With some SDIO modules, sometimes DMA transfer hangs. If
747 * stop_transfer() is not called then the DMA request is not
748 * removed, following ones are queued and never computed.
749 */
750 if (host->state == STATE_DATA_XFER)
751 host->stop_transfer(host);
Ludovic Desroches24011f32012-05-16 15:26:00 +0200752 } else {
753 host->mrq->cmd->error = -ETIMEDOUT;
754 host->cmd = NULL;
755 }
756 host->need_reset = 1;
757 host->state = STATE_END_REQUEST;
758 smp_wmb();
759 tasklet_schedule(&host->tasklet);
760}
761
Ludovic Desroches2c96a292011-08-11 15:25:41 +0000762static inline unsigned int atmci_ns_to_clocks(struct atmel_mci *host,
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +0200763 unsigned int ns)
764{
Ludovic Desroches66292ad2012-03-28 12:28:33 +0200765 /*
766 * It is easier here to use us instead of ns for the timeout,
767 * it prevents from overflows during calculation.
768 */
769 unsigned int us = DIV_ROUND_UP(ns, 1000);
770
771 /* Maximum clock frequency is host->bus_hz/2 */
772 return us * (DIV_ROUND_UP(host->bus_hz, 2000000));
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +0200773}
774
775static void atmci_set_timeout(struct atmel_mci *host,
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +0200776 struct atmel_mci_slot *slot, struct mmc_data *data)
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +0200777{
778 static unsigned dtomul_to_shift[] = {
779 0, 4, 7, 8, 10, 12, 16, 20
780 };
781 unsigned timeout;
782 unsigned dtocyc;
783 unsigned dtomul;
784
Ludovic Desroches2c96a292011-08-11 15:25:41 +0000785 timeout = atmci_ns_to_clocks(host, data->timeout_ns)
786 + data->timeout_clks;
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +0200787
788 for (dtomul = 0; dtomul < 8; dtomul++) {
789 unsigned shift = dtomul_to_shift[dtomul];
790 dtocyc = (timeout + (1 << shift) - 1) >> shift;
791 if (dtocyc < 15)
792 break;
793 }
794
795 if (dtomul >= 8) {
796 dtomul = 7;
797 dtocyc = 15;
798 }
799
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +0200800 dev_vdbg(&slot->mmc->class_dev, "setting timeout to %u cycles\n",
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +0200801 dtocyc << dtomul_to_shift[dtomul]);
Ludovic Desroches03fc9a72011-08-11 15:25:42 +0000802 atmci_writel(host, ATMCI_DTOR, (ATMCI_DTOMUL(dtomul) | ATMCI_DTOCYC(dtocyc)));
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +0200803}
804
805/*
806 * Return mask with command flags to be enabled for this command.
807 */
808static u32 atmci_prepare_command(struct mmc_host *mmc,
809 struct mmc_command *cmd)
810{
811 struct mmc_data *data;
812 u32 cmdr;
813
814 cmd->error = -EINPROGRESS;
815
Ludovic Desroches2c96a292011-08-11 15:25:41 +0000816 cmdr = ATMCI_CMDR_CMDNB(cmd->opcode);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +0200817
818 if (cmd->flags & MMC_RSP_PRESENT) {
819 if (cmd->flags & MMC_RSP_136)
Ludovic Desroches2c96a292011-08-11 15:25:41 +0000820 cmdr |= ATMCI_CMDR_RSPTYP_136BIT;
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +0200821 else
Ludovic Desroches2c96a292011-08-11 15:25:41 +0000822 cmdr |= ATMCI_CMDR_RSPTYP_48BIT;
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +0200823 }
824
825 /*
826 * This should really be MAXLAT_5 for CMD2 and ACMD41, but
827 * it's too difficult to determine whether this is an ACMD or
828 * not. Better make it 64.
829 */
Ludovic Desroches2c96a292011-08-11 15:25:41 +0000830 cmdr |= ATMCI_CMDR_MAXLAT_64CYC;
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +0200831
832 if (mmc->ios.bus_mode == MMC_BUSMODE_OPENDRAIN)
Ludovic Desroches2c96a292011-08-11 15:25:41 +0000833 cmdr |= ATMCI_CMDR_OPDCMD;
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +0200834
835 data = cmd->data;
836 if (data) {
Ludovic Desroches2c96a292011-08-11 15:25:41 +0000837 cmdr |= ATMCI_CMDR_START_XFER;
Nicolas Ferre2f1d7912010-12-10 19:14:32 +0100838
839 if (cmd->opcode == SD_IO_RW_EXTENDED) {
Ludovic Desroches2c96a292011-08-11 15:25:41 +0000840 cmdr |= ATMCI_CMDR_SDIO_BLOCK;
Nicolas Ferre2f1d7912010-12-10 19:14:32 +0100841 } else {
Jaehoon Chungfd551d92016-02-01 21:07:26 +0900842 if (data->blocks > 1)
Ludovic Desroches2c96a292011-08-11 15:25:41 +0000843 cmdr |= ATMCI_CMDR_MULTI_BLOCK;
Nicolas Ferre2f1d7912010-12-10 19:14:32 +0100844 else
Ludovic Desroches2c96a292011-08-11 15:25:41 +0000845 cmdr |= ATMCI_CMDR_BLOCK;
Nicolas Ferre2f1d7912010-12-10 19:14:32 +0100846 }
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +0200847
848 if (data->flags & MMC_DATA_READ)
Ludovic Desroches2c96a292011-08-11 15:25:41 +0000849 cmdr |= ATMCI_CMDR_TRDIR_READ;
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +0200850 }
851
852 return cmdr;
853}
854
Ludovic Desroches11d14882011-08-11 15:25:45 +0000855static void atmci_send_command(struct atmel_mci *host,
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +0200856 struct mmc_command *cmd, u32 cmd_flags)
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +0200857{
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +0200858 WARN_ON(host->cmd);
859 host->cmd = cmd;
860
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +0200861 dev_vdbg(&host->pdev->dev,
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +0200862 "start command: ARGR=0x%08x CMDR=0x%08x\n",
863 cmd->arg, cmd_flags);
864
Ludovic Desroches03fc9a72011-08-11 15:25:42 +0000865 atmci_writel(host, ATMCI_ARGR, cmd->arg);
866 atmci_writel(host, ATMCI_CMDR, cmd_flags);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +0200867}
868
Ludovic Desroches2c96a292011-08-11 15:25:41 +0000869static void atmci_send_stop_cmd(struct atmel_mci *host, struct mmc_data *data)
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +0200870{
Ludovic Desroches6801c412012-05-16 15:26:01 +0200871 dev_dbg(&host->pdev->dev, "send stop command\n");
Ludovic Desroches11d14882011-08-11 15:25:45 +0000872 atmci_send_command(host, data->stop, host->stop_cmdr);
Ludovic Desroches03fc9a72011-08-11 15:25:42 +0000873 atmci_writel(host, ATMCI_IER, ATMCI_CMDRDY);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +0200874}
875
Ludovic Desroches796211b2011-08-11 15:25:44 +0000876/*
877 * Configure given PDC buffer taking care of alignement issues.
878 * Update host->data_size and host->sg.
879 */
880static void atmci_pdc_set_single_buf(struct atmel_mci *host,
881 enum atmci_xfer_dir dir, enum atmci_pdc_buf buf_nb)
Haavard Skinnemoen65e8b082008-07-30 20:29:03 +0200882{
Ludovic Desroches796211b2011-08-11 15:25:44 +0000883 u32 pointer_reg, counter_reg;
Ludovic Desroches7a90dcc2012-05-16 15:25:58 +0200884 unsigned int buf_size;
Haavard Skinnemoen65e8b082008-07-30 20:29:03 +0200885
Ludovic Desroches796211b2011-08-11 15:25:44 +0000886 if (dir == XFER_RECEIVE) {
887 pointer_reg = ATMEL_PDC_RPR;
888 counter_reg = ATMEL_PDC_RCR;
889 } else {
890 pointer_reg = ATMEL_PDC_TPR;
891 counter_reg = ATMEL_PDC_TCR;
892 }
893
894 if (buf_nb == PDC_SECOND_BUF) {
Ludovic Desroches1ebbe3d2011-08-11 15:25:46 +0000895 pointer_reg += ATMEL_PDC_SCND_BUF_OFF;
896 counter_reg += ATMEL_PDC_SCND_BUF_OFF;
Ludovic Desroches796211b2011-08-11 15:25:44 +0000897 }
898
Ludovic Desroches7a90dcc2012-05-16 15:25:58 +0200899 if (!host->caps.has_rwproof) {
900 buf_size = host->buf_size;
901 atmci_writel(host, pointer_reg, host->buf_phys_addr);
902 } else {
903 buf_size = sg_dma_len(host->sg);
904 atmci_writel(host, pointer_reg, sg_dma_address(host->sg));
905 }
906
907 if (host->data_size <= buf_size) {
Ludovic Desroches796211b2011-08-11 15:25:44 +0000908 if (host->data_size & 0x3) {
909 /* If size is different from modulo 4, transfer bytes */
910 atmci_writel(host, counter_reg, host->data_size);
911 atmci_writel(host, ATMCI_MR, host->mode_reg | ATMCI_MR_PDCFBYTE);
912 } else {
913 /* Else transfer 32-bits words */
914 atmci_writel(host, counter_reg, host->data_size / 4);
915 }
916 host->data_size = 0;
917 } else {
918 /* We assume the size of a page is 32-bits aligned */
Ludovic Desroches341fa4c2011-08-11 15:25:47 +0000919 atmci_writel(host, counter_reg, sg_dma_len(host->sg) / 4);
920 host->data_size -= sg_dma_len(host->sg);
Ludovic Desroches796211b2011-08-11 15:25:44 +0000921 if (host->data_size)
922 host->sg = sg_next(host->sg);
923 }
Haavard Skinnemoen65e8b082008-07-30 20:29:03 +0200924}
925
Ludovic Desroches796211b2011-08-11 15:25:44 +0000926/*
927 * Configure PDC buffer according to the data size ie configuring one or two
928 * buffers. Don't use this function if you want to configure only the second
929 * buffer. In this case, use atmci_pdc_set_single_buf.
930 */
931static void atmci_pdc_set_both_buf(struct atmel_mci *host, int dir)
Haavard Skinnemoen65e8b082008-07-30 20:29:03 +0200932{
Ludovic Desroches796211b2011-08-11 15:25:44 +0000933 atmci_pdc_set_single_buf(host, dir, PDC_FIRST_BUF);
934 if (host->data_size)
935 atmci_pdc_set_single_buf(host, dir, PDC_SECOND_BUF);
936}
Haavard Skinnemoen65e8b082008-07-30 20:29:03 +0200937
Ludovic Desroches796211b2011-08-11 15:25:44 +0000938/*
939 * Unmap sg lists, called when transfer is finished.
940 */
941static void atmci_pdc_cleanup(struct atmel_mci *host)
942{
943 struct mmc_data *data = host->data;
944
945 if (data)
946 dma_unmap_sg(&host->pdev->dev,
947 data->sg, data->sg_len,
Heiner Kallweitfeeef092017-03-26 20:45:56 +0200948 mmc_get_dma_dir(data));
Ludovic Desroches796211b2011-08-11 15:25:44 +0000949}
950
951/*
952 * Disable PDC transfers. Update pending flags to EVENT_XFER_COMPLETE after
953 * having received ATMCI_TXBUFE or ATMCI_RXBUFF interrupt. Enable ATMCI_NOTBUSY
954 * interrupt needed for both transfer directions.
955 */
956static void atmci_pdc_complete(struct atmel_mci *host)
957{
Ludovic Desroches7a90dcc2012-05-16 15:25:58 +0200958 int transfer_size = host->data->blocks * host->data->blksz;
Ludovic Desroches24011f32012-05-16 15:26:00 +0200959 int i;
Ludovic Desroches7a90dcc2012-05-16 15:25:58 +0200960
Ludovic Desroches796211b2011-08-11 15:25:44 +0000961 atmci_writel(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS | ATMEL_PDC_TXTDIS);
Ludovic Desroches7a90dcc2012-05-16 15:25:58 +0200962
963 if ((!host->caps.has_rwproof)
Ludovic Desroches24011f32012-05-16 15:26:00 +0200964 && (host->data->flags & MMC_DATA_READ)) {
965 if (host->caps.has_bad_data_ordering)
966 for (i = 0; i < transfer_size; i++)
967 host->buffer[i] = swab32(host->buffer[i]);
Ludovic Desroches7a90dcc2012-05-16 15:25:58 +0200968 sg_copy_from_buffer(host->data->sg, host->data->sg_len,
969 host->buffer, transfer_size);
Ludovic Desroches24011f32012-05-16 15:26:00 +0200970 }
Ludovic Desroches7a90dcc2012-05-16 15:25:58 +0200971
Ludovic Desroches796211b2011-08-11 15:25:44 +0000972 atmci_pdc_cleanup(host);
973
Alexandre Belloni6e9e4062014-05-06 17:43:26 +0200974 dev_dbg(&host->pdev->dev, "(%s) set pending xfer complete\n", __func__);
975 atmci_set_pending(host, EVENT_XFER_COMPLETE);
976 tasklet_schedule(&host->tasklet);
Haavard Skinnemoen65e8b082008-07-30 20:29:03 +0200977}
978
Ludovic Desroches796211b2011-08-11 15:25:44 +0000979static void atmci_dma_cleanup(struct atmel_mci *host)
980{
981 struct mmc_data *data = host->data;
982
983 if (data)
984 dma_unmap_sg(host->dma.chan->device->dev,
985 data->sg, data->sg_len,
Heiner Kallweitfeeef092017-03-26 20:45:56 +0200986 mmc_get_dma_dir(data));
Ludovic Desroches796211b2011-08-11 15:25:44 +0000987}
988
989/*
990 * This function is called by the DMA driver from tasklet context.
991 */
Haavard Skinnemoen65e8b082008-07-30 20:29:03 +0200992static void atmci_dma_complete(void *arg)
993{
994 struct atmel_mci *host = arg;
995 struct mmc_data *data = host->data;
996
997 dev_vdbg(&host->pdev->dev, "DMA complete\n");
998
Hein_Tiboschccdfe612012-08-30 16:34:38 +0000999 if (host->caps.has_dma_conf_reg)
Nicolas Ferre74791a22009-12-14 18:01:31 -08001000 /* Disable DMA hardware handshaking on MCI */
Ludovic Desroches03fc9a72011-08-11 15:25:42 +00001001 atmci_writel(host, ATMCI_DMA, atmci_readl(host, ATMCI_DMA) & ~ATMCI_DMAEN);
Nicolas Ferre74791a22009-12-14 18:01:31 -08001002
Haavard Skinnemoen65e8b082008-07-30 20:29:03 +02001003 atmci_dma_cleanup(host);
1004
1005 /*
1006 * If the card was removed, data will be NULL. No point trying
1007 * to send the stop command or waiting for NBUSY in this case.
1008 */
1009 if (data) {
Ludovic Desroches6801c412012-05-16 15:26:01 +02001010 dev_dbg(&host->pdev->dev,
1011 "(%s) set pending xfer complete\n", __func__);
Haavard Skinnemoen65e8b082008-07-30 20:29:03 +02001012 atmci_set_pending(host, EVENT_XFER_COMPLETE);
1013 tasklet_schedule(&host->tasklet);
1014
1015 /*
1016 * Regardless of what the documentation says, we have
1017 * to wait for NOTBUSY even after block read
1018 * operations.
1019 *
1020 * When the DMA transfer is complete, the controller
1021 * may still be reading the CRC from the card, i.e.
1022 * the data transfer is still in progress and we
1023 * haven't seen all the potential error bits yet.
1024 *
1025 * The interrupt handler will schedule a different
1026 * tasklet to finish things up when the data transfer
1027 * is completely done.
1028 *
1029 * We may not complete the mmc request here anyway
1030 * because the mmc layer may call back and cause us to
1031 * violate the "don't submit new operations from the
1032 * completion callback" rule of the dma engine
1033 * framework.
1034 */
Ludovic Desroches03fc9a72011-08-11 15:25:42 +00001035 atmci_writel(host, ATMCI_IER, ATMCI_NOTBUSY);
Haavard Skinnemoen65e8b082008-07-30 20:29:03 +02001036 }
1037}
1038
Ludovic Desroches796211b2011-08-11 15:25:44 +00001039/*
1040 * Returns a mask of interrupt flags to be enabled after the whole
1041 * request has been prepared.
1042 */
1043static u32 atmci_prepare_data(struct atmel_mci *host, struct mmc_data *data)
1044{
1045 u32 iflags;
1046
1047 data->error = -EINPROGRESS;
1048
1049 host->sg = data->sg;
Terry Barnabybdbc5d02013-04-08 12:05:47 -04001050 host->sg_len = data->sg_len;
Ludovic Desroches796211b2011-08-11 15:25:44 +00001051 host->data = data;
1052 host->data_chan = NULL;
1053
1054 iflags = ATMCI_DATA_ERROR_FLAGS;
1055
1056 /*
1057 * Errata: MMC data write operation with less than 12
1058 * bytes is impossible.
1059 *
1060 * Errata: MCI Transmit Data Register (TDR) FIFO
1061 * corruption when length is not multiple of 4.
1062 */
1063 if (data->blocks * data->blksz < 12
1064 || (data->blocks * data->blksz) & 3)
1065 host->need_reset = true;
1066
1067 host->pio_offset = 0;
1068 if (data->flags & MMC_DATA_READ)
1069 iflags |= ATMCI_RXRDY;
1070 else
1071 iflags |= ATMCI_TXRDY;
1072
1073 return iflags;
1074}
1075
1076/*
1077 * Set interrupt flags and set block length into the MCI mode register even
1078 * if this value is also accessible in the MCI block register. It seems to be
1079 * necessary before the High Speed MCI version. It also map sg and configure
1080 * PDC registers.
1081 */
1082static u32
1083atmci_prepare_data_pdc(struct atmel_mci *host, struct mmc_data *data)
1084{
1085 u32 iflags, tmp;
Ludovic Desroches24011f32012-05-16 15:26:00 +02001086 int i;
Ludovic Desroches796211b2011-08-11 15:25:44 +00001087
1088 data->error = -EINPROGRESS;
1089
1090 host->data = data;
1091 host->sg = data->sg;
1092 iflags = ATMCI_DATA_ERROR_FLAGS;
1093
1094 /* Enable pdc mode */
1095 atmci_writel(host, ATMCI_MR, host->mode_reg | ATMCI_MR_PDCMODE);
1096
Heiner Kallweitfeeef092017-03-26 20:45:56 +02001097 if (data->flags & MMC_DATA_READ)
Ludovic Desroches796211b2011-08-11 15:25:44 +00001098 iflags |= ATMCI_ENDRX | ATMCI_RXBUFF;
Heiner Kallweitfeeef092017-03-26 20:45:56 +02001099 else
Ludovic Desrochesf5177542012-05-16 15:25:59 +02001100 iflags |= ATMCI_ENDTX | ATMCI_TXBUFE | ATMCI_BLKE;
Ludovic Desroches796211b2011-08-11 15:25:44 +00001101
1102 /* Set BLKLEN */
1103 tmp = atmci_readl(host, ATMCI_MR);
1104 tmp &= 0x0000ffff;
1105 tmp |= ATMCI_BLKLEN(data->blksz);
1106 atmci_writel(host, ATMCI_MR, tmp);
1107
1108 /* Configure PDC */
1109 host->data_size = data->blocks * data->blksz;
Shawn Linf98e0d52017-07-06 16:43:45 +08001110 dma_map_sg(&host->pdev->dev, data->sg, data->sg_len,
1111 mmc_get_dma_dir(data));
Ludovic Desroches7a90dcc2012-05-16 15:25:58 +02001112
1113 if ((!host->caps.has_rwproof)
Ludovic Desroches24011f32012-05-16 15:26:00 +02001114 && (host->data->flags & MMC_DATA_WRITE)) {
Ludovic Desroches7a90dcc2012-05-16 15:25:58 +02001115 sg_copy_to_buffer(host->data->sg, host->data->sg_len,
1116 host->buffer, host->data_size);
Ludovic Desroches24011f32012-05-16 15:26:00 +02001117 if (host->caps.has_bad_data_ordering)
1118 for (i = 0; i < host->data_size; i++)
1119 host->buffer[i] = swab32(host->buffer[i]);
1120 }
Ludovic Desroches7a90dcc2012-05-16 15:25:58 +02001121
Ludovic Desroches796211b2011-08-11 15:25:44 +00001122 if (host->data_size)
Heiner Kallweitfeeef092017-03-26 20:45:56 +02001123 atmci_pdc_set_both_buf(host, data->flags & MMC_DATA_READ ?
1124 XFER_RECEIVE : XFER_TRANSMIT);
Ludovic Desroches796211b2011-08-11 15:25:44 +00001125 return iflags;
1126}
1127
1128static u32
Nicolas Ferre74791a22009-12-14 18:01:31 -08001129atmci_prepare_data_dma(struct atmel_mci *host, struct mmc_data *data)
Haavard Skinnemoen65e8b082008-07-30 20:29:03 +02001130{
1131 struct dma_chan *chan;
1132 struct dma_async_tx_descriptor *desc;
1133 struct scatterlist *sg;
1134 unsigned int i;
Vinod Koule0d23ef2011-11-17 14:54:38 +05301135 enum dma_transfer_direction slave_dirn;
Atsushi Nemoto657a77f2009-09-08 17:53:05 -07001136 unsigned int sglen;
Nicolas Ferre693e5e22012-06-06 12:19:44 +02001137 u32 maxburst;
Ludovic Desroches796211b2011-08-11 15:25:44 +00001138 u32 iflags;
1139
1140 data->error = -EINPROGRESS;
1141
1142 WARN_ON(host->data);
1143 host->sg = NULL;
1144 host->data = data;
1145
1146 iflags = ATMCI_DATA_ERROR_FLAGS;
Haavard Skinnemoen65e8b082008-07-30 20:29:03 +02001147
1148 /*
1149 * We don't do DMA on "complex" transfers, i.e. with
1150 * non-word-aligned buffers or lengths. Also, we don't bother
1151 * with all the DMA setup overhead for short transfers.
1152 */
Ludovic Desroches796211b2011-08-11 15:25:44 +00001153 if (data->blocks * data->blksz < ATMCI_DMA_THRESHOLD)
1154 return atmci_prepare_data(host, data);
Haavard Skinnemoen65e8b082008-07-30 20:29:03 +02001155 if (data->blksz & 3)
Ludovic Desroches796211b2011-08-11 15:25:44 +00001156 return atmci_prepare_data(host, data);
Haavard Skinnemoen65e8b082008-07-30 20:29:03 +02001157
1158 for_each_sg(data->sg, sg, data->sg_len, i) {
1159 if (sg->offset & 3 || sg->length & 3)
Ludovic Desroches796211b2011-08-11 15:25:44 +00001160 return atmci_prepare_data(host, data);
Haavard Skinnemoen65e8b082008-07-30 20:29:03 +02001161 }
1162
1163 /* If we don't have a channel, we can't do DMA */
1164 chan = host->dma.chan;
Dan Williams6f49a572009-01-06 11:38:14 -07001165 if (chan)
Haavard Skinnemoen65e8b082008-07-30 20:29:03 +02001166 host->data_chan = chan;
Haavard Skinnemoen65e8b082008-07-30 20:29:03 +02001167
1168 if (!chan)
1169 return -ENODEV;
1170
Vinod Koule0d23ef2011-11-17 14:54:38 +05301171 if (data->flags & MMC_DATA_READ) {
Viresh Kumare2b35f32012-02-01 16:12:27 +05301172 host->dma_conf.direction = slave_dirn = DMA_DEV_TO_MEM;
ludovic.desroches@atmel.com447dc0d2015-11-23 16:27:32 +01001173 maxburst = atmci_convert_chksize(host,
1174 host->dma_conf.src_maxburst);
Vinod Koule0d23ef2011-11-17 14:54:38 +05301175 } else {
Viresh Kumare2b35f32012-02-01 16:12:27 +05301176 host->dma_conf.direction = slave_dirn = DMA_MEM_TO_DEV;
ludovic.desroches@atmel.com447dc0d2015-11-23 16:27:32 +01001177 maxburst = atmci_convert_chksize(host,
1178 host->dma_conf.dst_maxburst);
Vinod Koule0d23ef2011-11-17 14:54:38 +05301179 }
Haavard Skinnemoen65e8b082008-07-30 20:29:03 +02001180
Hein_Tiboschccdfe612012-08-30 16:34:38 +00001181 if (host->caps.has_dma_conf_reg)
1182 atmci_writel(host, ATMCI_DMA, ATMCI_DMA_CHKSIZE(maxburst) |
1183 ATMCI_DMAEN);
Nicolas Ferre693e5e22012-06-06 12:19:44 +02001184
Linus Walleij266ac3f2011-02-10 16:08:06 +01001185 sglen = dma_map_sg(chan->device->dev, data->sg,
Heiner Kallweitfeeef092017-03-26 20:45:56 +02001186 data->sg_len, mmc_get_dma_dir(data));
Linus Walleij88ce4db32011-02-10 16:08:16 +01001187
Viresh Kumare2b35f32012-02-01 16:12:27 +05301188 dmaengine_slave_config(chan, &host->dma_conf);
Alexandre Bounine16052822012-03-08 16:11:18 -05001189 desc = dmaengine_prep_slave_sg(chan,
Vinod Koule0d23ef2011-11-17 14:54:38 +05301190 data->sg, sglen, slave_dirn,
Haavard Skinnemoen65e8b082008-07-30 20:29:03 +02001191 DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
1192 if (!desc)
Atsushi Nemoto657a77f2009-09-08 17:53:05 -07001193 goto unmap_exit;
Haavard Skinnemoen65e8b082008-07-30 20:29:03 +02001194
1195 host->dma.data_desc = desc;
1196 desc->callback = atmci_dma_complete;
1197 desc->callback_param = host;
Haavard Skinnemoen65e8b082008-07-30 20:29:03 +02001198
Ludovic Desroches796211b2011-08-11 15:25:44 +00001199 return iflags;
Atsushi Nemoto657a77f2009-09-08 17:53:05 -07001200unmap_exit:
Heiner Kallweitfeeef092017-03-26 20:45:56 +02001201 dma_unmap_sg(chan->device->dev, data->sg, data->sg_len,
1202 mmc_get_dma_dir(data));
Atsushi Nemoto657a77f2009-09-08 17:53:05 -07001203 return -ENOMEM;
Haavard Skinnemoen65e8b082008-07-30 20:29:03 +02001204}
1205
Ludovic Desroches796211b2011-08-11 15:25:44 +00001206static void
1207atmci_submit_data(struct atmel_mci *host, struct mmc_data *data)
1208{
1209 return;
1210}
1211
1212/*
1213 * Start PDC according to transfer direction.
1214 */
1215static void
1216atmci_submit_data_pdc(struct atmel_mci *host, struct mmc_data *data)
1217{
1218 if (data->flags & MMC_DATA_READ)
1219 atmci_writel(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTEN);
1220 else
1221 atmci_writel(host, ATMEL_PDC_PTCR, ATMEL_PDC_TXTEN);
1222}
1223
1224static void
1225atmci_submit_data_dma(struct atmel_mci *host, struct mmc_data *data)
Nicolas Ferre74791a22009-12-14 18:01:31 -08001226{
1227 struct dma_chan *chan = host->data_chan;
1228 struct dma_async_tx_descriptor *desc = host->dma.data_desc;
1229
1230 if (chan) {
Linus Walleij53289062011-02-10 16:08:26 +01001231 dmaengine_submit(desc);
1232 dma_async_issue_pending(chan);
Nicolas Ferre74791a22009-12-14 18:01:31 -08001233 }
1234}
1235
Ludovic Desroches796211b2011-08-11 15:25:44 +00001236static void atmci_stop_transfer(struct atmel_mci *host)
Haavard Skinnemoen65e8b082008-07-30 20:29:03 +02001237{
Ludovic Desroches6801c412012-05-16 15:26:01 +02001238 dev_dbg(&host->pdev->dev,
1239 "(%s) set pending xfer complete\n", __func__);
Haavard Skinnemoen65e8b082008-07-30 20:29:03 +02001240 atmci_set_pending(host, EVENT_XFER_COMPLETE);
Ludovic Desroches03fc9a72011-08-11 15:25:42 +00001241 atmci_writel(host, ATMCI_IER, ATMCI_NOTBUSY);
Haavard Skinnemoen65e8b082008-07-30 20:29:03 +02001242}
1243
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001244/*
Masanari Iida7122bbb2012-08-05 23:25:40 +09001245 * Stop data transfer because error(s) occurred.
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001246 */
Ludovic Desroches796211b2011-08-11 15:25:44 +00001247static void atmci_stop_transfer_pdc(struct atmel_mci *host)
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001248{
Ludovic Desrochesf5177542012-05-16 15:25:59 +02001249 atmci_writel(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS | ATMEL_PDC_TXTDIS);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001250}
1251
Ludovic Desroches796211b2011-08-11 15:25:44 +00001252static void atmci_stop_transfer_dma(struct atmel_mci *host)
1253{
1254 struct dma_chan *chan = host->data_chan;
1255
1256 if (chan) {
1257 dmaengine_terminate_all(chan);
1258 atmci_dma_cleanup(host);
1259 } else {
1260 /* Data transfer was stopped by the interrupt handler */
Ludovic Desroches6801c412012-05-16 15:26:01 +02001261 dev_dbg(&host->pdev->dev,
1262 "(%s) set pending xfer complete\n", __func__);
Ludovic Desroches796211b2011-08-11 15:25:44 +00001263 atmci_set_pending(host, EVENT_XFER_COMPLETE);
1264 atmci_writel(host, ATMCI_IER, ATMCI_NOTBUSY);
1265 }
1266}
1267
1268/*
1269 * Start a request: prepare data if needed, prepare the command and activate
1270 * interrupts.
1271 */
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001272static void atmci_start_request(struct atmel_mci *host,
1273 struct atmel_mci_slot *slot)
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001274{
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001275 struct mmc_request *mrq;
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001276 struct mmc_command *cmd;
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001277 struct mmc_data *data;
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001278 u32 iflags;
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001279 u32 cmdflags;
1280
1281 mrq = slot->mrq;
1282 host->cur_slot = slot;
1283 host->mrq = mrq;
1284
1285 host->pending_events = 0;
1286 host->completed_events = 0;
Ludovic Desrochesf5177542012-05-16 15:25:59 +02001287 host->cmd_status = 0;
Haavard Skinnemoenca55f462008-10-05 15:16:59 +02001288 host->data_status = 0;
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001289
Ludovic Desroches6801c412012-05-16 15:26:01 +02001290 dev_dbg(&host->pdev->dev, "start request: cmd %u\n", mrq->cmd->opcode);
1291
Ludovic Desroches24011f32012-05-16 15:26:00 +02001292 if (host->need_reset || host->caps.need_reset_after_xfer) {
Ludovic Desroches18ee6842012-02-09 11:55:29 +01001293 iflags = atmci_readl(host, ATMCI_IMR);
1294 iflags &= (ATMCI_SDIOIRQA | ATMCI_SDIOIRQB);
Ludovic Desroches03fc9a72011-08-11 15:25:42 +00001295 atmci_writel(host, ATMCI_CR, ATMCI_CR_SWRST);
1296 atmci_writel(host, ATMCI_CR, ATMCI_CR_MCIEN);
1297 atmci_writel(host, ATMCI_MR, host->mode_reg);
Ludovic Desroches796211b2011-08-11 15:25:44 +00001298 if (host->caps.has_cfg_reg)
Ludovic Desroches03fc9a72011-08-11 15:25:42 +00001299 atmci_writel(host, ATMCI_CFG, host->cfg_reg);
Ludovic Desroches18ee6842012-02-09 11:55:29 +01001300 atmci_writel(host, ATMCI_IER, iflags);
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001301 host->need_reset = false;
1302 }
Ludovic Desroches03fc9a72011-08-11 15:25:42 +00001303 atmci_writel(host, ATMCI_SDCR, slot->sdc_reg);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001304
Ludovic Desroches03fc9a72011-08-11 15:25:42 +00001305 iflags = atmci_readl(host, ATMCI_IMR);
Ludovic Desroches2c96a292011-08-11 15:25:41 +00001306 if (iflags & ~(ATMCI_SDIOIRQA | ATMCI_SDIOIRQB))
Ludovic Desrochesf5177542012-05-16 15:25:59 +02001307 dev_dbg(&slot->mmc->class_dev, "WARNING: IMR=0x%08x\n",
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001308 iflags);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001309
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001310 if (unlikely(test_and_clear_bit(ATMCI_CARD_NEED_INIT, &slot->flags))) {
1311 /* Send init sequence (74 clock cycles) */
Ludovic Desroches03fc9a72011-08-11 15:25:42 +00001312 atmci_writel(host, ATMCI_CMDR, ATMCI_CMDR_SPCMD_INIT);
1313 while (!(atmci_readl(host, ATMCI_SR) & ATMCI_CMDRDY))
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001314 cpu_relax();
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001315 }
Nicolas Ferre74791a22009-12-14 18:01:31 -08001316 iflags = 0;
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001317 data = mrq->data;
1318 if (data) {
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001319 atmci_set_timeout(host, slot, data);
Haavard Skinnemoena252e3e2008-10-03 14:46:17 +02001320
1321 /* Must set block count/size before sending command */
Ludovic Desroches03fc9a72011-08-11 15:25:42 +00001322 atmci_writel(host, ATMCI_BLKR, ATMCI_BCNT(data->blocks)
Ludovic Desroches2c96a292011-08-11 15:25:41 +00001323 | ATMCI_BLKLEN(data->blksz));
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001324 dev_vdbg(&slot->mmc->class_dev, "BLKR=0x%08x\n",
Ludovic Desroches2c96a292011-08-11 15:25:41 +00001325 ATMCI_BCNT(data->blocks) | ATMCI_BLKLEN(data->blksz));
Nicolas Ferre74791a22009-12-14 18:01:31 -08001326
Ludovic Desroches796211b2011-08-11 15:25:44 +00001327 iflags |= host->prepare_data(host, data);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001328 }
1329
Ludovic Desroches2c96a292011-08-11 15:25:41 +00001330 iflags |= ATMCI_CMDRDY;
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001331 cmd = mrq->cmd;
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001332 cmdflags = atmci_prepare_command(slot->mmc, cmd);
Ludovic Desroches66b512e2013-11-20 16:01:11 +01001333
1334 /*
1335 * DMA transfer should be started before sending the command to avoid
1336 * unexpected errors especially for read operations in SDIO mode.
1337 * Unfortunately, in PDC mode, command has to be sent before starting
1338 * the transfer.
1339 */
1340 if (host->submit_data != &atmci_submit_data_dma)
1341 atmci_send_command(host, cmd, cmdflags);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001342
1343 if (data)
Ludovic Desroches796211b2011-08-11 15:25:44 +00001344 host->submit_data(host, data);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001345
Ludovic Desroches66b512e2013-11-20 16:01:11 +01001346 if (host->submit_data == &atmci_submit_data_dma)
1347 atmci_send_command(host, cmd, cmdflags);
1348
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001349 if (mrq->stop) {
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001350 host->stop_cmdr = atmci_prepare_command(slot->mmc, mrq->stop);
Ludovic Desroches2c96a292011-08-11 15:25:41 +00001351 host->stop_cmdr |= ATMCI_CMDR_STOP_XFER;
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001352 if (!(data->flags & MMC_DATA_WRITE))
Ludovic Desroches2c96a292011-08-11 15:25:41 +00001353 host->stop_cmdr |= ATMCI_CMDR_TRDIR_READ;
Jaehoon Chungfd551d92016-02-01 21:07:26 +09001354 host->stop_cmdr |= ATMCI_CMDR_MULTI_BLOCK;
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001355 }
1356
1357 /*
1358 * We could have enabled interrupts earlier, but I suspect
1359 * that would open up a nice can of interesting race
1360 * conditions (e.g. command and data complete, but stop not
1361 * prepared yet.)
1362 */
Ludovic Desroches03fc9a72011-08-11 15:25:42 +00001363 atmci_writel(host, ATMCI_IER, iflags);
Ludovic Desroches24011f32012-05-16 15:26:00 +02001364
1365 mod_timer(&host->timer, jiffies + msecs_to_jiffies(2000));
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001366}
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001367
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001368static void atmci_queue_request(struct atmel_mci *host,
1369 struct atmel_mci_slot *slot, struct mmc_request *mrq)
1370{
1371 dev_vdbg(&slot->mmc->class_dev, "queue request: state=%d\n",
1372 host->state);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001373
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001374 spin_lock_bh(&host->lock);
1375 slot->mrq = mrq;
1376 if (host->state == STATE_IDLE) {
1377 host->state = STATE_SENDING_CMD;
1378 atmci_start_request(host, slot);
1379 } else {
Ludovic Desroches6801c412012-05-16 15:26:01 +02001380 dev_dbg(&host->pdev->dev, "queue request\n");
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001381 list_add_tail(&slot->queue_node, &host->queue);
1382 }
1383 spin_unlock_bh(&host->lock);
1384}
1385
1386static void atmci_request(struct mmc_host *mmc, struct mmc_request *mrq)
1387{
1388 struct atmel_mci_slot *slot = mmc_priv(mmc);
1389 struct atmel_mci *host = slot->host;
1390 struct mmc_data *data;
1391
1392 WARN_ON(slot->mrq);
Ludovic Desroches6801c412012-05-16 15:26:01 +02001393 dev_dbg(&host->pdev->dev, "MRQ: cmd %u\n", mrq->cmd->opcode);
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001394
1395 /*
1396 * We may "know" the card is gone even though there's still an
1397 * electrical connection. If so, we really need to communicate
1398 * this to the MMC core since there won't be any more
1399 * interrupts as the card is completely removed. Otherwise,
1400 * the MMC core might believe the card is still there even
1401 * though the card was just removed very slowly.
1402 */
1403 if (!test_bit(ATMCI_CARD_PRESENT, &slot->flags)) {
1404 mrq->cmd->error = -ENOMEDIUM;
1405 mmc_request_done(mmc, mrq);
1406 return;
1407 }
1408
1409 /* We don't support multiple blocks of weird lengths. */
1410 data = mrq->data;
1411 if (data && data->blocks > 1 && data->blksz & 3) {
1412 mrq->cmd->error = -EINVAL;
1413 mmc_request_done(mmc, mrq);
1414 }
1415
1416 atmci_queue_request(host, slot, mrq);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001417}
1418
1419static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
1420{
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001421 struct atmel_mci_slot *slot = mmc_priv(mmc);
1422 struct atmel_mci *host = slot->host;
1423 unsigned int i;
Wenyou Yangae552ab2014-10-30 12:00:41 +08001424
Ludovic Desroches2c96a292011-08-11 15:25:41 +00001425 slot->sdc_reg &= ~ATMCI_SDCBUS_MASK;
Haavard Skinnemoen945533b52008-10-03 17:48:16 +02001426 switch (ios->bus_width) {
1427 case MMC_BUS_WIDTH_1:
Ludovic Desroches2c96a292011-08-11 15:25:41 +00001428 slot->sdc_reg |= ATMCI_SDCBUS_1BIT;
Haavard Skinnemoen945533b52008-10-03 17:48:16 +02001429 break;
1430 case MMC_BUS_WIDTH_4:
Ludovic Desroches2c96a292011-08-11 15:25:41 +00001431 slot->sdc_reg |= ATMCI_SDCBUS_4BIT;
Haavard Skinnemoen945533b52008-10-03 17:48:16 +02001432 break;
1433 }
1434
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001435 if (ios->clock) {
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001436 unsigned int clock_min = ~0U;
Ludovic Desroches60c8f782015-05-06 15:16:46 +02001437 int clkdiv;
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001438
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001439 spin_lock_bh(&host->lock);
1440 if (!host->mode_reg) {
Ludovic Desroches03fc9a72011-08-11 15:25:42 +00001441 atmci_writel(host, ATMCI_CR, ATMCI_CR_SWRST);
1442 atmci_writel(host, ATMCI_CR, ATMCI_CR_MCIEN);
Ludovic Desroches796211b2011-08-11 15:25:44 +00001443 if (host->caps.has_cfg_reg)
Ludovic Desroches03fc9a72011-08-11 15:25:42 +00001444 atmci_writel(host, ATMCI_CFG, host->cfg_reg);
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001445 }
Haavard Skinnemoen945533b52008-10-03 17:48:16 +02001446
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001447 /*
1448 * Use mirror of ios->clock to prevent race with mmc
1449 * core ios update when finding the minimum.
1450 */
1451 slot->clock = ios->clock;
Ludovic Desroches2c96a292011-08-11 15:25:41 +00001452 for (i = 0; i < ATMCI_MAX_NR_SLOTS; i++) {
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001453 if (host->slot[i] && host->slot[i]->clock
1454 && host->slot[i]->clock < clock_min)
1455 clock_min = host->slot[i]->clock;
1456 }
1457
1458 /* Calculate clock divider */
Ludovic Desrochesfaf81802012-03-21 16:41:23 +01001459 if (host->caps.has_odd_clk_div) {
1460 clkdiv = DIV_ROUND_UP(host->bus_hz, clock_min) - 2;
Ludovic Desroches60c8f782015-05-06 15:16:46 +02001461 if (clkdiv < 0) {
1462 dev_warn(&mmc->class_dev,
1463 "clock %u too fast; using %lu\n",
1464 clock_min, host->bus_hz / 2);
1465 clkdiv = 0;
1466 } else if (clkdiv > 511) {
Ludovic Desrochesfaf81802012-03-21 16:41:23 +01001467 dev_warn(&mmc->class_dev,
1468 "clock %u too slow; using %lu\n",
1469 clock_min, host->bus_hz / (511 + 2));
1470 clkdiv = 511;
1471 }
1472 host->mode_reg = ATMCI_MR_CLKDIV(clkdiv >> 1)
1473 | ATMCI_MR_CLKODD(clkdiv & 1);
1474 } else {
1475 clkdiv = DIV_ROUND_UP(host->bus_hz, 2 * clock_min) - 1;
1476 if (clkdiv > 255) {
1477 dev_warn(&mmc->class_dev,
1478 "clock %u too slow; using %lu\n",
1479 clock_min, host->bus_hz / (2 * 256));
1480 clkdiv = 255;
1481 }
1482 host->mode_reg = ATMCI_MR_CLKDIV(clkdiv);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001483 }
1484
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001485 /*
1486 * WRPROOF and RDPROOF prevent overruns/underruns by
1487 * stopping the clock when the FIFO is full/empty.
1488 * This state is not expected to last for long.
1489 */
Ludovic Desroches796211b2011-08-11 15:25:44 +00001490 if (host->caps.has_rwproof)
Ludovic Desroches2c96a292011-08-11 15:25:41 +00001491 host->mode_reg |= (ATMCI_MR_WRPROOF | ATMCI_MR_RDPROOF);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001492
Ludovic Desroches796211b2011-08-11 15:25:44 +00001493 if (host->caps.has_cfg_reg) {
Nicolas Ferre99ddffd2010-05-26 14:41:59 -07001494 /* setup High Speed mode in relation with card capacity */
1495 if (ios->timing == MMC_TIMING_SD_HS)
Ludovic Desroches2c96a292011-08-11 15:25:41 +00001496 host->cfg_reg |= ATMCI_CFG_HSMODE;
Nicolas Ferre99ddffd2010-05-26 14:41:59 -07001497 else
Ludovic Desroches2c96a292011-08-11 15:25:41 +00001498 host->cfg_reg &= ~ATMCI_CFG_HSMODE;
Nicolas Ferre99ddffd2010-05-26 14:41:59 -07001499 }
1500
1501 if (list_empty(&host->queue)) {
Ludovic Desroches03fc9a72011-08-11 15:25:42 +00001502 atmci_writel(host, ATMCI_MR, host->mode_reg);
Ludovic Desroches796211b2011-08-11 15:25:44 +00001503 if (host->caps.has_cfg_reg)
Ludovic Desroches03fc9a72011-08-11 15:25:42 +00001504 atmci_writel(host, ATMCI_CFG, host->cfg_reg);
Nicolas Ferre99ddffd2010-05-26 14:41:59 -07001505 } else {
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001506 host->need_clock_update = true;
Nicolas Ferre99ddffd2010-05-26 14:41:59 -07001507 }
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001508
1509 spin_unlock_bh(&host->lock);
Haavard Skinnemoen945533b52008-10-03 17:48:16 +02001510 } else {
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001511 bool any_slot_active = false;
1512
1513 spin_lock_bh(&host->lock);
1514 slot->clock = 0;
Ludovic Desroches2c96a292011-08-11 15:25:41 +00001515 for (i = 0; i < ATMCI_MAX_NR_SLOTS; i++) {
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001516 if (host->slot[i] && host->slot[i]->clock) {
1517 any_slot_active = true;
1518 break;
1519 }
Haavard Skinnemoen945533b52008-10-03 17:48:16 +02001520 }
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001521 if (!any_slot_active) {
Ludovic Desroches03fc9a72011-08-11 15:25:42 +00001522 atmci_writel(host, ATMCI_CR, ATMCI_CR_MCIDIS);
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001523 if (host->mode_reg) {
Ludovic Desroches03fc9a72011-08-11 15:25:42 +00001524 atmci_readl(host, ATMCI_MR);
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001525 }
1526 host->mode_reg = 0;
1527 }
1528 spin_unlock_bh(&host->lock);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001529 }
1530
1531 switch (ios->power_mode) {
Alexandre Belloni9e7861f2013-10-17 12:46:48 +02001532 case MMC_POWER_OFF:
1533 if (!IS_ERR(mmc->supply.vmmc))
1534 mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0);
1535 break;
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001536 case MMC_POWER_UP:
1537 set_bit(ATMCI_CARD_NEED_INIT, &slot->flags);
Alexandre Belloni9e7861f2013-10-17 12:46:48 +02001538 if (!IS_ERR(mmc->supply.vmmc))
1539 mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, ios->vdd);
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001540 break;
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001541 default:
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001542 break;
1543 }
1544}
1545
1546static int atmci_get_ro(struct mmc_host *mmc)
1547{
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001548 int read_only = -ENOSYS;
1549 struct atmel_mci_slot *slot = mmc_priv(mmc);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001550
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001551 if (gpio_is_valid(slot->wp_pin)) {
1552 read_only = gpio_get_value(slot->wp_pin);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001553 dev_dbg(&mmc->class_dev, "card is %s\n",
1554 read_only ? "read-only" : "read-write");
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001555 }
1556
1557 return read_only;
1558}
1559
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001560static int atmci_get_cd(struct mmc_host *mmc)
1561{
1562 int present = -ENOSYS;
1563 struct atmel_mci_slot *slot = mmc_priv(mmc);
1564
1565 if (gpio_is_valid(slot->detect_pin)) {
Jonas Larsson1c1452b2009-03-31 11:16:48 +02001566 present = !(gpio_get_value(slot->detect_pin) ^
1567 slot->detect_is_active_high);
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001568 dev_dbg(&mmc->class_dev, "card is %spresent\n",
1569 present ? "" : "not ");
1570 }
1571
1572 return present;
1573}
1574
Anders Grahn88ff82e2010-05-26 14:42:01 -07001575static void atmci_enable_sdio_irq(struct mmc_host *mmc, int enable)
1576{
1577 struct atmel_mci_slot *slot = mmc_priv(mmc);
1578 struct atmel_mci *host = slot->host;
1579
1580 if (enable)
Ludovic Desroches03fc9a72011-08-11 15:25:42 +00001581 atmci_writel(host, ATMCI_IER, slot->sdio_irq);
Anders Grahn88ff82e2010-05-26 14:42:01 -07001582 else
Ludovic Desroches03fc9a72011-08-11 15:25:42 +00001583 atmci_writel(host, ATMCI_IDR, slot->sdio_irq);
Anders Grahn88ff82e2010-05-26 14:42:01 -07001584}
1585
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001586static const struct mmc_host_ops atmci_ops = {
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001587 .request = atmci_request,
1588 .set_ios = atmci_set_ios,
1589 .get_ro = atmci_get_ro,
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001590 .get_cd = atmci_get_cd,
Anders Grahn88ff82e2010-05-26 14:42:01 -07001591 .enable_sdio_irq = atmci_enable_sdio_irq,
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001592};
1593
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001594/* Called with host->lock held */
1595static void atmci_request_end(struct atmel_mci *host, struct mmc_request *mrq)
1596 __releases(&host->lock)
1597 __acquires(&host->lock)
1598{
1599 struct atmel_mci_slot *slot = NULL;
1600 struct mmc_host *prev_mmc = host->cur_slot->mmc;
1601
1602 WARN_ON(host->cmd || host->data);
1603
1604 /*
1605 * Update the MMC clock rate if necessary. This may be
1606 * necessary if set_ios() is called when a different slot is
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001607 * busy transferring data.
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001608 */
Nicolas Ferre99ddffd2010-05-26 14:41:59 -07001609 if (host->need_clock_update) {
Ludovic Desroches03fc9a72011-08-11 15:25:42 +00001610 atmci_writel(host, ATMCI_MR, host->mode_reg);
Ludovic Desroches796211b2011-08-11 15:25:44 +00001611 if (host->caps.has_cfg_reg)
Ludovic Desroches03fc9a72011-08-11 15:25:42 +00001612 atmci_writel(host, ATMCI_CFG, host->cfg_reg);
Nicolas Ferre99ddffd2010-05-26 14:41:59 -07001613 }
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001614
1615 host->cur_slot->mrq = NULL;
1616 host->mrq = NULL;
1617 if (!list_empty(&host->queue)) {
1618 slot = list_entry(host->queue.next,
1619 struct atmel_mci_slot, queue_node);
1620 list_del(&slot->queue_node);
1621 dev_vdbg(&host->pdev->dev, "list not empty: %s is next\n",
1622 mmc_hostname(slot->mmc));
1623 host->state = STATE_SENDING_CMD;
1624 atmci_start_request(host, slot);
1625 } else {
1626 dev_vdbg(&host->pdev->dev, "list empty\n");
1627 host->state = STATE_IDLE;
1628 }
1629
Ludovic Desroches24011f32012-05-16 15:26:00 +02001630 del_timer(&host->timer);
1631
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001632 spin_unlock(&host->lock);
1633 mmc_request_done(prev_mmc, mrq);
1634 spin_lock(&host->lock);
1635}
1636
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001637static void atmci_command_complete(struct atmel_mci *host,
Haavard Skinnemoenc06ad252008-07-31 14:49:16 +02001638 struct mmc_command *cmd)
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001639{
Haavard Skinnemoenc06ad252008-07-31 14:49:16 +02001640 u32 status = host->cmd_status;
1641
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001642 /* Read the response from the card (up to 16 bytes) */
Ludovic Desroches03fc9a72011-08-11 15:25:42 +00001643 cmd->resp[0] = atmci_readl(host, ATMCI_RSPR);
1644 cmd->resp[1] = atmci_readl(host, ATMCI_RSPR);
1645 cmd->resp[2] = atmci_readl(host, ATMCI_RSPR);
1646 cmd->resp[3] = atmci_readl(host, ATMCI_RSPR);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001647
Ludovic Desroches2c96a292011-08-11 15:25:41 +00001648 if (status & ATMCI_RTOE)
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001649 cmd->error = -ETIMEDOUT;
Ludovic Desroches2c96a292011-08-11 15:25:41 +00001650 else if ((cmd->flags & MMC_RSP_CRC) && (status & ATMCI_RCRCE))
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001651 cmd->error = -EILSEQ;
Ludovic Desroches2c96a292011-08-11 15:25:41 +00001652 else if (status & (ATMCI_RINDE | ATMCI_RDIRE | ATMCI_RENDE))
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001653 cmd->error = -EIO;
Ludovic Desroches24011f32012-05-16 15:26:00 +02001654 else if (host->mrq->data && (host->mrq->data->blksz & 3)) {
1655 if (host->caps.need_blksz_mul_4) {
1656 cmd->error = -EINVAL;
1657 host->need_reset = 1;
1658 }
1659 } else
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001660 cmd->error = 0;
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001661}
1662
1663static void atmci_detect_change(unsigned long data)
1664{
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001665 struct atmel_mci_slot *slot = (struct atmel_mci_slot *)data;
1666 bool present;
1667 bool present_old;
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001668
1669 /*
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001670 * atmci_cleanup_slot() sets the ATMCI_SHUTDOWN flag before
1671 * freeing the interrupt. We must not re-enable the interrupt
1672 * if it has been freed, and if we're shutting down, it
1673 * doesn't really matter whether the card is present or not.
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001674 */
1675 smp_rmb();
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001676 if (test_bit(ATMCI_SHUTDOWN, &slot->flags))
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001677 return;
1678
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001679 enable_irq(gpio_to_irq(slot->detect_pin));
Jonas Larsson1c1452b2009-03-31 11:16:48 +02001680 present = !(gpio_get_value(slot->detect_pin) ^
1681 slot->detect_is_active_high);
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001682 present_old = test_bit(ATMCI_CARD_PRESENT, &slot->flags);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001683
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001684 dev_vdbg(&slot->mmc->class_dev, "detect change: %d (was %d)\n",
1685 present, present_old);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001686
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001687 if (present != present_old) {
1688 struct atmel_mci *host = slot->host;
1689 struct mmc_request *mrq;
1690
1691 dev_dbg(&slot->mmc->class_dev, "card %s\n",
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001692 present ? "inserted" : "removed");
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001693
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001694 spin_lock(&host->lock);
1695
1696 if (!present)
1697 clear_bit(ATMCI_CARD_PRESENT, &slot->flags);
1698 else
1699 set_bit(ATMCI_CARD_PRESENT, &slot->flags);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001700
1701 /* Clean up queue if present */
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001702 mrq = slot->mrq;
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001703 if (mrq) {
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001704 if (mrq == host->mrq) {
1705 /*
1706 * Reset controller to terminate any ongoing
1707 * commands or data transfers.
1708 */
Ludovic Desroches03fc9a72011-08-11 15:25:42 +00001709 atmci_writel(host, ATMCI_CR, ATMCI_CR_SWRST);
1710 atmci_writel(host, ATMCI_CR, ATMCI_CR_MCIEN);
1711 atmci_writel(host, ATMCI_MR, host->mode_reg);
Ludovic Desroches796211b2011-08-11 15:25:44 +00001712 if (host->caps.has_cfg_reg)
Ludovic Desroches03fc9a72011-08-11 15:25:42 +00001713 atmci_writel(host, ATMCI_CFG, host->cfg_reg);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001714
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001715 host->data = NULL;
1716 host->cmd = NULL;
Haavard Skinnemoenc06ad252008-07-31 14:49:16 +02001717
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001718 switch (host->state) {
1719 case STATE_IDLE:
Haavard Skinnemoenc06ad252008-07-31 14:49:16 +02001720 break;
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001721 case STATE_SENDING_CMD:
1722 mrq->cmd->error = -ENOMEDIUM;
Ludovic Desrochesf5177542012-05-16 15:25:59 +02001723 if (mrq->data)
1724 host->stop_transfer(host);
1725 break;
1726 case STATE_DATA_XFER:
Haavard Skinnemoenc06ad252008-07-31 14:49:16 +02001727 mrq->data->error = -ENOMEDIUM;
Ludovic Desroches796211b2011-08-11 15:25:44 +00001728 host->stop_transfer(host);
Haavard Skinnemoenc06ad252008-07-31 14:49:16 +02001729 break;
Ludovic Desrochesf5177542012-05-16 15:25:59 +02001730 case STATE_WAITING_NOTBUSY:
1731 mrq->data->error = -ENOMEDIUM;
1732 break;
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001733 case STATE_SENDING_STOP:
1734 mrq->stop->error = -ENOMEDIUM;
1735 break;
Ludovic Desrochesf5177542012-05-16 15:25:59 +02001736 case STATE_END_REQUEST:
1737 break;
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001738 }
1739
1740 atmci_request_end(host, mrq);
1741 } else {
1742 list_del(&slot->queue_node);
1743 mrq->cmd->error = -ENOMEDIUM;
1744 if (mrq->data)
1745 mrq->data->error = -ENOMEDIUM;
1746 if (mrq->stop)
1747 mrq->stop->error = -ENOMEDIUM;
1748
1749 spin_unlock(&host->lock);
1750 mmc_request_done(slot->mmc, mrq);
1751 spin_lock(&host->lock);
Haavard Skinnemoenc06ad252008-07-31 14:49:16 +02001752 }
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001753 }
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001754 spin_unlock(&host->lock);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001755
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001756 mmc_detect_change(slot->mmc, 0);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001757 }
1758}
1759
1760static void atmci_tasklet_func(unsigned long priv)
1761{
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001762 struct atmel_mci *host = (struct atmel_mci *)priv;
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001763 struct mmc_request *mrq = host->mrq;
1764 struct mmc_data *data = host->data;
Haavard Skinnemoenc06ad252008-07-31 14:49:16 +02001765 enum atmel_mci_state state = host->state;
1766 enum atmel_mci_state prev_state;
1767 u32 status;
1768
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001769 spin_lock(&host->lock);
1770
Haavard Skinnemoenc06ad252008-07-31 14:49:16 +02001771 state = host->state;
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001772
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001773 dev_vdbg(&host->pdev->dev,
Haavard Skinnemoenc06ad252008-07-31 14:49:16 +02001774 "tasklet: state %u pending/completed/mask %lx/%lx/%x\n",
1775 state, host->pending_events, host->completed_events,
Ludovic Desroches03fc9a72011-08-11 15:25:42 +00001776 atmci_readl(host, ATMCI_IMR));
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001777
Haavard Skinnemoenc06ad252008-07-31 14:49:16 +02001778 do {
1779 prev_state = state;
Ludovic Desroches6801c412012-05-16 15:26:01 +02001780 dev_dbg(&host->pdev->dev, "FSM: state=%d\n", state);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001781
Haavard Skinnemoenc06ad252008-07-31 14:49:16 +02001782 switch (state) {
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001783 case STATE_IDLE:
1784 break;
1785
Haavard Skinnemoenc06ad252008-07-31 14:49:16 +02001786 case STATE_SENDING_CMD:
Ludovic Desrochesf5177542012-05-16 15:25:59 +02001787 /*
1788 * Command has been sent, we are waiting for command
1789 * ready. Then we have three next states possible:
1790 * END_REQUEST by default, WAITING_NOTBUSY if it's a
1791 * command needing it or DATA_XFER if there is data.
1792 */
Ludovic Desroches6801c412012-05-16 15:26:01 +02001793 dev_dbg(&host->pdev->dev, "FSM: cmd ready?\n");
Haavard Skinnemoenc06ad252008-07-31 14:49:16 +02001794 if (!atmci_test_and_clear_pending(host,
Ludovic Desrochesf5177542012-05-16 15:25:59 +02001795 EVENT_CMD_RDY))
Haavard Skinnemoenc06ad252008-07-31 14:49:16 +02001796 break;
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001797
Ludovic Desroches6801c412012-05-16 15:26:01 +02001798 dev_dbg(&host->pdev->dev, "set completed cmd ready\n");
Haavard Skinnemoenc06ad252008-07-31 14:49:16 +02001799 host->cmd = NULL;
Ludovic Desrochesf5177542012-05-16 15:25:59 +02001800 atmci_set_completed(host, EVENT_CMD_RDY);
Haavard Skinnemoenc06ad252008-07-31 14:49:16 +02001801 atmci_command_complete(host, mrq->cmd);
Ludovic Desrochesf5177542012-05-16 15:25:59 +02001802 if (mrq->data) {
Ludovic Desroches6801c412012-05-16 15:26:01 +02001803 dev_dbg(&host->pdev->dev,
1804 "command with data transfer");
Ludovic Desrochesf5177542012-05-16 15:25:59 +02001805 /*
1806 * If there is a command error don't start
1807 * data transfer.
1808 */
1809 if (mrq->cmd->error) {
1810 host->stop_transfer(host);
1811 host->data = NULL;
1812 atmci_writel(host, ATMCI_IDR,
1813 ATMCI_TXRDY | ATMCI_RXRDY
1814 | ATMCI_DATA_ERROR_FLAGS);
1815 state = STATE_END_REQUEST;
1816 } else
1817 state = STATE_DATA_XFER;
1818 } else if ((!mrq->data) && (mrq->cmd->flags & MMC_RSP_BUSY)) {
Ludovic Desroches6801c412012-05-16 15:26:01 +02001819 dev_dbg(&host->pdev->dev,
1820 "command response need waiting notbusy");
Ludovic Desrochesf5177542012-05-16 15:25:59 +02001821 atmci_writel(host, ATMCI_IER, ATMCI_NOTBUSY);
1822 state = STATE_WAITING_NOTBUSY;
1823 } else
1824 state = STATE_END_REQUEST;
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001825
Ludovic Desrochesf5177542012-05-16 15:25:59 +02001826 break;
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001827
Ludovic Desrochesf5177542012-05-16 15:25:59 +02001828 case STATE_DATA_XFER:
Haavard Skinnemoenc06ad252008-07-31 14:49:16 +02001829 if (atmci_test_and_clear_pending(host,
1830 EVENT_DATA_ERROR)) {
Ludovic Desroches6801c412012-05-16 15:26:01 +02001831 dev_dbg(&host->pdev->dev, "set completed data error\n");
Ludovic Desrochesf5177542012-05-16 15:25:59 +02001832 atmci_set_completed(host, EVENT_DATA_ERROR);
1833 state = STATE_END_REQUEST;
Haavard Skinnemoenc06ad252008-07-31 14:49:16 +02001834 break;
1835 }
1836
Ludovic Desrochesf5177542012-05-16 15:25:59 +02001837 /*
1838 * A data transfer is in progress. The event expected
1839 * to move to the next state depends of data transfer
1840 * type (PDC or DMA). Once transfer done we can move
1841 * to the next step which is WAITING_NOTBUSY in write
1842 * case and directly SENDING_STOP in read case.
1843 */
Ludovic Desroches6801c412012-05-16 15:26:01 +02001844 dev_dbg(&host->pdev->dev, "FSM: xfer complete?\n");
Haavard Skinnemoenc06ad252008-07-31 14:49:16 +02001845 if (!atmci_test_and_clear_pending(host,
1846 EVENT_XFER_COMPLETE))
1847 break;
1848
Ludovic Desroches6801c412012-05-16 15:26:01 +02001849 dev_dbg(&host->pdev->dev,
1850 "(%s) set completed xfer complete\n",
1851 __func__);
Haavard Skinnemoenc06ad252008-07-31 14:49:16 +02001852 atmci_set_completed(host, EVENT_XFER_COMPLETE);
Haavard Skinnemoenc06ad252008-07-31 14:49:16 +02001853
Ludovic Desroches077d4072012-07-24 11:42:04 +02001854 if (host->caps.need_notbusy_for_read_ops ||
1855 (host->data->flags & MMC_DATA_WRITE)) {
Ludovic Desrochesf5177542012-05-16 15:25:59 +02001856 atmci_writel(host, ATMCI_IER, ATMCI_NOTBUSY);
1857 state = STATE_WAITING_NOTBUSY;
1858 } else if (host->mrq->stop) {
1859 atmci_writel(host, ATMCI_IER, ATMCI_CMDRDY);
1860 atmci_send_stop_cmd(host, data);
1861 state = STATE_SENDING_STOP;
Haavard Skinnemoenc06ad252008-07-31 14:49:16 +02001862 } else {
Ludovic Desrochesf5177542012-05-16 15:25:59 +02001863 host->data = NULL;
Haavard Skinnemoenc06ad252008-07-31 14:49:16 +02001864 data->bytes_xfered = data->blocks * data->blksz;
1865 data->error = 0;
Ludovic Desrochesf5177542012-05-16 15:25:59 +02001866 state = STATE_END_REQUEST;
Haavard Skinnemoenc06ad252008-07-31 14:49:16 +02001867 }
Ludovic Desrochesf5177542012-05-16 15:25:59 +02001868 break;
Haavard Skinnemoenc06ad252008-07-31 14:49:16 +02001869
Ludovic Desrochesf5177542012-05-16 15:25:59 +02001870 case STATE_WAITING_NOTBUSY:
1871 /*
1872 * We can be in the state for two reasons: a command
1873 * requiring waiting not busy signal (stop command
1874 * included) or a write operation. In the latest case,
1875 * we need to send a stop command.
1876 */
Ludovic Desroches6801c412012-05-16 15:26:01 +02001877 dev_dbg(&host->pdev->dev, "FSM: not busy?\n");
Ludovic Desrochesf5177542012-05-16 15:25:59 +02001878 if (!atmci_test_and_clear_pending(host,
1879 EVENT_NOTBUSY))
1880 break;
Haavard Skinnemoenc06ad252008-07-31 14:49:16 +02001881
Ludovic Desroches6801c412012-05-16 15:26:01 +02001882 dev_dbg(&host->pdev->dev, "set completed not busy\n");
Ludovic Desrochesf5177542012-05-16 15:25:59 +02001883 atmci_set_completed(host, EVENT_NOTBUSY);
1884
1885 if (host->data) {
1886 /*
1887 * For some commands such as CMD53, even if
1888 * there is data transfer, there is no stop
1889 * command to send.
1890 */
1891 if (host->mrq->stop) {
1892 atmci_writel(host, ATMCI_IER,
1893 ATMCI_CMDRDY);
1894 atmci_send_stop_cmd(host, data);
1895 state = STATE_SENDING_STOP;
1896 } else {
1897 host->data = NULL;
1898 data->bytes_xfered = data->blocks
1899 * data->blksz;
1900 data->error = 0;
1901 state = STATE_END_REQUEST;
1902 }
1903 } else
1904 state = STATE_END_REQUEST;
1905 break;
Haavard Skinnemoenc06ad252008-07-31 14:49:16 +02001906
1907 case STATE_SENDING_STOP:
Ludovic Desrochesf5177542012-05-16 15:25:59 +02001908 /*
1909 * In this state, it is important to set host->data to
1910 * NULL (which is tested in the waiting notbusy state)
1911 * in order to go to the end request state instead of
1912 * sending stop again.
1913 */
Ludovic Desroches6801c412012-05-16 15:26:01 +02001914 dev_dbg(&host->pdev->dev, "FSM: cmd ready?\n");
Haavard Skinnemoenc06ad252008-07-31 14:49:16 +02001915 if (!atmci_test_and_clear_pending(host,
Ludovic Desrochesf5177542012-05-16 15:25:59 +02001916 EVENT_CMD_RDY))
Haavard Skinnemoenc06ad252008-07-31 14:49:16 +02001917 break;
1918
Ludovic Desroches6801c412012-05-16 15:26:01 +02001919 dev_dbg(&host->pdev->dev, "FSM: cmd ready\n");
Haavard Skinnemoenc06ad252008-07-31 14:49:16 +02001920 host->cmd = NULL;
Ludovic Desrochesf5177542012-05-16 15:25:59 +02001921 data->bytes_xfered = data->blocks * data->blksz;
1922 data->error = 0;
Haavard Skinnemoenc06ad252008-07-31 14:49:16 +02001923 atmci_command_complete(host, mrq->stop);
Ludovic Desrochesf5177542012-05-16 15:25:59 +02001924 if (mrq->stop->error) {
1925 host->stop_transfer(host);
1926 atmci_writel(host, ATMCI_IDR,
1927 ATMCI_TXRDY | ATMCI_RXRDY
1928 | ATMCI_DATA_ERROR_FLAGS);
1929 state = STATE_END_REQUEST;
1930 } else {
1931 atmci_writel(host, ATMCI_IER, ATMCI_NOTBUSY);
1932 state = STATE_WAITING_NOTBUSY;
1933 }
Nicolas Ferre41b4e9a2012-07-06 11:58:33 +02001934 host->data = NULL;
Ludovic Desrochesf5177542012-05-16 15:25:59 +02001935 break;
1936
1937 case STATE_END_REQUEST:
1938 atmci_writel(host, ATMCI_IDR, ATMCI_TXRDY | ATMCI_RXRDY
1939 | ATMCI_DATA_ERROR_FLAGS);
1940 status = host->data_status;
1941 if (unlikely(status)) {
1942 host->stop_transfer(host);
1943 host->data = NULL;
Rodolfo Giomettifbd986c2013-09-09 17:31:59 +02001944 if (data) {
1945 if (status & ATMCI_DTOE) {
1946 data->error = -ETIMEDOUT;
1947 } else if (status & ATMCI_DCRCE) {
1948 data->error = -EILSEQ;
1949 } else {
1950 data->error = -EIO;
1951 }
Ludovic Desrochesf5177542012-05-16 15:25:59 +02001952 }
1953 }
1954
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001955 atmci_request_end(host, host->mrq);
Ludovic Desrochesf5177542012-05-16 15:25:59 +02001956 state = STATE_IDLE;
Haavard Skinnemoenc06ad252008-07-31 14:49:16 +02001957 break;
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001958 }
Haavard Skinnemoenc06ad252008-07-31 14:49:16 +02001959 } while (state != prev_state);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001960
Haavard Skinnemoenc06ad252008-07-31 14:49:16 +02001961 host->state = state;
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001962
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02001963 spin_unlock(&host->lock);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001964}
1965
1966static void atmci_read_data_pio(struct atmel_mci *host)
1967{
1968 struct scatterlist *sg = host->sg;
1969 void *buf = sg_virt(sg);
1970 unsigned int offset = host->pio_offset;
1971 struct mmc_data *data = host->data;
1972 u32 value;
1973 u32 status;
1974 unsigned int nbytes = 0;
1975
1976 do {
Ludovic Desroches03fc9a72011-08-11 15:25:42 +00001977 value = atmci_readl(host, ATMCI_RDR);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001978 if (likely(offset + 4 <= sg->length)) {
1979 put_unaligned(value, (u32 *)(buf + offset));
1980
1981 offset += 4;
1982 nbytes += 4;
1983
1984 if (offset == sg->length) {
Haavard Skinnemoen5e7184a2008-10-05 15:27:50 +02001985 flush_dcache_page(sg_page(sg));
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001986 host->sg = sg = sg_next(sg);
Terry Barnabybdbc5d02013-04-08 12:05:47 -04001987 host->sg_len--;
1988 if (!sg || !host->sg_len)
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02001989 goto done;
1990
1991 offset = 0;
1992 buf = sg_virt(sg);
1993 }
1994 } else {
1995 unsigned int remaining = sg->length - offset;
1996 memcpy(buf + offset, &value, remaining);
1997 nbytes += remaining;
1998
1999 flush_dcache_page(sg_page(sg));
2000 host->sg = sg = sg_next(sg);
Terry Barnabybdbc5d02013-04-08 12:05:47 -04002001 host->sg_len--;
2002 if (!sg || !host->sg_len)
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002003 goto done;
2004
2005 offset = 4 - remaining;
2006 buf = sg_virt(sg);
2007 memcpy(buf, (u8 *)&value + remaining, offset);
2008 nbytes += offset;
2009 }
2010
Ludovic Desroches03fc9a72011-08-11 15:25:42 +00002011 status = atmci_readl(host, ATMCI_SR);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002012 if (status & ATMCI_DATA_ERROR_FLAGS) {
Ludovic Desroches03fc9a72011-08-11 15:25:42 +00002013 atmci_writel(host, ATMCI_IDR, (ATMCI_NOTBUSY | ATMCI_RXRDY
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002014 | ATMCI_DATA_ERROR_FLAGS));
2015 host->data_status = status;
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02002016 data->bytes_xfered += nbytes;
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02002017 return;
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002018 }
Ludovic Desroches2c96a292011-08-11 15:25:41 +00002019 } while (status & ATMCI_RXRDY);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002020
2021 host->pio_offset = offset;
2022 data->bytes_xfered += nbytes;
2023
2024 return;
2025
2026done:
Ludovic Desroches03fc9a72011-08-11 15:25:42 +00002027 atmci_writel(host, ATMCI_IDR, ATMCI_RXRDY);
2028 atmci_writel(host, ATMCI_IER, ATMCI_NOTBUSY);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002029 data->bytes_xfered += nbytes;
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02002030 smp_wmb();
Haavard Skinnemoenc06ad252008-07-31 14:49:16 +02002031 atmci_set_pending(host, EVENT_XFER_COMPLETE);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002032}
2033
2034static void atmci_write_data_pio(struct atmel_mci *host)
2035{
2036 struct scatterlist *sg = host->sg;
2037 void *buf = sg_virt(sg);
2038 unsigned int offset = host->pio_offset;
2039 struct mmc_data *data = host->data;
2040 u32 value;
2041 u32 status;
2042 unsigned int nbytes = 0;
2043
2044 do {
2045 if (likely(offset + 4 <= sg->length)) {
2046 value = get_unaligned((u32 *)(buf + offset));
Ludovic Desroches03fc9a72011-08-11 15:25:42 +00002047 atmci_writel(host, ATMCI_TDR, value);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002048
2049 offset += 4;
2050 nbytes += 4;
2051 if (offset == sg->length) {
2052 host->sg = sg = sg_next(sg);
Terry Barnabybdbc5d02013-04-08 12:05:47 -04002053 host->sg_len--;
2054 if (!sg || !host->sg_len)
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002055 goto done;
2056
2057 offset = 0;
2058 buf = sg_virt(sg);
2059 }
2060 } else {
2061 unsigned int remaining = sg->length - offset;
2062
2063 value = 0;
2064 memcpy(&value, buf + offset, remaining);
2065 nbytes += remaining;
2066
2067 host->sg = sg = sg_next(sg);
Terry Barnabybdbc5d02013-04-08 12:05:47 -04002068 host->sg_len--;
2069 if (!sg || !host->sg_len) {
Ludovic Desroches03fc9a72011-08-11 15:25:42 +00002070 atmci_writel(host, ATMCI_TDR, value);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002071 goto done;
2072 }
2073
2074 offset = 4 - remaining;
2075 buf = sg_virt(sg);
2076 memcpy((u8 *)&value + remaining, buf, offset);
Ludovic Desroches03fc9a72011-08-11 15:25:42 +00002077 atmci_writel(host, ATMCI_TDR, value);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002078 nbytes += offset;
2079 }
2080
Ludovic Desroches03fc9a72011-08-11 15:25:42 +00002081 status = atmci_readl(host, ATMCI_SR);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002082 if (status & ATMCI_DATA_ERROR_FLAGS) {
Ludovic Desroches03fc9a72011-08-11 15:25:42 +00002083 atmci_writel(host, ATMCI_IDR, (ATMCI_NOTBUSY | ATMCI_TXRDY
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002084 | ATMCI_DATA_ERROR_FLAGS));
2085 host->data_status = status;
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02002086 data->bytes_xfered += nbytes;
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02002087 return;
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002088 }
Ludovic Desroches2c96a292011-08-11 15:25:41 +00002089 } while (status & ATMCI_TXRDY);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002090
2091 host->pio_offset = offset;
2092 data->bytes_xfered += nbytes;
2093
2094 return;
2095
2096done:
Ludovic Desroches03fc9a72011-08-11 15:25:42 +00002097 atmci_writel(host, ATMCI_IDR, ATMCI_TXRDY);
2098 atmci_writel(host, ATMCI_IER, ATMCI_NOTBUSY);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002099 data->bytes_xfered += nbytes;
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02002100 smp_wmb();
Haavard Skinnemoenc06ad252008-07-31 14:49:16 +02002101 atmci_set_pending(host, EVENT_XFER_COMPLETE);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002102}
2103
Anders Grahn88ff82e2010-05-26 14:42:01 -07002104static void atmci_sdio_interrupt(struct atmel_mci *host, u32 status)
2105{
2106 int i;
2107
Ludovic Desroches2c96a292011-08-11 15:25:41 +00002108 for (i = 0; i < ATMCI_MAX_NR_SLOTS; i++) {
Anders Grahn88ff82e2010-05-26 14:42:01 -07002109 struct atmel_mci_slot *slot = host->slot[i];
2110 if (slot && (status & slot->sdio_irq)) {
2111 mmc_signal_sdio_irq(slot->mmc);
2112 }
2113 }
2114}
2115
2116
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002117static irqreturn_t atmci_interrupt(int irq, void *dev_id)
2118{
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02002119 struct atmel_mci *host = dev_id;
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002120 u32 status, mask, pending;
2121 unsigned int pass_count = 0;
2122
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002123 do {
Ludovic Desroches03fc9a72011-08-11 15:25:42 +00002124 status = atmci_readl(host, ATMCI_SR);
2125 mask = atmci_readl(host, ATMCI_IMR);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002126 pending = status & mask;
2127 if (!pending)
2128 break;
2129
2130 if (pending & ATMCI_DATA_ERROR_FLAGS) {
Ludovic Desroches6801c412012-05-16 15:26:01 +02002131 dev_dbg(&host->pdev->dev, "IRQ: data error\n");
Ludovic Desroches03fc9a72011-08-11 15:25:42 +00002132 atmci_writel(host, ATMCI_IDR, ATMCI_DATA_ERROR_FLAGS
Ludovic Desrochesf5177542012-05-16 15:25:59 +02002133 | ATMCI_RXRDY | ATMCI_TXRDY
2134 | ATMCI_ENDRX | ATMCI_ENDTX
2135 | ATMCI_RXBUFF | ATMCI_TXBUFE);
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02002136
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002137 host->data_status = status;
Ludovic Desroches6801c412012-05-16 15:26:01 +02002138 dev_dbg(&host->pdev->dev, "set pending data error\n");
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02002139 smp_wmb();
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002140 atmci_set_pending(host, EVENT_DATA_ERROR);
2141 tasklet_schedule(&host->tasklet);
2142 }
Ludovic Desroches796211b2011-08-11 15:25:44 +00002143
Ludovic Desroches796211b2011-08-11 15:25:44 +00002144 if (pending & ATMCI_TXBUFE) {
Ludovic Desroches6801c412012-05-16 15:26:01 +02002145 dev_dbg(&host->pdev->dev, "IRQ: tx buffer empty\n");
Ludovic Desroches796211b2011-08-11 15:25:44 +00002146 atmci_writel(host, ATMCI_IDR, ATMCI_TXBUFE);
Ludovic Desroches7e8ba222011-08-11 15:25:48 +00002147 atmci_writel(host, ATMCI_IDR, ATMCI_ENDTX);
Ludovic Desroches796211b2011-08-11 15:25:44 +00002148 /*
2149 * We can receive this interruption before having configured
2150 * the second pdc buffer, so we need to reconfigure first and
2151 * second buffers again
2152 */
2153 if (host->data_size) {
2154 atmci_pdc_set_both_buf(host, XFER_TRANSMIT);
Ludovic Desroches7e8ba222011-08-11 15:25:48 +00002155 atmci_writel(host, ATMCI_IER, ATMCI_ENDTX);
Ludovic Desroches796211b2011-08-11 15:25:44 +00002156 atmci_writel(host, ATMCI_IER, ATMCI_TXBUFE);
2157 } else {
2158 atmci_pdc_complete(host);
2159 }
Ludovic Desroches7e8ba222011-08-11 15:25:48 +00002160 } else if (pending & ATMCI_ENDTX) {
Ludovic Desroches6801c412012-05-16 15:26:01 +02002161 dev_dbg(&host->pdev->dev, "IRQ: end of tx buffer\n");
Ludovic Desroches7e8ba222011-08-11 15:25:48 +00002162 atmci_writel(host, ATMCI_IDR, ATMCI_ENDTX);
2163
2164 if (host->data_size) {
2165 atmci_pdc_set_single_buf(host,
2166 XFER_TRANSMIT, PDC_SECOND_BUF);
2167 atmci_writel(host, ATMCI_IER, ATMCI_ENDTX);
2168 }
Ludovic Desroches796211b2011-08-11 15:25:44 +00002169 }
2170
Ludovic Desroches7e8ba222011-08-11 15:25:48 +00002171 if (pending & ATMCI_RXBUFF) {
Ludovic Desroches6801c412012-05-16 15:26:01 +02002172 dev_dbg(&host->pdev->dev, "IRQ: rx buffer full\n");
Ludovic Desroches7e8ba222011-08-11 15:25:48 +00002173 atmci_writel(host, ATMCI_IDR, ATMCI_RXBUFF);
2174 atmci_writel(host, ATMCI_IDR, ATMCI_ENDRX);
2175 /*
2176 * We can receive this interruption before having configured
2177 * the second pdc buffer, so we need to reconfigure first and
2178 * second buffers again
2179 */
2180 if (host->data_size) {
2181 atmci_pdc_set_both_buf(host, XFER_RECEIVE);
2182 atmci_writel(host, ATMCI_IER, ATMCI_ENDRX);
2183 atmci_writel(host, ATMCI_IER, ATMCI_RXBUFF);
2184 } else {
2185 atmci_pdc_complete(host);
2186 }
2187 } else if (pending & ATMCI_ENDRX) {
Ludovic Desroches6801c412012-05-16 15:26:01 +02002188 dev_dbg(&host->pdev->dev, "IRQ: end of rx buffer\n");
Ludovic Desroches796211b2011-08-11 15:25:44 +00002189 atmci_writel(host, ATMCI_IDR, ATMCI_ENDRX);
2190
2191 if (host->data_size) {
2192 atmci_pdc_set_single_buf(host,
2193 XFER_RECEIVE, PDC_SECOND_BUF);
2194 atmci_writel(host, ATMCI_IER, ATMCI_ENDRX);
2195 }
2196 }
2197
Ludovic Desrochesf5177542012-05-16 15:25:59 +02002198 /*
2199 * First mci IPs, so mainly the ones having pdc, have some
2200 * issues with the notbusy signal. You can't get it after
2201 * data transmission if you have not sent a stop command.
2202 * The appropriate workaround is to use the BLKE signal.
2203 */
2204 if (pending & ATMCI_BLKE) {
Ludovic Desroches6801c412012-05-16 15:26:01 +02002205 dev_dbg(&host->pdev->dev, "IRQ: blke\n");
Ludovic Desrochesf5177542012-05-16 15:25:59 +02002206 atmci_writel(host, ATMCI_IDR, ATMCI_BLKE);
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02002207 smp_wmb();
Ludovic Desroches6801c412012-05-16 15:26:01 +02002208 dev_dbg(&host->pdev->dev, "set pending notbusy\n");
Ludovic Desrochesf5177542012-05-16 15:25:59 +02002209 atmci_set_pending(host, EVENT_NOTBUSY);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002210 tasklet_schedule(&host->tasklet);
2211 }
Ludovic Desrochesf5177542012-05-16 15:25:59 +02002212
2213 if (pending & ATMCI_NOTBUSY) {
Ludovic Desroches6801c412012-05-16 15:26:01 +02002214 dev_dbg(&host->pdev->dev, "IRQ: not_busy\n");
Ludovic Desrochesf5177542012-05-16 15:25:59 +02002215 atmci_writel(host, ATMCI_IDR, ATMCI_NOTBUSY);
2216 smp_wmb();
Ludovic Desroches6801c412012-05-16 15:26:01 +02002217 dev_dbg(&host->pdev->dev, "set pending notbusy\n");
Ludovic Desrochesf5177542012-05-16 15:25:59 +02002218 atmci_set_pending(host, EVENT_NOTBUSY);
2219 tasklet_schedule(&host->tasklet);
2220 }
2221
Ludovic Desroches2c96a292011-08-11 15:25:41 +00002222 if (pending & ATMCI_RXRDY)
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002223 atmci_read_data_pio(host);
Ludovic Desroches2c96a292011-08-11 15:25:41 +00002224 if (pending & ATMCI_TXRDY)
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002225 atmci_write_data_pio(host);
2226
Ludovic Desrochesf5177542012-05-16 15:25:59 +02002227 if (pending & ATMCI_CMDRDY) {
Ludovic Desroches6801c412012-05-16 15:26:01 +02002228 dev_dbg(&host->pdev->dev, "IRQ: cmd ready\n");
Ludovic Desrochesf5177542012-05-16 15:25:59 +02002229 atmci_writel(host, ATMCI_IDR, ATMCI_CMDRDY);
2230 host->cmd_status = status;
2231 smp_wmb();
Ludovic Desroches6801c412012-05-16 15:26:01 +02002232 dev_dbg(&host->pdev->dev, "set pending cmd rdy\n");
Ludovic Desrochesf5177542012-05-16 15:25:59 +02002233 atmci_set_pending(host, EVENT_CMD_RDY);
2234 tasklet_schedule(&host->tasklet);
2235 }
Anders Grahn88ff82e2010-05-26 14:42:01 -07002236
Ludovic Desroches2c96a292011-08-11 15:25:41 +00002237 if (pending & (ATMCI_SDIOIRQA | ATMCI_SDIOIRQB))
Anders Grahn88ff82e2010-05-26 14:42:01 -07002238 atmci_sdio_interrupt(host, status);
2239
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002240 } while (pass_count++ < 5);
2241
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002242 return pass_count ? IRQ_HANDLED : IRQ_NONE;
2243}
2244
2245static irqreturn_t atmci_detect_interrupt(int irq, void *dev_id)
2246{
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02002247 struct atmel_mci_slot *slot = dev_id;
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002248
2249 /*
2250 * Disable interrupts until the pin has stabilized and check
2251 * the state then. Use mod_timer() since we may be in the
2252 * middle of the timer routine when this interrupt triggers.
2253 */
2254 disable_irq_nosync(irq);
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02002255 mod_timer(&slot->detect_timer, jiffies + msecs_to_jiffies(20));
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002256
2257 return IRQ_HANDLED;
2258}
2259
ludovic.desroches@atmel.comab050b92014-12-01 15:35:07 +01002260static int atmci_init_slot(struct atmel_mci *host,
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02002261 struct mci_slot_pdata *slot_data, unsigned int id,
Anders Grahn88ff82e2010-05-26 14:42:01 -07002262 u32 sdc_reg, u32 sdio_irq)
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02002263{
2264 struct mmc_host *mmc;
2265 struct atmel_mci_slot *slot;
2266
2267 mmc = mmc_alloc_host(sizeof(struct atmel_mci_slot), &host->pdev->dev);
2268 if (!mmc)
2269 return -ENOMEM;
2270
2271 slot = mmc_priv(mmc);
2272 slot->mmc = mmc;
2273 slot->host = host;
2274 slot->detect_pin = slot_data->detect_pin;
2275 slot->wp_pin = slot_data->wp_pin;
Jonas Larsson1c1452b2009-03-31 11:16:48 +02002276 slot->detect_is_active_high = slot_data->detect_is_active_high;
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02002277 slot->sdc_reg = sdc_reg;
Anders Grahn88ff82e2010-05-26 14:42:01 -07002278 slot->sdio_irq = sdio_irq;
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02002279
Ludovic Desrochese919fd22012-07-24 15:30:03 +02002280 dev_dbg(&mmc->class_dev,
2281 "slot[%u]: bus_width=%u, detect_pin=%d, "
2282 "detect_is_active_high=%s, wp_pin=%d\n",
2283 id, slot_data->bus_width, slot_data->detect_pin,
2284 slot_data->detect_is_active_high ? "true" : "false",
2285 slot_data->wp_pin);
2286
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02002287 mmc->ops = &atmci_ops;
2288 mmc->f_min = DIV_ROUND_UP(host->bus_hz, 512);
2289 mmc->f_max = host->bus_hz / 2;
2290 mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
Anders Grahn88ff82e2010-05-26 14:42:01 -07002291 if (sdio_irq)
2292 mmc->caps |= MMC_CAP_SDIO_IRQ;
Ludovic Desroches796211b2011-08-11 15:25:44 +00002293 if (host->caps.has_highspeed)
Nicolas Ferre99ddffd2010-05-26 14:41:59 -07002294 mmc->caps |= MMC_CAP_SD_HIGHSPEED;
Ludovic Desroches7a90dcc2012-05-16 15:25:58 +02002295 /*
2296 * Without the read/write proof capability, it is strongly suggested to
2297 * use only one bit for data to prevent fifo underruns and overruns
2298 * which will corrupt data.
2299 */
2300 if ((slot_data->bus_width >= 4) && host->caps.has_rwproof)
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02002301 mmc->caps |= MMC_CAP_4_BIT_DATA;
2302
Ludovic Desroches7a90dcc2012-05-16 15:25:58 +02002303 if (atmci_get_version(host) < 0x200) {
2304 mmc->max_segs = 256;
2305 mmc->max_blk_size = 4095;
2306 mmc->max_blk_count = 256;
2307 mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
2308 mmc->max_seg_size = mmc->max_blk_size * mmc->max_segs;
2309 } else {
2310 mmc->max_segs = 64;
2311 mmc->max_req_size = 32768 * 512;
2312 mmc->max_blk_size = 32768;
2313 mmc->max_blk_count = 512;
2314 }
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02002315
2316 /* Assume card is present initially */
2317 set_bit(ATMCI_CARD_PRESENT, &slot->flags);
2318 if (gpio_is_valid(slot->detect_pin)) {
Pramod Gurav7bca6462014-09-23 18:21:48 +05302319 if (devm_gpio_request(&host->pdev->dev, slot->detect_pin,
2320 "mmc_detect")) {
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02002321 dev_dbg(&mmc->class_dev, "no detect pin available\n");
2322 slot->detect_pin = -EBUSY;
Jonas Larsson1c1452b2009-03-31 11:16:48 +02002323 } else if (gpio_get_value(slot->detect_pin) ^
2324 slot->detect_is_active_high) {
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02002325 clear_bit(ATMCI_CARD_PRESENT, &slot->flags);
2326 }
2327 }
2328
Timo Kokkonen76d55562014-11-03 13:12:59 +02002329 if (!gpio_is_valid(slot->detect_pin)) {
2330 if (slot_data->non_removable)
2331 mmc->caps |= MMC_CAP_NONREMOVABLE;
2332 else
2333 mmc->caps |= MMC_CAP_NEEDS_POLL;
2334 }
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02002335
2336 if (gpio_is_valid(slot->wp_pin)) {
Pramod Gurav7bca6462014-09-23 18:21:48 +05302337 if (devm_gpio_request(&host->pdev->dev, slot->wp_pin,
2338 "mmc_wp")) {
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02002339 dev_dbg(&mmc->class_dev, "no WP pin available\n");
2340 slot->wp_pin = -EBUSY;
2341 }
2342 }
2343
2344 host->slot[id] = slot;
Alexandre Belloni9e7861f2013-10-17 12:46:48 +02002345 mmc_regulator_get_supply(mmc);
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02002346 mmc_add_host(mmc);
2347
2348 if (gpio_is_valid(slot->detect_pin)) {
2349 int ret;
2350
2351 setup_timer(&slot->detect_timer, atmci_detect_change,
2352 (unsigned long)slot);
2353
2354 ret = request_irq(gpio_to_irq(slot->detect_pin),
2355 atmci_detect_interrupt,
2356 IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
2357 "mmc-detect", slot);
2358 if (ret) {
2359 dev_dbg(&mmc->class_dev,
2360 "could not request IRQ %d for detect pin\n",
2361 gpio_to_irq(slot->detect_pin));
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02002362 slot->detect_pin = -EBUSY;
2363 }
2364 }
2365
2366 atmci_init_debugfs(slot);
2367
2368 return 0;
2369}
2370
Arnd Bergmann5fef3652014-09-26 21:34:58 +02002371static void atmci_cleanup_slot(struct atmel_mci_slot *slot,
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02002372 unsigned int id)
2373{
2374 /* Debugfs stuff is cleaned up by mmc core */
2375
2376 set_bit(ATMCI_SHUTDOWN, &slot->flags);
2377 smp_wmb();
2378
2379 mmc_remove_host(slot->mmc);
2380
2381 if (gpio_is_valid(slot->detect_pin)) {
2382 int pin = slot->detect_pin;
2383
2384 free_irq(gpio_to_irq(pin), slot);
2385 del_timer_sync(&slot->detect_timer);
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02002386 }
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02002387
2388 slot->host->slot[id] = NULL;
2389 mmc_free_host(slot->mmc);
2390}
2391
ludovic.desroches@atmel.com467e0812014-12-01 15:35:09 +01002392static int atmci_configure_dma(struct atmel_mci *host)
Nicolas Ferre2635d1b2009-12-14 18:01:30 -08002393{
ludovic.desroches@atmel.com467e0812014-12-01 15:35:09 +01002394 host->dma.chan = dma_request_slave_channel_reason(&host->pdev->dev,
2395 "rxtx");
Mans Rullgard74843782016-01-09 12:45:10 +00002396
2397 if (PTR_ERR(host->dma.chan) == -ENODEV) {
2398 struct mci_platform_data *pdata = host->pdev->dev.platform_data;
2399 dma_cap_mask_t mask;
2400
Brent Taylor93c77d22016-03-13 00:25:31 -06002401 if (!pdata || !pdata->dma_filter)
Mans Rullgard74843782016-01-09 12:45:10 +00002402 return -ENODEV;
2403
2404 dma_cap_zero(mask);
2405 dma_cap_set(DMA_SLAVE, mask);
2406
2407 host->dma.chan = dma_request_channel(mask, pdata->dma_filter,
2408 pdata->dma_slave);
2409 if (!host->dma.chan)
2410 host->dma.chan = ERR_PTR(-ENODEV);
2411 }
2412
ludovic.desroches@atmel.com467e0812014-12-01 15:35:09 +01002413 if (IS_ERR(host->dma.chan))
2414 return PTR_ERR(host->dma.chan);
Nicolas Ferre2635d1b2009-12-14 18:01:30 -08002415
ludovic.desroches@atmel.com467e0812014-12-01 15:35:09 +01002416 dev_info(&host->pdev->dev, "using %s for DMA transfers\n",
2417 dma_chan_name(host->dma.chan));
Viresh Kumare2b35f32012-02-01 16:12:27 +05302418
ludovic.desroches@atmel.com467e0812014-12-01 15:35:09 +01002419 host->dma_conf.src_addr = host->mapbase + ATMCI_RDR;
2420 host->dma_conf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
2421 host->dma_conf.src_maxburst = 1;
2422 host->dma_conf.dst_addr = host->mapbase + ATMCI_TDR;
2423 host->dma_conf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
2424 host->dma_conf.dst_maxburst = 1;
2425 host->dma_conf.device_fc = false;
2426
2427 return 0;
Nicolas Ferre2635d1b2009-12-14 18:01:30 -08002428}
Ludovic Desroches796211b2011-08-11 15:25:44 +00002429
Ludovic Desroches796211b2011-08-11 15:25:44 +00002430/*
2431 * HSMCI (High Speed MCI) module is not fully compatible with MCI module.
2432 * HSMCI provides DMA support and a new config register but no more supports
2433 * PDC.
2434 */
ludovic.desroches@atmel.comab050b92014-12-01 15:35:07 +01002435static void atmci_get_cap(struct atmel_mci *host)
Ludovic Desroches796211b2011-08-11 15:25:44 +00002436{
2437 unsigned int version;
2438
2439 version = atmci_get_version(host);
2440 dev_info(&host->pdev->dev,
2441 "version: 0x%x\n", version);
2442
Hein_Tiboschccdfe612012-08-30 16:34:38 +00002443 host->caps.has_dma_conf_reg = 0;
Andy Shevchenkoef4b1602017-05-09 20:21:17 +03002444 host->caps.has_pdc = 1;
Ludovic Desroches796211b2011-08-11 15:25:44 +00002445 host->caps.has_cfg_reg = 0;
2446 host->caps.has_cstor_reg = 0;
2447 host->caps.has_highspeed = 0;
2448 host->caps.has_rwproof = 0;
Ludovic Desrochesfaf81802012-03-21 16:41:23 +01002449 host->caps.has_odd_clk_div = 0;
Ludovic Desroches24011f32012-05-16 15:26:00 +02002450 host->caps.has_bad_data_ordering = 1;
2451 host->caps.need_reset_after_xfer = 1;
2452 host->caps.need_blksz_mul_4 = 1;
Ludovic Desroches077d4072012-07-24 11:42:04 +02002453 host->caps.need_notbusy_for_read_ops = 0;
Ludovic Desroches796211b2011-08-11 15:25:44 +00002454
2455 /* keep only major version number */
2456 switch (version & 0xf00) {
Nicolas Ferre215ba392014-06-12 09:47:45 +02002457 case 0x600:
Ludovic Desroches796211b2011-08-11 15:25:44 +00002458 case 0x500:
Ludovic Desrochesfaf81802012-03-21 16:41:23 +01002459 host->caps.has_odd_clk_div = 1;
2460 case 0x400:
2461 case 0x300:
Hein_Tiboschccdfe612012-08-30 16:34:38 +00002462 host->caps.has_dma_conf_reg = 1;
Ludovic Desrochesfaf81802012-03-21 16:41:23 +01002463 host->caps.has_pdc = 0;
Ludovic Desroches796211b2011-08-11 15:25:44 +00002464 host->caps.has_cfg_reg = 1;
2465 host->caps.has_cstor_reg = 1;
2466 host->caps.has_highspeed = 1;
Ludovic Desrochesfaf81802012-03-21 16:41:23 +01002467 case 0x200:
Ludovic Desroches796211b2011-08-11 15:25:44 +00002468 host->caps.has_rwproof = 1;
Ludovic Desroches24011f32012-05-16 15:26:00 +02002469 host->caps.need_blksz_mul_4 = 0;
Ludovic Desroches077d4072012-07-24 11:42:04 +02002470 host->caps.need_notbusy_for_read_ops = 1;
Ludovic Desrochesfaf81802012-03-21 16:41:23 +01002471 case 0x100:
Ludovic Desroches24011f32012-05-16 15:26:00 +02002472 host->caps.has_bad_data_ordering = 0;
2473 host->caps.need_reset_after_xfer = 0;
2474 case 0x0:
Ludovic Desroches796211b2011-08-11 15:25:44 +00002475 break;
2476 default:
Ludovic Desrochesfaf81802012-03-21 16:41:23 +01002477 host->caps.has_pdc = 0;
Ludovic Desroches796211b2011-08-11 15:25:44 +00002478 dev_warn(&host->pdev->dev,
2479 "Unmanaged mci version, set minimum capabilities\n");
2480 break;
2481 }
2482}
Dan Williams74465b42009-01-06 11:38:16 -07002483
ludovic.desroches@atmel.comab050b92014-12-01 15:35:07 +01002484static int atmci_probe(struct platform_device *pdev)
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002485{
2486 struct mci_platform_data *pdata;
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02002487 struct atmel_mci *host;
2488 struct resource *regs;
2489 unsigned int nr_slots;
2490 int irq;
Pramod Gurav528bc782014-09-23 15:50:06 +05302491 int ret, i;
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002492
2493 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2494 if (!regs)
2495 return -ENXIO;
2496 pdata = pdev->dev.platform_data;
Ludovic Desrochese919fd22012-07-24 15:30:03 +02002497 if (!pdata) {
2498 pdata = atmci_of_init(pdev);
2499 if (IS_ERR(pdata)) {
2500 dev_err(&pdev->dev, "platform data not available\n");
2501 return PTR_ERR(pdata);
2502 }
2503 }
2504
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002505 irq = platform_get_irq(pdev, 0);
2506 if (irq < 0)
2507 return irq;
2508
Pramod Gurav7bca6462014-09-23 18:21:48 +05302509 host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL);
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02002510 if (!host)
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002511 return -ENOMEM;
2512
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002513 host->pdev = pdev;
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02002514 spin_lock_init(&host->lock);
2515 INIT_LIST_HEAD(&host->queue);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002516
Pramod Gurav7bca6462014-09-23 18:21:48 +05302517 host->mck = devm_clk_get(&pdev->dev, "mci_clk");
2518 if (IS_ERR(host->mck))
2519 return PTR_ERR(host->mck);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002520
Pramod Gurav7bca6462014-09-23 18:21:48 +05302521 host->regs = devm_ioremap(&pdev->dev, regs->start, resource_size(regs));
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002522 if (!host->regs)
Pramod Gurav7bca6462014-09-23 18:21:48 +05302523 return -ENOMEM;
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002524
Boris BREZILLONb3894f22013-07-18 09:38:52 +02002525 ret = clk_prepare_enable(host->mck);
2526 if (ret)
Pramod Gurav7bca6462014-09-23 18:21:48 +05302527 return ret;
2528
Ludovic Desroches03fc9a72011-08-11 15:25:42 +00002529 atmci_writel(host, ATMCI_CR, ATMCI_CR_SWRST);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002530 host->bus_hz = clk_get_rate(host->mck);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002531
2532 host->mapbase = regs->start;
2533
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02002534 tasklet_init(&host->tasklet, atmci_tasklet_func, (unsigned long)host);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002535
Kay Sievers89c8aa22009-02-02 21:08:30 +01002536 ret = request_irq(irq, atmci_interrupt, 0, dev_name(&pdev->dev), host);
Wenyou Yangae552ab2014-10-30 12:00:41 +08002537 if (ret) {
2538 clk_disable_unprepare(host->mck);
Pramod Gurav7bca6462014-09-23 18:21:48 +05302539 return ret;
Wenyou Yangae552ab2014-10-30 12:00:41 +08002540 }
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002541
Ludovic Desroches796211b2011-08-11 15:25:44 +00002542 /* Get MCI capabilities and set operations according to it */
2543 atmci_get_cap(host);
ludovic.desroches@atmel.com467e0812014-12-01 15:35:09 +01002544 ret = atmci_configure_dma(host);
2545 if (ret == -EPROBE_DEFER)
2546 goto err_dma_probe_defer;
2547 if (ret == 0) {
Ludovic Desroches796211b2011-08-11 15:25:44 +00002548 host->prepare_data = &atmci_prepare_data_dma;
2549 host->submit_data = &atmci_submit_data_dma;
2550 host->stop_transfer = &atmci_stop_transfer_dma;
2551 } else if (host->caps.has_pdc) {
2552 dev_info(&pdev->dev, "using PDC\n");
2553 host->prepare_data = &atmci_prepare_data_pdc;
2554 host->submit_data = &atmci_submit_data_pdc;
2555 host->stop_transfer = &atmci_stop_transfer_pdc;
2556 } else {
Ludovic Desrochesef8781982012-02-09 16:33:53 +01002557 dev_info(&pdev->dev, "using PIO\n");
Ludovic Desroches796211b2011-08-11 15:25:44 +00002558 host->prepare_data = &atmci_prepare_data;
2559 host->submit_data = &atmci_submit_data;
2560 host->stop_transfer = &atmci_stop_transfer;
2561 }
2562
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002563 platform_set_drvdata(pdev, host);
2564
Ludovic Desrochesb87cc1b2012-05-23 15:52:15 +02002565 setup_timer(&host->timer, atmci_timeout_timer, (unsigned long)host);
2566
Wenyou Yangae552ab2014-10-30 12:00:41 +08002567 pm_runtime_get_noresume(&pdev->dev);
2568 pm_runtime_set_active(&pdev->dev);
2569 pm_runtime_set_autosuspend_delay(&pdev->dev, AUTOSUSPEND_DELAY);
2570 pm_runtime_use_autosuspend(&pdev->dev);
2571 pm_runtime_enable(&pdev->dev);
2572
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02002573 /* We need at least one slot to succeed */
2574 nr_slots = 0;
2575 ret = -ENODEV;
2576 if (pdata->slot[0].bus_width) {
2577 ret = atmci_init_slot(host, &pdata->slot[0],
Ludovic Desroches2c96a292011-08-11 15:25:41 +00002578 0, ATMCI_SDCSEL_SLOT_A, ATMCI_SDIOIRQA);
Ludovic Desroches7a90dcc2012-05-16 15:25:58 +02002579 if (!ret) {
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02002580 nr_slots++;
Ludovic Desroches7a90dcc2012-05-16 15:25:58 +02002581 host->buf_size = host->slot[0]->mmc->max_req_size;
2582 }
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02002583 }
2584 if (pdata->slot[1].bus_width) {
2585 ret = atmci_init_slot(host, &pdata->slot[1],
Ludovic Desroches2c96a292011-08-11 15:25:41 +00002586 1, ATMCI_SDCSEL_SLOT_B, ATMCI_SDIOIRQB);
Ludovic Desroches7a90dcc2012-05-16 15:25:58 +02002587 if (!ret) {
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02002588 nr_slots++;
Ludovic Desroches7a90dcc2012-05-16 15:25:58 +02002589 if (host->slot[1]->mmc->max_req_size > host->buf_size)
2590 host->buf_size =
2591 host->slot[1]->mmc->max_req_size;
2592 }
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002593 }
2594
Rob Emanuele04d699c2009-09-22 16:45:19 -07002595 if (!nr_slots) {
2596 dev_err(&pdev->dev, "init failed: no slot defined\n");
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02002597 goto err_init_slot;
Rob Emanuele04d699c2009-09-22 16:45:19 -07002598 }
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002599
Ludovic Desroches7a90dcc2012-05-16 15:25:58 +02002600 if (!host->caps.has_rwproof) {
2601 host->buffer = dma_alloc_coherent(&pdev->dev, host->buf_size,
2602 &host->buf_phys_addr,
2603 GFP_KERNEL);
2604 if (!host->buffer) {
2605 ret = -ENOMEM;
2606 dev_err(&pdev->dev, "buffer allocation failed\n");
Pramod Gurav528bc782014-09-23 15:50:06 +05302607 goto err_dma_alloc;
Ludovic Desroches7a90dcc2012-05-16 15:25:58 +02002608 }
2609 }
2610
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02002611 dev_info(&pdev->dev,
2612 "Atmel MCI controller at 0x%08lx irq %d, %u slots\n",
2613 host->mapbase, irq, nr_slots);
Haavard Skinnemoendeec9ae2008-07-24 14:18:59 +02002614
Wenyou Yangae552ab2014-10-30 12:00:41 +08002615 pm_runtime_mark_last_busy(&host->pdev->dev);
2616 pm_runtime_put_autosuspend(&pdev->dev);
2617
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002618 return 0;
2619
Pramod Gurav528bc782014-09-23 15:50:06 +05302620err_dma_alloc:
2621 for (i = 0; i < ATMCI_MAX_NR_SLOTS; i++) {
2622 if (host->slot[i])
2623 atmci_cleanup_slot(host->slot[i], i);
2624 }
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02002625err_init_slot:
Wenyou Yangae552ab2014-10-30 12:00:41 +08002626 clk_disable_unprepare(host->mck);
2627
2628 pm_runtime_disable(&pdev->dev);
2629 pm_runtime_put_noidle(&pdev->dev);
2630
Pramod Gurav528bc782014-09-23 15:50:06 +05302631 del_timer_sync(&host->timer);
ludovic.desroches@atmel.com467e0812014-12-01 15:35:09 +01002632 if (!IS_ERR(host->dma.chan))
Dan Williams74465b42009-01-06 11:38:16 -07002633 dma_release_channel(host->dma.chan);
ludovic.desroches@atmel.com467e0812014-12-01 15:35:09 +01002634err_dma_probe_defer:
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02002635 free_irq(irq, host);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002636 return ret;
2637}
2638
ludovic.desroches@atmel.comab050b92014-12-01 15:35:07 +01002639static int atmci_remove(struct platform_device *pdev)
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002640{
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02002641 struct atmel_mci *host = platform_get_drvdata(pdev);
2642 unsigned int i;
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002643
Wenyou Yangae552ab2014-10-30 12:00:41 +08002644 pm_runtime_get_sync(&pdev->dev);
2645
Ludovic Desroches7a90dcc2012-05-16 15:25:58 +02002646 if (host->buffer)
2647 dma_free_coherent(&pdev->dev, host->buf_size,
2648 host->buffer, host->buf_phys_addr);
2649
Ludovic Desroches2c96a292011-08-11 15:25:41 +00002650 for (i = 0; i < ATMCI_MAX_NR_SLOTS; i++) {
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02002651 if (host->slot[i])
2652 atmci_cleanup_slot(host->slot[i], i);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002653 }
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02002654
Ludovic Desroches03fc9a72011-08-11 15:25:42 +00002655 atmci_writel(host, ATMCI_IDR, ~0UL);
2656 atmci_writel(host, ATMCI_CR, ATMCI_CR_MCIDIS);
2657 atmci_readl(host, ATMCI_SR);
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02002658
Pramod Gurav528bc782014-09-23 15:50:06 +05302659 del_timer_sync(&host->timer);
ludovic.desroches@atmel.com467e0812014-12-01 15:35:09 +01002660 if (!IS_ERR(host->dma.chan))
Dan Williams74465b42009-01-06 11:38:16 -07002661 dma_release_channel(host->dma.chan);
Haavard Skinnemoen65e8b082008-07-30 20:29:03 +02002662
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02002663 free_irq(platform_get_irq(pdev, 0), host);
Haavard Skinnemoen965ebf32008-09-17 20:53:55 +02002664
Wenyou Yangae552ab2014-10-30 12:00:41 +08002665 clk_disable_unprepare(host->mck);
2666
2667 pm_runtime_disable(&pdev->dev);
2668 pm_runtime_put_noidle(&pdev->dev);
2669
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002670 return 0;
2671}
2672
Wenyou Yangae552ab2014-10-30 12:00:41 +08002673#ifdef CONFIG_PM
2674static int atmci_runtime_suspend(struct device *dev)
2675{
2676 struct atmel_mci *host = dev_get_drvdata(dev);
2677
2678 clk_disable_unprepare(host->mck);
2679
Wenyou Yangb5b64fa2014-11-07 08:48:13 +08002680 pinctrl_pm_select_sleep_state(dev);
2681
Wenyou Yangae552ab2014-10-30 12:00:41 +08002682 return 0;
2683}
2684
2685static int atmci_runtime_resume(struct device *dev)
2686{
2687 struct atmel_mci *host = dev_get_drvdata(dev);
2688
Wenyou Yangb5b64fa2014-11-07 08:48:13 +08002689 pinctrl_pm_select_default_state(dev);
2690
Wenyou Yangae552ab2014-10-30 12:00:41 +08002691 return clk_prepare_enable(host->mck);
2692}
2693#endif
2694
2695static const struct dev_pm_ops atmci_dev_pm_ops = {
2696 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
2697 pm_runtime_force_resume)
Ludovic Desrochesc3cb6ba2014-12-13 00:44:11 +01002698 SET_RUNTIME_PM_OPS(atmci_runtime_suspend, atmci_runtime_resume, NULL)
Wenyou Yangae552ab2014-10-30 12:00:41 +08002699};
2700
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002701static struct platform_driver atmci_driver = {
ludovic.desroches@atmel.com5e0fe892014-12-01 15:35:08 +01002702 .probe = atmci_probe,
ludovic.desroches@atmel.comab050b92014-12-01 15:35:07 +01002703 .remove = atmci_remove,
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002704 .driver = {
2705 .name = "atmel_mci",
Ludovic Desrochese919fd22012-07-24 15:30:03 +02002706 .of_match_table = of_match_ptr(atmci_dt_ids),
Wenyou Yangae552ab2014-10-30 12:00:41 +08002707 .pm = &atmci_dev_pm_ops,
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002708 },
2709};
ludovic.desroches@atmel.com5e0fe892014-12-01 15:35:08 +01002710module_platform_driver(atmci_driver);
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002711
2712MODULE_DESCRIPTION("Atmel Multimedia Card Interface driver");
Jean Delvaree05503e2011-05-18 16:49:24 +02002713MODULE_AUTHOR("Haavard Skinnemoen (Atmel)");
Haavard Skinnemoen7d2be072008-06-30 18:35:03 +02002714MODULE_LICENSE("GPL v2");