Hi Albert, On Fri, Feb 10, 2012 at 12:38 PM, Albert ARIBAUD <albert.u.b...@aribaud.net> wrote: > Hi Simon, > > Le 15/01/2012 01:47, Simon Glass a écrit : > >> Add support for adjusting the cachability of an L1 section by updating >> the MMU. The mmu_set_region_dcache() function allows drivers to make >> these changes after the MMU is set up. >> >> It is implemented only for ARMv7 at present. >> >> This is needed for LCD support, where we want to make the LCD frame buffer >> write-through (or off) rather than write-back. >> >> Signed-off-by: Simon Glass<s...@chromium.org> >> --- >> arch/arm/cpu/armv7/cache_v7.c | 11 +++++++ >> arch/arm/include/asm/system.h | 30 ++++++++++++++++++++ >> arch/arm/lib/cache-cp15.c | 62 >> +++++++++++++++++++++++++++++++++------- >> 3 files changed, 92 insertions(+), 11 deletions(-) >> >> diff --git a/arch/arm/cpu/armv7/cache_v7.c b/arch/arm/cpu/armv7/cache_v7.c >> index 1b4e808..5f6d039 100644 >> --- a/arch/arm/cpu/armv7/cache_v7.c >> +++ b/arch/arm/cpu/armv7/cache_v7.c >> @@ -297,6 +297,12 @@ void arm_init_before_mmu(void) >> v7_inval_tlb(); >> } >> >> +void mmu_page_table_flush(unsigned long start, unsigned long stop) >> +{ >> + flush_dcache_range(start, stop); >> + v7_inval_tlb(); > > > If that means "invalidate", then spell it out.
Are you asking for a patch to rename v7_inval_tlb()? That is an existing function - I agree it is a bit cryptic. > >> +} >> + >> /* >> * Flush range from all levels of d-cache/unified-cache used: >> * Affects the range [start, start + size - 1] >> @@ -329,6 +335,11 @@ void arm_init_before_mmu(void) >> void flush_cache(unsigned long start, unsigned long size) >> { >> } >> + >> +void mmu_page_table_flush(unsigned long start, unsigned long stop) >> +{ >> +} >> + >> #endif /* #ifndef CONFIG_SYS_DCACHE_OFF */ >> >> #ifndef CONFIG_SYS_ICACHE_OFF >> diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h >> index 2b28a26..f52a4fc 100644 >> --- a/arch/arm/include/asm/system.h >> +++ b/arch/arm/include/asm/system.h >> @@ -75,6 +75,36 @@ static inline void set_cr(unsigned int val) >> isb(); >> } >> >> +/* options available for data cache on each page */ >> +enum dcache_option { >> + DCACHE_OFF, >> + DCACHE_WRITETHROUGH, >> + DCACHE_WRITEBACK, >> +}; >> + >> +/* Size of an MMU section */ >> +enum { >> + MMU_SECTION_SHIFT = 20, >> + MMU_SECTION_SIZE = 1<< MMU_SECTION_SHIFT, >> +}; >> + >> +/** >> + * Change the cache settings for a region. >> + * >> + * \param start start address of memory region to change >> + * \param size size of memory region to change >> + * \param option dcache option to select >> + */ >> +void mmu_set_region_dcache(u32 start, int size, enum dcache_option >> option); >> + >> +/** >> + * Register an update to the page tables, and flush the TLB >> + * >> + * \param start start address of update in page table >> + * \param stop stop address of update in page table >> + */ >> +void mmu_page_table_flush(unsigned long start, unsigned long stop); >> + >> #endif /* __ASSEMBLY__ */ >> >> #define arch_align_stack(x) (x) >> diff --git a/arch/arm/lib/cache-cp15.c b/arch/arm/lib/cache-cp15.c >> index e6c3eae..facb1a7 100644 >> --- a/arch/arm/lib/cache-cp15.c >> +++ b/arch/arm/lib/cache-cp15.c >> @@ -26,12 +26,6 @@ >> >> #if !(defined(CONFIG_SYS_ICACHE_OFF)&& defined(CONFIG_SYS_DCACHE_OFF)) >> >> >> -#if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH) >> -#define CACHE_SETUP 0x1a >> -#else >> -#define CACHE_SETUP 0x1e >> -#endif >> - >> DECLARE_GLOBAL_DATA_PTR; >> >> void __arm_init_before_mmu(void) >> @@ -50,9 +44,52 @@ static void cp_delay (void) >> asm volatile("" : : : "memory"); >> } >> >> -static inline void dram_bank_mmu_setup(int bank) >> +void set_section_dcache(int section, enum dcache_option option) >> { >> + u32 value = section<< MMU_SECTION_SHIFT | (3<< 10); >> u32 *page_table = (u32 *)gd->tlb_addr; >> + >> + switch (option) { >> + case DCACHE_WRITETHROUGH: >> + value |= 0x1a; >> + break; >> + >> + case DCACHE_WRITEBACK: >> + value |= 0x1e; >> + break; >> + >> + case DCACHE_OFF: >> + value |= 0x12; >> + break; >> + } >> + >> + page_table[section] = value; >> +} >> + >> +void __mmu_page_table_flush(unsigned long start, unsigned long stop) >> +{ >> + debug("%s: Warning: not implemented\n", __func__); >> +} >> + >> +void mmu_page_table_flush(unsigned long start, unsigned long stop) >> + __attribute__((weak, alias("__mmu_page_table_flush"))); >> + >> +void mmu_set_region_dcache(u32 start, int size, enum dcache_option >> option) >> +{ >> + u32 *page_table = (u32 *)gd->tlb_addr; >> + u32 upto, end; >> + >> + end = ALIGN(start + size, MMU_SECTION_SIZE)>> MMU_SECTION_SHIFT; >> + start = start>> MMU_SECTION_SHIFT; >> + debug("mmu_set_region_dcache start=%x, size=%x, option=%d\n", >> + start, size, option); >> + for (upto = start; upto< end; upto++) >> + set_section_dcache(upto, option); >> + mmu_page_table_flush((u32)&page_table[start], >> (u32)&page_table[end]); >> +} >> + >> +static inline void dram_bank_mmu_setup(int bank) >> +{ >> bd_t *bd = gd->bd; >> int i; >> >> @@ -60,21 +97,24 @@ static inline void dram_bank_mmu_setup(int bank) >> for (i = bd->bi_dram[bank].start>> 20; >> i< (bd->bi_dram[bank].start + bd->bi_dram[bank].size)>> 20; >> i++) { >> - page_table[i] = i<< 20 | (3<< 10) | CACHE_SETUP; >> +#if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH) >> + set_section_dcache(i, DCACHE_WRITETHROUGH); >> +#else >> + set_section_dcache(i, DCACHE_WRITEBACK); >> +#endif >> } >> } >> >> /* to activate the MMU we need to set up virtual memory: use 1M areas */ >> static inline void mmu_setup(void) >> { >> - u32 *page_table = (u32 *)gd->tlb_addr; >> int i; >> u32 reg; >> >> arm_init_before_mmu(); >> /* Set up an identity-mapping for all 4GB, rw for everyone */ >> for (i = 0; i< 4096; i++) >> - page_table[i] = i<< 20 | (3<< 10) | 0x12; > > > Maybe give names to some of the magic numbers here (and in other places > where they appear). OK - this line is actually being removed but I will add constants for the values in set_section_dcache(). > > >> + set_section_dcache(i, DCACHE_OFF); >> >> for (i = 0; i< CONFIG_NR_DRAM_BANKS; i++) { >> dram_bank_mmu_setup(i); >> @@ -82,7 +122,7 @@ static inline void mmu_setup(void) >> >> /* Copy the page table address to cp15 */ >> asm volatile("mcr p15, 0, %0, c2, c0, 0" >> - : : "r" (page_table) : "memory"); >> + : : "r" (gd->tlb_addr) : "memory"); >> /* Set the access control to all-supervisor */ >> asm volatile("mcr p15, 0, %0, c3, c0, 0" >> : : "r" (~0)); > > > Amicalement, > -- > Albert. Regards, Simon _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot