118cb3fafSGreg Ungerer /***************************************************************************/ 218cb3fafSGreg Ungerer 318cb3fafSGreg Ungerer /* 418cb3fafSGreg Ungerer * timers.c - Generic hardware timer support. 518cb3fafSGreg Ungerer * 618cb3fafSGreg Ungerer * Copyright (C) 1993 Hamish Macdonald 718cb3fafSGreg Ungerer * Copyright (C) 1999 D. Jeff Dionne 818cb3fafSGreg Ungerer * Copyright (C) 2001 Georges Menie, Ken Desmet 918cb3fafSGreg Ungerer * 1018cb3fafSGreg Ungerer * This file is subject to the terms and conditions of the GNU General Public 1118cb3fafSGreg Ungerer * License. See the file COPYING in the main directory of this archive 1218cb3fafSGreg Ungerer * for more details. 1318cb3fafSGreg Ungerer */ 1418cb3fafSGreg Ungerer 1518cb3fafSGreg Ungerer /***************************************************************************/ 1618cb3fafSGreg Ungerer 1718cb3fafSGreg Ungerer #include <linux/types.h> 1818cb3fafSGreg Ungerer #include <linux/kernel.h> 1918cb3fafSGreg Ungerer #include <linux/mm.h> 2018cb3fafSGreg Ungerer #include <linux/interrupt.h> 2118cb3fafSGreg Ungerer #include <linux/irq.h> 2218cb3fafSGreg Ungerer #include <linux/clocksource.h> 2318cb3fafSGreg Ungerer #include <linux/rtc.h> 2418cb3fafSGreg Ungerer #include <asm/setup.h> 2518cb3fafSGreg Ungerer #include <asm/pgtable.h> 2618cb3fafSGreg Ungerer #include <asm/machdep.h> 2718cb3fafSGreg Ungerer #include <asm/MC68VZ328.h> 2818cb3fafSGreg Ungerer 2918cb3fafSGreg Ungerer /***************************************************************************/ 3018cb3fafSGreg Ungerer 3118cb3fafSGreg Ungerer #if defined(CONFIG_DRAGEN2) 3218cb3fafSGreg Ungerer /* with a 33.16 MHz clock, this will give usec resolution to the time functions */ 3318cb3fafSGreg Ungerer #define CLOCK_SOURCE TCTL_CLKSOURCE_SYSCLK 3418cb3fafSGreg Ungerer #define CLOCK_PRE 7 3518cb3fafSGreg Ungerer #define TICKS_PER_JIFFY 41450 3618cb3fafSGreg Ungerer 3718cb3fafSGreg Ungerer #elif defined(CONFIG_XCOPILOT_BUGS) 3818cb3fafSGreg Ungerer /* 3918cb3fafSGreg Ungerer * The only thing I know is that CLK32 is not available on Xcopilot 4018cb3fafSGreg Ungerer * I have little idea about what frequency SYSCLK has on Xcopilot. 4118cb3fafSGreg Ungerer * The values for prescaler and compare registers were simply 4218cb3fafSGreg Ungerer * taken from the original source 4318cb3fafSGreg Ungerer */ 4418cb3fafSGreg Ungerer #define CLOCK_SOURCE TCTL_CLKSOURCE_SYSCLK 4518cb3fafSGreg Ungerer #define CLOCK_PRE 2 4618cb3fafSGreg Ungerer #define TICKS_PER_JIFFY 0xd7e4 4718cb3fafSGreg Ungerer 4818cb3fafSGreg Ungerer #else 4918cb3fafSGreg Ungerer /* default to using the 32Khz clock */ 5018cb3fafSGreg Ungerer #define CLOCK_SOURCE TCTL_CLKSOURCE_32KHZ 5118cb3fafSGreg Ungerer #define CLOCK_PRE 31 5218cb3fafSGreg Ungerer #define TICKS_PER_JIFFY 10 5318cb3fafSGreg Ungerer #endif 5418cb3fafSGreg Ungerer 5518cb3fafSGreg Ungerer static u32 m68328_tick_cnt; 5618cb3fafSGreg Ungerer static irq_handler_t timer_interrupt; 5718cb3fafSGreg Ungerer 5818cb3fafSGreg Ungerer /***************************************************************************/ 5918cb3fafSGreg Ungerer 6018cb3fafSGreg Ungerer static irqreturn_t hw_tick(int irq, void *dummy) 6118cb3fafSGreg Ungerer { 6218cb3fafSGreg Ungerer /* Reset Timer1 */ 6318cb3fafSGreg Ungerer TSTAT &= 0; 6418cb3fafSGreg Ungerer 6518cb3fafSGreg Ungerer m68328_tick_cnt += TICKS_PER_JIFFY; 6618cb3fafSGreg Ungerer return timer_interrupt(irq, dummy); 6718cb3fafSGreg Ungerer } 6818cb3fafSGreg Ungerer 6918cb3fafSGreg Ungerer /***************************************************************************/ 7018cb3fafSGreg Ungerer 7118cb3fafSGreg Ungerer static struct irqaction m68328_timer_irq = { 7218cb3fafSGreg Ungerer .name = "timer", 7318cb3fafSGreg Ungerer .flags = IRQF_TIMER, 7418cb3fafSGreg Ungerer .handler = hw_tick, 7518cb3fafSGreg Ungerer }; 7618cb3fafSGreg Ungerer 7718cb3fafSGreg Ungerer /***************************************************************************/ 7818cb3fafSGreg Ungerer 79a5a1d1c2SThomas Gleixner static u64 m68328_read_clk(struct clocksource *cs) 8018cb3fafSGreg Ungerer { 8118cb3fafSGreg Ungerer unsigned long flags; 8218cb3fafSGreg Ungerer u32 cycles; 8318cb3fafSGreg Ungerer 8418cb3fafSGreg Ungerer local_irq_save(flags); 8518cb3fafSGreg Ungerer cycles = m68328_tick_cnt + TCN; 8618cb3fafSGreg Ungerer local_irq_restore(flags); 8718cb3fafSGreg Ungerer 8818cb3fafSGreg Ungerer return cycles; 8918cb3fafSGreg Ungerer } 9018cb3fafSGreg Ungerer 9118cb3fafSGreg Ungerer /***************************************************************************/ 9218cb3fafSGreg Ungerer 9318cb3fafSGreg Ungerer static struct clocksource m68328_clk = { 9418cb3fafSGreg Ungerer .name = "timer", 9518cb3fafSGreg Ungerer .rating = 250, 9618cb3fafSGreg Ungerer .read = m68328_read_clk, 9718cb3fafSGreg Ungerer .mask = CLOCKSOURCE_MASK(32), 9818cb3fafSGreg Ungerer .flags = CLOCK_SOURCE_IS_CONTINUOUS, 9918cb3fafSGreg Ungerer }; 10018cb3fafSGreg Ungerer 10118cb3fafSGreg Ungerer /***************************************************************************/ 10218cb3fafSGreg Ungerer 10318cb3fafSGreg Ungerer void hw_timer_init(irq_handler_t handler) 10418cb3fafSGreg Ungerer { 10518cb3fafSGreg Ungerer /* disable timer 1 */ 10618cb3fafSGreg Ungerer TCTL = 0; 10718cb3fafSGreg Ungerer 10818cb3fafSGreg Ungerer /* set ISR */ 10918cb3fafSGreg Ungerer setup_irq(TMR_IRQ_NUM, &m68328_timer_irq); 11018cb3fafSGreg Ungerer 11118cb3fafSGreg Ungerer /* Restart mode, Enable int, Set clock source */ 11218cb3fafSGreg Ungerer TCTL = TCTL_OM | TCTL_IRQEN | CLOCK_SOURCE; 11318cb3fafSGreg Ungerer TPRER = CLOCK_PRE; 11418cb3fafSGreg Ungerer TCMP = TICKS_PER_JIFFY; 11518cb3fafSGreg Ungerer 11618cb3fafSGreg Ungerer /* Enable timer 1 */ 11718cb3fafSGreg Ungerer TCTL |= TCTL_TEN; 11818cb3fafSGreg Ungerer clocksource_register_hz(&m68328_clk, TICKS_PER_JIFFY*HZ); 11918cb3fafSGreg Ungerer timer_interrupt = handler; 12018cb3fafSGreg Ungerer } 12118cb3fafSGreg Ungerer 12218cb3fafSGreg Ungerer /***************************************************************************/ 12318cb3fafSGreg Ungerer 12418cb3fafSGreg Ungerer int m68328_hwclk(int set, struct rtc_time *t) 12518cb3fafSGreg Ungerer { 12618cb3fafSGreg Ungerer if (!set) { 12718cb3fafSGreg Ungerer long now = RTCTIME; 12818cb3fafSGreg Ungerer t->tm_year = t->tm_mon = t->tm_mday = 1; 12918cb3fafSGreg Ungerer t->tm_hour = (now >> 24) % 24; 13018cb3fafSGreg Ungerer t->tm_min = (now >> 16) % 60; 13118cb3fafSGreg Ungerer t->tm_sec = now % 60; 13218cb3fafSGreg Ungerer } 13318cb3fafSGreg Ungerer 13418cb3fafSGreg Ungerer return 0; 13518cb3fafSGreg Ungerer } 13618cb3fafSGreg Ungerer 13718cb3fafSGreg Ungerer /***************************************************************************/ 138