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