From da2014a2b080e7f3024a4eb6917d47069ad9620b Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 29 Jul 2008 21:01:19 +0900 Subject: sh: Shuffle the board directories in to mach groups. This flattens out the board directories in to individual mach groups, we will use this for getting rid of unneeded directories, simplifying the build system, and becoming more coherent with the refactored arch/sh/include topology. Signed-off-by: Paul Mundt --- arch/sh/boards/mach-dreamcast/rtc.c | 81 +++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 arch/sh/boards/mach-dreamcast/rtc.c (limited to 'arch/sh/boards/mach-dreamcast/rtc.c') diff --git a/arch/sh/boards/mach-dreamcast/rtc.c b/arch/sh/boards/mach-dreamcast/rtc.c new file mode 100644 index 000000000000..a7433685798d --- /dev/null +++ b/arch/sh/boards/mach-dreamcast/rtc.c @@ -0,0 +1,81 @@ +/* + * arch/sh/boards/dreamcast/rtc.c + * + * Dreamcast AICA RTC routines. + * + * Copyright (c) 2001, 2002 M. R. Brown + * Copyright (c) 2002 Paul Mundt + * + * Released under the terms of the GNU GPL v2.0. + * + */ + +#include +#include +#include + +/* The AICA RTC has an Epoch of 1/1/1950, so we must subtract 20 years (in + seconds) to get the standard Unix Epoch when getting the time, and add + 20 years when setting the time. */ +#define TWENTY_YEARS ((20 * 365LU + 5) * 86400) + +/* The AICA RTC is represented by a 32-bit seconds counter stored in 2 16-bit + registers.*/ +#define AICA_RTC_SECS_H 0xa0710000 +#define AICA_RTC_SECS_L 0xa0710004 + +/** + * aica_rtc_gettimeofday - Get the time from the AICA RTC + * @ts: pointer to resulting timespec + * + * Grabs the current RTC seconds counter and adjusts it to the Unix Epoch. + */ +static void aica_rtc_gettimeofday(struct timespec *ts) +{ + unsigned long val1, val2; + + do { + val1 = ((ctrl_inl(AICA_RTC_SECS_H) & 0xffff) << 16) | + (ctrl_inl(AICA_RTC_SECS_L) & 0xffff); + + val2 = ((ctrl_inl(AICA_RTC_SECS_H) & 0xffff) << 16) | + (ctrl_inl(AICA_RTC_SECS_L) & 0xffff); + } while (val1 != val2); + + ts->tv_sec = val1 - TWENTY_YEARS; + + /* Can't get nanoseconds with just a seconds counter. */ + ts->tv_nsec = 0; +} + +/** + * aica_rtc_settimeofday - Set the AICA RTC to the current time + * @secs: contains the time_t to set + * + * Adjusts the given @tv to the AICA Epoch and sets the RTC seconds counter. + */ +static int aica_rtc_settimeofday(const time_t secs) +{ + unsigned long val1, val2; + unsigned long adj = secs + TWENTY_YEARS; + + do { + ctrl_outl((adj & 0xffff0000) >> 16, AICA_RTC_SECS_H); + ctrl_outl((adj & 0xffff), AICA_RTC_SECS_L); + + val1 = ((ctrl_inl(AICA_RTC_SECS_H) & 0xffff) << 16) | + (ctrl_inl(AICA_RTC_SECS_L) & 0xffff); + + val2 = ((ctrl_inl(AICA_RTC_SECS_H) & 0xffff) << 16) | + (ctrl_inl(AICA_RTC_SECS_L) & 0xffff); + } while (val1 != val2); + + return 0; +} + +void aica_time_init(void) +{ + rtc_sh_get_time = aica_rtc_gettimeofday; + rtc_sh_set_time = aica_rtc_settimeofday; +} + -- cgit v1.2.3