2 Copyright © 2013, The AROS Development Team. All rights reserved.
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>
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/vcmbox.h>
29 #include <asm/bcm2835.h>
30 #include <hardware/arasan.h>
31 #include <hardware/videocore.h>
32 #include <hardware/mmc.h>
33 #include <hardware/sdhc.h>
37 #include "sdcard_intern.h"
40 #include LC_LIBDEFS_FILE
42 #define VCMB_PROPCHAN 8
43 #define VCMBoxBase SDCardBase->sdcard_VCMBoxBase
45 unsigned int VCMBoxMessage
[8] __attribute__((used
,aligned(16)));
47 BOOL
FNAME_SDC(RegisterVolume
)(struct sdcard_Bus
*bus
)
49 struct SDCardBase
*SDCardBase
= bus
->sdcb_DeviceBase
;
50 struct sdcard_Unit
*sdcUnit
= NULL
;
51 unsigned int timeout
= 1000000, timeout_udelay
= 2000;
52 struct DeviceNode
*devnode
;
53 BOOL sdcHighCap
= FALSE
;
54 struct TagItem sdcRegTags
[] =
58 {SDCARD_TAG_RSPTYPE
, 0},
63 D(bug("[SDCard>>] %s()\n", __PRETTY_FUNCTION__
));
65 if ((ExpansionBase
= (struct ExpansionBase
*)OpenLibrary("expansion.library", 40L)) != NULL
)
68 ULONG response136
[4] = {0, 0, 0, 0};
70 D(bug("[SDCard>>] %s: Telling controller to idle...\n", __PRETTY_FUNCTION__
));
71 sdcRegTags
[0].ti_Data
= MMC_CMD_GO_IDLE_STATE
;
72 sdcRegTags
[1].ti_Data
= 0;
73 sdcRegTags
[2].ti_Data
= MMC_RSP_NONE
;
74 if (FNAME_SDCBUS(SendCmd
)(sdcRegTags
, bus
) == -1)
76 D(bug("[SDCard>>] %s: Failed to go idle?\n", __PRETTY_FUNCTION__
));
77 CloseLibrary((struct Library
*)ExpansionBase
);
81 for (; timeout_udelay
> 0; timeout_udelay
--) asm volatile("mov r0, r0\n");
83 sdcRegTags
[0].ti_Data
= SD_CMD_SEND_IF_COND
;
84 sdcRegTags
[1].ti_Data
= ((bus
->sdcb_Power
& 0xFF8000) != 0) << 8 | 0xAA;
85 sdcRegTags
[2].ti_Data
= MMC_RSP_R7
;
86 D(bug("[SDCard>>] %s: Querying Interface conditions [%08x] ... ", __PRETTY_FUNCTION__
, sdcRegTags
[1].ti_Data
));
88 if ((FNAME_SDCBUS(SendCmd
)(sdcRegTags
, bus
)) != -1)
90 D(bug("response %08x\n", sdcRegTags
[3].ti_Data
));
93 D(bug("[SDCard>>] %s: Attempt to send an App Command ... ", __PRETTY_FUNCTION__
));
94 sdcRegTags
[0].ti_Data
= MMC_CMD_APP_CMD
;
95 sdcRegTags
[1].ti_Data
= 0;
96 sdcRegTags
[2].ti_Data
= MMC_RSP_R1
;
98 if (FNAME_SDCBUS(SendCmd
)(sdcRegTags
, bus
) == -1)
100 D(bug("error (-1)\n"));
101 CloseLibrary((struct Library
*)ExpansionBase
);
104 D(bug("response %08x\n", sdcRegTags
[3].ti_Data
));
106 sdcRegTags
[0].ti_Data
= SD_CMD_APP_SEND_OP_COND
;
107 sdcRegTags
[1].ti_Data
= (bus
->sdcb_Power
& 0xFF8000) | OCR_HCS
;
108 sdcRegTags
[2].ti_Data
= MMC_RSP_R3
;
110 D(bug("[SDCard>>] %s: Querying Operating conditions [%08x] ... ", __PRETTY_FUNCTION__
, sdcRegTags
[1].ti_Data
));
111 if (FNAME_SDCBUS(SendCmd
)(sdcRegTags
, bus
) != -1)
113 D(bug("response %08x\n", sdcRegTags
[3].ti_Data
));
114 timeout_udelay
= timeout
- 1000;
115 for (; timeout
> timeout_udelay
; timeout
--) asm volatile("mov r0, r0\n");
119 D(bug("error (-1)\n"));
120 CloseLibrary((struct Library
*)ExpansionBase
);
123 } while ((!(sdcRegTags
[3].ti_Data
& OCR_BUSY
)) && timeout
--);
127 D(bug("[SDCard>>] %s: Card OCR = %08x\n", __PRETTY_FUNCTION__
, (sdcRegTags
[3].ti_Data
& 0xFFFF00)));
129 if (sdcRegTags
[3].ti_Data
& OCR_HCS
)
132 D(bug("[SDCard>>] %s: Card is now operating in Identification Mode\n", __PRETTY_FUNCTION__
));
134 /* Put the "card" into identify mode*/
135 D(bug("[SDCard>>] %s: Querying Card Identification Data ...\n", __PRETTY_FUNCTION__
));
136 sdcRegTags
[0].ti_Data
= MMC_CMD_ALL_SEND_CID
;
137 sdcRegTags
[1].ti_Data
= 0;
138 sdcRegTags
[2].ti_Data
= MMC_RSP_R2
;
139 sdcRegTags
[3].ti_Data
= response136
;
140 if (FNAME_SDCBUS(SendCmd
)(sdcRegTags
, bus
) != -1)
142 if (sdcRegTags
[3].ti_Data
)
144 D(bug("[SDCard>>] %s: %08x%08x%08x%08x\n", __PRETTY_FUNCTION__
, response136
[0], response136
[1], response136
[2], response136
[3]));
145 D(bug("[SDCard>>] %s: Card Identification Data (CID) Register\n", __PRETTY_FUNCTION__
));
146 D(bug("[SDCard>>] %s: ======================================\n", __PRETTY_FUNCTION__
));
147 D(bug("[SDCard>>] %s: Manuafacturer ID (MID) : %06x\n", __PRETTY_FUNCTION__
, FNAME_SDCBUS(Rsp136Unpack
)(response136
, 120, 8)));
148 D(bug("[SDCard>>] %s: Product Name (PNM) : %c%c%c%c%c\n", __PRETTY_FUNCTION__
, FNAME_SDCBUS(Rsp136Unpack
)(response136
, 96, 8), FNAME_SDCBUS(Rsp136Unpack
)(response136
, 88, 8), FNAME_SDCBUS(Rsp136Unpack
)(response136
, 80, 8), FNAME_SDCBUS(Rsp136Unpack
)(response136
, 72, 8), FNAME_SDCBUS(Rsp136Unpack
)(response136
, 64, 8)));
149 D(bug("[SDCard>>] %s: Product Revision (PRV) : %d.%d\n", __PRETTY_FUNCTION__
, FNAME_SDCBUS(Rsp136Unpack
)(response136
, 60, 4), FNAME_SDCBUS(Rsp136Unpack
)(response136
, 56, 4)));
150 D(bug("[SDCard>>] %s: Serial number (PSN) : %08x\n", __PRETTY_FUNCTION__
, FNAME_SDCBUS(Rsp136Unpack
)(response136
, 24, 32)));
151 D(bug("[SDCard>>] %s: Manufacturing Date Code (MDT) : %d/%d\n", __PRETTY_FUNCTION__
, FNAME_SDCBUS(Rsp136Unpack
)(response136
, 8, 4), FNAME_SDCBUS(Rsp136Unpack
)(response136
, 12, 8)));
152 D(bug("[SDCard>>] %s: CRC7 checksum (CRC7) : %x\n", __PRETTY_FUNCTION__
, FNAME_SDCBUS(Rsp136Unpack
)(response136
, 1, 7)));
153 D(bug("[SDCard>>] %s: Reserved : %x\n", __PRETTY_FUNCTION__
, FNAME_SDCBUS(Rsp136Unpack
)(response136
, 0, 1)));
156 D(bug("[SDCard>>] %s: Querying Card Relative Address... ", __PRETTY_FUNCTION__
));
157 sdcRegTags
[0].ti_Data
= SD_CMD_SEND_RELATIVE_ADDR
;
158 sdcRegTags
[1].ti_Data
= 0;
159 sdcRegTags
[2].ti_Data
= MMC_RSP_R6
;
160 sdcRegTags
[3].ti_Data
= NULL
;
161 if (FNAME_SDCBUS(SendCmd
)(sdcRegTags
, bus
) != -1)
163 if ((sdcUnit
= AllocVecPooled(SDCardBase
->sdcard_MemPool
, sizeof(struct sdcard_Unit
))) != NULL
)
165 sdcUnit
->sdcu_Bus
= bus
;
166 sdcUnit
->sdcu_UnitNum
= bus
->sdcb_UnitCnt
++;
167 bus
->sdcb_Units
[sdcUnit
->sdcu_UnitNum
] = sdcUnit
;
168 sdcUnit
->sdcu_CardRCA
= (sdcRegTags
[3].ti_Data
>> 16) & 0xFFFF;
169 D(bug("[RCA %d]\n", sdcUnit
->sdcu_CardRCA
));
171 sdcRegTags
[0].ti_Data
= MMC_CMD_SEND_CSD
;
172 sdcRegTags
[1].ti_Data
= sdcUnit
->sdcu_CardRCA
<< 16;
173 sdcRegTags
[2].ti_Data
= MMC_RSP_R2
;
174 sdcRegTags
[3].ti_Data
= response136
;
175 D(bug("[SDCard%02ld] %s: Querying Card Specific Data [%08x] ...\n", sdcUnit
->sdcu_UnitNum
, __PRETTY_FUNCTION__
, sdcRegTags
[1].ti_Data
));
176 if (FNAME_SDCBUS(SendCmd
)(sdcRegTags
, bus
) != -1)
178 if (sdcRegTags
[3].ti_Data
)
180 int __csdstruct
= FNAME_SDCBUS(Rsp136Unpack
)(response136
, 126, 2);
181 D(bug("[SDCard%02ld] %s: %08x%08x%08x%08x\n", sdcUnit
->sdcu_UnitNum
, __PRETTY_FUNCTION__
, response136
[0], response136
[1], response136
[2], response136
[3]));
182 D(bug("[SDCard%02ld] %s: Card Specific Data (CSD) Register\n", sdcUnit
->sdcu_UnitNum
, __PRETTY_FUNCTION__
));
183 D(bug("[SDCard%02ld] %s: =================================\n", sdcUnit
->sdcu_UnitNum
, __PRETTY_FUNCTION__
));
184 D(bug("[SDCard%02ld] %s: CSD_STRUCTURE : %x ", sdcUnit
->sdcu_UnitNum
, __PRETTY_FUNCTION__
, __csdstruct
));
186 sdcUnit
->sdcu_Read32
= FNAME_SDCIO(ReadSector32
);
187 sdcUnit
->sdcu_Write32
= FNAME_SDCIO(WriteSector32
);
188 sdcUnit
->sdcu_Flags
= AF_MediaPresent
;
190 sdcUnit
->sdcu_Flags
|= AF_HighCapacity
;
196 D(bug("[SDSC Card]\n"));
197 pp
[DE_SIZEBLOCK
+ 4] = 2 << (FNAME_SDCBUS(Rsp136Unpack
)(response136
, 80, 4) - 1);
198 pp
[DE_SECSPERBLOCK
+ 4] = pp
[DE_SIZEBLOCK
+ 4] >> 9;
199 pp
[DE_HIGHCYL
+ 4] = ((1 + FNAME_SDCBUS(Rsp136Unpack
)(response136
, 62, 12)) << (FNAME_SDCBUS(Rsp136Unpack
)(response136
, 47, 3) + 2));
204 D(bug("[SDHC/XC Card]\n"));
206 pp
[DE_SECSPERBLOCK
+ 4] = 2;
207 pp
[DE_SIZEBLOCK
+ 4] = 2 << (10 - 1);
208 pp
[DE_HIGHCYL
+ 4] = ((1 + FNAME_SDCBUS(Rsp136Unpack
)(response136
, 48, 22)) * (2 << (9 - 1)));
210 sdcUnit
->sdcu_Flags
|= AF_MMC
;
212 sdcUnit
->sdcu_Read64
= FNAME_SDCIO(ReadSector64
);
213 sdcUnit
->sdcu_Write64
= FNAME_SDCIO(WriteSector64
);
217 D(bug("[SDCard%02ld] %s: Unsupported Card\n", sdcUnit
->sdcu_UnitNum
, __PRETTY_FUNCTION__
));
218 CloseLibrary((struct Library
*)ExpansionBase
);
222 sdcUnit
->sdcu_Cylinders
= pp
[DE_HIGHCYL
+ 4];
223 sdcUnit
->sdcu_Heads
= 1;
224 sdcUnit
->sdcu_Sectors
= pp
[DE_SECSPERBLOCK
+ 4];
225 sdcUnit
->sdcu_Capacity
= sdcUnit
->sdcu_Cylinders
* sdcUnit
->sdcu_Heads
* sdcUnit
->sdcu_Sectors
;
227 sdcUnit
->sdcu_Eject
= FNAME_SDCIO(Eject
);
229 D(bug("[SDCard%02ld] %s: READ_BL_LEN : %dbytes\n", sdcUnit
->sdcu_UnitNum
, __PRETTY_FUNCTION__
, pp
[DE_SIZEBLOCK
+ 4] / sdcUnit
->sdcu_Sectors
));
230 D(bug("[SDCard%02ld] %s: C_SIZE : %d\n", sdcUnit
->sdcu_UnitNum
, __PRETTY_FUNCTION__
, sdcUnit
->sdcu_Cylinders
));
232 pp
[0] = (IPTR
)"MMC0";
233 pp
[1] = (IPTR
)MOD_NAME_STRING
;
235 pp
[DE_TABLESIZE
+ 4] = DE_BOOTBLOCKS
;
236 pp
[DE_NUMHEADS
+ 4] = sdcUnit
->sdcu_Heads
;
237 pp
[DE_BLKSPERTRACK
+ 4] = 1;
238 pp
[DE_RESERVEDBLKS
+ 4] = 2;
239 pp
[DE_LOWCYL
+ 4] = 0;
240 pp
[DE_NUMBUFFERS
+ 4] = 10;
241 pp
[DE_BUFMEMTYPE
+ 4] = MEMF_PUBLIC
| MEMF_31BIT
;
242 pp
[DE_MAXTRANSFER
+ 4] = 0x00200000;
243 pp
[DE_MASK
+ 4] = 0x7FFFFFFE;
244 pp
[DE_BOOTPRI
+ 4] = 0;
245 pp
[DE_DOSTYPE
+ 4] = AROS_MAKE_ID('D','O','S','\001');
246 pp
[DE_CONTROL
+ 4] = 0;
247 pp
[DE_BOOTBLOCKS
+ 4] = 2;
249 devnode
= MakeDosNode(pp
);
253 D(bug("[SDCard%02ld] %s: %b: [%dMB Capacity]\n", sdcUnit
->sdcu_UnitNum
, __PRETTY_FUNCTION__
, devnode
->dn_Name
, sdcUnit
->sdcu_Capacity
>> 11));
254 D(bug("[SDCard%02ld] %s: StartCyl:%d, EndCyl:%d ..\n", sdcUnit
->sdcu_UnitNum
, __PRETTY_FUNCTION__
,
255 pp
[DE_LOWCYL
+ 4], pp
[DE_HIGHCYL
+ 4]));
256 D(bug("[SDCard%02ld] %s: BlockSize:%d, SectorsPerBlock:%d ..\n", sdcUnit
->sdcu_UnitNum
, __PRETTY_FUNCTION__
,
257 pp
[DE_SIZEBLOCK
+ 4], sdcUnit
->sdcu_Sectors
));
259 if (sdcUnit
->sdcu_Flags
& AF_MMC
)
264 FNAME_SDCBUS(SDUnitChangeFrequency
)(sdcUnit
);
267 if (!(sdcUnit
->sdcu_Flags
& AF_HighCapacity
))
269 sdcRegTags
[0].ti_Data
= MMC_CMD_SET_BLOCKLEN
;
270 sdcRegTags
[1].ti_Data
= 1 << sdcUnit
->sdcu_Bus
->sdcb_SectorShift
;
271 sdcRegTags
[2].ti_Data
= MMC_RSP_R1
;
272 sdcRegTags
[3].ti_Data
= 0;
273 if (FNAME_SDCBUS(SendCmd
)(sdcRegTags
, bus
) != -1)
275 D(bug("[SDCard%02ld] %s: Blocklen set to %d\n", sdcUnit
->sdcu_UnitNum
, __PRETTY_FUNCTION__
, sdcRegTags
[1].ti_Data
));
279 D(bug("[SDCard%02ld] %s: Failed to change Blocklen\n", sdcUnit
->sdcu_UnitNum
, __PRETTY_FUNCTION__
));
282 AddBootNode(pp
[DE_BOOTPRI
+ 4], ADNF_STARTPROC
, devnode
, NULL
);
283 D(bug("[SDCard%02ld] %s: done\n", sdcUnit
->sdcu_UnitNum
, __PRETTY_FUNCTION__
));
291 D(bug("[SDCard%02ld] %s: returned error (-1)\n", sdcUnit
->sdcu_UnitNum
, __PRETTY_FUNCTION__
));
296 D(bug("[SDCard>>] %s: Failed to allocate Unit #%d\n", __PRETTY_FUNCTION__
, bus
->sdcb_UnitCnt
));
301 D(bug("error (-1)\n"));
306 D(bug("[SDCard>>] %s: returned error (-1)\n", __PRETTY_FUNCTION__
));
311 D(bug("[SDCard>>] %s: Failed to set card operating conditions\n", __PRETTY_FUNCTION__
));
316 D(bug("[SDCard>>] %s: returned error (-1)\n", __PRETTY_FUNCTION__
));
318 CloseLibrary((struct Library
*)ExpansionBase
);
327 #define VCPOWER_SDHCI 0
328 #define VCPOWER_STATE_ON (1 << 0)
329 #define VCPOWER_STATE_WAIT (1 << 1)
330 #define VCCLOCK_SDHCI 1
333 * This init routine has +127 priority, so it runs after all
334 * bus scanners have done their job.
335 * It initializes all discovered units.
337 static int FNAME_SDC(Scan
)(struct SDCardBase
*SDCardBase
)
339 unsigned int sdcReg
= 0, sdcClkDiv
, timeout
= 10000, timeout_udelay
;
341 D(bug("[SDCard--] %s()\n", __PRETTY_FUNCTION__
));
343 *(volatile unsigned int *)GPSET0
= (1 << 16); // Turn Activity LED OFF
345 SDCardBase
->sdcard_Bus
->sdcb_IntrMask
= SDHCI_INT_BUS_POWER
| SDHCI_INT_DATA_END_BIT
|
346 SDHCI_INT_DATA_CRC
| SDHCI_INT_DATA_TIMEOUT
| SDHCI_INT_INDEX
|
347 SDHCI_INT_END_BIT
| SDHCI_INT_CRC
| SDHCI_INT_TIMEOUT
|
348 SDHCI_INT_CARD_REMOVE
| SDHCI_INT_CARD_INSERT
|
349 SDHCI_INT_DATA_AVAIL
| SDHCI_INT_SPACE_AVAIL
|
350 SDHCI_INT_DMA_END
| SDHCI_INT_DATA_END
| SDHCI_INT_RESPONSE
|
353 FNAME_SDCBUS(MMIOWriteWord
)(SDHCI_CLOCK_CONTROL
, 0, SDCardBase
->sdcard_Bus
);
355 D(bug("[SDCard--] %s: Setting Min Clock... ", __PRETTY_FUNCTION__
));
356 for (sdcClkDiv
= 2; sdcClkDiv
< V300_MAXCLKDIV
; sdcClkDiv
+= 2) {
357 if ((SDCardBase
->sdcard_Bus
->sdcb_ClockMax
/ sdcClkDiv
) <= HOSTCLOCK_MIN
)
361 D(bug("div = %d\n", sdcClkDiv
));
363 sdcReg
= (sdcClkDiv
& SDHCI_DIV_MASK
) << SDHCI_DIVIDER_SHIFT
;
364 sdcReg
|= ((sdcClkDiv
& SDHCI_DIV_HI_MASK
) >> SDHCI_DIV_MASK_LEN
) << SDHCI_DIVIDER_HI_SHIFT
;
365 FNAME_SDCBUS(MMIOWriteWord
)(SDHCI_CLOCK_CONTROL
, (sdcReg
| SDHCI_CLOCK_INT_EN
), SDCardBase
->sdcard_Bus
);
368 while (!((sdcReg
= FNAME_SDCBUS(MMIOReadWord
)(SDHCI_CLOCK_CONTROL
, SDCardBase
->sdcard_Bus
)) & SDHCI_CLOCK_INT_STABLE
)) {
370 D(bug("[SDCard--] %s: SDHCI Clock failed to stabilise\n", __PRETTY_FUNCTION__
));
373 timeout_udelay
= timeout
- 1000;
374 for (; timeout
> timeout_udelay
; timeout
--) asm volatile("mov r0, r0\n");
376 D(bug("[SDCard--] %s: Enabling clock...\n", __PRETTY_FUNCTION__
));
377 sdcReg
|= SDHCI_CLOCK_CARD_EN
;
378 FNAME_SDCBUS(MMIOWriteWord
)(SDHCI_CLOCK_CONTROL
, sdcReg
, SDCardBase
->sdcard_Bus
);
380 D(bug("[SDCard--] %s: Setting Power Lvl... ", __PRETTY_FUNCTION__
));
382 if (SDCardBase
->sdcard_Bus
->sdcb_Power
& MMC_VDD_165_195
)
383 sdcReg
= SDHCI_POWER_180
;
384 else if (SDCardBase
->sdcard_Bus
->sdcb_Power
& (MMC_VDD_290_300
|MMC_VDD_300_310
))
385 sdcReg
= SDHCI_POWER_300
;
386 else if (SDCardBase
->sdcard_Bus
->sdcb_Power
& (MMC_VDD_320_330
|MMC_VDD_330_340
))
387 sdcReg
= SDHCI_POWER_330
;
391 D(bug("%x\n", sdcReg
));
392 FNAME_SDCBUS(MMIOWriteByte
)(SDHCI_POWER_CONTROL
, sdcReg
, SDCardBase
->sdcard_Bus
);
393 sdcReg
|= SDHCI_POWER_ON
;
394 FNAME_SDCBUS(MMIOWriteByte
)(SDHCI_POWER_CONTROL
, sdcReg
, SDCardBase
->sdcard_Bus
);
396 D(bug("[SDCard--] %s: Setting Min Buswidth...\n", __PRETTY_FUNCTION__
));
397 sdcReg
= FNAME_SDCBUS(MMIOReadByte
)(SDHCI_HOST_CONTROL
, SDCardBase
->sdcard_Bus
);
398 sdcReg
&= ~(SDHCI_HCTRL_4BITBUS
|SDHCI_HCTRL_HISPD
);
399 sdcReg
|= SDHCI_HCTRL_4BITBUS
;
400 FNAME_SDCBUS(MMIOWriteByte
)(SDHCI_HOST_CONTROL
, sdcReg
, SDCardBase
->sdcard_Bus
);
402 D(bug("[SDCard--] %s: Masking chipset Interrupts...\n", __PRETTY_FUNCTION__
));
404 FNAME_SDCBUS(MMIOWriteLong
)(SDHCI_INT_ENABLE
, SDCardBase
->sdcard_Bus
->sdcb_IntrMask
, SDCardBase
->sdcard_Bus
);
405 FNAME_SDCBUS(MMIOWriteLong
)(SDHCI_SIGNAL_ENABLE
, SDCardBase
->sdcard_Bus
->sdcb_IntrMask
, SDCardBase
->sdcard_Bus
);
407 D(bug("[SDCard--] %s: Launching Bus Task...\n", __PRETTY_FUNCTION__
));
409 return NewCreateTask(
410 TASKTAG_PC
, FNAME_SDCBUS(BusTask
),
411 TASKTAG_NAME
, "SDCard Subsystem",
412 TASKTAG_STACKSIZE
, STACK_SIZE
,
413 TASKTAG_PRI
, TASK_PRI
,
414 TASKTAG_TASKMSGPORT
, &SDCardBase
->sdcard_Bus
->sdcb_MsgPort
,
415 TASKTAG_ARG1
, SDCardBase
->sdcard_Bus
,
416 TAG_DONE
) ? TRUE
: FALSE
;
419 static int FNAME_SDC(Init
)(struct SDCardBase
*SDCardBase
)
421 D(bug("[SDCard--] %s()\n", __PRETTY_FUNCTION__
));
423 if ((VCMBoxBase
= OpenResource("vcmbox.resource")) == NULL
)
425 D(bug("[SDCard--] %s: Failed to open vcmbox.resource\n", __PRETTY_FUNCTION__
));
429 LIBBASE
->sdcard_MemPool
= CreatePool(MEMF_CLEAR
| MEMF_PUBLIC
| MEMF_SEM_PROTECTED
, 8192, 4096);
430 if (LIBBASE
->sdcard_MemPool
== NULL
)
432 D(bug("[SDCard--] %s: Failed to Allocate MemPool\n", __PRETTY_FUNCTION__
));
436 D(bug("[SDCard--] %s: MemPool @ %p\n", __PRETTY_FUNCTION__
, LIBBASE
->sdcard_MemPool
));
438 VCMBoxMessage
[0] = 8 * 4;
439 VCMBoxMessage
[1] = VCTAG_REQ
;
440 VCMBoxMessage
[2] = VCTAG_GETPOWER
;
441 VCMBoxMessage
[3] = 8;
442 VCMBoxMessage
[4] = 4;
443 VCMBoxMessage
[5] = VCPOWER_SDHCI
;
444 VCMBoxMessage
[6] = 0;
446 VCMBoxMessage
[7] = 0; // terminate tag
448 VCMBoxWrite(VCMB_BASE
, VCMB_PROPCHAN
, VCMBoxMessage
);
449 if (VCMBoxRead(VCMB_BASE
, VCMB_PROPCHAN
) != VCMBoxMessage
)
451 D(bug("[SDCard--] %s: Failed to read controller's Power state\n", __PRETTY_FUNCTION__
));
455 if (!(VCMBoxMessage
[6] & VCPOWER_STATE_ON
))
457 D(bug("[SDCard--] %s: Powering on Arasan SDHCI controller...\n", __PRETTY_FUNCTION__
));
459 VCMBoxMessage
[0] = 8 * 4;
460 VCMBoxMessage
[1] = VCTAG_REQ
;
461 VCMBoxMessage
[2] = VCTAG_SETPOWER
;
462 VCMBoxMessage
[3] = 8;
463 VCMBoxMessage
[4] = 8;
464 VCMBoxMessage
[5] = VCPOWER_SDHCI
;
465 VCMBoxMessage
[6] = VCPOWER_STATE_ON
| VCPOWER_STATE_WAIT
;
467 VCMBoxMessage
[7] = 0; // terminate tag
469 VCMBoxWrite(VCMB_BASE
, VCMB_PROPCHAN
, VCMBoxMessage
);
470 if ((VCMBoxRead(VCMB_BASE
, VCMB_PROPCHAN
) != VCMBoxMessage
) || (!(VCMBoxMessage
[6] & VCPOWER_STATE_ON
)))
472 D(bug("[SDCard--] %s: Failed to power on controller\n", __PRETTY_FUNCTION__
));
477 VCMBoxMessage
[0] = 8 * 4;
478 VCMBoxMessage
[1] = VCTAG_REQ
;
479 VCMBoxMessage
[2] = VCTAG_GETCLKRATE
;
480 VCMBoxMessage
[3] = 8;
481 VCMBoxMessage
[4] = 4;
482 VCMBoxMessage
[5] = VCCLOCK_SDHCI
;
483 VCMBoxMessage
[6] = 0;
485 VCMBoxMessage
[7] = 0; // terminate tag
487 VCMBoxWrite(VCMB_BASE
, VCMB_PROPCHAN
, VCMBoxMessage
);
488 if (VCMBoxRead(VCMB_BASE
, VCMB_PROPCHAN
) != VCMBoxMessage
)
490 D(bug("[SDCard--] %s: Failed to determine Max SDHC Clock\n", __PRETTY_FUNCTION__
));
494 if ((LIBBASE
->sdcard_Bus
= AllocPooled(LIBBASE
->sdcard_MemPool
, sizeof(struct sdcard_Bus
))) != NULL
)
496 LIBBASE
->sdcard_Bus
->sdcb_DeviceBase
= LIBBASE
;
497 LIBBASE
->sdcard_Bus
->sdcb_IOBase
= ARASAN_BASE
;
498 LIBBASE
->sdcard_Bus
->sdcb_SectorShift
= 9;
500 LIBBASE
->sdcard_Bus
->sdcb_ClockMax
= VCMBoxMessage
[6];
502 D(bug("[SDCard--] %s: Reseting SDHCI...\n", __PRETTY_FUNCTION__
));
504 FNAME_SDCBUS(SoftReset
)(SDHCI_RESET_ALL
, LIBBASE
->sdcard_Bus
);
506 D(bug("[SDCard--] %s: SDHC Max Clock Rate : %dMHz\n", __PRETTY_FUNCTION__
, LIBBASE
->sdcard_Bus
->sdcb_ClockMax
/ 1000000));
507 D(bug("[SDCard--] %s: SDHC Min Clock Rate : %dHz (hardcoded)\n", __PRETTY_FUNCTION__
, HOSTCLOCK_MIN
));
509 LIBBASE
->sdcard_Bus
->sdcb_Version
= FNAME_SDCBUS(MMIOReadWord
)(SDHCI_HOST_VERSION
, LIBBASE
->sdcard_Bus
);
510 LIBBASE
->sdcard_Bus
->sdcb_Capabilities
= FNAME_SDCBUS(MMIOReadLong
)(SDHCI_CAPABILITIES
, LIBBASE
->sdcard_Bus
);
511 LIBBASE
->sdcard_Bus
->sdcb_Power
= MMC_VDD_165_195
| MMC_VDD_320_330
| MMC_VDD_330_340
;
513 D(bug("[SDCard--] %s: SDHCI Host Vers : %d [SD Host Spec %d]\n", __PRETTY_FUNCTION__
, ((LIBBASE
->sdcard_Bus
->sdcb_Version
& 0xFF00) >> 8), (LIBBASE
->sdcard_Bus
->sdcb_Version
& 0xFF) + 1));
514 D(bug("[SDCard--] %s: SDHCI Capabilities : 0x%08x\n", __PRETTY_FUNCTION__
, LIBBASE
->sdcard_Bus
->sdcb_Capabilities
));
515 D(bug("[SDCard--] %s: SDHCI Voltages : 0x%08x (hardcoded)\n", __PRETTY_FUNCTION__
, LIBBASE
->sdcard_Bus
->sdcb_Power
));
517 LIBBASE
->sdcard_Bus
->sdcb_LastWrite
= *((volatile unsigned int *)(SYSTIMER_CLO
));
522 static int FNAME_SDC(Open
)
524 LIBBASETYPEPTR LIBBASE
,
525 struct IORequest
*iorq
,
530 unsigned int sdcReg
= 0, sdcClkDiv
, timeout
= 10000, timeout_udelay
;
532 D(bug("[SDCard--] %s()\n", __PRETTY_FUNCTION__
));
534 /* Assume it failed */
535 iorq
->io_Error
= IOERR_OPENFAIL
;
537 if ((unitnum
< LIBBASE
->sdcard_Bus
->sdcb_UnitCnt
) && (LIBBASE
->sdcard_Bus
->sdcb_Units
[unitnum
]))
539 struct TagItem sdcOpenTags
[] =
541 {SDCARD_TAG_CMD
, MMC_CMD_SELECT_CARD
},
542 {SDCARD_TAG_ARG
, LIBBASE
->sdcard_Bus
->sdcb_Units
[unitnum
]->sdcu_CardRCA
<< 16},
543 {SDCARD_TAG_RSPTYPE
, MMC_RSP_R1
},
547 if (FNAME_SDCBUS(SendCmd
)(sdcOpenTags
, LIBBASE
->sdcard_Bus
) != -1)
549 iorq
->io_Unit
= &LIBBASE
->sdcard_Bus
->sdcb_Units
[unitnum
]->sdcu_Unit
;
550 ((struct sdcard_Unit
*)iorq
->io_Unit
)->sdcu_Unit
.unit_OpenCnt
++;
552 D(bug("[SDCard%02ld] %s: Selected card with RCA %d\n", unitnum
, __PRETTY_FUNCTION__
, LIBBASE
->sdcard_Bus
->sdcb_Units
[unitnum
]->sdcu_CardRCA
));
553 D(bug("[SDCard%02ld] %s: Card is now operating in Transfer Mode\n", unitnum
, __PRETTY_FUNCTION__
));
555 FNAME_SDCBUS(MMIOWriteWord
)(SDHCI_CLOCK_CONTROL
, 0, LIBBASE
->sdcard_Bus
);
557 D(bug("[SDCard%02ld] %s: Setting Clock... ", unitnum
, __PRETTY_FUNCTION__
));
558 for (sdcClkDiv
= 2; sdcClkDiv
< V300_MAXCLKDIV
; sdcClkDiv
+= 2) {
559 if ((LIBBASE
->sdcard_Bus
->sdcb_ClockMax
/ sdcClkDiv
) <= 25000000)
563 D(bug("div = %d\n", sdcClkDiv
));
565 sdcReg
= (sdcClkDiv
& SDHCI_DIV_MASK
) << SDHCI_DIVIDER_SHIFT
;
566 sdcReg
|= ((sdcClkDiv
& SDHCI_DIV_HI_MASK
) >> SDHCI_DIV_MASK_LEN
) << SDHCI_DIVIDER_HI_SHIFT
;
567 FNAME_SDCBUS(MMIOWriteWord
)(SDHCI_CLOCK_CONTROL
, (sdcReg
| SDHCI_CLOCK_INT_EN
), LIBBASE
->sdcard_Bus
);
570 while (!((sdcReg
= FNAME_SDCBUS(MMIOReadWord
)(SDHCI_CLOCK_CONTROL
, LIBBASE
->sdcard_Bus
)) & SDHCI_CLOCK_INT_STABLE
)) {
572 D(bug("[SDCard%02ld] %s: SDHCI Clock failed to stabilise\n", unitnum
, __PRETTY_FUNCTION__
));
575 timeout_udelay
= timeout
- 1000;
576 for (; timeout
> timeout_udelay
; timeout
--) asm volatile("mov r0, r0\n");
578 D(bug("[SDCard%02ld] %s: Enabling clock...\n", unitnum
, __PRETTY_FUNCTION__
));
579 sdcReg
|= SDHCI_CLOCK_CARD_EN
;
580 FNAME_SDCBUS(MMIOWriteWord
)(SDHCI_CLOCK_CONTROL
, sdcReg
, LIBBASE
->sdcard_Bus
);
585 return iorq
->io_Error
? FALSE
: TRUE
;
588 /* Close given device */
589 static int FNAME_SDC(Close
)
591 LIBBASETYPEPTR LIBBASE
,
592 struct IORequest
*iorq
595 struct sdcard_Unit
*unit
= (struct sdcard_Unit
*)iorq
->io_Unit
;
597 D(bug("[SDCard--] %s()\n", __PRETTY_FUNCTION__
));
599 /* First of all make the important fields of struct IORequest invalid! */
600 iorq
->io_Unit
= (struct Unit
*)~0;
602 /* Decrease use counters of unit */
603 unit
->sdcu_Unit
.unit_OpenCnt
--;
608 ADD2INITLIB(FNAME_SDC(Init
), 0)
609 ADD2INITLIB(FNAME_SDC(Scan
), 127)
610 ADD2OPENDEV(FNAME_SDC(Open
), 0)
611 ADD2CLOSEDEV(FNAME_SDC(Close
), 0)