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>
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 unsigned int VCMBoxMessage
[8] __attribute__((used
, aligned(16)));
24 IPTR __arm_periiobase
__attribute__((used
)) = 0 ;
26 static int FNAME_BCMSDC(BCM283xInit
)(struct SDCardBase
*SDCardBase
)
28 struct sdcard_Bus
*__BCM283xBus
;
31 DINIT(bug("[SDCard--] %s()\n", __PRETTY_FUNCTION__
));
33 __arm_periiobase
= KrnGetSystemAttr(KATTR_PeripheralBase
);
35 if ((VCMBoxBase
= OpenResource("vcmbox.resource")) == NULL
)
37 bug("[SDCard--] %s: Failed to open vcmbox.resource\n", __PRETTY_FUNCTION__
);
41 VCMBoxMessage
[0] = 8 * 4;
42 VCMBoxMessage
[1] = VCTAG_REQ
;
43 VCMBoxMessage
[2] = VCTAG_GETPOWER
;
46 VCMBoxMessage
[5] = VCPOWER_SDHCI
;
49 VCMBoxMessage
[7] = 0; // terminate tag
51 VCMBoxWrite((APTR
)VCMB_BASE
, VCMB_PROPCHAN
, VCMBoxMessage
);
52 if (VCMBoxRead((APTR
)VCMB_BASE
, VCMB_PROPCHAN
) != VCMBoxMessage
)
54 DINIT(bug("[SDCard--] %s: Failed to read controller's Power state\n", __PRETTY_FUNCTION__
));
58 if (!(VCMBoxMessage
[6] & VCPOWER_STATE_ON
))
60 DINIT(bug("[SDCard--] %s: Powering on Arasan SDHCI controller...\n", __PRETTY_FUNCTION__
));
62 VCMBoxMessage
[0] = 8 * 4;
63 VCMBoxMessage
[1] = VCTAG_REQ
;
64 VCMBoxMessage
[2] = VCTAG_SETPOWER
;
67 VCMBoxMessage
[5] = VCPOWER_SDHCI
;
68 VCMBoxMessage
[6] = VCPOWER_STATE_ON
| VCPOWER_STATE_WAIT
;
70 VCMBoxMessage
[7] = 0; // terminate tag
72 VCMBoxWrite((APTR
)VCMB_BASE
, VCMB_PROPCHAN
, VCMBoxMessage
);
73 if ((VCMBoxRead((APTR
)VCMB_BASE
, VCMB_PROPCHAN
) != VCMBoxMessage
) || (!(VCMBoxMessage
[6] & VCPOWER_STATE_ON
)))
75 DINIT(bug("[SDCard--] %s: Failed to power on controller\n", __PRETTY_FUNCTION__
));
80 VCMBoxMessage
[0] = 8 * 4;
81 VCMBoxMessage
[1] = VCTAG_REQ
;
82 VCMBoxMessage
[2] = VCTAG_GETCLKRATE
;
85 VCMBoxMessage
[5] = VCCLOCK_SDHCI
;
88 VCMBoxMessage
[7] = 0; // terminate tag
90 VCMBoxWrite((APTR
)VCMB_BASE
, VCMB_PROPCHAN
, VCMBoxMessage
);
91 if (VCMBoxRead((APTR
)VCMB_BASE
, VCMB_PROPCHAN
) != VCMBoxMessage
)
93 DINIT(bug("[SDCard--] %s: Failed to determine Max SDHC Clock\n", __PRETTY_FUNCTION__
));
97 if ((__BCM283xBus
= AllocPooled(SDCardBase
->sdcard_MemPool
, sizeof(struct sdcard_Bus
))) != NULL
)
99 __BCM283xBus
->sdcb_DeviceBase
= SDCardBase
;
100 __BCM283xBus
->sdcb_IOBase
= (APTR
)ARASAN_BASE
;
101 __BCM283xBus
->sdcb_BusIRQ
= IRQ_VC_ARASANSDIO
;
103 __BCM283xBus
->sdcb_ClockMax
= VCMBoxMessage
[6];
104 __BCM283xBus
->sdcb_ClockMin
= BCM283xSDCLOCK_MIN
;
106 __BCM283xBus
->sdcb_LEDCtrl
= FNAME_BCMSDCBUS(BCMLEDCtrl
);
107 __BCM283xBus
->sdcb_IOReadByte
= FNAME_BCMSDCBUS(BCMMMIOReadByte
);
108 __BCM283xBus
->sdcb_IOReadWord
= FNAME_BCMSDCBUS(BCMMMIOReadWord
);
109 __BCM283xBus
->sdcb_IOReadLong
= FNAME_BCMSDCBUS(BCMMMIOReadLong
);
111 __BCM283xBus
->sdcb_IOWriteByte
= FNAME_BCMSDCBUS(BCMMMIOWriteByte
);
112 __BCM283xBus
->sdcb_IOWriteWord
= FNAME_BCMSDCBUS(BCMMMIOWriteWord
);
113 __BCM283xBus
->sdcb_IOWriteLong
= FNAME_BCMSDCBUS(BCMMMIOWriteLong
);
115 if ((__BCM283xBus
->sdcb_BusUnits
= AllocPooled(SDCardBase
->sdcard_MemPool
, sizeof(struct sdcard_BusUnits
))) != NULL
)
117 ObtainSemaphore(&SDCardBase
->sdcard_BusSem
);
118 __BCM283xBus
->sdcb_BusUnits
->sdcbu_UnitBase
= SDCardBase
->sdcard_TotalBusUnits
;
119 __BCM283xBus
->sdcb_BusUnits
->sdcbu_UnitMax
= BCM283xSDUNIT_MAX
;
120 SDCardBase
->sdcard_TotalBusUnits
+= __BCM283xBus
->sdcb_BusUnits
->sdcbu_UnitMax
;
121 __BCM283xBus
->sdcb_BusNum
= SDCardBase
->sdcard_BusCnt
++;
122 ReleaseSemaphore(&SDCardBase
->sdcard_BusSem
);
124 DINIT(bug("[SDCard--] %s: Bus #%02u - %u Unit(s) starting from %02u\n", __PRETTY_FUNCTION__
,
125 __BCM283xBus
->sdcb_BusNum
,
126 __BCM283xBus
->sdcb_BusUnits
->sdcbu_UnitMax
,
127 __BCM283xBus
->sdcb_BusUnits
->sdcbu_UnitBase
));
129 __BCM283xBus
->sdcb_SectorShift
= 9;
131 DINIT(bug("[SDCard--] %s: Reseting SDHCI...\n", __PRETTY_FUNCTION__
));
133 FNAME_SDCBUS(SoftReset
)(SDHCI_RESET_ALL
, __BCM283xBus
);
135 DINIT(bug("[SDCard--] %s: SDHC Max Clock Rate : %dMHz\n", __PRETTY_FUNCTION__
, __BCM283xBus
->sdcb_ClockMax
/ 1000000));
136 DINIT(bug("[SDCard--] %s: SDHC Min Clock Rate : %dHz (hardcoded)\n", __PRETTY_FUNCTION__
, __BCM283xBus
->sdcb_ClockMin
));
138 __BCM283xBus
->sdcb_Version
= FNAME_BCMSDCBUS(BCMMMIOReadWord
)(SDHCI_HOST_VERSION
, __BCM283xBus
);
139 __BCM283xBus
->sdcb_Capabilities
= FNAME_BCMSDCBUS(BCMMMIOReadLong
)(SDHCI_CAPABILITIES
, __BCM283xBus
);
140 __BCM283xBus
->sdcb_Quirks
= AB_Quirk_MissingCapabilities
|AF_Quirk_AtomicTMAndCMD
;
141 __BCM283xBus
->sdcb_Power
= MMC_VDD_165_195
| MMC_VDD_320_330
| MMC_VDD_330_340
;
143 DINIT(bug("[SDCard--] %s: SDHCI Host Vers : %d [SD Host Spec %d]\n", __PRETTY_FUNCTION__
, ((__BCM283xBus
->sdcb_Version
& 0xFF00) >> 8), (__BCM283xBus
->sdcb_Version
& 0xFF) + 1));
144 DINIT(bug("[SDCard--] %s: SDHCI Capabilities : 0x%08x\n", __PRETTY_FUNCTION__
, __BCM283xBus
->sdcb_Capabilities
));
145 DINIT(bug("[SDCard--] %s: SDHCI Voltages : 0x%08x (hardcoded)\n", __PRETTY_FUNCTION__
, __BCM283xBus
->sdcb_Power
));
147 __BCM283xBus
->sdcb_Private
= (IPTR
)sdcard_CurrentTime();
149 FNAME_SDC(RegisterBus
)(__BCM283xBus
, SDCardBase
);
155 FreePooled(SDCardBase
->sdcard_MemPool
, __BCM283xBus
, sizeof(struct sdcard_Bus
));
163 ADD2INITLIB(FNAME_BCMSDC(BCM283xInit
), SDCARD_BUSINITPRIO
)