aboutsummaryrefslogtreecommitdiff
path: root/sys/powerpc
diff options
context:
space:
mode:
authorRui Paulo <rpaulo@FreeBSD.org>2013-04-27 06:54:49 +0000
committerRui Paulo <rpaulo@FreeBSD.org>2013-04-27 06:54:49 +0000
commit276ea50a4511454a6e11541c16520ed6ff8e95a9 (patch)
treeb575f11aa2b95288d9dcce71bc5b991e11a155dc /sys/powerpc
parent2bc87cacee9208d9fa18eb8e39c9f07e5fee32e6 (diff)
downloadsrc-276ea50a4511454a6e11541c16520ed6ff8e95a9.tar.gz
src-276ea50a4511454a6e11541c16520ed6ff8e95a9.zip
Add reset support to the Wii.
Notes
Notes: svn path=/head/; revision=249973
Diffstat (limited to 'sys/powerpc')
-rw-r--r--sys/powerpc/wii/platform_wii.c10
-rw-r--r--sys/powerpc/wii/wii_bus.c53
2 files changed, 55 insertions, 8 deletions
diff --git a/sys/powerpc/wii/platform_wii.c b/sys/powerpc/wii/platform_wii.c
index bc35105c0db0..f43ee9198066 100644
--- a/sys/powerpc/wii/platform_wii.c
+++ b/sys/powerpc/wii/platform_wii.c
@@ -58,9 +58,11 @@ static int wii_probe(platform_t);
static int wii_attach(platform_t);
static void wii_mem_regions(platform_t, struct mem_region **,
int *, struct mem_region **, int *);
-static unsigned long wii_timebase_freq(platform_t, struct cpuref *cpuref);
+static unsigned long wii_timebase_freq(platform_t, struct cpuref *);
static void wii_reset(platform_t);
-static void wii_cpu_idle(sbintime_t sbt);
+static void wii_cpu_idle(sbintime_t);
+
+extern void wiibus_reset_system(void);
static platform_method_t wii_methods[] = {
PLATFORMMETHOD(platform_probe, wii_probe),
@@ -150,8 +152,10 @@ wii_timebase_freq(platform_t plat, struct cpuref *cpuref)
}
static void
-wii_reset(platform_t plat)
+wii_reset(platform_t plat __unused)
{
+
+ wiibus_reset_system();
}
static void
diff --git a/sys/powerpc/wii/wii_bus.c b/sys/powerpc/wii/wii_bus.c
index 52779884ea64..e836529176c5 100644
--- a/sys/powerpc/wii/wii_bus.c
+++ b/sys/powerpc/wii/wii_bus.c
@@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
#include <machine/platform.h>
#include <machine/pmap.h>
#include <machine/resource.h>
+#include <machine/platformvar.h>
#include <powerpc/wii/wii_picreg.h>
#include <powerpc/wii/wii_fbreg.h>
@@ -51,6 +52,21 @@ __FBSDID("$FreeBSD$");
#include <powerpc/wii/wii_ipcreg.h>
#include <powerpc/wii/wii_gpioreg.h>
+#define WIIBUS_CSR_ADDR 0x0d800100
+#define WIIBUS_CSR_LEN 0x300
+#define WIIBUS_CSR_RESET 0x94
+
+struct wiibus_softc {
+ device_t sc_dev;
+ struct rman sc_rman;
+ bus_space_tag_t sc_tag;
+ bus_space_handle_t sc_handle;
+};
+
+static struct wiibus_softc *wiibus_sc = NULL;
+
+static uint32_t wiibus_csr_read(struct wiibus_softc *, uint16_t);
+static void wiibus_csr_write(struct wiibus_softc *, uint16_t, uint32_t);
static void wiibus_identify(driver_t *, device_t);
static int wiibus_probe(device_t);
static int wiibus_attach(device_t);
@@ -61,6 +77,7 @@ static struct resource *
unsigned int);
static int wiibus_activate_resource(device_t, device_t, int, int,
struct resource *);
+ void wiibus_reset_system(void);
static device_method_t wiibus_methods[] = {
/* Device interface */
@@ -79,11 +96,6 @@ static device_method_t wiibus_methods[] = {
DEVMETHOD_END
};
-struct wiibus_softc {
- device_t sc_dev;
- struct rman sc_rman;
-};
-
static MALLOC_DEFINE(M_WIIBUS, "wiibus", "Nintendo Wii system bus");
struct wiibus_devinfo {
@@ -101,6 +113,21 @@ static devclass_t wiibus_devclass;
DRIVER_MODULE(wiibus, nexus, wiibus_driver, wiibus_devclass, 0, 0);
+static uint32_t
+wiibus_csr_read(struct wiibus_softc *sc, uint16_t reg)
+{
+
+ return (bus_space_read_4(sc->sc_tag, sc->sc_handle, reg));
+}
+
+static void
+wiibus_csr_write(struct wiibus_softc *sc, uint16_t reg,
+ uint32_t val)
+{
+
+ bus_space_write_4(sc->sc_tag, sc->sc_handle, reg, val);
+}
+
static void
wiibus_identify(driver_t *driver, device_t parent)
{
@@ -153,6 +180,8 @@ wiibus_attach(device_t self)
sc->sc_rman.rm_type = RMAN_ARRAY;
sc->sc_rman.rm_descr = "Wii Bus Memory Mapped I/O";
rman_init(&sc->sc_rman);
+ KASSERT(wiibus_sc == NULL, ("wiibus_sc already initialised"));
+ wiibus_sc = sc;
/* Nintendo PIC */
dinfo = malloc(sizeof(*dinfo), M_WIIBUS, M_WAITOK | M_ZERO);
@@ -193,6 +222,11 @@ wiibus_attach(device_t self)
cdev = BUS_ADD_CHILD(self, 0, "wiigpio", 0);
device_set_ivars(cdev, dinfo);
+ /* The control registers */
+ sc->sc_tag = &bs_be_tag;
+ sc->sc_handle = (bus_space_handle_t)pmap_mapdev(WIIBUS_CSR_ADDR,
+ WIIBUS_CSR_LEN);
+
return (bus_generic_attach(self));
}
@@ -295,3 +329,12 @@ wiibus_activate_resource(device_t bus, device_t child, int type, int rid,
return (rman_activate_resource(res));
}
+void
+wiibus_reset_system(void)
+{
+ uint32_t r;
+
+ r = wiibus_csr_read(wiibus_sc, WIIBUS_CSR_RESET);
+ r &= ~1;
+ wiibus_csr_write(wiibus_sc, WIIBUS_CSR_RESET, r);
+}