1/* 2 * Copyright 2014, General Dynamics C4 Systems 3 * 4 * SPDX-License-Identifier: GPL-2.0-only 5 */ 6 7#include <config.h> 8#include <types.h> 9#include <machine/io.h> 10#include <kernel/vspace.h> 11#include <arch/machine.h> 12#include <arch/kernel/vspace.h> 13#include <linker.h> 14#include <drivers/timer/imx31-epit_gen.h> 15 16#define L2_LINE_SIZE_BITS 5 17#define L2_LINE_SIZE BIT(L2_LINE_SIZE_BITS) 18 19#define L2_LINE_START(a) ROUND_DOWN(a, L2_LINE_SIZE_BITS) 20#define L2_LINE_INDEX(a) (L2_LINE_START(a)>>L2_LINE_SIZE_BITS) 21 22timer_t *epit1 = (timer_t *) EPIT_PPTR; 23 24enum IPGConstants { 25 IPG_CLK = 1, 26 IPG_CLK_HIGHFREQ = 2, 27 IPG_CLK_32K = 3 28}; 29 30#define TIMER_CLOCK_SRC IPG_CLK_32K 31 32/* Configure EPIT1 as kernel preemption timer */ 33BOOT_CODE void initTimer(void) 34{ 35 epitcr_t epitcr_kludge; 36 37 /* Stop timer */ 38 epit1->epitcr = 0; 39 40 /* Configure timer */ 41 epitcr_kludge.words[0] = 0; /* Zero struct */ 42 epitcr_kludge = epitcr_set_clksrc(epitcr_kludge, TIMER_CLOCK_SRC); 43 /* Overwrite counter immediately on write */ 44 epitcr_kludge = epitcr_set_iovw(epitcr_kludge, 1); 45 /* Reload from modulus register */ 46 epitcr_kludge = epitcr_set_rld(epitcr_kludge, 1); 47 /* Enable interrupt */ 48 epitcr_kludge = epitcr_set_ocien(epitcr_kludge, 1); 49 /* Count from modulus value on restart */ 50 epitcr_kludge = epitcr_set_enmod(epitcr_kludge, 1); 51 epit1->epitcr = epitcr_kludge.words[0]; 52 53 /* Set counter modulus */ 54 epit1->epitlr = TIMER_RELOAD; 55 56 /* Interrupt at zero count */ 57 epit1->epitcmpr = 0; 58 59 /* Clear pending interrupt */ 60 epit1->epitsr = 1; 61 62 /* Enable timer */ 63 epitcr_kludge = epitcr_set_en(epitcr_kludge, 1); 64 epit1->epitcr = epitcr_kludge.words[0]; 65} 66 67