linux/arch/m68k/68000/timers.c
<<
>>
Prefs
   1/***************************************************************************/
   2
   3/*
   4 *  timers.c - Generic hardware timer support.
   5 *
   6 *  Copyright (C) 1993 Hamish Macdonald
   7 *  Copyright (C) 1999 D. Jeff Dionne
   8 *  Copyright (C) 2001 Georges Menie, Ken Desmet
   9 *
  10 * This file is subject to the terms and conditions of the GNU General Public
  11 * License.  See the file COPYING in the main directory of this archive
  12 * for more details.
  13 */
  14
  15/***************************************************************************/
  16
  17#include <linux/types.h>
  18#include <linux/kernel.h>
  19#include <linux/mm.h>
  20#include <linux/interrupt.h>
  21#include <linux/irq.h>
  22#include <linux/clocksource.h>
  23#include <linux/rtc.h>
  24#include <asm/setup.h>
  25#include <asm/pgtable.h>
  26#include <asm/machdep.h>
  27#include <asm/MC68VZ328.h>
  28
  29/***************************************************************************/
  30
  31#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_SYSCLK
  34#define CLOCK_PRE       7
  35#define TICKS_PER_JIFFY 41450
  36
  37#elif defined(CONFIG_XCOPILOT_BUGS)
  38/*
  39 * The only thing I know is that CLK32 is not available on Xcopilot
  40 * I have little idea about what frequency SYSCLK has on Xcopilot.
  41 * The values for prescaler and compare registers were simply
  42 * taken from the original source
  43 */
  44#define CLOCK_SOURCE    TCTL_CLKSOURCE_SYSCLK
  45#define CLOCK_PRE       2
  46#define TICKS_PER_JIFFY 0xd7e4
  47
  48#else
  49/* default to using the 32Khz clock */
  50#define CLOCK_SOURCE    TCTL_CLKSOURCE_32KHZ
  51#define CLOCK_PRE       31
  52#define TICKS_PER_JIFFY 10
  53#endif
  54
  55static u32 m68328_tick_cnt;
  56static irq_handler_t timer_interrupt;
  57
  58/***************************************************************************/
  59
  60static irqreturn_t hw_tick(int irq, void *dummy)
  61{
  62        /* Reset Timer1 */
  63        TSTAT &= 0;
  64
  65        m68328_tick_cnt += TICKS_PER_JIFFY;
  66        return timer_interrupt(irq, dummy);
  67}
  68
  69/***************************************************************************/
  70
  71static struct irqaction m68328_timer_irq = {
  72        .name    = "timer",
  73        .flags   = IRQF_TIMER,
  74        .handler = hw_tick,
  75};
  76
  77/***************************************************************************/
  78
  79static u64 m68328_read_clk(struct clocksource *cs)
  80{
  81        unsigned long flags;
  82        u32 cycles;
  83
  84        local_irq_save(flags);
  85        cycles = m68328_tick_cnt + TCN;
  86        local_irq_restore(flags);
  87
  88        return cycles;
  89}
  90
  91/***************************************************************************/
  92
  93static struct clocksource m68328_clk = {
  94        .name   = "timer",
  95        .rating = 250,
  96        .read   = m68328_read_clk,
  97        .mask   = CLOCKSOURCE_MASK(32),
  98        .flags  = CLOCK_SOURCE_IS_CONTINUOUS,
  99};
 100
 101/***************************************************************************/
 102
 103void hw_timer_init(irq_handler_t handler)
 104{
 105        /* disable timer 1 */
 106        TCTL = 0;
 107
 108        /* set ISR */
 109        setup_irq(TMR_IRQ_NUM, &m68328_timer_irq);
 110
 111        /* Restart mode, Enable int, Set clock source */
 112        TCTL = TCTL_OM | TCTL_IRQEN | CLOCK_SOURCE;
 113        TPRER = CLOCK_PRE;
 114        TCMP = TICKS_PER_JIFFY;
 115
 116        /* Enable timer 1 */
 117        TCTL |= TCTL_TEN;
 118        clocksource_register_hz(&m68328_clk, TICKS_PER_JIFFY*HZ);
 119        timer_interrupt = handler;
 120}
 121
 122/***************************************************************************/
 123
 124int m68328_hwclk(int set, struct rtc_time *t)
 125{
 126        if (!set) {
 127                long now = RTCTIME;
 128                t->tm_year = t->tm_mon = t->tm_mday = 1;
 129                t->tm_hour = (now >> 24) % 24;
 130                t->tm_min = (now >> 16) % 60;
 131                t->tm_sec = now % 60;
 132        }
 133
 134        return 0;
 135}
 136
 137/***************************************************************************/
 138