aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2012-01-11 23:11:43 -0500
committerPaul Mundt <lethal@linux-sh.org>2012-01-11 23:11:43 -0500
commitb1bdd255661369cb6eb90b6e181169b5e6d0f9b6 (patch)
tree17d15f3a6dc5bdd6205070dbef0e339421b13d25 /arch/sh
parent9d14070f656addddce3d63fd483de46930b51850 (diff)
parentc1537b4863da620f12f5b42ece61bf65314148ed (diff)
Merge branch 'sh/nommu' into sh-latest
Diffstat (limited to 'arch/sh')
-rw-r--r--arch/sh/Kconfig4
-rw-r--r--arch/sh/drivers/pci/pci.c23
-rw-r--r--arch/sh/mm/cache-sh2a.c123
3 files changed, 85 insertions, 65 deletions
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 47a2f1c2cb0d..3c8db65c89e5 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -85,9 +85,6 @@ config GENERIC_GPIO
85config GENERIC_CALIBRATE_DELAY 85config GENERIC_CALIBRATE_DELAY
86 bool 86 bool
87 87
88config GENERIC_IOMAP
89 bool
90
91config GENERIC_CLOCKEVENTS 88config GENERIC_CLOCKEVENTS
92 def_bool y 89 def_bool y
93 90
@@ -861,6 +858,7 @@ config PCI
861 bool "PCI support" 858 bool "PCI support"
862 depends on SYS_SUPPORTS_PCI 859 depends on SYS_SUPPORTS_PCI
863 select PCI_DOMAINS 860 select PCI_DOMAINS
861 select GENERIC_PCI_IOMAP
864 help 862 help
865 Find out whether you have a PCI motherboard. PCI is the name of a 863 Find out whether you have a PCI motherboard. PCI is the name of a
866 bus system, i.e. the way the CPU talks to the other stuff inside 864 bus system, i.e. the way the CPU talks to the other stuff inside
diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c
index c2691afe8f79..11aaf2fdec84 100644
--- a/arch/sh/drivers/pci/pci.c
+++ b/arch/sh/drivers/pci/pci.c
@@ -393,29 +393,6 @@ static void __iomem *ioport_map_pci(struct pci_dev *dev,
393 return (void __iomem *)(chan->io_map_base + port); 393 return (void __iomem *)(chan->io_map_base + port);
394} 394}
395 395
396void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
397{
398 resource_size_t start = pci_resource_start(dev, bar);
399 resource_size_t len = pci_resource_len(dev, bar);
400 unsigned long flags = pci_resource_flags(dev, bar);
401
402 if (unlikely(!len || !start))
403 return NULL;
404 if (maxlen && len > maxlen)
405 len = maxlen;
406
407 if (flags & IORESOURCE_IO)
408 return ioport_map_pci(dev, start, len);
409 if (flags & IORESOURCE_MEM) {
410 if (flags & IORESOURCE_CACHEABLE)
411 return ioremap(start, len);
412 return ioremap_nocache(start, len);
413 }
414
415 return NULL;
416}
417EXPORT_SYMBOL(pci_iomap);
418
419void pci_iounmap(struct pci_dev *dev, void __iomem *addr) 396void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
420{ 397{
421 iounmap(addr); 398 iounmap(addr);
diff --git a/arch/sh/mm/cache-sh2a.c b/arch/sh/mm/cache-sh2a.c
index 1f51225426a2..ae08cbbfa569 100644
--- a/arch/sh/mm/cache-sh2a.c
+++ b/arch/sh/mm/cache-sh2a.c
@@ -15,35 +15,78 @@
15#include <asm/cacheflush.h> 15#include <asm/cacheflush.h>
16#include <asm/io.h> 16#include <asm/io.h>
17 17
18/*
19 * The maximum number of pages we support up to when doing ranged dcache
20 * flushing. Anything exceeding this will simply flush the dcache in its
21 * entirety.
22 */
23#define MAX_OCACHE_PAGES 32
24#define MAX_ICACHE_PAGES 32
25
26static void sh2a_flush_oc_line(unsigned long v, int way)
27{
28 unsigned long addr = (v & 0x000007f0) | (way << 11);
29 unsigned long data;
30
31 data = __raw_readl(CACHE_OC_ADDRESS_ARRAY | addr);
32 if ((data & CACHE_PHYSADDR_MASK) == (v & CACHE_PHYSADDR_MASK)) {
33 data &= ~SH_CACHE_UPDATED;
34 __raw_writel(data, CACHE_OC_ADDRESS_ARRAY | addr);
35 }
36}
37
38static void sh2a_invalidate_line(unsigned long cache_addr, unsigned long v)
39{
40 /* Set associative bit to hit all ways */
41 unsigned long addr = (v & 0x000007f0) | SH_CACHE_ASSOC;
42 __raw_writel((addr & CACHE_PHYSADDR_MASK), cache_addr | addr);
43}
44
45/*
46 * Write back the dirty D-caches, but not invalidate them.
47 */
18static void sh2a__flush_wback_region(void *start, int size) 48static void sh2a__flush_wback_region(void *start, int size)
19{ 49{
50#ifdef CONFIG_CACHE_WRITEBACK
20 unsigned long v; 51 unsigned long v;
21 unsigned long begin, end; 52 unsigned long begin, end;
22 unsigned long flags; 53 unsigned long flags;
54 int nr_ways;
23 55
24 begin = (unsigned long)start & ~(L1_CACHE_BYTES-1); 56 begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
25 end = ((unsigned long)start + size + L1_CACHE_BYTES-1) 57 end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
26 & ~(L1_CACHE_BYTES-1); 58 & ~(L1_CACHE_BYTES-1);
59 nr_ways = current_cpu_data.dcache.ways;
27 60
28 local_irq_save(flags); 61 local_irq_save(flags);
29 jump_to_uncached(); 62 jump_to_uncached();
30 63
31 for (v = begin; v < end; v+=L1_CACHE_BYTES) { 64 /* If there are too many pages then flush the entire cache */
32 unsigned long addr = CACHE_OC_ADDRESS_ARRAY | (v & 0x000007f0); 65 if (((end - begin) >> PAGE_SHIFT) >= MAX_OCACHE_PAGES) {
66 begin = CACHE_OC_ADDRESS_ARRAY;
67 end = begin + (nr_ways * current_cpu_data.dcache.way_size);
68
69 for (v = begin; v < end; v += L1_CACHE_BYTES) {
70 unsigned long data = __raw_readl(v);
71 if (data & SH_CACHE_UPDATED)
72 __raw_writel(data & ~SH_CACHE_UPDATED, v);
73 }
74 } else {
33 int way; 75 int way;
34 for (way = 0; way < 4; way++) { 76 for (way = 0; way < nr_ways; way++) {
35 unsigned long data = __raw_readl(addr | (way << 11)); 77 for (v = begin; v < end; v += L1_CACHE_BYTES)
36 if ((data & CACHE_PHYSADDR_MASK) == (v & CACHE_PHYSADDR_MASK)) { 78 sh2a_flush_oc_line(v, way);
37 data &= ~SH_CACHE_UPDATED;
38 __raw_writel(data, addr | (way << 11));
39 }
40 } 79 }
41 } 80 }
42 81
43 back_to_cached(); 82 back_to_cached();
44 local_irq_restore(flags); 83 local_irq_restore(flags);
84#endif
45} 85}
46 86
87/*
88 * Write back the dirty D-caches and invalidate them.
89 */
47static void sh2a__flush_purge_region(void *start, int size) 90static void sh2a__flush_purge_region(void *start, int size)
48{ 91{
49 unsigned long v; 92 unsigned long v;
@@ -58,13 +101,22 @@ static void sh2a__flush_purge_region(void *start, int size)
58 jump_to_uncached(); 101 jump_to_uncached();
59 102
60 for (v = begin; v < end; v+=L1_CACHE_BYTES) { 103 for (v = begin; v < end; v+=L1_CACHE_BYTES) {
61 __raw_writel((v & CACHE_PHYSADDR_MASK), 104#ifdef CONFIG_CACHE_WRITEBACK
62 CACHE_OC_ADDRESS_ARRAY | (v & 0x000007f0) | 0x00000008); 105 int way;
106 int nr_ways = current_cpu_data.dcache.ways;
107 for (way = 0; way < nr_ways; way++)
108 sh2a_flush_oc_line(v, way);
109#endif
110 sh2a_invalidate_line(CACHE_OC_ADDRESS_ARRAY, v);
63 } 111 }
112
64 back_to_cached(); 113 back_to_cached();
65 local_irq_restore(flags); 114 local_irq_restore(flags);
66} 115}
67 116
117/*
118 * Invalidate the D-caches, but no write back please
119 */
68static void sh2a__flush_invalidate_region(void *start, int size) 120static void sh2a__flush_invalidate_region(void *start, int size)
69{ 121{
70 unsigned long v; 122 unsigned long v;
@@ -74,29 +126,25 @@ static void sh2a__flush_invalidate_region(void *start, int size)
74 begin = (unsigned long)start & ~(L1_CACHE_BYTES-1); 126 begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
75 end = ((unsigned long)start + size + L1_CACHE_BYTES-1) 127 end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
76 & ~(L1_CACHE_BYTES-1); 128 & ~(L1_CACHE_BYTES-1);
129
77 local_irq_save(flags); 130 local_irq_save(flags);
78 jump_to_uncached(); 131 jump_to_uncached();
79 132
80#ifdef CONFIG_CACHE_WRITEBACK 133 /* If there are too many pages then just blow the cache */
81 __raw_writel(__raw_readl(CCR) | CCR_OCACHE_INVALIDATE, CCR); 134 if (((end - begin) >> PAGE_SHIFT) >= MAX_OCACHE_PAGES) {
82 /* I-cache invalidate */ 135 __raw_writel(__raw_readl(CCR) | CCR_OCACHE_INVALIDATE, CCR);
83 for (v = begin; v < end; v+=L1_CACHE_BYTES) { 136 } else {
84 __raw_writel((v & CACHE_PHYSADDR_MASK), 137 for (v = begin; v < end; v += L1_CACHE_BYTES)
85 CACHE_IC_ADDRESS_ARRAY | (v & 0x000007f0) | 0x00000008); 138 sh2a_invalidate_line(CACHE_OC_ADDRESS_ARRAY, v);
86 }
87#else
88 for (v = begin; v < end; v+=L1_CACHE_BYTES) {
89 __raw_writel((v & CACHE_PHYSADDR_MASK),
90 CACHE_IC_ADDRESS_ARRAY | (v & 0x000007f0) | 0x00000008);
91 __raw_writel((v & CACHE_PHYSADDR_MASK),
92 CACHE_OC_ADDRESS_ARRAY | (v & 0x000007f0) | 0x00000008);
93 } 139 }
94#endif 140
95 back_to_cached(); 141 back_to_cached();
96 local_irq_restore(flags); 142 local_irq_restore(flags);
97} 143}
98 144
99/* WBack O-Cache and flush I-Cache */ 145/*
146 * Write back the range of D-cache, and purge the I-cache.
147 */
100static void sh2a_flush_icache_range(void *args) 148static void sh2a_flush_icache_range(void *args)
101{ 149{
102 struct flusher_data *data = args; 150 struct flusher_data *data = args;
@@ -107,23 +155,20 @@ static void sh2a_flush_icache_range(void *args)
107 start = data->addr1 & ~(L1_CACHE_BYTES-1); 155 start = data->addr1 & ~(L1_CACHE_BYTES-1);
108 end = (data->addr2 + L1_CACHE_BYTES-1) & ~(L1_CACHE_BYTES-1); 156 end = (data->addr2 + L1_CACHE_BYTES-1) & ~(L1_CACHE_BYTES-1);
109 157
158#ifdef CONFIG_CACHE_WRITEBACK
159 sh2a__flush_wback_region((void *)start, end-start);
160#endif
161
110 local_irq_save(flags); 162 local_irq_save(flags);
111 jump_to_uncached(); 163 jump_to_uncached();
112 164
113 for (v = start; v < end; v+=L1_CACHE_BYTES) { 165 /* I-Cache invalidate */
114 unsigned long addr = (v & 0x000007f0); 166 /* If there are too many pages then just blow the cache */
115 int way; 167 if (((end - start) >> PAGE_SHIFT) >= MAX_ICACHE_PAGES) {
116 /* O-Cache writeback */ 168 __raw_writel(__raw_readl(CCR) | CCR_ICACHE_INVALIDATE, CCR);
117 for (way = 0; way < 4; way++) { 169 } else {
118 unsigned long data = __raw_readl(CACHE_OC_ADDRESS_ARRAY | addr | (way << 11)); 170 for (v = start; v < end; v += L1_CACHE_BYTES)
119 if ((data & CACHE_PHYSADDR_MASK) == (v & CACHE_PHYSADDR_MASK)) { 171 sh2a_invalidate_line(CACHE_IC_ADDRESS_ARRAY, v);
120 data &= ~SH_CACHE_UPDATED;
121 __raw_writel(data, CACHE_OC_ADDRESS_ARRAY | addr | (way << 11));
122 }
123 }
124 /* I-Cache invalidate */
125 __raw_writel(addr,
126 CACHE_IC_ADDRESS_ARRAY | addr | 0x00000008);
127 } 172 }
128 173
129 back_to_cached(); 174 back_to_cached();