264 lines
7.7 KiB
Plaintext
264 lines
7.7 KiB
Plaintext
; --------------------------------------------------------------------------------
|
|
; @Title: SPI Flash program script for IMX8QM (by FLASH command)
|
|
; @Description:
|
|
; I.MX8QM has a same FlexSPI controller with i.MX8QX
|
|
;
|
|
; It does not matter of the boot mode (SD/eMMC/QSPI and so on)
|
|
;
|
|
; @Keywords: ARM, Cortex-M4
|
|
; @Author: JIM
|
|
; @Board: MX8QMLPD4CPU
|
|
; @Chip: IMX8QM-CM4-0
|
|
; @Copyright: (C) 1989-2023 Lauterbach GmbH, licensed for use with TRACE32(R) only
|
|
; --------------------------------------------------------------------------------
|
|
; $Id: imx8qm-spi.cmm 12976 2024-01-24 02:57:05Z jjeong $
|
|
|
|
PRIVATE ¶meters ¶m_prepareonly
|
|
ENTRY %LINE ¶meters
|
|
¶m_prepareonly=(STRing.SCAN(STRing.UPpeR("¶meters"),"PREPAREONLY",0)!=-1)
|
|
|
|
&FLEXSPI_BASE=0x5D120000 ;FLEXSPI0 controller base address
|
|
&ipc_addr=0x41480000 ; CM4_0_MU1_A_BASE , Messaging Unit
|
|
|
|
;if the flash is empty then, you need to kick the first CM4
|
|
;DO ~~/demo/arm/hardware/imx8/imx8/scripts/kick_cores.cmm "M4_0"
|
|
|
|
SYStem.CPU IMX8QM-CM4-0
|
|
SYStem.Mode Attach
|
|
|
|
IF STATE.RUN()
|
|
Break.direct
|
|
|
|
Data.Set A:&ipc_addr+0x24 %Long 0x0 ; /* Clear GIEn, RIEn, TIEn, GIRn and ABFn. */
|
|
|
|
// SC_PAD_SET &padNum &mux &ctrl &cfg
|
|
GOSUB SC_PAD_SET 181. 0x0 0x21 0x0 ; LSIO.QSPI0A.DATA0
|
|
GOSUB SC_PAD_SET 182. 0x0 0x21 0x0 ; LSIO.QSPI0A.DATA1
|
|
GOSUB SC_PAD_SET 183. 0x0 0x21 0x0 ; LSIO.QSPI0A.DATA2
|
|
GOSUB SC_PAD_SET 184. 0x0 0x21 0x0 ; LSIO.QSPI0A.DATA3
|
|
GOSUB SC_PAD_SET 185. 0x0 0x21 0x0 ; LSIO.QSPI0A.DQS1
|
|
GOSUB SC_PAD_SET 186. 0x0 0x21 0x0 ; LSIO.QSPI0A.SS0_B
|
|
GOSUB SC_PAD_SET 187. 0x0 0x21 0x0 ; LSIO.QSPI0A.SS1_B
|
|
GOSUB SC_PAD_SET 188. 0x0 0x21 0x0 ; LSIO.QSPI0A.SCLK
|
|
|
|
; --------------------------------------------------------------------------------
|
|
; Power ON SC_R_FSPI_0( QSPI0 = FSPI0 = 237. )
|
|
; --------------------------------------------------------------------------------
|
|
// SC_POWER_ON_SET &resource &mode
|
|
GOSUB SC_POWER_ON_SET 0xED 0x03
|
|
|
|
; --------------------------------------------------------------------------------
|
|
; CLK Enable FSPI_0
|
|
; --------------------------------------------------------------------------------
|
|
// SC_CLK_ENABLE &resource &clk
|
|
GOSUB SC_CLK_ENABLE 0xED 0x02
|
|
|
|
GOSUB FLEXSPIconfig
|
|
|
|
GOSUB READ_ID_TEST
|
|
|
|
FLASH.RESet
|
|
FLASH.Create 1. 0x08000000++0xFFFFFF 0x10000 TARGET Byte
|
|
FLASH.TARGET 0x20010000 E:0x20012000 0x2000 ~~/demo/arm/flash/byte/snor_imx8qx.bin /DUALPORT /STACKSIZE 0x400
|
|
|
|
// !!! please do not erase the boot image area,
|
|
// the boot is wrong, then system.up will not work !!!
|
|
|
|
IF ¶m_prepareonly
|
|
ENDDO
|
|
|
|
FLASH.List
|
|
|
|
;FLASH.SPICMD 1. 0x9F /READ 0x10 ;Get Flash Read_ID
|
|
;FLASH.ReProgram ALL
|
|
;Data.LOAD.auto *
|
|
;Data.LOAD.Binary * 0x08000000
|
|
|
|
;FLASH.ReProgram OFF
|
|
|
|
ENDDO
|
|
|
|
FLEXSPIconfig:
|
|
(
|
|
//unlock
|
|
Data.Set A:&FLEXSPI_BASE+0x018 %LE %Long 0x5AF05AF0
|
|
Data.Set A:&FLEXSPI_BASE+0x01C %LE %Long 2
|
|
|
|
//controller init
|
|
Data.Set A:&FLEXSPI_BASE+0x000 %LE %Long 0xFFFF8000
|
|
Data.Set A:&FLEXSPI_BASE+0x004 %LE %Long 0xFFFFFFFF
|
|
Data.Set A:&FLEXSPI_BASE+0x008 %LE %Long 0x200001F7
|
|
Data.Set A:&FLEXSPI_BASE+0x00C %LE %Long 0x58
|
|
Data.Set A:&FLEXSPI_BASE+0x020 %LE %Long 0x80000000
|
|
Data.Set A:&FLEXSPI_BASE+0x024 %LE %Long 0x80000000
|
|
Data.Set A:&FLEXSPI_BASE+0x028 %LE %Long 0x80000000
|
|
Data.Set A:&FLEXSPI_BASE+0x060 %LE %Long 0x00200000
|
|
|
|
Data.Set A:&FLEXSPI_BASE+0x060 %LE %Long 0x4000 ; 0x4000 * 0x400(KB unit size) = 16MB Flash_A0 size.
|
|
Data.Set A:&FLEXSPI_BASE+0x064 %LE %Long 0x4000
|
|
Data.Set A:&FLEXSPI_BASE+0x068 %LE %Long 0x4000
|
|
Data.Set A:&FLEXSPI_BASE+0x06C %LE %Long 0x4000
|
|
|
|
//timing
|
|
Data.Set A:&FLEXSPI_BASE+0x070 %LE %Long 0x00000063
|
|
Data.Set A:&FLEXSPI_BASE+0x074 %LE %Long 0x00000063
|
|
Data.Set A:&FLEXSPI_BASE+0x078 %LE %Long 0x00000063
|
|
Data.Set A:&FLEXSPI_BASE+0x07C %LE %Long 0x00000063
|
|
|
|
Data.Set A:&FLEXSPI_BASE+0x080 %LE %Long 0x00000900
|
|
Data.Set A:&FLEXSPI_BASE+0x084 %LE %Long 0x00000900
|
|
Data.Set A:&FLEXSPI_BASE+0x088 %LE %Long 0x00000900
|
|
Data.Set A:&FLEXSPI_BASE+0x08C %LE %Long 0x00000900
|
|
|
|
Data.Set A:&FLEXSPI_BASE+0x0B8 %LE %Long 0x1 ; water marker level 0 , reset assert 0x1
|
|
Data.Set A:&FLEXSPI_BASE+0x0BC %LE %Long 0x1 ; water marker level 0 , reset assert 0x1
|
|
|
|
Data.Set A:&FLEXSPI_BASE+0x0C0 %LE %Long 0x0100
|
|
Data.Set A:&FLEXSPI_BASE+0x0C4 %LE %Long 0x0100
|
|
|
|
//LUT0 for read the spi memory data to the AHB
|
|
//FAST READ Quad I/O
|
|
; Data.Set A:&FLEXSPI_BASE+0x200 %LE %Long 0x0A1804EB
|
|
; Data.Set A:&FLEXSPI_BASE+0x204 %LE %Long 0x26043206
|
|
; Data.Set A:&FLEXSPI_BASE+0x208 %LE %Long 0x00
|
|
; Data.Set A:&FLEXSPI_BASE+0x20C %LE %Long 0x00
|
|
//Normal Read Mode
|
|
Data.Set A:&FLEXSPI_BASE+0x200 %LE %Long 0x08180403
|
|
Data.Set A:&FLEXSPI_BASE+0x204 %LE %Long 0x00002404
|
|
Data.Set A:&FLEXSPI_BASE+0x208 %LE %Long 0x00
|
|
Data.Set A:&FLEXSPI_BASE+0x20C %LE %Long 0x00
|
|
|
|
//AHB update automatically even though the window size is < 1KB
|
|
Data.Set A:&FLEXSPI_BASE+0x00C %LE %Long Data.Long(A:&FLEXSPI_BASE+0x00C)&~0x20
|
|
|
|
RETURN
|
|
)
|
|
|
|
READ_ID_TEST:
|
|
(
|
|
PRINT "READ_ID_TEST..."
|
|
|
|
Data.Set ASD:&FLEXSPI_BASE+0x80 %LE %Long 0x80000900 ;FLASHCR2
|
|
|
|
Data.Set ASD:&FLEXSPI_BASE+0x14 %LE %Long -1 ;INTR clear
|
|
|
|
Data.Set A:&FLEXSPI_BASE+0xB8 %Long 0x1 ;IPRXFCR
|
|
Data.Set A:&FLEXSPI_BASE+0xBC %Long 0x1 ;IPTXFCR
|
|
|
|
Data.Set A:&FLEXSPI_BASE+0x250 %LE %Long 0x2404049F ;readid with 4 bytes READ data
|
|
Data.Set A:&FLEXSPI_BASE+0x254 %LE %Long 0x0 ;
|
|
Data.Set A:&FLEXSPI_BASE+0x258 %LE %Long 0x0 ;
|
|
Data.Set A:&FLEXSPI_BASE+0x25c %LE %Long 0x0 ;
|
|
|
|
Data.Set A:&FLEXSPI_BASE+0x0A4 %LE %Long (5.<<16.)|0x4
|
|
|
|
Data.Set A:&FLEXSPI_BASE+0x0B0 %LE %Long 1 ;start
|
|
|
|
PRINT "1st 0x" Data.Long(A:&FLEXSPI_BASE+0x100)&0xFF " (Manufacturer)"
|
|
PRINT "2nd 0x" (Data.Long(A:&FLEXSPI_BASE+0x100)>>8.)&0xFF " (Device ID)"
|
|
PRINT "3rd 0x" (Data.Long(A:&FLEXSPI_BASE+0x100)>>16.)&0xFF
|
|
PRINT "4th 0x" Data.Long(A:&FLEXSPI_BASE+0x100)>>24.
|
|
|
|
RETURN
|
|
)
|
|
|
|
SC_PAD_SET:
|
|
(
|
|
ENTRY &padNum &mux &ctrl &cfg
|
|
|
|
&data=0x00000001 ;version
|
|
&data=&data|0x00000400 ;message size
|
|
&data=&data|0x00060000 ;svc_pad
|
|
&data=&data|0x05000000 ;func
|
|
|
|
;wait until Tx buffer empty
|
|
Data.Set A:&ipc_addr %Long &data
|
|
Data.Set A:&ipc_addr+0x4 %Long &ctrl
|
|
|
|
&data=&padNum
|
|
&data=&data|(&mux<<16.)
|
|
&data=&data|(&cfg<<24.)
|
|
Data.Set A:&ipc_addr+0x8 %Long &data
|
|
|
|
Data.Set A:&ipc_addr+0xC %Long 0x00
|
|
|
|
&status=Data.Long(A:&ipc_addr+0x20)
|
|
&rxBuff=(&ipc_addr+0x10)
|
|
WHILE (((&status>>24.)&0xF)!=0)
|
|
(
|
|
&data=Data.Long(A:&rxBuff)
|
|
&rxBuff=&rxBuff+0x4
|
|
&status=Data.Long(A:&ipc_addr+0x20)
|
|
)
|
|
RETURN
|
|
)
|
|
|
|
//Power_ON_SDHC1
|
|
SC_POWER_ON_SET:
|
|
(
|
|
ENTRY &resource &mode
|
|
|
|
&data=0x00000001 ;version
|
|
&data=&data|0x00000200 ;message size
|
|
&data=&data|0x00020000 ;svc_pm
|
|
&data=&data|0x03000000 ;func, POWER_MODE
|
|
|
|
;wait until Tx buffer empty
|
|
Data.Set A:&ipc_addr %Long &data
|
|
|
|
&data=&resource
|
|
&data=&data|(&mode<<16.)
|
|
&data=&data|0x07000000
|
|
Data.Set A:&ipc_addr+0x4 %Long &data
|
|
|
|
&status=Data.Long(A:&ipc_addr+0x20)
|
|
&rxBuff=(&ipc_addr+0x10)
|
|
WHILE (((&status>>24.)&0xF)!=0)
|
|
(
|
|
&data=Data.Long(A:&rxBuff)
|
|
&rxBuff=&rxBuff+0x4
|
|
&status=Data.Long(A:&ipc_addr+0x20)
|
|
)
|
|
|
|
wait 200.ms ;dummy wait
|
|
|
|
RETURN
|
|
)
|
|
|
|
//Clock_Enable_SDHC1
|
|
SC_CLK_ENABLE:
|
|
(
|
|
ENTRY &resource &clk
|
|
|
|
&data=0x00000001 ;version
|
|
&data=&data|0x00000300 ;message size
|
|
&data=&data|0x00020000 ;svc_pm
|
|
&data=&data|0x07000000 ;func, POWER_MODE
|
|
|
|
;wait until Tx buffer empty
|
|
Data.Set A:&ipc_addr %Long &data
|
|
|
|
&data=&resource
|
|
&data=&data|(&clk<<16.)
|
|
&data=&data|0x01000000
|
|
Data.Set A:&ipc_addr+0x4 %Long &data
|
|
|
|
;&data=0x00CA0001
|
|
&data=0x00C81301 ;imx8qx
|
|
Data.Set A:&ipc_addr+0x8 %Long &data
|
|
|
|
&status=Data.Long(A:&ipc_addr+0x20)
|
|
&rxBuff=(&ipc_addr+0x10)
|
|
WHILE (((&status>>24.)&0xF)!=0)
|
|
(
|
|
&data=Data.Long(A:&rxBuff)
|
|
&rxBuff=&rxBuff+0x4
|
|
&status=Data.Long(A:&ipc_addr+0x20)
|
|
)
|
|
|
|
wait 200.ms ;dummy wait
|
|
|
|
RETURN
|
|
)
|
|
|