1239478Sadrian/*-
2239478Sadrian * Copyright (C) 2012 Margarida Gouveia
3239478Sadrian * All rights reserved.
4239478Sadrian *
5239478Sadrian * Redistribution and use in source and binary forms, with or without
6239478Sadrian * modification, are permitted provided that the following conditions
7239478Sadrian * are met:
8239478Sadrian * 1. Redistributions of source code must retain the above copyright
9239478Sadrian *    notice, this list of conditions and the following disclaimer,
10239478Sadrian *    without modification, immediately at the beginning of the file.
11239478Sadrian * 2. Redistributions in binary form must reproduce the above copyright
12239478Sadrian *    notice, this list of conditions and the following disclaimer in the
13239478Sadrian *    documentation and/or other materials provided with the distribution.
14239478Sadrian *
15239478Sadrian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16239478Sadrian * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17239478Sadrian * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18239478Sadrian * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19239478Sadrian * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20239478Sadrian * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21239478Sadrian * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22239478Sadrian * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23239478Sadrian * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24239478Sadrian * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25239478Sadrian */
26239478Sadrian#include <sys/cdefs.h>
27239478Sadrian__FBSDID("$FreeBSD$");
28239478Sadrian
29239478Sadrian#include <sys/param.h>
30239478Sadrian#include <sys/systm.h>
31239478Sadrian#include <sys/kernel.h>
32239478Sadrian#include <sys/bus.h>
33239478Sadrian#include <sys/pcpu.h>
34239478Sadrian#include <sys/proc.h>
35239478Sadrian#include <sys/reboot.h>
36239478Sadrian#include <sys/smp.h>
37239478Sadrian#include <sys/fbio.h>
38239478Sadrian
39239478Sadrian#include <vm/vm.h>
40239478Sadrian#include <vm/pmap.h>
41239478Sadrian
42239478Sadrian#include <machine/bus.h>
43239478Sadrian#include <machine/cpu.h>
44239478Sadrian#include <machine/hid.h>
45239478Sadrian#include <machine/platform.h>
46239478Sadrian#include <machine/platformvar.h>
47239478Sadrian#include <machine/pmap.h>
48239478Sadrian#include <machine/smp.h>
49239478Sadrian#include <machine/spr.h>
50239478Sadrian#include <machine/vmparam.h>
51239478Sadrian
52239478Sadrian#include <powerpc/wii/wii_fbreg.h>
53241861Srpaulo#include <powerpc/wii/wii_ipcreg.h>
54239478Sadrian
55239478Sadrian#include "platform_if.h"
56239478Sadrian
57239478Sadrianstatic int		wii_probe(platform_t);
58239478Sadrianstatic int		wii_attach(platform_t);
59266020Sianstatic void		wii_mem_regions(platform_t, struct mem_region *,
60266020Sian			    int *, struct mem_region *, int *);
61249973Srpaulostatic unsigned long	wii_timebase_freq(platform_t, struct cpuref *);
62239478Sadrianstatic void		wii_reset(platform_t);
63249973Srpaulostatic void		wii_cpu_idle(sbintime_t);
64239478Sadrian
65249973Srpauloextern void		 wiibus_reset_system(void);
66249973Srpaulo
67239478Sadrianstatic platform_method_t wii_methods[] = {
68239478Sadrian	PLATFORMMETHOD(platform_probe,		wii_probe),
69239478Sadrian	PLATFORMMETHOD(platform_attach,		wii_attach),
70239478Sadrian	PLATFORMMETHOD(platform_mem_regions,	wii_mem_regions),
71239478Sadrian	PLATFORMMETHOD(platform_timebase_freq,	wii_timebase_freq),
72239478Sadrian	PLATFORMMETHOD(platform_reset,		wii_reset),
73239478Sadrian
74246732Srpaulo	PLATFORMMETHOD_END
75239478Sadrian};
76239478Sadrian
77239478Sadrianstatic platform_def_t wii_platform = {
78239478Sadrian	"wii",
79239478Sadrian	wii_methods,
80239478Sadrian	0
81239478Sadrian};
82239478Sadrian
83239478SadrianPLATFORM_DEF(wii_platform);
84239478Sadrian
85239478Sadrianstatic int
86239478Sadrianwii_probe(platform_t plat)
87239478Sadrian{
88239478Sadrian	register_t vers = mfpvr();
89239478Sadrian
90239478Sadrian	/*
91239478Sadrian	 * The Wii includes a PowerPC 750CL with custom modifications
92239478Sadrian	 * ("Broadway").
93239478Sadrian	 * For now, we just assume that if we are running on a
94239478Sadrian	 * PowerPC 750CL, then this platform is a Nintendo Wii.
95239478Sadrian	 */
96239478Sadrian	if ((vers & 0xfffff0e0) == (MPC750 << 16 | MPC750CL))
97239478Sadrian		return (BUS_PROBE_SPECIFIC);
98239478Sadrian
99239478Sadrian	return (ENXIO);
100239478Sadrian}
101239478Sadrian
102239478Sadrianstatic int
103239478Sadrianwii_attach(platform_t plat)
104239478Sadrian{
105239478Sadrian	cpu_idle_hook = wii_cpu_idle;
106239478Sadrian
107239478Sadrian	return (0);
108239478Sadrian}
109239478Sadrian
110239478Sadrianstatic void
111266020Sianwii_mem_regions(platform_t plat, struct mem_region *phys, int *physsz,
112266020Sian    struct mem_region *avail_regions, int *availsz)
113239478Sadrian{
114239478Sadrian	/* 24MB 1T-SRAM */
115239478Sadrian	avail_regions[0].mr_start = 0x00000000;
116241861Srpaulo	avail_regions[0].mr_size  = 0x01800000;
117239478Sadrian
118239478Sadrian	/*
119239478Sadrian	 * Reserve space for the framebuffer which is located
120239478Sadrian	 * at the end of this 24MB memory region. See wii_fbreg.h.
121239478Sadrian	 */
122239478Sadrian	avail_regions[0].mr_size -= WIIFB_FB_LEN;
123239478Sadrian
124239478Sadrian	/* 64MB GDDR3 SDRAM */
125241861Srpaulo	avail_regions[1].mr_start = 0x10000000;
126241861Srpaulo	avail_regions[1].mr_size  = 0x04000000;
127239478Sadrian
128241861Srpaulo	/*
129241861Srpaulo	 * Reserve space for the DSP.
130241861Srpaulo	 */
131241861Srpaulo	avail_regions[1].mr_start += 0x4000;
132241861Srpaulo	avail_regions[1].mr_size -= 0x4000;
133239478Sadrian
134241861Srpaulo	/*
135241861Srpaulo	 * Reserve space for the IOS I/O memory.
136241861Srpaulo	 */
137241861Srpaulo	avail_regions[1].mr_size -= WIIIPC_IOH_LEN + 1;
138241861Srpaulo
139266020Sian	memcpy(phys, avail_regions, 2*sizeof(*avail_regions));
140266020Sian	*physsz = *availsz = 2;
141239478Sadrian}
142239478Sadrian
143239478Sadrianstatic u_long
144239478Sadrianwii_timebase_freq(platform_t plat, struct cpuref *cpuref)
145239478Sadrian{
146239478Sadrian
147239478Sadrian	/* Bus Frequency (243MHz) / 4 */
148239478Sadrian	return (60750000);
149239478Sadrian}
150239478Sadrian
151239478Sadrianstatic void
152249973Srpaulowii_reset(platform_t plat __unused)
153239478Sadrian{
154249973Srpaulo
155249973Srpaulo	wiibus_reset_system();
156239478Sadrian}
157239478Sadrian
158239478Sadrianstatic void
159247454Sdavidewii_cpu_idle(sbintime_t sbt)
160239478Sadrian{
161239478Sadrian}
162