uboot/arch/arm/lib/cache-pl310.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2010
   3 * Texas Instruments, <www.ti.com>
   4 * Aneesh V <aneesh@ti.com>
   5 *
   6 * See file CREDITS for list of people who contributed to this
   7 * project.
   8 *
   9 * This program is free software; you can redistribute it and/or
  10 * modify it under the terms of the GNU General Public License as
  11 * published by the Free Software Foundation; either version 2 of
  12 * the License, or (at your option) any later version.
  13 *
  14 * This program is distributed in the hope that it will be useful,
  15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17 * GNU General Public License for more details.
  18 *
  19 * You should have received a copy of the GNU General Public License
  20 * along with this program; if not, write to the Free Software
  21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  22 * MA 02111-1307 USA
  23 */
  24#include <linux/types.h>
  25#include <asm/io.h>
  26#include <asm/armv7.h>
  27#include <asm/pl310.h>
  28#include <config.h>
  29#include <common.h>
  30
  31struct pl310_regs *const pl310 = (struct pl310_regs *)CONFIG_SYS_PL310_BASE;
  32
  33static void pl310_cache_sync(void)
  34{
  35        writel(0, &pl310->pl310_cache_sync);
  36}
  37
  38static void pl310_background_op_all_ways(u32 *op_reg)
  39{
  40        u32 assoc_16, associativity, way_mask;
  41
  42        assoc_16 = readl(&pl310->pl310_aux_ctrl) &
  43                        PL310_AUX_CTRL_ASSOCIATIVITY_MASK;
  44        if (assoc_16)
  45                associativity = 16;
  46        else
  47                associativity = 8;
  48
  49        way_mask = (1 << associativity) - 1;
  50        /* Invalidate all ways */
  51        writel(way_mask, op_reg);
  52        /* Wait for all ways to be invalidated */
  53        while (readl(op_reg) && way_mask)
  54                ;
  55        pl310_cache_sync();
  56}
  57
  58void v7_outer_cache_inval_all(void)
  59{
  60        pl310_background_op_all_ways(&pl310->pl310_inv_way);
  61}
  62
  63void v7_outer_cache_flush_all(void)
  64{
  65        pl310_background_op_all_ways(&pl310->pl310_clean_inv_way);
  66}
  67
  68/* Flush(clean invalidate) memory from start to stop-1 */
  69void v7_outer_cache_flush_range(u32 start, u32 stop)
  70{
  71        /* PL310 currently supports only 32 bytes cache line */
  72        u32 pa, line_size = 32;
  73
  74        /*
  75         * Align to the beginning of cache-line - this ensures that
  76         * the first 5 bits are 0 as required by PL310 TRM
  77         */
  78        start &= ~(line_size - 1);
  79
  80        for (pa = start; pa < stop; pa = pa + line_size)
  81                writel(pa, &pl310->pl310_clean_inv_line_pa);
  82
  83        pl310_cache_sync();
  84}
  85
  86/* invalidate memory from start to stop-1 */
  87void v7_outer_cache_inval_range(u32 start, u32 stop)
  88{
  89        /* PL310 currently supports only 32 bytes cache line */
  90        u32 pa, line_size = 32;
  91
  92        /*
  93         * If start address is not aligned to cache-line do not
  94         * invalidate the first cache-line
  95         */
  96        if (start & (line_size - 1)) {
  97                printf("ERROR: %s - start address is not aligned - 0x%08x\n",
  98                        __func__, start);
  99                /* move to next cache line */
 100                start = (start + line_size - 1) & ~(line_size - 1);
 101        }
 102
 103        /*
 104         * If stop address is not aligned to cache-line do not
 105         * invalidate the last cache-line
 106         */
 107        if (stop & (line_size - 1)) {
 108                printf("ERROR: %s - stop address is not aligned - 0x%08x\n",
 109                        __func__, stop);
 110                /* align to the beginning of this cache line */
 111                stop &= ~(line_size - 1);
 112        }
 113
 114        for (pa = start; pa < stop; pa = pa + line_size)
 115                writel(pa, &pl310->pl310_inv_line_pa);
 116
 117        pl310_cache_sync();
 118}
 119