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