* 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.
|
* Copyright (c) 2002 The NetBSD Foundation, Inc.
|
||||||
|
@ -34,7 +34,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#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/param.h>
|
||||||
#include <sys/systm.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 <dev/clock_subr.h>
|
||||||
#include <sh3/clock.h>
|
#include <sh3/clock.h>
|
||||||
|
|
||||||
|
#include <dreamcast/dev/g2/g2busvar.h>
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
#define STATIC
|
#define STATIC
|
||||||
#else
|
#else
|
||||||
#define STATIC static
|
#define STATIC static
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define DREAMCAST_RTC 0xa0710000
|
#define DREAMCAST_RTC 0x00710000
|
||||||
|
|
||||||
STATIC void dreamcast_rtc_init(void *);
|
STATIC void dreamcast_rtc_init(void *);
|
||||||
STATIC void dreamcast_rtc_get(void *, time_t, struct clock_ymdhms *);
|
STATIC void dreamcast_rtc_get(void *, time_t, struct clock_ymdhms *);
|
||||||
STATIC void dreamcast_rtc_set(void *, struct clock_ymdhms *);
|
STATIC void dreamcast_rtc_set(void *, struct clock_ymdhms *);
|
||||||
|
|
||||||
STATIC u_int32_t dreamcast_read_rtc(void);
|
STATIC u_int32_t dreamcast_read_rtc(void);
|
||||||
|
STATIC void dreamcast_write_rtc(u_int32_t);
|
||||||
|
|
||||||
STATIC struct rtc_ops dreamcast_rtc_ops = {
|
STATIC struct rtc_ops dreamcast_rtc_ops = {
|
||||||
.init = dreamcast_rtc_init,
|
.init = dreamcast_rtc_init,
|
||||||
|
@ -62,6 +65,9 @@ STATIC struct rtc_ops dreamcast_rtc_ops = {
|
||||||
.set = dreamcast_rtc_set
|
.set = dreamcast_rtc_set
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static bus_space_tag_t rtc_tag;
|
||||||
|
static bus_space_handle_t rtc_handle;
|
||||||
|
|
||||||
void
|
void
|
||||||
machine_clock_init()
|
machine_clock_init()
|
||||||
{
|
{
|
||||||
|
@ -72,7 +78,20 @@ machine_clock_init()
|
||||||
void
|
void
|
||||||
dreamcast_rtc_init(void *cookie)
|
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
|
void
|
||||||
|
@ -86,19 +105,21 @@ void
|
||||||
dreamcast_rtc_set(void *cookie, struct clock_ymdhms *dt)
|
dreamcast_rtc_set(void *cookie, struct clock_ymdhms *dt)
|
||||||
{
|
{
|
||||||
|
|
||||||
/* Not suppoted */
|
dreamcast_write_rtc(clock_ymdhms_to_secs(dt));
|
||||||
}
|
}
|
||||||
|
|
||||||
u_int32_t
|
u_int32_t
|
||||||
dreamcast_read_rtc()
|
dreamcast_read_rtc()
|
||||||
{
|
{
|
||||||
__volatile__ u_int32_t *rtc = (__volatile__ u_int32_t *)DREAMCAST_RTC;
|
|
||||||
u_int32_t new, old;
|
u_int32_t new, old;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (old = 0;;) {
|
for (old = 0;;) {
|
||||||
for (i = 0; i < 3; i++) {
|
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)
|
if (new != old)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -111,3 +132,33 @@ dreamcast_read_rtc()
|
||||||
/* offset 20 years */
|
/* offset 20 years */
|
||||||
return (new - 631152000);
|
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