14247417dSYoichi Yuasa /* 24247417dSYoichi Yuasa * DEC I/O ASIC's counter clocksource 34247417dSYoichi Yuasa * 4ada8e951SYoichi Yuasa * Copyright (C) 2008 Yoichi Yuasa <yuasa@linux-mips.org> 54247417dSYoichi Yuasa * 64247417dSYoichi Yuasa * This program is free software; you can redistribute it and/or modify 74247417dSYoichi Yuasa * it under the terms of the GNU General Public License as published by 84247417dSYoichi Yuasa * the Free Software Foundation; either version 2 of the License, or 94247417dSYoichi Yuasa * (at your option) any later version. 104247417dSYoichi Yuasa * 114247417dSYoichi Yuasa * This program is distributed in the hope that it will be useful, 124247417dSYoichi Yuasa * but WITHOUT ANY WARRANTY; without even the implied warranty of 134247417dSYoichi Yuasa * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 144247417dSYoichi Yuasa * GNU General Public License for more details. 154247417dSYoichi Yuasa */ 164247417dSYoichi Yuasa #include <linux/clocksource.h> 177cb24b70SDeng-Cheng Zhu #include <linux/sched_clock.h> 184247417dSYoichi Yuasa #include <linux/init.h> 194247417dSYoichi Yuasa 204247417dSYoichi Yuasa #include <asm/ds1287.h> 214247417dSYoichi Yuasa #include <asm/time.h> 224247417dSYoichi Yuasa #include <asm/dec/ioasic.h> 234247417dSYoichi Yuasa #include <asm/dec/ioasic_addrs.h> 244247417dSYoichi Yuasa 25a5a1d1c2SThomas Gleixner static u64 dec_ioasic_hpt_read(struct clocksource *cs) 264247417dSYoichi Yuasa { 274247417dSYoichi Yuasa return ioasic_read(IO_REG_FCTR); 284247417dSYoichi Yuasa } 294247417dSYoichi Yuasa 304247417dSYoichi Yuasa static struct clocksource clocksource_dec = { 314247417dSYoichi Yuasa .name = "dec-ioasic", 324247417dSYoichi Yuasa .read = dec_ioasic_hpt_read, 334247417dSYoichi Yuasa .mask = CLOCKSOURCE_MASK(32), 344247417dSYoichi Yuasa .flags = CLOCK_SOURCE_IS_CONTINUOUS, 354247417dSYoichi Yuasa }; 364247417dSYoichi Yuasa 377cb24b70SDeng-Cheng Zhu static u64 notrace dec_ioasic_read_sched_clock(void) 387cb24b70SDeng-Cheng Zhu { 397cb24b70SDeng-Cheng Zhu return ioasic_read(IO_REG_FCTR); 407cb24b70SDeng-Cheng Zhu } 417cb24b70SDeng-Cheng Zhu 42daed1285SMaciej W. Rozycki int __init dec_ioasic_clocksource_init(void) 434247417dSYoichi Yuasa { 444247417dSYoichi Yuasa unsigned int freq; 454247417dSYoichi Yuasa u32 start, end; 468533966aSMaciej W. Rozycki int i = HZ / 8; 474247417dSYoichi Yuasa 488533966aSMaciej W. Rozycki ds1287_timer_state(); 494247417dSYoichi Yuasa while (!ds1287_timer_state()) 504247417dSYoichi Yuasa ; 514247417dSYoichi Yuasa 528e19608eSMagnus Damm start = dec_ioasic_hpt_read(&clocksource_dec); 534247417dSYoichi Yuasa 544247417dSYoichi Yuasa while (i--) 554247417dSYoichi Yuasa while (!ds1287_timer_state()) 564247417dSYoichi Yuasa ; 574247417dSYoichi Yuasa 588e19608eSMagnus Damm end = dec_ioasic_hpt_read(&clocksource_dec); 594247417dSYoichi Yuasa 608533966aSMaciej W. Rozycki freq = (end - start) * 8; 61daed1285SMaciej W. Rozycki 62daed1285SMaciej W. Rozycki /* An early revision of the I/O ASIC didn't have the counter. */ 63daed1285SMaciej W. Rozycki if (!freq) 64daed1285SMaciej W. Rozycki return -ENXIO; 65daed1285SMaciej W. Rozycki 664247417dSYoichi Yuasa printk(KERN_INFO "I/O ASIC clock frequency %dHz\n", freq); 674247417dSYoichi Yuasa 684247417dSYoichi Yuasa clocksource_dec.rating = 200 + freq / 10000000; 6975c4fd8cSJohn Stultz clocksource_register_hz(&clocksource_dec, freq); 707cb24b70SDeng-Cheng Zhu 717cb24b70SDeng-Cheng Zhu sched_clock_register(dec_ioasic_read_sched_clock, 32, freq); 727cb24b70SDeng-Cheng Zhu 73daed1285SMaciej W. Rozycki return 0; 744247417dSYoichi Yuasa } 75