uboot/arch/arm/mach-imx/cache.c
<<
>>
Prefs
   1/*
   2 * Copyright 2015 Freescale Semiconductor, Inc.
   3 *
   4 * SPDX-License-Identifier:     GPL-2.0+
   5 */
   6
   7#include <common.h>
   8#include <asm/armv7.h>
   9#include <asm/pl310.h>
  10#include <asm/io.h>
  11#include <asm/mach-imx/sys_proto.h>
  12
  13#ifndef CONFIG_SYS_DCACHE_OFF
  14void enable_caches(void)
  15{
  16#if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH)
  17        enum dcache_option option = DCACHE_WRITETHROUGH;
  18#else
  19        enum dcache_option option = DCACHE_WRITEBACK;
  20#endif
  21        /* Avoid random hang when download by usb */
  22        invalidate_dcache_all();
  23
  24        /* Enable D-cache. I-cache is already enabled in start.S */
  25        dcache_enable();
  26
  27        /* Enable caching on OCRAM and ROM */
  28        mmu_set_region_dcache_behaviour(ROMCP_ARB_BASE_ADDR,
  29                                        ROMCP_ARB_END_ADDR,
  30                                        option);
  31        mmu_set_region_dcache_behaviour(IRAM_BASE_ADDR,
  32                                        IRAM_SIZE,
  33                                        option);
  34}
  35#endif
  36
  37#ifndef CONFIG_SYS_L2CACHE_OFF
  38#ifdef CONFIG_SYS_L2_PL310
  39#define IOMUXC_GPR11_L2CACHE_AS_OCRAM 0x00000002
  40void v7_outer_cache_enable(void)
  41{
  42        struct pl310_regs *const pl310 = (struct pl310_regs *)L2_PL310_BASE;
  43        struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
  44        unsigned int val;
  45
  46
  47        /*
  48         * Must disable the L2 before changing the latency parameters
  49         * and auxiliary control register.
  50         */
  51        clrbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN);
  52
  53        /*
  54         * Set bit 22 in the auxiliary control register. If this bit
  55         * is cleared, PL310 treats Normal Shared Non-cacheable
  56         * accesses as Cacheable no-allocate.
  57         */
  58        setbits_le32(&pl310->pl310_aux_ctrl, L310_SHARED_ATT_OVERRIDE_ENABLE);
  59
  60        if (is_mx6sl() || is_mx6sll()) {
  61                val = readl(&iomux->gpr[11]);
  62                if (val & IOMUXC_GPR11_L2CACHE_AS_OCRAM) {
  63                        /* L2 cache configured as OCRAM, reset it */
  64                        val &= ~IOMUXC_GPR11_L2CACHE_AS_OCRAM;
  65                        writel(val, &iomux->gpr[11]);
  66                }
  67        }
  68
  69        writel(0x132, &pl310->pl310_tag_latency_ctrl);
  70        writel(0x132, &pl310->pl310_data_latency_ctrl);
  71
  72        val = readl(&pl310->pl310_prefetch_ctrl);
  73
  74        /* Turn on the L2 I/D prefetch */
  75        val |= 0x30000000;
  76
  77        /*
  78         * The L2 cache controller(PL310) version on the i.MX6D/Q is r3p1-50rel0
  79         * The L2 cache controller(PL310) version on the i.MX6DL/SOLO/SL is r3p2
  80         * But according to ARM PL310 errata: 752271
  81         * ID: 752271: Double linefill feature can cause data corruption
  82         * Fault Status: Present in: r3p0, r3p1, r3p1-50rel0. Fixed in r3p2
  83         * Workaround: The only workaround to this erratum is to disable the
  84         * double linefill feature. This is the default behavior.
  85         */
  86
  87#ifndef CONFIG_MX6Q
  88        val |= 0x40800000;
  89#endif
  90        writel(val, &pl310->pl310_prefetch_ctrl);
  91
  92        val = readl(&pl310->pl310_power_ctrl);
  93        val |= L2X0_DYNAMIC_CLK_GATING_EN;
  94        val |= L2X0_STNDBY_MODE_EN;
  95        writel(val, &pl310->pl310_power_ctrl);
  96
  97        setbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN);
  98}
  99
 100void v7_outer_cache_disable(void)
 101{
 102        struct pl310_regs *const pl310 = (struct pl310_regs *)L2_PL310_BASE;
 103
 104        clrbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN);
 105}
 106#endif /* !CONFIG_SYS_L2_PL310 */
 107#endif /* !CONFIG_SYS_L2CACHE_OFF */
 108