w.i.p sdcard device driver for raspi. detects cards but isnt able to send commands...
[AROS.git] / arch / arm-raspi / devs / sdcard / sdcard_bus.c
bloba9d9aee62506aeb9a78c54faa7e88fe24d11a8f4
1 /*
2 Copyright © 2013, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #define DEBUG 1
7 #include <aros/debug.h>
9 #include <aros/bootloader.h>
10 #include <aros/symbolsets.h>
11 #include <exec/exec.h>
12 #include <exec/resident.h>
13 #include <exec/tasks.h>
14 #include <exec/memory.h>
15 #include <exec/nodes.h>
16 #include <utility/utility.h>
17 #include <libraries/expansion.h>
18 #include <libraries/configvars.h>
19 #include <dos/bptr.h>
20 #include <dos/dosextens.h>
21 #include <dos/filehandler.h>
23 #include <proto/exec.h>
24 #include <proto/timer.h>
25 #include <proto/bootloader.h>
26 #include <proto/expansion.h>
27 #include <proto/utility.h>
28 #include <proto/vcmbox.h>
30 #include <asm/bcm2835.h>
31 #include <hardware/videocore.h>
32 #include <hardware/mmc.h>
33 #include <hardware/sdhc.h>
35 #include <string.h>
37 #include "sdcard_intern.h"
38 #include "timer.h"
40 #include LC_LIBDEFS_FILE
42 UBYTE FNAME_SDCBUS(MMIOReadByte)(ULONG reg, struct sdcard_Bus *bus)
44 ULONG val = *(volatile ULONG *)(((ULONG)bus->sdcb_IOBase + reg) & ~3);
46 return (val >> ((reg & 3) << 3)) & 0xff;
49 UWORD FNAME_SDCBUS(MMIOReadWord)(ULONG reg, struct sdcard_Bus *bus)
51 ULONG val = *(volatile ULONG *)(((ULONG)bus->sdcb_IOBase + reg) & ~3);
53 return (val >> (((reg >> 1) & 1) << 4)) & 0xffff;
56 ULONG FNAME_SDCBUS(MMIOReadLong)(ULONG reg, struct sdcard_Bus *bus)
58 return *(volatile ULONG *)(bus->sdcb_IOBase + reg);
61 void FNAME_SDCBUS(ArasanWriteLong)(ULONG reg, ULONG val, struct sdcard_Bus *bus)
63 /* Bug: two SDC clock cycle delay required between successive chipset writes */
64 while (*((volatile ULONG *)(SYSTIMER_CLO)) < (bus->sdcb_LastWrite + 100))
65 asm volatile("mov r0, r0\n");
67 *(volatile ULONG *)(bus->sdcb_IOBase + reg) = val;
68 bus->sdcb_LastWrite = *((volatile ULONG *)(SYSTIMER_CLO));
71 void FNAME_SDCBUS(MMIOWriteByte)(ULONG reg, UBYTE val, struct sdcard_Bus *bus)
73 ULONG currval = *(volatile ULONG *)(((ULONG)bus->sdcb_IOBase + reg) & ~3);
74 ULONG shift = (reg & 3) * 8;
75 ULONG mask = 0xff << shift;
76 ULONG newval = (currval & ~mask) | (val << shift);
78 FNAME_SDCBUS(ArasanWriteLong)(reg & ~3, newval, bus);
81 void FNAME_SDCBUS(MMIOWriteWord)(ULONG reg, UWORD val, struct sdcard_Bus *bus)
83 ULONG currval = *(volatile ULONG *)(((ULONG)bus->sdcb_IOBase + reg) & ~3);
84 ULONG shift = ((reg >> 1) & 1) * 16;
85 ULONG mask = 0xffff << shift;
86 ULONG newval = (currval & ~mask) | (val << shift);
88 FNAME_SDCBUS(ArasanWriteLong)(reg & ~3, newval, bus);
91 void FNAME_SDCBUS(MMIOWriteLong)(ULONG reg, ULONG val, struct sdcard_Bus *bus)
93 FNAME_SDCBUS(ArasanWriteLong)(reg, val, bus);
96 void FNAME_SDCBUS(SoftReset)(UBYTE mask, struct sdcard_Bus *bus)
98 ULONG timeout = 10000, timeout_udelay;
100 FNAME_SDCBUS(MMIOWriteByte)(SDHCI_RESET, mask, bus);
101 while (FNAME_SDCBUS(MMIOReadByte)(SDHCI_RESET, bus) & mask) {
102 if (timeout == 0) {
103 D(bug("[SDCard--] %s: Timeout\n", __PRETTY_FUNCTION__));
104 break;
106 timeout_udelay = timeout - 1000;
107 for (; timeout > timeout_udelay; timeout --) asm volatile("mov r0, r0\n");
111 ULONG FNAME_SDCBUS(SendCmd)(struct TagItem *CmdTags, struct sdcard_Bus *bus)
113 struct TagItem *Response = NULL;
115 UWORD sdCommand = (UWORD)GetTagData(SDCARD_TAG_CMD, 0, CmdTags);
116 ULONG sdArg = GetTagData(SDCARD_TAG_ARG, 0, CmdTags);
117 ULONG sdResponseType = GetTagData(SDCARD_TAG_RSPTYPE, MMC_RSP_NONE, CmdTags);
118 ULONG sdData, sdDataLen = 0, sdDataFlags;
120 UWORD sdcTransMode = 0, sdCommandFlags;
121 ULONG sdStatus = 0, sdCommandMask = SDHCI_PS_CMD_INHIBIT;
122 ULONG timeout = 10000, timeout_udelay;
123 ULONG ret = 0;
125 if (sdResponseType != MMC_RSP_NONE)
127 Response = FindTagItem(SDCARD_TAG_RSP, CmdTags);
130 if ((sdData = GetTagData(SDCARD_TAG_DATA, 0, CmdTags)) != 0)
132 sdDataLen = GetTagData(SDCARD_TAG_DATALEN, 0, CmdTags);
133 sdDataFlags = GetTagData(SDCARD_TAG_DATAFLAGS, 0, CmdTags);
134 if (!(sdDataLen))
135 sdData = 0;
138 /* Dont wait for DATA inihibit for stop commands */
139 if (sdCommand != MMC_CMD_STOP_TRANSMISSION)
140 sdCommandMask |= SDHCI_PS_DATA_INHIBIT;
142 while (FNAME_SDCBUS(MMIOReadLong)(SDHCI_PRESENT_STATE, bus) & sdCommandMask) {
143 if (timeout == 0) {
144 D(bug("[SDCard--] %s: Controller failed to release inhibited bit(s).\n", __PRETTY_FUNCTION__));
145 return -1;
147 timeout_udelay = timeout - 1000;
148 for (; timeout > timeout_udelay; timeout--)
149 asm volatile("mov r0, r0\n");
152 sdCommandMask = SDHCI_INT_RESPONSE;
153 if (!(sdResponseType & MMC_RSP_PRESENT))
154 sdCommandFlags = SDHCI_CMD_RESP_NONE;
155 else if (sdResponseType & MMC_RSP_136)
156 sdCommandFlags = SDHCI_CMD_RESP_LONG;
157 else if (sdResponseType & MMC_RSP_BUSY) {
158 sdCommandFlags = SDHCI_CMD_RESP_SHORT_BUSY;
159 sdCommandMask |= SDHCI_INT_DATA_END;
160 } else
161 sdCommandFlags = SDHCI_CMD_RESP_SHORT;
163 if (sdResponseType & MMC_RSP_CRC)
164 sdCommandFlags |= SDHCI_CMD_CRC;
165 if (sdResponseType & MMC_RSP_OPCODE)
166 sdCommandFlags |= SDHCI_CMD_INDEX;
167 if (sdData)
168 sdCommandFlags |= SDHCI_CMD_DATA;
170 if (sdData != 0) {
171 sdcTransMode = SDHCI_TRANSMOD_BLK_CNT_EN;
172 D(bug("[SDCard--] %s: Configuring Data Transfer\n", __PRETTY_FUNCTION__));
174 *(volatile ULONG *)GPCLR0 = 1<<16; // Turn Activity LED ON
176 FNAME_SDCBUS(MMIOWriteByte)(SDHCI_TIMEOUT_CONTROL, 0xe, bus);
178 FNAME_SDCBUS(MMIOWriteWord)(SDHCI_BLOCK_SIZE, 1 << bus->sdcb_SectorShift, bus);
179 if ((sdDataLen >> bus->sdcb_SectorShift) > 1)
181 sdcTransMode |= SDHCI_TRANSMOD_MULTI;
182 FNAME_SDCBUS(MMIOWriteWord)(SDHCI_BLOCK_COUNT, sdDataLen >> bus->sdcb_SectorShift, bus);
184 else
186 FNAME_SDCBUS(MMIOWriteWord)(SDHCI_BLOCK_COUNT, 1, bus);
189 if (sdDataFlags == MMC_DATA_READ)
190 sdcTransMode |= SDHCI_TRANSMOD_READ;
192 D(bug("[SDCard--] %s: Mode %08x, BlockSize %d, Count %d\n", __PRETTY_FUNCTION__, sdcTransMode, 1 << bus->sdcb_SectorShift, sdDataLen >> bus->sdcb_SectorShift));
195 FNAME_SDCBUS(MMIOWriteLong)(SDHCI_ARGUMENT, sdArg, bus);
196 if (sdcTransMode)
197 FNAME_SDCBUS(MMIOWriteLong)(SDHCI_TRANSFER_MODE, (sdcTransMode << 16) | SDHCI_MAKE_CMD(sdCommand, sdCommandFlags), bus);
198 else
199 FNAME_SDCBUS(MMIOWriteWord)(SDHCI_COMMAND, SDHCI_MAKE_CMD(sdCommand, sdCommandFlags), bus);
201 timeout = 10000;
202 do {
203 sdStatus = FNAME_SDCBUS(MMIOReadLong)(SDHCI_INT_STATUS, bus);
204 if (sdStatus & SDHCI_INT_ERROR)
205 break;
206 if (--timeout == 0)
207 break;
208 } while ((sdStatus & sdCommandMask) != sdCommandMask);
210 if (timeout != 0) {
211 if ((sdStatus & (sdCommandMask|SDHCI_INT_ERROR)) == sdCommandMask) {
212 if (sdStatus & SDHCI_INT_ERROR)
214 D(bug("[SDCard--] %s: Error?", __PRETTY_FUNCTION__));
217 if (Response)
219 D(bug("[SDCard--] %s: Reading Response ", __PRETTY_FUNCTION__));
220 if (sdResponseType & MMC_RSP_136)
222 D(bug("[136bit]\n"));
223 if (Response->ti_Data)
225 ULONG i;
226 for (i = 0; i < 4; i ++)
228 ((ULONG *)Response->ti_Data)[i] = FNAME_SDCBUS(MMIOReadLong)(SDHCI_RESPONSE + (3 - i) * 4, bus) << 8;
229 if (i != 3)
230 ((ULONG *)Response->ti_Data)[i] |= FNAME_SDCBUS(MMIOReadByte)(SDHCI_RESPONSE + (3 - i) * 4 - 1, bus);
234 else
236 D(bug("\n"));
237 Response->ti_Data = FNAME_SDCBUS(MMIOReadLong)(SDHCI_RESPONSE, bus);
240 FNAME_SDCBUS(MMIOWriteLong)(SDHCI_INT_STATUS, sdCommandMask, bus);
242 else
244 D(bug("[SDCard--] %s: Failed? [status = %08x]\n", __PRETTY_FUNCTION__, sdStatus));
245 ret = -1;
248 if (!ret && sdData)
250 D(bug("[SDCard--] %s: Transfering Data..\n", __PRETTY_FUNCTION__));
251 timeout = 1000000;
252 sdCommand = SDHCI_INT_SPACE_AVAIL | SDHCI_INT_DATA_AVAIL;
253 sdCommandMask = SDHCI_PS_DATA_AVAILABLE | SDHCI_PS_SPACE_AVAILABLE;
254 do {
255 sdStatus = FNAME_SDCBUS(MMIOReadLong)(SDHCI_INT_STATUS, bus);
256 if (sdStatus & SDHCI_INT_ERROR) {
257 D(bug("[SDCard--] %s: Error [status 0x%X]!\n", __PRETTY_FUNCTION__, sdStatus));
258 ret = -1;
259 break;
261 if (sdStatus & sdCommand) {
262 if (!(FNAME_SDCBUS(MMIOReadLong)(SDHCI_PRESENT_STATE, bus) & sdCommandMask))
263 continue;
264 FNAME_SDCBUS(MMIOWriteLong)(SDHCI_INT_STATUS, sdCommand, bus);
265 #warning "TODO: Transfer bytes ;)"
267 if (timeout-- <= 0)
269 D(bug("[SDCard--] %s: Timeout!\n", __PRETTY_FUNCTION__));
270 ret = -1;
271 break;
273 } while (!(sdStatus & SDHCI_INT_DATA_END));
276 else
278 D(bug("[SDCard--] %s: Error - command timed out\n", __PRETTY_FUNCTION__));
279 ret = -1;
281 timeout = 1000;
282 timeout_udelay = 0;
283 for (; timeout > timeout_udelay; timeout --) asm volatile("mov r0, r0\n");
285 *(volatile ULONG *)GPSET0 = (1 << 16); // Turn Activity LED OFF
287 sdStatus = FNAME_SDCBUS(MMIOReadLong)(SDHCI_INT_STATUS, bus);
288 FNAME_SDCBUS(MMIOWriteLong)(SDHCI_INT_STATUS, SDHCI_INT_ALL_MASK, bus);
289 if (!ret) {
290 return 0;
293 D(bug("[SDCard--] %s: Reseting SDHCI CMD/DATA\n", __PRETTY_FUNCTION__));
295 FNAME_SDCBUS(SoftReset)(SDHCI_RESET_CMD, bus);
296 FNAME_SDCBUS(SoftReset)(SDHCI_RESET_DATA, bus);
297 if (sdStatus & SDHCI_INT_TIMEOUT)
298 return -1;
299 else
300 return -1;
303 ULONG FNAME_SDCBUS(Rsp136Unpack)(ULONG *buf, ULONG offset, const ULONG len)
305 const ULONG mask = ((len < 32) ? (1 << len) : 0) - 1;
306 const ULONG shift = (offset) & 0x1F;
307 ULONG retval;
309 retval = buf[3 - (offset >> 5)] >> shift;
310 if (len + shift > 32)
311 retval |= buf[3 - (offset >> 5) - 1] << ((32 - shift) % 32);
313 return (retval & mask);
317 int FNAME_SDCBUS(SDUnitSwitch)(BOOL test, int group, UBYTE value, APTR buf, struct sdcard_Unit *sdcUnit)
319 struct TagItem sdcSwitchTags[] =
321 {SDCARD_TAG_CMD, SD_CMD_SWITCH_FUNC},
322 {SDCARD_TAG_ARG, 0},
323 {SDCARD_TAG_RSPTYPE, MMC_RSP_R1},
324 {SDCARD_TAG_RSP, 0},
325 {SDCARD_TAG_DATA, buf},
326 {SDCARD_TAG_DATALEN, 64},
327 {SDCARD_TAG_DATAFLAGS, MMC_DATA_READ},
328 {TAG_DONE, 0}
331 D(bug("[SDCard%02ld] %s()\n", sdcUnit->sdcu_UnitNum, __PRETTY_FUNCTION__));
333 sdcSwitchTags[1].ti_Data = ((test) ? 0 : (1 << 31)) | 0xffffff;
334 sdcSwitchTags[1].ti_Data &= ~(0xf << (group * 4));
335 sdcSwitchTags[1].ti_Data |= value << (group * 4);
337 return FNAME_SDCBUS(SendCmd)(sdcSwitchTags, sdcUnit->sdcu_Bus);
341 int FNAME_SDCBUS(SDUnitChangeFrequency)(struct sdcard_Unit *sdcUnit)
343 unsigned int timeout;
344 struct TagItem sdcChFreqTags[] =
346 {SDCARD_TAG_CMD, 0},
347 {SDCARD_TAG_ARG, 0},
348 {SDCARD_TAG_RSPTYPE, 0},
349 {SDCARD_TAG_RSP, 0},
350 {TAG_DONE, 0}, /* SDCARD_TAG_DATA */
351 {SDCARD_TAG_DATALEN, 0},
352 {SDCARD_TAG_DATAFLAGS, MMC_DATA_READ},
353 {TAG_DONE, 0}
356 /* Read the SCR to find out if higher speeds are supported ..*/
358 D(bug("[SDCard%02ld] %s: Attempt to send App Command ... \n", sdcUnit->sdcu_UnitNum, __PRETTY_FUNCTION__));
359 sdcChFreqTags[0].ti_Data = MMC_CMD_APP_CMD;
360 sdcChFreqTags[1].ti_Data = sdcUnit->sdcu_CardRCA << 16;
361 sdcChFreqTags[2].ti_Data = MMC_RSP_R1;
362 if (FNAME_SDCBUS(SendCmd)(sdcChFreqTags, sdcUnit->sdcu_Bus) != -1)
364 ULONG sdcardRespBuf[2] = {0, 0};
366 sdcChFreqTags[0].ti_Data = SD_CMD_APP_SEND_SCR;
367 sdcChFreqTags[1].ti_Data = 0;
368 sdcChFreqTags[2].ti_Data = MMC_RSP_R1;
370 timeout = 3;
371 D(bug("[SDCard%02ld] %s: Attempt to Query SCR Register ... \n", sdcUnit->sdcu_UnitNum, __PRETTY_FUNCTION__));
374 sdcChFreqTags[4].ti_Tag = SDCARD_TAG_DATA;
375 sdcChFreqTags[4].ti_Data = sdcardRespBuf;
376 sdcChFreqTags[5].ti_Data = 8;
378 if (FNAME_SDCBUS(SendCmd)(sdcChFreqTags, sdcUnit->sdcu_Bus) != -1)
379 break;
380 } while (timeout-- > 0);
382 if (timeout > 0)
384 if (AROS_BE2LONG(sdcardRespBuf[0]) & SD_SCR_DATA4BIT)
385 sdcUnit->sdcu_Flags |= AF_4bitData;
387 /* v1.0 SDCards don't support switching */
388 if (((AROS_BE2LONG(sdcardRespBuf[0]) >> 24) & 0xf) < 1)
390 D(bug("[SDCard%02ld] %s: Card doesnt support Switching\n", sdcUnit->sdcu_UnitNum, __PRETTY_FUNCTION__));
391 return 0;
394 timeout = 4;
395 while (timeout-- > 0) {
396 if (FNAME_SDCBUS(SDUnitSwitch)(TRUE, 0, 1, sdcardRespBuf, sdcUnit) != -1)
398 /* The high-speed function is busy. Try again */
399 if (!(AROS_BE2LONG(sdcardRespBuf[7]) & SD_SCR_HIGHSPEED))
400 break;
402 else
404 D(bug("[SDCard%02ld] %s: Switch failed\n", sdcUnit->sdcu_UnitNum, __PRETTY_FUNCTION__));
405 return -1;
409 if (timeout > 0)
411 /* Is high-speed supported? */
412 if (!(AROS_BE2LONG(sdcardRespBuf[3]) & SD_SCR_HIGHSPEED))
414 D(bug("[SDCard%02ld] %s: Card doesnt support Highspeed mode\n", sdcUnit->sdcu_UnitNum, __PRETTY_FUNCTION__));
415 return 0;
418 if (FNAME_SDCBUS(SDUnitSwitch)(FALSE, 0, 1, sdcardRespBuf, sdcUnit) != -1)
420 if ((AROS_BE2LONG(sdcardRespBuf[4]) & 0x0F000000) == 0x01000000)
421 sdcUnit->sdcu_Flags |= AF_HighSpeed;
425 else
427 D(bug("[SDCard%02ld] %s: Query Failed\n", sdcUnit->sdcu_UnitNum, __PRETTY_FUNCTION__));
430 else
432 D(bug("[SDCard%02ld] %s: App Command Failed\n", sdcUnit->sdcu_UnitNum, __PRETTY_FUNCTION__));
436 void FNAME_SDCBUS(BusTask)(struct sdcard_Bus *bus)
438 struct SDCardBase *SDCardBase = bus->sdcb_DeviceBase;
439 struct sdcard_Unit *unit;
440 struct IORequest *msg;
441 ULONG sdcReg;
442 ULONG sig;
444 D(bug("[SDCard**] Task started (bus: %u)\n", bus->sdcb_BusNum));
446 bus->sdcb_Timer = sdcard_OpenTimer(SDCardBase);
448 /* Get the signal used for sleeping */
449 bus->sdcb_Task = FindTask(0);
450 bus->sdcb_TaskSig = AllocSignal(-1);
451 /* Failed to get it? Use SIGBREAKB_CTRL_E instead */
452 if (bus->sdcb_TaskSig < 0)
453 bus->sdcb_TaskSig = SIGBREAKB_CTRL_E;
455 sig = 1L << bus->sdcb_MsgPort->mp_SigBit;
457 sdcReg = FNAME_SDCBUS(MMIOReadLong)(SDHCI_PRESENT_STATE, bus);
458 if (sdcReg & SDHCI_PS_CARD_PRESENT)
460 FNAME_SDC(RegisterVolume)(bus);
463 /* Wait forever and process messages */
464 for (;;)
466 Wait(sig);
468 /* Even if you get new signal, do not process it until Unit is not active */
469 if (!(bus->sdcb_BusFlags & UNITF_ACTIVE))
471 bus->sdcb_BusFlags |= UNITF_ACTIVE;
473 /* Empty the request queue */
474 while ((msg = (struct IORequest *)GetMsg(bus->sdcb_MsgPort)))
476 /* And do IO's */
477 if (FNAME_SDC(HandleIO)(msg))
479 ReplyMsg((struct Message *)msg);
483 bus->sdcb_BusFlags &= ~(UNITF_INTASK | UNITF_ACTIVE);