Thank you very much for your response, CptTitanic; it is very much appreciated!
I've removed a zero ohm jumper resistor on my custom board to disconnect the chip select of the second SDRAM (connected to data bits D[32:16] on the EBI bus). After modifying SAM-BA and At91Bootstrap for a 16-bit SDRAM, I've found that the first SDRAM chip (connected to data bits D[15:0] on the EBI bus) works normally using the following call to sdram_init in At91bootstrap:
sdram_init( AT91C_SDRAMC_NC_10 | // Column bits
AT91C_SDRAMC_NR_13 |
AT91C_SDRAMC_CAS_3 |
AT91C_SDRAMC_NB_4_BANKS |
AT91C_SDRAMC_DBW_16_BITS |
AT91C_SDRAMC_TWR_3 |
AT91C_SDRAMC_TRC_9 |
AT91C_SDRAMC_TRP_3 |
AT91C_SDRAMC_TRCD_3 |
AT91C_SDRAMC_TRAS_6 |
AT91C_SDRAMC_TXSR_10,
(MASTER_CLOCK * 7)/1000000,
AT91C_SDRAMC_MD_SDRAM);
I've written standalone test programs to read and write data into the SDRAM chips, and I find that there is indeed a pattern to the bits that are not working.
When configured as a 16-bit bus for one SDRAM chip, reads and writes to SDRAM work normally up to (64*1024*1024) memory locations (64 MB). This is normal behavior.
However, when I set up the SDRAM using AT91C_SDRAMC_DBW_32_BITS, and when I use both of the SDRAM chips, I've found that reads to memory do not work for accessing locations greater than (64*1024*1024).
For memory locations greater than (64*1024*1024), the bits read from SDRAM are all high (0xFFFFFFFF).
I've added the following test code to AT91bootstrap. This test code is similar to my standalone program. When the counter variable exceeds (64*1024*1024), the bits read from SDRAM are all high.
#define MEM_START AT91C_EBI_SDRAM // AT91C_EBI_SDRAM address 0x20000000
#define MEM_SIZE 128*1024*1024
#define TEST_NUM 0xAAAAAAAA
void test_memory( void )
{
unsigned int *ptr = (unsigned int *) MEM_START;
int i;
dbg_print("Starting memory test and filling locations...\n\r");
for (i = 0; i < MEM_SIZE; i++)
ptr[i] = TEST_NUM;
dbg_print("Reading back test data...\n\r");
for (i = 0; i < MEM_SIZE; ++i) // fails for i greater than 64*1024*1024
{
if(ptr[i] != TEST_NUM)
{
dbg_print("Memory test did not pass\n\r");
return;
}
}
dbg_print("Memory test passed\n\r");
} // end of function
There is a section of the datasheet (Bus Matrix Master Remap Control Register, pg. 132) that may suggest bus remapping is required to use EBI memory locations greater than 64*1024*1024. Here is a link to the datasheet:
http://www.atmel.com/dyn/resources/prod ... oc6384.pdf.
In my At91bootstrap code, I've turned on bus remapping:
writel( AT91C_MATRIX_RCA926I | AT91C_MATRIX_RCA926D, AT91C_BASE_MATRIX + MATRIX_MRCR );
However, bus remapping still causes the above code to fail.
Perhaps we are dealing with an obscure hardware bug? I've checked the SDRAM connections, and everything appears to be wired up correctly.