OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [rc203soc/] [sw/] [uClinux/] [arch/] [armnommu/] [kernel/] [time.c] - Diff between revs 1765 and 1782

Only display areas with differences | Details | Blame | View Log

Rev 1765 Rev 1782
/*
/*
 *  linux/arch/arm/kernel/time.c
 *  linux/arch/arm/kernel/time.c
 *
 *
 *  Copyright (C) 1991, 1992, 1995  Linus Torvalds
 *  Copyright (C) 1991, 1992, 1995  Linus Torvalds
 *  Modifications for ARM (C) 1994, 1995, 1996,1997 Russell King
 *  Modifications for ARM (C) 1994, 1995, 1996,1997 Russell King
 *
 *
 * This file contains the ARM-specific time handling details:
 * This file contains the ARM-specific time handling details:
 * reading the RTC at bootup, etc...
 * reading the RTC at bootup, etc...
 *
 *
 * 1994-07-02  Alan Modra
 * 1994-07-02  Alan Modra
 *             fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime
 *             fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime
 * 1997-09-10  Updated NTP code according to technical memorandum Jan '96
 * 1997-09-10  Updated NTP code according to technical memorandum Jan '96
 *             "A Kernel Model for Precision Timekeeping" by Dave Mills
 *             "A Kernel Model for Precision Timekeeping" by Dave Mills
 */
 */
#include <linux/errno.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/param.h>
#include <linux/param.h>
#include <linux/string.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/interrupt.h>
 
 
#include <asm/segment.h>
#include <asm/segment.h>
#include <asm/io.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/irq.h>
 
 
#include <linux/timex.h>
#include <linux/timex.h>
#include <asm/hardware.h>
#include <asm/hardware.h>
 
 
#ifndef BCD_TO_BIN
#ifndef BCD_TO_BIN
#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
#endif
#endif
 
 
#ifndef BIN_TO_BCD
#ifndef BIN_TO_BCD
#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
#endif
#endif
 
 
#define DEBUG 1
#define DEBUG 1
 
 
/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
 * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
 * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
 * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
 * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
 *
 *
 * [For the Julian calendar (which was used in Russia before 1917,
 * [For the Julian calendar (which was used in Russia before 1917,
 * Britain & colonies before 1752, anywhere else before 1582,
 * Britain & colonies before 1752, anywhere else before 1582,
 * and is still in use by some communities) leave out the
 * and is still in use by some communities) leave out the
 * -year/100+year/400 terms, and add 10.]
 * -year/100+year/400 terms, and add 10.]
 *
 *
 * This algorithm was first published by Gauss (I think).
 * This algorithm was first published by Gauss (I think).
 *
 *
 * WARNING: this function will overflow on 2106-02-07 06:28:16 on
 * WARNING: this function will overflow on 2106-02-07 06:28:16 on
 * machines were long is 32-bit! (However, as time_t is signed, we
 * machines were long is 32-bit! (However, as time_t is signed, we
 * will already get problems at other places on 2038-01-19 03:14:08)
 * will already get problems at other places on 2038-01-19 03:14:08)
 */
 */
static inline unsigned long mktime(unsigned int year, unsigned int mon,
static inline unsigned long mktime(unsigned int year, unsigned int mon,
        unsigned int day, unsigned int hour,
        unsigned int day, unsigned int hour,
        unsigned int min, unsigned int sec)
        unsigned int min, unsigned int sec)
{
{
        if (0 >= (int) (mon -= 2)) {     /* 1..12 -> 11,12,1..10 */
        if (0 >= (int) (mon -= 2)) {     /* 1..12 -> 11,12,1..10 */
                mon += 12;      /* Puts Feb last since it has leap day */
                mon += 12;      /* Puts Feb last since it has leap day */
                year -= 1;
                year -= 1;
        }
        }
        return (((
        return (((
                    (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) +
                    (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) +
                      year*365 - 719499
                      year*365 - 719499
                    )*24 + hour /* now have hours */
                    )*24 + hour /* now have hours */
                   )*60 + min /* now have minutes */
                   )*60 + min /* now have minutes */
                  )*60 + sec; /* finally seconds */
                  )*60 + sec; /* finally seconds */
}
}
 
 
#include <asm/arch/time.h>
#include <asm/arch/time.h>
 
 
static unsigned long do_gettimeoffset(void)
static unsigned long do_gettimeoffset(void)
{
{
 
 
        return gettimeoffset ();
        return gettimeoffset ();
}
}
 
 
void do_gettimeofday(struct timeval *tv)
void do_gettimeofday(struct timeval *tv)
{
{
        unsigned long flags;
        unsigned long flags;
 
 
        save_flags_cli (flags);
        save_flags_cli (flags);
        *tv = xtime;
        *tv = xtime;
        tv->tv_usec += do_gettimeoffset();
        tv->tv_usec += do_gettimeoffset();
        if (tv->tv_usec >= 1000000) {
        if (tv->tv_usec >= 1000000) {
                tv->tv_usec -= 1000000;
                tv->tv_usec -= 1000000;
                tv->tv_sec++;
                tv->tv_sec++;
        }
        }
        restore_flags(flags);
        restore_flags(flags);
}
}
 
 
void do_settimeofday(struct timeval *tv)
void do_settimeofday(struct timeval *tv)
{
{
        cli ();
        cli ();
        /* This is revolting. We need to set the xtime.tv_usec
        /* This is revolting. We need to set the xtime.tv_usec
         * correctly. However, the value in this location is
         * correctly. However, the value in this location is
         * is value at the last tick.
         * is value at the last tick.
         * Discover what correction gettimeofday
         * Discover what correction gettimeofday
         * would have done, and then undo it!
         * would have done, and then undo it!
         */
         */
        tv->tv_usec -= do_gettimeoffset();
        tv->tv_usec -= do_gettimeoffset();
 
 
        if (tv->tv_usec < 0) {
        if (tv->tv_usec < 0) {
                tv->tv_usec += 1000000;
                tv->tv_usec += 1000000;
                tv->tv_sec--;
                tv->tv_sec--;
        }
        }
 
 
        xtime = *tv;
        xtime = *tv;
        time_adjust = 0;         /* stop active adjtime() */
        time_adjust = 0;         /* stop active adjtime() */
        time_status |= STA_UNSYNC;
        time_status |= STA_UNSYNC;
        time_state = TIME_ERROR;        /* p. 24, (a) */
        time_state = TIME_ERROR;        /* p. 24, (a) */
        time_maxerror = NTP_PHASE_LIMIT;
        time_maxerror = NTP_PHASE_LIMIT;
        time_esterror = NTP_PHASE_LIMIT;
        time_esterror = NTP_PHASE_LIMIT;
        sti ();
        sti ();
}
}
 
 
/*
/*
 * timer_interrupt() needs to keep up the real-time clock,
 * timer_interrupt() needs to keep up the real-time clock,
 * as well as call the "do_timer()" routine every clocktick.
 * as well as call the "do_timer()" routine every clocktick.
 */
 */
static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
{
        if (reset_timer ())
        if (reset_timer ())
                do_timer(regs);
                do_timer(regs);
 
 
        update_rtc ();
        update_rtc ();
}
}
 
 
static struct irqaction irqtimer1 = { timer_interrupt, 0, 0, "timer", NULL, NULL};
static struct irqaction irqtimer1 = { timer_interrupt, 0, 0, "timer", NULL, NULL};
 
 
extern int setup_arm_irq(int, struct irqaction *);
extern int setup_arm_irq(int, struct irqaction *);
 
 
#ifdef DEBUG
#ifdef DEBUG
unsigned long arch_setup_timer (void)
unsigned long arch_setup_timer (void)
{
{
        register volatile struct trio_timers* tt = (struct trio_timers*) (PERIPH_BASE+TC_OFFSET);
        register volatile struct trio_timers* tt = (struct trio_timers*) (PERIPH_BASE+TC_OFFSET);
        register volatile struct trio_timer_channel* tc = &tt->chans[1].ch;
        register volatile struct trio_timer_channel* tc = &tt->chans[1].ch;
        unsigned long v;
        unsigned long v;
 
 
 
 
 
 
        /* program NO signal on XC1 */
        /* program NO signal on XC1 */
        v = tt->bcr;
        v = tt->bcr;
        v = (v & ~(3 << 2)) | (1 << 2);
        v = (v & ~(3 << 2)) | (1 << 2);
        tt->bcr = v;
        tt->bcr = v;
 
 
        tc->ccr = 0x20;  /* disable the channel */
        tc->ccr = 0x20;  /* disable the channel */
 
 
        /* select ACLK/128 as inupt frequensy for TC1 and enable CPCTRG */
        /* select ACLK/128 as inupt frequensy for TC1 and enable CPCTRG */
        tc->cmr = 3 | (1 << 14);
        tc->cmr = 3 | (1 << 14);
 
 
        tc->idr = ~0ul;  /* disable all interrupt */
        tc->idr = ~0ul;  /* disable all interrupt */
        tc->rc = ((ARM_CLK/128)/HZ - 1);   /* load the count limit into the CR register */
        tc->rc = ((ARM_CLK/128)/HZ - 1);   /* load the count limit into the CR register */
        tc->ier = TC_CPCS;  /* enable CPCS interrupt */
        tc->ier = TC_CPCS;  /* enable CPCS interrupt */
 
 
        /* enable the channel */
        /* enable the channel */
        tc->ccr = TC_SWTRG|TC_CLKEN;
        tc->ccr = TC_SWTRG|TC_CLKEN;
 
 
        return mktime(1999, 11, 1, 0, 0, 0);
        return mktime(1999, 11, 1, 0, 0, 0);
 
 
 
 
}
}
 
 
#define setup_timer arch_setup_timer
#define setup_timer arch_setup_timer
#endif
#endif
 
 
 
 
void time_init(void)
void time_init(void)
{
{
        xtime.tv_sec = setup_timer();
        xtime.tv_sec = setup_timer();
        xtime.tv_usec = 0;
        xtime.tv_usec = 0;
 
 
        setup_arm_irq(IRQ_TC1, &irqtimer1);
        setup_arm_irq(IRQ_TC1, &irqtimer1);
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.