blob: 3529ccbdff9a22ee682ce394221ee233e019465e [file] [log] [blame]
/* ----------------------------------------------------------------------------
* 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