1/* 2 * Copyright 2014, General Dynamics C4 Systems 3 * 4 * This software may be distributed and modified according to the terms of 5 * the GNU General Public License version 2. Note that NO WARRANTY is provided. 6 * See "LICENSE_GPLv2.txt" for details. 7 * 8 * @TAG(GD_GPL) 9 */ 10 11#include <config.h> 12#include <types.h> 13#include <machine/io.h> 14#include <kernel/vspace.h> 15#include <arch/machine.h> 16#include <arch/kernel/vspace.h> 17#include <plat/machine.h> 18#include <linker.h> 19#include <plat/machine/devices.h> 20#include <plat/machine/hardware.h> 21#include <plat/machine/timer.h> 22#include <plat/machine/hardware_gen.h> 23#include <arch/benchmark_overflowHandler.h> 24 25#define L2_LINE_SIZE_BITS 5 26#define L2_LINE_SIZE BIT(L2_LINE_SIZE_BITS) 27 28#define L2_LINE_START(a) ROUND_DOWN(a, L2_LINE_SIZE_BITS) 29#define L2_LINE_INDEX(a) (L2_LINE_START(a)>>L2_LINE_SIZE_BITS) 30 31timer_t *epit1 = (timer_t *) EPIT_PPTR; 32 33enum IPGConstants { 34 IPG_CLK = 1, 35 IPG_CLK_HIGHFREQ = 2, 36 IPG_CLK_32K = 3 37}; 38 39#define TIMER_CLOCK_SRC IPG_CLK_32K 40 41interrupt_t active_irq = irqInvalid; 42 43/* Configure EPIT1 as kernel preemption timer */ 44BOOT_CODE void 45initTimer(void) 46{ 47 epitcr_t epitcr_kludge; 48 49 /* Stop timer */ 50 epit1->epitcr = 0; 51 52 /* Configure timer */ 53 epitcr_kludge.words[0] = 0; /* Zero struct */ 54 epitcr_kludge = epitcr_set_clksrc(epitcr_kludge, TIMER_CLOCK_SRC); 55 /* Overwrite counter immediately on write */ 56 epitcr_kludge = epitcr_set_iovw(epitcr_kludge, 1); 57 /* Reload from modulus register */ 58 epitcr_kludge = epitcr_set_rld(epitcr_kludge, 1); 59 /* Enable interrupt */ 60 epitcr_kludge = epitcr_set_ocien(epitcr_kludge, 1); 61 /* Count from modulus value on restart */ 62 epitcr_kludge = epitcr_set_enmod(epitcr_kludge, 1); 63 epit1->epitcr = epitcr_kludge.words[0]; 64 65 /* Set counter modulus */ 66 epit1->epitlr = TIMER_RELOAD; 67 68 /* Interrupt at zero count */ 69 epit1->epitcmpr = 0; 70 71 /* Clear pending interrupt */ 72 epit1->epitsr = 1; 73 74 /* Enable timer */ 75 epitcr_kludge = epitcr_set_en(epitcr_kludge, 1); 76 epit1->epitcr = epitcr_kludge.words[0]; 77} 78 79static void cleanL2(void) 80{ 81 /* clean all ways */ 82 imx31_l2cc_flush_regs->clean_by_way = 0xff; 83 /* Busy-wait for completion */ 84 while (imx31_l2cc_flush_regs->clean_by_way); 85} 86 87static void invalidateL2(void) 88{ 89 /* Invalidate all ways. */ 90 imx31_l2cc_flush_regs->inv_by_way = 0xff; 91 /* Busy-wait for completion. */ 92 while (imx31_l2cc_flush_regs->inv_by_way); 93} 94 95static void finaliseL2Op(void) 96{ 97 /* We sync the l2 cache, which drains the write and eviction 98 buffers, to ensure that everything is consistent with RAM. */ 99 imx31_l2cc_flush_regs->sync = 1; 100} 101 102void plat_cleanL2Range(paddr_t start, paddr_t end) 103{ 104 paddr_t line; 105 word_t index; 106 107 for (index = L2_LINE_INDEX(start); 108 index < L2_LINE_INDEX(end) + 1; 109 index++) { 110 line = index << L2_LINE_SIZE_BITS; 111 imx31_l2cc_flush_regs->clean_by_pa = line; 112 } 113 finaliseL2Op(); 114} 115 116void plat_invalidateL2Range(paddr_t start, paddr_t end) 117{ 118 paddr_t line; 119 word_t index; 120 121 for (index = L2_LINE_INDEX(start); 122 index < L2_LINE_INDEX(end) + 1; 123 index++) { 124 line = index << L2_LINE_SIZE_BITS; 125 imx31_l2cc_flush_regs->inv_by_pa = line; 126 } 127 128 finaliseL2Op(); 129} 130 131void plat_cleanInvalidateL2Range(paddr_t start, paddr_t end) 132{ 133 paddr_t line; 134 word_t index; 135 136 for (index = L2_LINE_INDEX(start); 137 index < L2_LINE_INDEX(end) + 1; 138 index++) { 139 line = index << L2_LINE_SIZE_BITS; 140 imx31_l2cc_flush_regs->clinv_by_pa = line; 141 } 142 finaliseL2Op(); 143} 144 145void plat_cleanInvalidateCache(void) 146{ 147 cleanL2(); 148 invalidateL2(); 149} 150 151BOOT_CODE void 152initL2Cache(void) 153{ 154#ifndef CONFIG_DEBUG_DISABLE_L2_CACHE 155 /* Configure L2 cache */ 156 imx31_l2cc_ctrl_regs->aux_control = 0x0003001b; 157 158 /* Invalidate the L2 cache */ 159 invalidateL2(); 160 161 /* Enable the L2 cache */ 162 imx31_l2cc_ctrl_regs->control = 1; 163#endif 164} 165 166BOOT_CODE void 167initIRQController(void) 168{ 169 /* Do nothing */ 170} 171 172BOOT_CODE void cpu_initLocalIRQController(void) 173{ 174 /* Do nothing */ 175} 176