| Will Newton | f95f385 | 2011-01-02 01:11:59 -0500 | [diff] [blame] | 1 | /* | 
|  | 2 | * Synopsys DesignWare Multimedia Card Interface driver | 
|  | 3 | *  (Based on NXP driver for lpc 31xx) | 
|  | 4 | * | 
|  | 5 | * Copyright (C) 2009 NXP Semiconductors | 
|  | 6 | * Copyright (C) 2009, 2010 Imagination Technologies Ltd. | 
|  | 7 | * | 
|  | 8 | * This program is free software; you can redistribute it and/or modify | 
|  | 9 | * it under the terms of the GNU General Public License as published by | 
|  | 10 | * the Free Software Foundation; either version 2 of the License, or | 
|  | 11 | * (at your option) any later version. | 
|  | 12 | */ | 
|  | 13 |  | 
| Robert P. J. Day | 100e918 | 2011-05-27 16:04:03 -0400 | [diff] [blame] | 14 | #ifndef LINUX_MMC_DW_MMC_H | 
|  | 15 | #define LINUX_MMC_DW_MMC_H | 
| Will Newton | f95f385 | 2011-01-02 01:11:59 -0500 | [diff] [blame] | 16 |  | 
| Seungwon Jeon | f9c2a0d | 2012-02-09 14:32:43 +0900 | [diff] [blame] | 17 | #include <linux/scatterlist.h> | 
| Seungwon Jeon | 90c2143 | 2013-08-31 00:14:05 +0900 | [diff] [blame] | 18 | #include <linux/mmc/core.h> | 
| Seungwon Jeon | f9c2a0d | 2012-02-09 14:32:43 +0900 | [diff] [blame] | 19 |  | 
| Will Newton | f95f385 | 2011-01-02 01:11:59 -0500 | [diff] [blame] | 20 | #define MAX_MCI_SLOTS	2 | 
|  | 21 |  | 
|  | 22 | enum dw_mci_state { | 
|  | 23 | STATE_IDLE = 0, | 
|  | 24 | STATE_SENDING_CMD, | 
|  | 25 | STATE_SENDING_DATA, | 
|  | 26 | STATE_DATA_BUSY, | 
|  | 27 | STATE_SENDING_STOP, | 
|  | 28 | STATE_DATA_ERROR, | 
| Doug Anderson | 0173055 | 2014-08-22 19:17:51 +0530 | [diff] [blame] | 29 | STATE_SENDING_CMD11, | 
|  | 30 | STATE_WAITING_CMD11_DONE, | 
| Will Newton | f95f385 | 2011-01-02 01:11:59 -0500 | [diff] [blame] | 31 | }; | 
|  | 32 |  | 
|  | 33 | enum { | 
|  | 34 | EVENT_CMD_COMPLETE = 0, | 
|  | 35 | EVENT_XFER_COMPLETE, | 
|  | 36 | EVENT_DATA_COMPLETE, | 
|  | 37 | EVENT_DATA_ERROR, | 
|  | 38 | EVENT_XFER_ERROR | 
|  | 39 | }; | 
|  | 40 |  | 
|  | 41 | struct mmc_data; | 
|  | 42 |  | 
|  | 43 | /** | 
|  | 44 | * struct dw_mci - MMC controller state shared between all slots | 
|  | 45 | * @lock: Spinlock protecting the queue and associated data. | 
|  | 46 | * @regs: Pointer to MMIO registers. | 
|  | 47 | * @sg: Scatterlist entry currently being processed by PIO code, if any. | 
| Seungwon Jeon | f9c2a0d | 2012-02-09 14:32:43 +0900 | [diff] [blame] | 48 | * @sg_miter: PIO mapping scatterlist iterator. | 
| Will Newton | f95f385 | 2011-01-02 01:11:59 -0500 | [diff] [blame] | 49 | * @cur_slot: The slot which is currently using the controller. | 
|  | 50 | * @mrq: The request currently being processed on @cur_slot, | 
|  | 51 | *	or NULL if the controller is idle. | 
|  | 52 | * @cmd: The command currently being sent to the card, or NULL. | 
|  | 53 | * @data: The data currently being transferred, or NULL if no data | 
|  | 54 | *	transfer is in progress. | 
|  | 55 | * @use_dma: Whether DMA channel is initialized or not. | 
| James Hogan | 03e8cb5 | 2011-06-29 09:28:43 +0100 | [diff] [blame] | 56 | * @using_dma: Whether DMA is in use for the current transfer. | 
| Prabu Thangamuthu | 69d99fd | 2014-10-20 07:12:33 +0000 | [diff] [blame] | 57 | * @dma_64bit_address: Whether DMA supports 64-bit address mode or not. | 
| Will Newton | f95f385 | 2011-01-02 01:11:59 -0500 | [diff] [blame] | 58 | * @sg_dma: Bus address of DMA buffer. | 
|  | 59 | * @sg_cpu: Virtual address of DMA buffer. | 
|  | 60 | * @dma_ops: Pointer to platform-specific DMA callbacks. | 
|  | 61 | * @cmd_status: Snapshot of SR taken upon completion of the current | 
|  | 62 | *	command. Only valid when EVENT_CMD_COMPLETE is pending. | 
|  | 63 | * @data_status: Snapshot of SR taken upon completion of the current | 
|  | 64 | *	data transfer. Only valid when EVENT_DATA_COMPLETE or | 
|  | 65 | *	EVENT_DATA_ERROR is pending. | 
|  | 66 | * @stop_cmdr: Value to be loaded into CMDR when the stop command is | 
|  | 67 | *	to be sent. | 
|  | 68 | * @dir_status: Direction of current transfer. | 
|  | 69 | * @tasklet: Tasklet running the request state machine. | 
|  | 70 | * @card_tasklet: Tasklet handling card detect. | 
|  | 71 | * @pending_events: Bitmask of events flagged by the interrupt handler | 
|  | 72 | *	to be processed by the tasklet. | 
|  | 73 | * @completed_events: Bitmask of events which the state machine has | 
|  | 74 | *	processed. | 
|  | 75 | * @state: Tasklet state. | 
|  | 76 | * @queue: List of slots waiting for access to the controller. | 
|  | 77 | * @bus_hz: The rate of @mck in Hz. This forms the basis for MMC bus | 
|  | 78 | *	rate and timeout calculations. | 
|  | 79 | * @current_speed: Configured rate of the controller. | 
|  | 80 | * @num_slots: Number of slots available. | 
| Jaehoon Chung | 4e0a5ad | 2011-10-17 19:36:23 +0900 | [diff] [blame] | 81 | * @verid: Denote Version ID. | 
|  | 82 | * @data_offset: Set the offset of DATA register according to VERID. | 
| Shashidhar Hiremath | 62ca803 | 2012-01-13 16:04:57 +0530 | [diff] [blame] | 83 | * @dev: Device associated with the MMC controller. | 
| Will Newton | f95f385 | 2011-01-02 01:11:59 -0500 | [diff] [blame] | 84 | * @pdata: Platform data associated with the MMC controller. | 
| Thomas Abraham | 800d78b | 2012-09-17 18:16:42 +0000 | [diff] [blame] | 85 | * @drv_data: Driver specific data for identified variant of the controller | 
|  | 86 | * @priv: Implementation defined private data. | 
| Thomas Abraham | f90a061 | 2012-09-17 18:16:38 +0000 | [diff] [blame] | 87 | * @biu_clk: Pointer to bus interface unit clock instance. | 
|  | 88 | * @ciu_clk: Pointer to card interface unit clock instance. | 
| Will Newton | f95f385 | 2011-01-02 01:11:59 -0500 | [diff] [blame] | 89 | * @slot: Slots sharing this MMC controller. | 
| James Hogan | b86d825 | 2011-06-24 13:57:18 +0100 | [diff] [blame] | 90 | * @fifo_depth: depth of FIFO. | 
| Will Newton | f95f385 | 2011-01-02 01:11:59 -0500 | [diff] [blame] | 91 | * @data_shift: log2 of FIFO item size. | 
| James Hogan | 34b664a | 2011-06-24 13:57:56 +0100 | [diff] [blame] | 92 | * @part_buf_start: Start index in part_buf. | 
|  | 93 | * @part_buf_count: Bytes of partial data in part_buf. | 
|  | 94 | * @part_buf: Simple buffer for partial fifo reads/writes. | 
| Will Newton | f95f385 | 2011-01-02 01:11:59 -0500 | [diff] [blame] | 95 | * @push_data: Pointer to FIFO push function. | 
|  | 96 | * @pull_data: Pointer to FIFO pull function. | 
|  | 97 | * @quirks: Set of quirks that apply to specific versions of the IP. | 
| Shashidhar Hiremath | 62ca803 | 2012-01-13 16:04:57 +0530 | [diff] [blame] | 98 | * @irq_flags: The flags to be passed to request_irq. | 
|  | 99 | * @irq: The irq value to be passed to request_irq. | 
| Addy Ke | 7675623 | 2014-11-04 22:03:09 +0800 | [diff] [blame] | 100 | * @sdio_id0: Number of slot0 in the SDIO interrupt registers. | 
| Will Newton | f95f385 | 2011-01-02 01:11:59 -0500 | [diff] [blame] | 101 | * | 
|  | 102 | * Locking | 
|  | 103 | * ======= | 
|  | 104 | * | 
|  | 105 | * @lock is a softirq-safe spinlock protecting @queue as well as | 
|  | 106 | * @cur_slot, @mrq and @state. These must always be updated | 
|  | 107 | * at the same time while holding @lock. | 
|  | 108 | * | 
| Doug Anderson | f8c58c1 | 2014-12-02 15:42:47 -0800 | [diff] [blame] | 109 | * @irq_lock is an irq-safe spinlock protecting the INTMASK register | 
|  | 110 | * to allow the interrupt handler to modify it directly.  Held for only long | 
|  | 111 | * enough to read-modify-write INTMASK and no other locks are grabbed when | 
|  | 112 | * holding this one. | 
|  | 113 | * | 
| Will Newton | f95f385 | 2011-01-02 01:11:59 -0500 | [diff] [blame] | 114 | * The @mrq field of struct dw_mci_slot is also protected by @lock, | 
|  | 115 | * and must always be written at the same time as the slot is added to | 
|  | 116 | * @queue. | 
|  | 117 | * | 
|  | 118 | * @pending_events and @completed_events are accessed using atomic bit | 
|  | 119 | * operations, so they don't need any locking. | 
|  | 120 | * | 
|  | 121 | * None of the fields touched by the interrupt handler need any | 
|  | 122 | * locking. However, ordering is important: Before EVENT_DATA_ERROR or | 
|  | 123 | * EVENT_DATA_COMPLETE is set in @pending_events, all data-related | 
|  | 124 | * interrupts must be disabled and @data_status updated with a | 
|  | 125 | * snapshot of SR. Similarly, before EVENT_CMD_COMPLETE is set, the | 
| Lucas De Marchi | 25985ed | 2011-03-30 22:57:33 -0300 | [diff] [blame] | 126 | * CMDRDY interrupt must be disabled and @cmd_status updated with a | 
| Will Newton | f95f385 | 2011-01-02 01:11:59 -0500 | [diff] [blame] | 127 | * snapshot of SR, and before EVENT_XFER_COMPLETE can be set, the | 
|  | 128 | * bytes_xfered field of @data must be written. This is ensured by | 
|  | 129 | * using barriers. | 
|  | 130 | */ | 
|  | 131 | struct dw_mci { | 
|  | 132 | spinlock_t		lock; | 
| Doug Anderson | f8c58c1 | 2014-12-02 15:42:47 -0800 | [diff] [blame] | 133 | spinlock_t		irq_lock; | 
| Will Newton | f95f385 | 2011-01-02 01:11:59 -0500 | [diff] [blame] | 134 | void __iomem		*regs; | 
|  | 135 |  | 
|  | 136 | struct scatterlist	*sg; | 
| Seungwon Jeon | f9c2a0d | 2012-02-09 14:32:43 +0900 | [diff] [blame] | 137 | struct sg_mapping_iter	sg_miter; | 
| Will Newton | f95f385 | 2011-01-02 01:11:59 -0500 | [diff] [blame] | 138 |  | 
|  | 139 | struct dw_mci_slot	*cur_slot; | 
|  | 140 | struct mmc_request	*mrq; | 
|  | 141 | struct mmc_command	*cmd; | 
|  | 142 | struct mmc_data		*data; | 
| Seungwon Jeon | 90c2143 | 2013-08-31 00:14:05 +0900 | [diff] [blame] | 143 | struct mmc_command	stop_abort; | 
| Seungwon Jeon | 52426899 | 2013-08-31 00:13:42 +0900 | [diff] [blame] | 144 | unsigned int		prev_blksz; | 
| Seungwon Jeon | f1d2736 | 2013-08-31 00:13:55 +0900 | [diff] [blame] | 145 | unsigned char		timing; | 
| Will Newton | f95f385 | 2011-01-02 01:11:59 -0500 | [diff] [blame] | 146 |  | 
|  | 147 | /* DMA interface members*/ | 
|  | 148 | int			use_dma; | 
| James Hogan | 03e8cb5 | 2011-06-29 09:28:43 +0100 | [diff] [blame] | 149 | int			using_dma; | 
| Prabu Thangamuthu | 69d99fd | 2014-10-20 07:12:33 +0000 | [diff] [blame] | 150 | int			dma_64bit_address; | 
| Will Newton | f95f385 | 2011-01-02 01:11:59 -0500 | [diff] [blame] | 151 |  | 
|  | 152 | dma_addr_t		sg_dma; | 
|  | 153 | void			*sg_cpu; | 
| Arnd Bergmann | 8e2b36e | 2012-11-06 22:55:31 +0100 | [diff] [blame] | 154 | const struct dw_mci_dma_ops	*dma_ops; | 
| Will Newton | f95f385 | 2011-01-02 01:11:59 -0500 | [diff] [blame] | 155 | #ifdef CONFIG_MMC_DW_IDMAC | 
|  | 156 | unsigned int		ring_size; | 
|  | 157 | #else | 
|  | 158 | struct dw_mci_dma_data	*dma_data; | 
|  | 159 | #endif | 
|  | 160 | u32			cmd_status; | 
|  | 161 | u32			data_status; | 
|  | 162 | u32			stop_cmdr; | 
|  | 163 | u32			dir_status; | 
|  | 164 | struct tasklet_struct	tasklet; | 
| Will Newton | f95f385 | 2011-01-02 01:11:59 -0500 | [diff] [blame] | 165 | unsigned long		pending_events; | 
|  | 166 | unsigned long		completed_events; | 
|  | 167 | enum dw_mci_state	state; | 
|  | 168 | struct list_head	queue; | 
|  | 169 |  | 
|  | 170 | u32			bus_hz; | 
|  | 171 | u32			current_speed; | 
|  | 172 | u32			num_slots; | 
| Jaehoon Chung | e61cf11 | 2011-03-17 20:32:33 +0900 | [diff] [blame] | 173 | u32			fifoth_val; | 
| Jaehoon Chung | 4e0a5ad | 2011-10-17 19:36:23 +0900 | [diff] [blame] | 174 | u16			verid; | 
|  | 175 | u16			data_offset; | 
| Thomas Abraham | 4a90920 | 2012-09-17 18:16:35 +0000 | [diff] [blame] | 176 | struct device		*dev; | 
| Will Newton | f95f385 | 2011-01-02 01:11:59 -0500 | [diff] [blame] | 177 | struct dw_mci_board	*pdata; | 
| Arnd Bergmann | 8e2b36e | 2012-11-06 22:55:31 +0100 | [diff] [blame] | 178 | const struct dw_mci_drv_data	*drv_data; | 
| Thomas Abraham | 800d78b | 2012-09-17 18:16:42 +0000 | [diff] [blame] | 179 | void			*priv; | 
| Thomas Abraham | f90a061 | 2012-09-17 18:16:38 +0000 | [diff] [blame] | 180 | struct clk		*biu_clk; | 
|  | 181 | struct clk		*ciu_clk; | 
| Will Newton | f95f385 | 2011-01-02 01:11:59 -0500 | [diff] [blame] | 182 | struct dw_mci_slot	*slot[MAX_MCI_SLOTS]; | 
|  | 183 |  | 
|  | 184 | /* FIFO push and pull */ | 
| James Hogan | b86d825 | 2011-06-24 13:57:18 +0100 | [diff] [blame] | 185 | int			fifo_depth; | 
| Will Newton | f95f385 | 2011-01-02 01:11:59 -0500 | [diff] [blame] | 186 | int			data_shift; | 
| James Hogan | 34b664a | 2011-06-24 13:57:56 +0100 | [diff] [blame] | 187 | u8			part_buf_start; | 
|  | 188 | u8			part_buf_count; | 
|  | 189 | union { | 
|  | 190 | u16		part_buf16; | 
|  | 191 | u32		part_buf32; | 
|  | 192 | u64		part_buf; | 
|  | 193 | }; | 
| Will Newton | f95f385 | 2011-01-02 01:11:59 -0500 | [diff] [blame] | 194 | void (*push_data)(struct dw_mci *host, void *buf, int cnt); | 
|  | 195 | void (*pull_data)(struct dw_mci *host, void *buf, int cnt); | 
|  | 196 |  | 
|  | 197 | /* Workaround flags */ | 
|  | 198 | u32			quirks; | 
| Jaehoon Chung | c07946a | 2011-02-25 11:08:14 +0900 | [diff] [blame] | 199 |  | 
| Yuvaraj CD | 51da224 | 2014-08-22 19:17:50 +0530 | [diff] [blame] | 200 | bool			vqmmc_enabled; | 
| Shashidhar Hiremath | 62ca803 | 2012-01-13 16:04:57 +0530 | [diff] [blame] | 201 | unsigned long		irq_flags; /* IRQ flags */ | 
| Seungwon Jeon | d676188 | 2012-09-28 14:21:59 +0900 | [diff] [blame] | 202 | int			irq; | 
| Addy Ke | 7675623 | 2014-11-04 22:03:09 +0800 | [diff] [blame] | 203 |  | 
|  | 204 | int			sdio_id0; | 
| Will Newton | f95f385 | 2011-01-02 01:11:59 -0500 | [diff] [blame] | 205 | }; | 
|  | 206 |  | 
|  | 207 | /* DMA ops for Internal/External DMAC interface */ | 
|  | 208 | struct dw_mci_dma_ops { | 
|  | 209 | /* DMA Ops */ | 
|  | 210 | int (*init)(struct dw_mci *host); | 
|  | 211 | void (*start)(struct dw_mci *host, unsigned int sg_len); | 
|  | 212 | void (*complete)(struct dw_mci *host); | 
|  | 213 | void (*stop)(struct dw_mci *host); | 
|  | 214 | void (*cleanup)(struct dw_mci *host); | 
|  | 215 | void (*exit)(struct dw_mci *host); | 
|  | 216 | }; | 
|  | 217 |  | 
|  | 218 | /* IP Quirks/flags. */ | 
| Will Newton | f95f385 | 2011-01-02 01:11:59 -0500 | [diff] [blame] | 219 | /* DTO fix for command transmission with IDMAC configured */ | 
| Jaehoon Chung | fc3d772 | 2011-02-25 11:08:15 +0900 | [diff] [blame] | 220 | #define DW_MCI_QUIRK_IDMAC_DTO			BIT(0) | 
| Will Newton | f95f385 | 2011-01-02 01:11:59 -0500 | [diff] [blame] | 221 | /* delay needed between retries on some 2.11a implementations */ | 
| Jaehoon Chung | fc3d772 | 2011-02-25 11:08:15 +0900 | [diff] [blame] | 222 | #define DW_MCI_QUIRK_RETRY_DELAY		BIT(1) | 
| Lucas De Marchi | 25985ed | 2011-03-30 22:57:33 -0300 | [diff] [blame] | 223 | /* High Speed Capable - Supports HS cards (up to 50MHz) */ | 
| Jaehoon Chung | fc3d772 | 2011-02-25 11:08:15 +0900 | [diff] [blame] | 224 | #define DW_MCI_QUIRK_HIGHSPEED			BIT(2) | 
|  | 225 | /* Unreliable card detection */ | 
|  | 226 | #define DW_MCI_QUIRK_BROKEN_CARD_DETECTION	BIT(3) | 
| Jaehoon Chung | 26375b5 | 2014-08-07 16:37:58 +0900 | [diff] [blame] | 227 | /* No write protect */ | 
|  | 228 | #define DW_MCI_QUIRK_NO_WRITE_PROTECT		BIT(4) | 
| Doug Anderson | a70aaa6 | 2013-01-11 17:03:50 +0000 | [diff] [blame] | 229 |  | 
| Doug Anderson | a70aaa6 | 2013-01-11 17:03:50 +0000 | [diff] [blame] | 230 | /* Slot level quirks */ | 
|  | 231 | /* This slot has no write protect */ | 
|  | 232 | #define DW_MCI_SLOT_QUIRK_NO_WRITE_PROTECT	BIT(0) | 
|  | 233 |  | 
| Will Newton | f95f385 | 2011-01-02 01:11:59 -0500 | [diff] [blame] | 234 | struct dma_pdata; | 
|  | 235 |  | 
|  | 236 | struct block_settings { | 
|  | 237 | unsigned short	max_segs;	/* see blk_queue_max_segments */ | 
|  | 238 | unsigned int	max_blk_size;	/* maximum size of one mmc block */ | 
|  | 239 | unsigned int	max_blk_count;	/* maximum number of blocks in one req*/ | 
|  | 240 | unsigned int	max_req_size;	/* maximum number of bytes in one req*/ | 
|  | 241 | unsigned int	max_seg_size;	/* see blk_queue_max_segment_size */ | 
|  | 242 | }; | 
|  | 243 |  | 
|  | 244 | /* Board platform data */ | 
|  | 245 | struct dw_mci_board { | 
|  | 246 | u32 num_slots; | 
|  | 247 |  | 
|  | 248 | u32 quirks; /* Workaround / Quirk flags */ | 
| Thomas Abraham | c366500 | 2012-09-17 18:16:43 +0000 | [diff] [blame] | 249 | unsigned int bus_hz; /* Clock speed at the cclk_in pad */ | 
| Will Newton | f95f385 | 2011-01-02 01:11:59 -0500 | [diff] [blame] | 250 |  | 
| Lee Jones | 5f1a4dd | 2012-11-14 12:35:51 +0000 | [diff] [blame] | 251 | u32 caps;	/* Capabilities */ | 
|  | 252 | u32 caps2;	/* More capabilities */ | 
| Abhilash Kesavan | ab26912 | 2012-11-19 10:26:21 +0530 | [diff] [blame] | 253 | u32 pm_caps;	/* PM capabilities */ | 
| James Hogan | b86d825 | 2011-06-24 13:57:18 +0100 | [diff] [blame] | 254 | /* | 
|  | 255 | * Override fifo depth. If 0, autodetect it from the FIFOTH register, | 
|  | 256 | * but note that this may not be reliable after a bootloader has used | 
|  | 257 | * it. | 
|  | 258 | */ | 
|  | 259 | unsigned int fifo_depth; | 
| Jaehoon Chung | fc3d772 | 2011-02-25 11:08:15 +0900 | [diff] [blame] | 260 |  | 
| Will Newton | f95f385 | 2011-01-02 01:11:59 -0500 | [diff] [blame] | 261 | /* delay in mS before detecting cards after interrupt */ | 
|  | 262 | u32 detect_delay_ms; | 
|  | 263 |  | 
| Will Newton | f95f385 | 2011-01-02 01:11:59 -0500 | [diff] [blame] | 264 | struct dw_mci_dma_ops *dma_ops; | 
|  | 265 | struct dma_pdata *data; | 
|  | 266 | struct block_settings *blk_settings; | 
|  | 267 | }; | 
|  | 268 |  | 
| Robert P. J. Day | 100e918 | 2011-05-27 16:04:03 -0400 | [diff] [blame] | 269 | #endif /* LINUX_MMC_DW_MMC_H */ |