/***************************************************************************/12/*3* timers.c - Generic hardware timer support.4*5* Copyright (C) 1993 Hamish Macdonald6* Copyright (C) 1999 D. Jeff Dionne7* Copyright (C) 2001 Georges Menie, Ken Desmet8*9* This file is subject to the terms and conditions of the GNU General Public10* License. See the file COPYING in the main directory of this archive11* for more details.12*/1314/***************************************************************************/1516#include <linux/types.h>17#include <linux/kernel.h>18#include <linux/mm.h>19#include <linux/interrupt.h>20#include <linux/irq.h>21#include <linux/clocksource.h>22#include <linux/rtc.h>23#include <asm/setup.h>24#include <asm/machdep.h>25#include <asm/MC68VZ328.h>2627#include "m68328.h"2829/***************************************************************************/3031#if defined(CONFIG_DRAGEN2)32/* with a 33.16 MHz clock, this will give usec resolution to the time functions */33#define CLOCK_SOURCE TCTL_CLKSOURCE_SYSCLK34#define CLOCK_PRE 735#define TICKS_PER_JIFFY 414503637#elif defined(CONFIG_XCOPILOT_BUGS)38/*39* The only thing I know is that CLK32 is not available on Xcopilot40* I have little idea about what frequency SYSCLK has on Xcopilot.41* The values for prescaler and compare registers were simply42* taken from the original source43*/44#define CLOCK_SOURCE TCTL_CLKSOURCE_SYSCLK45#define CLOCK_PRE 246#define TICKS_PER_JIFFY 0xd7e44748#else49/* default to using the 32Khz clock */50#define CLOCK_SOURCE TCTL_CLKSOURCE_32KHZ51#define CLOCK_PRE 3152#define TICKS_PER_JIFFY 1053#endif5455static u32 m68328_tick_cnt;5657/***************************************************************************/5859static irqreturn_t hw_tick(int irq, void *dummy)60{61/* Reset Timer1 */62TSTAT &= 0;6364m68328_tick_cnt += TICKS_PER_JIFFY;65legacy_timer_tick(1);66return IRQ_HANDLED;67}6869/***************************************************************************/7071static u64 m68328_read_clk(struct clocksource *cs)72{73unsigned long flags;74u32 cycles;7576local_irq_save(flags);77cycles = m68328_tick_cnt + TCN;78local_irq_restore(flags);7980return cycles;81}8283/***************************************************************************/8485static struct clocksource m68328_clk = {86.name = "timer",87.rating = 250,88.read = m68328_read_clk,89.mask = CLOCKSOURCE_MASK(32),90.flags = CLOCK_SOURCE_IS_CONTINUOUS,91};9293/***************************************************************************/9495void hw_timer_init(void)96{97int ret;9899/* disable timer 1 */100TCTL = 0;101102/* set ISR */103ret = request_irq(TMR_IRQ_NUM, hw_tick, IRQF_TIMER, "timer", NULL);104if (ret) {105pr_err("Failed to request irq %d (timer): %pe\n", TMR_IRQ_NUM,106ERR_PTR(ret));107}108109/* Restart mode, Enable int, Set clock source */110TCTL = TCTL_OM | TCTL_IRQEN | CLOCK_SOURCE;111TPRER = CLOCK_PRE;112TCMP = TICKS_PER_JIFFY;113114/* Enable timer 1 */115TCTL |= TCTL_TEN;116clocksource_register_hz(&m68328_clk, TICKS_PER_JIFFY*HZ);117}118119/***************************************************************************/120121int m68328_hwclk(int set, struct rtc_time *t)122{123if (!set) {124long now = RTCTIME;125t->tm_year = 1;126t->tm_mon = 0;127t->tm_mday = 1;128t->tm_hour = (now >> 24) % 24;129t->tm_min = (now >> 16) % 60;130t->tm_sec = now % 60;131}132133return 0;134}135136/***************************************************************************/137138139