1/** 2 * \file 3 * \brief ARM Cortex A9 Global Timer driver. 4 */ 5 6/* 7 * Copyright (c) 2015 ETH Zurich. 8 * All rights reserved. 9 * 10 * This file is distributed under the terms in the attached LICENSE file. 11 * If you do not find this file, copies can be found by writing to: 12 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group. 13 */ 14#include <a9_gt.h> 15#include <maps/a9mpcore_map.h> 16#include <kernel.h> 17#include <paging_kernel_arch.h> 18#include <dev/cortex_a9_gt_dev.h> 19#include <systime.h> 20 21static cortex_a9_gt_t a9_gt; 22static bool initialized = false; 23 24#define MSG(format, ...) \ 25 printk( LOG_NOTE, "CortexA9 GT: "format, ## __VA_ARGS__ ) 26 27/* 28 * Initialize the timer. The MMU is on. 29 */ 30void a9_gt_init(lpaddr_t addr) 31{ 32 assert(!initialized); 33 lvaddr_t gt_base = paging_map_device(addr, A9MPCORE_TIMER_GBL_SIZE); 34 cortex_a9_gt_initialize(&a9_gt, (mackerel_addr_t)gt_base); 35 initialized = true; 36 MSG("initialized at 0x%"PRIxLVADDR"\n", gt_base); 37 38 // set the global timer 39 cortex_a9_gt_TimerControl_timer_enable_wrf(&a9_gt, 0x1); 40 cortex_a9_gt_TimerControl_comp_enable_wrf(&a9_gt, 0x0); 41 cortex_a9_gt_TimerControl_int_enable_wrf(&a9_gt, 0x1); 42 cortex_a9_gt_TimerControl_auto_increment_wrf(&a9_gt, 0x0); 43 cortex_a9_gt_TimerControl_prescale_wrf(&a9_gt, 0x0); 44 a9_gt_ack_irq(); 45} 46 47uint64_t a9_gt_read(void) 48{ 49 // need to re-read high value according to ARM TRM 4.4.1 50 uint32_t low, high; 51 do { 52 high = cortex_a9_gt_TimerCounterHigh_rd(&a9_gt); 53 low = cortex_a9_gt_TimerCounterLow_rd(&a9_gt); 54 } while(high != cortex_a9_gt_TimerCounterHigh_rd(&a9_gt)); 55 56 return (((uint64_t) high) << 32) | ((uint32_t) low); 57} 58 59uint32_t a9_gt_read_low(void) 60{ 61 return cortex_a9_gt_TimerCounterLow_rd(&a9_gt); 62} 63 64uint32_t a9_gt_read_high(void) 65{ 66 return cortex_a9_gt_TimerCounterHigh_rd(&a9_gt); 67} 68 69void a9_gt_set_comparator(uint64_t timeout) 70{ 71 cortex_a9_gt_TimerControl_comp_enable_wrf(&a9_gt, 0x0); 72 cortex_a9_gt_TimerComparatorLow_wr(&a9_gt, timeout); 73 cortex_a9_gt_TimerComparatorHigh_wr(&a9_gt, timeout >> 32); 74 cortex_a9_gt_TimerControl_comp_enable_wrf(&a9_gt, 0x1); 75} 76 77void a9_gt_ack_irq(void) 78{ 79 cortex_a9_gt_TimerIntStat_event_flag_wrf(&a9_gt, 0x1); 80} 81