~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to arch/sh/mm/cache-sh2.c

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * arch/sh/mm/cache-sh2.c
 
3
 *
 
4
 * Copyright (C) 2002 Paul Mundt
 
5
 * Copyright (C) 2008 Yoshinori Sato
 
6
 *
 
7
 * Released under the terms of the GNU GPL v2.0.
 
8
 */
 
9
 
 
10
#include <linux/init.h>
 
11
#include <linux/mm.h>
 
12
 
 
13
#include <asm/cache.h>
 
14
#include <asm/addrspace.h>
 
15
#include <asm/processor.h>
 
16
#include <asm/cacheflush.h>
 
17
#include <asm/io.h>
 
18
 
 
19
static void sh2__flush_wback_region(void *start, int size)
 
20
{
 
21
        unsigned long v;
 
22
        unsigned long begin, end;
 
23
 
 
24
        begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
 
25
        end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
 
26
                & ~(L1_CACHE_BYTES-1);
 
27
        for (v = begin; v < end; v+=L1_CACHE_BYTES) {
 
28
                unsigned long addr = CACHE_OC_ADDRESS_ARRAY | (v & 0x00000ff0);
 
29
                int way;
 
30
                for (way = 0; way < 4; way++) {
 
31
                        unsigned long data =  __raw_readl(addr | (way << 12));
 
32
                        if ((data & CACHE_PHYSADDR_MASK) == (v & CACHE_PHYSADDR_MASK)) {
 
33
                                data &= ~SH_CACHE_UPDATED;
 
34
                                __raw_writel(data, addr | (way << 12));
 
35
                        }
 
36
                }
 
37
        }
 
38
}
 
39
 
 
40
static void sh2__flush_purge_region(void *start, int size)
 
41
{
 
42
        unsigned long v;
 
43
        unsigned long begin, end;
 
44
 
 
45
        begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
 
46
        end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
 
47
                & ~(L1_CACHE_BYTES-1);
 
48
 
 
49
        for (v = begin; v < end; v+=L1_CACHE_BYTES)
 
50
                __raw_writel((v & CACHE_PHYSADDR_MASK),
 
51
                          CACHE_OC_ADDRESS_ARRAY | (v & 0x00000ff0) | 0x00000008);
 
52
}
 
53
 
 
54
static void sh2__flush_invalidate_region(void *start, int size)
 
55
{
 
56
#ifdef CONFIG_CACHE_WRITEBACK
 
57
        /*
 
58
         * SH-2 does not support individual line invalidation, only a
 
59
         * global invalidate.
 
60
         */
 
61
        unsigned long ccr;
 
62
        unsigned long flags;
 
63
        local_irq_save(flags);
 
64
        jump_to_uncached();
 
65
 
 
66
        ccr = __raw_readl(CCR);
 
67
        ccr |= CCR_CACHE_INVALIDATE;
 
68
        __raw_writel(ccr, CCR);
 
69
 
 
70
        back_to_cached();
 
71
        local_irq_restore(flags);
 
72
#else
 
73
        unsigned long v;
 
74
        unsigned long begin, end;
 
75
 
 
76
        begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
 
77
        end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
 
78
                & ~(L1_CACHE_BYTES-1);
 
79
 
 
80
        for (v = begin; v < end; v+=L1_CACHE_BYTES)
 
81
                __raw_writel((v & CACHE_PHYSADDR_MASK),
 
82
                          CACHE_OC_ADDRESS_ARRAY | (v & 0x00000ff0) | 0x00000008);
 
83
#endif
 
84
}
 
85
 
 
86
void __init sh2_cache_init(void)
 
87
{
 
88
        __flush_wback_region            = sh2__flush_wback_region;
 
89
        __flush_purge_region            = sh2__flush_purge_region;
 
90
        __flush_invalidate_region       = sh2__flush_invalidate_region;
 
91
}