Commit b1569c4f authored by Ben Avison's avatar Ben Avison Committed by ROOL

Support EMMC2 controller

This controller is now preferred over the legacy EMMC controller, and it is
capable of UHS speeds (pending support in SDIODriver).

Requires RiscOS/Sources/HWSupport/SD/SDIODriver!4
parent 07348d58
......@@ -391,7 +391,6 @@ GPAFEDE1 * &8c ; GPIO Async falling edge detect enable 1
GPPUPDEN * &94 ; GPIO PullUp PullDown Enable
GPPUDCK0 * &98 ; GPIO PullUp PullDown Clock 0
GPPUDCK1 * &9c ; GPIO PullUp PullDown Clock 1
GPPinMuxSD * &d0
; Auxio peripherals
; MiniUart uses TXD1 and RXD1
......
......@@ -94,6 +94,7 @@ FIQ_Base_Address # 4
ExtIRQ_Base_Address # 4
ARM_Counter_IO_Address # 4
ARM_Timer_IO_Address # 4
SDIO_Address # 4
UARTOldModemStatus # 4
MMUOffBaseAddr # 4 ; original address kernel was loaded from
MachineID # 8 ; derived from MAC address if there
......
......@@ -30,12 +30,17 @@
IMPORT memcpy
IMPORT HAL_CounterDelay
IMPORT HAL_CounterRead
IMPORT HAL_SendHostMessage
; KEEP ; for debugging
GET Hdr:ListOpts
GET Hdr:CPU.Arch
GET Hdr:Macros
GET Hdr:System
GET Hdr:FSNumbers
GET Hdr:NewErrors
GET Hdr:BCMSupport
GET hdr.CastleMacros
GET hdr.BCM2835
GET hdr.StaticWS
......@@ -61,6 +66,9 @@ MIN_SDCLK * 400
; Base address of controller as an offset from PeriBase
EMMC_Base * &00300000
; Base address of 2nd controller as an offset from PeriBase (BCM2838 only)
EMMC2_Base * &00340000
; GPIO pin assignments
GPIO_DAT3 * 53
GPIO_DAT2 * 52
......@@ -72,6 +80,7 @@ GPIO_CD_AB * 47 ; needs pull-up; active low
GPIO_STATUS_LED_AB * 16 ; active low
GPIO_STATUS_LED_BPlus * 47 ; active high
GPIO_STATUS_LED_B4 * 42 ; active high
EXPGPIO_VREG * 4 ; 0 => 3.3V, 1 => 1.8V
; GPIO function select bitfields
GPIO_FSEL_INPUT * 0
......@@ -156,8 +165,7 @@ MEASURE_ACCURACY * 5
; response, so it doesn't matter that lots of things aren't set up properly yet.
MeasureSpeed ROUT
Push "v1-v3,lr"
LDR v1, PeriBase
ADD v1, v1, #EMMC_Base
LDR v1, SDIO_Address
; Switch the clock divider to a known value.
; This is a simplified version of the algorithm in SetSDCLK.
......@@ -261,6 +269,58 @@ MeasureSpeed ROUT
Pull "v1-v3,pc"
; in: a1 = GPIO pin number
; a2 = setting
ExpGPIOWrite ROUT
Push "a1-a2,lr"
ADR a1, tagbuffer + 12
BIC a1, a1, #15 ; align to 16-byte boundary
ADR a2, %FT01
MOV a3, #%FT04 - %FT01
BL memcpy
Pull "a3-a4"
ADD a3, a3, #128
STR a3, [a1, #%FT02 - %FT01]
STR a4, [a1, #%FT03 - %FT01]
CallOS OS_LogToPhys
MOV a2, a1
MOV a1, #MB_Chan_ARM2VC
BL HAL_SendHostMessage
Pull "pc"
01 & %FT04 - .
& 0 ; request
& ARM2VC_Tag_SetExtGPIOState
& 8 ; tag buffer size
& 8 ; number of bytes in buffer on entry
02 & 0 ; fill in with GPIO pin number + 128
03 & 0 ; fill in with GPIO pin setting
& ARM2VC_Tag_End
04
Init_BCM2838 ROUT
Push "v1,lr"
; Set voltage regulator to 3.3V
MOV a1, #EXPGPIO_VREG
MOV a2, #0
BL ExpGPIOWrite
; Settling time for the regulator is 5 ms.
; Wait for the counter to wrap twice (which will take somewhere
; between 10-20 ms).
BL HAL_CounterRead
01 MOV v1, a1
BL HAL_CounterRead
CMP a1, v1
BLS %BT01
01 MOV v1, a1
BL HAL_CounterRead
CMP a1, v1
BLS %BT01
Pull "v1,pc"
MACRO
$class HALDeviceField $field, $value
......@@ -295,23 +355,23 @@ Template
HALDeviceField Deactivate
HALDeviceField Reset
HALDeviceField Sleep
HALDeviceField Device, iDev_GPU_SDIO ; unconfirmed
HALDeviceField Device, iDev_GPU_SDIO ; patched up at initialisation
HALDeviceField TestIRQ
HALDeviceField ClearIRQ, 0
HALDeviceField Reserved2, 0
SDHCI HALDeviceField Flags, HALDeviceSDHCI_Flag_32bit
SDHCI HALDeviceField Slots, 1
SDHCI HALDeviceField SlotInfo, 0 ; patched up at initialisation
SDHCI HALDeviceField WriteRegister
SDHCI HALDeviceField WriteRegister ; patched up at initialisation
SDHCI HALDeviceField GetCapabilities, 0 ; patched up at initialisation
SDHCI HALDeviceField GetVddCapabilities, 0 ; our fake capabilities register suffices already
SDHCI HALDeviceField SetVdd
SDHCI HALDeviceField SetVdd ; patched up at initialisation
SDHCI HALDeviceField SetBusMode, 0
SDHCI HALDeviceField PostPowerOn, 0
SDHCI HALDeviceField SetBusWidth, 0
SDHCI HALDeviceField GetMaxCurrent
SDHCI HALDeviceField SetSDCLK
SDHCI HALDeviceField GetTMCLK
SDHCI HALDeviceField GetMaxCurrent ; patched up at initialisation
SDHCI HALDeviceField SetSDCLK ; patched up at initialisation
SDHCI HALDeviceField GetTMCLK ; patched up at initialisation
SDHCI HALDeviceField SetActivity, 0 ; patched up at initialisation
SDHCI HALDeviceField GetCardDetect, 0 ; patched up at initialisation
SDHCI HALDeviceField GetWriteProtect
......@@ -320,19 +380,17 @@ SDHCI HALDeviceField GetWriteProtect
; Init the SDHCI HAL device
SDIO_InitDevices ROUT
Push "lr"
CPUDetect a1
BLS %FT00
; Pi 4 setup - select legacy emmc controller for now
LDR a1, PeriBase
MOV a2, #3
ADD a1, a1, #GPIO_Base
DoMemBarrier lr
STR a2, [a1, #GPPinMuxSD]
DoMemBarrier lr
00
BL MeasureSpeed
CPUDetect lr
ADDLS a1, a1, #EMMC_Base
ADDHI a1, a1, #EMMC2_Base
STR a1, SDIO_Address
ADR lr, %FT00
BLS MeasureSpeed
BHI Init_BCM2838
00
ADR a1, SDHCIDevice
ADR a2, Template
MOV a3, #HALDevice_SDHCISize
......@@ -362,8 +420,7 @@ SDIO_InitDevices ROUT
STR a1, SDHCIDevice + HALDevice_Activate
; Address and SlotInfo_StdRegs
LDR a1, PeriBase
ADD a1, a1, #EMMC_Base
LDR a1, SDIO_Address
STR a1, SDHCIDevice + HALDevice_Address
STR a1, SDHCISlotInfo + HALDeviceSDHCI_SlotInfo_StdRegs
......@@ -412,9 +469,29 @@ SDIO_InitDevices ROUT
TEQ a3, #BoardRevision_Model_B3
TEQNE a3, #BoardRevision_Model_B3Plus
TEQNE a3, #BoardRevision_Model_A3Plus
TEQNE a3, #BoardRevision_Model_B4
ADREQ a1, Activate_Compute
STREQ a1, SDHCIDevice + HALDevice_Activate
TEQ a3, #BoardRevision_Model_B4
ADREQ a1, Activate_B4
STREQ a1, SDHCIDevice + HALDevice_Activate
; Patch a few things up for Pi 4...
; Device
CPUDetect a1
MOVHI a1, #iDev_GPU_VCSDIO
STRHI a1, SDHCIDevice + HALDevice_Device
MOVHI a1, #0
; WriteRegister - assume this hardware bug has been fixed now
STRHI a1, SDHCIDevice + HALDevice_SDHCIWriteRegister
; Most of the registers now strictly follow the SDHCI standard!!
STRHI a1, SDHCIDevice + HALDevice_SDHCIGetCapabilities
STRHI a1, SDHCIDevice + HALDevice_SDHCISetVdd
STRHI a1, SDHCIDevice + HALDevice_SDHCIGetMaxCurrent
STRHI a1, SDHCIDevice + HALDevice_SDHCISetSDCLK
STRHI a1, SDHCIDevice + HALDevice_SDHCIGetTMCLK
MOV a1, #0 ; flags
ADR a2, SDHCIDevice
......@@ -580,6 +657,15 @@ Activate_Compute ROUT
MOV a3, #MIN_SDCLK
BL SetSDCLK
DoMemBarrier a1 ; switch to GPIO peripheral
B Activate_Common
Activate_B4 ROUT
Push "sb,lr"
SUB sb, a1, #:INDEX:SDHCIDevice
; Assume requirement to preinitialise SDCLK has gone away
DoMemBarrier a1 ; switch to GPIO peripheral
; drop through...
Activate_Common
......@@ -741,8 +827,7 @@ SetSDCLK ROUT
; v1 = interval, v2 = divider, v3 = freq
; Program clock control register
LDR v5, PeriBase
ADD v5, v5, #EMMC_Base
LDR v5, SDIO_Address
LDR v4, [v5, #CONTROL1]!
BIC v4, v4, #CONTROL1_CLK_EN ; stop clock going to card
......@@ -809,8 +894,7 @@ GetTMCLK ROUT
; SDCLK is reused for TMCLK
Push "sb,lr"
SUB sb, a1, #:INDEX:SDHCIDevice
LDR a1, PeriBase
ADD a1, a1, #EMMC_Base
LDR a1, SDIO_Address
LDR a2, [a1, #CONTROL1]
AND a3, a2, #CONTROL1_CLK_FREQ8_MASK
AND a4, a2, #CONTROL1_CLK_FREQ_MS2_MASK
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment