; -------------------------------------------------------------------------------- ; @Title: eMMC FLASH Program script by the core for the RCARV3H Evaluation Board ; @Description: ; eMMC FLASH KLMBG4GESD ; The eMMC is connected to the SDHI Controller ; ; Prerequisites: ; * Connect Debug Cable/Combiprobe to CN29 JTAG ; * set CortexA53 as boot core ; MD[7..6] = 0y01 -> SW3[1..2] = 0y10 ; * activate Coresight on JTAG1 (CN29) ; MD10 = 0 -> SW20[3] = 1 ; MD[21..20] = 0y10 -> SW20[4..5] = 0y01 ; ; SRAM: 0xE6328000 ; SDHI(MMC) controller Base: 0xEE140000 ; ; @Keywords: ARM, Cortex-A53 ; @Author: JIM ; @Board: R-CarV3H System Evaluation Board "Condor", V3H Starter Kit ; @Chip: RCARV3H ; @Copyright: (C) 1989-2022 Lauterbach GmbH, licensed for use with TRACE32(R) only ; -------------------------------------------------------------------------------- ; $Id: rcarv3h-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 SYStem.RESet SYStem.CPU R8A77980 SYStem.JtagClock CTCK 10MHz CORE.ASSIGN 1. ; select only master core 1 - 1. first core, 2. second core, 1. 2. first + second core (SMP) ... SYStem.Up Register.Set I 0 Register.Set M 0x5 ;EL1h ; enable SRAM Data.Set A:0xE67F0018 %Long 0x1 Data.Set A:0xE6260604 %Long 0x8 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 FLASHFILE.CONFIG &MMC_BASE //FLASHFILE.TARGET FLASHFILE.TARGET 0xE6328000++0x1FFF EAXI:0xE632A000++0x43FF &pdd/flash/byte/emmc_shsdhi.bin /KEEP /STACKSIZE 0x200 /DUALPORT 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,14 clear &value=0xFFFF8FDF Data.Set A:0xE6150900 %Long ~(&value) Data.Set A:0xE615013C %Long &value PRINT "MSTPSR3: 0x" Data.Long(A:0xE6150048) ; //bit 12,13,14 have to be cleared. RETURN //InitMmc0PinFunction PIN_MUX: //eMMC pin mapping //VI1_DATA3 : MMC_CMD //VI1_DATA4 : MMC_DAT0 //VI1_DATA8 : MMC_CLK &value=0x44440000 Data.Set A:0xE6060000 %Long ~(&value) ;PFC_PMMR Data.Set A:0xE6060214 %Long &value ;PFC_IPSR5 [31:16] &value=0x44444444 Data.Set A:0xE6060000 %Long ~(&value) ;PFC_PMMR Data.Set A:0xE6060218 %Long &value ;PFC_IPSR6 [31:0] &value=0x00000004 Data.Set A:0xE6060000 %Long ~(&value) ;PFC_PMMR Data.Set A:0xE606021C %Long &value ;PFC_IPSR7 [3:0] &value=0x01FFFF Data.Set A:0xE6060000 %Long ~(&value) ;PFC_PMMR Data.Set A:0xE606010C %Long &value ;PFC_GPSR3 &value=0x00000077 Data.Set A:0xE6060000 %Long ~(&value) ;PFC_PMMR Data.Set A:0xE606031C %Long &value ;PFC_DRVCTRL7 &value=0x77777777 Data.Set A:0xE6060000 %Long ~(&value) ;PFC_PMMR Data.Set A:0xE6060320 %Long &value ;PFC_DRVCTRL8 &value=0x77700000 Data.Set A:0xE6060000 %Long ~(&value) ;PFC_PMMR Data.Set A:0xE6060324 %Long &value ;PFC_DRVCTRL9 //Function: Each bit in POCCTRL0 must be set according to IO voltage level that is supplied to the pin. //0: 1.8v 1: 3.3v &value=0xFF0000FF Data.Set A:0xE6060000 %Long ~(&value) Data.Set A:0xE6060384 %Long &value ;PFC_POCCTRL1 &value=0x0 Data.Set A:0xE6060000 %Long ~(&value) Data.Set A:0xE60603C0 %Long &value ;TDSELCTRL0 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 0x120 //*((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|(0x2<<2) Data.Set A:0xE6150900 %Long ~(&value) Data.Set A:0xE6150074 %Long &value ;SD0 ;for rcharv3h Data.Set A:0xE6150078 %Long &value ;SD1 Data.Set A:0xE6150268 %Long &value ;SD2 Data.Set A:0xE615026C %Long &value ;SD3 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 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 WDOG_DISABLE: //RCLK Watchdog Timer disable Data.Set ZAXI:0xE6020004 %Long 0xA5A5A500|0x00 ; Write 0 to the RCLK Watchdog Timer Control Register A Data.Set ZAXI:0xE6020008 %Long 0xA5A5A500|0x00 ; Write 0 to the RCLK Watchdog Timer Control Register B //System Watchdog Timer disable Data.Set ZAXI:0xE6030004 %Long 0xA5A5A500|0x00 ; Write 0 to the System Watchdog Timer Control Register A Data.Set ZAXI:0xE6030008 %Long 0xA5A5A500|0x00 ; Write 0 to the System Watchdog Timer Control Register B RETURN