From ec1d1b72fc58f664506ed4a8071cf8d48c7d9e64 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Fri, 2 Aug 2013 11:11:57 -0600 Subject: SAMA5: More MMU-related changes to properly initialize SDRAM --- nuttx/ChangeLog | 11 + nuttx/arch/arm/src/armv7-a/arm_mmu.c | 205 +++++++++++++++++++ nuttx/arch/arm/src/armv7-a/cp15.h | 16 +- nuttx/arch/arm/src/armv7-a/mmu.h | 197 +++++++++++++++++- nuttx/arch/arm/src/sama5/Kconfig | 7 +- nuttx/arch/arm/src/sama5/Make.defs | 2 +- nuttx/arch/arm/src/sama5/chip/sama5d3x_memorymap.h | 25 ++- nuttx/arch/arm/src/sama5/sam_allocateheap.c | 20 +- nuttx/arch/arm/src/sama5/sam_boot.c | 226 ++++++++++----------- nuttx/configs/sama5d3x-ek/Kconfig | 17 ++ nuttx/configs/sama5d3x-ek/hello/defconfig | 16 +- nuttx/configs/sama5d3x-ek/norboot/defconfig | 2 +- nuttx/configs/sama5d3x-ek/nsh/defconfig | 2 +- nuttx/configs/sama5d3x-ek/ostest/defconfig | 2 +- nuttx/configs/sama5d3x-ek/src/sam_boot.c | 12 ++ nuttx/configs/sama5d3x-ek/src/sam_sdram.c | 139 +++++++------ nuttx/configs/sama5d3x-ek/src/sama5d3x-ek.h | 7 +- 17 files changed, 682 insertions(+), 224 deletions(-) create mode 100644 nuttx/arch/arm/src/armv7-a/arm_mmu.c diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog index 9d40b4253..4a72b867a 100644 --- a/nuttx/ChangeLog +++ b/nuttx/ChangeLog @@ -5257,4 +5257,15 @@ * nuttx/configs/sama5d3x-ek/src/sam_sdram.c: Add logic which will (eventually) support the SDRAM on the SAMA5D3x-EK board. Initial commit is untested and incomplete (2013-8-1). + * arch/arm/src/armv7-a/arm_mmu.c: Move some generic MMU logic + out of SAMA5-specific code into this share-able file (2013-8-2) + * arch/arm/src/armv7-a/mmu.h: Add inline functions to invalidate + a single TLB. + * arch/arm/src/sama5/sam_allocateheap.c and chip/sama5d3x_memorymap.h: + Add logic to handle signed overflow when a memory region is + greater than or equal to 2GB (2013-8-2). + * arch/arm/src/sama5/sam_boot.c: Boot logic now initially + configures DRAM as strongly ordered so that it can be initialized. + After initialization, the page table entries are modified so + that DRAM is fully cache-able (2018-8-2). diff --git a/nuttx/arch/arm/src/armv7-a/arm_mmu.c b/nuttx/arch/arm/src/armv7-a/arm_mmu.c new file mode 100644 index 000000000..b88ada551 --- /dev/null +++ b/nuttx/arch/arm/src/armv7-a/arm_mmu.c @@ -0,0 +1,205 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_mmu.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "cache.h" +#include "mmu.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mmu_l1_setentry + * + * Description: + * Set a one level 1 translation table entry. Only a single L1 page table + * is supported. + * + * Input Paramters: + * paddr - The physical address to be mapped. Must be aligned to a 1MB + * address boundary + * vaddr - The virtual address to be mapped. Must be aligned to a 1MB + * address boundary + * mmuflags - The MMU flags to use in the mapping. + * + ****************************************************************************/ + +#ifndef CONFIG_ARCH_ROMPGTABLE +void mmu_l1_setentry(uint32_t paddr, uint32_t vaddr, uint32_t mmuflags) +{ + uint32_t *l1table = (uint32_t*)PGTABLE_BASE_VADDR; + uint32_t index = vaddr >> 20; + + /* Save the page table entry */ + + l1table[index] = (paddr | mmuflags); + + /* Flush the data cache entry. Make sure that the modified contents + * of the page table are flushed into physical memory. + */ + + cp15_clean_dcache_bymva((uint32_t)&l1table[index]); + + /* Invalidate the TLB cache associated with virtual address range */ + + mmu_invalidate_region(vaddr, 1024*1024); +} +#endif + +/**************************************************************************** + * Name: mmu_l2_setentry + * + * Description: + * Set one small (4096B) entry in a level2 translation table. + * + * Input Parameters: + * l2vaddr - the virtual address of the beginning of the L2 translation + * table. + * paddr - The physical address to be mapped. Must be aligned to a 4KB + * address boundary + * vaddr - The virtual address to be mapped. Must be aligned to a 4KB + * address boundary + * mmuflags - The MMU flags to use in the mapping. + * + ****************************************************************************/ + +#ifndef CONFIG_ARCH_ROMPGTABLE +void mmu_l2_setentry(uint32_t l2vaddr, uint32_t paddr, uint32_t vaddr, + uint32_t mmuflags) +{ + uint32_t *l2table = (uint32_t*)l2vaddr; + uint32_t index; + + /* The table divides a 1Mb address space up into 256 entries, each + * corresponding to 4Kb of address space. The page table index is + * related to the offset from the beginning of 1Mb region. + */ + + index = (vaddr & 0x000ff000) >> 12; + + /* Save the table entry */ + + l2table[index] = (paddr | mmuflags); + + /* Flush the data cache entry. Make sure that the modified contents + * of the page table are flushed into physical memory. + */ + + cp15_clean_dcache_bymva((uint32_t)&l2table[index]); + + /* Invalidate the TLB cache associated with virtual address range */ + + cp15_invalidate_tlb_bymva(vaddr); +} +#endif + +/**************************************************************************** + * Name: mmu_l2_map_region + * + * Description: + * Set multiple level 1 translation table entries in order to map a + * region of memory. + * + * Input Parameters: + * mapping - Describes the mapping to be performed. + * + ****************************************************************************/ + +#ifndef CONFIG_ARCH_ROMPGTABLE +void mmu_l2_map_region(const struct section_mapping_s *mapping) +{ + uint32_t paddr = mapping->physbase; + uint32_t vaddr = mapping->virtbase; + uint32_t mmuflags = mapping->mmuflags; + int i; + + /* Loop, writting each mapping into the L1 page table */ + + for (i = 0; i < mapping->nsections; i++) + { + mmu_l1_setentry(paddr, vaddr, mmuflags); + paddr += SECTION_SIZE; + vaddr += SECTION_SIZE; + } +} +#endif + +/**************************************************************************** + * Name: mmu_invalidate_region + * + * Description: + * Invalidate TLBs for a range of addresses (all 4KB aligned). + * + * Input Parameters: + * vaddr - The beginning of the region to invalidate. + * size - The size of the region in bytes to be invalidated. + * + ****************************************************************************/ + +#ifndef CONFIG_ARCH_ROMPGTABLE +void mmu_invalidate_region(uint32_t vstart, size_t size) +{ + uint32_t vaddr = vstart & 0xfffff000; + uint32_t vend = vaddr + size; + + /* Loop, writting each mapping into the L1 page table */ + + while (vaddr < vend) + { + cp15_invalidate_tlb_bymva(vaddr); + vaddr += 4096; + } +} +#endif diff --git a/nuttx/arch/arm/src/armv7-a/cp15.h b/nuttx/arch/arm/src/armv7-a/cp15.h index 49face4cd..193437419 100644 --- a/nuttx/arch/arm/src/armv7-a/cp15.h +++ b/nuttx/arch/arm/src/armv7-a/cp15.h @@ -147,14 +147,14 @@ #define CP15_DCCIMVAC(r) _CP15(0, r, c7, c14, 1) #define CP15_DCCISW(r) _CP15(0, r, c7, c14, 2) -#define CP15_TLBIALLIS(r) _CP15(0, r, c8, c3, 0) /* TLB maintenance operations */ -#define CP15_TLBIMVAIS(r) _CP15(0, r, c8, c3, 1) -#define CP15_TLBIASIDIS(r) _CP15(0, r, c8, c3, 2) -#define CP15_TLBIMVAAIS(r) _CP15(0, r, c8, c3, 3) -#define CP15_TLBIALL(r,c) _CP15(0, r, c8, c, 0) /* CRm = c5, c6, or c7 */ -#define CP15_TLBIMVA(r,c) _CP15(0, r, c8, c, 1) /* CRm = c5, c6, or c7 */ -#define CP15_TLBIASID(r,c) _CP15(0, r, c8, c, 2) /* CRm = c5, c6, or c7 */ -#define CP15_TLBIMVAA(r,c) _CP15(0, r, c8, c, 3) /* CRm = c5, c6, or c7 */ +#define CP15_TLBIALLIS(r) _CP15(0, r, c8, c3, 0) /* Invalidate entire unified TLB Inner Shareable */ +#define CP15_TLBIMVAIS(r) _CP15(0, r, c8, c3, 1) /* Invalidate unified TLB entry by MVA and ASID, Inner Shareable */ +#define CP15_TLBIASIDIS(r) _CP15(0, r, c8, c3, 2) /* Invalidate unified TLB by ASID match Inner Shareable */ +#define CP15_TLBIMVAAIS(r) _CP15(0, r, c8, c3, 3) /* Invalidate unified TLB entry by MVA all ASID Inner Shareable */ +#define CP15_TLBIALL(r,c) _CP15(0, r, c8, c, 0) /* Invalidate entire instruction TLB. CRm = c5, c6, or c7 */ +#define CP15_TLBIMVA(r,c) _CP15(0, r, c8, c, 1) /* Invalidate instruction TLB entry by MVA and ASID. CRm = c5, c6, or c7 */ +#define CP15_TLBIASID(r,c) _CP15(0, r, c8, c, 2) /* Invalidate data TLB by ASID match. CRm = c5, c6, or c7 */ +#define CP15_TLBIMVAA(r,c) _CP15(0, r, c8, c, 3) /* Invalidate unified TLB entry by MVA and ASID. CRm = c5, c6, or c7 */ #define CP15_MCR(r) _CP15(0, r, c9, c12, 0) /* Performance Monitor Control Register */ #define CP15_PMCNTENSET(r) _CP15(0, r, c9, c12, 1) /* Count Enable Set Register */ diff --git a/nuttx/arch/arm/src/armv7-a/mmu.h b/nuttx/arch/arm/src/armv7-a/mmu.h index 4cd7fad10..3067add52 100644 --- a/nuttx/arch/arm/src/armv7-a/mmu.h +++ b/nuttx/arch/arm/src/armv7-a/mmu.h @@ -49,6 +49,14 @@ * Included Files ************************************************************************************/ +#include + +#ifndef __ASSEMBLY__ +# include +# include +# include "chip.h" +#endif /* __ASSEMBLY__ */ + /************************************************************************************ * Pre-processor Definitions ************************************************************************************/ @@ -490,7 +498,7 @@ * NMRR[23:22] = 0b11, Region is Write-Back, no Write-Allocate */ -#define PMD_STRONGLY_ORDER (0) +#define PMD_STRONGLY_ORDERED (0) #define PMD_DEVICE (PMD_SECT_B) #define PMD_WRITE_THROUGH (PMD_SECT_C) #define PMD_WRITE_BACK (PMD_SECT_B | PMD_SECT_C) @@ -511,6 +519,9 @@ PMD_SECT_DOM(0)) #define MMU_IOFLAGS (PMD_TYPE_SECT | PMD_SECT_AP_RW1 | PMD_DEVICE | \ PMD_SECT_DOM(0) | PMD_SECT_XN) +#define MMU_STRONGLY_ORDERED (PMD_TYPE_SECT | PMD_SECT_AP_RW1 | \ + PMD_STRONGLY_ORDERED | PMD_SECT_DOM(0) | \ + PMD_SECT_XN) #define MMU_L1_VECTORFLAGS (PMD_TYPE_PTE | PMD_PTE_PXN | PMD_PTE_DOM(0)) #define MMU_L2_VECTORFLAGS (PTE_TYPE_SMALL | PTE_WRITE_THROUGH | PTE_AP_RW1) @@ -787,6 +798,26 @@ #endif /* CONFIG_PAGING */ +/************************************************************************************ + * Public Types + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +/* struct section_mapping_s describes the L1 mapping of a large region of memory + * consisting of one or more 1MB sections (nsections). + * + * All addresses must be aligned to 1MB address boundaries. + */ + +struct section_mapping_s +{ + uint32_t physbase; /* Physical address of the region to be mapped */ + uint32_t virtbase; /* Virtual address of the region to be mapped */ + uint32_t mmuflags; /* MMU settings for the region (e.g., cache-able) */ + uint32_t nsections; /* Number of mappings in the region */ +}; +#endif + /************************************************************************************ * Assemby Macros ************************************************************************************/ @@ -814,7 +845,12 @@ * Name: cp15_invalidate_tlbs * * Description: - * Invalidate TLBs + * Invalidate entire unified TLB + * + * The Invalidate entire TLB operations invalidate all unlocked entries in the + * TLB. The operation ignores the value in the register Rt specified by the MCR + * instruction that performs the operation. Software does not have to write a + * value to the register before issuing the MCR instruction. * * Inputs: * None @@ -825,6 +861,24 @@ mcr p15, 0, \scratch, c8, c7, 0 /* TLBIALL */ .endm +/************************************************************************************ + * Name: cp15_invalidate_tlb_bymva + * + * Description: + * Invalidate unified TLB entry by MVA all ASID Inner Shareable + * + * Inputs: + * vaddr - The virtual address to be invalidated + * + ************************************************************************************/ + + .macro cp15_invalidate_tlb_bymva, vaddr + dsb + mcr p15, 0, \vaddr, c8, c3, 3 /* TLBIMVAAIS */ + dsb + isb + .endm + /************************************************************************************ * Name: cp15_wrdacr * @@ -1060,7 +1114,12 @@ static inline void cp15_disable_mmu(void) * Name: cp15_invalidate_tlbs * * Description: - * Invalidate TLBs + * Invalidate entire unified TLB + * + * The Invalidate entire TLB operations invalidate all unlocked entries in the + * TLB. The operation ignores the value in the register Rt specified by the MCR + * instruction that performs the operation. Software does not have to write a + * value to the register before issuing the MCR instruction. * * Inputs: * None @@ -1078,6 +1137,31 @@ static inline void cp15_invalidate_tlbs(void) ); } +/************************************************************************************ + * Name: cp15_invalidate_tlb_bymva + * + * Description: + * Invalidate unified TLB entry by MVA all ASID Inner Shareable + * + * Inputs: + * vaddr - The virtual address to be invalidated + * + ************************************************************************************/ + +static inline void cp15_invalidate_tlb_bymva(uint32_t vaddr) +{ + __asm__ __volatile__ + ( + "\tdsb\n" + "\tmcr p15, 0, %0, c8, c3, 3\n" /* TLBIMVAAIS */ + "\tdsb\n" + "\tisb\n" + : + : "r" (vaddr) + : "r1", "memory" + ); +} + /************************************************************************************ * Name: cp15_wrdacr * @@ -1144,6 +1228,61 @@ static inline void cp14_wrttb(unsigned int ttb) ); } +/************************************************************************************* + * Name: mmu_l1_getentry + * + * Description: + * Given a virtual address, return the valule of the corresponding L1 table entry. + * + * Input Paramters: + * vaddr - The virtual address to be mapped. + * + ************************************************************************************/ + +#ifndef CONFIG_ARCH_ROMPGTABLE +static inline uint32_t mmu_l1_getentry(uint32_t vaddr) +{ + uint32_t *l1table = (uint32_t*)PGTABLE_BASE_VADDR; + uint32_t index = vaddr >> 20; + + /* Return the address of the page table entry */ + + return l1table[index]; +} +#endif + +/************************************************************************************* + * Name: mmu_l2_getentry + * + * Description: + * Given a address of the beginning of an L2 page table and a virtual address, + * return the varlue of the corresponding L2 page table entry. + * + * Input Paramters: + * l2vaddr - The virtual address of the beginning of the L2 page table + * vaddr - The virtual address to be mapped. + * + ************************************************************************************/ + +#ifndef CONFIG_ARCH_ROMPGTABLE +static inline uint32_t mmu_l2_getentry(uint32_t l2vaddr, uint32_t vaddr) +{ + uint32_t *l2table = (uint32_t*)l2vaddr; + uint32_t index; + + /* The table divides a 1Mb address space up into 256 entries, each + * corresponding to 4Kb of address space. The page table index is + * related to the offset from the beginning of 1Mb region. + */ + + index = (vaddr & 0x000ff000) >> 12; + + /* Return the address of the page table entry */ + + return l2table[index]; +} +#endif + #endif /* __ASSEMBLY__ */ /************************************************************************************ @@ -1162,6 +1301,58 @@ extern "C" { #define EXTERN extern #endif +/************************************************************************************ + * Name: mmu_l1_setentry + * + * Description: + * Set a one level 1 translation table entry. Only a single L1 page table is + * supported. + * + * Input Paramters: + * paddr - The physical address to be mapped. Must be aligned to a 1MB address + * boundary + * vaddr - The virtual address to be mapped. Must be aligned to a 1MB address + * boundary + * mmuflags - The MMU flags to use in the mapping. + * + ************************************************************************************/ + +#ifndef CONFIG_ARCH_ROMPGTABLE +void mmu_l1_setentry(uint32_t paddr, uint32_t vaddr, uint32_t mmuflags); +#endif + +/************************************************************************************ + * Name: mmu_l2_map_region + * + * Description: + * Set multiple level 1 translation table entries in order to map a region of + * memory. + * + * Input Parameters: + * mapping - Describes the mapping to be performed. + * + ************************************************************************************/ + +#ifndef CONFIG_ARCH_ROMPGTABLE +void mmu_l2_map_region(const struct section_mapping_s *mapping); +#endif + +/**************************************************************************** + * Name: mmu_invalidate_region + * + * Description: + * Invalidate TLBs for a range of addresses (all 4KB aligned). + * + * Input Parameters: + * vaddr - The beginning of the region to invalidate. + * size - The size of the region in bytes to be invalidated. + * + ****************************************************************************/ + +#ifndef CONFIG_ARCH_ROMPGTABLE +void mmu_invalidate_region(uint32_t vstart, size_t size); +#endif + #undef EXTERN #ifdef __cplusplus } diff --git a/nuttx/arch/arm/src/sama5/Kconfig b/nuttx/arch/arm/src/sama5/Kconfig index 407d68772..68fcb3b08 100644 --- a/nuttx/arch/arm/src/sama5/Kconfig +++ b/nuttx/arch/arm/src/sama5/Kconfig @@ -44,7 +44,7 @@ config SAMA5_WDT default n config SAMA5_HSMC - bool "Multi-bit ECC Interrupt (HSMC)" + bool "Static Memory Controller (HSMC)" default n config SAMA5_SMD @@ -241,6 +241,7 @@ menu "External Memory Configuration" config SAMA5_DDRCS bool "External DDR-SDRAM Memory" default n + depends on SAMA5_MPDDRC ---help--- Build in support for DDR-SDRAM memory resources. @@ -270,6 +271,7 @@ endif # SAMA5_DDRCS config SAMA5_EBICS0 bool "External CS0 Memory" default n + depends on SAMA5_HSMC ---help--- Build in support for memory resources in the chip select 0 (CS0) memory region. @@ -318,6 +320,7 @@ endif # SAMA5_EBICS0 config SAMA5_EBICS1 bool "External CS1 Memory" default n + depends on SAMA5_HSMC ---help--- Build in support for memory resources in the chip select 1 (CS1) memory region. @@ -365,6 +368,7 @@ endif # SAMA5_EBICS1 config SAMA5_EBICS2 bool "External CS2 Memory" + depends on SAMA5_HSMC default n ---help--- Build in support for memory resources in the chip select 2 (CS2) @@ -414,6 +418,7 @@ endif # SAMA5_EBICS2 config SAMA5_EBICS3 bool "External CS3 Memory" default n + depends on SAMA5_HSMC ---help--- Build in support for memory resources in the chip select 3 (CS3) memory region. diff --git a/nuttx/arch/arm/src/sama5/Make.defs b/nuttx/arch/arm/src/sama5/Make.defs index c3a65ef47..176230cf6 100644 --- a/nuttx/arch/arm/src/sama5/Make.defs +++ b/nuttx/arch/arm/src/sama5/Make.defs @@ -62,7 +62,7 @@ CMN_CSRCS += up_mdelay.c up_udelay.c CMN_CSRCS += up_modifyreg8.c up_modifyreg16.c up_modifyreg32.c CMN_CSRCS += arm_assert.c arm_blocktask.c arm_copyfullstate.c arm_dataabort.c -CMN_CSRCS += arm_doirq.c arm_initialstate.c arm_prefetchabort.c +CMN_CSRCS += arm_doirq.c arm_initialstate.c arm_mmu.c arm_prefetchabort.c CMN_CSRCS += arm_releasepending.c arm_reprioritizertr.c CMN_CSRCS += arm_schedulesigaction.c arm_sigdeliver.c arm_syscall.c CMN_CSRCS += arm_unblocktask.c arm_undefinedinsn.c diff --git a/nuttx/arch/arm/src/sama5/chip/sama5d3x_memorymap.h b/nuttx/arch/arm/src/sama5/chip/sama5d3x_memorymap.h index abb40b63a..b3ba2deff 100644 --- a/nuttx/arch/arm/src/sama5/chip/sama5d3x_memorymap.h +++ b/nuttx/arch/arm/src/sama5/chip/sama5d3x_memorymap.h @@ -46,6 +46,13 @@ /************************************************************************************ * Pre-processor Definitions ************************************************************************************/ +/* Decimal configuration values may exceed 2Gb and, hence, overflow to negative + * values unless we force them to unsigned long: + */ + +#define __CONCAT(a,b) a ## b +#define MKULONG(a) __CONCAT(a,ul) + /* Overview: * * SAMA5 Physical (unmapped) Memory Map @@ -189,6 +196,14 @@ #define SAM_PERIPHB_SIZE (272*1024) /* 0xf8000000-0xf8043fff: Internal Peripherals */ #define SAM_SYSC_SIZE (1*1024*1024) /* 0xfff00000-0x0ffffedf: Internal Peripherals */ +/* Force configured sizes that might exceed 2GB to be unsigned long */ + +#define SAMA5_EBICS0_SIZE MKULONG(CONFIG_SAMA5_EBICS0_SIZE) +#define SAMA5_DDRCS_SIZE MKULONG(CONFIG_SAMA5_DDRCS_SIZE) +#define SAMA5_EBICS1_SIZE MKULONG(CONFIG_SAMA5_EBICS1_SIZE) +#define SAMA5_EBICS2_SIZE MKULONG(CONFIG_SAMA5_EBICS2_SIZE) +#define SAMA5_EBICS3_SIZE MKULONG(CONFIG_SAMA5_EBICS3_SIZE) + /* Convert size in bytes to number of sections (in Mb). */ #define _NSECTIONS(b) (((b)+0x000fffff) >> 20) @@ -212,11 +227,11 @@ #define SAM_AXIMX_NSECTIONS _NSECTIONS(SAM_AXIMX_SIZE) #define SAM_DAP_NSECTIONS _NSECTIONS(SAM_DAP_SIZE) -#define SAM_EBICS0_NSECTIONS _NSECTIONS(CONFIG_SAMA5_EBICS0_SIZE) -#define SAM_DDRCS_NSECTIONS _NSECTIONS(CONFIG_SAMA5_DDRCS_SIZE) -#define SAM_EBICS1_NSECTIONS _NSECTIONS(CONFIG_SAMA5_EBICS1_SIZE) -#define SAM_EBICS2_NSECTIONS _NSECTIONS(CONFIG_SAMA5_EBICS2_SIZE) -#define SAM_EBICS3_NSECTIONS _NSECTIONS(CONFIG_SAMA5_EBICS3_SIZE) +#define SAM_EBICS0_NSECTIONS _NSECTIONS(SAMA5_EBICS0_SIZE) +#define SAM_DDRCS_NSECTIONS _NSECTIONS(SAMA5_DDRCS_SIZE) +#define SAM_EBICS1_NSECTIONS _NSECTIONS(SAMA5_EBICS1_SIZE) +#define SAM_EBICS2_NSECTIONS _NSECTIONS(SAMA5_EBICS2_SIZE) +#define SAM_EBICS3_NSECTIONS _NSECTIONS(SAMA5_EBICS3_SIZE) #define SAM_NFCCR_NSECTIONS _NSECTIONS(SAM_NFCCR_SIZE) #define SAM_PERIPHA_NSECTIONS _NSECTIONS(SAM_PERIPHA_SIZE) diff --git a/nuttx/arch/arm/src/sama5/sam_allocateheap.c b/nuttx/arch/arm/src/sama5/sam_allocateheap.c index 7d68f15fb..a87aa50ab 100644 --- a/nuttx/arch/arm/src/sama5/sam_allocateheap.c +++ b/nuttx/arch/arm/src/sama5/sam_allocateheap.c @@ -45,6 +45,7 @@ #include #include +#include #include #include @@ -242,11 +243,11 @@ void up_addregion(void) size_t size; #ifdef CONFIG_SAMA5_ISRAM_HEAP -#if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP) + size = SAM_ISRAM0_SIZE + SAM_ISRAM1_SIZE; +#if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP) /* Allow user-mode access to the ISRAM heap */ - size = SAM_ISRAM0_SIZE + SAM_ISRAM1_SIZE; sam_uheap((uintptr_t)SAM_ISRAM0_VADDR, size); #endif @@ -261,10 +262,11 @@ void up_addregion(void) #ifdef CONFIG_SAMA5_DDRCS_HEAP if (nregions > 0) { + size = SAMA5_DDRCS_SIZE; + #if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP) /* Allow user-mode access to the ISRAM heap */ - size = CONFIG_SAMA5_DDRCS_SIZE; sam_uheap((uintptr_t)SAM_DDRCS_VSECTION, size); #endif @@ -285,10 +287,11 @@ void up_addregion(void) #ifdef SAMA5_EBICS0_HEAP if (nregions > 0) { + size = SAMA5_EBICS0_SIZE; + #if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP) /* Allow user-mode access to the ISRAM heap */ - size = CONFIG_SAMA5_EBICS0_SIZE; sam_uheap((uintptr_t)SAM_EBICS0_VSECTION, size); #endif @@ -309,10 +312,11 @@ void up_addregion(void) #ifdef SAMA5_EBICS1_HEAP if (nregions > 0) { + size = SAMA5_EBICS1_SIZE; + #if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP) /* Allow user-mode access to the ISRAM heap */ - size = CONFIG_SAMA5_EBICS1_SIZE; sam_uheap((uintptr_t)SAM_EBICS1_VSECTION, size); #endif @@ -333,10 +337,11 @@ void up_addregion(void) #ifdef SAMA5_EBICS2_HEAP if (nregions > 0) { + size = SAMA5_EBICS2_SIZE; + #if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP) /* Allow user-mode access to the ISRAM heap */ - size = CONFIG_SAMA5_EBICS2_SIZE; sam_uheap((uintptr_t)SAM_EBICS2_VSECTION, size); #endif @@ -357,10 +362,11 @@ void up_addregion(void) #ifdef SAMA5_EBICS3_HEAP if (nregions > 0) { + size = SAMA5_EBICS3_SIZE; + #if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP) /* Allow user-mode access to the ISRAM heap */ - size = CONFIG_SAMA5_EBICS3_SIZE; sam_uheap((uintptr_t)SAM_EBICS3_VSECTION, size); #endif diff --git a/nuttx/arch/arm/src/sama5/sam_boot.c b/nuttx/arch/arm/src/sama5/sam_boot.c index 995ee376b..075e79593 100644 --- a/nuttx/arch/arm/src/sama5/sam_boot.c +++ b/nuttx/arch/arm/src/sama5/sam_boot.c @@ -51,7 +51,6 @@ #include "chip.h" #include "arm.h" #include "mmu.h" -#include "cache.h" #include "fpu.h" #include "up_internal.h" #include "up_arch.h" @@ -89,14 +88,6 @@ * Private Types ****************************************************************************/ -struct section_mapping_s -{ - uint32_t physbase; /* Physical address of the region to be mapped */ - uint32_t virtbase; /* Virtual address of the region to be mapped */ - uint32_t mmuflags; /* MMU settings for the region (e.g., cache-able) */ - uint32_t nsections; /* Number of mappings in the region */ -}; - /**************************************************************************** * Public Variables ****************************************************************************/ @@ -142,140 +133,128 @@ static const struct section_mapping_s section_mapping[] = */ #if defined(CONFIG_ARCH_LOWVECTORS) && !defined(CONFIG_SAMA5_BOOT_ISRAM) - { CONFIG_FLASH_VSTART, 0x00000000, MMU_ROMFLAGS, 1}, + { CONFIG_FLASH_VSTART, 0x00000000, + MMU_ROMFLAGS, 1 }, #else - { SAM_BOOTMEM_PSECTION, SAM_BOOTMEM_VSECTION, - SAM_BOOTMEM_MMUFLAGS, SAM_BOOTMEM_NSECTIONS}, + { SAM_BOOTMEM_PSECTION, SAM_BOOTMEM_VSECTION, + SAM_BOOTMEM_MMUFLAGS, SAM_BOOTMEM_NSECTIONS }, #endif - { SAM_ROM_PSECTION, SAM_ROM_VSECTION, - SAM_ROM_MMUFLAGS, SAM_ROM_NSECTIONS}, - { SAM_NFCSRAM_PSECTION, SAM_NFCSRAM_VSECTION, - SAM_NFCSRAM_MMUFLAGS, SAM_NFCSRAM_NSECTIONS}, + { SAM_ROM_PSECTION, SAM_ROM_VSECTION, + SAM_ROM_MMUFLAGS, SAM_ROM_NSECTIONS }, + { SAM_NFCSRAM_PSECTION, SAM_NFCSRAM_VSECTION, + SAM_NFCSRAM_MMUFLAGS, SAM_NFCSRAM_NSECTIONS }, #ifndef CONFIG_PAGING /* Internal SRAM is already fully mapped */ - { SAM_ISRAM_PSECTION, SAM_ISRAM_VSECTION, - SAM_ISRAM_MMUFLAGS, SAM_ISRAM_NSECTIONS}, + { SAM_ISRAM_PSECTION, SAM_ISRAM_VSECTION, + SAM_ISRAM_MMUFLAGS, SAM_ISRAM_NSECTIONS }, #endif - { SAM_SMD_PSECTION, SAM_SMD_VSECTION, - SAM_SMD_MMUFLAGS, SAM_SMD_NSECTIONS}, + { SAM_SMD_PSECTION, SAM_SMD_VSECTION, + SAM_SMD_MMUFLAGS, SAM_SMD_NSECTIONS }, { SAM_UDPHSRAM_PSECTION, SAM_UDPHSRAM_VSECTION, - SAM_UDPHSRAM_MMUFLAGS, SAM_UDPHSRAM_NSECTIONS}, - { SAM_UHPOHCI_PSECTION, SAM_UHPOHCI_VSECTION, - SAM_UHPOHCI_MMUFLAGS, SAM_UHPOHCI_NSECTIONS}, - { SAM_UHPEHCI_PSECTION, SAM_UHPEHCI_VSECTION, - SAM_UHPEHCI_MMUFLAGS, SAM_UHPEHCI_NSECTIONS}, - { SAM_AXIMX_PSECTION, SAM_AXIMX_VSECTION, - SAM_AXIMX_MMUFLAGS, SAM_AXIMX_NSECTIONS}, - { SAM_DAP_PSECTION, SAM_DAP_VSECTION, - SAM_DAP_MMUFLAGS, SAM_DAP_NSECTIONS}, - -/* SAMA5 External Memories */ + SAM_UDPHSRAM_MMUFLAGS, SAM_UDPHSRAM_NSECTIONS }, + { SAM_UHPOHCI_PSECTION, SAM_UHPOHCI_VSECTION, + SAM_UHPOHCI_MMUFLAGS, SAM_UHPOHCI_NSECTIONS }, + { SAM_UHPEHCI_PSECTION, SAM_UHPEHCI_VSECTION, + SAM_UHPEHCI_MMUFLAGS, SAM_UHPEHCI_NSECTIONS }, + { SAM_AXIMX_PSECTION, SAM_AXIMX_VSECTION, + SAM_AXIMX_MMUFLAGS, SAM_AXIMX_NSECTIONS }, + { SAM_DAP_PSECTION, SAM_DAP_VSECTION, + SAM_DAP_MMUFLAGS, SAM_DAP_NSECTIONS }, + +/* SAMA5 CS0 External Memories */ #ifdef CONFIG_SAMA5_EBICS0 { SAM_EBICS0_PSECTION, SAM_EBICS0_VSECTION, - SAM_EBICS0_MMUFLAGS, SAM_EBICS0_NSECTIONS}, + SAM_EBICS0_MMUFLAGS, SAM_EBICS0_NSECTIONS }, #endif + +/* SAMA5 External SDRAM Memory. The SDRAM is not usable until it has been + * initialized. If we are running out of SDRAM now, we can assume that some + * second level boot loader has properly configured SRAM for us. In that + * case, we set the the MMU flags for the final, fully cache-able state. + * + * If we are running from ISRAM or NOR flash, then we will need to configure + * the SDRAM ourselves. In this case, we set the MMU flags to the strongly + * ordered, non-cacheable state. We need this direct access to SDRAM in + * order to configure it. Once SDRAM has been initialized, it will be re- + * configured in its final state. + */ + #ifdef CONFIG_SAMA5_DDRCS - { SAM_DDRCS_PSECTION, SAM_DDRCS_VSECTION, - SAM_DDRCS_MMUFLAGS, SAM_DDRCS_NSECTIONS}, +#ifdef CONFIG_SAMA5_BOOT_SDRAM + { SAM_DDRCS_PSECTION, SAM_DDRCS_VSECTION, + MMU_STRONGLY_ORDERED, SAM_DDRCS_NSECTIONS }, +#else + { SAM_DDRCS_PSECTION, SAM_DDRCS_VSECTION, + SAM_DDRCS_MMUFLAGS, SAM_DDRCS_NSECTIONS }, +#endif #endif + +/* SAMA5 CS1-3 External Memories */ + #ifdef CONFIG_SAMA5_EBICS1 - { SAM_EBICS1_PSECTION, SAM_EBICS1_VSECTION, - SAM_EBICS1_MMUFLAGS, SAM_EBICS1_NSECTIONS}, + { SAM_EBICS1_PSECTION, SAM_EBICS1_VSECTION, + SAM_EBICS1_MMUFLAGS, SAM_EBICS1_NSECTIONS }, #endif #ifdef CONFIG_SAMA5_EBICS2 - { SAM_EBICS2_PSECTION, SAM_EBICS2_VSECTION, - SAM_EBICS2_MMUFLAGS, SAM_EBICS2_NSECTIONS}, + { SAM_EBICS2_PSECTION, SAM_EBICS2_VSECTION, + SAM_EBICS2_MMUFLAGS, SAM_EBICS2_NSECTIONS }, #endif #ifdef CONFIG_SAMA5_EBICS3 - { SAM_EBICS3_PSECTION, SAM_EBICS3_VSECTION, - SAM_EBICS3_MMUFLAGS, SAM_EBICS3_NSECTIONS}, + { SAM_EBICS3_PSECTION, SAM_EBICS3_VSECTION, + SAM_EBICS3_MMUFLAGS, SAM_EBICS3_NSECTIONS }, #endif #ifdef CONFIG_SAMA5_NFCCR - { SAM_NFCCR_PSECTION, SAM_NFCCR_VSECTION, - SAM_NFCCR_MMUFLAGS, SAM_NFCCR_NSECTIONS}, + { SAM_NFCCR_PSECTION, SAM_NFCCR_VSECTION, + SAM_NFCCR_MMUFLAGS, SAM_NFCCR_NSECTIONS }, #endif /* SAMA5 Internal Peripherals */ { SAM_PERIPHA_PSECTION, SAM_PERIPHA_VSECTION, - SAM_PERIPHA_MMUFLAGS, SAM_PERIPHA_NSECTIONS}, + SAM_PERIPHA_MMUFLAGS, SAM_PERIPHA_NSECTIONS }, { SAM_PERIPHB_PSECTION, SAM_PERIPHB_VSECTION, - SAM_PERIPHB_MMUFLAGS, SAM_PERIPHB_NSECTIONS}, - { SAM_SYSC_PSECTION, SAM_SYSC_VSECTION, - SAM_SYSC_MMUFLAGS, SAM_SYSC_NSECTIONS}, + SAM_PERIPHB_MMUFLAGS, SAM_PERIPHB_NSECTIONS }, + { SAM_SYSC_PSECTION, SAM_SYSC_VSECTION, + SAM_SYSC_MMUFLAGS, SAM_SYSC_NSECTIONS }, }; #define NMAPPINGS (sizeof(section_mapping) / sizeof(struct section_mapping_s)) #endif -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: sam_setl1entry - * - * Description: - * Set a level 1 translation table entry. - * - ****************************************************************************/ +/* SAMA5 External SDRAM Memory. Final configuration. The SDRAM was + * configured in a temporary state to support low-level ininitialization. + * After the SDRAM has been fully initialized, this structure is used to + * set the SDRM in its final, fully cache-able state. + */ -#ifndef CONFIG_ARCH_ROMPGTABLE -static inline void sam_setl1entry(uint32_t paddr, uint32_t vaddr, - uint32_t mmuflags) +#if defined(CONFIG_SAMA5_DDRCS) && !defined(CONFIG_SAMA5_BOOT_SDRAM) +static const struct section_mapping_s operational_mapping = { - uint32_t *pgtable = (uint32_t*)PGTABLE_BASE_VADDR; - uint32_t index = vaddr >> 20; - - /* Save the page table entry */ - - pgtable[index] = (paddr | mmuflags); -} + SAM_DDRCS_PSECTION, SAM_DDRCS_VSECTION, + SAM_DDRCS_MMUFLAGS, SAM_DDRCS_NSECTIONS +}; #endif /**************************************************************************** - * Name: sam_setl2smallentry + * Private Functions ****************************************************************************/ -static inline void sam_setl2smallentry(uint32_t ctabvaddr, uint32_t paddr, - uint32_t vaddr, uint32_t mmuflags) -{ - uint32_t *ctable = (uint32_t*)ctabvaddr; - uint32_t index; - - /* The table divides a 1Mb address space up into 256 entries, each - * corresponding to 4Kb of address space. The page table index is - * related to the offset from the beginning of 1Mb region. - */ - - index = (vaddr & 0x000ff000) >> 12; - - /* Save the table entry */ - - ctable[index] = (paddr | mmuflags); -} - /**************************************************************************** * Name: sam_setupmappings + * + * Description + * Map all of the memory regions defined in section_mapping[] + * ****************************************************************************/ #ifndef CONFIG_ARCH_ROMPGTABLE -static void sam_setupmappings(void) +static inline void sam_setupmappings(void) { - int i, j; + int i; for (i = 0; i < NMAPPINGS; i++) { - uint32_t sect_paddr = section_mapping[i].physbase; - uint32_t sect_vaddr = section_mapping[i].virtbase; - uint32_t mmuflags = section_mapping[i].mmuflags; - - for (j = 0; j < section_mapping[i].nsections; j++) - { - sam_setl1entry(sect_paddr, sect_vaddr, mmuflags); - sect_paddr += SECTION_SIZE; - sect_vaddr += SECTION_SIZE; - } + mmu_l2_map_region(§ion_mapping[i]); } } #endif @@ -290,16 +269,17 @@ static void sam_setupmappings(void) #if !defined(CONFIG_ARCH_ROMPGTABLE) && defined(CONFIG_ARCH_LOWVECTORS) && \ defined(CONFIG_PAGING) -static void sam_vectorpermissions(uint32_t mmuflags) +static void sam_vectorpermissions(uint32_t mmuflags) { /* The PTE for the beginning of ISRAM is at the base of the L2 page table */ - uint32_t *ptr = (uint32_t*)PG_L2_VECT_VADDR; - uint32_t pte; + uint32_t pte = mmu_l2_getentry(PG_L2_VECT_VADDR, 0); - /* The pte might be zero the first time this function is called. */ + /* String the MMU flags from the page table entry. + * + * The pte might be zero the first time this function is called. + */ - pte = *ptr; if (pte == 0) { pte = PG_VECT_PBASE; @@ -309,13 +289,9 @@ static void sam_vectorpermissions(uint32_t mmuflags) pte &= PG_L1_PADDRMASK; } - /* Update the MMU flags and save */ - - *ptr = pte | mmuflags; - - /* Invalid the TLB for this address */ + /* Update the page table entry with the MMU flags and save */ - tlb_invalidate_single(PG_L2_VECT_VADDR); + mmu_l2_setentry(PG_L2_VECT_VADDR, pte, 0, mmuflags); } #endif @@ -352,17 +328,17 @@ static void sam_vectormapping(void) while (vector_paddr < end_paddr) { - sam_setl2smallentry(VECTOR_L2_VBASE, vector_paddr, vector_vaddr, - MMU_L2_VECTORFLAGS); + mmu_l2_setentry(VECTOR_L2_VBASE, vector_paddr, vector_vaddr, + MMU_L2_VECTORFLAGS); vector_paddr += 4096; vector_vaddr += 4096; } /* Now set the level 1 descriptor to refer to the level 2 page table. */ - sam_setl1entry(VECTOR_L2_PBASE & PMD_PTE_PADDR_MASK, - SAM_VECTOR_VADDR & PMD_PTE_PADDR_MASK, - MMU_L1_VECTORFLAGS); + mmu_l1_setentry(VECTOR_L2_PBASE & PMD_PTE_PADDR_MASK, + SAM_VECTOR_VADDR & PMD_PTE_PADDR_MASK, + MMU_L1_VECTORFLAGS); } #else /* No vector remap */ @@ -527,13 +503,6 @@ void up_boot(void) sam_vectormapping(); - /* The SRAM address hold the the page table is probably buffered. Make sure - * that the modified contents of the page table are flushed into physical - * memory. - */ - - cp15_clean_dcache(PGTABLE_BASE_VADDR, PGTABLE_BASE_VADDR + PGTABLE_SIZE); - #endif /* CONFIG_ARCH_ROMPGTABLE */ /* Setup up vector block. _vector_start and _vector_end are exported from @@ -578,7 +547,20 @@ void up_boot(void) sam_userspace(); #endif - /* Perform board-specific initialization */ + /* Perform board-specific initialization, This must include: + * + * - Initialization of board-specific memory resources (e.g., SDRAM) + * - Configuration of board specific resources (GPIOs, LEDs, etc). + */ sam_boardinitialize(); + + /* SDRAM was configured in a temporary state to support low-level + * ininitialization. Now that the SDRAM has been fully initialized, + * we can reconfigure the SDRAM in its final, fully cache-able state. + */ + +#if defined(CONFIG_SAMA5_DDRCS) && !defined(CONFIG_SAMA5_BOOT_SDRAM) + mmu_l2_map_region(&operational_mapping); +#endif } diff --git a/nuttx/configs/sama5d3x-ek/Kconfig b/nuttx/configs/sama5d3x-ek/Kconfig index 5f977fe16..301b272e1 100644 --- a/nuttx/configs/sama5d3x-ek/Kconfig +++ b/nuttx/configs/sama5d3x-ek/Kconfig @@ -5,6 +5,23 @@ if ARCH_BOARD_SAMA5D3X_EK +choice + prompt "SAMA5D3x-EK DRAM Type" + default SAMA5_MT47H128M16RT + depends on SAMA5_DDRCS + +config SAMA5_MT47H128M16RT + bool "MT47H128M16RT" + ---help--- + Micron 2Gbit x16 DDR2-1066 128Mb + +config SAMA5_MT47H64M16HR + bool "MT47H64M16HR" + ---help--- + Micron 1Gbit x16 DDR2-800 64Mb + +endchoice + config SAMA5_NOR_MAIN bool "Build nor_main" default n diff --git a/nuttx/configs/sama5d3x-ek/hello/defconfig b/nuttx/configs/sama5d3x-ek/hello/defconfig index b047352fa..2166fc65f 100644 --- a/nuttx/configs/sama5d3x-ek/hello/defconfig +++ b/nuttx/configs/sama5d3x-ek/hello/defconfig @@ -167,11 +167,6 @@ CONFIG_SAMA5_USART1=y # # External Memory Configuration # -# CONFIG_SAMA5_DDRCS is not set -# CONFIG_SAMA5_EBICS0 is not set -# CONFIG_SAMA5_EBICS1 is not set -# CONFIG_SAMA5_EBICS2 is not set -# CONFIG_SAMA5_EBICS3 is not set CONFIG_SAMA5_BOOT_ISRAM=y # @@ -199,9 +194,6 @@ CONFIG_ARCH_STACKDUMP=y # CONFIG_BOARD_LOOPSPERMSEC=49341 # CONFIG_ARCH_CALIBRATION is not set -CONFIG_RAM_START=0x00300000 -CONFIG_RAM_VSTART=0x00300000 -CONFIG_RAM_SIZE=114688 CONFIG_ARCH_HAVE_INTERRUPTSTACK=y CONFIG_ARCH_INTERRUPTSTACK=0 @@ -214,6 +206,13 @@ CONFIG_BOOT_RUNFROMISRAM=y # CONFIG_BOOT_RUNFROMSDRAM is not set # CONFIG_BOOT_COPYTORAM is not set +# +# Boot Memory Configuration +# +CONFIG_RAM_START=0x00300000 +CONFIG_RAM_VSTART=0x00300000 +CONFIG_RAM_SIZE=114688 + # # Board Selection # @@ -233,6 +232,7 @@ CONFIG_ARCH_HAVE_IRQBUTTONS=y # # Board-Specific Options # +# CONFIG_SAMA5_NOR_MAIN is not set # # RTOS Features diff --git a/nuttx/configs/sama5d3x-ek/norboot/defconfig b/nuttx/configs/sama5d3x-ek/norboot/defconfig index 92cb7bbc0..1537ef783 100644 --- a/nuttx/configs/sama5d3x-ek/norboot/defconfig +++ b/nuttx/configs/sama5d3x-ek/norboot/defconfig @@ -123,7 +123,7 @@ CONFIG_ARCH_CHIP_ATSAMA5D33=y # CONFIG_SAMA5_DBGU is not set # CONFIG_SAMA5_PIT is not set # CONFIG_SAMA5_WDT is not set -# CONFIG_SAMA5_HSMC is not set +CONFIG_SAMA5_HSMC=y # CONFIG_SAMA5_SMD is not set # CONFIG_SAMA5_UART0 is not set # CONFIG_SAMA5_UART1 is not set diff --git a/nuttx/configs/sama5d3x-ek/nsh/defconfig b/nuttx/configs/sama5d3x-ek/nsh/defconfig index adeca9925..0d76d8d4a 100644 --- a/nuttx/configs/sama5d3x-ek/nsh/defconfig +++ b/nuttx/configs/sama5d3x-ek/nsh/defconfig @@ -123,7 +123,7 @@ CONFIG_ARCH_CHIP_ATSAMA5D33=y # CONFIG_SAMA5_DBGU is not set # CONFIG_SAMA5_PIT is not set # CONFIG_SAMA5_WDT is not set -# CONFIG_SAMA5_HSMC is not set +CONFIG_SAMA5_HSMC=y # CONFIG_SAMA5_SMD is not set # CONFIG_SAMA5_UART0 is not set # CONFIG_SAMA5_UART1 is not set diff --git a/nuttx/configs/sama5d3x-ek/ostest/defconfig b/nuttx/configs/sama5d3x-ek/ostest/defconfig index 8262ee7dd..30a80cb09 100644 --- a/nuttx/configs/sama5d3x-ek/ostest/defconfig +++ b/nuttx/configs/sama5d3x-ek/ostest/defconfig @@ -123,7 +123,7 @@ CONFIG_ARCH_CHIP_ATSAMA5D33=y # CONFIG_SAMA5_DBGU is not set # CONFIG_SAMA5_PIT is not set # CONFIG_SAMA5_WDT is not set -# CONFIG_SAMA5_HSMC is not set +CONFIG_SAMA5_HSMC=y # CONFIG_SAMA5_SMD is not set # CONFIG_SAMA5_UART0 is not set # CONFIG_SAMA5_UART1 is not set diff --git a/nuttx/configs/sama5d3x-ek/src/sam_boot.c b/nuttx/configs/sama5d3x-ek/src/sam_boot.c index fd21a6564..f68cae4b4 100644 --- a/nuttx/configs/sama5d3x-ek/src/sam_boot.c +++ b/nuttx/configs/sama5d3x-ek/src/sam_boot.c @@ -67,6 +67,18 @@ void sam_boardinitialize(void) { +#if defined(CONFIG_SAMA5_DDRCS) && !defined(CONFIG_SAMA5_BOOT_SDRAM) + + /* Configure SDRAM if (1) SDRAM has been enalbled in the NuttX configuration and + * (2) if we are not currently running out of SDRAM. If we are now running out + * of SDRAM then we have to assume that some second level bootloader has properly + * configured SDRAM for our use. + */ + + sam_sdram_config(); + +#endif + #ifdef CONFIG_ARCH_LEDS /* Configure on-board LEDs if LED support has been selected. */ diff --git a/nuttx/configs/sama5d3x-ek/src/sam_sdram.c b/nuttx/configs/sama5d3x-ek/src/sam_sdram.c index 71b9748dd..ce1fa1e04 100644 --- a/nuttx/configs/sama5d3x-ek/src/sam_sdram.c +++ b/nuttx/configs/sama5d3x-ek/src/sam_sdram.c @@ -51,36 +51,50 @@ #include "up_arch.h" #include "sam_periphclks.h" -#incldue "chip/sam_memorymap.h" +#include "chip/sam_memorymap.h" #include "chip/sam_pmc.h" #include "chip/sam_sfr.h" +#include "chip/sam_mpddrc.h" #include "sama5d3x-ek.h" /* This file requires: * * CONFIG_SAMA5_DDRCS -- DRAM support is enabled, and - * !CONFIG_SAMA5_BOOT_SDRAM - We did not boot into SRAM, and - * !CONFIG_BOOT_RUNFROMSDRAM - We are not running from SDRAM. + * !CONFIG_SAMA5_BOOT_SDRAM - We did not boot into SRAM. */ -#if defined(CONFIG_SAMA5_DDRCS) && !defined(CONFIG_SAMA5_BOOT_SDRAM) && \ - !defined(CONFIG_BOOT_RUNFROMSDRAM) +#if defined(CONFIG_SAMA5_DDRCS) && !defined(CONFIG_SAMA5_BOOT_SDRAM) /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ -/* Used for SDRAM command handshaking */ +/* SDRAM differences */ -#define DDR2_BA0(r) (1 << (25 + r)) -#define DDR2_BA1(r) (1 << (26 + r)) +#if defined(CONFIG_SAMA5_MT47H128M16RT) + + /* Used for SDRAM command handshaking */ + +# define DDR2_BA0 (1 << 26) +# define DDR2_BA1 (1 << 27) + +#elif defined(CONFIG_SAMA5_MT47H64M16HR) + + /* Used for SDRAM command handshaking */ + +# define DDR2_BA0 (1 << 25) +# define DDR2_BA1 (1 << 26) + +#else +# error Unknwon SDRAM type +#endif /**************************************************************************** * Private Functions ****************************************************************************/ /**************************************************************************** - * Name: board_sdram_delay + * Name: sam_sdram_delay * * Description: * Precision delay function for SDRAM configuration. @@ -90,7 +104,7 @@ * ****************************************************************************/ -static inline board_sdram_delay(unsigned int loops) +static inline void sam_sdram_delay(unsigned int loops) { volatile unsigned int i; @@ -105,7 +119,7 @@ static inline board_sdram_delay(unsigned int loops) ************************************************************************************/ /************************************************************************************ - * Name: board_sdram_config + * Name: sam_sdram_config * * Description: * Configures DDR2 (MT47H128M16RT 128MB/ MT47H64M16HR) @@ -128,7 +142,7 @@ static inline board_sdram_delay(unsigned int loops) * ************************************************************************************/ -void board_sdram_config(uint8_t sdramtype) +void sam_sdram_config(void) { volatile uint8_t *ddr = (uint8_t *)SAM_DDRCS_VSECTION; uint32_t regval; @@ -180,7 +194,7 @@ void board_sdram_config(uint8_t sdramtype) regval = getreg32(SAM_MPDDRC_IO_CALIBR); regval &= ~(MPDDRC_IO_CALIBR_RDIV_MASK | MPDDRC_IO_CALIBR_TZQIO_MASK); regval |= (MPDDRC_IO_CALIBR_RZQ48_40 | MPDDRC_IO_CALIBR_TZQIO(3)); - putreg(regval, SAM_MPDDRC_IO_CALIBR); + putreg32(regval, SAM_MPDDRC_IO_CALIBR); /* Force DDR_DQ and DDR_DQS input buffer always on, clearing other bits * (undocumented) @@ -198,8 +212,11 @@ void board_sdram_config(uint8_t sdramtype) /* Step 2: Program the features of DDR2-SDRAM device into the Timing * Register - * - * For DDRAM_MT47H128M16RT + */ + +#if defined(CONFIG_SAMA5_MT47H128M16RT) + + /* For MT47H128M16RT * * NC = 10 DDR column bits * NR = 14 DDR row bits @@ -217,19 +234,16 @@ void board_sdram_config(uint8_t sdramtype) * UNAL = Unaliged access supported */ - if (sdramtype == DDRAM_MT47H128M16RT) - { - regval = MPDDRC_CR_NC_10 | /* Number of Column Bits */ - MPDDRC_CR_NR_14 | /* Number of Row Bits */ - MPDDRC_CR_CAS_4 | /* CAS Latency */ - MPDDRC_CR_OCD_EXIT | /* Off-chip Driver */ - MPDDRC_CR_8BANKS | /* Number of Banks */ - MPDDRC_CR_NDQS | /* Not DQS */ - MPDDRC_CR_UNAL; /* upport Unaligned Access */ - putreg32(regval, SAM_MPDDRC_CR); - } + regval = MPDDRC_CR_NC_10 | /* Number of Column Bits */ + MPDDRC_CR_NR_14 | /* Number of Row Bits */ + MPDDRC_CR_CAS_4 | /* CAS Latency */ + MPDDRC_CR_OCD_EXIT | /* Off-chip Driver */ + MPDDRC_CR_8BANKS | /* Number of Banks */ + MPDDRC_CR_NDQS | /* Not DQS */ + MPDDRC_CR_UNAL; /* upport Unaligned Access */ - /* For DDRAM_MT47H128M16RT +#elif defined(CONFIG_SAMA5_MT47H64M16HR) + /* For MT47H64M16HR * * NC = 10 DDR column bits * NR = 13 DDR row bits @@ -247,17 +261,19 @@ void board_sdram_config(uint8_t sdramtype) * UNAL = Unaliged access supported */ - else if (sdramtype == DDRAM_MT47H64M16HR) - { - regval = MPDDRC_CR_NC_10 | /* Number of Column Bits */ - MPDDRC_CR_NR_13 | /* Number of Row Bits */ - MPDDRC_CR_CAS_3 | /* CAS Latency */ - MPDDRC_CR_OCD_EXIT | /* Off-chip Driver */ - MPDDRC_CR_8BANKS | /* Number of Banks */ - MPDDRC_CR_NDQS | /* Not DQS */ - MPDDRC_CR_UNAL; /* upport Unaligned Access */ - putreg32(regval, SAM_MPDDRC_CR); - } + regval = MPDDRC_CR_NC_10 | /* Number of Column Bits */ + MPDDRC_CR_NR_13 | /* Number of Row Bits */ + MPDDRC_CR_CAS_3 | /* CAS Latency */ + MPDDRC_CR_OCD_EXIT | /* Off-chip Driver */ + MPDDRC_CR_8BANKS | /* Number of Banks */ + MPDDRC_CR_NDQS | /* Not DQS */ + MPDDRC_CR_UNAL; /* upport Unaligned Access */ + +#else +# error Unknwon SDRAM type +#endif + + putreg32(regval, SAM_MPDDRC_CR); /* Configure the Timing Parameter 0 Register */ @@ -301,7 +317,7 @@ void board_sdram_config(uint8_t sdramtype) /* DDRSDRC Low-power Register */ - board_sdram_delay(13200); + sam_sdram_delay(13200); regval = MPDDRC_LPR_LPCB_DISABLED | /* Low-power Feature is inhibited */ MPDDRC_LPR_TIMEOUT_0CLKS | /* Activates low-power mode after the end of transfer */ @@ -333,7 +349,7 @@ void board_sdram_config(uint8_t sdramtype) /* Now CKE is driven high.*/ /* Wait 400 ns min */ - board_sdram_delay(100); + sam_sdram_delay(100); /* Step 5: An all banks precharge command is issued to the DDR2-SDRAM. */ @@ -345,7 +361,7 @@ void board_sdram_config(uint8_t sdramtype) /* Wait 400 ns min */ - board_sdram_delay(100); + sam_sdram_delay(100); /* Step 6: An Extended Mode Register set (EMRS2) cycle is issued to chose * between commercialor high temperature operations. @@ -355,11 +371,11 @@ void board_sdram_config(uint8_t sdramtype) */ putreg32(MPDDRC_MR_MODE_EXTLMR, SAM_MPDDRC_MR); - *((uint8_t *)(ddr + DDR2_BA1(sdramtype))) = 0; + *((uint8_t *)(ddr + DDR2_BA1)) = 0; /* Wait 2 cycles min */ - board_sdram_delay(100); + sam_sdram_delay(100); /* Step 7: An Extended Mode Register set (EMRS3) cycle is issued to set * all registers to 0. @@ -369,11 +385,11 @@ void board_sdram_config(uint8_t sdramtype) */ putreg32(MPDDRC_MR_MODE_EXTLMR, SAM_MPDDRC_MR); - *((uint8_t *)(ddr + DDR2_BA1(sdramtype) + DDR2_BA0(sdramtype))) = 0; + *((uint8_t *)(ddr + DDR2_BA1 + DDR2_BA0)) = 0; /* Wait 2 cycles min */ - board_sdram_delay(100); + sam_sdram_delay(100); /* Step 8: An Extended Mode Register set (EMRS1) cycle is issued to enable DLL. * @@ -381,11 +397,11 @@ void board_sdram_config(uint8_t sdramtype) */ putreg32(MPDDRC_MR_MODE_EXTLMR, SAM_MPDDRC_MR); - *((uint8_t *)(ddr + DDR2_BA0(sdramtype))) = 0; + *((uint8_t *)(ddr + DDR2_BA0)) = 0; /* An additional 200 cycles of clock are required for locking DLL */ - board_sdram_delay(10000); + sam_sdram_delay(10000); /* Step 9: Program DLL field into the Configuration Register.*/ @@ -403,11 +419,12 @@ void board_sdram_config(uint8_t sdramtype) /* Wait 2 cycles min */ - board_sdram_delay(100); + sam_sdram_delay(100); /* Step 11: An all banks precharge command is issued to the DDR2-SDRAM. * - * Perform a write access to any DDR2-SDRAM address to acknowledge this command */ + * Perform a write access to any DDR2-SDRAM address to acknowledge this + * command */ putreg32(MPDDRC_MR_MODE_PRCGALL, SAM_MPDDRC_MR); @@ -415,7 +432,7 @@ void board_sdram_config(uint8_t sdramtype) /* Wait 2 cycles min */ - board_sdram_delay(100); + sam_sdram_delay(100); /* Step 12: Two auto-refresh (CBR) cycles are provided. Program the auto * refresh command (CBR) into the Mode Register. @@ -429,7 +446,7 @@ void board_sdram_config(uint8_t sdramtype) /* Wait 2 cycles min */ - board_sdram_delay(100); + sam_sdram_delay(100); /* Configure 2nd CBR. * @@ -441,7 +458,7 @@ void board_sdram_config(uint8_t sdramtype) /* Wait 2 cycles min */ - board_sdram_delay(100); + sam_sdram_delay(100); /* Step 13: Program DLL field into the Configuration Register to low * (Disable DLL reset). @@ -462,14 +479,14 @@ void board_sdram_config(uint8_t sdramtype) /* Wait 2 cycles min */ - board_sdram_delay(100); + sam_sdram_delay(100); /* Step 15: Program OCD field into the Configuration Register to high (OCD * calibration default). */ regval = getreg32(SAM_MPDDRC_CR); - retval |= MPDDRC_CR_OCD_DEFAULT; + regval |= MPDDRC_CR_OCD_DEFAULT; putreg32(regval, SAM_MPDDRC_CR); /* Step 16: An Extended Mode Register set (EMRS1) cycle is issued to OCD @@ -480,11 +497,11 @@ void board_sdram_config(uint8_t sdramtype) */ putreg32(MPDDRC_MR_MODE_EXTLMR, SAM_MPDDRC_MR); - *((uint8_t *)(ddr + DDR2_BA0(sdramtype))) = 0; + *((uint8_t *)(ddr + DDR2_BA0)) = 0; /* Wait 2 cycles min */ - board_sdram_delay(100); + sam_sdram_delay(100); /* Step 17: Program OCD field into the Configuration Register to low (OCD * calibration mode exit). @@ -504,11 +521,11 @@ void board_sdram_config(uint8_t sdramtype) */ putreg32(MPDDRC_MR_MODE_EXTLMR, SAM_MPDDRC_MR); - *((uint8_t *)(ddr + DDR2_BA0(sdramtype))) = 0; + *((uint8_t *)(ddr + DDR2_BA0)) = 0; /* Wait 2 cycles min */ - board_sdram_delay(100); + sam_sdram_delay(100); /* Step 19,20: A mode Normal command is provided. Program the Normal mode * into Mode Register. @@ -540,9 +557,7 @@ void board_sdram_config(uint8_t sdramtype) /* OK now we are ready to work on the DDRSDR */ /* Wait for end of calibration */ - board_sdram_delay(500); -#warning Make SDRAM cacheable + sam_sdram_delay(500); } -#endif /* CONFIG_SAMA5_DDRCS && !CONFIG_SAMA5_BOOT_SDRAM && !CONFIG_BOOT_RUNFROMSDRAM */ -#endif /* CONFIG_SAMA5_BOOT_CS0FLASH */ +#endif /* CONFIG_SAMA5_DDRCS && !CONFIG_SAMA5_BOOT_SDRAM */ diff --git a/nuttx/configs/sama5d3x-ek/src/sama5d3x-ek.h b/nuttx/configs/sama5d3x-ek/src/sama5d3x-ek.h index 2b2a0d7fb..757863c18 100644 --- a/nuttx/configs/sama5d3x-ek/src/sama5d3x-ek.h +++ b/nuttx/configs/sama5d3x-ek/src/sama5d3x-ek.h @@ -112,7 +112,7 @@ * Name: board_sdram_config * * Description: - * Configures DDR2 (MT47H128M16RT 128MB/ MT47H64M16HR) + * Configures DDR2 (MT47H128M16RT 128MB / MT47H64M16HR) * * MT47H64M16HR : 8 Meg x 16 x 8 banks * Refresh count: 8K @@ -132,9 +132,8 @@ * ************************************************************************************/ -#if defined(CONFIG_SAMA5_DDRCS) && !defined(CONFIG_SAMA5_BOOT_SDRAM) && \ - !defined(CONFIG_BOOT_RUNFROMSDRAM) -void board_sdram_config(uint8_t sdramtype); +#if defined(CONFIG_SAMA5_DDRCS) && !defined(CONFIG_SAMA5_BOOT_SDRAM) +void sam_sdram_config(void); #else # define board_sdram_config(t) #endif -- cgit v1.2.3