| /* ---------------------------------------------------------------------------- | |
| * 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 |