Module Name: src Committed By: jmcneill Date: Sun Oct 13 16:21:37 UTC 2024
Modified Files: src/sys/arch/evbppc/include: wii.h src/sys/arch/evbppc/wii: autoconf.c machdep.c wii_locore.S wii_mmuinit.S src/sys/arch/evbppc/wii/dev: avenc.c ehci_hollywood.c vireg.h wiifb.c Log Message: wii: Support loading the kernel from boot2 Improve hardware initialization steps so the NetBSD kernel can be launched directly from boot2 and does not rely on any other PPC software to setup the hardware. To generate a diff of this commit: cvs rdiff -u -r1.8 -r1.9 src/sys/arch/evbppc/include/wii.h cvs rdiff -u -r1.2 -r1.3 src/sys/arch/evbppc/wii/autoconf.c \ src/sys/arch/evbppc/wii/wii_locore.S cvs rdiff -u -r1.6 -r1.7 src/sys/arch/evbppc/wii/machdep.c cvs rdiff -u -r1.1 -r1.2 src/sys/arch/evbppc/wii/wii_mmuinit.S cvs rdiff -u -r1.1 -r1.2 src/sys/arch/evbppc/wii/dev/avenc.c cvs rdiff -u -r1.3 -r1.4 src/sys/arch/evbppc/wii/dev/ehci_hollywood.c cvs rdiff -u -r1.2 -r1.3 src/sys/arch/evbppc/wii/dev/vireg.h cvs rdiff -u -r1.6 -r1.7 src/sys/arch/evbppc/wii/dev/wiifb.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/evbppc/include/wii.h diff -u src/sys/arch/evbppc/include/wii.h:1.8 src/sys/arch/evbppc/include/wii.h:1.9 --- src/sys/arch/evbppc/include/wii.h:1.8 Sun Sep 22 13:56:25 2024 +++ src/sys/arch/evbppc/include/wii.h Sun Oct 13 16:21:36 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: wii.h,v 1.8 2024/09/22 13:56:25 jmcneill Exp $ */ +/* $NetBSD: wii.h,v 1.9 2024/10/13 16:21:36 jmcneill Exp $ */ /*- * Copyright (c) 2024 Jared McNeill <jmcne...@invisible.ca> @@ -119,6 +119,8 @@ #define IOPOH1EN __BIT(22) #define IOPOH0EN __BIT(21) #define IOPEHCEN __BIT(20) +#define HW_AIPPROT (HOLLYWOOD_PRIV_BASE + 0x070) +#define ENAHBIOPI __BIT(0) #define HW_GPIOB_OUT (HOLLYWOOD_BASE + 0x0c0) #define HW_GPIOB_DIR (HOLLYWOOD_BASE + 0x0c4) #define HW_GPIOB_IN (HOLLYWOOD_BASE + 0x0c8) @@ -155,4 +157,19 @@ wii_slot_led_blink(u_int interval_us) } } +/* Enable or disable the slot LED. */ +static inline void +wii_slot_led(bool enable) +{ + uint32_t val; + + val = in32(HW_GPIOB_OUT); + if (enable) { + val |= __BIT(GPIO_SLOT_LED); + } else { + val &= ~__BIT(GPIO_SLOT_LED); + } + out32(HW_GPIOB_OUT, val); +} + #endif /* !_WII_H */ Index: src/sys/arch/evbppc/wii/autoconf.c diff -u src/sys/arch/evbppc/wii/autoconf.c:1.2 src/sys/arch/evbppc/wii/autoconf.c:1.3 --- src/sys/arch/evbppc/wii/autoconf.c:1.2 Wed Jan 24 21:53:34 2024 +++ src/sys/arch/evbppc/wii/autoconf.c Sun Oct 13 16:21:37 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: autoconf.c,v 1.2 2024/01/24 21:53:34 jmcneill Exp $ */ +/* $NetBSD: autoconf.c,v 1.3 2024/10/13 16:21:37 jmcneill Exp $ */ /*- * Copyright (c) 1990 The Regents of the University of California. @@ -44,7 +44,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.2 2024/01/24 21:53:34 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.3 2024/10/13 16:21:37 jmcneill Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -77,6 +77,8 @@ cpu_configure(void) panic("configure: mainbus not configured"); genppc_cpu_configure(); + + wii_slot_led(false); } void Index: src/sys/arch/evbppc/wii/wii_locore.S diff -u src/sys/arch/evbppc/wii/wii_locore.S:1.2 src/sys/arch/evbppc/wii/wii_locore.S:1.3 --- src/sys/arch/evbppc/wii/wii_locore.S:1.2 Wed Jan 24 21:53:34 2024 +++ src/sys/arch/evbppc/wii/wii_locore.S Sun Oct 13 16:21:37 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: wii_locore.S,v 1.2 2024/01/24 21:53:34 jmcneill Exp $ */ +/* $NetBSD: wii_locore.S,v 1.3 2024/10/13 16:21:37 jmcneill Exp $ */ /* $OpenBSD: locore.S,v 1.4 1997/01/26 09:06:38 rahnds Exp $ */ /* @@ -97,27 +97,35 @@ __mmu_init: #include "wii_mmuinit.S" /* compute end of kernel memory */ - lis 4,_C_LABEL(end)@ha - addi 4,4,_C_LABEL(end)@l - rlwinm 4,4,0,1,31 - - INIT_CPUINFO(4,1,9,5) - - lis 3,__start@ha - addi 3,3,__start@l - rlwinm 3,3,0,1,31 - - xor 5,5,5 - xor 6,6,6 - bl _C_LABEL(cpu_model_init) + lis %r4, _C_LABEL(end)@ha + addi %r4, %r4, _C_LABEL(end)@l + +#if NKSYMS || defined(DDB) || defined(MODULAR) + /* If we had symbol table location we'd store it here and would've adjusted r4 here */ + lis %r7, _C_LABEL(startsym)@ha + addi %r7, %r7, _C_LABEL(startsym)@l + stw %r4, 0(%r7) + lis %r7, _C_LABEL(endsym)@ha + addi %r7, %r7,_C_LABEL(endsym)@l + stw %r4, 0(%r7) +#endif + + lis %r1, 0 + INIT_CPUINFO(%r4, %r1, %r9, %r0) + + lis %r3, __start@ha + addi %r3, %r3, __start@l + + xor %r5, %r5, %r5 + xor %r6, %r6, %r6 bl _C_LABEL(initppc) sync isync - mfspr 8,SPR_HID0 - ori 8, 8, (HID0_ICE | HID0_DCE)@l + mfspr %r8, SPR_HID0 + ori %r8, %r8, (HID0_ICE | HID0_DCE)@l isync - mtspr SPR_HID0,8 + mtspr SPR_HID0, %r8 sync isync @@ -127,16 +135,16 @@ loop: b loop /* XXX not reached */ .globl _C_LABEL(enable_intr) _C_LABEL(enable_intr): - mfmsr 3 - ori 3,3,PSL_EE@l - mtmsr 3 + mfmsr %r3 + ori %r3, %r3, PSL_EE@l + mtmsr %r3 blr .globl _C_LABEL(disable_intr) _C_LABEL(disable_intr): - mfmsr 3 - andi. 3,3,~PSL_EE@l - mtmsr 3 + mfmsr %r3 + andi. %r3, %r3, ~PSL_EE@l + mtmsr %r3 blr /* Index: src/sys/arch/evbppc/wii/machdep.c diff -u src/sys/arch/evbppc/wii/machdep.c:1.6 src/sys/arch/evbppc/wii/machdep.c:1.7 --- src/sys/arch/evbppc/wii/machdep.c:1.6 Tue Mar 5 14:15:31 2024 +++ src/sys/arch/evbppc/wii/machdep.c Sun Oct 13 16:21:37 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.6 2024/03/05 14:15:31 thorpej Exp $ */ +/* $NetBSD: machdep.c,v 1.7 2024/10/13 16:21:37 jmcneill Exp $ */ /* * Copyright (c) 2002, 2024 The NetBSD Foundation, Inc. @@ -63,7 +63,7 @@ #define _POWERPC_BUS_DMA_PRIVATE #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.6 2024/03/05 14:15:31 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.7 2024/10/13 16:21:37 jmcneill Exp $"); #include "opt_compat_netbsd.h" #include "opt_ddb.h" @@ -122,11 +122,17 @@ __KERNEL_RCSID(0, "$NetBSD: machdep.c,v #include "ksyms.h" #include "ukbd.h" +#ifndef WII_DEFAULT_CMDLINE +#define WII_DEFAULT_CMDLINE "root=ld0a" +#endif + #define IBM750CL_SPR_HID4 1011 #define L2_CCFI 0x00100000 /* L2 complete castout prior * to L2 flash invalidate. */ +#define MINI_MEM2_START 0x13f00000 /* Start of reserved MEM2 for MINI */ + extern u_int l2cr_config; struct powerpc_bus_space wii_mem_tag = { @@ -233,15 +239,29 @@ initppc(u_int startkernel, u_int endkern memset(&edata, 0, end - edata); /* clear BSS */ + wii_cmdline[0] = '\0'; if (wii_argv.magic == WII_ARGV_MAGIC) { void *ptr = (void *)(uintptr_t)(wii_argv.cmdline & ~0x80000000); if (ptr != NULL) { memcpy(wii_cmdline, ptr, wii_argv.length); } + } else { + snprintf(wii_cmdline, sizeof(wii_cmdline), WII_DEFAULT_CMDLINE); } mem2_start = in32(GLOBAL_MEM2_AVAIL_START) & ~0x80000000; mem2_end = in32(GLOBAL_MEM2_AVAIL_END) & ~0x80000000; + if (mem2_start < WII_MEM2_BASE) { + /* Must have been booted from MINI. */ + mem2_start = WII_MEM2_BASE + DSP_MEM_SIZE; + mem2_end = MINI_MEM2_START; + } + /* + * Clear GLOBAL_MEM2_AVAIL_{START,END} so we can detect the correct + * memory size when soft resetting from IOS to MINI. + */ + out32(GLOBAL_MEM2_AVAIL_START, 0); + out32(GLOBAL_MEM2_AVAIL_END, 0); /* MEM1 24MB 1T-SRAM */ physmemr[0].start = WII_MEM1_BASE; @@ -407,10 +427,13 @@ static void wii_setup(void) { /* Turn on the drive slot LED. */ - out32(HW_GPIOB_OUT, in32(HW_GPIOB_OUT) | __BIT(GPIO_SLOT_LED)); + wii_slot_led(true); /* Enable PPC access to SHUTDOWN GPIO. */ out32(HW_GPIO_OWNER, in32(HW_GPIO_OWNER) | __BIT(GPIO_SHUTDOWN)); + + /* Enable PPC access to EXI bus. */ + out32(HW_AIPPROT, in32(HW_AIPPROT) | ENAHBIOPI); } static void Index: src/sys/arch/evbppc/wii/wii_mmuinit.S diff -u src/sys/arch/evbppc/wii/wii_mmuinit.S:1.1 src/sys/arch/evbppc/wii/wii_mmuinit.S:1.2 --- src/sys/arch/evbppc/wii/wii_mmuinit.S:1.1 Sat Jan 20 21:36:00 2024 +++ src/sys/arch/evbppc/wii/wii_mmuinit.S Sun Oct 13 16:21:37 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: wii_mmuinit.S,v 1.1 2024/01/20 21:36:00 jmcneill Exp $ */ +/* $NetBSD: wii_mmuinit.S,v 1.2 2024/10/13 16:21:37 jmcneill Exp $ */ /*- * Copyright (C) 2012 Margarida Gouveia @@ -67,6 +67,27 @@ MMU_REALMODE() + /* Initialize HID0 and HID4 */ + lis %r11, 0x0011 + ori %r11, %r11, 0x0c64 + mtspr SPR_HID0, %r11 + isync + + lis %r11, 0x8200 + mtspr 1011, %r11 /* 1011 = SPR_HID4 */ + isync + + mfspr %r11, 920 + oris %r11, %r11, 0xa000 + mtspr 920, %r11 + + mfspr %r11, SPR_HID0 + ori %r11, %r11, 0xc000 + ori %r11, %r11, 0x0800 + ori %r11, %r11, 0x0200 + mtspr SPR_HID0, %r11 + isync + /* Reset standard BATs */ li %r11, 0 mtibatu 0, %r11 Index: src/sys/arch/evbppc/wii/dev/avenc.c diff -u src/sys/arch/evbppc/wii/dev/avenc.c:1.1 src/sys/arch/evbppc/wii/dev/avenc.c:1.2 --- src/sys/arch/evbppc/wii/dev/avenc.c:1.1 Tue Jan 23 21:48:12 2024 +++ src/sys/arch/evbppc/wii/dev/avenc.c Sun Oct 13 16:21:37 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: avenc.c,v 1.1 2024/01/23 21:48:12 jmcneill Exp $ */ +/* $NetBSD: avenc.c,v 1.2 2024/10/13 16:21:37 jmcneill Exp $ */ /*- * Copyright (c) 2024 Jared McNeill <jmcne...@invisible.ca> @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: avenc.c,v 1.1 2024/01/23 21:48:12 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: avenc.c,v 1.2 2024/10/13 16:21:37 jmcneill Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -36,12 +36,14 @@ __KERNEL_RCSID(0, "$NetBSD: avenc.c,v 1. #include <sys/conf.h> #include <sys/bus.h> #include <sys/kmem.h> +#include <machine/wii.h> #include <lib/libkern/libkern.h> /* hexdump */ #include <dev/i2c/i2cvar.h> #include "avenc.h" +#include "vireg.h" #define AVENC_DEBUG 0 @@ -53,7 +55,10 @@ __KERNEL_RCSID(0, "$NetBSD: avenc.c,v 1. #define RD1 avenc_read_1 #define RD2 avenc_read_2 +#define WR1 avenc_write_1 #define WR2 avenc_write_2 +#define WR4 avenc_write_4 +#define WRBUF avenc_write_buf static i2c_tag_t avenc_tag; static i2c_addr_t avenc_addr; @@ -73,19 +78,54 @@ avenc_read_1(i2c_tag_t tag, i2c_addr_t a static uint16_t avenc_read_2(i2c_tag_t tag, i2c_addr_t addr, uint8_t reg) { - uint16_t val; + uint8_t vbuf[2]; - if (iic_smbus_read_word(tag, addr, reg, &val, 0) != 0) { - val = 0xffff; + if (iic_exec(tag, I2C_OP_READ_WITH_STOP, addr, ®, 1, + vbuf, sizeof(vbuf), 0) != 0) { + return 0xffff; + } else { + return ((uint16_t)vbuf[0] << 8) | vbuf[1]; } +} - return val; +static void +avenc_write_1(i2c_tag_t tag, i2c_addr_t addr, uint8_t reg, uint8_t val) +{ + iic_smbus_write_byte(tag, addr, reg, val, 0); } static void avenc_write_2(i2c_tag_t tag, i2c_addr_t addr, uint8_t reg, uint16_t val) { - iic_smbus_write_word(tag, addr, reg, val, 0); + uint8_t vbuf[2]; + + vbuf[0] = (val >> 8) & 0xff; + vbuf[1] = val & 0xff; + + iic_exec(tag, I2C_OP_WRITE_WITH_STOP, addr, ®, 1, + vbuf, sizeof(vbuf), 0); +} + +static void +avenc_write_4(i2c_tag_t tag, i2c_addr_t addr, uint8_t reg, uint32_t val) +{ + uint8_t vbuf[4]; + + vbuf[0] = (val >> 24) & 0xff; + vbuf[1] = (val >> 16) & 0xff; + vbuf[2] = (val >> 8) & 0xff; + vbuf[3] = val & 0xff; + + iic_exec(tag, I2C_OP_WRITE_WITH_STOP, addr, ®, 1, + vbuf, sizeof(vbuf), 0); +} + +static void +avenc_write_buf(i2c_tag_t tag, i2c_addr_t addr, uint8_t reg, uint8_t *buf, + size_t buflen) +{ + iic_exec(tag, I2C_OP_WRITE_WITH_STOP, addr, ®, 1, + buf, buflen, 0); } void @@ -124,7 +164,7 @@ avenc_set_volume(uint8_t left, uint8_t r } static void -avenc_dump_regs(i2c_tag_t tag, i2c_addr_t addr) +avenc_dump_regs(const char *pfx, i2c_tag_t tag, i2c_addr_t addr) { uint8_t regdump[0x100]; unsigned int reg; @@ -137,9 +177,54 @@ avenc_dump_regs(i2c_tag_t tag, i2c_addr_ iic_release_bus(tag, 0); - hexdump(printf, "avenc0", regdump, sizeof(regdump)); + hexdump(printf, pfx, regdump, sizeof(regdump)); +} + +static void +avenc_init(i2c_tag_t tag, i2c_addr_t addr) +{ + uint8_t mvinit[26] = {}; + uint8_t ginit[] = { + 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, + 0x10, 0x00, 0x10, 0x00, 0x10, 0x20, 0x40, 0x60, + 0x80, 0xa0, 0xeb, 0x10, 0x00, 0x20, 0x00, 0x40, + 0x00, 0x60, 0x00, 0x80, 0x00, 0xa0, 0x00, 0xeb, + 0x00 + }; + uint8_t video_fmt; + + video_fmt = 0; + if (__SHIFTOUT(in16(VI_BASE + VI_DCR), VI_DCR_FMT) == VI_DCR_FMT_PAL) { + video_fmt |= 0x02; + } + if ((in16(VI_BASE + VI_VISEL) & VI_VISEL_COMPONENT_CABLE) != 0) { + video_fmt |= 0x20; + } + + iic_acquire_bus(tag, 0); + WR1(tag, addr, 0x6a, 1); + WR1(tag, addr, 0x65, 3); + WR1(tag, addr, 0x01, video_fmt); + WR1(tag, addr, 0x00, 0); + WR1(tag, addr, 0x02, 7); + WR2(tag, addr, 0x05, 0); + WR2(tag, addr, 0x08, 0); + WR4(tag, addr, 0x7a, 0); + WRBUF(tag, addr, 0x40, mvinit, sizeof(mvinit)); + WR1(tag, addr, 0x0a, 0); + WR1(tag, addr, 0x03, 1); + WRBUF(tag, addr, 0x10, ginit, sizeof(ginit)); + WR1(tag, addr, 0x04, 1); + WR4(tag, addr, 0x7a, 0); + WR2(tag, addr, 0x08, 0); + WR1(tag, addr, 0x03, 1); + WR1(tag, addr, 0x6e, 0); + iic_release_bus(tag, 0); + + avenc_set_volume(0x8e, 0x8e); } + static int avenc_match(device_t parent, cfdata_t match, void *aux) { @@ -161,11 +246,17 @@ avenc_attach(device_t parent, device_t s aprint_normal(": A/V Encoder\n"); if (AVENC_DEBUG) { - avenc_dump_regs(tag, addr); + avenc_dump_regs("avenc pre ", tag, addr); } avenc_tag = tag; avenc_addr = addr; + + avenc_init(tag, addr); + + if (AVENC_DEBUG) { + avenc_dump_regs("avenc post", tag, addr); + } } CFATTACH_DECL_NEW(avenc, 0, avenc_match, avenc_attach, NULL, NULL); Index: src/sys/arch/evbppc/wii/dev/ehci_hollywood.c diff -u src/sys/arch/evbppc/wii/dev/ehci_hollywood.c:1.3 src/sys/arch/evbppc/wii/dev/ehci_hollywood.c:1.4 --- src/sys/arch/evbppc/wii/dev/ehci_hollywood.c:1.3 Sun Sep 22 13:56:25 2024 +++ src/sys/arch/evbppc/wii/dev/ehci_hollywood.c Sun Oct 13 16:21:37 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: ehci_hollywood.c,v 1.3 2024/09/22 13:56:25 jmcneill Exp $ */ +/* $NetBSD: ehci_hollywood.c,v 1.4 2024/10/13 16:21:37 jmcneill Exp $ */ /*- * Copyright (c) 2024 Jared McNeill <jmcne...@invisible.ca> @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ehci_hollywood.c,v 1.3 2024/09/22 13:56:25 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ehci_hollywood.c,v 1.4 2024/10/13 16:21:37 jmcneill Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -44,6 +44,9 @@ __KERNEL_RCSID(0, "$NetBSD: ehci_hollywo #include <machine/wii.h> #include "hollywood.h" +#define USB_CHICKENBITS 0x0d0400cc +#define EHCI_INTR_ENABLE 0x00008000 + extern struct powerpc_bus_dma_tag wii_mem2_bus_dma_tag; static int ehci_hollywood_match(device_t, cfdata_t, void *); @@ -86,6 +89,8 @@ ehci_hollywood_attach(device_t parent, d sc->sc_offs = EREAD1(sc, EHCI_CAPLENGTH); EOWRITE4(sc, EHCI_USBINTR, 0); + out32(USB_CHICKENBITS, in32(USB_CHICKENBITS) | EHCI_INTR_ENABLE); + hollywood_intr_establish(haa->haa_irq, IPL_USB, ehci_intr, sc, device_xname(self)); Index: src/sys/arch/evbppc/wii/dev/vireg.h diff -u src/sys/arch/evbppc/wii/dev/vireg.h:1.2 src/sys/arch/evbppc/wii/dev/vireg.h:1.3 --- src/sys/arch/evbppc/wii/dev/vireg.h:1.2 Sun Jan 21 13:05:29 2024 +++ src/sys/arch/evbppc/wii/dev/vireg.h Sun Oct 13 16:21:37 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: vireg.h,v 1.2 2024/01/21 13:05:29 jmcneill Exp $ */ +/* $NetBSD: vireg.h,v 1.3 2024/10/13 16:21:37 jmcneill Exp $ */ /*- * Copyright (c) 2024 Jared McNeill <jmcne...@invisible.ca> @@ -145,12 +145,13 @@ #define VI_HSR_STP __BITS(8,0) /* [4B] FCT[0-6] - Filter Coefficient Table 0-6 */ -#define VI_FCT0 0x50 -#define VI_FCT1 0x54 -#define VI_FCT2 0x58 -#define VI_FCT3 0x5c -#define VI_FCT4 0x60 -#define VI_FCT5 0x64 +#define VI_FCT0 0x4c +#define VI_FCT1 0x50 +#define VI_FCT2 0x54 +#define VI_FCT3 0x58 +#define VI_FCT4 0x5c +#define VI_FCT5 0x60 +#define VI_FCT6 0x64 /* [4B] ??? */ #define VI_UNKNOWN_68H 0x68 Index: src/sys/arch/evbppc/wii/dev/wiifb.c diff -u src/sys/arch/evbppc/wii/dev/wiifb.c:1.6 src/sys/arch/evbppc/wii/dev/wiifb.c:1.7 --- src/sys/arch/evbppc/wii/dev/wiifb.c:1.6 Mon Feb 5 23:48:35 2024 +++ src/sys/arch/evbppc/wii/dev/wiifb.c Sun Oct 13 16:21:37 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: wiifb.c,v 1.6 2024/02/05 23:48:35 jmcneill Exp $ */ +/* $NetBSD: wiifb.c,v 1.7 2024/10/13 16:21:37 jmcneill Exp $ */ /*- * Copyright (c) 2024 Jared McNeill <jmcne...@invisible.ca> @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: wiifb.c,v 1.6 2024/02/05 23:48:35 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wiifb.c,v 1.7 2024/10/13 16:21:37 jmcneill Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -221,8 +221,13 @@ wiifb_init(struct wiifb_softc *sc) } /* Reset video interface. */ - WR2(sc, VI_DCR, dcr | VI_DCR_RST); - WR2(sc, VI_DCR, dcr & ~VI_DCR_RST); + WR2(sc, VI_DCR, VI_DCR_RST); + delay(1000); + + /* Initialize video format and interlace selector. */ + dcr = __SHIFTIN(sc->sc_format, VI_DCR_FMT) | + (sc->sc_interlaced ? 0 : VI_DCR_NIN); + WR2(sc, VI_DCR, dcr); } static void @@ -241,6 +246,8 @@ wiifb_set_mode(struct wiifb_softc *sc, u WR4(sc, VI_VTE, 0x00020019); WR4(sc, VI_BBOI, 0x410C410C); WR4(sc, VI_BBEI, 0x40ED40ED); + WR2(sc, VI_DPV, 0x0000); + WR2(sc, VI_DPH, 0x0000); } else if (modeidx == WIIFB_MODE_INDEX(VI_DCR_FMT_NTSC, 0)) { /* NTSC 480p */ WR2(sc, VI_VTR, 0x1e0c); @@ -250,6 +257,8 @@ wiifb_set_mode(struct wiifb_softc *sc, u WR4(sc, VI_VTE, 0x00060030); WR4(sc, VI_BBOI, 0x81d881d8); WR4(sc, VI_BBEI, 0x81d881d8); + WR2(sc, VI_DPV, 0x0000); + WR2(sc, VI_DPH, 0x0000); } else if (modeidx == WIIFB_MODE_INDEX(VI_DCR_FMT_PAL, 1)) { /* PAL 576i */ WR2(sc, VI_VTR, 0x11f5); @@ -259,6 +268,8 @@ wiifb_set_mode(struct wiifb_softc *sc, u WR4(sc, VI_VTE, 0x00000024); WR4(sc, VI_BBOI, 0x4d2b4d6d); WR4(sc, VI_BBEI, 0x4d8a4d4c); + WR2(sc, VI_DPV, 0x013c); + WR2(sc, VI_DPH, 0x0144); } else { /* * Display mode is not supported. Blink the slot LED to @@ -273,6 +284,21 @@ wiifb_set_mode(struct wiifb_softc *sc, u } sc->sc_curmode = &wiifb_modes[modeidx]; + /* Filter coefficient table, values from YAGCD. */ + WR4(sc, VI_FCT0, 0x1ae771f0); + WR4(sc, VI_FCT1, 0x0db4a574); + WR4(sc, VI_FCT2, 0x00c1188e); + WR4(sc, VI_FCT3, 0xc4c0cbe2); + WR4(sc, VI_FCT4, 0xfcecdecf); + WR4(sc, VI_FCT5, 0x13130f08); + WR4(sc, VI_FCT6, 0x00080C0f); + + /* Unknown registers. */ + WR4(sc, VI_UNKNOWN_68H, 0x00ff0000); + WR2(sc, VI_UNKNOWN_76H, 0x00ff); + WR4(sc, VI_UNKNOWN_78H, 0x00ff00ff); + WR4(sc, VI_UNKNOWN_7CH, 0x00ff00ff); + /* Picture configuration */ strides = (sc->sc_curmode->width * 2) / (interlaced ? 16 : 32); reads = (sc->sc_curmode->width * 2) / 32; @@ -296,6 +322,9 @@ wiifb_set_mode(struct wiifb_softc *sc, u /* Set framebuffer address */ wiifb_set_fb(sc); + + /* Finally, enable the framebuffer */ + WR2(sc, VI_DCR, RD2(sc, VI_DCR) | VI_DCR_ENB); } static void