diff options
author | Rafaël Carré <rafael.carre@gmail.com> | 2008-10-29 20:21:59 +0000 |
---|---|---|
committer | Rafaël Carré <rafael.carre@gmail.com> | 2008-10-29 20:21:59 +0000 |
commit | e1b483848120507a909e95417e938324ed377bd5 (patch) | |
tree | 3496098d3d781071cde64b165bfa77951835c186 /firmware/target/arm | |
parent | 4c457afe899b32f74cfa761b5bd078a296a75251 (diff) | |
download | rockbox-e1b483848120507a909e95417e938324ed377bd5.tar.gz rockbox-e1b483848120507a909e95417e938324ed377bd5.zip |
Embryo of a SD driver for Sansav2
Debug code included, needed until the bootloader is ready
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@18926 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm')
-rw-r--r-- | firmware/target/arm/as3525/ata_sd_as3525.c | 341 | ||||
-rw-r--r-- | firmware/target/arm/as3525/mmci.h | 123 |
2 files changed, 464 insertions, 0 deletions
diff --git a/firmware/target/arm/as3525/ata_sd_as3525.c b/firmware/target/arm/as3525/ata_sd_as3525.c new file mode 100644 index 0000000000..e8f899bc37 --- /dev/null +++ b/firmware/target/arm/as3525/ata_sd_as3525.c | |||
@@ -0,0 +1,341 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright © 2008 Rafaël Carré | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | /* Driver for the ARM PL180 SD/MMC controller inside AS3525 SoC */ | ||
23 | |||
24 | #include "config.h" /* for HAVE_MULTIVOLUME */ | ||
25 | |||
26 | #include "as3525.h" | ||
27 | #include "mmci.h" | ||
28 | #include "panic.h" | ||
29 | #include "stdbool.h" | ||
30 | #include "ata.h" | ||
31 | |||
32 | #define NAND_AS3525 0 | ||
33 | #define SD_AS3525 1 | ||
34 | static int pl180_base[2] = { NAND_FLASH_BASE, SD_MCI_BASE }; | ||
35 | |||
36 | /* ARM PL180 registers */ | ||
37 | #define MMC_POWER(i) (*(volatile unsigned long *) (pl180_base[i]+0x00)) | ||
38 | #define MMC_CLOCK(i) (*(volatile unsigned long *) (pl180_base[i]+0x04)) | ||
39 | #define MMC_ARGUMENT(i) (*(volatile unsigned long *) (pl180_base[i]+0x08)) | ||
40 | #define MMC_COMMAND(i) (*(volatile unsigned long *) (pl180_base[i]+0x0C)) | ||
41 | #define MMC_RESPCMD(i) (*(volatile unsigned long *) (pl180_base[i]+0x10)) | ||
42 | #define MMC_RESP0(i) (*(volatile unsigned long *) (pl180_base[i]+0x14)) | ||
43 | #define MMC_RESP1(i) (*(volatile unsigned long *) (pl180_base[i]+0x18)) | ||
44 | #define MMC_RESP2(i) (*(volatile unsigned long *) (pl180_base[i]+0x1C)) | ||
45 | #define MMC_RESP3(i) (*(volatile unsigned long *) (pl180_base[i]+0x20)) | ||
46 | #define MMC_DATACTRL(i) (*(volatile unsigned long *) (pl180_base[i]+0x2C)) | ||
47 | #define MMC_STATUS(i) (*(volatile unsigned long *) (pl180_base[i]+0x34)) | ||
48 | #define MMC_CLEAR(i) (*(volatile unsigned long *) (pl180_base[i]+0x38)) | ||
49 | #define MMC_MASK0(i) (*(volatile unsigned long *) (pl180_base[i]+0x3C)) | ||
50 | #define MMC_MASK1(i) (*(volatile unsigned long *) (pl180_base[i]+0x40)) | ||
51 | #define MMC_SELECT(i) (*(volatile unsigned long *) (pl180_base[i]+0x44)) | ||
52 | |||
53 | |||
54 | /* SD commands */ | ||
55 | #define GO_IDLE_STATE 0 | ||
56 | #define MMC_CMD_READ_CID 2 | ||
57 | #define SEND_IF_COND 8 | ||
58 | #define SEND_OP_COND 41 | ||
59 | #define APP_CMD 55 | ||
60 | |||
61 | /* command flags */ | ||
62 | #define MMC_NO_FLAGS (0<<0) | ||
63 | #define MMC_RESP (1<<0) | ||
64 | #define MMC_LONG_RESP (1<<1) | ||
65 | #define MMC_ARG (1<<2) | ||
66 | |||
67 | #ifdef BOOTLOADER | ||
68 | #define DEBUG | ||
69 | void reset_screen(void); | ||
70 | void printf(const char *format, ...); | ||
71 | #endif | ||
72 | |||
73 | struct mmc_command | ||
74 | { | ||
75 | int cmd; | ||
76 | int arg; | ||
77 | int resp[4]; | ||
78 | int flags; | ||
79 | }; | ||
80 | |||
81 | static inline void mci_delay(void) { int i = 0xffff; while(i--) ; } | ||
82 | |||
83 | static void mci_set_clock_divider(const int drive, int divider) | ||
84 | { | ||
85 | int clock = MMC_CLOCK(drive); | ||
86 | |||
87 | if(divider > 1) | ||
88 | { | ||
89 | /* use divide logic */ | ||
90 | clock &= ~MCI_CLK_BYPASS; | ||
91 | |||
92 | /* convert divider to MMC_CLOCK logic */ | ||
93 | divider = (divider/2) - 1; | ||
94 | if(divider >= 256) | ||
95 | divider = 255; | ||
96 | } | ||
97 | else | ||
98 | { | ||
99 | /* bypass dividing logic */ | ||
100 | clock |= MCI_CLK_BYPASS; | ||
101 | divider = 0; | ||
102 | } | ||
103 | |||
104 | MMC_CLOCK(drive) = clock | divider; | ||
105 | |||
106 | mci_delay(); | ||
107 | } | ||
108 | |||
109 | static int send_cmd(const int drive, struct mmc_command *cmd) | ||
110 | { | ||
111 | int val, status; | ||
112 | |||
113 | while(MMC_STATUS(drive) & MCI_CMDACTIVE); /* useless */ | ||
114 | |||
115 | if(MMC_COMMAND(drive) & MCI_CPSM_ENABLE) /* clears existing command */ | ||
116 | { | ||
117 | MMC_COMMAND(drive) = 0; | ||
118 | mci_delay(); | ||
119 | } | ||
120 | |||
121 | val = cmd->cmd | MCI_CPSM_ENABLE; | ||
122 | if(cmd->flags & MMC_RESP) | ||
123 | { | ||
124 | val |= MCI_CPSM_RESPONSE; | ||
125 | if(cmd->flags & MMC_LONG_RESP) | ||
126 | val |= MCI_CPSM_LONGRSP; | ||
127 | } | ||
128 | |||
129 | MMC_CLEAR(drive) = 0x7ff; | ||
130 | |||
131 | MMC_ARGUMENT(drive) = (cmd->flags & MMC_ARG) ? cmd->arg : 0; | ||
132 | MMC_COMMAND(drive) = val; | ||
133 | |||
134 | while(MMC_STATUS(drive) & MCI_CMDACTIVE); | ||
135 | |||
136 | MMC_COMMAND(drive) = 0; | ||
137 | MMC_ARGUMENT(drive) = ~0; | ||
138 | |||
139 | do | ||
140 | { | ||
141 | status = MMC_STATUS(drive); | ||
142 | if(cmd->flags & MMC_RESP) | ||
143 | { | ||
144 | if(status & MCI_CMDTIMEOUT) | ||
145 | { | ||
146 | if(cmd->cmd == SEND_IF_COND) | ||
147 | break; /* SDHC test can fail */ | ||
148 | panicf("Response timeout"); | ||
149 | } | ||
150 | else if(status & (MCI_CMDCRCFAIL|MCI_CMDRESPEND)) | ||
151 | { /* resp received */ | ||
152 | cmd->resp[0] = MMC_RESP0(drive); | ||
153 | if(cmd->flags & MMC_LONG_RESP) | ||
154 | { | ||
155 | cmd->resp[1] = MMC_RESP1(drive); | ||
156 | cmd->resp[2] = MMC_RESP2(drive); | ||
157 | cmd->resp[3] = MMC_RESP3(drive); | ||
158 | } | ||
159 | break; | ||
160 | } | ||
161 | } | ||
162 | else | ||
163 | if(status & MCI_CMDSENT) | ||
164 | break; | ||
165 | |||
166 | } while(1); | ||
167 | |||
168 | MMC_CLEAR(drive) = 0x7ff; | ||
169 | return status; | ||
170 | } | ||
171 | |||
172 | static void sd_init_card(const int drive) | ||
173 | { | ||
174 | struct mmc_command cmd_app, cmd_op_cond, cmd_idle, cmd_if_cond; | ||
175 | int status; | ||
176 | bool sdhc; | ||
177 | |||
178 | #ifdef DEBUG | ||
179 | reset_screen(); | ||
180 | printf("now - powered up"); | ||
181 | #endif | ||
182 | |||
183 | cmd_idle.cmd = GO_IDLE_STATE; | ||
184 | cmd_idle.arg = 0; | ||
185 | cmd_idle.flags = MMC_NO_FLAGS; | ||
186 | if(send_cmd(drive, &cmd_idle) != MCI_CMDSENT) | ||
187 | panicf("goto idle failed!"); | ||
188 | #ifdef DEBUG | ||
189 | else | ||
190 | printf("now - idle"); | ||
191 | #endif | ||
192 | |||
193 | mci_delay(); | ||
194 | |||
195 | cmd_if_cond.cmd = SEND_IF_COND; | ||
196 | cmd_if_cond.arg = (1 /* 2.7-3.6V */ << 8) | 0xAA /* check pattern */; | ||
197 | cmd_if_cond.flags = MMC_RESP | MMC_ARG; | ||
198 | |||
199 | cmd_app.cmd = APP_CMD; | ||
200 | cmd_app.flags = MMC_RESP | MMC_ARG; | ||
201 | cmd_app.arg = 0; /* 31:16 RCA (0) , 15:0 stuff bits */ | ||
202 | |||
203 | cmd_op_cond.cmd = SEND_OP_COND; | ||
204 | cmd_op_cond.flags = MMC_RESP | MMC_ARG; | ||
205 | |||
206 | #ifdef DEBUG | ||
207 | printf("now - card powering up"); | ||
208 | #endif | ||
209 | |||
210 | sdhc = false; | ||
211 | status = send_cmd(drive, &cmd_if_cond); | ||
212 | if(status & (MCI_CMDCRCFAIL|MCI_CMDRESPEND)) | ||
213 | { | ||
214 | if((cmd_if_cond.resp[0] & 0xFFF) == cmd_if_cond.arg) | ||
215 | sdhc = true; | ||
216 | #ifdef DEBUG | ||
217 | else | ||
218 | printf("Bad resp: %x",cmd_if_cond.arg); | ||
219 | #endif | ||
220 | } | ||
221 | #ifdef DEBUG | ||
222 | else | ||
223 | printf("cmd_if_cond stat: 0x%x",status); | ||
224 | |||
225 | printf("%s Capacity",sdhc?"High":"Normal"); | ||
226 | mci_delay(); | ||
227 | mci_delay(); | ||
228 | mci_delay(); | ||
229 | #endif | ||
230 | |||
231 | #ifdef DEBUG | ||
232 | int loop = 0; | ||
233 | #endif | ||
234 | do { | ||
235 | mci_delay(); | ||
236 | mci_delay(); | ||
237 | #ifdef DEBUG | ||
238 | reset_screen(); | ||
239 | printf("Loop number #%d", ++loop); | ||
240 | #endif | ||
241 | /* app_cmd */ | ||
242 | status = send_cmd(drive, &cmd_app); | ||
243 | if( !(status & (MCI_CMDCRCFAIL|MCI_CMDRESPEND)) || | ||
244 | !(cmd_app.resp[0] & (1<<5)) ) | ||
245 | { | ||
246 | panicf("app_cmd failed"); | ||
247 | } | ||
248 | |||
249 | cmd_op_cond.arg = sdhc ? 0x40FF8000 : (8<<0x14); /* ocr */ | ||
250 | status = send_cmd(drive, &cmd_op_cond); | ||
251 | if(!(status & (MCI_CMDCRCFAIL|MCI_CMDRESPEND))) | ||
252 | panicf("cmd_op_cond failed"); | ||
253 | |||
254 | #ifdef DEBUG | ||
255 | printf("OP COND: 0x%.8x", cmd_op_cond.resp[0]); | ||
256 | #endif | ||
257 | } while(!(cmd_op_cond.resp[0] & (1<<31))); /* until card is powered up */ | ||
258 | |||
259 | #ifdef DEBUG | ||
260 | printf("now - card ready !"); | ||
261 | #endif | ||
262 | } | ||
263 | |||
264 | static void init_pl180_controller(const int drive) | ||
265 | { | ||
266 | MMC_COMMAND(drive) = MMC_DATACTRL(drive) = 0; | ||
267 | MMC_CLEAR(drive) = 0x7ff; | ||
268 | |||
269 | MMC_MASK0(drive) = MMC_MASK1(drive) = 0; /* disable all interrupts */ | ||
270 | |||
271 | MMC_POWER(drive) = MCI_PWR_UP | (10 /*voltage*/ << 2); /* use OF voltage */ | ||
272 | mci_delay(); | ||
273 | |||
274 | MMC_POWER(drive) |= MCI_PWR_ON; | ||
275 | mci_delay(); | ||
276 | |||
277 | MMC_SELECT(drive) = 0; | ||
278 | |||
279 | MMC_CLOCK(drive) = MCI_CLK_ENABLE; | ||
280 | MMC_CLOCK(drive) &= ~MCI_CLK_PWRSAVE; | ||
281 | |||
282 | /* set MCLK divider */ | ||
283 | mci_set_clock_divider(drive, 200); | ||
284 | } | ||
285 | |||
286 | int ata_init(void) | ||
287 | { | ||
288 | /* reset peripherals */ | ||
289 | |||
290 | CCU_SRC = | ||
291 | #ifdef HAVE_MULTIVOLUME | ||
292 | CCU_SRC_SDMCI_EN | | ||
293 | #endif | ||
294 | CCU_SRC_NAF_EN | CCU_SRC_IDE_EN | CCU_SRC_IDE_AHB_EN | CCU_SRC_MST_EN; | ||
295 | |||
296 | CCU_SRL = CCU_SRL_MAGIC_NUMBER; | ||
297 | CCU_SRL = 0; | ||
298 | |||
299 | GPIOC_DIR &= ~(1<<1); | ||
300 | if(GPIOC_PIN(1)) | ||
301 | CCU_SPARE1 |= 4; /* sets bit 3 of undocumented register */ | ||
302 | else | ||
303 | CCU_SPARE1 &= ~4; /* or clear it */ | ||
304 | |||
305 | CGU_IDE = (1<<7)|(1<<6); /* enable, 24MHz clock */ | ||
306 | CGU_MEMSTICK = (1<<8); /* enable, 24MHz clock */ | ||
307 | |||
308 | CGU_PERI |= CGU_NAF_CLOCK_ENABLE; | ||
309 | #ifdef HAVE_MULTIVOLUME | ||
310 | CGU_PERI |= CGU_MCI_CLOCK_ENABLE; | ||
311 | #endif | ||
312 | |||
313 | CCU_IO &= ~8; /* bits 3:2 = 01, xpd is SD interface */ | ||
314 | CCU_IO |= 4; | ||
315 | |||
316 | init_pl180_controller(NAND_AS3525); | ||
317 | sd_init_card(NAND_AS3525); | ||
318 | |||
319 | #ifdef HAVE_MULTIVOLUME | ||
320 | init_pl180_controller(SD_AS3525); | ||
321 | sd_init_card(SD_AS3525); | ||
322 | #endif | ||
323 | |||
324 | return 0; | ||
325 | } | ||
326 | |||
327 | int ata_read_sectors(IF_MV2(int drive,) unsigned long start, int count, void* buf) | ||
328 | { | ||
329 | (void)start; | ||
330 | (void)count; | ||
331 | (void)buf; | ||
332 | return 0; /* TODO */ | ||
333 | } | ||
334 | |||
335 | int ata_write_sectors(IF_MV2(int drive,) unsigned long start, int count, const void* buf) | ||
336 | { | ||
337 | (void)start; | ||
338 | (void)count; | ||
339 | (void)buf; | ||
340 | return 0; /* TODO */ | ||
341 | } | ||
diff --git a/firmware/target/arm/as3525/mmci.h b/firmware/target/arm/as3525/mmci.h new file mode 100644 index 0000000000..284eee0c75 --- /dev/null +++ b/firmware/target/arm/as3525/mmci.h | |||
@@ -0,0 +1,123 @@ | |||
1 | /* | ||
2 | * linux/drivers/mmc/host/mmci.h - ARM PrimeCell MMCI PL180/1 driver | ||
3 | * | ||
4 | * Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved. | ||
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 | //#define MMCIPOWER 0x000 | ||
11 | #define MCI_PWR_OFF 0x00 | ||
12 | #define MCI_PWR_UP 0x02 | ||
13 | #define MCI_PWR_ON 0x03 | ||
14 | #define MCI_OD (1 << 6) | ||
15 | #define MCI_ROD (1 << 7) | ||
16 | |||
17 | //#define MMCICLOCK 0x004 | ||
18 | #define MCI_CLK_ENABLE (1 << 8) | ||
19 | #define MCI_CLK_PWRSAVE (1 << 9) | ||
20 | #define MCI_CLK_BYPASS (1 << 10) | ||
21 | #define MCI_WIDEBUS (1 << 11) | ||
22 | |||
23 | //#define MMCIARGUMENT 0x008 | ||
24 | //#define MMCICOMMAND 0x00c | ||
25 | #define MCI_CPSM_RESPONSE (1 << 6) | ||
26 | #define MCI_CPSM_LONGRSP (1 << 7) | ||
27 | #define MCI_CPSM_INTERRUPT (1 << 8) | ||
28 | #define MCI_CPSM_PENDING (1 << 9) | ||
29 | #define MCI_CPSM_ENABLE (1 << 10) | ||
30 | |||
31 | #if 0 | ||
32 | #define MMCIRESPCMD 0x010 | ||
33 | #define MMCIRESPONSE0 0x014 | ||
34 | #define MMCIRESPONSE1 0x018 | ||
35 | #define MMCIRESPONSE2 0x01c | ||
36 | #define MMCIRESPONSE3 0x020 | ||
37 | #define MMCIDATATIMER 0x024 | ||
38 | #define MMCIDATALENGTH 0x028 | ||
39 | #define MMCIDATACTRL 0x02c | ||
40 | #endif | ||
41 | #define MCI_DPSM_ENABLE (1 << 0) | ||
42 | #define MCI_DPSM_DIRECTION (1 << 1) | ||
43 | #define MCI_DPSM_MODE (1 << 2) | ||
44 | #define MCI_DPSM_DMAENABLE (1 << 3) | ||
45 | |||
46 | //#define MMCIDATACNT 0x030 | ||
47 | //#define MMCISTATUS 0x034 | ||
48 | #define MCI_CMDCRCFAIL (1 << 0) | ||
49 | #define MCI_DATACRCFAIL (1 << 1) | ||
50 | #define MCI_CMDTIMEOUT (1 << 2) | ||
51 | #define MCI_DATATIMEOUT (1 << 3) | ||
52 | #define MCI_TXUNDERRUN (1 << 4) | ||
53 | #define MCI_RXOVERRUN (1 << 5) | ||
54 | #define MCI_CMDRESPEND (1 << 6) | ||
55 | #define MCI_CMDSENT (1 << 7) | ||
56 | #define MCI_DATAEND (1 << 8) | ||
57 | #define MCI_DATABLOCKEND (1 << 10) | ||
58 | #define MCI_CMDACTIVE (1 << 11) | ||
59 | #define MCI_TXACTIVE (1 << 12) | ||
60 | #define MCI_RXACTIVE (1 << 13) | ||
61 | #define MCI_TXFIFOHALFEMPTY (1 << 14) | ||
62 | #define MCI_RXFIFOHALFFULL (1 << 15) | ||
63 | #define MCI_TXFIFOFULL (1 << 16) | ||
64 | #define MCI_RXFIFOFULL (1 << 17) | ||
65 | #define MCI_TXFIFOEMPTY (1 << 18) | ||
66 | #define MCI_RXFIFOEMPTY (1 << 19) | ||
67 | #define MCI_TXDATAAVLBL (1 << 20) | ||
68 | #define MCI_RXDATAAVLBL (1 << 21) | ||
69 | |||
70 | //#define MMCICLEAR 0x038 | ||
71 | #define MCI_CMDCRCFAILCLR (1 << 0) | ||
72 | #define MCI_DATACRCFAILCLR (1 << 1) | ||
73 | #define MCI_CMDTIMEOUTCLR (1 << 2) | ||
74 | #define MCI_DATATIMEOUTCLR (1 << 3) | ||
75 | #define MCI_TXUNDERRUNCLR (1 << 4) | ||
76 | #define MCI_RXOVERRUNCLR (1 << 5) | ||
77 | #define MCI_CMDRESPENDCLR (1 << 6) | ||
78 | #define MCI_CMDSENTCLR (1 << 7) | ||
79 | #define MCI_DATAENDCLR (1 << 8) | ||
80 | #define MCI_DATABLOCKENDCLR (1 << 10) | ||
81 | |||
82 | //#define MMCIMASK0 0x03c | ||
83 | #define MCI_CMDCRCFAILMASK (1 << 0) | ||
84 | #define MCI_DATACRCFAILMASK (1 << 1) | ||
85 | #define MCI_CMDTIMEOUTMASK (1 << 2) | ||
86 | #define MCI_DATATIMEOUTMASK (1 << 3) | ||
87 | #define MCI_TXUNDERRUNMASK (1 << 4) | ||
88 | #define MCI_RXOVERRUNMASK (1 << 5) | ||
89 | #define MCI_CMDRESPENDMASK (1 << 6) | ||
90 | #define MCI_CMDSENTMASK (1 << 7) | ||
91 | #define MCI_DATAENDMASK (1 << 8) | ||
92 | #define MCI_DATABLOCKENDMASK (1 << 10) | ||
93 | #define MCI_CMDACTIVEMASK (1 << 11) | ||
94 | #define MCI_TXACTIVEMASK (1 << 12) | ||
95 | #define MCI_RXACTIVEMASK (1 << 13) | ||
96 | #define MCI_TXFIFOHALFEMPTYMASK (1 << 14) | ||
97 | #define MCI_RXFIFOHALFFULLMASK (1 << 15) | ||
98 | #define MCI_TXFIFOFULLMASK (1 << 16) | ||
99 | #define MCI_RXFIFOFULLMASK (1 << 17) | ||
100 | #define MCI_TXFIFOEMPTYMASK (1 << 18) | ||
101 | #define MCI_RXFIFOEMPTYMASK (1 << 19) | ||
102 | #define MCI_TXDATAAVLBLMASK (1 << 20) | ||
103 | #define MCI_RXDATAAVLBLMASK (1 << 21) | ||
104 | |||
105 | #if 0 | ||
106 | #define MMCIMASK1 0x040 | ||
107 | #define MMCIFIFOCNT 0x048 | ||
108 | #define MMCIFIFO 0x080 /* to 0x0bc */ | ||
109 | #endif | ||
110 | |||
111 | #define MCI_IRQENABLE \ | ||
112 | (MCI_CMDCRCFAILMASK|MCI_DATACRCFAILMASK|MCI_CMDTIMEOUTMASK| \ | ||
113 | MCI_DATATIMEOUTMASK|MCI_TXUNDERRUNMASK|MCI_RXOVERRUNMASK| \ | ||
114 | MCI_CMDRESPENDMASK|MCI_CMDSENTMASK|MCI_DATABLOCKENDMASK) | ||
115 | |||
116 | /* | ||
117 | * The size of the FIFO in bytes. | ||
118 | */ | ||
119 | #define MCI_FIFOSIZE (16*4) | ||
120 | |||
121 | #define MCI_FIFOHALFSIZE (MCI_FIFOSIZE / 2) | ||
122 | |||
123 | #define NR_SG 16 | ||