* RTC can now be set to a new date.
Thanks to Ryo Shimizu for sending in a patch. * Use proper G2 bus space functions to enforce locking protocol.
This commit is contained in:
parent
a8f065cf19
commit
c17ec7adc5
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: clock_machdep.c,v 1.2 2003/07/15 01:31:41 lukem Exp $ */
|
||||
/* $NetBSD: clock_machdep.c,v 1.3 2003/08/07 23:14:13 marcus Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2002 The NetBSD Foundation, Inc.
|
||||
|
@ -34,7 +34,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: clock_machdep.c,v 1.2 2003/07/15 01:31:41 lukem Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: clock_machdep.c,v 1.3 2003/08/07 23:14:13 marcus Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -42,19 +42,22 @@ __KERNEL_RCSID(0, "$NetBSD: clock_machdep.c,v 1.2 2003/07/15 01:31:41 lukem Exp
|
|||
#include <dev/clock_subr.h>
|
||||
#include <sh3/clock.h>
|
||||
|
||||
#include <dreamcast/dev/g2/g2busvar.h>
|
||||
|
||||
#ifdef DEBUG
|
||||
#define STATIC
|
||||
#else
|
||||
#define STATIC static
|
||||
#endif
|
||||
|
||||
#define DREAMCAST_RTC 0xa0710000
|
||||
#define DREAMCAST_RTC 0x00710000
|
||||
|
||||
STATIC void dreamcast_rtc_init(void *);
|
||||
STATIC void dreamcast_rtc_get(void *, time_t, struct clock_ymdhms *);
|
||||
STATIC void dreamcast_rtc_set(void *, struct clock_ymdhms *);
|
||||
|
||||
STATIC u_int32_t dreamcast_read_rtc(void);
|
||||
STATIC void dreamcast_write_rtc(u_int32_t);
|
||||
|
||||
STATIC struct rtc_ops dreamcast_rtc_ops = {
|
||||
.init = dreamcast_rtc_init,
|
||||
|
@ -62,6 +65,9 @@ STATIC struct rtc_ops dreamcast_rtc_ops = {
|
|||
.set = dreamcast_rtc_set
|
||||
};
|
||||
|
||||
static bus_space_tag_t rtc_tag;
|
||||
static bus_space_handle_t rtc_handle;
|
||||
|
||||
void
|
||||
machine_clock_init()
|
||||
{
|
||||
|
@ -72,7 +78,20 @@ machine_clock_init()
|
|||
void
|
||||
dreamcast_rtc_init(void *cookie)
|
||||
{
|
||||
/* Nothing to do */
|
||||
struct device *dv;
|
||||
|
||||
/* Find g2bus device */
|
||||
for (dv = TAILQ_FIRST(&alldevs); dv != NULL;
|
||||
dv = TAILQ_NEXT(dv, dv_list))
|
||||
if (!strcmp(dv->dv_xname, "g2bus0"))
|
||||
break;
|
||||
|
||||
if (!dv)
|
||||
panic("No g2bus!");
|
||||
|
||||
rtc_tag = &((struct g2bus_softc *)dv)->sc_memt;
|
||||
|
||||
bus_space_map(rtc_tag, DREAMCAST_RTC, 12, 0, &rtc_handle);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -86,19 +105,21 @@ void
|
|||
dreamcast_rtc_set(void *cookie, struct clock_ymdhms *dt)
|
||||
{
|
||||
|
||||
/* Not suppoted */
|
||||
dreamcast_write_rtc(clock_ymdhms_to_secs(dt));
|
||||
}
|
||||
|
||||
u_int32_t
|
||||
dreamcast_read_rtc()
|
||||
{
|
||||
__volatile__ u_int32_t *rtc = (__volatile__ u_int32_t *)DREAMCAST_RTC;
|
||||
u_int32_t new, old;
|
||||
int i;
|
||||
|
||||
for (old = 0;;) {
|
||||
for (i = 0; i < 3; i++) {
|
||||
new = ((rtc[0] & 0xffff) << 16) | (rtc[1] & 0xffff);
|
||||
new = ((bus_space_read_4(rtc_tag, rtc_handle, 0)
|
||||
& 0xffff) << 16)
|
||||
| (bus_space_read_4(rtc_tag, rtc_handle, 4)
|
||||
& 0xffff);
|
||||
if (new != old)
|
||||
break;
|
||||
}
|
||||
|
@ -111,3 +132,33 @@ dreamcast_read_rtc()
|
|||
/* offset 20 years */
|
||||
return (new - 631152000);
|
||||
}
|
||||
|
||||
void
|
||||
dreamcast_write_rtc(u_int32_t secs)
|
||||
{
|
||||
u_int32_t new;
|
||||
int i, retry;
|
||||
|
||||
/* offset 20 years */
|
||||
secs += 631152000;
|
||||
|
||||
for (retry = 0; retry < 5; retry++) {
|
||||
|
||||
/* Don't change an order */
|
||||
bus_space_write_4(rtc_tag, rtc_handle, 8, 1);
|
||||
bus_space_write_4(rtc_tag, rtc_handle, 4, secs & 0xffff);
|
||||
bus_space_write_4(rtc_tag, rtc_handle, 0, secs >> 16);
|
||||
|
||||
/* verify */
|
||||
for (i = 0; i < 3; i++) {
|
||||
new = ((bus_space_read_4(rtc_tag, rtc_handle, 0)
|
||||
& 0xffff) << 16)
|
||||
| (bus_space_read_4(rtc_tag, rtc_handle, 4)
|
||||
& 0xffff);
|
||||
if (new == secs)
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* set failure. but nothing to do */
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue