aboutsummaryrefslogtreecommitdiff
path: root/drivers/mmc/host/msm_sdcc.h
blob: 402028d16b86836171a5c4a1c43ff7eea2ab8bb4 (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
/*
 *  linux/drivers/mmc/host/msmsdcc.h - QCT MSM7K SDC Controller
 *
 *  Copyright (C) 2008 Google, All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * - Based on mmci.h
 */

#ifndef _MSM_SDCC_H
#define _MSM_SDCC_H

#define MSMSDCC_CRCI_SDC1	6
#define MSMSDCC_CRCI_SDC2	7
#define MSMSDCC_CRCI_SDC3	12
#define MSMSDCC_CRCI_SDC4	13

#define MMCIPOWER		0x000
#define MCI_PWR_OFF		0x00
#define MCI_PWR_UP		0x02
#define MCI_PWR_ON		0x03
#define MCI_OD			(1 << 6)

#define MMCICLOCK		0x004
#define MCI_CLK_ENABLE		(1 << 8)
#define MCI_CLK_PWRSAVE		(1 << 9)
#define MCI_CLK_WIDEBUS		(1 << 10)
#define MCI_CLK_FLOWENA		(1 << 12)
#define MCI_CLK_INVERTOUT	(1 << 13)
#define MCI_CLK_SELECTIN	(1 << 14)

#define MMCIARGUMENT		0x008
#define MMCICOMMAND		0x00c
#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)
#define MCI_CPSM_PROGENA	(1 << 11)
#define MCI_CSPM_DATCMD		(1 << 12)
#define MCI_CSPM_MCIABORT	(1 << 13)
#define MCI_CSPM_CCSENABLE	(1 << 14)
#define MCI_CSPM_CCSDISABLE	(1 << 15)


#define MMCIRESPCMD		0x010
#define MMCIRESPONSE0		0x014
#define MMCIRESPONSE1		0x018
#define MMCIRESPONSE2		0x01c
#define MMCIRESPONSE3		0x020
#define MMCIDATATIMER		0x024
#define MMCIDATALENGTH		0x028

#define MMCIDATACTRL		0x02c
#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 MMCIDATACNT		0x030
#define MMCISTATUS		0x034
#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_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_SDIOINTR		(1 << 22)
#define MCI_PROGDONE		(1 << 23)
#define MCI_ATACMDCOMPL		(1 << 24)
#define MCI_SDIOINTOPER		(1 << 25)
#define MCI_CCSTIMEOUT		(1 << 26)

#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 MMCIMASK0		0x03c
#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_SDIOINTMASK		(1 << 22)
#define MCI_PROGDONEMASK	(1 << 23)
#define MCI_ATACMDCOMPLMASK	(1 << 24)
#define MCI_SDIOINTOPERMASK	(1 << 25)
#define MCI_CCSTIMEOUTMASK	(1 << 26)

#define MMCIMASK1		0x040
#define MMCIFIFOCNT		0x044
#define MCICCSTIMER		0x058

#define MMCIFIFO		0x080 /* to 0x0bc */

#define MCI_IRQENABLE	\
	(MCI_CMDCRCFAILMASK|MCI_DATACRCFAILMASK|MCI_CMDTIMEOUTMASK|	\
	MCI_DATATIMEOUTMASK|MCI_TXUNDERRUNMASK|MCI_RXOVERRUNMASK|	\
	MCI_CMDRESPENDMASK|MCI_CMDSENTMASK|MCI_DATAENDMASK|MCI_PROGDONEMASK)

#define MCI_IRQ_PIO \
	(MCI_RXDATAAVLBLMASK | MCI_TXDATAAVLBLMASK | MCI_RXFIFOEMPTYMASK | \
	 MCI_TXFIFOEMPTYMASK | MCI_RXFIFOFULLMASK | MCI_TXFIFOFULLMASK | \
	 MCI_RXFIFOHALFFULLMASK | MCI_TXFIFOHALFEMPTYMASK | \
	 MCI_RXACTIVEMASK | MCI_TXACTIVEMASK)
/*
 * The size of the FIFO in bytes.
 */
#define MCI_FIFOSIZE	(16*4)

#define MCI_FIFOHALFSIZE (MCI_FIFOSIZE / 2)

#define NR_SG		32

struct clk;

struct msmsdcc_nc_dmadata {
	dmov_box	cmd[NR_SG];
	uint32_t	cmdptr;
};

struct msmsdcc_dma_data {
	struct msmsdcc_nc_dmadata	*nc;
	dma_addr_t			nc_busaddr;
	dma_addr_t			cmd_busaddr;
	dma_addr_t			cmdptr_busaddr;

	struct msm_dmov_cmd		hdr;
	enum dma_data_direction		dir;

	struct scatterlist		*sg;
	int				num_ents;

	int				channel;
	struct msmsdcc_host		*host;
	int				busy; /* Set if DM is busy */
	int				active;
	unsigned int			result;
	struct msm_dmov_errdata		err;
};

struct msmsdcc_pio_data {
	struct scatterlist	*sg;
	unsigned int		sg_len;
	unsigned int		sg_off;
};

struct msmsdcc_curr_req {
	struct mmc_request	*mrq;
	struct mmc_command	*cmd;
	struct mmc_data		*data;
	unsigned int		xfer_size;	/* Total data size */
	unsigned int		xfer_remain;	/* Bytes remaining to send */
	unsigned int		data_xfered;	/* Bytes acked by BLKEND irq */
	int			got_dataend;
	int			user_pages;
};

struct msmsdcc_stats {
	unsigned int reqs;
	unsigned int cmds;
	unsigned int cmdpoll_hits;
	unsigned int cmdpoll_misses;
};

struct msmsdcc_host {
	struct resource		*cmd_irqres;
	struct resource		*memres;
	struct resource		*dmares;
	void __iomem		*base;
	int			pdev_id;
	unsigned int		stat_irq;

	struct msmsdcc_curr_req	curr;

	struct mmc_host		*mmc;
	struct clk		*clk;		/* main MMC bus clock */
	struct clk		*pclk;		/* SDCC peripheral bus clock */
	unsigned int		clks_on;	/* set if clocks are enabled */
	struct timer_list	busclk_timer;

	unsigned int		eject;		/* eject state */

	spinlock_t		lock;

	unsigned int		clk_rate;	/* Current clock rate */
	unsigned int		pclk_rate;

	u32			pwr;
	u32			saved_irq0mask;	/* MMCIMASK0 reg value */
	struct msm_mmc_platform_data *plat;

	struct timer_list	timer;
	unsigned int		oldstat;

	struct msmsdcc_dma_data	dma;
	struct msmsdcc_pio_data	pio;
	int			cmdpoll;
	struct msmsdcc_stats	stats;

	struct tasklet_struct	dma_tlet;
	/* Command parameters */
	unsigned int		cmd_timeout;
	unsigned int		cmd_pio_irqmask;
	unsigned int		cmd_datactrl;
	struct mmc_command	*cmd_cmd;
	u32			cmd_c;
	bool			gpio_config_status;

	bool prog_scan;
	bool prog_enable;
};

#endif