Commit 60752490 authored by Ben Avison's avatar Ben Avison
Browse files

Add support for Raspberry Pi Compute module and Raspberry Pi 2

  * Compute module support consists of eMMC support in the SDHCI driver. The
    eMMC chip on the Compute module only works reliably if under-clocked to
    25 MHz.
  * Pi 1 vs Pi 2 differences are selected at runtime by checking the CPU ID,
    so a single ROM image will work with both boards.
  * Added ARMv7 cache maintenance routine for use on Pi 2.
  * The physical address of the peripherals has moved in Pi 2 to make space
    for the 1 GB of RAM.
  * The ARM physical address space is mapped differently onto the GPU
    address space in Pi 2 because the ARM now uses the L2 cache that comes
    with the Cortex-A7 instead of the GPU's L2 cache.
  * Still waiting for confirmation on the board revision ID that will be
    used for Pi 2, so may require further tweaks for production releases.

Version 0.40. Tagged as 'BCM2835-0_40'
parent 846ad983
/* (0.39)
/* (0.40)
* This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.1.
#define Module_MajorVersion_CMHG 0.39
#define Module_MajorVersion_CMHG 0.40
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 30 Oct 2014
#define Module_Date_CMHG 02 Feb 2015
#define Module_MajorVersion "0.39"
#define Module_Version 39
#define Module_MajorVersion "0.40"
#define Module_Version 40
#define Module_MinorVersion ""
#define Module_Date "30 Oct 2014"
#define Module_Date "02 Feb 2015"
#define Module_ApplicationDate "30-Oct-14"
#define Module_ApplicationDate "02-Feb-15"
#define Module_ComponentName "BCM2835"
#define Module_ComponentPath "mixed/RiscOS/Sources/HAL/BCM2835"
#define Module_FullVersion "0.39"
#define Module_HelpVersion "0.39 (30 Oct 2014)"
#define Module_LibraryVersionInfo "0:39"
#define Module_FullVersion "0.40"
#define Module_HelpVersion "0.40 (02 Feb 2015)"
#define Module_LibraryVersionInfo "0:40"
......@@ -62,7 +62,8 @@ Debug SETL {TRUE}
;ROM_Base * &00000000
IO_Base * &20000000
IO_Base_BCM2835 * &20000000
IO_Base_BCM2836 * &3F000000 ; it moves in Pi 2
IO_Size * &01000000
RAM_Base * &00000000 ; try off bottom
Boot_RAM_Base * &00000000
......@@ -296,15 +297,60 @@ $label MOV$cond $r, #0
MCR$cond p15, 0, $r, c7, c10,5
$label FlushDataCache $r, $cond
$label MOV$cond $r, #0
[ {UAL}
MCR$cond p15, #0, $r, c7, c14, #0
MCR$cond p15, 0, $r, c7, c14,0
$label FlushDataCacheV6 $tmp
$label MOV $tmp, #0
MCR p15, 0, $tmp, c7, c14, 0 ; clean and invalidate entire data cache
$label FlushDataCacheV7 $clidr, $loc, $level, $ccsidr, $linelen, $way, $wayshift, $set, $tmp
$label MRC p15, 1, $clidr, c0, c0, 1 ; read CLIDR
ANDS $loc, $clidr, #&07000000
MOV $loc, $loc, LSR #23 ; extract level of coherence * 2
BEQ %F99 ; nothing to do if loc = 0
MOV $level, #0 ; cache level * 2
10 ADD $tmp, $level, $level, LSR #1 ; cache level * 3
MOV $tmp, $clidr, LSR $tmp
AND $tmp, $tmp, #7
CMP $tmp, #2
BLT %FT40 ; no cache or only instruction cache at this level
MCR p15, 2, $level, c0, c0, 0 ; write CSSELR
ISB ; sync the change to the CCSIDR
MRC p15, 1, $ccsidr, c0, c0, 0 ; read current CCSIDR
AND $linelen, $ccsidr, #7 ; extract the line length field
ADD $linelen, $linelen, #4 ; add 4 for the line length offset (log2 16 bytes)
UBFX $way, $ccsidr, #3, #10 ; associativity aka number of ways
CLZ $wayshift, $way
20 UBFX $set, $ccsidr, #13, #15 ; number of sets
30 ORR $tmp, $level, $way, LSL $wayshift
ORR $tmp, $tmp, $set, LSL $linelen
MCR p15, 0, $tmp, c7, c14, 2 ; data cache clean and invalidate by set/way
SUBS $set, $set, #1
SUBS $way, $way, #1
40 ADD $level, $level, #2
CMP $level, $loc
$label FlushDataCache
$label MRC p15, 0, lr, c0, c0, 0 ; read Main ID Register
AND lr, lr, #&FF00
CMP lr, #&C000 ; xxxxB76x for ARM1176, xxxxC07x for Cortex-A7
FlushDataCacheV6 lr
B %FT99
07 STMFD r13!, {r4-r9}
FlushDataCacheV7 r2,r3,r4,r5,r6,r7,r8,r9,lr
LDMFD r13!, {r4-r9}
$label FlushDataCacheRange $startaddr,$endaddr,$cond
$label BIC$cond $startaddr, $startaddr, #&1f
......@@ -501,7 +501,8 @@ features_lite
; Just remember these for later
STR a2, DMACOptions
ADD a3, a3, #&7e000000-IO_Base ; ARM periph addr -> VC bus periph addr
BIC a3, a3, #&ff000000
ORR a3, a3, #&7e000000 ; ARM periph addr -> VC bus periph addr
STR a3, DMACPeriAddress
MOV pc, lr
......@@ -58,7 +58,7 @@
HAL_SendHostMessage ROUT
STMFD r13!, {r1-r3, lr}
DoMemBarrier r3
FlushDataCache r3
FlushDataCache ; corrupts r2,r3,lr
LDR r3, PeriBase
ADD r3, r3, #MB_Base
; check we can send a message
......@@ -100,8 +100,12 @@ HAL_QueryPlatform ROUT
DCB "HalQueryPl",10,0
mov r4, #GPU_L2CnonAl ; L2 Cache off mode
str r4, FB_CacheMode ; remember
mrc p15, 0, r4, c0, c0, 0 ; read Main ID Register
and r4, r4, #&FF00
cmp r4, #&C000 ; xxxxB76x for ARM1176, xxxxC07x for Cortex-A7
movcc r4, #GPU_L2CnonAl ; Pi 1 has L2 cache enabled
movcs r4, #GPU_UnCached ; Pi 2 has L2 cache disabled
str r4, FB_CacheMode ; remember base of bus addresses (i.e. memory accessed by GPU and GPU peripherals like DMA and USB)
adrl r1, tagbuffer
adr r0, tagb
......@@ -303,7 +303,7 @@ SDHCI HALDeviceField Flags, HALDeviceSDHCI_Flag_32bit
SDHCI HALDeviceField Slots, 1
SDHCI HALDeviceField SlotInfo, 0 ; patched up at initialisation
SDHCI HALDeviceField WriteRegister
SDHCI HALDeviceField GetCapabilities
SDHCI HALDeviceField GetCapabilities, 0 ; patched up at initialisation
SDHCI HALDeviceField GetVddCapabilities, 0 ; our fake capabilities register suffices already
SDHCI HALDeviceField SetVdd
SDHCI HALDeviceField SetBusMode, 0
......@@ -331,8 +331,9 @@ SDIO_InitDevices ROUT
CMP a3, #BoardRevision_BPlus
; Activate
ADRCC a1, Activate_AB
ADRCS a1, Activate_BPlus
ADRLO a1, Activate_AB
ADREQ a1, Activate_BPlus
ADRHI a1, Activate_Compute
STR a1, SDHCIDevice + HALDevice_Activate
; Address and SlotInfo_StdRegs
......@@ -347,14 +348,21 @@ SDIO_InitDevices ROUT
; SlotInfo_Flags
MOV a1, #HALDeviceSDHCI_SlotFlag_Bus4Bit
ORRCS a1, a1, #HALDeviceSDHCI_SlotFlag_NoCardDetect
ORREQ a1, a1, #HALDeviceSDHCI_SlotFlag_NoCardDetect
ORRHI a1, a1, #HALDeviceSDHCI_SlotFlag_IntegratedMem
STR a1, SDHCISlotInfo + HALDeviceSDHCI_SlotInfo_Flags
; GetCapabilities
ADR a1, GetCapabilities_AB_BPlus
ADDHI a1, a1, #GetCapabilities_Compute - GetCapabilities_AB_BPlus
STR a1, SDHCIDevice + HALDevice_SDHCIGetCapabilities
; SetActivity and GetCardDetect
ADRL a1, SetActivity_AB
ADDCS a1, a1, #SetActivity_BPlus - SetActivity_AB
ADDEQ a1, a1, #SetActivity_BPlus - SetActivity_AB
ADDHI a1, a1, #SetActivity_Compute - SetActivity_AB
ADRL a2, GetCardDetect_AB
ADDCS a2, a2, #GetCardDetect_BPlus - GetCardDetect_AB
ADDHS a2, a2, #GetCardDetect_BPlus_Compute - GetCardDetect_AB
STR a1, SDHCIDevice + HALDevice_SDHCISetActivity
STR a2, SDHCIDevice + HALDevice_SDHCIGetCardDetect
......@@ -508,6 +516,21 @@ Activate_BPlus ROUT
B Activate_Common
Activate_Compute ROUT
Push "sb,lr"
SUB sb, a1, #:INDEX:SDHCIDevice
MOV lr, #0
STR lr, SDHCILastWriteCount
; SDCLK has to be set up before any register writes are done - it's not
; reasonable to expect SDIODriver to know this requirement
DoMemBarrier a1 ; switch to GPIO peripheral
; drop through...
......@@ -592,13 +615,24 @@ WriteRegister ROUT
STR a1, SDHCILastWriteCount
Pull "v1-v4,sb,pc"
GetCapabilities ROUT
GetCapabilities_AB_BPlus ROUT
; Vss is fixed in hardware - see schematics
; Eben says high bus speed doesn't work, but Linux seems to manage?
; Buffer size is mentioned in the prose in the BCM2835 ARM peripherals datasheet
LDR a1, =CAP_VS33 :OR: CAP_HSS :OR: CAP_MBL_1024
MOV pc, lr
GetCapabilities_Compute ROUT
; The eMMC chip doesn't seem to be compatible with the BCM2835's high bus speed timings.
; We get command line conflicts unless we set HostControl1's HSE bit (which we don't
; normally do due to compatibility issues with some 50 MHz MMCplus cards and 52 MHz
; SD cards, which otherwise function on the Pis with card slots - see SDIODriver.c.probe
; for more). But even if we do set HSE, data transfer is too unreliable for practical
; use with the eMMC. The easiest workaround is to alter the fake capabilities register
; to claim that high speed isn't supported by the controller.
LDR a1, =CAP_VS33 :OR: CAP_MBL_1024
MOV pc, lr
SetVdd * NOPEntry ; There is no software control of Vdd for this board
GetMaxCurrent ROUT
......@@ -766,6 +800,10 @@ SetActivity_BPlus ROUT
DoMemBarrier lr ; back to SDHCI peripheral
Pull "sb,pc"
SetActivity_Compute ROUT
; No standard way of wiring up the activity LED on Compute
MOV pc, lr
GetCardDetect_AB ROUT
Push "sb,lr"
DoMemBarrier lr ; switch to GPIO peripheral
......@@ -780,7 +818,7 @@ GetCardDetect_AB ROUT
DoMemBarrier lr ; back to SDHCI peripheral
Pull "sb,pc"
GetCardDetect_BPlus ROUT
GetCardDetect_BPlus_Compute ROUT
; CD is not connected. This entry shouldn't be called, but just in case
; (perhaps someone softloaded old SDFSDriver/SDFS?) report card present
MOV a1, #1
......@@ -209,7 +209,11 @@ start MSR CPSR_c,#F32_bit+I32_bit+SVC32_mode
ADRL R13,end_stack
ADRL r4, reset
STR r4, MMUOffBaseAddr
LDR r4,=IO_Base
MRC p15,0,r4,c0,c0,0 ; read Main ID Register
AND r4,r4,#&FF00
CMP r4,#&C000 ; xxxxB76x for ARM1176, xxxxC07x for Cortex-A7
LDRCC r4,=IO_Base_BCM2835
LDRCS r4,=IO_Base_BCM2836
STR r4,PeriBase
[ HALDebug
......@@ -533,7 +537,11 @@ HAL_Init
BL SetUpOSEntries
MOV a1, #0 ; map in the IO space
LDR a2, =IO_Base
MRC p15, 0, a2, c0, c0, 0 ; read Main ID Register
AND a2, a2, #&FF00
CMP a2, #&C000 ; xxxxB76x for ARM1176, xxxxC07x for Cortex-A7
LDRCC a2, =IO_Base_BCM2835
LDRCS a2, =IO_Base_BCM2836
LDR a3, =IO_Size
STR a1, PeriBase
......@@ -740,7 +748,11 @@ HAL_PhysInfo ROUT
CMP a2, v4
; Fill in IO region
SUB a2, a2, #524288-(IO_Base>>13)
MRC p15,0,v5,c0,c0,0 ; read Main ID Register
AND v5,v5,#&FF00
CMP v5,#&C000 ; xxxxB76x for ARM1176, xxxxC07x for Cortex-A7
SUB a2, a2, #524288-(IO_Base_BCM2835>>13)
ADDCS a2, a2, #(IO_Base_BCM2836-IO_Base_BCM2835)>>13
ORR a1, a1, a1, LSR #1 ; Pattern for IO regions
ORR a3, a3, a3, LSR #1
ORR a4, a4, a4, LSR #1
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