Skip to content

Commit

Permalink
Blackfin: decouple unrelated cache settings to get exact behavior
Browse files Browse the repository at this point in the history
The current cache options don't really represent the hardware features.
They end up setting different aspects of the hardware so that the end
result is to turn on/off the cache.  Unfortunately, when we hit cache
problems with the hardware, it's difficult to test different settings to
root cause the problem.  The current settings also don't cleanly allow for
different caching behaviors with different regions of memory.

So split the configure options such that they properly reflect the settings
that are applied to the hardware.

Signed-off-by: Jie Zhang <jie.zhang@analog.com>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
  • Loading branch information
Jie Zhang authored and Mike Frysinger committed Jun 23, 2009
1 parent 7c039a9 commit 41ba653
Show file tree
Hide file tree
Showing 11 changed files with 176 additions and 81 deletions.
57 changes: 39 additions & 18 deletions arch/blackfin/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -907,23 +907,41 @@ endchoice


comment "Cache Support"

config BFIN_ICACHE
bool "Enable ICACHE"
default y
config BFIN_ICACHE_LOCK
bool "Enable Instruction Cache Locking"
depends on BFIN_ICACHE
default n
config BFIN_EXTMEM_ICACHEABLE
bool "Enable ICACHE for external memory"
depends on BFIN_ICACHE
default y
config BFIN_L2_ICACHEABLE
bool "Enable ICACHE for L2 SRAM"
depends on BFIN_ICACHE
depends on BF54x || BF561
default n

config BFIN_DCACHE
bool "Enable DCACHE"
default y
config BFIN_DCACHE_BANKA
bool "Enable only 16k BankA DCACHE - BankB is SRAM"
depends on BFIN_DCACHE && !BF531
default n
config BFIN_ICACHE_LOCK
bool "Enable Instruction Cache Locking"

choice
prompt "External memory cache policy"
config BFIN_EXTMEM_DCACHEABLE
bool "Enable DCACHE for external memory"
depends on BFIN_DCACHE
default BFIN_WB if !SMP
default BFIN_WT if SMP
config BFIN_WB
default y
choice
prompt "External memory DCACHE policy"
depends on BFIN_EXTMEM_DCACHEABLE
default BFIN_EXTMEM_WRITEBACK if !SMP
default BFIN_EXTMEM_WRITETHROUGH if SMP
config BFIN_EXTMEM_WRITEBACK
bool "Write back"
depends on !SMP
help
Expand All @@ -941,7 +959,7 @@ config BFIN_WB
If you are unsure of the options and you want to be safe,
then go with Write Through.

config BFIN_WT
config BFIN_EXTMEM_WRITETHROUGH
bool "Write through"
help
Write Back Policy:
Expand All @@ -960,23 +978,26 @@ config BFIN_WT

endchoice

config BFIN_L2_DCACHEABLE
bool "Enable DCACHE for L2 SRAM"
depends on BFIN_DCACHE
depends on BF54x || BF561
default n
choice
prompt "L2 SRAM cache policy"
depends on (BF54x || BF561)
default BFIN_L2_WT
config BFIN_L2_WB
prompt "L2 SRAM DCACHE policy"
depends on BFIN_L2_DCACHEABLE
default BFIN_L2_WRITEBACK
config BFIN_L2_WRITEBACK
bool "Write back"
depends on !SMP

config BFIN_L2_WT
config BFIN_L2_WRITETHROUGH
bool "Write through"
depends on !SMP

config BFIN_L2_NOT_CACHED
bool "Not cached"

endchoice


comment "Memory Protection Unit"
config MPU
bool "Enable the memory protection unit (EXPERIMENTAL)"
default n
Expand Down
4 changes: 2 additions & 2 deletions arch/blackfin/include/asm/cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@

#if defined(CONFIG_SMP) && \
!defined(CONFIG_BFIN_CACHE_COHERENT)
# if defined(CONFIG_BFIN_ICACHE)
# if defined(CONFIG_BFIN_ICACHEABLE) || defined(CONFIG_BFIN_L2_ICACHEABLE)
# define __ARCH_SYNC_CORE_ICACHE
# endif
# if defined(CONFIG_BFIN_DCACHE)
# if defined(CONFIG_BFIN_DCACHEABLE) || defined(CONFIG_BFIN_L2_DCACHEABLE)
# define __ARCH_SYNC_CORE_DCACHE
# endif
#ifndef __ASSEMBLY__
Expand Down
10 changes: 5 additions & 5 deletions arch/blackfin/include/asm/cacheflush.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ extern void blackfin_invalidate_entire_icache(void);

static inline void flush_icache_range(unsigned start, unsigned end)
{
#if defined(CONFIG_BFIN_WB)
#if defined(CONFIG_BFIN_EXTMEM_WRITEBACK) || defined(CONFIG_BFIN_L2_WRITEBACK)
blackfin_dcache_flush_range(start, end);
#endif

Expand Down Expand Up @@ -87,9 +87,9 @@ do { memcpy(dst, src, len); \
#else
# define invalidate_dcache_range(start,end) do { } while (0)
#endif
#if defined(CONFIG_BFIN_DCACHE) && defined(CONFIG_BFIN_WB)
#if defined(CONFIG_BFIN_EXTMEM_WRITEBACK) || defined(CONFIG_BFIN_L2_WRITEBACK)
# define flush_dcache_range(start,end) blackfin_dcache_flush_range((start), (end))
# define flush_dcache_page(page) blackfin_dflush_page(page_address(page))
# define flush_dcache_page(page) blackfin_dflush_page(page_address(page))
#else
# define flush_dcache_range(start,end) do { } while (0)
# define flush_dcache_page(page) do { } while (0)
Expand All @@ -100,7 +100,7 @@ extern unsigned long reserved_mem_icache_on;

static inline int bfin_addr_dcacheable(unsigned long addr)
{
#ifdef CONFIG_BFIN_DCACHE
#ifdef CONFIG_BFIN_EXTMEM_DCACHEABLE
if (addr < (_ramend - DMA_UNCACHED_REGION))
return 1;
#endif
Expand All @@ -109,7 +109,7 @@ static inline int bfin_addr_dcacheable(unsigned long addr)
addr >= _ramend && addr < physical_mem_end)
return 1;

#ifndef CONFIG_BFIN_L2_NOT_CACHED
#ifdef CONFIG_BFIN_L2_DCACHEABLE
if (addr >= L2_START && addr < L2_START + L2_LENGTH)
return 1;
#endif
Expand Down
32 changes: 17 additions & 15 deletions arch/blackfin/include/asm/cplb.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@
#define L1_IMEMORY ( CPLB_USER_RD | CPLB_VALID | CPLB_LOCK)
#define SDRAM_INON_CHBL ( CPLB_USER_RD | CPLB_VALID)

/*Use the menuconfig cache policy here - CONFIG_BFIN_WT/CONFIG_BFIN_WB*/

#if ANOMALY_05000158
#define ANOMALY_05000158_WORKAROUND 0x200
#else
Expand All @@ -47,10 +45,12 @@

#define CPLB_COMMON (CPLB_DIRTY | CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND)

#ifdef CONFIG_BFIN_WB /*Write Back Policy */
#ifdef CONFIG_BFIN_EXTMEM_WRITEBACK
#define SDRAM_DGENERIC (CPLB_L1_CHBL | CPLB_COMMON)
#else /*Write Through */
#elif defined(CONFIG_BFIN_EXTMEM_WRITETHROUGH)
#define SDRAM_DGENERIC (CPLB_L1_CHBL | CPLB_WT | CPLB_L1_AOW | CPLB_COMMON)
#else
#define SDRAM_DGENERIC (CPLB_COMMON)
#endif

#define SDRAM_DNON_CHBL (CPLB_COMMON)
Expand All @@ -61,21 +61,23 @@

#ifdef CONFIG_SMP
#define L2_ATTR (INITIAL_T | I_CPLB | D_CPLB)
#define L2_IMEMORY (CPLB_COMMON)
#define L2_DMEMORY (CPLB_LOCK | CPLB_COMMON)
#define L2_IMEMORY (CPLB_COMMON | PAGE_SIZE_1MB)
#define L2_DMEMORY (CPLB_LOCK | CPLB_COMMON | PAGE_SIZE_1MB)

#else
#define L2_ATTR (INITIAL_T | SWITCH_T | I_CPLB | D_CPLB)
#define L2_IMEMORY (SDRAM_IGENERIC)

# if defined(CONFIG_BFIN_L2_WB)
# define L2_DMEMORY (CPLB_L1_CHBL | CPLB_COMMON)
# elif defined(CONFIG_BFIN_L2_WT)
# define L2_DMEMORY (CPLB_L1_CHBL | CPLB_WT | CPLB_L1_AOW | CPLB_COMMON)
# elif defined(CONFIG_BFIN_L2_NOT_CACHED)
# define L2_DMEMORY (CPLB_COMMON)
# if defined(CONFIG_BFIN_L2_ICACHEABLE)
# define L2_IMEMORY (CPLB_L1_CHBL | CPLB_USER_RD | CPLB_VALID | PAGE_SIZE_1MB)
# else
# define L2_IMEMORY ( CPLB_USER_RD | CPLB_VALID | PAGE_SIZE_1MB)
# endif

# if defined(CONFIG_BFIN_L2_WRITEBACK)
# define L2_DMEMORY (CPLB_L1_CHBL | CPLB_COMMON | PAGE_SIZE_1MB)
# elif defined(CONFIG_BFIN_L2_WRITETHROUGH)
# define L2_DMEMORY (CPLB_L1_CHBL | CPLB_WT | CPLB_L1_AOW | CPLB_COMMON | PAGE_SIZE_1MB)
# else
# define L2_DMEMORY (0)
# define L2_DMEMORY (CPLB_COMMON | PAGE_SIZE_1MB)
# endif
#endif /* CONFIG_SMP */

Expand Down
10 changes: 5 additions & 5 deletions arch/blackfin/kernel/cplb-mpu/cplbinit.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,13 @@ void __init generate_cplb_tables_cpu(unsigned int cpu)

printk(KERN_INFO "MPU: setting up cplb tables with memory protection\n");

#ifdef CONFIG_BFIN_ICACHE
#ifdef CONFIG_BFIN_EXTMEM_ICACHEABLE
i_cache = CPLB_L1_CHBL | ANOMALY_05000158_WORKAROUND;
#endif

#ifdef CONFIG_BFIN_DCACHE
#ifdef CONFIG_BFIN_EXTMEM_DCACHEABLE
d_cache = CPLB_L1_CHBL;
#ifdef CONFIG_BFIN_WT
#ifdef CONFIG_BFIN_EXTMEM_WRITETROUGH
d_cache |= CPLB_L1_AOW | CPLB_WT;
#endif
#endif
Expand Down Expand Up @@ -91,9 +91,9 @@ void __init generate_cplb_tables_cpu(unsigned int cpu)
/* Cover L2 memory */
#if L2_LENGTH > 0
dcplb_tbl[cpu][i_d].addr = L2_START;
dcplb_tbl[cpu][i_d++].data = L2_DMEMORY | PAGE_SIZE_1MB;
dcplb_tbl[cpu][i_d++].data = L2_DMEMORY;
icplb_tbl[cpu][i_i].addr = L2_START;
icplb_tbl[cpu][i_i++].data = L2_IMEMORY | PAGE_SIZE_1MB;
icplb_tbl[cpu][i_i++].data = L2_IMEMORY;
#endif

first_mask_dcplb = i_d;
Expand Down
36 changes: 24 additions & 12 deletions arch/blackfin/kernel/cplb-mpu/cplbmgr.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,15 +150,19 @@ static noinline int dcplb_miss(unsigned int cpu)
nr_dcplb_miss[cpu]++;

d_data = CPLB_SUPV_WR | CPLB_VALID | CPLB_DIRTY | PAGE_SIZE_4KB;
#ifdef CONFIG_BFIN_DCACHE
#ifdef CONFIG_BFIN_EXTMEM_DCACHEABLE
if (bfin_addr_dcacheable(addr)) {
d_data |= CPLB_L1_CHBL | ANOMALY_05000158_WORKAROUND;
#ifdef CONFIG_BFIN_WT
# ifdef CONFIG_BFIN_EXTMEM_WRITETHROUGH
d_data |= CPLB_L1_AOW | CPLB_WT;
#endif
# endif
}
#endif
if (addr >= physical_mem_end) {

if (L2_LENGTH && addr >= L2_START && addr < L2_START + L2_LENGTH) {
addr = L2_START;
d_data = L2_DMEMORY;
} else if (addr >= physical_mem_end) {
if (addr >= ASYNC_BANK0_BASE && addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE
&& (status & FAULT_USERSUPV)) {
addr &= ~0x3fffff;
Expand Down Expand Up @@ -235,7 +239,7 @@ static noinline int icplb_miss(unsigned int cpu)

i_data = CPLB_VALID | CPLB_PORTPRIO | PAGE_SIZE_4KB;

#ifdef CONFIG_BFIN_ICACHE
#ifdef CONFIG_BFIN_EXTMEM_ICACHEABLE
/*
* Normal RAM, and possibly the reserved memory area, are
* cacheable.
Expand All @@ -245,7 +249,10 @@ static noinline int icplb_miss(unsigned int cpu)
i_data |= CPLB_L1_CHBL | ANOMALY_05000158_WORKAROUND;
#endif

if (addr >= physical_mem_end) {
if (L2_LENGTH && addr >= L2_START && addr < L2_START + L2_LENGTH) {
addr = L2_START;
i_data = L2_IMEMORY;
} else if (addr >= physical_mem_end) {
if (addr >= BOOT_ROM_START && addr < BOOT_ROM_START + BOOT_ROM_LENGTH
&& (status & FAULT_USERSUPV)) {
addr &= ~(1 * 1024 * 1024 - 1);
Expand Down Expand Up @@ -365,13 +372,18 @@ void set_mask_dcplbs(unsigned long *masks, unsigned int cpu)
local_irq_save_hw(flags);
current_rwx_mask[cpu] = masks;

d_data = CPLB_SUPV_WR | CPLB_VALID | CPLB_DIRTY | PAGE_SIZE_4KB;
#ifdef CONFIG_BFIN_DCACHE
d_data |= CPLB_L1_CHBL;
#ifdef CONFIG_BFIN_WT
d_data |= CPLB_L1_AOW | CPLB_WT;
#endif
if (L2_LENGTH && addr >= L2_START && addr < L2_START + L2_LENGTH) {
addr = L2_START;
d_data = L2_DMEMORY;
} else {
d_data = CPLB_SUPV_WR | CPLB_VALID | CPLB_DIRTY | PAGE_SIZE_4KB;
#ifdef CONFIG_BFIN_EXTMEM_DCACHEABLE
d_data |= CPLB_L1_CHBL;
# ifdef CONFIG_BFIN_EXTMEM_WRITETHROUGH
d_data |= CPLB_L1_AOW | CPLB_WT;
# endif
#endif
}

disable_dcplb();
for (i = first_mask_dcplb; i < first_switched_dcplb; i++) {
Expand Down
Loading

0 comments on commit 41ba653

Please sign in to comment.