Hi,
I’m trying to distinguish the difference between the Karo TX53-1331 (IMX535) and the Karo Tx53-8030 (IMX537) module at boot time (U-boot). I’d like to use a single U-boot image for both modules, and dynamically set the speed and configuration based on the board.
My first thought was to read the chip identification register, but I can’t find any means to distinguish between the two chips. The identification tells me that they are both IMX53 chips, but not whether they are 535 vs 537.
At a board level, the 1331 has 1 GB of external memory, and the 8030 has 512 MB. Additionally, we’re getting a new TX53 module with 2 GB of memory. It would be nice to use a memory size test to determine which board I’m using. I’ve struggled quite a bit with this task, due to the lack on an emulator and unfamiliarity the the ARM boot process, exception handling, and assembly language. My premise is to execute code prior to enabling the MMU, referencing the physical address of the RAM. Ideally, I’d want the data abort exception disabled, then write to the start of the second memory bank at PHYS_SDRAM_2 (0xB0000000). I’d read from the same location, and compare it with a known value. If the value matched, then I have the 1331 module with 1 GB of memory (forget about the 2 GB module for now), otherwise it’s the 8030 module. I didn’t see a way to specifically disable the data abort exception, so I tried to add a handler that just returned to the statement after the exception. That resulted in no output to the display (initialization failed).
Assuming that maybe I was getting a different exception, I tried installing the same handler to all the exception vectors, with some modification based on the exception mode and where the exception address is saved. This produced the same result.
I’ve tried many different approaches, but can’t seem to get them to do what I want. Additionally, the simplistic approach given above needs to be enhanced to handle recognition of a module with 2 GB of memory.
I also attempted to use the get_ram_size() routine used by some other Arm processors for the same problem. It would be nice to be able to call this during early initialization so that I could set the processor speed/type based on the result.
The lack of an emulator really complicates things, since I have no way of stepping through the code and evaluating registers other than rebuilding the image with instrumentation. The instrumentation is limited as well, since I’m in the early bootup, and don’t have print capabilities.
The test_memory macro (below) is called from lowlevel_init.S, immediately after the call to sdram_init. Of note is the fact that for karo modules, the sdram_init routine is not used. Instead, the initialization is done inside flash_header.S, using hardcoded register offsets (which made it difficult for me to find). I modified that code to always initialize with the assumption that there are two banks of memory.
FYI… In support of the changes to test memory, I modified several configuration macros related to memory size and CPU speed, changing them to global variables. I modified all code that referenced them to use the variables instead.
My questions are:
Miscellaneous coding:
Data abort handler
data_abort:
subs pc, lr, #4 // Return to location after abort
Test memory
.macro _test_memory
#if BANK_READY_TEST
ldr r3, =ESDCTL_BASE_ADDR
ldr r0, [r3, #0x10] //ESDMISC
adrls r1, PHYS_SDRAM_2_SIZE // Load address of PHYS_SDRAM_2_SIZE into r1
// Test the CSD1_RDY bit to see if there is another RAM Bank
tst r0, #0x40000000
beq cfg1Gigabyte
b cfg512Megabyte
#endif
ldr r0, =PHYS_SDRAM_2 // Load physical address of second memory bank into r0 (0xB0000000)
adrls r1, PHYS_SDRAM_2_SIZE // Load address of PHYS_SDRAM_2_SIZE into r1
ldr r2, =0xABCDABCD // Load 0xABCDABCD into r2
ldr r3, =0xDBCADBCA // Load 0xDBCADBCA into r3
str r2, [r0] // Store 0xABCDABCD at location PHYS_SDRAM_2
ldr r3, [r0] // Load r3 with contents of location PHYS_SDRAM_2
cmp r3, r2 // Compare the content of PHYS_SDRAM_2 with 0xABCDABCD
beq cfg1Gigabyte // If we were able to read the value back successfully, we have two memory banks
cfg512Megabyte:
ldr r2, =0x00000000 // Total Memory: 512 Megabytes
strls r2, [r1] // Load 0 Megabytes into PHYS_SDRAM_2_SIZE
#if BANK_READY_TEST
ldr r3, =ESDCTL_BASE_ADDR
ldr r0, [r3, #0x0] //ESDCTL
// Turn off enable for bank 2
and r0, r0, #0xBFFFFFFF
str r0, [r3, #0x0]
#endif
b cfgDone
cfg1Gigabyte:
ldr r2, =0x20000000 // Total Memory: 1 Gigabyte
strls r2, [r1] // Load 512 Megabytes into PHYS_SDRAM_2_SIZE
cfgDone:
.endm @ _test_memory
Take a look a the spl approach done in U-boot for the mx6 ventana boards:
It can detect the chip variant (quad/dual-lite.solo), the different RAM densities and configure it dynamically.
Maybe you could try porting spl support to mx53 karo board.
Hi Chris
you can try to read ESDCTL_ESDCTL register:
for "TX53 module with 2 GB of memory" one can expect both
SDE_0,1 set. For others one can check difference in ROW,COL numbers.
p.211, 1233, IMX53RM i.MX53 Reference Manual
Best regards
igor