linux/arch/metag/include/asm/l2cache.h
<<
>>
Prefs
   1#ifndef _METAG_L2CACHE_H
   2#define _METAG_L2CACHE_H
   3
   4#ifdef CONFIG_METAG_L2C
   5
   6#include <asm/global_lock.h>
   7#include <asm/io.h>
   8
   9/*
  10 * Store the last known value of pfenable (we don't want prefetch enabled while
  11 * L2 is off).
  12 */
  13extern int l2c_pfenable;
  14
  15/* defined in arch/metag/drivers/core-sysfs.c */
  16extern struct sysdev_class cache_sysclass;
  17
  18static inline void wr_fence(void);
  19
  20/*
  21 * Functions for reading of L2 cache configuration.
  22 */
  23
  24/* Get raw L2 config register (CORE_CONFIG3) */
  25static inline unsigned int meta_l2c_config(void)
  26{
  27        const unsigned int *corecfg3 = (const unsigned int *)METAC_CORE_CONFIG3;
  28        return *corecfg3;
  29}
  30
  31/* Get whether the L2 is present */
  32static inline int meta_l2c_is_present(void)
  33{
  34        return meta_l2c_config() & METAC_CORECFG3_L2C_HAVE_L2C_BIT;
  35}
  36
  37/* Get whether the L2 is configured for write-back instead of write-through */
  38static inline int meta_l2c_is_writeback(void)
  39{
  40        return meta_l2c_config() & METAC_CORECFG3_L2C_MODE_BIT;
  41}
  42
  43/* Get whether the L2 is unified instead of separated code/data */
  44static inline int meta_l2c_is_unified(void)
  45{
  46        return meta_l2c_config() & METAC_CORECFG3_L2C_UNIFIED_BIT;
  47}
  48
  49/* Get the L2 cache size in bytes */
  50static inline unsigned int meta_l2c_size(void)
  51{
  52        unsigned int size_s;
  53        if (!meta_l2c_is_present())
  54                return 0;
  55        size_s = (meta_l2c_config() & METAC_CORECFG3_L2C_SIZE_BITS)
  56                        >> METAC_CORECFG3_L2C_SIZE_S;
  57        /* L2CSIZE is in KiB */
  58        return 1024 << size_s;
  59}
  60
  61/* Get the number of ways in the L2 cache */
  62static inline unsigned int meta_l2c_ways(void)
  63{
  64        unsigned int ways_s;
  65        if (!meta_l2c_is_present())
  66                return 0;
  67        ways_s = (meta_l2c_config() & METAC_CORECFG3_L2C_NUM_WAYS_BITS)
  68                        >> METAC_CORECFG3_L2C_NUM_WAYS_S;
  69        return 0x1 << ways_s;
  70}
  71
  72/* Get the line size of the L2 cache */
  73static inline unsigned int meta_l2c_linesize(void)
  74{
  75        unsigned int line_size;
  76        if (!meta_l2c_is_present())
  77                return 0;
  78        line_size = (meta_l2c_config() & METAC_CORECFG3_L2C_LINE_SIZE_BITS)
  79                        >> METAC_CORECFG3_L2C_LINE_SIZE_S;
  80        switch (line_size) {
  81        case METAC_CORECFG3_L2C_LINE_SIZE_64B:
  82                return 64;
  83        default:
  84                return 0;
  85        }
  86}
  87
  88/* Get the revision ID of the L2 cache */
  89static inline unsigned int meta_l2c_revision(void)
  90{
  91        return (meta_l2c_config() & METAC_CORECFG3_L2C_REV_ID_BITS)
  92                        >> METAC_CORECFG3_L2C_REV_ID_S;
  93}
  94
  95
  96/*
  97 * Start an initialisation of the L2 cachelines and wait for completion.
  98 * This should only be done in a LOCK1 or LOCK2 critical section while the L2
  99 * is disabled.
 100 */
 101static inline void _meta_l2c_init(void)
 102{
 103        metag_out32(SYSC_L2C_INIT_INIT, SYSC_L2C_INIT);
 104        while (metag_in32(SYSC_L2C_INIT) == SYSC_L2C_INIT_IN_PROGRESS)
 105                /* do nothing */;
 106}
 107
 108/*
 109 * Start a writeback of dirty L2 cachelines and wait for completion.
 110 * This should only be done in a LOCK1 or LOCK2 critical section.
 111 */
 112static inline void _meta_l2c_purge(void)
 113{
 114        metag_out32(SYSC_L2C_PURGE_PURGE, SYSC_L2C_PURGE);
 115        while (metag_in32(SYSC_L2C_PURGE) == SYSC_L2C_PURGE_IN_PROGRESS)
 116                /* do nothing */;
 117}
 118
 119/* Set whether the L2 cache is enabled. */
 120static inline void _meta_l2c_enable(int enabled)
 121{
 122        unsigned int enable;
 123
 124        enable = metag_in32(SYSC_L2C_ENABLE);
 125        if (enabled)
 126                enable |= SYSC_L2C_ENABLE_ENABLE_BIT;
 127        else
 128                enable &= ~SYSC_L2C_ENABLE_ENABLE_BIT;
 129        metag_out32(enable, SYSC_L2C_ENABLE);
 130}
 131
 132/* Set whether the L2 cache prefetch is enabled. */
 133static inline void _meta_l2c_pf_enable(int pfenabled)
 134{
 135        unsigned int enable;
 136
 137        enable = metag_in32(SYSC_L2C_ENABLE);
 138        if (pfenabled)
 139                enable |= SYSC_L2C_ENABLE_PFENABLE_BIT;
 140        else
 141                enable &= ~SYSC_L2C_ENABLE_PFENABLE_BIT;
 142        metag_out32(enable, SYSC_L2C_ENABLE);
 143}
 144
 145/* Return whether the L2 cache is enabled */
 146static inline int _meta_l2c_is_enabled(void)
 147{
 148        return metag_in32(SYSC_L2C_ENABLE) & SYSC_L2C_ENABLE_ENABLE_BIT;
 149}
 150
 151/* Return whether the L2 cache prefetch is enabled */
 152static inline int _meta_l2c_pf_is_enabled(void)
 153{
 154        return metag_in32(SYSC_L2C_ENABLE) & SYSC_L2C_ENABLE_PFENABLE_BIT;
 155}
 156
 157
 158/* Return whether the L2 cache is enabled */
 159static inline int meta_l2c_is_enabled(void)
 160{
 161        int en;
 162
 163        /*
 164         * There is no need to lock at the moment, as the enable bit is never
 165         * intermediately changed, so we will never see an intermediate result.
 166         */
 167        en = _meta_l2c_is_enabled();
 168
 169        return en;
 170}
 171
 172/*
 173 * Ensure the L2 cache is disabled.
 174 * Return whether the L2 was previously disabled.
 175 */
 176int meta_l2c_disable(void);
 177
 178/*
 179 * Ensure the L2 cache is enabled.
 180 * Return whether the L2 was previously enabled.
 181 */
 182int meta_l2c_enable(void);
 183
 184/* Return whether the L2 cache prefetch is enabled */
 185static inline int meta_l2c_pf_is_enabled(void)
 186{
 187        return l2c_pfenable;
 188}
 189
 190/*
 191 * Set whether the L2 cache prefetch is enabled.
 192 * Return whether the L2 prefetch was previously enabled.
 193 */
 194int meta_l2c_pf_enable(int pfenable);
 195
 196/*
 197 * Flush the L2 cache.
 198 * Return 1 if the L2 is disabled.
 199 */
 200int meta_l2c_flush(void);
 201
 202/*
 203 * Write back all dirty cache lines in the L2 cache.
 204 * Return 1 if the L2 is disabled or there isn't any writeback.
 205 */
 206static inline int meta_l2c_writeback(void)
 207{
 208        unsigned long flags;
 209        int en;
 210
 211        /* no need to purge if it's not a writeback cache */
 212        if (!meta_l2c_is_writeback())
 213                return 1;
 214
 215        /*
 216         * Purge only works if the L2 is enabled, and involves reading back to
 217         * detect completion, so keep this operation atomic with other threads.
 218         */
 219        __global_lock1(flags);
 220        en = meta_l2c_is_enabled();
 221        if (likely(en)) {
 222                wr_fence();
 223                _meta_l2c_purge();
 224        }
 225        __global_unlock1(flags);
 226
 227        return !en;
 228}
 229
 230#else /* CONFIG_METAG_L2C */
 231
 232#define meta_l2c_config()               0
 233#define meta_l2c_is_present()           0
 234#define meta_l2c_is_writeback()         0
 235#define meta_l2c_is_unified()           0
 236#define meta_l2c_size()                 0
 237#define meta_l2c_ways()                 0
 238#define meta_l2c_linesize()             0
 239#define meta_l2c_revision()             0
 240
 241#define meta_l2c_is_enabled()           0
 242#define _meta_l2c_pf_is_enabled()       0
 243#define meta_l2c_pf_is_enabled()        0
 244#define meta_l2c_disable()              1
 245#define meta_l2c_enable()               0
 246#define meta_l2c_pf_enable(X)           0
 247static inline int meta_l2c_flush(void)
 248{
 249        return 1;
 250}
 251static inline int meta_l2c_writeback(void)
 252{
 253        return 1;
 254}
 255
 256#endif /* CONFIG_METAG_L2C */
 257
 258#endif /* _METAG_L2CACHE_H */
 259