306 lines
8.9 KiB
Plaintext
306 lines
8.9 KiB
Plaintext
; --------------------------------------------------------------------------------
|
|
; @Title: eMMC FLASH Program script by the core for the RCARH3 Evaluation Board
|
|
; @Description:
|
|
; eMMC FLASH KLMBG4GESD
|
|
; Board (Salvator-X)
|
|
; The eMMC is connected to the SDHI_2/MMC_0 Controller
|
|
;
|
|
; Prerequisites:
|
|
; * set
|
|
; MD[7..6] = 0y00 - Cortex-A57 boot
|
|
; MD[4..1] = 0y0101 - eMMC flash ROM boot
|
|
; or MD[4..1] = 0y0000
|
|
; MD[15] = 1 - AARCH64 for CortexA5x
|
|
; as the DIP-Switches are inverted
|
|
; SW10[1..2] = 0y11 - Cortex-A57 boot
|
|
; SW10[5..8] = 0y1100 - RPC flash ROM boot at (80/160)MHz using DMA
|
|
; or SW10[4..1] = 0y1111
|
|
; SW12[1] = 0 - AARCH64 for CortexA5x
|
|
; * activate JTAG on CN1, SDHI0/1 normal function
|
|
; MD[10] = 0
|
|
; MD[21..20] = 0y10 - CN1=JTAG
|
|
; MD[11] = 0 - SDHI0/1 normal function
|
|
; as the DIP-Switches are inverted
|
|
; SW11[3] = 1
|
|
; SW11[4..5] = 0y01 - CN1=JTAG
|
|
; SW11[6] = 1 - SDHI0/1 normal function
|
|
; * deactivate QSPI flash
|
|
; SW1/SW2 = 0
|
|
; SW3 = 1
|
|
;
|
|
;
|
|
; SRAM: 0xE6328000--0xE632FFFF
|
|
; SDHI_2 controller Base: A:0xEE140000
|
|
;
|
|
; @Author: JIM
|
|
; @Keywords:
|
|
; @Copyright: (C) 1989-2022 Lauterbach GmbH, licensed for use with TRACE32(R) only
|
|
; --------------------------------------------------------------------------------
|
|
; $Id: rcarh3-ca53-emmc.cmm 12742 2023-11-17 08:05:09Z mschaeffner $
|
|
|
|
LOCAL &arg1
|
|
ENTRY &arg1
|
|
&arg1=STRing.UPpeR("&arg1") // for example "PREPAREONLY"
|
|
|
|
&MMC_BASE=0xEE140000
|
|
|
|
; ------------------------------------------------------------------------------
|
|
; Setup CPU
|
|
RESet
|
|
SYStem.RESet
|
|
SYStem.CPU R8A77951
|
|
SYStem.JtagClock CTCK 10MHz
|
|
CORE.ASSIGN 1. // Cortex-A57
|
|
; CORE.ASSIGN 2. // Cortex-A53
|
|
Trace.DISable
|
|
SYStem.Up
|
|
|
|
; enable SRAM
|
|
Data.Set A:0xE67F0018 %LE %Long 0x1
|
|
|
|
Register.Set M 0x5 ;EL1h
|
|
|
|
GOSUB PIN_MUX
|
|
GOSUB POWERON_MMC0
|
|
GOSUB CLKINIT_MMC0
|
|
GOSUB INIT_MMC0
|
|
GOSUB WDOG_DISABLE
|
|
|
|
GOSUB READ_ID_TEST
|
|
|
|
LOCAL &pdd
|
|
&pdd=OS.PresentDemoDirectory()
|
|
|
|
Break.RESet
|
|
|
|
FLASHFILE.RESet
|
|
|
|
//FLASHFILE.CONFIG <MMC Base Address>
|
|
FLASHFILE.CONFIG &MMC_BASE
|
|
|
|
//FLASHFILE.TARGET <code range> <data range> <Algorithm file>
|
|
FLASHFILE.TARGET 0xE6328000++0x1FFF 0xE632A000++0x21FF &pdd/flash/byte/emmc_shsdhi.bin /KEEP /STACKSIZE 0x200
|
|
|
|
GOSUB CLK_DOWN_400KHz
|
|
|
|
FLASHFILE.GETID
|
|
|
|
GOSUB CLK_UP_20MHz
|
|
|
|
//Get EXTended CSD registers
|
|
FLASHFILE.GETEXTCSD
|
|
|
|
//End of the test prepareonly
|
|
IF "&arg1"=="PREPAREONLY"
|
|
ENDDO
|
|
|
|
|
|
//When you access to the other partition on the flash
|
|
; FLASHFILE.SETEXTCSD 179. 0x00 ; access: partition null, no boot, access: no boot partition
|
|
; FLASHFILE.SETEXTCSD 179. 0x48 ; access: partition null
|
|
; FLASHFILE.SETEXTCSD 179. 0x49 ; access: partition boot 1
|
|
; FLASHFILE.SETEXTCSD 179. 0x4A ; access: partition boot 2
|
|
|
|
FLASHFILE.DUMP 0x0 ; Read eMMC
|
|
;FLASHFILE.ERASE 0x0--0xFFFFF ; Erase eMMC
|
|
;FLASHFILE.LOAD * 0x0 ; Write eMMC
|
|
|
|
ENDDO
|
|
|
|
POWERON_MMC0:
|
|
//poweronmmc0, Bit12,13 clear
|
|
&value=0xFFFFCFDF
|
|
Data.Set A:0xE6150900 %Long ~(&value)
|
|
Data.Set A:0xE615013C %Long &value
|
|
;PRINT Data.Long(A:0xE6150048) ; //bit 12,13 have to be cleared.
|
|
RETURN
|
|
|
|
|
|
//InitMmc0PinFunction
|
|
PIN_MUX:
|
|
|
|
&value=0x11110000
|
|
Data.Set A:0xE6060000 %Long ~(&value) ;PFC_PMMR
|
|
Data.Set A:0xE6060220 %Long &value ; PFC_IPSR8
|
|
|
|
&value=0x0
|
|
Data.Set A:0xE6060000 %Long ~(&value) ;PFC_PMMR
|
|
Data.Set A:0xE6060224 %Long &value ; PFC_IPSR9
|
|
|
|
&value=0x0F00
|
|
Data.Set A:0xE6060000 %Long ~(&value) ;PFC_PMMR
|
|
Data.Set A:0xE606010C %Long &value ; PFC_GPSR3
|
|
|
|
&value=0x7F
|
|
Data.Set A:0xE6060000 %Long ~(&value) ;PFC_PMMR
|
|
Data.Set A:0xE6060110 %Long &value ; PFC_GPSR4
|
|
|
|
//revers value setting
|
|
&value=~(0x07FFC0)
|
|
Data.Set A:0xE6060000 %Long ~(&value)
|
|
Data.Set A:0xE6060380 %Long &value ;PFC_POCCTRL0
|
|
|
|
&value=~(0x000003C)
|
|
Data.Set A:0xE6060000 %Long ~(&value)
|
|
Data.Set A:0xE60603C0 %Long &value ;PFC_TDSELCTRL0
|
|
|
|
|
|
&value=0x2F7
|
|
Data.Set A:0xE6060000 %Long ~(&value)
|
|
Data.Set A:0xE606040C %Long &value ;PFC_PUEN3
|
|
|
|
|
|
&value=0x00777777
|
|
Data.Set A:0xE6060000 %Long ~(&value)
|
|
Data.Set A:0xE6060338 %Long &value ;PFC_DRVCTRL14
|
|
|
|
&value=0x77777000
|
|
Data.Set A:0xE6060000 %Long ~(&value)
|
|
Data.Set A:0xE606033C %Long &value ;PFC_PFC_DRVCTRL15
|
|
|
|
RETURN
|
|
|
|
CLK_UP_20MHz:
|
|
|
|
PER.Set.simple ANSD:&MMC_BASE+0x0090 %Long 0x0
|
|
|
|
//*((volatile uint32_t*)MMC_CH0_SD_CLK_CTRL) = 0x101; //1/4 ; 20Mhz
|
|
PER.Set.simple ANSD:&MMC_BASE+0x0090 %Quad 0x101
|
|
//*((volatile uint32_t*)(MMC_CH0_SCC_DTCNTL)) = 0x00080000; // SCC_DTCNTL.TAPEN=0
|
|
PER.Set.simple ANSD:&MMC_BASE+0x1000 %Long 0x00080000
|
|
//*((volatile uint32_t*)(MMC_CH0_SCC_TAPSET)) = 2; // SCC_TAPSET
|
|
PER.Set.simple A:&MMC_BASE+0x1008 %Long 0x2
|
|
//*((volatile uint32_t*)(MMC_CH0_SCC_CKSEL)) = 0x00000000; // SCC_CKSEL=0
|
|
PER.Set.simple A:&MMC_BASE+0x1018 %Long 0x0
|
|
|
|
RETURN
|
|
|
|
|
|
CLK_DOWN_400KHz:
|
|
|
|
// *((volatile uint32_t*)MMC_CH0_SD_CLK_CTRL) = 0x00000000; // Automatic Control=Disable, Clock Output=Disable
|
|
PER.Set.simple ANSD:&MMC_BASE+0x0090 %Long 0x0
|
|
// *((volatile uint32_t*)MMC_CH0_SD_CLK_CTRL) = 0x180; //1/512 ; 400KHz
|
|
PER.Set.simple ANSD:&MMC_BASE+0x0090 %Quad 0x180
|
|
//*((volatile uint32_t*)(MMC_CH0_SCC_DTCNTL)) = 0x00080000; // SCC_DTCNTL.TAPEN=0
|
|
PER.Set.simple ANSD:&MMC_BASE+0x1000 %Long 0x00080000
|
|
//*((volatile uint32_t*)(MMC_CH0_SCC_TAPSET)) = 2; // SCC_TAPSET
|
|
PER.Set.simple A:&MMC_BASE+0x1008 %Long 0x2
|
|
//*((volatile uint32_t*)(MMC_CH0_SCC_CKSEL)) = 0x00000000; // SCC_CKSEL=0
|
|
PER.Set.simple A:&MMC_BASE+0x1018 %Long 0x0
|
|
|
|
RETURN
|
|
|
|
CLKINIT_MMC0:
|
|
//clock init
|
|
&value=0x1
|
|
Data.Set A:0xE6150900 %Long ~(&value)
|
|
Data.Set A:0xE6150078 %Long &value ;SD1
|
|
Data.Set A:0xE6150268 %Long &value ;SD2
|
|
RETURN
|
|
|
|
INIT_MMC0:
|
|
//SW Reset for the MMC memory
|
|
Data.Set A:&MMC_BASE+0x380 %LE %Quad 0x0
|
|
WAIT 100.ms
|
|
Data.Set A:&MMC_BASE+0x380 %LE %Quad 0x7
|
|
|
|
// *((volatile uint32_t*)MMC_CH0_HOST_MODE) = 0x00000000; // SD_BUF access width = 64-bit
|
|
PER.Set.simple ANSD:&MMC_BASE+0x0390 %Long 0x0
|
|
// *((volatile uint32_t*)MMC_CH0_SD_OPTION) = 0x0000C0EE; // Bus width = 1bit, timeout=MAX
|
|
PER.Set.simple ANSD:&MMC_BASE+0x00A0 %Long 0xc0EE
|
|
|
|
// *((volatile uint32_t*)MMC_CH0_SD_CLK_CTRL) = 0x00000000; // Automatic Control=Disable, Clock Output=Disable
|
|
PER.Set.simple ANSD:&MMC_BASE+0x0090 %Long 0x0
|
|
// *((volatile uint32_t*)MMC_CH0_SD_CLK_CTRL) = 0x180; //1/512 ; 400KHz
|
|
PER.Set.simple ANSD:&MMC_BASE+0x0090 %Quad 0x180
|
|
//*((volatile uint32_t*)(MMC_CH0_SCC_DTCNTL)) = 0x00080000; // SCC_DTCNTL.TAPEN=0
|
|
PER.Set.simple ANSD:&MMC_BASE+0x1000 %Long 0x00080000
|
|
//*((volatile uint32_t*)(MMC_CH0_SCC_TAPSET)) = 2; // SCC_TAPSET
|
|
PER.Set.simple A:&MMC_BASE+0x1008 %Long 0x2
|
|
//*((volatile uint32_t*)(MMC_CH0_SCC_CKSEL)) = 0x00000000; // SCC_CKSEL=0
|
|
PER.Set.simple A:&MMC_BASE+0x1018 %Long 0x0
|
|
|
|
// *((volatile uint32_t*)MMC_CH0_SD_INFO1_MASK) = 0x0001031D; // all mask (0x0000FFFE in HWM)
|
|
PER.Set.simple ANSD:&MMC_BASE+0x0080 %Quad 0x1031D
|
|
// *((volatile uint32_t*)MMC_CH0_SD_INFO2_MASK) = 0x00008B7F; // all mask (0x00007F80 in HWM)
|
|
PER.Set.simple ANSD:&MMC_BASE+0x0088 %Quad 0x8B7F
|
|
RETURN
|
|
|
|
WDOG_DISABLE:
|
|
//RCLK Watchdog Timer disable
|
|
Data.Set EZAXI:0xE6020004 %Long 0xA5A5A500|0x00 ; Write 0 to the RCLK Watchdog Timer Control Register A
|
|
Data.Set EZAXI:0xE6020008 %Long 0xA5A5A500|0x00 ; Write 0 to the RCLK Watchdog Timer Control Register B
|
|
|
|
//System Watchdog Timer disable
|
|
Data.Set EZAXI:0xE6030004 %Long 0xA5A5A500|0x00 ; Write 0 to the System Watchdog Timer Control Register A
|
|
Data.Set EZAXI:0xE6030008 %Long 0xA5A5A500|0x00 ; Write 0 to the System Watchdog Timer Control Register B
|
|
RETURN
|
|
|
|
READ_ID_TEST:
|
|
|
|
//CMD0
|
|
RePeaT 2.
|
|
(
|
|
//MMC_CH0_SD_INFO1
|
|
PER.Set.simple ANSD:&MMC_BASE+0x0070 %Long 0xFFFE ;clear resp end BIT0
|
|
// SendMmc0Cmd0(0x00000000);
|
|
PER.Set.simple ANSD:&MMC_BASE+0x0010 %Long 0x0 ;arg
|
|
PER.Set.simple ANSD:&MMC_BASE+0x0000 %Quad 0x0 ;cmd
|
|
WAIT 100.ms
|
|
)
|
|
|
|
//CMD1
|
|
RePeaT 10.
|
|
(
|
|
//SendMmc0Command(MMC_CMD1,ocr);
|
|
//MMC_CH0_SD_INFO1
|
|
PER.Set.simple ANSD:&MMC_BASE+0x0070 %Long 0xFFFE ;clear resp end BIT0
|
|
PER.Set.simple ANSD:&MMC_BASE+0x0010 %Long 0x40FF8080 ;arg
|
|
PER.Set.simple ANSD:&MMC_BASE+0x0000 %Quad 0x701 ;cmd
|
|
|
|
WAIT 100.ms
|
|
&resp=Data.Long(A:&MMC_BASE+0x0030)
|
|
//print "CMD1 resp: 0x" &resp
|
|
IF (&resp&0x80000000)==0x80000000
|
|
(
|
|
GOTO jump_cmd2
|
|
)
|
|
)
|
|
|
|
PRINT "CMD1 fail"
|
|
END
|
|
|
|
jump_cmd2:
|
|
//CMD2
|
|
PER.Set.simple ANSD:&MMC_BASE+0x0070 %Long 0xFFFE ;clear resp end BIT0
|
|
PER.Set.simple ANSD:&MMC_BASE+0x0010 %Long 0x0 ;arg
|
|
PER.Set.simple ANSD:&MMC_BASE+0x0000 %Quad 0x2 ;cmd
|
|
WAIT 10.ms
|
|
|
|
//CMD3
|
|
PER.Set.simple ANSD:&MMC_BASE+0x0070 %Long 0xFFFE ;clear resp end BIT0
|
|
PER.Set.simple ANSD:&MMC_BASE+0x0010 %Long 0x10000 ;arg
|
|
PER.Set.simple ANSD:&MMC_BASE+0x0000 %Quad 0x3 ;cmd
|
|
WAIT 10.ms
|
|
|
|
//CMD10
|
|
PER.Set.simple ANSD:&MMC_BASE+0x0070 %Long 0xFFFE ;clear resp end BIT0
|
|
PER.Set.simple ANSD:&MMC_BASE+0x0010 %Long 0x10000 ;arg
|
|
PER.Set.simple ANSD:&MMC_BASE+0x0000 %Quad 0x0000000A ;cmd
|
|
WAIT 10.ms
|
|
|
|
//Response2
|
|
PRINT "CID register"
|
|
PRINT "[127:104] 0x" Data.Long(A:&MMC_BASE+0x0060)
|
|
PRINT "[103:72] 0x" Data.Long(A:&MMC_BASE+0x0050)
|
|
PRINT "[71:40] 0x" Data.Long(A:&MMC_BASE+0x0040)
|
|
PRINT "[39:8] 0x" Data.Long(A:&MMC_BASE+0x0030)
|
|
|
|
RETURN
|
|
|
|
|
|
|
|
|
|
|