Module Name: src Committed By: jmcneill Date: Sat Mar 21 01:17:00 UTC 2015
Modified Files: src/sys/arch/arm/amlogic: amlogic_io.c amlogic_reg.h amlogic_var.h files.amlogic src/sys/arch/evbarm/amlogic: amlogic_machdep.c src/sys/arch/evbarm/conf: ODROID-C1 Added Files: src/sys/arch/arm/amlogic: amlogic_canvasreg.h amlogic_genfb.c amlogic_hdmireg.h amlogic_vpureg.h Log Message: Basic framebuffer console support. Work in progress. To generate a diff of this commit: cvs rdiff -u -r0 -r1.1 src/sys/arch/arm/amlogic/amlogic_canvasreg.h \ src/sys/arch/arm/amlogic/amlogic_genfb.c \ src/sys/arch/arm/amlogic/amlogic_hdmireg.h \ src/sys/arch/arm/amlogic/amlogic_vpureg.h cvs rdiff -u -r1.6 -r1.7 src/sys/arch/arm/amlogic/amlogic_io.c cvs rdiff -u -r1.8 -r1.9 src/sys/arch/arm/amlogic/amlogic_reg.h cvs rdiff -u -r1.7 -r1.8 src/sys/arch/arm/amlogic/amlogic_var.h \ src/sys/arch/arm/amlogic/files.amlogic cvs rdiff -u -r1.16 -r1.17 src/sys/arch/evbarm/amlogic/amlogic_machdep.c cvs rdiff -u -r1.11 -r1.12 src/sys/arch/evbarm/conf/ODROID-C1 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/arm/amlogic/amlogic_io.c diff -u src/sys/arch/arm/amlogic/amlogic_io.c:1.6 src/sys/arch/arm/amlogic/amlogic_io.c:1.7 --- src/sys/arch/arm/amlogic/amlogic_io.c:1.6 Sun Mar 8 12:44:55 2015 +++ src/sys/arch/arm/amlogic/amlogic_io.c Sat Mar 21 01:17:00 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: amlogic_io.c,v 1.6 2015/03/08 12:44:55 jmcneill Exp $ */ +/* $NetBSD: amlogic_io.c,v 1.7 2015/03/21 01:17:00 jmcneill Exp $ */ /*- * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca> @@ -29,7 +29,7 @@ #include "opt_amlogic.h" #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: amlogic_io.c,v 1.6 2015/03/08 12:44:55 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: amlogic_io.c,v 1.7 2015/03/21 01:17:00 jmcneill Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -63,10 +63,8 @@ static const struct amlogic_locators aml AMLOGIC_UART0AO_OFFSET, AMLOGIC_UART_SIZE, 0, AMLOGIC_INTR_UART0AO }, { "amlogiccom", AMLOGIC_UART2AO_OFFSET, AMLOGIC_UART_SIZE, 2, AMLOGIC_INTR_UART2AO }, -#if notyet { "genfb", AMLOGIC_DMC_OFFSET, AMLOGIC_DMC_SIZE, NOPORT, NOINTR }, -#endif { "amlogicrng", AMLOGIC_RAND_OFFSET, AMLOGIC_RAND_SIZE, NOPORT, NOINTR }, { "dwctwo", Index: src/sys/arch/arm/amlogic/amlogic_reg.h diff -u src/sys/arch/arm/amlogic/amlogic_reg.h:1.8 src/sys/arch/arm/amlogic/amlogic_reg.h:1.9 --- src/sys/arch/arm/amlogic/amlogic_reg.h:1.8 Sun Mar 8 12:44:55 2015 +++ src/sys/arch/arm/amlogic/amlogic_reg.h Sat Mar 21 01:17:00 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: amlogic_reg.h,v 1.8 2015/03/08 12:44:55 jmcneill Exp $ */ +/* $NetBSD: amlogic_reg.h,v 1.9 2015/03/21 01:17:00 jmcneill Exp $ */ /*- * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca> @@ -70,6 +70,12 @@ #define AMLOGIC_GMAC_OFFSET 0x09410000 #define AMLOGIC_GMAC_SIZE 0x10000 +#define AMLOGIC_HDMI_OFFSET 0x10040000 +#define AMLOGIC_HDMI_SIZE 0x10000 /* ? */ + +#define AMLOGIC_VPU_OFFSET 0x10100000 +#define AMLOGIC_VPU_SIZE 0x100000 /* ? */ + #define AMLOGIC_SRAM_OFFSET 0x19000000 #define AMLOGIC_CPUCONF_OFFSET 0x1901ff80 Index: src/sys/arch/arm/amlogic/amlogic_var.h diff -u src/sys/arch/arm/amlogic/amlogic_var.h:1.7 src/sys/arch/arm/amlogic/amlogic_var.h:1.8 --- src/sys/arch/arm/amlogic/amlogic_var.h:1.7 Tue Mar 17 22:29:40 2015 +++ src/sys/arch/arm/amlogic/amlogic_var.h Sat Mar 21 01:17:00 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: amlogic_var.h,v 1.7 2015/03/17 22:29:40 jmcneill Exp $ */ +/* $NetBSD: amlogic_var.h,v 1.8 2015/03/21 01:17:00 jmcneill Exp $ */ /*- * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca> @@ -74,6 +74,9 @@ uint32_t amlogic_get_rate_fixed(void); uint32_t amlogic_get_rate_a9(void); uint32_t amlogic_get_rate_a9periph(void); +void amlogic_genfb_ddb_trap_callback(int); +void amlogic_genfb_set_console_dev(device_t); + static void inline amlogic_reg_set_clear(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t o, uint32_t set_mask, uint32_t clr_mask) Index: src/sys/arch/arm/amlogic/files.amlogic diff -u src/sys/arch/arm/amlogic/files.amlogic:1.7 src/sys/arch/arm/amlogic/files.amlogic:1.8 --- src/sys/arch/arm/amlogic/files.amlogic:1.7 Tue Mar 17 22:29:40 2015 +++ src/sys/arch/arm/amlogic/files.amlogic Sat Mar 21 01:17:00 2015 @@ -1,4 +1,4 @@ -# $NetBSD: files.amlogic,v 1.7 2015/03/17 22:29:40 jmcneill Exp $ +# $NetBSD: files.amlogic,v 1.8 2015/03/21 01:17:00 jmcneill Exp $ # # Configuration info for Amlogic ARM Peripherals # @@ -26,6 +26,10 @@ device amlogiccom attach amlogiccom at amlogicio with amlogic_com file arch/arm/amlogic/amlogic_com.c amlogic_com needs-flag +# Framebuffer console +attach genfb at amlogicio with amlogic_genfb +file arch/arm/amlogic/amlogic_genfb.c amlogic_genfb needs-flag + # SDHC device amlogicsdhc: sdmmcbus attach amlogicsdhc at amlogicio with amlogic_sdhc Index: src/sys/arch/evbarm/amlogic/amlogic_machdep.c diff -u src/sys/arch/evbarm/amlogic/amlogic_machdep.c:1.16 src/sys/arch/evbarm/amlogic/amlogic_machdep.c:1.17 --- src/sys/arch/evbarm/amlogic/amlogic_machdep.c:1.16 Tue Mar 17 22:29:40 2015 +++ src/sys/arch/evbarm/amlogic/amlogic_machdep.c Sat Mar 21 01:17:00 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: amlogic_machdep.c,v 1.16 2015/03/17 22:29:40 jmcneill Exp $ */ +/* $NetBSD: amlogic_machdep.c,v 1.17 2015/03/21 01:17:00 jmcneill Exp $ */ /* * Machine dependent functions for kernel setup for TI OSK5912 board. @@ -125,7 +125,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: amlogic_machdep.c,v 1.16 2015/03/17 22:29:40 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: amlogic_machdep.c,v 1.17 2015/03/21 01:17:00 jmcneill Exp $"); #include "opt_machdep.h" #include "opt_ddb.h" @@ -136,6 +136,8 @@ __KERNEL_RCSID(0, "$NetBSD: amlogic_mach #include "amlogic_com.h" #include "arml2cc.h" +#include "ukbd.h" +#include "genfb.h" #include "ether.h" #include <sys/param.h> @@ -472,10 +474,8 @@ consinit(void) const bus_space_handle_t bsh = AMLOGIC_CORE_VBASE + (consaddr - AMLOGIC_CORE_BASE); amlogic_com_cnattach(&amlogic_bs_tag, bsh, conspeed, conmode); -#endif - -#if NUKBD > 0 - ukbd_cnattach(); /* allow USB keyboard to become console */ +#else +#error only UART console is supported #endif } @@ -541,6 +541,25 @@ amlogic_device_register(device_t self, v prop_object_release(pd); } } + +#if NGENFB > 0 + if (device_is_a(self, "genfb")) { + char *ptr; + amlogic_genfb_set_console_dev(self); +#ifdef DDB + db_trap_callback = amlogic_genfb_ddb_trap_callback; +#endif + if (get_bootconf_option(boot_args, "console", + BOOTOPT_TYPE_STRING, &ptr) && strncmp(ptr, "fb", 2) == 0) { + prop_dictionary_set_bool(dict, "is_console", true); +#if NUKBD > 0 + ukbd_cnattach(); +#endif + } else { + prop_dictionary_set_bool(dict, "is_console", false); + } + } +#endif } #if defined(MULTIPROCESSOR) Index: src/sys/arch/evbarm/conf/ODROID-C1 diff -u src/sys/arch/evbarm/conf/ODROID-C1:1.11 src/sys/arch/evbarm/conf/ODROID-C1:1.12 --- src/sys/arch/evbarm/conf/ODROID-C1:1.11 Wed Mar 18 23:03:06 2015 +++ src/sys/arch/evbarm/conf/ODROID-C1 Sat Mar 21 01:17:00 2015 @@ -1,5 +1,5 @@ # -# $NetBSD: ODROID-C1,v 1.11 2015/03/18 23:03:06 jmcneill Exp $ +# $NetBSD: ODROID-C1,v 1.12 2015/03/21 01:17:00 jmcneill Exp $ # # Odroid-C1 (Amlogic S805) based SBC (Single Board Computer) # @@ -177,19 +177,21 @@ amlogiccom0 at amlogicio0 port 0 options CONSADDR=0xc81004c0, CONSPEED=115200 # Framebuffer -#genfb0 at amlogicio0 -#wsdisplay* at genfb? -#options VCONS_DRAW_INTR -#options WSEMUL_VT100 -#options WS_DEFAULT_FG=WSCOL_WHITE -#options WS_DEFAULT_BG=WSCOL_BLACK -#options WS_KERNEL_FG=WSCOL_GREEN -#options WS_KERNEL_BG=WSCOL_BLACK -#options WSDISPLAY_COMPAT_PCVT -#options WSDISPLAY_COMPAT_SYSCONS -#options WSDISPLAY_COMPAT_USL -#options WSDISPLAY_COMPAT_RAWKBD -#options WSDISPLAY_DEFAULTSCREENS=4 +genfb0 at amlogicio0 +wsdisplay* at genfb? +options VCONS_DRAW_INTR +options WSEMUL_VT100 +options WS_DEFAULT_FG=WSCOL_WHITE +options WS_DEFAULT_BG=WSCOL_BLACK +options WS_KERNEL_FG=WSCOL_GREEN +options WS_KERNEL_BG=WSCOL_BLACK +options WSDISPLAY_COMPAT_PCVT +options WSDISPLAY_COMPAT_SYSCONS +options WSDISPLAY_COMPAT_USL +options WSDISPLAY_COMPAT_RAWKBD +options WSDISPLAY_DEFAULTSCREENS=4 +pseudo-device wsmux +pseudo-device wsfont # Hardware random number generator amlogicrng0 at amlogicio0 Added files: Index: src/sys/arch/arm/amlogic/amlogic_canvasreg.h diff -u /dev/null src/sys/arch/arm/amlogic/amlogic_canvasreg.h:1.1 --- /dev/null Sat Mar 21 01:17:01 2015 +++ src/sys/arch/arm/amlogic/amlogic_canvasreg.h Sat Mar 21 01:17:00 2015 @@ -0,0 +1,54 @@ +/* $NetBSD: amlogic_canvasreg.h,v 1.1 2015/03/21 01:17:00 jmcneill Exp $ */ + +/*- + * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca> + * 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. + */ + +#ifndef _ARM_AMLOGIC_CANVASREG_H +#define _ARM_AMLOGIC_CANVASREG_H + +#define CANVAS_REG(n) ((n) << 2) + +#define DC_CAV_LUT_DATAL_REG CANVAS_REG(0x12) +#define DC_CAV_LUT_DATAH_REG CANVAS_REG(0x13) +#define DC_CAV_LUT_ADDR_REG CANVAS_REG(0x14) + +#define DC_CAV_LUT_DATAL_FBADDR __BITS(28,0) +#define DC_CAV_LUT_DATAL_WIDTH_L __BITS(31,29) + +#define DC_CAV_LUT_DATAH_BLKMODE __BITS(25,24) +#define DC_CAV_LUT_DATAH_BLKMODE_LINEAR 0 +#define DC_CAV_LUT_DATAH_BLKMODE_32X32 1 +#define DC_CAV_LUT_DATAH_BLKMODE_64X64 2 +#define DC_CAV_LUT_DATAH_YWRAP __BIT(23) +#define DC_CAV_LUT_DATAH_XWRAP __BIT(22) +#define DC_CAV_LUT_DATAH_HEIGHT __BITS(21,9) +#define DC_CAV_LUT_DATAH_WIDTH_H __BITS(8,0) + +#define DC_CAV_LUT_ADDR_WR_EN __BIT(9) +#define DC_CAV_LUT_ADDR_RD_EN __BIT(8) +#define DC_CAV_LUT_ADDR_INDEX __BITS(2,0) + +#endif /* _ARM_AMLOGIC_CANVASREG_H */ Index: src/sys/arch/arm/amlogic/amlogic_genfb.c diff -u /dev/null src/sys/arch/arm/amlogic/amlogic_genfb.c:1.1 --- /dev/null Sat Mar 21 01:17:01 2015 +++ src/sys/arch/arm/amlogic/amlogic_genfb.c Sat Mar 21 01:17:00 2015 @@ -0,0 +1,389 @@ +/* $NetBSD: amlogic_genfb.c,v 1.1 2015/03/21 01:17:00 jmcneill Exp $ */ + +/*- + * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca> + * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/* + * Generic framebuffer console driver + */ + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: amlogic_genfb.c,v 1.1 2015/03/21 01:17:00 jmcneill Exp $"); + +#include <sys/param.h> +#include <sys/types.h> +#include <sys/systm.h> +#include <sys/device.h> +#include <sys/conf.h> +#include <sys/bus.h> +#include <sys/kmem.h> + +#include <arm/amlogic/amlogic_reg.h> +#include <arm/amlogic/amlogic_var.h> +#include <arm/amlogic/amlogic_canvasreg.h> +#include <arm/amlogic/amlogic_vpureg.h> +#include <arm/amlogic/amlogic_hdmireg.h> + +#include <dev/wsfb/genfbvar.h> + +/* Map CEA-861-D video code (VIC) to framebuffer dimensions */ +static const struct amlogic_genfb_vic2mode { + u_int vic; + u_int width; + u_int height; +} amlogic_genfb_modes[] = { + { 1, 640, 480 }, + { 2, 720, 480 }, + { 3, 720, 480 }, + { 4, 1280, 720 }, + { 5, 1920, 1080 }, + { 16, 1920, 1080 }, + { 17, 720, 576 }, + { 18, 720, 576 }, + { 19, 1280, 720 }, + { 20, 1920, 1080 }, + { 31, 1920, 1080 }, + { 32, 1920, 1080 }, + { 33, 1920, 1080 }, + { 34, 1920, 1080 }, + { 39, 1920, 1080 }, +}; + +struct amlogic_genfb_softc { + struct genfb_softc sc_gen; + bus_space_tag_t sc_bst; + bus_space_handle_t sc_bsh; + bus_space_handle_t sc_hdmi_bsh; + bus_space_handle_t sc_vpu_bsh; + bus_dma_tag_t sc_dmat; + + bus_dma_segment_t sc_dmasegs[1]; + bus_size_t sc_dmasize; + bus_dmamap_t sc_dmamap; + void *sc_dmap; + + uint32_t sc_wstype; +}; + +static int amlogic_genfb_match(device_t, cfdata_t, void *); +static void amlogic_genfb_attach(device_t, device_t, void *); + +static int amlogic_genfb_ioctl(void *, void *, u_long, void *, int, lwp_t *); +static paddr_t amlogic_genfb_mmap(void *, void *, off_t, int); +static bool amlogic_genfb_shutdown(device_t, int); + +static void amlogic_genfb_probe(struct amlogic_genfb_softc *); +static int amlogic_genfb_alloc_videomem(struct amlogic_genfb_softc *); + +void amlogic_genfb_set_console_dev(device_t); +void amlogic_genfb_ddb_trap_callback(int); + +static device_t amlogic_genfb_console_dev = NULL; + +CFATTACH_DECL_NEW(amlogic_genfb, sizeof(struct amlogic_genfb_softc), + amlogic_genfb_match, amlogic_genfb_attach, NULL, NULL); + +static inline uint32_t +amlogic_genfb_hdmi_read_4(struct amlogic_genfb_softc *sc, uint32_t addr) +{ + bus_space_write_4(sc->sc_bst, sc->sc_hdmi_bsh, HDMI_ADDR_REG, addr); + bus_space_write_4(sc->sc_bst, sc->sc_hdmi_bsh, HDMI_ADDR_REG, addr); + return bus_space_read_4(sc->sc_bst, sc->sc_hdmi_bsh, HDMI_DATA_REG); +} + +static inline void +amlogic_genfb_hdmi_write_4(struct amlogic_genfb_softc *sc, uint32_t addr, + uint32_t data) +{ + bus_space_write_4(sc->sc_bst, sc->sc_hdmi_bsh, HDMI_ADDR_REG, addr); + bus_space_write_4(sc->sc_bst, sc->sc_hdmi_bsh, HDMI_ADDR_REG, addr); + bus_space_write_4(sc->sc_bst, sc->sc_hdmi_bsh, HDMI_DATA_REG, data); +} + +#define HDMI_READ amlogic_genfb_hdmi_read_4 +#define HDMI_WRITE amlogic_genfb_hdmi_write_4 + +#define VPU_READ(sc, reg) \ + bus_space_read_4((sc)->sc_bst, (sc)->sc_vpu_bsh, (reg)) +#define VPU_WRITE(sc, reg, val) \ + bus_space_write_4((sc)->sc_bst, (sc)->sc_vpu_bsh, (reg), (val)) + +static int +amlogic_genfb_match(device_t parent, cfdata_t match, void *aux) +{ + return 1; +} + +static void +amlogic_genfb_attach(device_t parent, device_t self, void *aux) +{ + struct amlogic_genfb_softc *sc = device_private(self); + struct amlogicio_attach_args * const aio = aux; + const struct amlogic_locators * const loc = &aio->aio_loc; + prop_dictionary_t dict = device_properties(self); + static const struct genfb_ops zero_ops; + struct genfb_ops ops = zero_ops; + bool is_console = false; + + sc->sc_gen.sc_dev = self; + sc->sc_bst = aio->aio_core_bst; + sc->sc_dmat = aio->aio_dmat; + bus_space_subregion(aio->aio_core_bst, aio->aio_bsh, + loc->loc_offset, loc->loc_size, &sc->sc_bsh); + bus_space_subregion(aio->aio_core_bst, aio->aio_bsh, + AMLOGIC_HDMI_OFFSET, AMLOGIC_HDMI_SIZE, &sc->sc_hdmi_bsh); + bus_space_subregion(aio->aio_core_bst, aio->aio_bsh, + AMLOGIC_VPU_OFFSET, AMLOGIC_VPU_SIZE, &sc->sc_vpu_bsh); + + amlogic_genfb_probe(sc); + + sc->sc_wstype = WSDISPLAY_TYPE_MESON; + prop_dictionary_get_bool(dict, "is_console", &is_console); + + genfb_init(&sc->sc_gen); + + if (sc->sc_gen.sc_width == 0 || + sc->sc_gen.sc_fbsize == 0) { + aprint_normal(": disabled\n"); + return; + } + + pmf_device_register1(self, NULL, NULL, amlogic_genfb_shutdown); + + memset(&ops, 0, sizeof(ops)); + ops.genfb_ioctl = amlogic_genfb_ioctl; + ops.genfb_mmap = amlogic_genfb_mmap; + + aprint_naive("\n"); + + if (is_console) + aprint_normal(": switching to framebuffer console\n"); + else + aprint_normal("\n"); + + genfb_attach(&sc->sc_gen, &ops); +} + +static int +amlogic_genfb_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, lwp_t *l) +{ + struct amlogic_genfb_softc *sc = v; + struct wsdisplayio_bus_id *busid; + + switch (cmd) { + case WSDISPLAYIO_GTYPE: + *(u_int *)data = sc->sc_wstype; + return 0; + case WSDISPLAYIO_GET_BUSID: + busid = data; + busid->bus_type = WSDISPLAYIO_BUS_SOC; + return 0; + case WSDISPLAYIO_GET_FBINFO: + { + struct wsdisplayio_fbinfo *fbi = data; + struct rasops_info *ri = &sc->sc_gen.vd.active->scr_ri; + int ret; + + ret = wsdisplayio_get_fbinfo(ri, fbi); + fbi->fbi_flags |= WSFB_VRAM_IS_RAM; + return ret; + } + default: + return EPASSTHROUGH; + } +} + +static paddr_t +amlogic_genfb_mmap(void *v, void *vs, off_t offset, int prot) +{ + struct amlogic_genfb_softc *sc = v; + + if (offset < 0 || offset >= sc->sc_dmasegs[0].ds_len) + return -1; + + return bus_dmamem_mmap(sc->sc_dmat, sc->sc_dmasegs, 1, + offset, prot, BUS_DMA_PREFETCHABLE); +} + +static bool +amlogic_genfb_shutdown(device_t self, int flags) +{ + genfb_enable_polling(self); + return true; +} + +static void +amlogic_genfb_probe(struct amlogic_genfb_softc *sc) +{ + prop_dictionary_t cfg = device_properties(sc->sc_gen.sc_dev); + u_int width = 0, height = 0, i; + uint32_t datal, datah, addr; + uint32_t w1, w2, w3, w4; + int error; + + datal = bus_space_read_4(sc->sc_bst, sc->sc_bsh, DC_CAV_LUT_DATAL_REG); + datah = bus_space_read_4(sc->sc_bst, sc->sc_bsh, DC_CAV_LUT_DATAH_REG); + addr = bus_space_read_4(sc->sc_bst, sc->sc_bsh, DC_CAV_LUT_ADDR_REG); + + w1 = VPU_READ(sc, VIU_OSD2_BLK0_CFG_W1_REG); + w2 = VPU_READ(sc, VIU_OSD2_BLK0_CFG_W2_REG); + w3 = VPU_READ(sc, VIU_OSD2_BLK0_CFG_W3_REG); + w4 = VPU_READ(sc, VIU_OSD2_BLK0_CFG_W4_REG); + +#if 0 + const u_int w = (__SHIFTOUT(datal, DC_CAV_LUT_DATAL_WIDTH_L) | + (__SHIFTOUT(datah, DC_CAV_LUT_DATAH_WIDTH_H) << 3)) << 3; + const u_int h = __SHIFTOUT(datah, DC_CAV_LUT_DATAH_HEIGHT); +#endif + + /* VIC is in AVI InfoFrame PB4. */ + const uint32_t vic = HDMI_READ(sc, HDMITX_AVI_INFO_ADDR + 4) & 0x7f; + + for (i = 0; i < __arraycount(amlogic_genfb_modes); i++) { + if (amlogic_genfb_modes[i].vic == vic) { + aprint_debug(" [HDMI VIC %d]", vic); + width = amlogic_genfb_modes[i].width; + height = amlogic_genfb_modes[i].height; + } + } + + if (width == 0 || height == 0) { + aprint_error(" [UNSUPPORTED HDMI VIC %d]", vic); + return; + } + + const uint32_t fbsize = width * height * 3; + sc->sc_dmasize = (fbsize + 3) & ~3; + + error = amlogic_genfb_alloc_videomem(sc); + if (error == 0) { + const paddr_t pa = sc->sc_dmamap->dm_segs[0].ds_addr; + const uint32_t w = width * 3; + const uint32_t h = height; + + datal &= ~DC_CAV_LUT_DATAL_WIDTH_L; + datal |= __SHIFTIN(w >> 3, DC_CAV_LUT_DATAL_WIDTH_L); + datal &= ~DC_CAV_LUT_DATAL_FBADDR; + datal |= __SHIFTIN(pa >> 3, DC_CAV_LUT_DATAL_FBADDR); + bus_space_write_4(sc->sc_bst, sc->sc_bsh, DC_CAV_LUT_DATAL_REG, + datal); + + datah &= ~DC_CAV_LUT_DATAH_BLKMODE; + datah |= __SHIFTIN(DC_CAV_LUT_DATAH_BLKMODE_LINEAR, + DC_CAV_LUT_DATAH_BLKMODE); + datah &= ~DC_CAV_LUT_DATAH_WIDTH_H; + datah |= __SHIFTIN(w >> 6, DC_CAV_LUT_DATAH_WIDTH_H); + datah &= ~DC_CAV_LUT_DATAH_HEIGHT; + datah |= __SHIFTIN(h, DC_CAV_LUT_DATAH_HEIGHT); + bus_space_write_4(sc->sc_bst, sc->sc_bsh, DC_CAV_LUT_DATAH_REG, + datah); + + addr |= DC_CAV_LUT_ADDR_WR_EN; + bus_space_write_4(sc->sc_bst, sc->sc_bsh, DC_CAV_LUT_ADDR_REG, + addr); + + w1 = __SHIFTIN(width - 1, VIU_OSD_BLK_CFG_W1_X_END); + w2 = __SHIFTIN(height - 1, VIU_OSD_BLK_CFG_W2_Y_END); + w3 = __SHIFTIN(width - 1, VIU_OSD_BLK_CFG_W3_H_END); + w4 = __SHIFTIN(height - 1, VIU_OSD_BLK_CFG_W4_V_END); + + VPU_WRITE(sc, VIU_OSD2_BLK0_CFG_W1_REG, w1); + VPU_WRITE(sc, VIU_OSD2_BLK0_CFG_W2_REG, w2); + VPU_WRITE(sc, VIU_OSD2_BLK0_CFG_W3_REG, w3); + VPU_WRITE(sc, VIU_OSD2_BLK0_CFG_W4_REG, w4); + + prop_dictionary_set_uint32(cfg, "width", width); + prop_dictionary_set_uint32(cfg, "height", height); + prop_dictionary_set_uint8(cfg, "depth", 24); + prop_dictionary_set_uint16(cfg, "linebytes", width * 3); + prop_dictionary_set_uint32(cfg, "address", 0); + prop_dictionary_set_uint32(cfg, "virtual_address", + (uintptr_t)sc->sc_dmap); + } else { + aprint_error_dev(sc->sc_gen.sc_dev, + "failed to allocate %u bytes of video memory: %d\n", + (u_int)sc->sc_dmasize, error); + } +} + +static int +amlogic_genfb_alloc_videomem(struct amlogic_genfb_softc *sc) +{ + int error, nsegs; + + error = bus_dmamem_alloc(sc->sc_dmat, sc->sc_dmasize, 0x1000, 0, + sc->sc_dmasegs, 1, &nsegs, BUS_DMA_WAITOK); + if (error) + return error; + error = bus_dmamem_map(sc->sc_dmat, sc->sc_dmasegs, nsegs, + sc->sc_dmasize, &sc->sc_dmap, BUS_DMA_WAITOK | BUS_DMA_COHERENT); + if (error) + goto free; + error = bus_dmamap_create(sc->sc_dmat, sc->sc_dmasize, 1, + sc->sc_dmasize, 0, BUS_DMA_WAITOK, &sc->sc_dmamap); + if (error) + goto unmap; + error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap, sc->sc_dmap, + sc->sc_dmasize, NULL, BUS_DMA_WAITOK); + if (error) + goto destroy; + + memset(sc->sc_dmap, 0, sc->sc_dmasize); + + return 0; + +destroy: + bus_dmamap_destroy(sc->sc_dmat, sc->sc_dmamap); +unmap: + bus_dmamem_unmap(sc->sc_dmat, sc->sc_dmap, sc->sc_dmasize); +free: + bus_dmamem_free(sc->sc_dmat, sc->sc_dmasegs, nsegs); + + sc->sc_dmasize = 0; + sc->sc_dmap = NULL; + + return error; +} + +void +amlogic_genfb_set_console_dev(device_t dev) +{ + KASSERT(amlogic_genfb_console_dev == NULL); + amlogic_genfb_console_dev = dev; +} + +void +amlogic_genfb_ddb_trap_callback(int where) +{ + if (amlogic_genfb_console_dev == NULL) + return; + + if (where) { + genfb_enable_polling(amlogic_genfb_console_dev); + } else { + genfb_disable_polling(amlogic_genfb_console_dev); + } +} Index: src/sys/arch/arm/amlogic/amlogic_hdmireg.h diff -u /dev/null src/sys/arch/arm/amlogic/amlogic_hdmireg.h:1.1 --- /dev/null Sat Mar 21 01:17:01 2015 +++ src/sys/arch/arm/amlogic/amlogic_hdmireg.h Sat Mar 21 01:17:00 2015 @@ -0,0 +1,38 @@ +/* $NetBSD: amlogic_hdmireg.h,v 1.1 2015/03/21 01:17:00 jmcneill Exp $ */ + +/*- + * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca> + * 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. + */ + +#ifndef _ARM_AMLOGIC_HDMIREG_H +#define _ARM_AMLOGIC_HDMIREG_H + +#define HDMI_ADDR_REG 0x2000 +#define HDMI_DATA_REG 0x2004 +#define HDMI_CTRL_REG 0x2008 + +#define HDMITX_AVI_INFO_ADDR 0x260 + +#endif /* _ARM_AMLOGIC_HDMIREG_H */ Index: src/sys/arch/arm/amlogic/amlogic_vpureg.h diff -u /dev/null src/sys/arch/arm/amlogic/amlogic_vpureg.h:1.1 --- /dev/null Sat Mar 21 01:17:01 2015 +++ src/sys/arch/arm/amlogic/amlogic_vpureg.h Sat Mar 21 01:17:00 2015 @@ -0,0 +1,73 @@ +/* $NetBSD: amlogic_vpureg.h,v 1.1 2015/03/21 01:17:00 jmcneill Exp $ */ + +/*- + * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca> + * 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. + */ + +#ifndef _ARM_AMLOGIC_VPUREG_H +#define _ARM_AMLOGIC_VPUREG_H + +#define VPU_REG(n) ((n) << 2) + +#define VIU_OSD2_CTRL_STAT_REG VPU_REG(0x1a30) +#define VIU_OSD2_BLK0_CFG_W0_REG VPU_REG(0x1a3b) +#define VIU_OSD2_BLK0_CFG_W1_REG VPU_REG(0x1a3c) +#define VIU_OSD2_BLK0_CFG_W2_REG VPU_REG(0x1a3d) +#define VIU_OSD2_BLK0_CFG_W3_REG VPU_REG(0x1a3e) +#define VIU_OSD2_BLK0_CFG_W4_REG VPU_REG(0x1a64) +#define VPP_MISC_REG VPU_REG(0x1d26) + +#define VIU_OSD_CTRL_STAT_ENABLE __BIT(21) +#define VIU_OSD_CTRL_STAT_BLK3_ENABLE __BIT(3) +#define VIU_OSD_CTRL_STAT_BLK2_ENABLE __BIT(2) +#define VIU_OSD_CTRL_STAT_BLK1_ENABLE __BIT(1) +#define VIU_OSD_CTRL_STAT_BLK0_ENABLE __BIT(0) + +#define VIU_OSD_BLK_CFG_W0_TBL_ADDR __BITS(23,16) +#define VIU_OSD_BLK_CFG_W0_LITTLE_ENDIAN __BIT(15) +#define VIU_OSD_BLK_CFG_W0_RPT_Y __BIT(14) +#define VIU_OSD_BLK_CFG_W0_INTERP_CTRL __BITS(13,12) +#define VIU_OSD_BLK_CFG_W0_OSD_BLK_MODE __BITS(11,8) +#define VIU_OSD_BLK_CFG_W0_RGB_EN __BIT(7) +#define VIU_OSD_BLK_CFG_W0_TC_ALPHA_EN __BIT(6) +#define VIU_OSD_BLK_CFG_W0_COLOR_MATRIX __BITS(5,2) +#define VIU_OSD_BLK_CFG_W0_INTERLACE_EN __BIT(1) +#define VIU_OSD_BLK_CFG_W0_INTERLACE_SEL_ODD __BIT(0) + +#define VIU_OSD_BLK_CFG_W1_X_END __BITS(28,16) +#define VIU_OSD_BLK_CFG_W1_X_START __BITS(12,0) + +#define VIU_OSD_BLK_CFG_W2_Y_END __BITS(28,16) +#define VIU_OSD_BLK_CFG_W2_Y_START __BITS(12,0) + +#define VIU_OSD_BLK_CFG_W3_H_END __BITS(27,16) +#define VIU_OSD_BLK_CFG_W3_H_START __BITS(11,0) + +#define VIU_OSD_BLK_CFG_W4_V_END __BITS(27,16) +#define VIU_OSD_BLK_CFG_W4_V_START __BITS(11,0) + +#define VPP_MISC_POSTBLEND __BIT(7) + +#endif /* _ARM_AMLOGIC_VPUREG_H */