aboutsummaryrefslogtreecommitdiff
path: root/arch/arm/mach-ux500/include/mach/mmc.h
blob: 90217c92a8f47ca621edc23fc666b4ef8d5f5a42 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
/*
 * Overview:
 *  	 SD/EMMC driver for u8500 platform
 *
 * Copyright (C) 2009 ST-Ericsson SA
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 */

/*-------------------------------------------------------------------------
 * SDI controller configuration
 * Kernel entry point for sdmmc/emmc chip
 *-------------------------------------------------------------------------
 * <VERSION>v1.0.0
 *-------------------------------------------------------------------------
 */
/*------------------------------i-----------------------------------------*/
#ifndef MACH_MMC_H
#define MACH_MMC_H

/*
 * SDI Power register offset
 */
#define MMCIPOWER		0x000
/*
 * SDI Power register bits
 */
#define MCI_PWR_OFF		0x00
#define MCI_PWR_UP		0x02
#define MCI_PWR_ON		0x03
#define MCI_STATE_ENABLE	0x38
#define MCI_OPEN_DRAIN		(1 << 6)
#define MCI_FBCLK_ENABLE	(1 << 7)
#define MCI_POWER_IOS_MASK	\
	(MCI_PWR_ON | MCI_DIREN_CMD | MCI_DIREN_DAT0 | MCI_DIREN_DAT2 | \
	 MCI_DIREN_DAT31 | MCI_DIREN_DAT74 | MCI_OPEN_DRAIN)
#define MCI_DIREN_CMD		(1<<3)
#define MCI_DIREN_DAT0		(1<<4)
#define MCI_DIREN_DAT2		(1<<2)
#define MCI_DIREN_DAT31		(1<<5)
#define MCI_DIREN_DAT74		(1<<8)
#define MCI_DIREN_1BIT		(MCI_DIREN_CMD|MCI_DIREN_DAT0)
#define MCI_DIREN_4BIT		(MCI_DIREN_CMD|MCI_DIREN_DAT0|MCI_DIREN_DAT31)
/* #define MCI_DIREN_8BIT	(MCI_DIREN_CMD|MCI_DIREN_DAT0|MCI_DIREN_DAT31)*/
#define MCI_DIREN_BIT		(MCI_DIREN_CMD|MCI_DIREN_DAT0|MCI_DIREN_DAT31|\
				 MCI_DIREN_DAT2|MCI_DIREN_DAT74)
/*
 * SDI Clock register offset
 */
#define MMCICLOCK		0x004
/*
 * SDI Power register bits
 */
#define MCI_CLK_ENABLE		(1 << 8)
#define MCI_CLK_PWRSAVE		(1 << 9)
#define MCI_CLK_BYPASS		(1 << 10)
#define MCI_BUS_WIDTH_1		(0 << 11)
#define MCI_BUS_WIDTH_4		(1 << 11)
#define MCI_BUS_WIDTH_8		(2 << 11)
#define MCI_HWFC_EN		(1 << 14)
#define MCI_NEG_EDGE            (1 << 13)
/*
 * SDI Arguement register offset
 */
#define MMCIARGUMENT		0x008
/*
 * SDI Command register offset
 */
#define MMCICOMMAND		0x00c
/*
 * SDI command register bits
 */
#define MCI_CPSM_RESPONSE	(1 << 6)
#define MCI_CPSM_LONGRSP	(1 << 7)
#define MCI_CPSM_INTERRUPT	(1 << 8)
#define MCI_CPSM_PENDING	(1 << 9)
#define MCI_CPSM_ENABLE		(1 << 10)

/*
 * SDI RespCMD register offset
 */
#define MMCIRESPCMD		0x010
/*
 * SDI Response0 register offset
 */
#define MMCIRESPONSE0		0x014
/*
 * SDI Response1 register offset
 */
#define MMCIRESPONSE1		0x018
/*
 * SDI Response2 register offset
 */
#define MMCIRESPONSE2		0x01c
/*
 * SDI Response3 register offset
 */
#define MMCIRESPONSE3		0x020
/*
 * SDI Datatimer register offset
 */
#define MMCIDATATIMER		0x024
/*
 * SDI DataLength register offset
 */
#define MMCIDATALENGTH		0x028
/*
 * SDI Data control register offset
 */
#define MMCIDATACTRL		0x02c
/*
 * SDI Data control register bits
 */
#define MCI_DPSM_ENABLE		(1 << 0)
#define MCI_DPSM_DIRECTION	(1 << 1)
#define MCI_DPSM_MODE		(1 << 2)
#define MCI_DPSM_DMAENABLE	(1 << 3)
#define MCI_DPSM_DMAreqctl	(1 << 12)
#define MCI_SDIO_ENABLE		(1 << 11)

/*
 * SDI Data Count register offset
 */
#define MMCIDATACNT		0x030
/*
 * SDI Status register offset
 */
#define MMCISTATUS		0x034
/*
 * SDI Status register bits
 */
#define MCI_CMDCRCFAIL		(1 << 0)
#define MCI_DATACRCFAIL		(1 << 1)
#define MCI_CMDTIMEOUT		(1 << 2)
#define MCI_DATATIMEOUT		(1 << 3)
#define MCI_TXUNDERRUN		(1 << 4)
#define MCI_RXOVERRUN		(1 << 5)
#define MCI_CMDRESPEND		(1 << 6)
#define MCI_CMDSENT		(1 << 7)
#define MCI_DATAEND		(1 << 8)
#define MCI_STBITERR	 	(1 << 9)
#define MCI_DATABLOCKEND	(1 << 10)
#define MCI_CMDACTIVE		(1 << 11)
#define MCI_TXACTIVE		(1 << 12)
#define MCI_RXACTIVE		(1 << 13)
#define MCI_TXFIFOHALFEMPTY	(1 << 14)
#define MCI_RXFIFOHALFFULL	(1 << 15)
#define MCI_TXFIFOFULL		(1 << 16)
#define MCI_RXFIFOFULL		(1 << 17)
#define MCI_TXFIFOEMPTY		(1 << 18)
#define MCI_RXFIFOEMPTY		(1 << 19)
#define MCI_TXDATAAVLBL		(1 << 20)
#define MCI_RXDATAAVLBL		(1 << 21)
#define MCI_SDIOIT		(1 << 22)
/*
 * SDI Clear register offset
 */
#define MMCICLEAR		0x038
#define MCI_CMDCRCFAILCLR	(1 << 0)
#define MCI_DATACRCFAILCLR	(1 << 1)
#define MCI_CMDTIMEOUTCLR	(1 << 2)
#define MCI_DATATIMEOUTCLR	(1 << 3)
#define MCI_TXUNDERRUNCLR	(1 << 4)
#define MCI_RXOVERRUNCLR	(1 << 5)
#define MCI_CMDRESPENDCLR	(1 << 6)
#define MCI_CMDSENTCLR		(1 << 7)
#define MCI_DATAENDCLR		(1 << 8)
#define MCI_DATABLOCKENDCLR	(1 << 10)
#define MCI_SDIOITCLR		(1 << 22)
/*
 * SDI Mask register offset
 */
#define MMCIMASK0		0x03c
/*
 * SDI Mask register bits
 */
#define MCI_CMDCRCFAILMASK	(1 << 0)
#define MCI_DATACRCFAILMASK	(1 << 1)
#define MCI_CMDTIMEOUTMASK	(1 << 2)
#define MCI_DATATIMEOUTMASK	(1 << 3)
#define MCI_TXUNDERRUNMASK	(1 << 4)
#define MCI_RXOVERRUNMASK	(1 << 5)
#define MCI_CMDRESPENDMASK	(1 << 6)
#define MCI_CMDSENTMASK		(1 << 7)
#define MCI_DATAENDMASK		(1 << 8)
#define MCI_DATABLOCKENDMASK	(1 << 10)
#define MCI_CMDACTIVEMASK	(1 << 11)
#define MCI_TXACTIVEMASK	(1 << 12)
#define MCI_RXACTIVEMASK	(1 << 13)
#define MCI_TXFIFOHALFEMPTYMASK	(1 << 14)
#define MCI_RXFIFOHALFFULLMASK	(1 << 15)
#define MCI_TXFIFOFULLMASK	(1 << 16)
#define MCI_RXFIFOFULLMASK	(1 << 17)
#define MCI_TXFIFOEMPTYMASK	(1 << 18)
#define MCI_RXFIFOEMPTYMASK	(1 << 19)
#define MCI_TXDATAAVLBLMASK	(1 << 20)
#define MCI_RXDATAAVLBLMASK	(1 << 21)
#define MCI_SDIOITMASK		(1 << 22)

#define MMCIMASK1		0x040
#define MMCIFIFOCNT		0x048
#define MMCIFIFO		0x080	/* to 0x0bc */

#define MCI_DATA_ERR	\
			(MCI_RXOVERRUN | MCI_TXUNDERRUN | MCI_DATATIMEOUT | \
			 MCI_DATACRCFAIL | MCI_STBITERR)
#define MCI_IRQENABLE	\
			(MCI_CMDCRCFAIL | MCI_DATACRCFAIL | MCI_CMDTIMEOUT | \
			 MCI_DATATIMEOUT | MCI_TXUNDERRUN | MCI_RXOVERRUN | \
			 MCI_CMDRESPEND | MCI_CMDSENT | MCI_DATABLOCKEND)
#define MCI_DATA_IRQ (MCI_DATA_ERR | MCI_DATAEND)
#define MCI_XFER_IRQ_MASK \
			(MCI_TXFIFOEMPTY | MCI_TXFIFOHALFEMPTY | \
			 MCI_RXFIFOHALFFULL | MCI_RXDATAAVLBL)
#define MCI_CMD_IRQ \
			(MCI_CMDCRCFAIL | MCI_CMDTIMEOUT | MCI_CMDRESPEND | \
			 MCI_CMDSENT)
#define MCI_XFER_IRQ \
			(MCI_TXFIFOHALFEMPTY | MCI_RXFIFOHALFFULL)

/*
 * The size of the FIFO in bytes.
 */
#define MCI_FIFOSIZE	16
#define MCI_FIFOHALFSIZE (MCI_FIFOSIZE / 2)
#define NR_SG		16

#define OCR_AVAIL	(MMC_VDD_17_18 | MMC_VDD_18_19 | \
			/*MMC_VDD_28_29 |*/ \
			MMC_VDD_29_30 | MMC_VDD_30_31 | MMC_VDD_32_33 | \
			 MMC_VDD_33_34)
#define INVALID_PIPEID	(-1)

/**
 * struct u8500_mmci_host - host device structure
 * @base:	pointer to the device baseaddress
 * @mrq:	pointer to the request structure
 * @cmd:        pointer to the command structure
 * @data:       pointer to the data structure
 * @mmc:        pointer to the mmc_host structure
 * @clk:        pointer to the clock structure
 * @data_xfered: variable which updates the data_transfered
 * @lock:      spinlock variable
 * @sg_ptr:    scatter list pointer
 * @mclk:      master clock
 * @cclk:      card clock
 * @card_detect_intr_value: callback for the carddetection
 * @oldstat: card detection value
 * @dmach_mmc2mem: dma pipeid card to memory
 * @dmach_mem2mmc: dma pipeid from memory to card
 * @dma_fifo_addr: dma fifo address
 * @dma_fifo_dev_type_rx: rx channel number
 * @dma_fifo_dev_type_tx: tx channel number
 * @level_shifter: variable for checking level shifter
 * @dma: ponter to dma_addr_t structure
 * @caps: host capabilities
 * @sg_len: scatter gather length
 * @sg_off: offset address
 * @size: data size
 * @buffer: buffer used in polling mode
 * @dma_buffer: buffer used in dma mode
 * @dma_done: variable for dma completion
 * @devicemode: variable for device mode
 * @is_sdio: variable for sdio
 * @board: pointer to the board structure
 * @regulator: pointer to the regulator structure
 * @sdio_setirq: set irq status for SDIO
 * @sdio_irqstatus: current irq status for SDIO
 * @aligned_blksz: aligned block size value for SDIO
 * @aligned_size: aligned size value for SDIO
 * @reg_context: array to store register context
 *
 * host controller Internal device structure
 */
struct u8500_mmci_host {
	void __iomem *base;
	struct mmc_request *mrq;
	struct mmc_command *cmd;
	struct mmc_data *data;
	struct mmc_host *mmc;
	struct clk *clk;
#ifdef CONFIG_REGULATOR
	struct regulator *regulator;
#endif
	unsigned int data_xfered;
	spinlock_t lock;
	unsigned int mclk;
	unsigned int cclk;
	int (*card_detect_intr_value) (void);
	unsigned int oldstat;
	unsigned int dmach_mmc2mem;
	unsigned int dmach_mem2mmc;
	unsigned int dma_fifo_addr;
	unsigned int dma_fifo_dev_type_rx;
	unsigned int dma_fifo_dev_type_tx;
	unsigned int level_shifter;
	dma_addr_t dma;
	unsigned long	caps;		/* Host capabilities */
	unsigned int sg_len;
	/* pio stuff */
	struct scatterlist *sg_ptr;
	unsigned int sg_off;
	unsigned int size;
	unsigned int *buffer;
	unsigned int *dma_buffer;
	void *dma_done;	/* completion data */
	int devicemode;
	unsigned int is_sdio;
	int sdio_setirq;
	int sdio_irqstatus;
	int aligned_blksz;
	int aligned_size;
	struct mmc_board *board;
	unsigned long reg_context[2];
};

/* Define the current mode  */
#define MCI_DMAMODE 		0x01
#define MCI_POLLINGMODE		0x02
#define MCI_INTERRUPTMODE	0x03
#define MCI_ALLINTERRUPTS	(0x007FFFFF)
#define MMCCLRSTATICFLAGS	(0x000007FF)
#define MCI_MAXVOLTTRIAL	(200)	/* 200 times */
#define MAX_FREQ (24000000)
#define MAX_DATA (64*512)
#define CLK_MAX	50000000
#define CLK_DIV 0xFF
/*
 * different card states
 */
enum card_state {
	CARD_STATE_EMPTY = -1,
	CARD_STATE_IDLE,
	CARD_STATE_READY,
	CARD_STATE_IDENT,
	CARD_STATE_STBY,
	CARD_STATE_TRAN,
	CARD_STATE_DATA,
	CARD_STATE_RCV,
	CARD_STATE_PRG,
	CARD_STATE_DIS,
};
/*
 * struct mmc_board -  mmc board dependent  structure
 * @init:	function pointer for mmc board related initialization
 * @exit:	function pointer for mmc board related de-initialization
 *
 * SDMMC platfoem dependent structure
 */
struct mmc_board {
	int (*init) (struct amba_device *dev);
	void (*exit) (struct amba_device *dev);
	int (*set_power) (struct device *dev, int power_on);
	int (*card_detect)(void (*callback)(void *parameter), void *);
	int (*card_detect_intr_value) (void);
	unsigned int dma_fifo_addr;
	unsigned int dma_fifo_dev_type_rx;
	unsigned int dma_fifo_dev_type_tx;
	unsigned int level_shifter;
	unsigned long	caps;	/* Host capabilities */
	int is_sdio;		/* To check if the bus is SD/MMC or sdio */
#ifdef CONFIG_REGULATOR
	const char *supply;
#endif
};

#endif