blob: e45e28a60832afa10647f5db223c3681f091482c [file] [log] [blame]
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright © 2010 by Rafaël Carré
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "config.h"
#include "cpu.h"
#define CACHE_NONE 0
#define CACHE_ALL 0x0C
#define UNCACHED_ADDR(a) (a + 0x10000000)
#if defined(SANSA_CLIP) || defined(SANSA_M200V4) || defined(SANSA_C200V2)
/* 16 bits external bus, low power SDRAM, 16 Mbits = 2 Mbytes */
#define MEMORY_MODEL 0x21
#elif defined(SANSA_E200V2) || defined(SANSA_FUZE) || defined(SANSA_CLIPV2) \
|| defined(SANSA_CLIPPLUS) || defined(SANSA_FUZEV2)
/* 16 bits external bus, high performance SDRAM, 64 Mbits = 8 Mbytes */
#define MEMORY_MODEL 0x5
#else
#error "The external memory in your player is unknown"
#endif
.global memory_init
.text
memory_init:
#ifdef BOOTLOADER
ldr r2, =0xC80F0014 @ CGU_PERI
ldr r1, [r2]
orr r1, r1, #(CGU_EXTMEM_CLOCK_ENABLE|CGU_EXTMEMIF_CLOCK_ENABLE)
str r1, [r2]
ldr r3, =0xC6030000 @ MPMC_BASE
mov r2, #1 @ enable MPMC
str r2, [r3] @ MPMC_CONTROL
ldr r2, =0x183 @ SDRAM NOP, all clocks high
str r2, [r3, #0x20] @ MPMC_DYNAMIC_CONTROL
ldr r2, =0x103 @ SDRAM PALL, all clocks high
str r2, [r3, #0x20] @ MPMC_DYNAMIC_CONTROL
ldr r1, =0x138 @ 0x138 * 16 HCLK ticks between SDRAM refresh cycles
str r1, [r3, #0x24] @ MPMC_DYNAMIC_REFRESH
mov r2, #0 @ little endian, HCLK:MPMCCLKOUT[3:0] ratio = 1:1
str r2, [r3, #8] @ MPMC_CONFIG
ldr r2, [r3, #0xfe8] @ MPMC_PERIPH_ID2
tst r2, #0xf0
movne r2, #1 @ command delayed, clock out not delayed
strne r2, [r3, #0x28] @ MPMC_DYNAMIC_READ_CONFIG
mov r1, #2
mov r0, #5
mov ip, #4
mov r2, #0
str r1, [r3, #0x30] @ tRP
str ip, [r3, #0x34] @ tRAS
str r0, [r3, #0x38] @ tSREX
str r2, [r3, #0x3c] @ tAPR
str ip, [r3, #0x40] @ tDAL
str r1, [r3, #0x44] @ tWR
str r0, [r3, #0x48] @ tRC
str r0, [r3, #0x4c] @ tRFC
str r0, [r3, #0x50] @ tXSR
str r1, [r3, #0x54] @ tRRD
str r1, [r3, #0x58] @ tMRD
mov ip, #(MEMORY_MODEL << 7)
str ip, [r3, #0x100] @ MPMC_DYNAMIC_CONFIG_CONFIG_0
orr r1, r1, #(2<<8) @ CAS & RAS latency = 2 clock cycle
str r1, [r3, #0x104] @ MPMC_DYNAMIC_CONFIG_RASCAS_0
str r2, [r3, #0x120] @ MPMC_DYNAMIC_CONFIG_CONFIG_1
str r2, [r3, #0x124] @ MPMC_DYNAMIC_CONFIG_RASCAS_1
str r2, [r3, #0x140] @ MPMC_DYNAMIC_CONFIG_CONFIG_2
str r2, [r3, #0x144] @ MPMC_DYNAMIC_CONFIG_RASCAS_2
str r2, [r3, #0x160] @ MPMC_DYNAMIC_CONFIG_CONFIG_3
str r2, [r3, #0x164] @ MPMC_DYNAMIC_CONFIG_RASCAS_3
mov r1, #0x82 @ SDRAM MODE, MPMCCLKOUT runs continuously
str r1, [r3, #0x20] @ MPMC_DYNAMIC_CONTROL
ldr r1, =DRAM_ORIG+(0x2300*MEMORYSIZE)
ldr r1, [r1]
str r2, [r3, #0x20] @ MPMC_DYNAMIC_CONTROL= SDRAM NORMAL,
@ MPMCCLKOUT stopped when SDRAM is idle
ldr r2, [r3, #0x100] @ MPMC_DYNAMIC_CONFIG_0
orr r2, r2, #(1<<19) @ buffer enable
str r2, [r3, #0x100]
#endif /* BOOTLOADER */
@ XXX: to avoid using the stack, we rely on the fact that:
@ - ttb_init
@ - map_section
@ - enable_mmu
@ do not modify ip (r12)
mov ip, lr
/* Setup MMU */
bl ttb_init
mov r0, #0 @ physical address
mov r1, #0 @ virtual address
mov r2, #0x1000 @ size (all memory)
mov r3, #CACHE_NONE
bl map_section
mov r0, #0 @ physical address
ldr r1, =IRAM_ORIG @ virtual address
mov r2, #1 @ size : 1MB
mov r3, #CACHE_ALL
bl map_section
mov r0, #0 @ physical address
ldr r1, =UNCACHED_ADDR(IRAM_ORIG) @ virtual address
mov r2, #1 @ size : 1MB
mov r3, #CACHE_NONE
bl map_section
mov r0, #0x30000000 @ physical address
mov r1, #DRAM_ORIG @ virtual address
mov r2, #MEMORYSIZE @ size
mov r3, #CACHE_ALL
bl map_section
mov r0, #0x30000000 @ physical address
mov r1, #UNCACHED_ADDR(DRAM_ORIG) @ virtual address
mov r2, #MEMORYSIZE @ size
mov r3, #CACHE_NONE
bl map_section
/* map 1st mbyte of RAM at 0x0 to have exception vectors available */
#ifdef BOOTLOADER
mov r0, #0x81000000 @ physical address
#else
mov r0, #0x30000000 @ physical address
#endif
mov r1, #0 @ virtual address
mov r2, #1 @ size
mov r3, #CACHE_ALL
bl map_section
bl enable_mmu
bx ip