Remove FreeBSD/wii.
This port failed to gain traction and probably only a couple Wii consoles ran FreeBSD all the way to single user mode with an md(4). IPC support was never implemented, so it was impossible to use any peripheral Any further development, if any, will happen at https://github.com/rpaulo/wii. Discussed with: nathanw (a long time ago), jhibbits
This commit is contained in:
parent
eb6368d4f8
commit
29d0137a8d
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=278495
@ -242,9 +242,3 @@ powerpc/psim/iobus.c optional psim
|
||||
powerpc/psim/ata_iobus.c optional ata psim
|
||||
powerpc/psim/openpic_iobus.c optional psim
|
||||
powerpc/psim/uart_iobus.c optional uart psim
|
||||
powerpc/wii/platform_wii.c optional wii
|
||||
powerpc/wii/wii_bus.c optional wii
|
||||
powerpc/wii/wii_pic.c optional wii
|
||||
powerpc/wii/wii_fb.c optional wii
|
||||
powerpc/wii/wii_gpio.c optional wii wiigpio
|
||||
powerpc/wii/wii_ipc.c optional wii
|
||||
|
@ -24,7 +24,6 @@ PS3 opt_platform.h
|
||||
MAMBO
|
||||
PSERIES
|
||||
PSIM
|
||||
WII opt_platform.h
|
||||
|
||||
SC_OFWFB opt_ofwfb.h
|
||||
|
||||
|
@ -118,9 +118,7 @@ __start:
|
||||
bdnz 1b
|
||||
sync
|
||||
isync
|
||||
#ifdef WII
|
||||
#include <powerpc/wii/locore.S>
|
||||
#endif
|
||||
|
||||
/* Zero bss, in case we were started by something unhelpful */
|
||||
li 0,0
|
||||
lis 8,_edata@ha
|
||||
|
@ -260,9 +260,6 @@ powerpc_init(vm_offset_t fdt, vm_offset_t toc, vm_offset_t ofentry, void *mdp)
|
||||
void *kmdp;
|
||||
char *env;
|
||||
register_t msr, scratch;
|
||||
#ifdef WII
|
||||
register_t vers;
|
||||
#endif
|
||||
uint8_t *cache_check;
|
||||
int cacheline_warn;
|
||||
#ifndef __powerpc64__
|
||||
@ -281,16 +278,6 @@ powerpc_init(vm_offset_t fdt, vm_offset_t toc, vm_offset_t ofentry, void *mdp)
|
||||
startkernel = __startkernel;
|
||||
endkernel = __endkernel;
|
||||
|
||||
#ifdef WII
|
||||
/*
|
||||
* The Wii loader doesn't pass us any environment so, mdp
|
||||
* points to garbage at this point. The Wii CPU is a 750CL.
|
||||
*/
|
||||
vers = mfpvr();
|
||||
if ((vers & 0xfffff0e0) == (MPC750 << 16 | MPC750CL))
|
||||
mdp = NULL;
|
||||
#endif
|
||||
|
||||
/* Check for ePAPR loader, which puts a magic value into r6 */
|
||||
if (mdp == (void *)0x65504150)
|
||||
mdp = NULL;
|
||||
@ -513,13 +500,13 @@ powerpc_init(vm_offset_t fdt, vm_offset_t toc, vm_offset_t ofentry, void *mdp)
|
||||
*/
|
||||
|
||||
trap_offset += (size_t)&restorebridgesize;
|
||||
bcopy(&restorebridge, (void *)EXC_RST, trap_offset);
|
||||
bcopy(&restorebridge, (void *)EXC_DSI, trap_offset);
|
||||
bcopy(&restorebridge, (void *)EXC_ALI, trap_offset);
|
||||
bcopy(&restorebridge, (void *)EXC_PGM, trap_offset);
|
||||
bcopy(&restorebridge, (void *)EXC_MCHK, trap_offset);
|
||||
bcopy(&restorebridge, (void *)EXC_TRC, trap_offset);
|
||||
bcopy(&restorebridge, (void *)EXC_BPT, trap_offset);
|
||||
bcopy(&restorebridge, (void *)EXC_RST, trap_offset);
|
||||
bcopy(&restorebridge, (void *)EXC_DSI, trap_offset);
|
||||
bcopy(&restorebridge, (void *)EXC_ALI, trap_offset);
|
||||
bcopy(&restorebridge, (void *)EXC_PGM, trap_offset);
|
||||
bcopy(&restorebridge, (void *)EXC_MCHK, trap_offset);
|
||||
bcopy(&restorebridge, (void *)EXC_TRC, trap_offset);
|
||||
bcopy(&restorebridge, (void *)EXC_BPT, trap_offset);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -560,7 +547,7 @@ powerpc_init(vm_offset_t fdt, vm_offset_t toc, vm_offset_t ofentry, void *mdp)
|
||||
* Restore MSR
|
||||
*/
|
||||
mtmsr(msr);
|
||||
|
||||
|
||||
/* Warn if cachline size was not determined */
|
||||
if (cacheline_warn == 1) {
|
||||
printf("WARNING: cacheline size undetermined, setting to 32\n");
|
||||
@ -569,7 +556,7 @@ powerpc_init(vm_offset_t fdt, vm_offset_t toc, vm_offset_t ofentry, void *mdp)
|
||||
/*
|
||||
* Choose a platform module so we can get the physical memory map.
|
||||
*/
|
||||
|
||||
|
||||
platform_probe_and_attach();
|
||||
|
||||
/*
|
||||
@ -698,7 +685,7 @@ int
|
||||
ptrace_single_step(struct thread *td)
|
||||
{
|
||||
struct trapframe *tf;
|
||||
|
||||
|
||||
tf = td->td_frame;
|
||||
tf->srr1 |= PSL_SE;
|
||||
|
||||
@ -789,7 +776,7 @@ db_trap_glue(struct trapframe *frame)
|
||||
int type = frame->exc;
|
||||
|
||||
/* Ignore DTrace traps. */
|
||||
if (*(uint32_t *)frame->srr0 == EXC_DTRACE)
|
||||
if (*(uint32_t *)frame->srr0 == EXC_DTRACE)
|
||||
return (0);
|
||||
if (type == EXC_PGM && (frame->srr1 & 0x20000)) {
|
||||
type = T_BREAKPOINT;
|
||||
|
@ -420,7 +420,7 @@ static void
|
||||
tlbia(void)
|
||||
{
|
||||
vm_offset_t va;
|
||||
|
||||
|
||||
for (va = 0; va < 0x00040000; va += 0x00001000) {
|
||||
__asm __volatile("tlbie %0" :: "r"(va));
|
||||
powerpc_sync();
|
||||
@ -623,17 +623,8 @@ moea_cpu_bootstrap(mmu_t mmup, int ap)
|
||||
isync();
|
||||
}
|
||||
|
||||
#ifdef WII
|
||||
/*
|
||||
* Special case for the Wii: don't install the PCI BAT.
|
||||
*/
|
||||
if (strcmp(installed_platform(), "wii") != 0) {
|
||||
#endif
|
||||
__asm __volatile("mtdbatu 1,%0" :: "r"(battable[8].batu));
|
||||
__asm __volatile("mtdbatl 1,%0" :: "r"(battable[8].batl));
|
||||
#ifdef WII
|
||||
}
|
||||
#endif
|
||||
__asm __volatile("mtdbatu 1,%0" :: "r"(battable[8].batu));
|
||||
__asm __volatile("mtdbatl 1,%0" :: "r"(battable[8].batl));
|
||||
isync();
|
||||
|
||||
__asm __volatile("mtibatu 1,%0" :: "r"(0));
|
||||
@ -706,15 +697,9 @@ moea_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernelend)
|
||||
:: "r"(battable[0].batu), "r"(battable[0].batl));
|
||||
mtmsr(msr);
|
||||
|
||||
#ifdef WII
|
||||
if (strcmp(installed_platform(), "wii") != 0) {
|
||||
#endif
|
||||
/* map pci space */
|
||||
__asm __volatile("mtdbatu 1,%0" :: "r"(battable[8].batu));
|
||||
__asm __volatile("mtdbatl 1,%0" :: "r"(battable[8].batl));
|
||||
#ifdef WII
|
||||
}
|
||||
#endif
|
||||
/* map pci space */
|
||||
__asm __volatile("mtdbatu 1,%0" :: "r"(battable[8].batu));
|
||||
__asm __volatile("mtdbatl 1,%0" :: "r"(battable[8].batl));
|
||||
isync();
|
||||
|
||||
/* set global direct map flag */
|
||||
@ -885,7 +870,7 @@ moea_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernelend)
|
||||
*/
|
||||
chosen = OF_finddevice("/chosen");
|
||||
if (chosen != -1 && OF_getprop(chosen, "mmu", &mmui, 4) != -1 &&
|
||||
(mmu = OF_instance_to_package(mmui)) != -1 &&
|
||||
(mmu = OF_instance_to_package(mmui)) != -1 &&
|
||||
(sz = OF_getproplen(mmu, "translations")) != -1) {
|
||||
translations = NULL;
|
||||
for (i = 0; phys_avail[i] != 0; i += 2) {
|
||||
@ -917,7 +902,7 @@ moea_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernelend)
|
||||
/* Enter the pages */
|
||||
for (off = 0; off < translations[i].om_len;
|
||||
off += PAGE_SIZE)
|
||||
moea_kenter(mmup, translations[i].om_va + off,
|
||||
moea_kenter(mmup, translations[i].om_va + off,
|
||||
translations[i].om_pa + off);
|
||||
}
|
||||
}
|
||||
@ -1488,7 +1473,7 @@ void
|
||||
moea_kenter_attr(mmu_t mmu, vm_offset_t va, vm_offset_t pa, vm_memattr_t ma)
|
||||
{
|
||||
u_int pte_lo;
|
||||
int error;
|
||||
int error;
|
||||
|
||||
#if 0
|
||||
if (va < VM_MIN_KERNEL_ADDRESS)
|
||||
@ -1637,7 +1622,7 @@ moea_pinit(mmu_t mmu, pmap_t pmap)
|
||||
== NULL) {
|
||||
pmap->pmap_phys = pmap;
|
||||
}
|
||||
|
||||
|
||||
|
||||
mtx_lock(&moea_vsid_mutex);
|
||||
/*
|
||||
@ -1782,7 +1767,7 @@ void
|
||||
moea_release(mmu_t mmu, pmap_t pmap)
|
||||
{
|
||||
int idx, mask;
|
||||
|
||||
|
||||
/*
|
||||
* Free segment register's VSID
|
||||
*/
|
||||
@ -1957,7 +1942,7 @@ moea_pvo_enter(pmap_t pm, uma_zone_t zone, struct pvo_head *pvo_head,
|
||||
} else {
|
||||
if (moea_bpvo_pool_index >= BPVO_POOL_SIZE) {
|
||||
panic("moea_enter: bpvo pool exhausted, %d, %d, %d",
|
||||
moea_bpvo_pool_index, BPVO_POOL_SIZE,
|
||||
moea_bpvo_pool_index, BPVO_POOL_SIZE,
|
||||
BPVO_POOL_SIZE * sizeof(struct pvo_entry));
|
||||
}
|
||||
pvo = &moea_bpvo_pool[moea_bpvo_pool_index];
|
||||
@ -2307,7 +2292,7 @@ moea_pte_spillable_ident(u_int ptegidx)
|
||||
if (!(pt->pte_lo & PTE_REF))
|
||||
return (pvo_walk);
|
||||
}
|
||||
|
||||
|
||||
return (pvo);
|
||||
}
|
||||
|
||||
@ -2504,7 +2489,7 @@ moea_bat_mapped(int idx, vm_offset_t pa, vm_size_t size)
|
||||
*/
|
||||
prot = battable[idx].batl & (BAT_I|BAT_G|BAT_PP_RW);
|
||||
if (prot != (BAT_I|BAT_G|BAT_PP_RW))
|
||||
return (EPERM);
|
||||
return (EPERM);
|
||||
|
||||
/*
|
||||
* The address should be within the BAT range. Assume that the
|
||||
@ -2527,7 +2512,7 @@ moea_dev_direct_mapped(mmu_t mmu, vm_paddr_t pa, vm_size_t size)
|
||||
int i;
|
||||
|
||||
/*
|
||||
* This currently does not work for entries that
|
||||
* This currently does not work for entries that
|
||||
* overlap 256M BAT segments.
|
||||
*/
|
||||
|
||||
@ -2560,7 +2545,7 @@ moea_mapdev_attr(mmu_t mmu, vm_offset_t pa, vm_size_t size, vm_memattr_t ma)
|
||||
ppa = trunc_page(pa);
|
||||
offset = pa & PAGE_MASK;
|
||||
size = roundup(offset + size, PAGE_SIZE);
|
||||
|
||||
|
||||
/*
|
||||
* If the physical address lies within a valid BAT table entry,
|
||||
* return the 1:1 mapping. This currently doesn't work
|
||||
|
@ -24,7 +24,6 @@ options POWERMAC #NewWorld Apple PowerMacs
|
||||
#options PS3 #Sony Playstation 3
|
||||
options PSIM #GDB PSIM ppc simulator
|
||||
options MAMBO #IBM Mambo Full System Simulator
|
||||
#options WII #Nintendo Wii
|
||||
|
||||
options SC_OFWFB # OFW frame buffer
|
||||
|
||||
|
@ -1,110 +0,0 @@
|
||||
#
|
||||
# Custom kernel for the Nintendo Wii.
|
||||
#
|
||||
# $FreeBSD$
|
||||
|
||||
cpu AIM
|
||||
ident WII
|
||||
machine powerpc powerpc
|
||||
|
||||
makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols
|
||||
|
||||
options WII
|
||||
|
||||
options SCHED_ULE #ULE scheduler
|
||||
options PREEMPTION #Enable kernel thread preemption
|
||||
options INET #InterNETworking
|
||||
options INET6 #IPv6 communications protocols
|
||||
options SCTP #Stream Control Transmission Protocol
|
||||
options FFS #Berkeley Fast Filesystem
|
||||
options SOFTUPDATES #Enable FFS soft updates support
|
||||
options UFS_ACL #Support for access control lists
|
||||
options UFS_DIRHASH #Improve performance on big directories
|
||||
options UFS_GJOURNAL #Enable gjournal-based UFS journaling
|
||||
options MD_ROOT #MD is a potential root device
|
||||
options NFSCL #Network Filesystem Client
|
||||
options NFSD #Network Filesystem Server
|
||||
options NFSLOCKD #Network Lock Manager
|
||||
options NFS_ROOT #NFS usable as root device
|
||||
options MSDOSFS #MSDOS Filesystem
|
||||
options CD9660 #ISO 9660 Filesystem
|
||||
options PROCFS #Process filesystem (requires PSEUDOFS)
|
||||
options PSEUDOFS #Pseudo-filesystem framework
|
||||
options GEOM_PART_GPT #GUID Partition Tables.
|
||||
options GEOM_LABEL #Provides labelization
|
||||
options SCSI_DELAY=5000 #Delay (in ms) before probing SCSI
|
||||
options KTRACE #ktrace(1) syscall trace support
|
||||
options STACK #stack(9) support
|
||||
options SYSVSHM #SYSV-style shared memory
|
||||
options SYSVMSG #SYSV-style message queues
|
||||
options SYSVSEM #SYSV-style semaphores
|
||||
options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions
|
||||
#options HWPMC_HOOKS # Necessary kernel hooks for hwpmc(4)
|
||||
options AUDIT # Security event auditing
|
||||
options CAPABILITY_MODE # Capsicum capability mode
|
||||
options CAPABILITIES # Capsicum capabilities
|
||||
options MAC # TrustedBSD MAC Framework
|
||||
options INCLUDE_CONFIG_FILE # Include this file in kernel
|
||||
|
||||
# Debugging support. Always need this:
|
||||
options KDB # Enable kernel debugger support.
|
||||
# For minimum debugger support (stable branch) use:
|
||||
options KDB_TRACE # Print a stack trace for a panic.
|
||||
# For full debugger support use this instead:
|
||||
options DDB #Support DDB
|
||||
#options DEADLKRES #Enable the deadlock resolver
|
||||
options INVARIANTS #Enable calls of extra sanity checking
|
||||
options INVARIANT_SUPPORT #Extra sanity checks of internal structures, required by INVARIANTS
|
||||
options WITNESS #Enable checks to detect deadlocks and cycles
|
||||
options WITNESS_SKIPSPIN #Don't run witness on spinlocks for speed
|
||||
options MALLOC_DEBUG_MAXZONES=8 # Separate malloc(9) zones
|
||||
|
||||
# ATA/SCSI peripherals
|
||||
device scbus # SCSI bus (required for ATA/SCSI)
|
||||
device da # Direct Access (disks)
|
||||
|
||||
# syscons is the default console driver, resembling an SCO console
|
||||
device sc
|
||||
device kbdmux
|
||||
options SC_DFLT_FONT # compile font in
|
||||
makeoptions SC_DFLT_FONT=cp437
|
||||
|
||||
# Pseudo devices.
|
||||
device loop # Network loopback
|
||||
device random # Entropy device
|
||||
device ether # Ethernet support
|
||||
device vlan # 802.1Q VLAN support
|
||||
device tun # Packet tunnel.
|
||||
device md # Memory "disks"
|
||||
device gif # IPv6 and IPv4 tunneling
|
||||
device firmware # firmware assist module
|
||||
|
||||
|
||||
# The `bpf' device enables the Berkeley Packet Filter.
|
||||
# Be aware of the administrative consequences of enabling this!
|
||||
# Note that 'bpf' is required for DHCP.
|
||||
device bpf #Berkeley packet filter
|
||||
|
||||
# USB support
|
||||
options USB_DEBUG # enable debug msgs
|
||||
device uhci # UHCI PCI->USB interface
|
||||
device ohci # OHCI PCI->USB interface
|
||||
device ehci # EHCI PCI->USB interface
|
||||
device usb # USB Bus (required)
|
||||
device uhid # "Human Interface Devices"
|
||||
device ukbd # Keyboard
|
||||
options KBD_INSTALL_CDEV # install a CDEV entry in /dev
|
||||
device ulpt # Printer
|
||||
device umass # Disks/Mass storage - Requires scbus and da0
|
||||
device ums # Mouse
|
||||
# USB Ethernet
|
||||
device miibus # MII bus support
|
||||
device aue # ADMtek USB Ethernet
|
||||
device axe # ASIX Electronics USB Ethernet
|
||||
device cdce # Generic USB over Ethernet
|
||||
device cue # CATC USB Ethernet
|
||||
device kue # Kawasaki LSI USB Ethernet
|
||||
|
||||
# GPIO
|
||||
device gpio
|
||||
device wiigpio
|
@ -412,7 +412,7 @@ ofwfb_init(int unit, video_adapter_t *adp, int flags)
|
||||
adp->va_window = (vm_offset_t) ofwfb_static_window;
|
||||
|
||||
/*
|
||||
* Enable future font-loading and flag color support, as well as
|
||||
* Enable future font-loading and flag color support, as well as
|
||||
* adding V_ADP_MODECHANGE so that we ofwfb_set_mode() gets called
|
||||
* when the X server shuts down. This enables us to get the console
|
||||
* back when X disappears.
|
||||
@ -874,7 +874,7 @@ ofwfb_putc32(video_adapter_t *adp, vm_offset_t off, uint8_t c, uint8_t a)
|
||||
addr = (uint32_t *)sc->sc_addr
|
||||
+ (row + sc->sc_ymargin)*(sc->sc_stride/4)
|
||||
+ col + sc->sc_xmargin;
|
||||
|
||||
|
||||
fg = ofwfb_pix32(sc, ofwfb_foreground(a));
|
||||
bg = ofwfb_pix32(sc, ofwfb_background(a));
|
||||
|
||||
@ -999,12 +999,6 @@ ofwfb_scidentify(driver_t *driver, device_t parent)
|
||||
{
|
||||
device_t child;
|
||||
|
||||
/*
|
||||
* The Nintendo Wii doesn't have open firmware, so don't probe ofwfb
|
||||
* because otherwise we will crash.
|
||||
*/
|
||||
if (strcmp(installed_platform(), "wii") == 0)
|
||||
return;
|
||||
/*
|
||||
* Add with a priority guaranteed to make it last on
|
||||
* the device list
|
||||
@ -1019,7 +1013,7 @@ ofwfb_scprobe(device_t dev)
|
||||
|
||||
device_set_desc(dev, "System console");
|
||||
|
||||
error = sc_probe_unit(device_get_unit(dev),
|
||||
error = sc_probe_unit(device_get_unit(dev),
|
||||
device_get_flags(dev) | SC_AUTODETECT_KBD);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
@ -1,64 +0,0 @@
|
||||
#-
|
||||
# Copyright (c) 2013 Rui Paulo
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
# SUCH DAMAGE.
|
||||
#
|
||||
# $FreeBSD$
|
||||
#
|
||||
|
||||
#include <sys/bus.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
INTERFACE ios;
|
||||
|
||||
METHOD int open {
|
||||
device_t dev;
|
||||
const char *path;
|
||||
int mode;
|
||||
};
|
||||
|
||||
METHOD int close {
|
||||
device_t dev;
|
||||
int fd;
|
||||
};
|
||||
|
||||
METHOD int ioctl {
|
||||
device_t dev;
|
||||
int fd;
|
||||
unsigned int request;
|
||||
void *ibuf;
|
||||
size_t ilen;
|
||||
void *obuf;
|
||||
size_t olen;
|
||||
};
|
||||
|
||||
METHOD int ioctlv {
|
||||
device_t dev;
|
||||
int fd;
|
||||
unsigned int request;
|
||||
struct iovec *in;
|
||||
size_t ilen;
|
||||
struct iovec *out;
|
||||
size_t olen;
|
||||
};
|
||||
|
@ -1,131 +0,0 @@
|
||||
/*-
|
||||
* Copyright (C) 2012 Margarida Gouveia
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <machine/bat.h>
|
||||
/*
|
||||
* When we are invoked from Wii loaders, the state of the MMU and the BAT
|
||||
* mappings can vary. In this file we try to reset the MMU to a state
|
||||
* that lets us boot FreeBSD.
|
||||
*
|
||||
* N.B.: keep the BAT0 in sync with mmu_oea.c and never touch BAT1 later.
|
||||
*
|
||||
* This file is being included from aim/locore32.S.
|
||||
*/
|
||||
|
||||
#define MMU_REALMODE() \
|
||||
mfmsr %r12; \
|
||||
rlwinm %r12, %r12, 0, ~(PSL_DR|PSL_IR);\
|
||||
sync; \
|
||||
bl 1f; \
|
||||
1: \
|
||||
mflr %r11; \
|
||||
clrlwi %r11, %r11, 3; /* XXX why? */ \
|
||||
addi %r11, %r11, 2f - 1b; \
|
||||
mtsrr0 %r11; \
|
||||
mtsrr1 %r12; /* Disables the MMU */ \
|
||||
isync; \
|
||||
rfi; \
|
||||
2:
|
||||
|
||||
#define MMU_VIRTUALMODE() \
|
||||
bl 3f; \
|
||||
3: \
|
||||
mflr %r11; \
|
||||
addi %r11, %r11, 4f - 3b; \
|
||||
mfmsr %r12; \
|
||||
ori %r12, %r12, PSL_DR|PSL_IR; \
|
||||
mtsrr0 %r11; \
|
||||
mtsrr1 %r12; /* Enables the MMU */ \
|
||||
isync; \
|
||||
rfi; \
|
||||
4:
|
||||
|
||||
MMU_REALMODE()
|
||||
|
||||
/* Reset standard BATs */
|
||||
li %r11, 0
|
||||
mtibatu 0, %r11
|
||||
mtibatl 0, %r11
|
||||
mtdbatu 0, %r11
|
||||
mtdbatl 0, %r11
|
||||
mtibatu 1, %r11
|
||||
mtibatl 1, %r11
|
||||
mtdbatu 1, %r11
|
||||
mtdbatl 1, %r11
|
||||
mtibatu 2, %r11
|
||||
mtibatl 2, %r11
|
||||
mtdbatu 2, %r11
|
||||
mtdbatl 2, %r11
|
||||
mtibatu 3, %r11
|
||||
mtibatl 3, %r11
|
||||
mtdbatu 3, %r11
|
||||
mtdbatl 3, %r11
|
||||
|
||||
/* Reset high BATs. IBAT[4-7][UL] + DBAT[4-7][UL] */
|
||||
mtspr 560, %r11
|
||||
mtspr 561, %r11
|
||||
mtspr 562, %r11
|
||||
mtspr 563, %r11
|
||||
mtspr 564, %r11
|
||||
mtspr 565, %r11
|
||||
mtspr 566, %r11
|
||||
mtspr 567, %r11
|
||||
mtspr 568, %r11
|
||||
mtspr 569, %r11
|
||||
mtspr 570, %r11
|
||||
mtspr 571, %r11
|
||||
mtspr 572, %r11
|
||||
mtspr 573, %r11
|
||||
mtspr 574, %r11
|
||||
mtspr 575, %r11
|
||||
|
||||
/*
|
||||
* We need to setup BAT0 as in mmu_oea.c.
|
||||
*/
|
||||
li %r11, BATU(0x00000000, BAT_BL_256M, BAT_Vs)
|
||||
li %r12, BATL(0x00000000, BAT_M, BAT_PP_RW)
|
||||
mtdbatu 0, %r11
|
||||
mtdbatl 0, %r12
|
||||
mtibatu 0, %r11
|
||||
mtibatl 0, %r12
|
||||
isync
|
||||
|
||||
/*
|
||||
* We use BAT1 to be able to write I/O memory, including the
|
||||
* framebuffer registers.
|
||||
*/
|
||||
/* BATU(0x0c000000, BAT_BL_32M, BAT_Vs) */
|
||||
lis %r11, 0x0c00
|
||||
ori %r11, %r11, BAT_BL_32M|BAT_Vs
|
||||
/* BATL(0x0c000000, BAT_I|BAT_G, BAT_PP_RW) */
|
||||
lis %r12, 0x0c00
|
||||
ori %r12, %r12, BAT_I|BAT_G|BAT_PP_RW
|
||||
mtdbatu 1, %r11
|
||||
mtdbatl 1, %r12
|
||||
isync
|
||||
|
||||
MMU_VIRTUALMODE()
|
@ -1,161 +0,0 @@
|
||||
/*-
|
||||
* Copyright (C) 2012 Margarida Gouveia
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer,
|
||||
* without modification, immediately at the beginning of the file.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/pcpu.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/reboot.h>
|
||||
#include <sys/smp.h>
|
||||
#include <sys/fbio.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/pmap.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/hid.h>
|
||||
#include <machine/platform.h>
|
||||
#include <machine/platformvar.h>
|
||||
#include <machine/pmap.h>
|
||||
#include <machine/smp.h>
|
||||
#include <machine/spr.h>
|
||||
#include <machine/vmparam.h>
|
||||
|
||||
#include <powerpc/wii/wii_fbreg.h>
|
||||
#include <powerpc/wii/wii_ipcreg.h>
|
||||
|
||||
#include "platform_if.h"
|
||||
|
||||
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 *);
|
||||
static void wii_reset(platform_t);
|
||||
static void wii_cpu_idle(sbintime_t);
|
||||
|
||||
extern void wiibus_reset_system(void);
|
||||
|
||||
static platform_method_t wii_methods[] = {
|
||||
PLATFORMMETHOD(platform_probe, wii_probe),
|
||||
PLATFORMMETHOD(platform_attach, wii_attach),
|
||||
PLATFORMMETHOD(platform_mem_regions, wii_mem_regions),
|
||||
PLATFORMMETHOD(platform_timebase_freq, wii_timebase_freq),
|
||||
PLATFORMMETHOD(platform_reset, wii_reset),
|
||||
|
||||
PLATFORMMETHOD_END
|
||||
};
|
||||
|
||||
static platform_def_t wii_platform = {
|
||||
"wii",
|
||||
wii_methods,
|
||||
0
|
||||
};
|
||||
|
||||
PLATFORM_DEF(wii_platform);
|
||||
|
||||
static int
|
||||
wii_probe(platform_t plat)
|
||||
{
|
||||
register_t vers = mfpvr();
|
||||
|
||||
/*
|
||||
* The Wii includes a PowerPC 750CL with custom modifications
|
||||
* ("Broadway").
|
||||
* For now, we just assume that if we are running on a
|
||||
* PowerPC 750CL, then this platform is a Nintendo Wii.
|
||||
*/
|
||||
if ((vers & 0xfffff0e0) == (MPC750 << 16 | MPC750CL))
|
||||
return (BUS_PROBE_SPECIFIC);
|
||||
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
static int
|
||||
wii_attach(platform_t plat)
|
||||
{
|
||||
cpu_idle_hook = wii_cpu_idle;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
wii_mem_regions(platform_t plat, struct mem_region *phys, int *physsz,
|
||||
struct mem_region *avail_regions, int *availsz)
|
||||
{
|
||||
/* 24MB 1T-SRAM */
|
||||
avail_regions[0].mr_start = 0x00000000;
|
||||
avail_regions[0].mr_size = 0x01800000;
|
||||
|
||||
/*
|
||||
* Reserve space for the framebuffer which is located
|
||||
* at the end of this 24MB memory region. See wii_fbreg.h.
|
||||
*/
|
||||
avail_regions[0].mr_size -= WIIFB_FB_LEN;
|
||||
|
||||
/* 64MB GDDR3 SDRAM */
|
||||
avail_regions[1].mr_start = 0x10000000;
|
||||
avail_regions[1].mr_size = 0x04000000;
|
||||
|
||||
/*
|
||||
* Reserve space for the DSP.
|
||||
*/
|
||||
avail_regions[1].mr_start += 0x4000;
|
||||
avail_regions[1].mr_size -= 0x4000;
|
||||
|
||||
/*
|
||||
* Reserve space for the IOS I/O memory.
|
||||
*/
|
||||
avail_regions[1].mr_size -= WIIIPC_IOH_LEN + 1;
|
||||
|
||||
memcpy(phys, avail_regions, 2*sizeof(*avail_regions));
|
||||
*physsz = *availsz = 2;
|
||||
}
|
||||
|
||||
static u_long
|
||||
wii_timebase_freq(platform_t plat, struct cpuref *cpuref)
|
||||
{
|
||||
|
||||
/* Bus Frequency (243MHz) / 4 */
|
||||
return (60750000);
|
||||
}
|
||||
|
||||
static void
|
||||
wii_reset(platform_t plat __unused)
|
||||
{
|
||||
|
||||
wiibus_reset_system();
|
||||
}
|
||||
|
||||
static void
|
||||
wii_cpu_idle(sbintime_t sbt)
|
||||
{
|
||||
}
|
@ -1,340 +0,0 @@
|
||||
/*-
|
||||
* Copyright (C) 2012 Margarida Gouveia
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer,
|
||||
* without modification, immediately at the beginning of the file.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/clock.h>
|
||||
#include <sys/cpu.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/pmap.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#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>
|
||||
#include <powerpc/wii/wii_exireg.h>
|
||||
#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);
|
||||
static int wiibus_print_child(device_t, device_t);
|
||||
static struct resource *
|
||||
wiibus_alloc_resource(device_t, device_t, int, int *,
|
||||
unsigned long, unsigned long, unsigned long,
|
||||
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 */
|
||||
DEVMETHOD(device_identify, wiibus_identify),
|
||||
DEVMETHOD(device_probe, wiibus_probe),
|
||||
DEVMETHOD(device_attach, wiibus_attach),
|
||||
|
||||
/* Bus interface */
|
||||
DEVMETHOD(bus_add_child, bus_generic_add_child),
|
||||
DEVMETHOD(bus_print_child, wiibus_print_child),
|
||||
DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
|
||||
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
|
||||
DEVMETHOD(bus_alloc_resource, wiibus_alloc_resource),
|
||||
DEVMETHOD(bus_activate_resource,wiibus_activate_resource),
|
||||
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
static MALLOC_DEFINE(M_WIIBUS, "wiibus", "Nintendo Wii system bus");
|
||||
|
||||
struct wiibus_devinfo {
|
||||
struct resource_list di_resources;
|
||||
uint8_t di_init;
|
||||
};
|
||||
|
||||
static driver_t wiibus_driver = {
|
||||
"wiibus",
|
||||
wiibus_methods,
|
||||
sizeof(struct wiibus_softc)
|
||||
};
|
||||
|
||||
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)
|
||||
{
|
||||
|
||||
if (strcmp(installed_platform(), "wii") != 0)
|
||||
return;
|
||||
|
||||
if (device_find_child(parent, "wiibus", -1) == NULL)
|
||||
BUS_ADD_CHILD(parent, 0, "wiibus", 0);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
wiibus_probe(device_t dev)
|
||||
{
|
||||
|
||||
device_set_desc(dev, "Nintendo Wii System Bus");
|
||||
|
||||
return (BUS_PROBE_NOWILDCARD);
|
||||
}
|
||||
|
||||
static void
|
||||
wiibus_init_device_resources(struct rman *rm, struct wiibus_devinfo *dinfo,
|
||||
unsigned int rid, uintptr_t addr, size_t len, unsigned int irq)
|
||||
|
||||
{
|
||||
|
||||
if (!dinfo->di_init) {
|
||||
resource_list_init(&dinfo->di_resources);
|
||||
dinfo->di_init++;
|
||||
}
|
||||
if (addr) {
|
||||
rman_manage_region(rm, addr, addr + len - 1);
|
||||
resource_list_add(&dinfo->di_resources, SYS_RES_MEMORY, rid,
|
||||
addr, addr + len, len);
|
||||
}
|
||||
if (irq)
|
||||
resource_list_add(&dinfo->di_resources, SYS_RES_IRQ, rid,
|
||||
irq, irq, 1);
|
||||
}
|
||||
|
||||
static int
|
||||
wiibus_attach(device_t self)
|
||||
{
|
||||
struct wiibus_softc *sc;
|
||||
struct wiibus_devinfo *dinfo;
|
||||
device_t cdev;
|
||||
|
||||
sc = device_get_softc(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);
|
||||
wiibus_init_device_resources(&sc->sc_rman, dinfo, 0, WIIPIC_REG_ADDR,
|
||||
WIIPIC_REG_LEN, 1);
|
||||
cdev = BUS_ADD_CHILD(self, 0, "wiipic", 0);
|
||||
device_set_ivars(cdev, dinfo);
|
||||
|
||||
/* Framebuffer */
|
||||
dinfo = malloc(sizeof(*dinfo), M_WIIBUS, M_WAITOK | M_ZERO);
|
||||
wiibus_init_device_resources(&sc->sc_rman, dinfo, 0, WIIFB_REG_ADDR,
|
||||
WIIFB_REG_LEN, 8);
|
||||
wiibus_init_device_resources(&sc->sc_rman, dinfo, 1, WIIFB_FB_ADDR,
|
||||
WIIFB_FB_LEN, 0);
|
||||
cdev = BUS_ADD_CHILD(self, 0, "wiifb", 0);
|
||||
device_set_ivars(cdev, dinfo);
|
||||
|
||||
/* External Interface Bus */
|
||||
dinfo = malloc(sizeof(*dinfo), M_WIIBUS, M_WAITOK | M_ZERO);
|
||||
wiibus_init_device_resources(&sc->sc_rman, dinfo, 0, WIIEXI_REG_ADDR,
|
||||
WIIEXI_REG_LEN, 4);
|
||||
cdev = BUS_ADD_CHILD(self, 0, "wiiexi", 0);
|
||||
device_set_ivars(cdev, dinfo);
|
||||
|
||||
/* Nintendo IOS IPC */
|
||||
dinfo = malloc(sizeof(*dinfo), M_WIIBUS, M_WAITOK | M_ZERO);
|
||||
wiibus_init_device_resources(&sc->sc_rman, dinfo, 0, WIIIPC_REG_ADDR,
|
||||
WIIIPC_REG_LEN, 14);
|
||||
wiibus_init_device_resources(&sc->sc_rman, dinfo, 1, WIIIPC_IOH_ADDR,
|
||||
WIIIPC_IOH_LEN, 0);
|
||||
cdev = BUS_ADD_CHILD(self, 0, "wiiipc", 0);
|
||||
device_set_ivars(cdev, dinfo);
|
||||
|
||||
/* GPIO */
|
||||
dinfo = malloc(sizeof(*dinfo), M_WIIBUS, M_WAITOK | M_ZERO);
|
||||
wiibus_init_device_resources(&sc->sc_rman, dinfo, 0, WIIGPIO_REG_ADDR,
|
||||
WIIGPIO_REG_LEN, 0);
|
||||
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));
|
||||
}
|
||||
|
||||
static int
|
||||
wiibus_print_child(device_t dev, device_t child)
|
||||
{
|
||||
struct wiibus_devinfo *dinfo = device_get_ivars(child);
|
||||
int retval = 0;
|
||||
|
||||
retval += bus_print_child_header(dev, child);
|
||||
retval += resource_list_print_type(&dinfo->di_resources, "mem",
|
||||
SYS_RES_MEMORY, "%#lx");
|
||||
retval += resource_list_print_type(&dinfo->di_resources, "irq",
|
||||
SYS_RES_IRQ, "%ld");
|
||||
retval += bus_print_child_footer(dev, child);
|
||||
|
||||
return (retval);
|
||||
}
|
||||
|
||||
static struct resource *
|
||||
wiibus_alloc_resource(device_t bus, device_t child, int type,
|
||||
int *rid, unsigned long start, unsigned long end,
|
||||
unsigned long count, unsigned int flags)
|
||||
{
|
||||
struct wiibus_softc *sc;
|
||||
struct wiibus_devinfo *dinfo;
|
||||
struct resource_list_entry *rle;
|
||||
struct resource *rv;
|
||||
int needactivate;
|
||||
|
||||
sc = device_get_softc(bus);
|
||||
dinfo = device_get_ivars(child);
|
||||
needactivate = flags & RF_ACTIVE;
|
||||
flags &= ~RF_ACTIVE;
|
||||
|
||||
switch (type) {
|
||||
case SYS_RES_MEMORY:
|
||||
rle = resource_list_find(&dinfo->di_resources, SYS_RES_MEMORY,
|
||||
*rid);
|
||||
if (rle == NULL) {
|
||||
device_printf(bus, "no res entry for %s memory 0x%x\n",
|
||||
device_get_nameunit(child), *rid);
|
||||
return (NULL);
|
||||
}
|
||||
rv = rman_reserve_resource(&sc->sc_rman, rle->start, rle->end,
|
||||
rle->count, flags, child);
|
||||
if (rv == NULL) {
|
||||
device_printf(bus,
|
||||
"failed to reserve resource for %s\n",
|
||||
device_get_nameunit(child));
|
||||
return (NULL);
|
||||
}
|
||||
rman_set_rid(rv, *rid);
|
||||
break;
|
||||
case SYS_RES_IRQ:
|
||||
return (resource_list_alloc(&dinfo->di_resources, bus, child,
|
||||
type, rid, start, end, count, flags));
|
||||
default:
|
||||
device_printf(bus, "unknown resource request from %s\n",
|
||||
device_get_nameunit(child));
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (needactivate) {
|
||||
if (bus_activate_resource(child, type, *rid, rv) != 0) {
|
||||
device_printf(bus,
|
||||
"failed to activate resource for %s\n",
|
||||
device_get_nameunit(child));
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
|
||||
return (rv);
|
||||
}
|
||||
|
||||
static int
|
||||
wiibus_activate_resource(device_t bus, device_t child, int type, int rid,
|
||||
struct resource *res)
|
||||
{
|
||||
void *p;
|
||||
|
||||
switch (type) {
|
||||
case SYS_RES_MEMORY:
|
||||
p = pmap_mapdev(rman_get_start(res), rman_get_size(res));
|
||||
if (p == NULL)
|
||||
return (ENOMEM);
|
||||
rman_set_virtual(res, p);
|
||||
rman_set_bustag(res, &bs_be_tag);
|
||||
rman_set_bushandle(res, (unsigned long)p);
|
||||
break;
|
||||
case SYS_RES_IRQ:
|
||||
return (bus_activate_resource(bus, type, rid, res));
|
||||
default:
|
||||
device_printf(bus,
|
||||
"unknown activate resource request from %s\n",
|
||||
device_get_nameunit(child));
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
/*-
|
||||
* Copyright (C) 2012 Margarida Gouveia
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _POWERPC_WII_WII_EXIREG_H
|
||||
#define _POWERPC_WII_WII_EXIREG_H
|
||||
|
||||
#define WIIEXI_REG_ADDR 0x0d006800
|
||||
#define WIIEXI_REG_LEN 0x40
|
||||
|
||||
#endif /* _POWERPC_WII_WII_IPCREG_H */
|
@ -1,885 +0,0 @@
|
||||
/*-
|
||||
* Copyright (C) 2012 Margarida Gouveia
|
||||
* Copyright (c) 2003 Peter Grehan
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer,
|
||||
* without modification, immediately at the beginning of the file.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/limits.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/cons.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/fbio.h>
|
||||
#include <sys/consio.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/pmap.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/sc_machdep.h>
|
||||
#include <machine/platform.h>
|
||||
#include <machine/pmap.h>
|
||||
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include <dev/fb/fbreg.h>
|
||||
#include <dev/syscons/syscons.h>
|
||||
|
||||
#include <powerpc/wii/wii_fbreg.h>
|
||||
#include <powerpc/wii/wii_fbvar.h>
|
||||
|
||||
/*
|
||||
* Driver for the Nintendo Wii's framebuffer. Based on Linux's gcnfb.c.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Syscons glue.
|
||||
*/
|
||||
static int wiifb_scprobe(device_t);
|
||||
static int wiifb_scattach(device_t);
|
||||
|
||||
static device_method_t wiifb_sc_methods[] = {
|
||||
DEVMETHOD(device_probe, wiifb_scprobe),
|
||||
DEVMETHOD(device_attach, wiifb_scattach),
|
||||
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
static driver_t wiifb_sc_driver = {
|
||||
"wiifb",
|
||||
wiifb_sc_methods,
|
||||
sizeof(sc_softc_t),
|
||||
};
|
||||
|
||||
static devclass_t sc_devclass;
|
||||
|
||||
DRIVER_MODULE(sc, wiibus, wiifb_sc_driver, sc_devclass, 0, 0);
|
||||
|
||||
static int
|
||||
wiifb_scprobe(device_t dev)
|
||||
{
|
||||
int error;
|
||||
|
||||
device_set_desc(dev, "Nintendo Wii frambuffer");
|
||||
|
||||
error = sc_probe_unit(device_get_unit(dev),
|
||||
device_get_flags(dev) | SC_AUTODETECT_KBD);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
/* This is a fake device, so make sure we added it ourselves */
|
||||
return (BUS_PROBE_NOWILDCARD);
|
||||
}
|
||||
|
||||
static int
|
||||
wiifb_scattach(device_t dev)
|
||||
{
|
||||
|
||||
return (sc_attach_unit(device_get_unit(dev),
|
||||
device_get_flags(dev) | SC_AUTODETECT_KBD));
|
||||
}
|
||||
|
||||
/*
|
||||
* Video driver routines and glue.
|
||||
*/
|
||||
static void wiifb_reset_video(struct wiifb_softc *);
|
||||
static void wiifb_enable_interrupts(struct wiifb_softc *);
|
||||
static void wiifb_configure_tv_mode(struct wiifb_softc *);
|
||||
static void wiifb_setup_framebuffer(struct wiifb_softc *);
|
||||
static int wiifb_configure(int);
|
||||
static vi_probe_t wiifb_probe;
|
||||
static vi_init_t wiifb_init;
|
||||
static vi_get_info_t wiifb_get_info;
|
||||
static vi_query_mode_t wiifb_query_mode;
|
||||
static vi_set_mode_t wiifb_set_mode;
|
||||
static vi_save_font_t wiifb_save_font;
|
||||
static vi_load_font_t wiifb_load_font;
|
||||
static vi_show_font_t wiifb_show_font;
|
||||
static vi_save_palette_t wiifb_save_palette;
|
||||
static vi_load_palette_t wiifb_load_palette;
|
||||
static vi_set_border_t wiifb_set_border;
|
||||
static vi_save_state_t wiifb_save_state;
|
||||
static vi_load_state_t wiifb_load_state;
|
||||
static vi_set_win_org_t wiifb_set_win_org;
|
||||
static vi_read_hw_cursor_t wiifb_read_hw_cursor;
|
||||
static vi_set_hw_cursor_t wiifb_set_hw_cursor;
|
||||
static vi_set_hw_cursor_shape_t wiifb_set_hw_cursor_shape;
|
||||
static vi_blank_display_t wiifb_blank_display;
|
||||
static vi_mmap_t wiifb_mmap;
|
||||
static vi_ioctl_t wiifb_ioctl;
|
||||
static vi_clear_t wiifb_clear;
|
||||
static vi_fill_rect_t wiifb_fill_rect;
|
||||
static vi_bitblt_t wiifb_bitblt;
|
||||
static vi_diag_t wiifb_diag;
|
||||
static vi_save_cursor_palette_t wiifb_save_cursor_palette;
|
||||
static vi_load_cursor_palette_t wiifb_load_cursor_palette;
|
||||
static vi_copy_t wiifb_copy;
|
||||
static vi_putp_t wiifb_putp;
|
||||
static vi_putc_t wiifb_putc;
|
||||
static vi_puts_t wiifb_puts;
|
||||
static vi_putm_t wiifb_putm;
|
||||
|
||||
static video_switch_t wiifbvidsw = {
|
||||
.probe = wiifb_probe,
|
||||
.init = wiifb_init,
|
||||
.get_info = wiifb_get_info,
|
||||
.query_mode = wiifb_query_mode,
|
||||
.set_mode = wiifb_set_mode,
|
||||
.save_font = wiifb_save_font,
|
||||
.load_font = wiifb_load_font,
|
||||
.show_font = wiifb_show_font,
|
||||
.save_palette = wiifb_save_palette,
|
||||
.load_palette = wiifb_load_palette,
|
||||
.set_border = wiifb_set_border,
|
||||
.save_state = wiifb_save_state,
|
||||
.load_state = wiifb_load_state,
|
||||
.set_win_org = wiifb_set_win_org,
|
||||
.read_hw_cursor = wiifb_read_hw_cursor,
|
||||
.set_hw_cursor = wiifb_set_hw_cursor,
|
||||
.set_hw_cursor_shape = wiifb_set_hw_cursor_shape,
|
||||
.blank_display = wiifb_blank_display,
|
||||
.mmap = wiifb_mmap,
|
||||
.ioctl = wiifb_ioctl,
|
||||
.clear = wiifb_clear,
|
||||
.fill_rect = wiifb_fill_rect,
|
||||
.bitblt = wiifb_bitblt,
|
||||
.diag = wiifb_diag,
|
||||
.save_cursor_palette = wiifb_save_cursor_palette,
|
||||
.load_cursor_palette = wiifb_load_cursor_palette,
|
||||
.copy = wiifb_copy,
|
||||
.putp = wiifb_putp,
|
||||
.putc = wiifb_putc,
|
||||
.puts = wiifb_puts,
|
||||
.putm = wiifb_putm,
|
||||
};
|
||||
|
||||
VIDEO_DRIVER(wiifb, wiifbvidsw, wiifb_configure);
|
||||
|
||||
extern sc_rndr_sw_t txtrndrsw;
|
||||
RENDERER(wiifb, 0, txtrndrsw, gfb_set);
|
||||
RENDERER_MODULE(wiifb, gfb_set);
|
||||
|
||||
static struct wiifb_softc wiifb_softc;
|
||||
static uint16_t wiifb_static_window[ROW*COL];
|
||||
extern u_char dflt_font_8[];
|
||||
|
||||
/*
|
||||
* Map the syscons colors to YUY2 (Y'UV422).
|
||||
* Some colours are an approximation.
|
||||
*
|
||||
* The Wii has a 16 bit pixel, so each 32 bit DWORD encodes
|
||||
* two pixels. The upper 16 bits is for pixel 0 (left hand pixel
|
||||
* in a pair), the lower 16 bits is for pixel 1.
|
||||
*
|
||||
* For now, we're going to ignore that entirely and just use the
|
||||
* lower 16 bits for each pixel. We'll take the upper value into
|
||||
* account later.
|
||||
*/
|
||||
static uint32_t wiifb_cmap[16] = {
|
||||
0x00800080, /* Black */
|
||||
0x1dff1d6b, /* Blue */
|
||||
0x4b554b4a, /* Green */
|
||||
0x80808080, /* Cyan */
|
||||
0x4c544cff, /* Red */
|
||||
0x3aaa34b5, /* Magenta */
|
||||
0x7140718a, /* Brown */
|
||||
0xff80ff80, /* White */
|
||||
0x80808080, /* Gray */
|
||||
0xc399c36a, /* Bright Blue */
|
||||
0xd076d074, /* Bright Green */
|
||||
0x80808080, /* Bright Cyan */
|
||||
0x4c544cff, /* Bright Red */
|
||||
0x3aaa34b5, /* Bright Magenta */
|
||||
0xe100e194, /* Bright Yellow */
|
||||
0xff80ff80 /* Bright White */
|
||||
};
|
||||
|
||||
static struct wiifb_mode_desc wiifb_modes[] = {
|
||||
[WIIFB_MODE_NTSC_480i] = {
|
||||
"NTSC 480i",
|
||||
640, 480,
|
||||
525,
|
||||
WIIFB_MODE_FLAG_INTERLACED,
|
||||
},
|
||||
[WIIFB_MODE_NTSC_480p] = {
|
||||
"NTSC 480p",
|
||||
640, 480,
|
||||
525,
|
||||
WIIFB_MODE_FLAG_PROGRESSIVE,
|
||||
},
|
||||
[WIIFB_MODE_PAL_576i] = {
|
||||
"PAL 576i (50Hz)",
|
||||
640, 574,
|
||||
625,
|
||||
WIIFB_MODE_FLAG_INTERLACED,
|
||||
},
|
||||
[WIIFB_MODE_PAL_480i] = {
|
||||
"PAL 480i (60Hz)",
|
||||
640, 480,
|
||||
525,
|
||||
WIIFB_MODE_FLAG_INTERLACED,
|
||||
},
|
||||
[WIIFB_MODE_PAL_480p] = {
|
||||
"PAL 480p",
|
||||
640, 480,
|
||||
525,
|
||||
WIIFB_MODE_FLAG_PROGRESSIVE,
|
||||
},
|
||||
};
|
||||
|
||||
static const uint32_t wiifb_filter_coeft[] = {
|
||||
0x1ae771f0, 0x0db4a574, 0x00c1188e, 0xc4c0cbe2, 0xfcecdecf,
|
||||
0x13130f08, 0x00080c0f
|
||||
};
|
||||
|
||||
static __inline int
|
||||
wiifb_background(uint8_t attr)
|
||||
{
|
||||
|
||||
return (attr >> 4);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
wiifb_foreground(uint8_t attr)
|
||||
{
|
||||
|
||||
return (attr & 0x0f);
|
||||
}
|
||||
|
||||
static void
|
||||
wiifb_reset_video(struct wiifb_softc *sc)
|
||||
{
|
||||
struct wiifb_dispcfg dc;
|
||||
|
||||
wiifb_dispcfg_read(sc, &dc);
|
||||
dc.dc_reset = 1;
|
||||
wiifb_dispcfg_write(sc, &dc);
|
||||
dc.dc_reset = 0;
|
||||
wiifb_dispcfg_write(sc, &dc);
|
||||
}
|
||||
|
||||
static void
|
||||
wiifb_enable_interrupts(struct wiifb_softc *sc)
|
||||
{
|
||||
struct wiifb_dispint di;
|
||||
|
||||
#ifdef notyet
|
||||
/*
|
||||
* Display Interrupt 0
|
||||
*/
|
||||
di.di_htiming = 1;
|
||||
di.di_vtiming = 1;
|
||||
di.di_enable = 1;
|
||||
di.di_irq = 1;
|
||||
wiifb_dispint_write(sc, 0, &di);
|
||||
|
||||
/*
|
||||
* Display Interrupt 1
|
||||
*/
|
||||
di.di_htiming = sc->sc_format == WIIFB_FORMAT_PAL ? 433 : 430;
|
||||
di.di_vtiming = sc->sc_mode->fd_lines;
|
||||
di.di_enable = 1;
|
||||
di.di_irq = 1;
|
||||
if (sc->sc_mode->fd_flags & WIIFB_MODE_FLAG_INTERLACED)
|
||||
di.di_vtiming /= 2;
|
||||
wiifb_dispint_write(sc, 1, &di);
|
||||
|
||||
/*
|
||||
* Display Interrupts 2 and 3 are not used.
|
||||
*/
|
||||
memset(&di, 0, sizeof(di));
|
||||
wiifb_dispint_write(sc, 2, &di);
|
||||
wiifb_dispint_write(sc, 3, &di);
|
||||
#else
|
||||
memset(&di, 0, sizeof(di));
|
||||
wiifb_dispint_write(sc, 0, &di);
|
||||
wiifb_dispint_write(sc, 1, &di);
|
||||
wiifb_dispint_write(sc, 2, &di);
|
||||
wiifb_dispint_write(sc, 3, &di);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Reference gcnfb.c for an in depth explanation.
|
||||
* XXX only works with NTSC.
|
||||
*/
|
||||
static void
|
||||
wiifb_configure_tv_mode(struct wiifb_softc *sc)
|
||||
{
|
||||
struct wiifb_vtiming vt;
|
||||
struct wiifb_hscaling hs;
|
||||
struct wiifb_htiming0 ht0;
|
||||
struct wiifb_htiming1 ht1;
|
||||
struct wiifb_vtimingodd vto;
|
||||
struct wiifb_vtimingeven vte;
|
||||
struct wiifb_burstblankodd bbo;
|
||||
struct wiifb_burstblankeven bbe;
|
||||
struct wiifb_picconf pc;
|
||||
struct wiifb_mode_desc *mode = sc->sc_mode;
|
||||
unsigned int height = mode->fd_height;
|
||||
unsigned int width = mode->fd_width;
|
||||
unsigned int eqpulse, interlacebias, shift;
|
||||
const unsigned int maxwidth = 714;
|
||||
unsigned int hblanking = maxwidth - width;
|
||||
unsigned int hmargin = hblanking / 2;
|
||||
unsigned int A = 20 + hmargin, C = 60 + hblanking - hmargin;
|
||||
unsigned int maxheight = 484;
|
||||
unsigned int P = 2 * (20 - 10 + 1);
|
||||
unsigned int Q = 1;
|
||||
unsigned int vblanking = maxheight - height;
|
||||
unsigned int vmargin = vblanking / 2;
|
||||
unsigned int prb = vmargin;
|
||||
unsigned int psb = vblanking - vmargin;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Vertical timing.
|
||||
*/
|
||||
if (mode->fd_flags & WIIFB_MODE_FLAG_INTERLACED) {
|
||||
vt.vt_actvideo = height / 2;
|
||||
interlacebias = 1;
|
||||
shift = 0;
|
||||
} else {
|
||||
vt.vt_actvideo = height;
|
||||
interlacebias = 0;
|
||||
shift = 1;
|
||||
}
|
||||
/* Lines of equalization */
|
||||
if (mode->fd_lines == 625)
|
||||
eqpulse = 2 * 2.5;
|
||||
else
|
||||
eqpulse = 2 * 3;
|
||||
vt.vt_eqpulse = eqpulse << shift;
|
||||
wiifb_vtiming_write(sc, &vt);
|
||||
|
||||
/*
|
||||
* Horizontal timings.
|
||||
*/
|
||||
ht0.ht0_hlinew = 858 / 2;
|
||||
ht1.ht1_hsyncw = 64;
|
||||
ht0.ht0_hcolourstart = 71;
|
||||
ht0.ht0_hcolourend = 71 + 34;
|
||||
ht1.ht1_hblankstart = (858 / 2) - A;
|
||||
ht1.ht1_hblankend = 64 + C;
|
||||
wiifb_htiming0_write(sc, &ht0);
|
||||
wiifb_htiming1_write(sc, &ht1);
|
||||
|
||||
/*
|
||||
* Vertical timing odd/even.
|
||||
*/
|
||||
if (vmargin & 1) {
|
||||
vto.vto_preb = (P + interlacebias + prb) << shift;
|
||||
vto.vto_postb = (Q - interlacebias + psb) << shift;
|
||||
vte.vte_preb = (P + prb) << shift;
|
||||
vte.vte_postb = (Q - psb) << shift;
|
||||
} else {
|
||||
/* XXX if this isn't 0, it doesn't work? */
|
||||
prb = 0;
|
||||
psb = 0;
|
||||
vte.vte_preb = (P + interlacebias + prb) << shift;
|
||||
vte.vte_postb = (Q - interlacebias + psb) << shift;
|
||||
vto.vto_preb = (P + prb) << shift;
|
||||
vto.vto_postb = (Q - psb) << shift;
|
||||
}
|
||||
wiifb_vtimingodd_write(sc, &vto);
|
||||
wiifb_vtimingeven_write(sc, &vte);
|
||||
|
||||
/*
|
||||
* Burst blanking odd/even interval.
|
||||
*/
|
||||
bbo.bbo_bs1 = 2 * (18 - 7 + 1);
|
||||
bbe.bbe_bs2 = bbo.bbo_bs3 = bbe.bbe_bs4 = bbo.bbo_bs1;
|
||||
bbo.bbo_be1 = 2 * (525 - 7 + 1);
|
||||
bbe.bbe_be2 = bbo.bbo_be3 = bbe.bbe_be4 = bbo.bbo_be1;
|
||||
wiifb_burstblankodd_write(sc, &bbo);
|
||||
wiifb_burstblankeven_write(sc, &bbe);
|
||||
|
||||
/*
|
||||
* Picture configuration.
|
||||
*/
|
||||
pc.pc_strides = (mode->fd_width * 2) / 32;
|
||||
if (mode->fd_flags & WIIFB_MODE_FLAG_INTERLACED)
|
||||
pc.pc_strides *= 2;
|
||||
pc.pc_reads = (mode->fd_width * 2) / 32;
|
||||
wiifb_picconf_write(sc, &pc);
|
||||
|
||||
/*
|
||||
* Horizontal scaling disabled.
|
||||
*/
|
||||
hs.hs_enable = 0;
|
||||
hs.hs_step = 256;
|
||||
wiifb_hscaling_write(sc, &hs);
|
||||
|
||||
/*
|
||||
* Filter coeficient table.
|
||||
*/
|
||||
for (i = 0; i < 7; i++)
|
||||
wiifb_filtcoeft_write(sc, i, wiifb_filter_coeft[i]);
|
||||
|
||||
/*
|
||||
* Anti alias.
|
||||
*/
|
||||
wiifb_antialias_write(sc, 0x00ff0000);
|
||||
|
||||
/*
|
||||
* Video clock.
|
||||
*/
|
||||
wiifb_videoclk_write(sc,
|
||||
mode->fd_flags & WIIFB_MODE_FLAG_INTERLACED ? 0 : 1);
|
||||
|
||||
/*
|
||||
* Disable horizontal scaling width.
|
||||
*/
|
||||
wiifb_hscalingw_write(sc, mode->fd_width);
|
||||
|
||||
/*
|
||||
* DEBUG mode borders. Not used.
|
||||
*/
|
||||
wiifb_hborderend_write(sc, 0);
|
||||
wiifb_hborderstart_write(sc, 0);
|
||||
|
||||
/*
|
||||
* XXX unknown registers.
|
||||
*/
|
||||
wiifb_unknown1_write(sc, 0x00ff);
|
||||
wiifb_unknown2_write(sc, 0x00ff00ff);
|
||||
wiifb_unknown3_write(sc, 0x00ff00ff);
|
||||
}
|
||||
|
||||
static void
|
||||
wiifb_setup_framebuffer(struct wiifb_softc *sc)
|
||||
{
|
||||
intptr_t addr = sc->sc_fb_addr;
|
||||
struct wiifb_topfieldbasel tfbl;
|
||||
struct wiifb_bottomfieldbasel bfbl;
|
||||
struct wiifb_topfieldbaser tfbr;
|
||||
struct wiifb_bottomfieldbaser bfbr;
|
||||
|
||||
tfbl.tfbl_fbaddr = addr >> 5;
|
||||
tfbl.tfbl_xoffset = (addr / 2) & 0xf;
|
||||
tfbl.tfbl_pageoffbit = 1;
|
||||
wiifb_topfieldbasel_write(sc, &tfbl);
|
||||
|
||||
if (sc->sc_mode->fd_flags & WIIFB_MODE_FLAG_INTERLACED)
|
||||
addr += sc->sc_mode->fd_width * 2;
|
||||
bfbl.bfbl_fbaddr = addr >> 5;
|
||||
bfbl.bfbl_xoffset = (addr / 2) & 0xf;
|
||||
bfbl.bfbl_pageoffbit = 1;
|
||||
wiifb_bottomfieldbasel_write(sc, &bfbl);
|
||||
|
||||
/*
|
||||
* Only used used for 3D.
|
||||
*/
|
||||
memset(&tfbr, 0, sizeof(tfbr));
|
||||
memset(&bfbr, 0, sizeof(bfbr));
|
||||
wiifb_topfieldbaser_write(sc, &tfbr);
|
||||
wiifb_bottomfieldbaser_write(sc, &bfbr);
|
||||
}
|
||||
|
||||
static int
|
||||
wiifb_configure(int flags)
|
||||
{
|
||||
struct wiifb_softc *sc;
|
||||
struct wiifb_dispcfg dc;
|
||||
int progressive;
|
||||
|
||||
sc = &wiifb_softc;
|
||||
if (sc->sc_initialized) {
|
||||
/* XXX We should instead use bus_space */
|
||||
sc->sc_fb_addr = (intptr_t)pmap_mapdev(WIIFB_FB_ADDR, WIIFB_FB_LEN);
|
||||
sc->sc_reg_addr = (intptr_t)pmap_mapdev(WIIFB_REG_ADDR, WIIFB_REG_LEN);
|
||||
return 0;
|
||||
}
|
||||
|
||||
sc->sc_console = 1;
|
||||
|
||||
sc->sc_fb_addr = WIIFB_FB_ADDR;
|
||||
sc->sc_fb_size = WIIFB_FB_LEN;
|
||||
|
||||
sc->sc_reg_addr = WIIFB_REG_ADDR;
|
||||
sc->sc_reg_size = WIIFB_REG_LEN;
|
||||
|
||||
wiifb_reset_video(sc);
|
||||
wiifb_dispcfg_read(sc, &dc);
|
||||
sc->sc_format = dc.dc_format;
|
||||
sc->sc_component = wiifb_component_enabled(sc);
|
||||
progressive = dc.dc_noninterlaced;
|
||||
switch (sc->sc_format) {
|
||||
case WIIFB_FORMAT_MPAL:
|
||||
case WIIFB_FORMAT_DEBUG:
|
||||
case WIIFB_FORMAT_NTSC:
|
||||
sc->sc_mode = progressive ?
|
||||
&wiifb_modes[WIIFB_MODE_NTSC_480p] :
|
||||
&wiifb_modes[WIIFB_MODE_NTSC_480i];
|
||||
break;
|
||||
case WIIFB_FORMAT_PAL:
|
||||
sc->sc_mode = progressive ?
|
||||
&wiifb_modes[WIIFB_MODE_PAL_480p] :
|
||||
&wiifb_modes[WIIFB_MODE_PAL_480i];
|
||||
break;
|
||||
}
|
||||
sc->sc_height = sc->sc_mode->fd_height;
|
||||
sc->sc_width = sc->sc_mode->fd_width;
|
||||
/* Usually we multiply by 4, but I think this looks better. */
|
||||
sc->sc_stride = sc->sc_width * 2;
|
||||
|
||||
wiifb_init(0, &sc->sc_va, 0);
|
||||
|
||||
sc->sc_initialized = 1;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
wiifb_probe(int unit, video_adapter_t **adp, void *arg, int flags)
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
wiifb_init(int unit, video_adapter_t *adp, int flags)
|
||||
{
|
||||
struct wiifb_softc *sc;
|
||||
video_info_t *vi;
|
||||
|
||||
sc = (struct wiifb_softc *)adp;
|
||||
vi = &adp->va_info;
|
||||
|
||||
vid_init_struct(adp, "wiifb", -1, unit);
|
||||
|
||||
sc->sc_font = dflt_font_8;
|
||||
vi->vi_cheight = WIIFB_FONT_HEIGHT;
|
||||
vi->vi_width = sc->sc_width/8;
|
||||
vi->vi_height = sc->sc_height/vi->vi_cheight;
|
||||
vi->vi_cwidth = 8;
|
||||
|
||||
/*
|
||||
* Clamp width/height to syscons maximums
|
||||
*/
|
||||
if (vi->vi_width > COL)
|
||||
vi->vi_width = COL;
|
||||
if (vi->vi_height > ROW)
|
||||
vi->vi_height = ROW;
|
||||
|
||||
sc->sc_xmargin = (sc->sc_width - (vi->vi_width * vi->vi_cwidth)) / 2;
|
||||
sc->sc_ymargin = (sc->sc_height - (vi->vi_height * vi->vi_cheight))/2;
|
||||
|
||||
adp->va_window = (vm_offset_t) wiifb_static_window;
|
||||
/* XXX no colour support */
|
||||
adp->va_flags |= V_ADP_FONT | /*V_ADP_COLOR |*/ V_ADP_MODECHANGE;
|
||||
|
||||
vid_register(&sc->sc_va);
|
||||
|
||||
wiifb_configure_tv_mode(sc);
|
||||
wiifb_setup_framebuffer(sc);
|
||||
wiifb_enable_interrupts(sc);
|
||||
wiifb_clear(adp);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
wiifb_get_info(video_adapter_t *adp, int mode, video_info_t *info)
|
||||
{
|
||||
|
||||
bcopy(&adp->va_info, info, sizeof(*info));
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
wiifb_query_mode(video_adapter_t *adp, video_info_t *info)
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
wiifb_set_mode(video_adapter_t *adp, int mode)
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
wiifb_save_font(video_adapter_t *adp, int page, int size, int width,
|
||||
u_char *data, int c, int count)
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
wiifb_load_font(video_adapter_t *adp, int page, int size, int width,
|
||||
u_char *data, int c, int count)
|
||||
{
|
||||
struct wiifb_softc *sc = (struct wiifb_softc *)adp;
|
||||
|
||||
sc->sc_font = data;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
wiifb_show_font(video_adapter_t *adp, int page)
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
wiifb_save_palette(video_adapter_t *adp, u_char *palette)
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
wiifb_load_palette(video_adapter_t *adp, u_char *palette)
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
wiifb_set_border(video_adapter_t *adp, int border)
|
||||
{
|
||||
|
||||
return (wiifb_blank_display(adp, border));
|
||||
}
|
||||
|
||||
static int
|
||||
wiifb_save_state(video_adapter_t *adp, void *p, size_t size)
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
wiifb_load_state(video_adapter_t *adp, void *p)
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
wiifb_set_win_org(video_adapter_t *adp, off_t offset)
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
wiifb_read_hw_cursor(video_adapter_t *adp, int *col, int *row)
|
||||
{
|
||||
|
||||
*col = *row = 0;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
wiifb_set_hw_cursor(video_adapter_t *adp, int col, int row)
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
wiifb_set_hw_cursor_shape(video_adapter_t *adp, int base, int height,
|
||||
int celsize, int blink)
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
wiifb_blank_display(video_adapter_t *adp, int mode)
|
||||
{
|
||||
struct wiifb_softc *sc = (struct wiifb_softc *)adp;
|
||||
uint32_t *p;
|
||||
|
||||
for (p = (uint32_t *)sc->sc_fb_addr;
|
||||
p < (uint32_t *)(sc->sc_fb_addr + sc->sc_fb_size);
|
||||
p++)
|
||||
*p = wiifb_cmap[wiifb_background(SC_NORM_ATTR)];
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
wiifb_mmap(video_adapter_t *adp, vm_ooffset_t offset, vm_paddr_t *paddr,
|
||||
int prot, vm_memattr_t *memattr)
|
||||
{
|
||||
struct wiifb_softc *sc;
|
||||
|
||||
sc = (struct wiifb_softc *)adp;
|
||||
|
||||
/*
|
||||
* This might be a legacy VGA mem request: if so, just point it at the
|
||||
* framebuffer, since it shouldn't be touched
|
||||
*/
|
||||
if (offset < sc->sc_stride*sc->sc_height) {
|
||||
*paddr = sc->sc_fb_addr + offset;
|
||||
return (0);
|
||||
}
|
||||
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
static int
|
||||
wiifb_ioctl(video_adapter_t *adp, u_long cmd, caddr_t data)
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
wiifb_clear(video_adapter_t *adp)
|
||||
{
|
||||
|
||||
return (wiifb_blank_display(adp, 0));
|
||||
}
|
||||
|
||||
static int
|
||||
wiifb_fill_rect(video_adapter_t *adp, int val, int x, int y, int cx, int cy)
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
wiifb_bitblt(video_adapter_t *adp, ...)
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
wiifb_diag(video_adapter_t *adp, int level)
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
wiifb_save_cursor_palette(video_adapter_t *adp, u_char *palette)
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
wiifb_load_cursor_palette(video_adapter_t *adp, u_char *palette)
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
wiifb_copy(video_adapter_t *adp, vm_offset_t src, vm_offset_t dst, int n)
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
wiifb_putp(video_adapter_t *adp, vm_offset_t off, uint32_t p, uint32_t a,
|
||||
int size, int bpp, int bit_ltor, int byte_ltor)
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
wiifb_putc(video_adapter_t *adp, vm_offset_t off, uint8_t c, uint8_t a)
|
||||
{
|
||||
struct wiifb_softc *sc;
|
||||
int row;
|
||||
int col;
|
||||
int i, j, k;
|
||||
uint32_t *addr;
|
||||
u_char *p;
|
||||
uint32_t fg, bg;
|
||||
unsigned long pixel[2];
|
||||
|
||||
sc = (struct wiifb_softc *)adp;
|
||||
row = (off / adp->va_info.vi_width) * adp->va_info.vi_cheight;
|
||||
col = (off % adp->va_info.vi_width) * adp->va_info.vi_cwidth / 2;
|
||||
p = sc->sc_font + c*WIIFB_FONT_HEIGHT;
|
||||
addr = (uint32_t *)sc->sc_fb_addr
|
||||
+ (row + sc->sc_ymargin)*(sc->sc_stride/4)
|
||||
+ col + sc->sc_xmargin;
|
||||
|
||||
bg = wiifb_cmap[wiifb_background(a)];
|
||||
fg = wiifb_cmap[wiifb_foreground(a)];
|
||||
|
||||
for (i = 0; i < WIIFB_FONT_HEIGHT; i++) {
|
||||
for (j = 0, k = 7; j < 4; j++, k--) {
|
||||
if ((p[i] & (1 << k)) == 0)
|
||||
pixel[0] = bg;
|
||||
else
|
||||
pixel[0] = fg;
|
||||
k--;
|
||||
if ((p[i] & (1 << k)) == 0)
|
||||
pixel[1] = bg;
|
||||
else
|
||||
pixel[1] = fg;
|
||||
|
||||
addr[j] = (pixel[0] & 0xffff00ff) |
|
||||
(pixel[1] & 0x0000ff00);
|
||||
}
|
||||
addr += (sc->sc_stride/4);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
wiifb_puts(video_adapter_t *adp, vm_offset_t off, u_int16_t *s, int len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
wiifb_putc(adp, off + i, s[i] & 0xff, (s[i] & 0xff00) >> 8);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
wiifb_putm(video_adapter_t *adp, int x, int y, uint8_t *pixel_image,
|
||||
uint32_t pixel_mask, int size, int width)
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
/*-
|
||||
* Copyright (C) 2012 Margarida Gouveia
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer,
|
||||
* without modification, immediately at the beginning of the file.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _POWERPC_WII_WII_FBREG_H
|
||||
#define _POWERPC_WII_WII_FBREG_H
|
||||
|
||||
/*
|
||||
* Memory addresses for the I/O and the framebuffer.
|
||||
*/
|
||||
#define WIIFB_REG_ADDR 0x0c002000
|
||||
#define WIIFB_REG_LEN 0x100
|
||||
#define WIIFB_FB_ADDR 0x01698000 /* at the end of 1T SRAM */
|
||||
#define WIIFB_FB_LEN 0x168000
|
||||
|
||||
#endif /* _POWERPC_WII_WII_FBREG_H */
|
@ -1,857 +0,0 @@
|
||||
/*-
|
||||
* Copyright (C) 2012 Margarida Gouveia
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer,
|
||||
* without modification, immediately at the beginning of the file.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _POWERPC_WII_WIIFB_H
|
||||
#define _POWERPC_WII_WIIFB_H
|
||||
|
||||
#define WIIFB_FONT_HEIGHT 8
|
||||
|
||||
enum wiifb_format {
|
||||
WIIFB_FORMAT_NTSC = 0,
|
||||
WIIFB_FORMAT_PAL = 1,
|
||||
WIIFB_FORMAT_MPAL = 2,
|
||||
WIIFB_FORMAT_DEBUG = 3
|
||||
};
|
||||
|
||||
enum wiifb_mode {
|
||||
WIIFB_MODE_NTSC_480i = 0,
|
||||
WIIFB_MODE_NTSC_480p = 1,
|
||||
WIIFB_MODE_PAL_576i = 2,
|
||||
WIIFB_MODE_PAL_480i = 3,
|
||||
WIIFB_MODE_PAL_480p = 4
|
||||
};
|
||||
|
||||
struct wiifb_mode_desc {
|
||||
const char *fd_name;
|
||||
unsigned int fd_width;
|
||||
unsigned int fd_height;
|
||||
unsigned int fd_lines;
|
||||
uint8_t fd_flags;
|
||||
#define WIIFB_MODE_FLAG_PROGRESSIVE 0x00
|
||||
#define WIIFB_MODE_FLAG_INTERLACED 0x01
|
||||
};
|
||||
|
||||
struct wiifb_softc {
|
||||
video_adapter_t sc_va;
|
||||
struct cdev *sc_si;
|
||||
int sc_console;
|
||||
|
||||
intptr_t sc_reg_addr;
|
||||
unsigned int sc_reg_size;
|
||||
|
||||
intptr_t sc_fb_addr;
|
||||
unsigned int sc_fb_size;
|
||||
|
||||
unsigned int sc_height;
|
||||
unsigned int sc_width;
|
||||
unsigned int sc_stride;
|
||||
|
||||
unsigned int sc_xmargin;
|
||||
unsigned int sc_ymargin;
|
||||
|
||||
boolean_t sc_component;
|
||||
enum wiifb_format sc_format;
|
||||
struct wiifb_mode_desc *sc_mode;
|
||||
|
||||
unsigned int sc_vtiming;
|
||||
unsigned int sc_htiming;
|
||||
|
||||
unsigned char *sc_font;
|
||||
int sc_initialized;
|
||||
int sc_rrid;
|
||||
};
|
||||
|
||||
/*
|
||||
* Vertical timing
|
||||
* 16 bit
|
||||
*/
|
||||
#define WIIFB_REG_VTIMING 0x00
|
||||
struct wiifb_vtiming {
|
||||
uint8_t vt_eqpulse;
|
||||
uint16_t vt_actvideo;
|
||||
};
|
||||
|
||||
static __inline void
|
||||
wiifb_vtiming_read(struct wiifb_softc *sc, struct wiifb_vtiming *vt)
|
||||
{
|
||||
volatile uint16_t *reg =
|
||||
(uint16_t *)(sc->sc_reg_addr + WIIFB_REG_VTIMING);
|
||||
|
||||
vt->vt_eqpulse = *reg & 0xf;
|
||||
vt->vt_actvideo = (*reg >> 4) & 0x3ff;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
wiifb_vtiming_write(struct wiifb_softc *sc, struct wiifb_vtiming *vt)
|
||||
{
|
||||
volatile uint16_t *reg =
|
||||
(uint16_t *)(sc->sc_reg_addr + WIIFB_REG_VTIMING);
|
||||
|
||||
*reg = ((vt->vt_actvideo & 0x3ff) << 4) |
|
||||
(vt->vt_eqpulse & 0xf);
|
||||
powerpc_sync();
|
||||
}
|
||||
|
||||
/*
|
||||
* Display configuration
|
||||
* 16 bit
|
||||
*/
|
||||
#define WIIFB_REG_DISPCFG 0x02
|
||||
struct wiifb_dispcfg {
|
||||
uint8_t dc_enable;
|
||||
uint8_t dc_reset;
|
||||
uint8_t dc_noninterlaced;
|
||||
uint8_t dc_3dmode;
|
||||
uint8_t dc_latchenb0;
|
||||
uint8_t dc_latchenb1;
|
||||
enum wiifb_format dc_format;
|
||||
};
|
||||
|
||||
static __inline void
|
||||
wiifb_dispcfg_read(struct wiifb_softc *sc, struct wiifb_dispcfg *dc)
|
||||
{
|
||||
volatile uint16_t *reg =
|
||||
(uint16_t *)(sc->sc_reg_addr + WIIFB_REG_DISPCFG);
|
||||
|
||||
dc->dc_enable = *reg & 0x1;
|
||||
dc->dc_reset = (*reg >> 1) & 0x1;
|
||||
dc->dc_noninterlaced = (*reg >> 2) & 0x1;
|
||||
dc->dc_3dmode = (*reg >> 3) & 0x1;
|
||||
dc->dc_latchenb0 = (*reg >> 4) & 0x3;
|
||||
dc->dc_latchenb1 = (*reg >> 6) & 0x3;
|
||||
dc->dc_format = (*reg >> 8) & 0x3;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
wiifb_dispcfg_write(struct wiifb_softc *sc, struct wiifb_dispcfg *dc)
|
||||
{
|
||||
volatile uint16_t *reg =
|
||||
(uint16_t *)(sc->sc_reg_addr + WIIFB_REG_DISPCFG);
|
||||
|
||||
*reg = ((dc->dc_format & 0x3) << 8) |
|
||||
((dc->dc_latchenb1 & 0x3) << 6) |
|
||||
((dc->dc_latchenb0 & 0x3) << 4) |
|
||||
((dc->dc_3dmode & 0x1) << 3) |
|
||||
((dc->dc_noninterlaced & 0x1) << 2) |
|
||||
((dc->dc_reset & 0x1) << 1) |
|
||||
(dc->dc_enable & 0x1);
|
||||
powerpc_sync();
|
||||
}
|
||||
|
||||
/*
|
||||
* Horizontal Timing 0
|
||||
* 32 bit
|
||||
*/
|
||||
#define WIIFB_REG_HTIMING0 0x04
|
||||
struct wiifb_htiming0 {
|
||||
uint16_t ht0_hlinew; /* half line width */
|
||||
uint8_t ht0_hcolourend;
|
||||
uint8_t ht0_hcolourstart;
|
||||
};
|
||||
|
||||
static __inline void
|
||||
wiifb_htiming0_read(struct wiifb_softc *sc, struct wiifb_htiming0 *ht0)
|
||||
{
|
||||
volatile uint32_t *reg =
|
||||
(uint32_t *)(sc->sc_reg_addr + WIIFB_REG_HTIMING0);
|
||||
|
||||
ht0->ht0_hlinew = *reg & 0x1ff;
|
||||
ht0->ht0_hcolourend = (*reg >> 16) & 0x7f;
|
||||
ht0->ht0_hcolourstart = (*reg >> 24) & 0x7f;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
wiifb_htiming0_write(struct wiifb_softc *sc, struct wiifb_htiming0 *ht0)
|
||||
{
|
||||
volatile uint32_t *reg =
|
||||
(uint32_t *)(sc->sc_reg_addr + WIIFB_REG_HTIMING0);
|
||||
|
||||
*reg = ((ht0->ht0_hcolourstart & 0x7f) << 24) |
|
||||
((ht0->ht0_hcolourend & 0x7f) << 16) |
|
||||
(ht0->ht0_hlinew & 0x1ff);
|
||||
powerpc_sync();
|
||||
}
|
||||
/*
|
||||
* Horizontal Timing 1
|
||||
* 32 bit
|
||||
*/
|
||||
#define WIIFB_REG_HTIMING1 0x08
|
||||
struct wiifb_htiming1 {
|
||||
uint8_t ht1_hsyncw;
|
||||
uint16_t ht1_hblankend;
|
||||
uint16_t ht1_hblankstart;
|
||||
};
|
||||
|
||||
static __inline void
|
||||
wiifb_htiming1_read(struct wiifb_softc *sc, struct wiifb_htiming1 *ht1)
|
||||
{
|
||||
volatile uint32_t *reg =
|
||||
(uint32_t *)(sc->sc_reg_addr + WIIFB_REG_HTIMING1);
|
||||
|
||||
ht1->ht1_hsyncw = *reg & 0x7f;
|
||||
ht1->ht1_hblankend = (*reg >> 7) & 0x3ff;
|
||||
ht1->ht1_hblankstart = (*reg >> 17) & 0x3ff;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
wiifb_htiming1_write(struct wiifb_softc *sc, struct wiifb_htiming1 *ht1)
|
||||
{
|
||||
volatile uint32_t *reg =
|
||||
(uint32_t *)(sc->sc_reg_addr + WIIFB_REG_HTIMING1);
|
||||
|
||||
*reg = ((ht1->ht1_hblankstart & 0x3ff) << 17) |
|
||||
((ht1->ht1_hblankend & 0x3ff) << 7) |
|
||||
(ht1->ht1_hsyncw & 0x7f);
|
||||
powerpc_sync();
|
||||
}
|
||||
|
||||
/*
|
||||
* Vertical Timing Odd
|
||||
* 32 bit
|
||||
*/
|
||||
#define WIIFB_REG_VTIMINGODD 0x0c
|
||||
struct wiifb_vtimingodd {
|
||||
uint16_t vto_preb; /* pre blanking */
|
||||
uint16_t vto_postb; /* post blanking */
|
||||
};
|
||||
|
||||
static __inline void
|
||||
wiifb_vtimingodd_read(struct wiifb_softc *sc, struct wiifb_vtimingodd *vto)
|
||||
{
|
||||
volatile uint32_t *reg =
|
||||
(uint32_t *)(sc->sc_reg_addr + WIIFB_REG_VTIMINGODD);
|
||||
|
||||
vto->vto_preb = *reg & 0x3ff;
|
||||
vto->vto_postb = (*reg >> 16) & 0x3ff;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
wiifb_vtimingodd_write(struct wiifb_softc *sc, struct wiifb_vtimingodd *vto)
|
||||
{
|
||||
volatile uint32_t *reg =
|
||||
(uint32_t *)(sc->sc_reg_addr + WIIFB_REG_VTIMINGODD);
|
||||
|
||||
*reg = ((vto->vto_postb & 0x3ff) << 16) |
|
||||
(vto->vto_preb & 0x3ff);
|
||||
powerpc_sync();
|
||||
}
|
||||
|
||||
/*
|
||||
* Vertical Timing Even
|
||||
* 32 bit
|
||||
*/
|
||||
#define WIIFB_REG_VTIMINGEVEN 0x10
|
||||
struct wiifb_vtimingeven {
|
||||
uint16_t vte_preb; /* pre blanking */
|
||||
uint16_t vte_postb; /* post blanking */
|
||||
};
|
||||
|
||||
static __inline void
|
||||
wiifb_vtimingeven_read(struct wiifb_softc *sc, struct wiifb_vtimingeven *vte)
|
||||
{
|
||||
volatile uint32_t *reg =
|
||||
(uint32_t *)(sc->sc_reg_addr + WIIFB_REG_VTIMINGEVEN);
|
||||
|
||||
vte->vte_preb = *reg & 0x3ff;
|
||||
vte->vte_postb = (*reg >> 16) & 0x3ff;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
wiifb_vtimingeven_write(struct wiifb_softc *sc, struct wiifb_vtimingeven *vte)
|
||||
{
|
||||
volatile uint32_t *reg =
|
||||
(uint32_t *)(sc->sc_reg_addr + WIIFB_REG_VTIMINGEVEN);
|
||||
|
||||
*reg = ((vte->vte_postb & 0x3ff) << 16) |
|
||||
(vte->vte_preb & 0x3ff);
|
||||
powerpc_sync();
|
||||
}
|
||||
|
||||
/*
|
||||
* Burst Blanking Odd Interval
|
||||
* 32 bit
|
||||
*/
|
||||
#define WIIFB_REG_BURSTBLANKODD 0x14
|
||||
struct wiifb_burstblankodd {
|
||||
uint8_t bbo_bs1;
|
||||
uint16_t bbo_be1;
|
||||
uint8_t bbo_bs3;
|
||||
uint16_t bbo_be3;
|
||||
};
|
||||
|
||||
static __inline void
|
||||
wiifb_burstblankodd_read(struct wiifb_softc *sc,
|
||||
struct wiifb_burstblankodd *bbo)
|
||||
{
|
||||
volatile uint32_t *reg =
|
||||
(uint32_t *)(sc->sc_reg_addr + WIIFB_REG_BURSTBLANKODD);
|
||||
|
||||
bbo->bbo_bs1 = *reg & 0x1f;
|
||||
bbo->bbo_be1 = (*reg >> 5) & 0x7ff;
|
||||
bbo->bbo_bs3 = (*reg >> 16) & 0x1f;
|
||||
bbo->bbo_be3 = (*reg >> 21) & 0x7ff;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
wiifb_burstblankodd_write(struct wiifb_softc *sc,
|
||||
struct wiifb_burstblankodd *bbo)
|
||||
{
|
||||
volatile uint32_t *reg =
|
||||
(uint32_t *)(sc->sc_reg_addr + WIIFB_REG_BURSTBLANKODD);
|
||||
|
||||
*reg = ((bbo->bbo_be3 & 0x7ff) << 21) |
|
||||
((bbo->bbo_bs3 & 0x1f) << 16) |
|
||||
((bbo->bbo_be1 & 0x7ff) << 5) |
|
||||
(bbo->bbo_bs1 & 0x1f);
|
||||
powerpc_sync();
|
||||
}
|
||||
|
||||
/*
|
||||
* Burst Blanking Even Interval
|
||||
* 32 bit
|
||||
*/
|
||||
#define WIIFB_REG_BURSTBLANKEVEN 0x18
|
||||
struct wiifb_burstblankeven {
|
||||
uint8_t bbe_bs2;
|
||||
uint16_t bbe_be2;
|
||||
uint8_t bbe_bs4;
|
||||
uint16_t bbe_be4;
|
||||
};
|
||||
|
||||
static __inline void
|
||||
wiifb_burstblankeven_read(struct wiifb_softc *sc,
|
||||
struct wiifb_burstblankeven *bbe)
|
||||
{
|
||||
volatile uint32_t *reg =
|
||||
(uint32_t *)(sc->sc_reg_addr + WIIFB_REG_BURSTBLANKEVEN);
|
||||
|
||||
bbe->bbe_bs2 = *reg & 0x1f;
|
||||
bbe->bbe_be2 = (*reg >> 5) & 0x7ff;
|
||||
bbe->bbe_bs4 = (*reg >> 16) & 0x1f;
|
||||
bbe->bbe_be4 = (*reg >> 21) & 0x7ff;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
wiifb_burstblankeven_write(struct wiifb_softc *sc,
|
||||
struct wiifb_burstblankeven *bbe)
|
||||
{
|
||||
volatile uint32_t *reg =
|
||||
(uint32_t *)(sc->sc_reg_addr + WIIFB_REG_BURSTBLANKEVEN);
|
||||
|
||||
*reg = ((bbe->bbe_be4 & 0x7ff) << 21) |
|
||||
((bbe->bbe_bs4 & 0x1f) << 16) |
|
||||
((bbe->bbe_be2 & 0x7ff) << 5) |
|
||||
(bbe->bbe_bs2 & 0x1f);
|
||||
powerpc_sync();
|
||||
}
|
||||
|
||||
/*
|
||||
* Top Field Base Left
|
||||
* 32 bit
|
||||
*/
|
||||
#define WIIFB_REG_TOPFIELDBASEL 0x1c
|
||||
struct wiifb_topfieldbasel {
|
||||
uint32_t tfbl_fbaddr;
|
||||
uint8_t tfbl_xoffset;
|
||||
uint8_t tfbl_pageoffbit;
|
||||
};
|
||||
|
||||
static __inline void
|
||||
wiifb_topfieldbasel_read(struct wiifb_softc *sc,
|
||||
struct wiifb_topfieldbasel *tfbl)
|
||||
{
|
||||
volatile uint32_t *reg =
|
||||
(uint32_t *)(sc->sc_reg_addr + WIIFB_REG_TOPFIELDBASEL);
|
||||
|
||||
tfbl->tfbl_fbaddr = *reg & 0xffffff;
|
||||
tfbl->tfbl_xoffset = (*reg >> 24) & 0xf;
|
||||
tfbl->tfbl_pageoffbit = (*reg >> 28) & 0x1;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
wiifb_topfieldbasel_write(struct wiifb_softc *sc,
|
||||
struct wiifb_topfieldbasel *tfbl)
|
||||
{
|
||||
volatile uint32_t *reg =
|
||||
(uint32_t *)(sc->sc_reg_addr + WIIFB_REG_TOPFIELDBASEL);
|
||||
|
||||
*reg = ((tfbl->tfbl_pageoffbit & 0x1) << 28) |
|
||||
((tfbl->tfbl_xoffset & 0xf) << 24) |
|
||||
(tfbl->tfbl_fbaddr & 0xffffff);
|
||||
powerpc_sync();
|
||||
}
|
||||
|
||||
/*
|
||||
* Top Field Base Right
|
||||
* 32 bit
|
||||
*/
|
||||
#define WIIFB_REG_TOPFIELDBASER 0x20
|
||||
struct wiifb_topfieldbaser {
|
||||
uint32_t tfbr_fbaddr;
|
||||
uint8_t tfbr_pageoffbit;
|
||||
};
|
||||
|
||||
static __inline void
|
||||
wiifb_topfieldbaser_read(struct wiifb_softc *sc,
|
||||
struct wiifb_topfieldbaser *tfbr)
|
||||
{
|
||||
volatile uint32_t *reg =
|
||||
(uint32_t *)(sc->sc_reg_addr + WIIFB_REG_TOPFIELDBASER);
|
||||
|
||||
tfbr->tfbr_fbaddr = *reg & 0xffffff;
|
||||
tfbr->tfbr_pageoffbit = (*reg >> 28) & 0x1;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
wiifb_topfieldbaser_write(struct wiifb_softc *sc,
|
||||
struct wiifb_topfieldbaser *tfbr)
|
||||
{
|
||||
volatile uint32_t *reg =
|
||||
(uint32_t *)(sc->sc_reg_addr + WIIFB_REG_TOPFIELDBASER);
|
||||
|
||||
*reg = ((tfbr->tfbr_pageoffbit & 0x1) << 28) |
|
||||
(tfbr->tfbr_fbaddr & 0xffffff);
|
||||
powerpc_sync();
|
||||
}
|
||||
|
||||
/*
|
||||
* Bottom Field Base Left
|
||||
* 32 bit
|
||||
*/
|
||||
#define WIIFB_REG_BOTTOMFIELDBASEL 0x24
|
||||
struct wiifb_bottomfieldbasel {
|
||||
uint32_t bfbl_fbaddr;
|
||||
uint8_t bfbl_xoffset;
|
||||
uint8_t bfbl_pageoffbit;
|
||||
};
|
||||
|
||||
static __inline void
|
||||
wiifb_bottomfieldbasel_read(struct wiifb_softc *sc,
|
||||
struct wiifb_bottomfieldbasel *bfbl)
|
||||
{
|
||||
volatile uint32_t *reg =
|
||||
(uint32_t *)(sc->sc_reg_addr + WIIFB_REG_BOTTOMFIELDBASEL);
|
||||
|
||||
bfbl->bfbl_fbaddr = *reg & 0xffffff;
|
||||
bfbl->bfbl_xoffset = (*reg >> 24) & 0xf;
|
||||
bfbl->bfbl_pageoffbit = (*reg >> 28) & 0x1;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
wiifb_bottomfieldbasel_write(struct wiifb_softc *sc,
|
||||
struct wiifb_bottomfieldbasel *bfbl)
|
||||
{
|
||||
volatile uint32_t *reg =
|
||||
(uint32_t *)(sc->sc_reg_addr + WIIFB_REG_BOTTOMFIELDBASEL);
|
||||
|
||||
*reg = ((bfbl->bfbl_pageoffbit & 0x1) << 28) |
|
||||
((bfbl->bfbl_xoffset & 0xf) << 24) |
|
||||
(bfbl->bfbl_fbaddr & 0xffffff);
|
||||
powerpc_sync();
|
||||
}
|
||||
|
||||
/*
|
||||
* Bottom Field Base Right
|
||||
* 32 bit
|
||||
*/
|
||||
#define WIIFB_REG_BOTTOMFIELDBASER 0x28
|
||||
struct wiifb_bottomfieldbaser {
|
||||
uint32_t bfbr_fbaddr;
|
||||
uint8_t bfbr_pageoffbit;
|
||||
};
|
||||
|
||||
static __inline void
|
||||
wiifb_bottomfieldbaser_read(struct wiifb_softc *sc,
|
||||
struct wiifb_bottomfieldbaser *bfbr)
|
||||
{
|
||||
volatile uint32_t *reg =
|
||||
(uint32_t *)(sc->sc_reg_addr + WIIFB_REG_BOTTOMFIELDBASER);
|
||||
|
||||
bfbr->bfbr_fbaddr = *reg & 0xffffff;
|
||||
bfbr->bfbr_pageoffbit = (*reg >> 28) & 0x1;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
wiifb_bottomfieldbaser_write(struct wiifb_softc *sc,
|
||||
struct wiifb_bottomfieldbaser *bfbr)
|
||||
{
|
||||
volatile uint32_t *reg =
|
||||
(uint32_t *)(sc->sc_reg_addr + WIIFB_REG_BOTTOMFIELDBASER);
|
||||
|
||||
*reg = ((bfbr->bfbr_pageoffbit & 0x1) << 28) |
|
||||
(bfbr->bfbr_fbaddr & 0xffffff);
|
||||
powerpc_sync();
|
||||
}
|
||||
|
||||
/*
|
||||
* Display Position Vertical
|
||||
* 16 bit
|
||||
*/
|
||||
#define WIIFB_REG_DISPPOSV 0x2c
|
||||
static __inline uint16_t
|
||||
wiifb_dispposv_read(struct wiifb_softc *sc)
|
||||
{
|
||||
volatile uint32_t *reg =
|
||||
(uint32_t *)(sc->sc_reg_addr + WIIFB_REG_DISPPOSV);
|
||||
|
||||
return (*reg & 0x7ff);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
wiifb_dispposv_write(struct wiifb_softc *sc, uint16_t val)
|
||||
{
|
||||
volatile uint32_t *reg =
|
||||
(uint32_t *)(sc->sc_reg_addr + WIIFB_REG_DISPPOSV);
|
||||
|
||||
*reg = val & 0x7ff;
|
||||
powerpc_sync();
|
||||
}
|
||||
|
||||
/*
|
||||
* Display Position Horizontal
|
||||
* 16 bit
|
||||
*/
|
||||
#define WIIFB_REG_DISPPOSH 0x2e
|
||||
static __inline uint16_t
|
||||
wiifb_dispposh_read(struct wiifb_softc *sc)
|
||||
{
|
||||
volatile uint32_t *reg =
|
||||
(uint32_t *)(sc->sc_reg_addr + WIIFB_REG_DISPPOSH);
|
||||
|
||||
return (*reg & 0x7ff);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
wiifb_dispposh_write(struct wiifb_softc *sc, uint16_t val)
|
||||
{
|
||||
volatile uint32_t *reg =
|
||||
(uint32_t *)(sc->sc_reg_addr + WIIFB_REG_DISPPOSH);
|
||||
|
||||
*reg = val & 0x7ff;
|
||||
powerpc_sync();
|
||||
}
|
||||
|
||||
/*
|
||||
* Display Interrupts.
|
||||
* There are 4 display interrupt registers, all 32 bit.
|
||||
*/
|
||||
#define WIIFB_REG_DISPINT0 0x30
|
||||
#define WIIFB_REG_DISPINT1 0x34
|
||||
#define WIIFB_REG_DISPINT2 0x38
|
||||
#define WIIFB_REG_DISPINT3 0x3c
|
||||
struct wiifb_dispint {
|
||||
uint16_t di_htiming;
|
||||
uint16_t di_vtiming;
|
||||
uint8_t di_enable;
|
||||
uint8_t di_irq;
|
||||
};
|
||||
|
||||
static __inline void
|
||||
wiifb_dispint_read(struct wiifb_softc *sc, int regno, struct wiifb_dispint *di)
|
||||
{
|
||||
volatile uint32_t *reg = (uint32_t *)(sc->sc_reg_addr +
|
||||
WIIFB_REG_DISPINT0 + regno * 4);
|
||||
|
||||
di->di_htiming = *reg & 0x3ff;
|
||||
di->di_vtiming = (*reg >> 16) & 0x3ff;
|
||||
di->di_enable = (*reg >> 28) & 0x1;
|
||||
di->di_irq = (*reg >> 31) & 0x1;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
wiifb_dispint_write(struct wiifb_softc *sc, int regno, struct wiifb_dispint *di)
|
||||
{
|
||||
volatile uint32_t *reg = (uint32_t *)(sc->sc_reg_addr +
|
||||
WIIFB_REG_DISPINT0 + regno * 4);
|
||||
|
||||
*reg = ((di->di_irq & 0x1) << 31) |
|
||||
((di->di_enable & 0x1) << 28) |
|
||||
((di->di_vtiming & 0x3ff) << 16) |
|
||||
(di->di_htiming & 0x3ff);
|
||||
powerpc_sync();
|
||||
}
|
||||
|
||||
/*
|
||||
* Display Latch 0
|
||||
* 32 bit
|
||||
*/
|
||||
#define WIIFB_REG_DISPLAYTCH0 0x40
|
||||
|
||||
/*
|
||||
* Display Latch 1
|
||||
* 32 bit
|
||||
*/
|
||||
#define WIIFB_REG_DISPLAYTCH1 0x44
|
||||
|
||||
/*
|
||||
* Picture Configuration
|
||||
* 16 bit
|
||||
*/
|
||||
#define WIIFB_REG_PICCONF 0x48
|
||||
struct wiifb_picconf {
|
||||
uint8_t pc_strides; /* strides per line (words) */
|
||||
uint8_t pc_reads; /* reads per line (words */
|
||||
};
|
||||
|
||||
static __inline void
|
||||
wiifb_picconf_read(struct wiifb_softc *sc, struct wiifb_picconf *pc)
|
||||
{
|
||||
volatile uint16_t *reg =
|
||||
(uint16_t *)(sc->sc_reg_addr + WIIFB_REG_PICCONF);
|
||||
|
||||
pc->pc_strides = *reg & 0xff;
|
||||
pc->pc_reads = (*reg >> 8) & 0xff;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
wiifb_picconf_write(struct wiifb_softc *sc, struct wiifb_picconf *pc)
|
||||
{
|
||||
volatile uint16_t *reg =
|
||||
(uint16_t *)(sc->sc_reg_addr + WIIFB_REG_PICCONF);
|
||||
|
||||
*reg = ((pc->pc_reads & 0xff) << 8) |
|
||||
(pc->pc_strides & 0xff);
|
||||
powerpc_sync();
|
||||
}
|
||||
|
||||
/*
|
||||
* Horizontal Scaling
|
||||
* 16 bit
|
||||
*/
|
||||
#define WIIFB_REG_HSCALING 0x4a
|
||||
struct wiifb_hscaling {
|
||||
uint16_t hs_step;
|
||||
uint8_t hs_enable;
|
||||
};
|
||||
|
||||
static __inline void
|
||||
wiifb_hscaling_read(struct wiifb_softc *sc, struct wiifb_hscaling *hs)
|
||||
{
|
||||
volatile uint16_t *reg =
|
||||
(uint16_t *)(sc->sc_reg_addr + WIIFB_REG_HSCALING);
|
||||
|
||||
hs->hs_step = *reg & 0x1ff;
|
||||
hs->hs_enable = (*reg >> 12) & 0x1;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
wiifb_hscaling_write(struct wiifb_softc *sc, struct wiifb_hscaling *hs)
|
||||
{
|
||||
volatile uint16_t *reg =
|
||||
(uint16_t *)(sc->sc_reg_addr + WIIFB_REG_HSCALING);
|
||||
|
||||
*reg = ((hs->hs_step & 0x1ff) << 12) |
|
||||
(hs->hs_enable & 0x1);
|
||||
powerpc_sync();
|
||||
}
|
||||
|
||||
/*
|
||||
* Filter Coeficient Table 0-6
|
||||
* 32 bit
|
||||
*/
|
||||
#define WIIFB_REG_FILTCOEFT0 0x4c
|
||||
#define WIIFB_REG_FILTCOEFT1 0x50
|
||||
#define WIIFB_REG_FILTCOEFT2 0x54
|
||||
#define WIIFB_REG_FILTCOEFT3 0x58
|
||||
#define WIIFB_REG_FILTCOEFT4 0x5c
|
||||
#define WIIFB_REG_FILTCOEFT5 0x60
|
||||
#define WIIFB_REG_FILTCOEFT6 0x64
|
||||
static __inline void
|
||||
wiifb_filtcoeft_write(struct wiifb_softc *sc, unsigned int regno,
|
||||
uint32_t coeft)
|
||||
{
|
||||
volatile uint32_t *reg =
|
||||
(uint32_t *)(sc->sc_reg_addr + WIIFB_REG_FILTCOEFT0 + 4 * regno);
|
||||
|
||||
*reg = coeft;
|
||||
powerpc_sync();
|
||||
}
|
||||
|
||||
/*
|
||||
* Anti-aliasing
|
||||
* 32 bit
|
||||
*/
|
||||
#define WIIFB_REG_ANTIALIAS 0x68
|
||||
static __inline void
|
||||
wiifb_antialias_write(struct wiifb_softc *sc, uint32_t antialias)
|
||||
{
|
||||
volatile uint32_t *reg =
|
||||
(uint32_t *)(sc->sc_reg_addr + WIIFB_REG_ANTIALIAS);
|
||||
|
||||
*reg = antialias;
|
||||
powerpc_sync();
|
||||
}
|
||||
|
||||
/*
|
||||
* Video Clock
|
||||
* 16 bit
|
||||
*/
|
||||
#define WIIFB_REG_VIDEOCLK 0x6c
|
||||
static __inline uint8_t
|
||||
wiifb_videoclk_read(struct wiifb_softc *sc)
|
||||
{
|
||||
volatile uint16_t *reg =
|
||||
(uint16_t *)(sc->sc_reg_addr + WIIFB_REG_VIDEOCLK);
|
||||
|
||||
return (*reg & 0x1);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
wiifb_videoclk_write(struct wiifb_softc *sc, uint16_t clk54mhz)
|
||||
{
|
||||
volatile uint16_t *reg =
|
||||
(uint16_t *)(sc->sc_reg_addr + WIIFB_REG_VIDEOCLK);
|
||||
|
||||
*reg = clk54mhz & 0x1;
|
||||
powerpc_sync();
|
||||
}
|
||||
|
||||
/*
|
||||
* DTV Status
|
||||
* 16 bit
|
||||
*
|
||||
* DTV is another name for the Component Cable output.
|
||||
*/
|
||||
#define WIIFB_REG_DTVSTATUS 0x6e
|
||||
static __inline uint16_t
|
||||
wiifb_dtvstatus_read(struct wiifb_softc *sc)
|
||||
{
|
||||
volatile uint16_t *reg =
|
||||
(uint16_t *)(sc->sc_reg_addr + WIIFB_REG_DTVSTATUS);
|
||||
|
||||
return (*reg & 0x1);
|
||||
}
|
||||
|
||||
static __inline uint16_t
|
||||
wiifb_component_enabled(struct wiifb_softc *sc)
|
||||
{
|
||||
|
||||
return wiifb_dtvstatus_read(sc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Horizontal Scaling Width
|
||||
* 16 bit
|
||||
*/
|
||||
#define WIIFB_REG_HSCALINGW 0x70
|
||||
static __inline uint16_t
|
||||
wiifb_hscalingw_read(struct wiifb_softc *sc)
|
||||
{
|
||||
volatile uint16_t *reg =
|
||||
(uint16_t *)(sc->sc_reg_addr + WIIFB_REG_HSCALINGW);
|
||||
|
||||
return (*reg & 0x3ff);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
wiifb_hscalingw_write(struct wiifb_softc *sc, uint16_t width)
|
||||
{
|
||||
volatile uint16_t *reg =
|
||||
(uint16_t *)(sc->sc_reg_addr + WIIFB_REG_HSCALINGW);
|
||||
|
||||
*reg = width & 0x3ff;
|
||||
powerpc_sync();
|
||||
}
|
||||
|
||||
/*
|
||||
* Horizontal Border End
|
||||
* For debug mode only. Not used by this driver.
|
||||
* 16 bit
|
||||
*/
|
||||
#define WIIFB_REG_HBORDEREND 0x72
|
||||
static __inline void
|
||||
wiifb_hborderend_write(struct wiifb_softc *sc, uint16_t border)
|
||||
{
|
||||
volatile uint16_t *reg =
|
||||
(uint16_t *)(sc->sc_reg_addr + WIIFB_REG_HBORDEREND);
|
||||
|
||||
*reg = border;
|
||||
powerpc_sync();
|
||||
}
|
||||
|
||||
/*
|
||||
* Horizontal Border Start
|
||||
* 16 bit
|
||||
*/
|
||||
#define WIIFB_REG_HBORDERSTART 0x74
|
||||
static __inline void
|
||||
wiifb_hborderstart_write(struct wiifb_softc *sc, uint16_t border)
|
||||
{
|
||||
volatile uint16_t *reg =
|
||||
(uint16_t *)(sc->sc_reg_addr + WIIFB_REG_HBORDERSTART);
|
||||
|
||||
*reg = border;
|
||||
powerpc_sync();
|
||||
}
|
||||
|
||||
/*
|
||||
* Unknown register
|
||||
* 16 bit
|
||||
*/
|
||||
#define WIIFB_REG_UNKNOWN1 0x76
|
||||
static __inline void
|
||||
wiifb_unknown1_write(struct wiifb_softc *sc, uint16_t unknown)
|
||||
{
|
||||
volatile uint16_t *reg =
|
||||
(uint16_t *)(sc->sc_reg_addr + WIIFB_REG_UNKNOWN1);
|
||||
|
||||
*reg = unknown;
|
||||
powerpc_sync();
|
||||
}
|
||||
|
||||
/*
|
||||
* Unknown register
|
||||
* 32 bit
|
||||
*/
|
||||
#define WIIFB_REG_UNKNOWN2 0x78
|
||||
static __inline void
|
||||
wiifb_unknown2_write(struct wiifb_softc *sc, uint32_t unknown)
|
||||
{
|
||||
volatile uint32_t *reg =
|
||||
(uint32_t *)(sc->sc_reg_addr + WIIFB_REG_UNKNOWN2);
|
||||
|
||||
*reg = unknown;
|
||||
powerpc_sync();
|
||||
}
|
||||
|
||||
/*
|
||||
* Unknown register
|
||||
* 32 bit
|
||||
*/
|
||||
#define WIIFB_REG_UNKNOWN3 0x7c
|
||||
static __inline void
|
||||
wiifb_unknown3_write(struct wiifb_softc *sc, uint32_t unknown)
|
||||
{
|
||||
volatile uint32_t *reg =
|
||||
(uint32_t *)(sc->sc_reg_addr + WIIFB_REG_UNKNOWN3);
|
||||
|
||||
*reg = unknown;
|
||||
powerpc_sync();
|
||||
}
|
||||
|
||||
#endif /* _POWERPC_WII_WIIFB_H */
|
@ -1,353 +0,0 @@
|
||||
/*-
|
||||
* Copyright (C) 2012 Margarida Gouveia
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/rman.h>
|
||||
#include <sys/gpio.h>
|
||||
#include <sys/reboot.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/platform.h>
|
||||
#include <machine/intr_machdep.h>
|
||||
#include <machine/resource.h>
|
||||
|
||||
#include <powerpc/wii/wii_gpioreg.h>
|
||||
|
||||
#include "gpio_if.h"
|
||||
|
||||
struct wiigpio_softc {
|
||||
device_t sc_dev;
|
||||
struct resource *sc_rres;
|
||||
bus_space_tag_t sc_bt;
|
||||
bus_space_handle_t sc_bh;
|
||||
int sc_rrid;
|
||||
struct mtx sc_mtx;
|
||||
struct gpio_pin sc_pins[WIIGPIO_NPINS];
|
||||
};
|
||||
|
||||
|
||||
#define WIIGPIO_PINBANK(_p) ((_p) / (WIIGPIO_NPINS / 2))
|
||||
#define WIIGPIO_PINMASK(_p) (1 << ((_p) % (WIIGPIO_NPINS / 2)))
|
||||
#define WIIGPIO_LOCK(sc) mtx_lock(&(sc)->sc_mtx)
|
||||
#define WIIGPIO_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx)
|
||||
|
||||
static int wiigpio_probe(device_t);
|
||||
static int wiigpio_attach(device_t);
|
||||
static int wiigpio_detach(device_t);
|
||||
static int wiigpio_pin_max(device_t, int *);
|
||||
static int wiigpio_pin_getname(device_t, uint32_t, char *);
|
||||
static int wiigpio_pin_getflags(device_t, uint32_t, uint32_t *);
|
||||
static int wiigpio_pin_setflags(device_t, uint32_t, uint32_t);
|
||||
static int wiigpio_pin_getcaps(device_t, uint32_t, uint32_t *);
|
||||
static int wiigpio_pin_get(device_t, uint32_t, unsigned int *);
|
||||
static int wiigpio_pin_set(device_t, uint32_t, unsigned int);
|
||||
static int wiigpio_pin_toggle(device_t, uint32_t);
|
||||
static void wiigpio_shutdown(void *, int);
|
||||
|
||||
static device_method_t wiigpio_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, wiigpio_probe),
|
||||
DEVMETHOD(device_attach, wiigpio_attach),
|
||||
DEVMETHOD(device_detach, wiigpio_detach),
|
||||
|
||||
/* GPIO protocol */
|
||||
DEVMETHOD(gpio_pin_max, wiigpio_pin_max),
|
||||
DEVMETHOD(gpio_pin_getname, wiigpio_pin_getname),
|
||||
DEVMETHOD(gpio_pin_getflags, wiigpio_pin_getflags),
|
||||
DEVMETHOD(gpio_pin_setflags, wiigpio_pin_setflags),
|
||||
DEVMETHOD(gpio_pin_getcaps, wiigpio_pin_getcaps),
|
||||
DEVMETHOD(gpio_pin_get, wiigpio_pin_get),
|
||||
DEVMETHOD(gpio_pin_set, wiigpio_pin_set),
|
||||
DEVMETHOD(gpio_pin_toggle, wiigpio_pin_toggle),
|
||||
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
static driver_t wiigpio_driver = {
|
||||
"wiigpio",
|
||||
wiigpio_methods,
|
||||
sizeof(struct wiigpio_softc)
|
||||
};
|
||||
|
||||
static devclass_t wiigpio_devclass;
|
||||
|
||||
DRIVER_MODULE(wiigpio, wiibus, wiigpio_driver, wiigpio_devclass, 0, 0);
|
||||
|
||||
static __inline uint32_t
|
||||
wiigpio_read(struct wiigpio_softc *sc, int n)
|
||||
{
|
||||
|
||||
return (bus_space_read_4(sc->sc_bt, sc->sc_bh, n * 0x20));
|
||||
}
|
||||
|
||||
static __inline void
|
||||
wiigpio_write(struct wiigpio_softc *sc, int n, uint32_t reg)
|
||||
{
|
||||
|
||||
bus_space_write_4(sc->sc_bt, sc->sc_bh, n * 0x20, reg);
|
||||
}
|
||||
|
||||
static __inline uint32_t
|
||||
wiigpio_dir_read(struct wiigpio_softc *sc, int n)
|
||||
{
|
||||
|
||||
return (bus_space_read_4(sc->sc_bt, sc->sc_bh, n * 0x20 + 4));
|
||||
}
|
||||
|
||||
static __inline void
|
||||
wiigpio_dir_write(struct wiigpio_softc *sc, int n, uint32_t reg)
|
||||
{
|
||||
|
||||
bus_space_write_4(sc->sc_bt, sc->sc_bh, n * 0x20 + 4, reg);
|
||||
}
|
||||
|
||||
static int
|
||||
wiigpio_probe(device_t dev)
|
||||
{
|
||||
device_set_desc(dev, "Nintendo Wii GPIO");
|
||||
|
||||
return (BUS_PROBE_NOWILDCARD);
|
||||
}
|
||||
|
||||
static int
|
||||
wiigpio_attach(device_t dev)
|
||||
{
|
||||
struct wiigpio_softc *sc;
|
||||
int i;
|
||||
uint32_t d;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
sc->sc_dev = dev;
|
||||
sc->sc_rrid = 0;
|
||||
sc->sc_rres = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
|
||||
&sc->sc_rrid, RF_ACTIVE);
|
||||
if (sc->sc_rres == NULL) {
|
||||
device_printf(dev, "could not alloc mem resource\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
sc->sc_bt = rman_get_bustag(sc->sc_rres);
|
||||
sc->sc_bh = rman_get_bushandle(sc->sc_rres);
|
||||
mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF);
|
||||
#ifdef WIIGPIO_DEBUG
|
||||
device_printf(dev, "dir bank0=0x%08x bank1=0x%08x\n",
|
||||
wiigpio_dir_read(sc, 0), wiigpio_dir_read(sc, 1));
|
||||
device_printf(dev, "val bank0=0x%08x bank1=0x%08x\n",
|
||||
wiigpio_read(sc, 0), wiigpio_read(sc, 1));
|
||||
#endif
|
||||
for (i = 0; i < WIIGPIO_NPINS; i++) {
|
||||
sc->sc_pins[i].gp_caps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT;
|
||||
sc->sc_pins[i].gp_pin = i;
|
||||
d = wiigpio_dir_read(sc, WIIGPIO_PINBANK(i));
|
||||
if (d & WIIGPIO_PINMASK(i))
|
||||
sc->sc_pins[i].gp_flags = GPIO_PIN_OUTPUT;
|
||||
else
|
||||
sc->sc_pins[i].gp_flags = GPIO_PIN_INPUT;
|
||||
snprintf(sc->sc_pins[i].gp_name, GPIOMAXNAME, "PIN %d", i);
|
||||
#ifdef WIIGPIO_DEBUG
|
||||
device_printf(dev, "PIN %d state %d flag %s\n", i,
|
||||
wiigpio_read(sc, WIIGPIO_PINBANK(i)) >>
|
||||
(i % (WIIGPIO_NPINS / 2)) & 1,
|
||||
sc->sc_pins[i].gp_flags == GPIO_PIN_INPUT ?
|
||||
"GPIO_PIN_INPUT" : "GPIO_PIN_OUTPUT");
|
||||
#endif
|
||||
}
|
||||
device_add_child(dev, "gpioc", -1);
|
||||
device_add_child(dev, "gpiobus", -1);
|
||||
/*
|
||||
* We will be responsible for powering off the system.
|
||||
*/
|
||||
EVENTHANDLER_REGISTER(shutdown_final, wiigpio_shutdown, dev,
|
||||
SHUTDOWN_PRI_LAST);
|
||||
|
||||
return (bus_generic_attach(dev));
|
||||
}
|
||||
|
||||
static int
|
||||
wiigpio_detach(device_t dev)
|
||||
{
|
||||
struct wiigpio_softc *sc;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_rrid, sc->sc_rres);
|
||||
mtx_destroy(&sc->sc_mtx);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
wiigpio_pin_max(device_t dev, int *maxpin)
|
||||
{
|
||||
|
||||
*maxpin = WIIGPIO_NPINS - 1;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
wiigpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
|
||||
{
|
||||
struct wiigpio_softc *sc;
|
||||
|
||||
if (pin >= WIIGPIO_NPINS)
|
||||
return (EINVAL);
|
||||
sc = device_get_softc(dev);
|
||||
*caps = sc->sc_pins[pin].gp_caps;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
wiigpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
|
||||
{
|
||||
struct wiigpio_softc *sc;
|
||||
uint32_t reg;
|
||||
|
||||
if (pin >= WIIGPIO_NPINS)
|
||||
return (EINVAL);
|
||||
sc = device_get_softc(dev);
|
||||
WIIGPIO_LOCK(sc);
|
||||
reg = wiigpio_read(sc, WIIGPIO_PINBANK(pin));
|
||||
*val = !!(reg & WIIGPIO_PINMASK(pin));
|
||||
WIIGPIO_UNLOCK(sc);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
wiigpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
|
||||
{
|
||||
struct wiigpio_softc *sc;
|
||||
uint32_t reg, pinbank, pinmask;
|
||||
|
||||
if (pin >= WIIGPIO_NPINS)
|
||||
return (EINVAL);
|
||||
sc = device_get_softc(dev);
|
||||
pinbank = WIIGPIO_PINBANK(pin);
|
||||
pinmask = WIIGPIO_PINMASK(pin);
|
||||
WIIGPIO_LOCK(sc);
|
||||
reg = wiigpio_read(sc, pinbank) & ~pinmask;
|
||||
if (value)
|
||||
reg |= pinmask;
|
||||
wiigpio_write(sc, pinbank, reg);
|
||||
WIIGPIO_UNLOCK(sc);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
wiigpio_pin_toggle(device_t dev, uint32_t pin)
|
||||
{
|
||||
struct wiigpio_softc *sc;
|
||||
uint32_t val, pinbank, pinmask;
|
||||
|
||||
if (pin >= WIIGPIO_NPINS)
|
||||
return (EINVAL);
|
||||
sc = device_get_softc(dev);
|
||||
pinbank = WIIGPIO_PINBANK(pin);
|
||||
pinmask = WIIGPIO_PINMASK(pin);
|
||||
WIIGPIO_LOCK(sc);
|
||||
val = wiigpio_read(sc, pinbank);
|
||||
if (val & pinmask)
|
||||
wiigpio_write(sc, pinbank, val & ~pinmask);
|
||||
else
|
||||
wiigpio_write(sc, pinbank, val | pinmask);
|
||||
WIIGPIO_UNLOCK(sc);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
wiigpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
|
||||
{
|
||||
struct wiigpio_softc *sc;
|
||||
uint32_t reg, pinbank, pinmask;
|
||||
|
||||
if (pin >= WIIGPIO_NPINS)
|
||||
return (EINVAL);
|
||||
sc = device_get_softc(dev);
|
||||
pinbank = WIIGPIO_PINBANK(pin);
|
||||
pinmask = WIIGPIO_PINMASK(pin);
|
||||
WIIGPIO_LOCK(sc);
|
||||
reg = wiigpio_dir_read(sc, WIIGPIO_PINBANK(pin));
|
||||
if (flags & GPIO_PIN_OUTPUT)
|
||||
wiigpio_dir_write(sc, pinbank, reg | pinmask);
|
||||
else
|
||||
wiigpio_dir_write(sc, pinbank, reg & ~pinmask);
|
||||
sc->sc_pins[pin].gp_flags = flags;
|
||||
WIIGPIO_UNLOCK(sc);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
wiigpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
|
||||
{
|
||||
struct wiigpio_softc *sc;
|
||||
|
||||
if (pin >= WIIGPIO_NPINS)
|
||||
return (EINVAL);
|
||||
sc = device_get_softc(dev);
|
||||
WIIGPIO_LOCK(sc);
|
||||
*flags = sc->sc_pins[pin].gp_flags;
|
||||
WIIGPIO_UNLOCK(sc);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
wiigpio_pin_getname(device_t dev, uint32_t pin, char *name)
|
||||
{
|
||||
struct wiigpio_softc *sc;
|
||||
|
||||
if (pin >= WIIGPIO_NPINS)
|
||||
return (EINVAL);
|
||||
sc = device_get_softc(dev);
|
||||
WIIGPIO_LOCK(sc);
|
||||
memcpy(name, sc->sc_pins[pin].gp_name, GPIOMAXNAME);
|
||||
WIIGPIO_UNLOCK(sc);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
wiigpio_shutdown(void *xdev, int howto)
|
||||
{
|
||||
device_t dev;
|
||||
|
||||
if (!(howto & RB_POWEROFF))
|
||||
return;
|
||||
dev = (device_t)xdev;
|
||||
wiigpio_pin_setflags(dev, WIIGPIO_POWEROFF_PIN, GPIO_PIN_OUTPUT);
|
||||
wiigpio_pin_set(dev, WIIGPIO_POWEROFF_PIN, 1);
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
/*-
|
||||
* Copyright (C) 2012 Margarida Gouveia
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _POWERPC_WII_WII_GPIOREG_H
|
||||
#define _POWERPC_WII_WII_GPIOREG_H
|
||||
|
||||
#define WIIGPIO_NPINS 64
|
||||
#define WIIGPIO_POWEROFF_PIN 33
|
||||
|
||||
#define WIIGPIO_REG_ADDR 0x0d8000c0
|
||||
#define WIIGPIO_REG_LEN 0x40
|
||||
|
||||
#endif /* _POWERPC_WII_WII_GPIOREG_H */
|
@ -1,102 +0,0 @@
|
||||
/*-
|
||||
* Copyright (C) 2012 Margarida Gouveia
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/platform.h>
|
||||
#include <machine/intr_machdep.h>
|
||||
#include <machine/resource.h>
|
||||
|
||||
#include <powerpc/wii/wii_ipcreg.h>
|
||||
|
||||
/*
|
||||
* Driver to interface with the Wii's IOS. IOS are small "microkernels" that run
|
||||
* on the Broadway GPU and provide access to system services like USB.
|
||||
*/
|
||||
static int wiiipc_probe(device_t);
|
||||
static int wiiipc_attach(device_t);
|
||||
|
||||
struct wiiipc_softc {
|
||||
};
|
||||
|
||||
static device_method_t wiiipc_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, wiiipc_probe),
|
||||
DEVMETHOD(device_attach, wiiipc_attach),
|
||||
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
static driver_t wiiipc_driver = {
|
||||
"wiiipc",
|
||||
wiiipc_methods,
|
||||
sizeof(struct wiiipc_softc)
|
||||
};
|
||||
|
||||
static devclass_t wiiipc_devclass;
|
||||
|
||||
DRIVER_MODULE(wiiipc, wiibus, wiiipc_driver, wiiipc_devclass, 0, 0);
|
||||
|
||||
static int
|
||||
wiiipc_probe(device_t dev)
|
||||
{
|
||||
device_set_desc(dev, "Nintendo Wii IOS IPC");
|
||||
|
||||
return (BUS_PROBE_NOWILDCARD);
|
||||
}
|
||||
|
||||
static int
|
||||
wiiipc_attach(device_t dev)
|
||||
{
|
||||
struct wiiipc_softc *sc;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
#ifdef notyet
|
||||
sc->sc_dev = dev;
|
||||
|
||||
sc->sc_rrid = 0;
|
||||
sc->sc_rres = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
|
||||
&sc->sc_rrid, RF_ACTIVE);
|
||||
if (sc->sc_rres == NULL) {
|
||||
device_printf(dev, "could not alloc mem resource\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
sc->sc_bt = rman_get_bustag(sc->sc_rres);
|
||||
sc->sc_bh = rman_get_bushandle(sc->sc_rres);
|
||||
#endif
|
||||
|
||||
return (0);
|
||||
}
|
@ -1,102 +0,0 @@
|
||||
/*-
|
||||
* Copyright (C) 2012 Margarida Gouveia
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _POWERPC_WII_WII_IPCREG_H
|
||||
#define _POWERPC_WII_WII_IPCREG_H
|
||||
|
||||
#define WIIIPC_REG_ADDR 0x0d000000
|
||||
#define WIIIPC_REG_LEN 0x40
|
||||
#define WIIIPC_IOH_ADDR 0x133e0000
|
||||
#define WIIIPC_IOH_LEN 0xc20000
|
||||
|
||||
#define WIIIPC_TXBUF 0x00
|
||||
#define WIIIPC_CSR 0x04
|
||||
#define WIIIPC_CSR_TXSTART 0x01
|
||||
#define WIIIPC_CSR_TBEI 0x02
|
||||
#define WIIIPC_CSR_RBFI 0x04
|
||||
#define WIIIPC_CSR_RXREADY 0x08
|
||||
#define WIIIPC_CSR_RBFIMASK 0x10
|
||||
#define WIIIPC_CSR_TBEIMASK 0x20
|
||||
#define WIIIPC_RXBUF 0x08
|
||||
#define WIIIPC_ISR 0x30
|
||||
#define WIIIPC_ISR_MAGIC 0x40000000
|
||||
|
||||
enum wiiipc_cmd {
|
||||
WIIIPC_CMD_OPEN = 1,
|
||||
WIIIPC_CMD_CLOSE = 2,
|
||||
WIIIPC_CMD_READ = 3,
|
||||
WIIIPC_CMD_WRITE = 4,
|
||||
WIIIPC_CMD_SEEK = 5,
|
||||
WIIIPC_CMD_IOCTL = 6,
|
||||
WIIIPC_CMD_IOCTLV = 7,
|
||||
WIIIPC_CMD_ASYNCRESP = 8
|
||||
};
|
||||
|
||||
struct wiiipc_ipc_msg {
|
||||
uint32_t ipc_cmd;
|
||||
int32_t ipc_result;
|
||||
int32_t ipc_fd; /* WIIIPC_CMD_ASYNCRESP - the original cmd */
|
||||
union {
|
||||
struct {
|
||||
intptr_t pathname;
|
||||
uint32_t mode;
|
||||
} _ipc_open;
|
||||
struct {
|
||||
intptr_t data;
|
||||
uint32_t len;
|
||||
} _ipc_read, _ipc_write;
|
||||
struct {
|
||||
int32_t offset;
|
||||
int32_t whence;
|
||||
} _ipc_seek;
|
||||
struct {
|
||||
uint32_t request;
|
||||
intptr_t ibuf;
|
||||
uint32_t ilen;
|
||||
intptr_t obuf;
|
||||
uint32_t olen;
|
||||
} _ipc_ioctl;
|
||||
struct {
|
||||
uint32_t request;
|
||||
uint32_t argin;
|
||||
uint32_t argout;
|
||||
intptr_t iovec;
|
||||
} _ipc_ioctlv;
|
||||
uint32_t _ipc_argv[5];
|
||||
} args;
|
||||
} __attribute__((packed));
|
||||
|
||||
CTASSERT(sizeof(struct wiiipc_ipc_msg) == 32);
|
||||
|
||||
#define ipc_open args._ipc_open
|
||||
#define ipc_read args._ipc_read
|
||||
#define ipc_write args._ipc_write
|
||||
#define ipc_ioctl args._ipc_ioctl
|
||||
#define ipc_ioctlv args._ipc_ioctlv
|
||||
|
||||
#endif /* _POWERPC_WII_WII_IPCREG_H */
|
@ -1,244 +0,0 @@
|
||||
/*-
|
||||
* Copyright (C) 2012 Margarida Gouveia
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/rman.h>
|
||||
#include <sys/reboot.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/platform.h>
|
||||
#include <machine/intr_machdep.h>
|
||||
#include <machine/resource.h>
|
||||
|
||||
#include <powerpc/wii/wii_picreg.h>
|
||||
|
||||
#include "pic_if.h"
|
||||
|
||||
static int wiipic_probe(device_t);
|
||||
static int wiipic_attach(device_t);
|
||||
static void wiipic_dispatch(device_t, struct trapframe *);
|
||||
static void wiipic_enable(device_t, unsigned int, unsigned int);
|
||||
static void wiipic_eoi(device_t, unsigned int);
|
||||
static void wiipic_mask(device_t, unsigned int);
|
||||
static void wiipic_unmask(device_t, unsigned int);
|
||||
static void wiipic_intr(void *);
|
||||
|
||||
struct wiipic_softc {
|
||||
device_t sc_dev;
|
||||
struct resource *sc_rres;
|
||||
bus_space_tag_t sc_bt;
|
||||
bus_space_handle_t sc_bh;
|
||||
int sc_rrid;
|
||||
int sc_irqid;
|
||||
struct resource *sc_irq;
|
||||
void *sc_irqctx;
|
||||
int sc_vector[WIIPIC_NIRQ];
|
||||
};
|
||||
|
||||
static device_method_t wiipic_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, wiipic_probe),
|
||||
DEVMETHOD(device_attach, wiipic_attach),
|
||||
|
||||
/* PIC interface */
|
||||
DEVMETHOD(pic_dispatch, wiipic_dispatch),
|
||||
DEVMETHOD(pic_enable, wiipic_enable),
|
||||
DEVMETHOD(pic_eoi, wiipic_eoi),
|
||||
DEVMETHOD(pic_mask, wiipic_mask),
|
||||
DEVMETHOD(pic_unmask, wiipic_unmask),
|
||||
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
static driver_t wiipic_driver = {
|
||||
"wiipic",
|
||||
wiipic_methods,
|
||||
sizeof(struct wiipic_softc)
|
||||
};
|
||||
|
||||
static devclass_t wiipic_devclass;
|
||||
|
||||
DRIVER_MODULE(wiipic, wiibus, wiipic_driver, wiipic_devclass, 0, 0);
|
||||
|
||||
static __inline uint32_t
|
||||
wiipic_imr_read(struct wiipic_softc *sc)
|
||||
{
|
||||
|
||||
return (bus_space_read_4(sc->sc_bt, sc->sc_bh, WIIPIC_IMR));
|
||||
}
|
||||
|
||||
static __inline void
|
||||
wiipic_imr_write(struct wiipic_softc *sc, uint32_t imr)
|
||||
{
|
||||
|
||||
bus_space_write_4(sc->sc_bt, sc->sc_bh, WIIPIC_IMR, imr);
|
||||
}
|
||||
|
||||
static __inline uint32_t
|
||||
wiipic_icr_read(struct wiipic_softc *sc)
|
||||
{
|
||||
|
||||
return (bus_space_read_4(sc->sc_bt, sc->sc_bh, WIIPIC_ICR));
|
||||
}
|
||||
|
||||
static __inline void
|
||||
wiipic_icr_write(struct wiipic_softc *sc, uint32_t icr)
|
||||
{
|
||||
|
||||
bus_space_write_4(sc->sc_bt, sc->sc_bh, WIIPIC_ICR, icr);
|
||||
}
|
||||
|
||||
static int
|
||||
wiipic_probe(device_t dev)
|
||||
{
|
||||
device_set_desc(dev, "Nintendo Wii PIC");
|
||||
|
||||
return (BUS_PROBE_NOWILDCARD);
|
||||
}
|
||||
|
||||
static int
|
||||
wiipic_attach(device_t dev)
|
||||
{
|
||||
struct wiipic_softc *sc;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
sc->sc_dev = dev;
|
||||
|
||||
sc->sc_rrid = 0;
|
||||
sc->sc_rres = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
|
||||
&sc->sc_rrid, RF_ACTIVE);
|
||||
if (sc->sc_rres == NULL) {
|
||||
device_printf(dev, "could not alloc mem resource\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
sc->sc_bt = rman_get_bustag(sc->sc_rres);
|
||||
sc->sc_bh = rman_get_bushandle(sc->sc_rres);
|
||||
|
||||
/* Turn off all interrupts */
|
||||
wiipic_imr_write(sc, 0x00000000);
|
||||
wiipic_icr_write(sc, 0xffffffff);
|
||||
|
||||
powerpc_register_pic(dev, 0, WIIPIC_NIRQ, 0, FALSE);
|
||||
|
||||
/*
|
||||
* Setup the interrupt handler.
|
||||
*/
|
||||
sc->sc_irqid = 0;
|
||||
sc->sc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->sc_irqid,
|
||||
RF_ACTIVE);
|
||||
if (sc->sc_irq == NULL) {
|
||||
device_printf(dev, "could not alloc IRQ resource\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_MISC | INTR_MPSAFE,
|
||||
NULL, wiipic_intr, sc, &sc->sc_irqctx);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
wiipic_dispatch(device_t dev, struct trapframe *tf)
|
||||
{
|
||||
struct wiipic_softc *sc;
|
||||
uint32_t irq;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
irq = wiipic_icr_read(sc) & wiipic_imr_read(sc);
|
||||
if (irq == 0)
|
||||
return;
|
||||
irq = ffs(irq) - 1;
|
||||
KASSERT(irq < WIIPIC_NIRQ, ("bogus irq %d", irq));
|
||||
powerpc_dispatch_intr(sc->sc_vector[irq], tf);
|
||||
}
|
||||
|
||||
static void
|
||||
wiipic_enable(device_t dev, unsigned int irq, unsigned int vector)
|
||||
{
|
||||
struct wiipic_softc *sc;
|
||||
|
||||
KASSERT(irq < WIIPIC_NIRQ, ("bogus irq %d", irq));
|
||||
sc = device_get_softc(dev);
|
||||
sc->sc_vector[irq] = vector;
|
||||
wiipic_unmask(dev, irq);
|
||||
}
|
||||
|
||||
static void
|
||||
wiipic_eoi(device_t dev, unsigned int irq)
|
||||
{
|
||||
struct wiipic_softc *sc;
|
||||
uint32_t icr;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
icr = wiipic_icr_read(sc);
|
||||
icr |= (1 << irq);
|
||||
wiipic_icr_write(sc, icr);
|
||||
}
|
||||
|
||||
static void
|
||||
wiipic_mask(device_t dev, unsigned int irq)
|
||||
{
|
||||
struct wiipic_softc *sc;
|
||||
uint32_t imr;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
imr = wiipic_imr_read(sc);
|
||||
imr &= ~(1 << irq);
|
||||
wiipic_imr_write(sc, imr);
|
||||
}
|
||||
|
||||
static void
|
||||
wiipic_unmask(device_t dev, unsigned int irq)
|
||||
{
|
||||
struct wiipic_softc *sc;
|
||||
uint32_t imr;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
imr = wiipic_imr_read(sc);
|
||||
imr |= (1 << irq);
|
||||
wiipic_imr_write(sc, imr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset button interrupt.
|
||||
*/
|
||||
static void
|
||||
wiipic_intr(void *xsc)
|
||||
{
|
||||
struct wiipic_softc *sc;
|
||||
|
||||
sc = (struct wiipic_softc *)xsc;
|
||||
if (wiipic_icr_read(sc) & WIIPIC_RBS)
|
||||
shutdown_nice(RB_AUTOBOOT);
|
||||
}
|
||||
|
@ -1,42 +0,0 @@
|
||||
/*-
|
||||
* Copyright (C) 2012 Margarida Gouveia
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _POWERPC_WII_WII_PICREG_H
|
||||
#define _POWERPC_WII_WII_PICREG_H
|
||||
|
||||
#define WIIPIC_REG_ADDR 0x0c003000
|
||||
#define WIIPIC_REG_LEN 0x28
|
||||
|
||||
#define WIIPIC_ICR 0x00
|
||||
#define WIIPIC_RBS 0x10000
|
||||
#define WIIPIC_IMR 0x04
|
||||
#define WIIPIC_RESET 0x24
|
||||
|
||||
#define WIIPIC_NIRQ 32
|
||||
|
||||
#endif /* _POWERPC_WII_WII_PICREG_H */
|
Loading…
Reference in New Issue
Block a user