1 /* 2 * Copyright 2007-2012, Haiku Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * François Revol <revol@free.fr> 7 * Ithamar R. Adema <ithamar@upgrade-android.com> 8 * 9 * Copyright 2001, Travis Geiselbrecht. All rights reserved. 10 * Distributed under the terms of the NewOS License. 11 */ 12 13 14 #include <boot/stage2.h> 15 #include <kernel.h> 16 #include <debug.h> 17 18 #include <timer.h> 19 #include <arch/timer.h> 20 #include <arch/cpu.h> 21 22 23 //#define TRACE_ARCH_TIMER 24 #ifdef TRACE_ARCH_TIMER 25 # define TRACE(x) dprintf x 26 #else 27 # define TRACE(x) ; 28 #endif 29 30 31 #define PXA_TIMERS_PHYS_BASE 0x40A00000 32 #define PXA_TIMERS_SIZE 0x000000C0 33 #define PXA_TIMERS_INTERRUPT 7 /* OST_4_11 */ 34 35 #define PXA_OSSR 0x05 36 #define PXA_OIER 0x07 37 #define PXA_OSCR4 0x10 38 #define PXA_OSMR4 0x20 39 #define PXA_OMCR4 0x30 40 41 42 static area_id sPxaTimersArea; 43 static uint32 *sPxaTimersBase; 44 45 46 static int32 47 pxa_timer_interrupt(void *data) 48 { 49 int32 ret = timer_interrupt(); 50 sPxaTimersBase[PXA_OSSR] |= (1 << 4); 51 52 return ret; 53 } 54 55 56 void 57 arch_timer_set_hardware_timer(bigtime_t timeout) 58 { 59 TRACE(("arch_timer_set_hardware_timer(%lld)\n", timeout)); 60 61 if (sPxaTimersBase) { 62 sPxaTimersBase[PXA_OIER] |= (1 << 4); 63 sPxaTimersBase[PXA_OMCR4] = 4; // set to exactly single milisecond resolution 64 sPxaTimersBase[PXA_OSMR4] = timeout; 65 sPxaTimersBase[PXA_OSCR4] = 0; // start counting from 0 again 66 } 67 } 68 69 70 void 71 arch_timer_clear_hardware_timer() 72 { 73 TRACE(("arch_timer_clear_hardware_timer\n")); 74 75 if (sPxaTimersBase) { 76 sPxaTimersBase[PXA_OMCR4] = 0; // disable our timer 77 sPxaTimersBase[PXA_OIER] &= ~(4 << 1); 78 } 79 } 80 81 82 int 83 arch_init_timer(kernel_args *args) 84 { 85 sPxaTimersArea = map_physical_memory("pxa_timers", PXA_TIMERS_PHYS_BASE, 86 PXA_TIMERS_SIZE, 0, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, (void**)&sPxaTimersBase); 87 88 if (sPxaTimersArea < 0) 89 return sPxaTimersArea; 90 91 sPxaTimersBase[PXA_OMCR4] = 0; // disable our timer 92 93 install_io_interrupt_handler(PXA_TIMERS_INTERRUPT, &pxa_timer_interrupt, NULL, 0); 94 95 return B_OK; 96 } 97