/* ---------------------------------------------------------------------------- | |
* SAM Software Package License | |
* ---------------------------------------------------------------------------- | |
* Copyright (c) 2015, Atmel Corporation | |
* | |
* All rights reserved. | |
* | |
* Redistribution and use in source and binary forms, with or without | |
* modification, are permitted provided that the following conditions are met: | |
* | |
* - Redistributions of source code must retain the above copyright notice, | |
* this list of conditions and the disclaimer below. | |
* | |
* Atmel's name may not be used to endorse or promote products derived from | |
* this software without specific prior written permission. | |
* | |
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR | |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE | |
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, | |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, | |
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, | |
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
* ---------------------------------------------------------------------------- | |
*/ | |
/** | |
* \file | |
* | |
* Implementation of memories configuration on board. | |
* | |
*/ | |
/*---------------------------------------------------------------------------- | |
* Headers | |
*----------------------------------------------------------------------------*/ | |
#include "board.h" | |
#include "board_memories.h" | |
#include "trace.h" | |
#include "cortex-a/mmu.h" | |
#include "peripherals/hsmc.h" | |
#include "peripherals/l2cc.h" | |
#include "peripherals/matrix.h" | |
#include "peripherals/pmc.h" | |
#include "memories/ddram.h" | |
/*---------------------------------------------------------------------------- | |
* Local constants | |
*----------------------------------------------------------------------------*/ | |
const static struct _l2cc_control l2cc_cfg = { | |
.instruct_prefetch = true, // Instruction prefetch enable | |
.data_prefetch = true, // Data prefetch enable | |
.double_linefill = true, | |
.incr_double_linefill = true, | |
/* Disable Write back (enables write through, Use this setting | |
if DDR2 mem is not write-back) */ | |
//cfg.no_write_back = true, | |
.force_write_alloc = FWA_NO_ALLOCATE, | |
.offset = 31, | |
.prefetch_drop = true, | |
.standby_mode = true, | |
.dyn_clock_gating = true | |
}; | |
/*---------------------------------------------------------------------------- | |
* Local functions | |
*----------------------------------------------------------------------------*/ | |
#ifdef BOARD_DDRAM_TYPE | |
static void matrix_configure_slave_ddr(void) | |
{ | |
int i; | |
/* Disable write protection */ | |
matrix_remove_write_protection(MATRIX0); | |
/* External DDR */ | |
/* DDR port 0 not used */ | |
for (i = H64MX_SLAVE_DDR_PORT1; i <= H64MX_SLAVE_DDR_PORT7; i++) { | |
matrix_configure_slave_sec(MATRIX0, i, 0xff, 0xff, 0xff); | |
matrix_set_slave_split_addr(MATRIX0, i, MATRIX_AREA_128M, 0xf); | |
matrix_set_slave_region_size(MATRIX0, i, MATRIX_AREA_128M, 0x1); | |
} | |
} | |
#endif | |
#ifdef CONFIG_HAVE_NANDFLASH | |
static void matrix_configure_slave_nand(void) | |
{ | |
/* Disable write protection */ | |
matrix_remove_write_protection(MATRIX1); | |
/* NFC Command Register */ | |
matrix_configure_slave_sec(MATRIX1, | |
H32MX_SLAVE_NFC_CMD, 0xc0, 0xc0, 0xc0); | |
matrix_set_slave_split_addr(MATRIX1, | |
H32MX_SLAVE_NFC_CMD, MATRIX_AREA_128M, 0xc0); | |
matrix_set_slave_region_size(MATRIX1, | |
H32MX_SLAVE_NFC_CMD, MATRIX_AREA_128M, 0xc0); | |
/* NFC SRAM */ | |
matrix_configure_slave_sec(MATRIX1, | |
H32MX_SLAVE_NFC_SRAM, 0x1, 0x1, 0x1); | |
matrix_set_slave_split_addr(MATRIX1, | |
H32MX_SLAVE_NFC_SRAM, MATRIX_AREA_8K, 0x1); | |
matrix_set_slave_region_size(MATRIX1, | |
H32MX_SLAVE_NFC_SRAM, MATRIX_AREA_8K, 0x1); | |
} | |
#endif | |
/*---------------------------------------------------------------------------- | |
* Exported functions | |
*----------------------------------------------------------------------------*/ | |
void board_setup_tlb(uint32_t *tlb) | |
{ | |
uint32_t addr; | |
/* TODO: some peripherals are configured TTB_SECT_STRONGLY_ORDERED | |
instead of TTB_SECT_SHAREABLE_DEVICE because their drivers have to | |
be verified for correct operation when write-back is enabled */ | |
/* Reset table entries */ | |
for (addr = 0; addr < 4096; addr++) | |
tlb[addr] = 0; | |
/* 0x00000000: ROM */ | |
tlb[0x000] = TTB_SECT_ADDR(0x00000000) | |
| TTB_SECT_AP_READ_ONLY | |
| TTB_SECT_DOMAIN(0xf) | |
| TTB_SECT_EXEC | |
| TTB_SECT_CACHEABLE_WB | |
| TTB_TYPE_SECT; | |
/* 0x00100000: NFC SRAM */ | |
tlb[0x001] = TTB_SECT_ADDR(0x00100000) | |
| TTB_SECT_AP_FULL_ACCESS | |
| TTB_SECT_DOMAIN(0xf) | |
| TTB_SECT_EXEC | |
| TTB_SECT_SHAREABLE_DEVICE | |
| TTB_TYPE_SECT; | |
/* 0x00200000: SRAM */ | |
tlb[0x002] = TTB_SECT_ADDR(0x00200000) | |
| TTB_SECT_AP_FULL_ACCESS | |
| TTB_SECT_DOMAIN(0xf) | |
| TTB_SECT_EXEC | |
| TTB_SECT_CACHEABLE_WB | |
| TTB_TYPE_SECT; | |
/* 0x00300000: UDPHS (RAM) */ | |
tlb[0x003] = TTB_SECT_ADDR(0x00300000) | |
| TTB_SECT_AP_FULL_ACCESS | |
| TTB_SECT_DOMAIN(0xf) | |
| TTB_SECT_EXEC_NEVER | |
| TTB_SECT_SHAREABLE_DEVICE | |
| TTB_TYPE_SECT; | |
/* 0x00400000: UHPHS (OHCI) */ | |
tlb[0x004] = TTB_SECT_ADDR(0x00400000) | |
| TTB_SECT_AP_FULL_ACCESS | |
| TTB_SECT_DOMAIN(0xf) | |
| TTB_SECT_EXEC_NEVER | |
| TTB_SECT_SHAREABLE_DEVICE | |
| TTB_TYPE_SECT; | |
/* 0x00500000: UDPHS (EHCI) */ | |
tlb[0x005] = TTB_SECT_ADDR(0x00500000) | |
| TTB_SECT_AP_FULL_ACCESS | |
| TTB_SECT_DOMAIN(0xf) | |
| TTB_SECT_EXEC_NEVER | |
| TTB_SECT_SHAREABLE_DEVICE | |
| TTB_TYPE_SECT; | |
/* 0x00600000: AXIMX */ | |
tlb[0x006] = TTB_SECT_ADDR(0x00600000) | |
| TTB_SECT_AP_FULL_ACCESS | |
| TTB_SECT_DOMAIN(0xf) | |
| TTB_SECT_EXEC_NEVER | |
| TTB_SECT_SHAREABLE_DEVICE | |
| TTB_TYPE_SECT; | |
/* 0x00700000: DAP */ | |
tlb[0x007] = TTB_SECT_ADDR(0x00700000) | |
| TTB_SECT_AP_FULL_ACCESS | |
| TTB_SECT_DOMAIN(0xf) | |
| TTB_SECT_EXEC_NEVER | |
| TTB_SECT_SHAREABLE_DEVICE | |
| TTB_TYPE_SECT; | |
/* 0x00a00000: L2CC */ | |
tlb[0x00a] = TTB_SECT_ADDR(0x00a00000) | |
| TTB_SECT_AP_FULL_ACCESS | |
| TTB_SECT_DOMAIN(0xf) | |
| TTB_SECT_EXEC_NEVER | |
| TTB_SECT_SHAREABLE_DEVICE | |
| TTB_TYPE_SECT; | |
tlb[0x00b] = TTB_SECT_ADDR(0x00b00000) | |
| TTB_SECT_AP_FULL_ACCESS | |
| TTB_SECT_DOMAIN(0xf) | |
| TTB_SECT_EXEC_NEVER | |
| TTB_SECT_SHAREABLE_DEVICE | |
| TTB_TYPE_SECT; | |
/* 0x10000000: EBI Chip Select 0 */ | |
for (addr = 0x100; addr < 0x200; addr++) | |
tlb[addr] = TTB_SECT_ADDR(addr << 20) | |
| TTB_SECT_AP_FULL_ACCESS | |
| TTB_SECT_DOMAIN(0xf) | |
| TTB_SECT_EXEC_NEVER | |
| TTB_SECT_STRONGLY_ORDERED | |
| TTB_TYPE_SECT; | |
/* 0x20000000: DDR Chip Select */ | |
/* (64MB cacheable, 448MB strongly ordered) */ | |
for (addr = 0x200; addr < 0x240; addr++) | |
tlb[addr] = TTB_SECT_ADDR(addr << 20) | |
| TTB_SECT_AP_FULL_ACCESS | |
| TTB_SECT_DOMAIN(0xf) | |
| TTB_SECT_EXEC | |
| TTB_SECT_CACHEABLE_WB | |
| TTB_TYPE_SECT; | |
for (addr = 0x240; addr < 0x400; addr++) | |
tlb[addr] = TTB_SECT_ADDR(addr << 20) | |
| TTB_SECT_AP_FULL_ACCESS | |
| TTB_SECT_DOMAIN(0xf) | |
| TTB_SECT_EXEC | |
| TTB_SECT_STRONGLY_ORDERED | |
| TTB_TYPE_SECT; | |
/* 0x40000000: DDR AESB Chip Select */ | |
for (addr = 0x400; addr < 0x600; addr++) | |
tlb[addr] = TTB_SECT_ADDR(addr << 20) | |
| TTB_SECT_AP_FULL_ACCESS | |
| TTB_SECT_DOMAIN(0xf) | |
| TTB_SECT_EXEC | |
| TTB_SECT_CACHEABLE_WB | |
| TTB_TYPE_SECT; | |
/* 0x60000000: EBI Chip Select 1 */ | |
for (addr = 0x600; addr < 0x700; addr++) | |
tlb[addr] = TTB_SECT_ADDR(addr << 20) | |
| TTB_SECT_AP_FULL_ACCESS | |
| TTB_SECT_DOMAIN(0xf) | |
| TTB_SECT_EXEC_NEVER | |
| TTB_SECT_STRONGLY_ORDERED | |
| TTB_TYPE_SECT; | |
/* 0x70000000: EBI Chip Select 2 */ | |
for (addr = 0x700; addr < 0x800; addr++) | |
tlb[addr] = TTB_SECT_ADDR(addr << 20) | |
| TTB_SECT_AP_FULL_ACCESS | |
| TTB_SECT_DOMAIN(0xf) | |
| TTB_SECT_EXEC_NEVER | |
| TTB_SECT_STRONGLY_ORDERED | |
| TTB_TYPE_SECT; | |
/* 0x80000000: EBI Chip Select 3 */ | |
for (addr = 0x800; addr < 0x900; addr++) | |
tlb[addr] = TTB_SECT_ADDR(addr << 20) | |
| TTB_SECT_AP_FULL_ACCESS | |
| TTB_SECT_DOMAIN(0xf) | |
| TTB_SECT_EXEC_NEVER | |
| TTB_SECT_STRONGLY_ORDERED | |
| TTB_TYPE_SECT; | |
/* 0x90000000: QSPI0/1 AESB MEM */ | |
for (addr = 0x900; addr < 0xa00; addr++) | |
tlb[addr] = TTB_SECT_ADDR(addr << 20) | |
| TTB_SECT_AP_FULL_ACCESS | |
| TTB_SECT_DOMAIN(0xf) | |
| TTB_SECT_EXEC | |
| TTB_SECT_STRONGLY_ORDERED | |
| TTB_TYPE_SECT; | |
/* 0xa0000000: SDMMC0 */ | |
for (addr = 0xa00; addr < 0xb00; addr++) | |
tlb[addr] = TTB_SECT_ADDR(addr << 20) | |
| TTB_SECT_AP_FULL_ACCESS | |
| TTB_SECT_DOMAIN(0xf) | |
| TTB_SECT_EXEC_NEVER | |
//| TTB_SECT_SHAREABLE_DEVICE | |
| TTB_SECT_STRONGLY_ORDERED | |
| TTB_TYPE_SECT; | |
/* 0xb0000000: SDMMC1 */ | |
for (addr = 0xb00; addr < 0xc00; addr++) | |
tlb[addr] = TTB_SECT_ADDR(addr << 20) | |
| TTB_SECT_AP_FULL_ACCESS | |
| TTB_SECT_DOMAIN(0xf) | |
| TTB_SECT_EXEC_NEVER | |
//| TTB_SECT_SHAREABLE_DEVICE | |
| TTB_SECT_STRONGLY_ORDERED | |
| TTB_TYPE_SECT; | |
/* 0xc0000000: NFC Command Register */ | |
for (addr = 0xc00; addr < 0xd00; addr++) | |
tlb[addr] = TTB_SECT_ADDR(addr << 20) | |
| TTB_SECT_AP_FULL_ACCESS | |
| TTB_SECT_DOMAIN(0xf) | |
| TTB_SECT_EXEC_NEVER | |
//| TTB_SECT_SHAREABLE_DEVICE | |
| TTB_SECT_STRONGLY_ORDERED | |
| TTB_TYPE_SECT; | |
/* 0xd0000000: QSPI0/1 MEM */ | |
for (addr = 0xe00; addr < 0xe00; addr++) | |
tlb[addr] = TTB_SECT_ADDR(addr << 20) | |
| TTB_SECT_AP_FULL_ACCESS | |
| TTB_SECT_DOMAIN(0xf) | |
| TTB_SECT_EXEC | |
| TTB_SECT_STRONGLY_ORDERED | |
| TTB_TYPE_SECT; | |
/* 0xf0000000: Internal Peripherals */ | |
tlb[0xf00] = TTB_SECT_ADDR(0xf0000000) | |
| TTB_SECT_AP_FULL_ACCESS | |
| TTB_SECT_DOMAIN(0xf) | |
| TTB_SECT_EXEC | |
| TTB_SECT_STRONGLY_ORDERED | |
| TTB_TYPE_SECT; | |
/* 0xf8000000: Internal Peripherals */ | |
tlb[0xf80] = TTB_SECT_ADDR(0xf8000000) | |
| TTB_SECT_AP_FULL_ACCESS | |
| TTB_SECT_DOMAIN(0xf) | |
| TTB_SECT_EXEC | |
| TTB_SECT_STRONGLY_ORDERED | |
| TTB_TYPE_SECT; | |
/* 0xfc000000: Internal Peripherals */ | |
tlb[0xfc0] = TTB_SECT_ADDR(0xfc000000) | |
| TTB_SECT_AP_FULL_ACCESS | |
| TTB_SECT_DOMAIN(0xf) | |
| TTB_SECT_EXEC | |
| TTB_SECT_STRONGLY_ORDERED | |
| TTB_TYPE_SECT; | |
} | |
void board_cfg_l2cc(void) | |
{ | |
l2cc_configure(&l2cc_cfg); | |
} | |
void board_cfg_ddram (void) | |
{ | |
#ifdef BOARD_DDRAM_TYPE | |
matrix_configure_slave_ddr(); | |
struct _mpddrc_desc desc; | |
ddram_init_descriptor(&desc, BOARD_DDRAM_TYPE); | |
ddram_configure(&desc); | |
#else | |
trace_fatal("Cannot configure DDRAM: target board have no DDRAM type definition!"); | |
#endif | |
} | |
#ifdef CONFIG_HAVE_NANDFLASH | |
void board_cfg_nand_flash(void) | |
{ | |
matrix_configure_slave_nand(); | |
hsmc_nand_configure(BOARD_NANDFLASH_CS, BOARD_NANDFLASH_BUS_WIDTH); | |
} | |
#endif |