2 Copyright © 2013-2015, 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] = 8 * 4;
43 MBoxMessage
[1] = VCTAG_REQ
;
44 MBoxMessage
[2] = VCTAG_GETPOWER
;
47 MBoxMessage
[5] = 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 (!(MBoxMessage
[6] & VCPOWER_STATE_ON
))
61 DINIT(bug("[SDCard--] %s: Powering on Arasan SDHCI controller...\n", __PRETTY_FUNCTION__
));
63 MBoxMessage
[0] = 8 * 4;
64 MBoxMessage
[1] = VCTAG_REQ
;
65 MBoxMessage
[2] = VCTAG_SETPOWER
;
68 MBoxMessage
[5] = VCPOWER_SDHCI
;
69 MBoxMessage
[6] = 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
) || (!(MBoxMessage
[6] & VCPOWER_STATE_ON
)))
76 DINIT(bug("[SDCard--] %s: Failed to power on controller\n", __PRETTY_FUNCTION__
));
81 MBoxMessage
[0] = 8 * 4;
82 MBoxMessage
[1] = VCTAG_REQ
;
83 MBoxMessage
[2] = VCTAG_GETCLKRATE
;
86 MBoxMessage
[5] = 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
= MBoxMessage
[6];
105 __BCM2708Bus
->sdcb_ClockMin
= BCM2708SDCLOCK_MIN
;
107 __BCM2708Bus
->sdcb_LEDCtrl
= 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
)