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 */

Reply via email to