2 Copyright © 2013-2019, The AROS Development Team. All rights reserved.
7 #include <aros/debug.h>
9 #include <proto/exec.h>
10 #include <proto/mbox.h>
11 #include <proto/kernel.h>
13 #include <hardware/mmc.h>
14 #include <hardware/sdhc.h>
16 #include "sdcard_intern.h"
19 #include <hardware/arasan.h>
20 #include <hardware/videocore.h>
23 IPTR __arm_periiobase
__attribute__((used
)) = 0 ;
25 static int FNAME_BCMSDC(BCM2708Init
)(struct SDCardBase
*SDCardBase
)
27 struct sdcard_Bus
*__BCM2708Bus
;
29 unsigned int *MBoxMessage_
= AllocMem(8*4+16, MEMF_PUBLIC
| MEMF_CLEAR
);
30 unsigned int *MBoxMessage
= (unsigned int *)((((IPTR
)MBoxMessage_
) + 15) & ~15);
32 DINIT(bug("[SDCard--] %s()\n", __PRETTY_FUNCTION__
));
34 __arm_periiobase
= KrnGetSystemAttr(KATTR_PeripheralBase
);
36 if ((MBoxBase
= OpenResource("mbox.resource")) == NULL
)
38 bug("[SDCard--] %s: Failed to open mbox.resource\n", __PRETTY_FUNCTION__
);
42 MBoxMessage
[0] = AROS_LONG2LE(8 * 4);
43 MBoxMessage
[1] = AROS_LONG2LE(VCTAG_REQ
);
44 MBoxMessage
[2] = AROS_LONG2LE(VCTAG_GETPOWER
);
45 MBoxMessage
[3] = AROS_LONG2LE(8);
46 MBoxMessage
[4] = AROS_LONG2LE(4);
47 MBoxMessage
[5] = AROS_LONG2LE(VCPOWER_SDHCI
);
50 MBoxMessage
[7] = 0; // terminate tag
52 MBoxWrite((APTR
)VCMB_BASE
, VCMB_PROPCHAN
, MBoxMessage
);
53 if (MBoxRead((APTR
)VCMB_BASE
, VCMB_PROPCHAN
) != MBoxMessage
)
55 DINIT(bug("[SDCard--] %s: Failed to read controller's Power state\n", __PRETTY_FUNCTION__
));
59 if (!(AROS_LE2LONG(MBoxMessage
[6]) & VCPOWER_STATE_ON
))
61 DINIT(bug("[SDCard--] %s: Powering on Arasan SDHCI controller...\n", __PRETTY_FUNCTION__
));
63 MBoxMessage
[0] = AROS_LONG2LE(8 * 4);
64 MBoxMessage
[1] = AROS_LONG2LE(VCTAG_REQ
);
65 MBoxMessage
[2] = AROS_LONG2LE(VCTAG_SETPOWER
);
66 MBoxMessage
[3] = AROS_LONG2LE(8);
67 MBoxMessage
[4] = AROS_LONG2LE(8);
68 MBoxMessage
[5] = AROS_LONG2LE(VCPOWER_SDHCI
);
69 MBoxMessage
[6] = AROS_LONG2LE(VCPOWER_STATE_ON
| VCPOWER_STATE_WAIT
);
71 MBoxMessage
[7] = 0; // terminate tag
73 MBoxWrite((APTR
)VCMB_BASE
, VCMB_PROPCHAN
, MBoxMessage
);
74 if ((MBoxRead((APTR
)VCMB_BASE
, VCMB_PROPCHAN
) != MBoxMessage
) || (!(AROS_LE2LONG(MBoxMessage
[6]) & VCPOWER_STATE_ON
)))
76 DINIT(bug("[SDCard--] %s: Failed to power on controller\n", __PRETTY_FUNCTION__
));
81 MBoxMessage
[0] = AROS_LONG2LE(8 * 4);
82 MBoxMessage
[1] = AROS_LONG2LE(VCTAG_REQ
);
83 MBoxMessage
[2] = AROS_LONG2LE(VCTAG_GETCLKRATE
);
84 MBoxMessage
[3] = AROS_LONG2LE(8);
85 MBoxMessage
[4] = AROS_LONG2LE(4);
86 MBoxMessage
[5] = AROS_LONG2LE(VCCLOCK_SDHCI
);
89 MBoxMessage
[7] = 0; // terminate tag
91 MBoxWrite((APTR
)VCMB_BASE
, VCMB_PROPCHAN
, MBoxMessage
);
92 if (MBoxRead((APTR
)VCMB_BASE
, VCMB_PROPCHAN
) != MBoxMessage
)
94 DINIT(bug("[SDCard--] %s: Failed to determine Max SDHC Clock\n", __PRETTY_FUNCTION__
));
98 if ((__BCM2708Bus
= AllocPooled(SDCardBase
->sdcard_MemPool
, sizeof(struct sdcard_Bus
))) != NULL
)
100 __BCM2708Bus
->sdcb_DeviceBase
= SDCardBase
;
101 __BCM2708Bus
->sdcb_IOBase
= (APTR
)ARASAN_BASE
;
102 __BCM2708Bus
->sdcb_BusIRQ
= IRQ_VC_ARASANSDIO
;
104 __BCM2708Bus
->sdcb_ClockMax
= AROS_LE2LONG(MBoxMessage
[6]);
105 __BCM2708Bus
->sdcb_ClockMin
= BCM2708SDCLOCK_MIN
;
107 __BCM2708Bus
->sdcb_LEDCtrl
= (BYTE (*)(int))FNAME_BCMSDCBUS(BCMLEDCtrl
);
108 __BCM2708Bus
->sdcb_IOReadByte
= FNAME_BCMSDCBUS(BCMMMIOReadByte
);
109 __BCM2708Bus
->sdcb_IOReadWord
= FNAME_BCMSDCBUS(BCMMMIOReadWord
);
110 __BCM2708Bus
->sdcb_IOReadLong
= FNAME_BCMSDCBUS(BCMMMIOReadLong
);
112 __BCM2708Bus
->sdcb_IOWriteByte
= FNAME_BCMSDCBUS(BCMMMIOWriteByte
);
113 __BCM2708Bus
->sdcb_IOWriteWord
= FNAME_BCMSDCBUS(BCMMMIOWriteWord
);
114 __BCM2708Bus
->sdcb_IOWriteLong
= FNAME_BCMSDCBUS(BCMMMIOWriteLong
);
116 if ((__BCM2708Bus
->sdcb_BusUnits
= AllocPooled(SDCardBase
->sdcard_MemPool
, sizeof(struct sdcard_BusUnits
))) != NULL
)
118 ObtainSemaphore(&SDCardBase
->sdcard_BusSem
);
119 __BCM2708Bus
->sdcb_BusUnits
->sdcbu_UnitBase
= SDCardBase
->sdcard_TotalBusUnits
;
120 __BCM2708Bus
->sdcb_BusUnits
->sdcbu_UnitMax
= BCM2708SDUNIT_MAX
;
121 SDCardBase
->sdcard_TotalBusUnits
+= __BCM2708Bus
->sdcb_BusUnits
->sdcbu_UnitMax
;
122 __BCM2708Bus
->sdcb_BusNum
= SDCardBase
->sdcard_BusCnt
++;
123 ReleaseSemaphore(&SDCardBase
->sdcard_BusSem
);
125 DINIT(bug("[SDCard--] %s: Bus #%02u - %u Unit(s) starting from %02u\n", __PRETTY_FUNCTION__
,
126 __BCM2708Bus
->sdcb_BusNum
,
127 __BCM2708Bus
->sdcb_BusUnits
->sdcbu_UnitMax
,
128 __BCM2708Bus
->sdcb_BusUnits
->sdcbu_UnitBase
));
130 __BCM2708Bus
->sdcb_SectorShift
= 9;
132 DINIT(bug("[SDCard--] %s: Reseting SDHCI...\n", __PRETTY_FUNCTION__
));
134 FNAME_SDCBUS(SoftReset
)(SDHCI_RESET_ALL
, __BCM2708Bus
);
136 DINIT(bug("[SDCard--] %s: SDHC Max Clock Rate : %dMHz\n", __PRETTY_FUNCTION__
, __BCM2708Bus
->sdcb_ClockMax
/ 1000000));
137 DINIT(bug("[SDCard--] %s: SDHC Min Clock Rate : %dHz (hardcoded)\n", __PRETTY_FUNCTION__
, __BCM2708Bus
->sdcb_ClockMin
));
139 __BCM2708Bus
->sdcb_Version
= FNAME_BCMSDCBUS(BCMMMIOReadWord
)(SDHCI_HOST_VERSION
, __BCM2708Bus
);
140 __BCM2708Bus
->sdcb_Capabilities
= FNAME_BCMSDCBUS(BCMMMIOReadLong
)(SDHCI_CAPABILITIES
, __BCM2708Bus
);
141 __BCM2708Bus
->sdcb_Quirks
= AB_Quirk_MissingCapabilities
|AF_Quirk_AtomicTMAndCMD
;
142 __BCM2708Bus
->sdcb_Power
= MMC_VDD_165_195
| MMC_VDD_320_330
| MMC_VDD_330_340
;
144 DINIT(bug("[SDCard--] %s: SDHCI Host Vers : %d [SD Host Spec %d]\n", __PRETTY_FUNCTION__
, ((__BCM2708Bus
->sdcb_Version
& 0xFF00) >> 8), (__BCM2708Bus
->sdcb_Version
& 0xFF) + 1));
145 DINIT(bug("[SDCard--] %s: SDHCI Capabilities : 0x%08x\n", __PRETTY_FUNCTION__
, __BCM2708Bus
->sdcb_Capabilities
));
146 DINIT(bug("[SDCard--] %s: SDHCI Voltages : 0x%08x (hardcoded)\n", __PRETTY_FUNCTION__
, __BCM2708Bus
->sdcb_Power
));
148 __BCM2708Bus
->sdcb_Private
= (IPTR
)sdcard_CurrentTime();
150 FNAME_SDC(RegisterBus
)(__BCM2708Bus
, SDCardBase
);
156 FreePooled(SDCardBase
->sdcard_MemPool
, __BCM2708Bus
, sizeof(struct sdcard_Bus
));
162 FreeMem(MBoxMessage_
, 8*4+16);
167 ADD2INITLIB(FNAME_BCMSDC(BCM2708Init
), SDCARD_BUSINITPRIO
)