2 Copyright © 2013, The AROS Development Team. All rights reserved.
7 #include <aros/debug.h>
9 #include <proto/exec.h>
10 #include <proto/vcmbox.h>
12 #include <asm/bcm2835.h>
13 #include <hardware/arasan.h>
14 #include <hardware/videocore.h>
16 #include <hardware/mmc.h>
17 #include <hardware/sdhc.h>
19 #include "sdcard_intern.h"
23 unsigned int VCMBoxMessage
[8] __attribute__((used
, aligned(16)));
25 static int FNAME_BCMSDC(BCM2835Init
)(struct SDCardBase
*SDCardBase
)
27 struct sdcard_Bus
*__BCM2835Bus
;
30 DINIT(bug("[SDCard--] %s()\n", __PRETTY_FUNCTION__
));
32 if ((VCMBoxBase
= OpenResource("vcmbox.resource")) == NULL
)
34 bug("[SDCard--] %s: Failed to open vcmbox.resource\n", __PRETTY_FUNCTION__
);
38 VCMBoxMessage
[0] = 8 * 4;
39 VCMBoxMessage
[1] = VCTAG_REQ
;
40 VCMBoxMessage
[2] = VCTAG_GETPOWER
;
43 VCMBoxMessage
[5] = VCPOWER_SDHCI
;
46 VCMBoxMessage
[7] = 0; // terminate tag
48 VCMBoxWrite((APTR
)VCMB_BASE
, VCMB_PROPCHAN
, VCMBoxMessage
);
49 if (VCMBoxRead((APTR
)VCMB_BASE
, VCMB_PROPCHAN
) != VCMBoxMessage
)
51 DINIT(bug("[SDCard--] %s: Failed to read controller's Power state\n", __PRETTY_FUNCTION__
));
55 if (!(VCMBoxMessage
[6] & VCPOWER_STATE_ON
))
57 DINIT(bug("[SDCard--] %s: Powering on Arasan SDHCI controller...\n", __PRETTY_FUNCTION__
));
59 VCMBoxMessage
[0] = 8 * 4;
60 VCMBoxMessage
[1] = VCTAG_REQ
;
61 VCMBoxMessage
[2] = VCTAG_SETPOWER
;
64 VCMBoxMessage
[5] = VCPOWER_SDHCI
;
65 VCMBoxMessage
[6] = VCPOWER_STATE_ON
| VCPOWER_STATE_WAIT
;
67 VCMBoxMessage
[7] = 0; // terminate tag
69 VCMBoxWrite((APTR
)VCMB_BASE
, VCMB_PROPCHAN
, VCMBoxMessage
);
70 if ((VCMBoxRead((APTR
)VCMB_BASE
, VCMB_PROPCHAN
) != VCMBoxMessage
) || (!(VCMBoxMessage
[6] & VCPOWER_STATE_ON
)))
72 DINIT(bug("[SDCard--] %s: Failed to power on controller\n", __PRETTY_FUNCTION__
));
77 VCMBoxMessage
[0] = 8 * 4;
78 VCMBoxMessage
[1] = VCTAG_REQ
;
79 VCMBoxMessage
[2] = VCTAG_GETCLKRATE
;
82 VCMBoxMessage
[5] = VCCLOCK_SDHCI
;
85 VCMBoxMessage
[7] = 0; // terminate tag
87 VCMBoxWrite((APTR
)VCMB_BASE
, VCMB_PROPCHAN
, VCMBoxMessage
);
88 if (VCMBoxRead((APTR
)VCMB_BASE
, VCMB_PROPCHAN
) != VCMBoxMessage
)
90 DINIT(bug("[SDCard--] %s: Failed to determine Max SDHC Clock\n", __PRETTY_FUNCTION__
));
94 if ((__BCM2835Bus
= AllocPooled(SDCardBase
->sdcard_MemPool
, sizeof(struct sdcard_Bus
))) != NULL
)
96 __BCM2835Bus
->sdcb_DeviceBase
= SDCardBase
;
97 __BCM2835Bus
->sdcb_IOBase
= (APTR
)ARASAN_BASE
;
98 __BCM2835Bus
->sdcb_BusIRQ
= IRQ_VC_ARASANSDIO
;
100 __BCM2835Bus
->sdcb_ClockMax
= VCMBoxMessage
[6];
101 __BCM2835Bus
->sdcb_ClockMin
= BCM2835SDCLOCK_MIN
;
103 __BCM2835Bus
->sdcb_LEDCtrl
= FNAME_BCMSDCBUS(BCMLEDCtrl
);
104 __BCM2835Bus
->sdcb_IOReadByte
= FNAME_BCMSDCBUS(BCMMMIOReadByte
);
105 __BCM2835Bus
->sdcb_IOReadWord
= FNAME_BCMSDCBUS(BCMMMIOReadWord
);
106 __BCM2835Bus
->sdcb_IOReadLong
= FNAME_BCMSDCBUS(BCMMMIOReadLong
);
108 __BCM2835Bus
->sdcb_IOWriteByte
= FNAME_BCMSDCBUS(BCMMMIOWriteByte
);
109 __BCM2835Bus
->sdcb_IOWriteWord
= FNAME_BCMSDCBUS(BCMMMIOWriteWord
);
110 __BCM2835Bus
->sdcb_IOWriteLong
= FNAME_BCMSDCBUS(BCMMMIOWriteLong
);
112 if ((__BCM2835Bus
->sdcb_BusUnits
= AllocPooled(SDCardBase
->sdcard_MemPool
, sizeof(struct sdcard_BusUnits
))) != NULL
)
114 ObtainSemaphore(&SDCardBase
->sdcard_BusSem
);
115 __BCM2835Bus
->sdcb_BusUnits
->sdcbu_UnitBase
= SDCardBase
->sdcard_TotalBusUnits
;
116 __BCM2835Bus
->sdcb_BusUnits
->sdcbu_UnitMax
= BCM2835SDUNIT_MAX
;
117 SDCardBase
->sdcard_TotalBusUnits
+= __BCM2835Bus
->sdcb_BusUnits
->sdcbu_UnitMax
;
118 __BCM2835Bus
->sdcb_BusNum
= SDCardBase
->sdcard_BusCnt
++;
119 ReleaseSemaphore(&SDCardBase
->sdcard_BusSem
);
121 DINIT(bug("[SDCard--] %s: Bus #%02u - %u Unit(s) starting from %02u\n", __PRETTY_FUNCTION__
,
122 __BCM2835Bus
->sdcb_BusNum
,
123 __BCM2835Bus
->sdcb_BusUnits
->sdcbu_UnitMax
,
124 __BCM2835Bus
->sdcb_BusUnits
->sdcbu_UnitBase
));
126 __BCM2835Bus
->sdcb_SectorShift
= 9;
128 DINIT(bug("[SDCard--] %s: Reseting SDHCI...\n", __PRETTY_FUNCTION__
));
130 FNAME_SDCBUS(SoftReset
)(SDHCI_RESET_ALL
, __BCM2835Bus
);
132 DINIT(bug("[SDCard--] %s: SDHC Max Clock Rate : %dMHz\n", __PRETTY_FUNCTION__
, __BCM2835Bus
->sdcb_ClockMax
/ 1000000));
133 DINIT(bug("[SDCard--] %s: SDHC Min Clock Rate : %dHz (hardcoded)\n", __PRETTY_FUNCTION__
, __BCM2835Bus
->sdcb_ClockMin
));
135 __BCM2835Bus
->sdcb_Version
= FNAME_BCMSDCBUS(BCMMMIOReadWord
)(SDHCI_HOST_VERSION
, __BCM2835Bus
);
136 __BCM2835Bus
->sdcb_Capabilities
= FNAME_BCMSDCBUS(BCMMMIOReadLong
)(SDHCI_CAPABILITIES
, __BCM2835Bus
);
137 __BCM2835Bus
->sdcb_Quirks
= AB_Quirk_MissingCapabilities
|AF_Quirk_AtomicTMAndCMD
;
138 __BCM2835Bus
->sdcb_Power
= MMC_VDD_165_195
| MMC_VDD_320_330
| MMC_VDD_330_340
;
140 DINIT(bug("[SDCard--] %s: SDHCI Host Vers : %d [SD Host Spec %d]\n", __PRETTY_FUNCTION__
, ((__BCM2835Bus
->sdcb_Version
& 0xFF00) >> 8), (__BCM2835Bus
->sdcb_Version
& 0xFF) + 1));
141 DINIT(bug("[SDCard--] %s: SDHCI Capabilities : 0x%08x\n", __PRETTY_FUNCTION__
, __BCM2835Bus
->sdcb_Capabilities
));
142 DINIT(bug("[SDCard--] %s: SDHCI Voltages : 0x%08x (hardcoded)\n", __PRETTY_FUNCTION__
, __BCM2835Bus
->sdcb_Power
));
144 __BCM2835Bus
->sdcb_Private
= (IPTR
)sdcard_CurrentTime();
146 FNAME_SDC(RegisterBus
)(__BCM2835Bus
, SDCardBase
);
152 FreePooled(SDCardBase
->sdcard_MemPool
, __BCM2835Bus
, sizeof(struct sdcard_Bus
));
160 ADD2INITLIB(FNAME_BCMSDC(BCM2835Init
), SDCARD_BUSINITPRIO
)