1 /* $NetBSD: acpipmtimer.c,v 1.4 2007/10/19 11:59:44 ad Exp $ */ 2 3 #include <sys/cdefs.h> 4 __KERNEL_RCSID(0, "$NetBSD: acpipmtimer.c,v 1.4 2007/10/19 11:59:44 ad Exp $"); 5 6 #include <sys/types.h> 7 8 #ifdef __HAVE_TIMECOUNTER 9 10 #include <sys/systm.h> 11 #include <sys/device.h> 12 #include <sys/malloc.h> 13 #include <sys/bus.h> 14 #include <sys/time.h> 15 #include <sys/timetc.h> 16 17 #include <dev/ic/acpipmtimer.h> 18 19 #define ACPI_PM_TIMER_FREQUENCY 3579545 20 21 struct hwtc { 22 struct timecounter tc; 23 bus_space_tag_t t; 24 bus_space_handle_t h; 25 bus_size_t off; 26 }; 27 28 static u_int acpihwtimer_read_safe(struct timecounter *); 29 static u_int acpihwtimer_read_fast(struct timecounter *); 30 31 int 32 acpipmtimer_attach(struct device *dev, 33 bus_space_tag_t t, bus_space_handle_t h, bus_size_t off, 34 int flags) 35 { 36 struct hwtc *tc; 37 38 tc = malloc(sizeof(struct hwtc), M_DEVBUF, M_WAITOK|M_ZERO); 39 if (!tc) 40 return (-1); 41 42 tc->tc.tc_name = dev->dv_xname; 43 tc->tc.tc_frequency = ACPI_PM_TIMER_FREQUENCY; 44 if (flags & ACPIPMT_32BIT) 45 tc->tc.tc_counter_mask = 0xffffffff; 46 else 47 tc->tc.tc_counter_mask = 0x00ffffff; 48 if (flags & ACPIPMT_BADLATCH) { 49 tc->tc.tc_get_timecount = acpihwtimer_read_safe; 50 tc->tc.tc_quality = 900; 51 } else { 52 tc->tc.tc_get_timecount = acpihwtimer_read_fast; 53 tc->tc.tc_quality = 1000; 54 } 55 56 tc->t = t; 57 tc->h = h; 58 tc->off = off; 59 60 tc->tc.tc_priv = tc; 61 tc_init(&tc->tc); 62 aprint_normal("%s: %d-bit timer\n", tc->tc.tc_name, 63 (flags & ACPIPMT_32BIT ? 32 : 24)); 64 return (0); 65 } 66 67 #define r(h) bus_space_read_4(h->t, h->h, h->off) 68 69 static u_int 70 acpihwtimer_read_safe(struct timecounter *tc) 71 { 72 struct hwtc *h = tc->tc_priv; 73 uint32_t t1, t2, t3; 74 75 t2 = r(h); 76 t3 = r(h); 77 do { 78 t1 = t2; 79 t2 = t3; 80 t3 = r(h); 81 } while ((t1 > t2) || (t2 > t3)); 82 return (t2); 83 } 84 85 static u_int 86 acpihwtimer_read_fast(struct timecounter *tc) 87 { 88 struct hwtc *h = tc->tc_priv; 89 90 return r(h); 91 } 92 93 #endif 94