]>
Commit | Line | Data |
---|---|---|
6cb142fa WD |
1 | /* |
2 | * U-boot - cache.c | |
3 | * | |
b86b3416 | 4 | * Copyright (c) 2005-2008 Analog Devices Inc. |
6cb142fa WD |
5 | * |
6 | * (C) Copyright 2000-2004 | |
7 | * Wolfgang Denk, DENX Software Engineering, wd@denx.de. | |
8 | * | |
b86b3416 | 9 | * Licensed under the GPL-2 or later. |
6cb142fa WD |
10 | */ |
11 | ||
3f0606ad AL |
12 | #include <common.h> |
13 | #include <asm/blackfin.h> | |
50f0d211 | 14 | #include <asm/mach-common/bits/mpu.h> |
3f0606ad | 15 | |
b86b3416 | 16 | void flush_cache(unsigned long addr, unsigned long size) |
6cb142fa | 17 | { |
fdce83c1 MF |
18 | void *start_addr, *end_addr; |
19 | int istatus, dstatus; | |
20 | ||
b86b3416 MF |
21 | /* no need to flush stuff in on chip memory (L1/L2/etc...) */ |
22 | if (addr >= 0xE0000000) | |
3f0606ad AL |
23 | return; |
24 | ||
fdce83c1 MF |
25 | start_addr = (void *)addr; |
26 | end_addr = (void *)(addr + size); | |
27 | istatus = icache_status(); | |
28 | dstatus = dcache_status(); | |
3f0606ad | 29 | |
fdce83c1 MF |
30 | if (istatus) { |
31 | if (dstatus) | |
32 | blackfin_icache_dcache_flush_range(start_addr, end_addr); | |
33 | else | |
34 | blackfin_icache_flush_range(start_addr, end_addr); | |
35 | } else if (dstatus) | |
36 | blackfin_dcache_flush_range(start_addr, end_addr); | |
6cb142fa | 37 | } |
50f0d211 | 38 | |
1c7a79a0 MF |
39 | #ifdef CONFIG_DCACHE_WB |
40 | static void flushinv_all_dcache(void) | |
41 | { | |
42 | u32 way, bank, subbank, set; | |
43 | u32 status, addr; | |
44 | u32 dmem_ctl = bfin_read_DMEM_CONTROL(); | |
45 | ||
46 | for (bank = 0; bank < 2; ++bank) { | |
47 | if (!(dmem_ctl & (1 << (DMC1_P - bank)))) | |
48 | continue; | |
49 | ||
50 | for (way = 0; way < 2; ++way) | |
51 | for (subbank = 0; subbank < 4; ++subbank) | |
52 | for (set = 0; set < 64; ++set) { | |
53 | ||
54 | bfin_write_DTEST_COMMAND( | |
55 | way << 26 | | |
56 | bank << 23 | | |
57 | subbank << 16 | | |
58 | set << 5 | |
59 | ); | |
60 | CSYNC(); | |
61 | status = bfin_read_DTEST_DATA0(); | |
62 | ||
63 | /* only worry about valid/dirty entries */ | |
64 | if ((status & 0x3) != 0x3) | |
65 | continue; | |
66 | ||
67 | /* construct the address using the tag */ | |
68 | addr = (status & 0xFFFFC800) | (subbank << 12) | (set << 5); | |
69 | ||
70 | /* flush it */ | |
71 | __asm__ __volatile__("FLUSHINV[%0];" : : "a"(addr)); | |
72 | } | |
73 | } | |
74 | } | |
75 | #endif | |
76 | ||
50f0d211 MF |
77 | void icache_enable(void) |
78 | { | |
79 | bfin_write_IMEM_CONTROL(IMC | ENICPLB); | |
80 | SSYNC(); | |
81 | } | |
82 | ||
83 | void icache_disable(void) | |
84 | { | |
85 | bfin_write_IMEM_CONTROL(0); | |
86 | SSYNC(); | |
87 | } | |
88 | ||
89 | int icache_status(void) | |
90 | { | |
0f9a8819 | 91 | return bfin_read_IMEM_CONTROL() & IMC; |
50f0d211 MF |
92 | } |
93 | ||
94 | void dcache_enable(void) | |
95 | { | |
96 | bfin_write_DMEM_CONTROL(ACACHE_BCACHE | ENDCPLB | PORT_PREF0); | |
97 | SSYNC(); | |
98 | } | |
99 | ||
100 | void dcache_disable(void) | |
101 | { | |
1c7a79a0 MF |
102 | #ifdef CONFIG_DCACHE_WB |
103 | bfin_write_DMEM_CONTROL(bfin_read_DMEM_CONTROL() & ~(ENDCPLB)); | |
104 | flushinv_all_dcache(); | |
105 | #endif | |
50f0d211 MF |
106 | bfin_write_DMEM_CONTROL(0); |
107 | SSYNC(); | |
108 | } | |
109 | ||
110 | int dcache_status(void) | |
111 | { | |
0f9a8819 | 112 | return bfin_read_DMEM_CONTROL() & ACACHE_BCACHE; |
50f0d211 | 113 | } |