Module Name:    src
Committed By:   hkenken
Date:           Mon Dec 21 04:26:29 UTC 2015

Modified Files:
        src/sys/arch/arm/imx: files.imx51 imx51_ipuv3.c imx51_ipuv3var.h
            imx51var.h
        src/sys/arch/evbarm/conf: NETWALKER files.netwalker
        src/sys/arch/evbarm/netwalker: netwalker_backlight.c
            netwalker_backlightvar.h netwalker_lcd.c netwalker_machdep.c
Added Files:
        src/sys/arch/arm/imx: imx_genfb.c

Log Message:
Rewritten to take advantage of genfb(4).


To generate a diff of this commit:
cvs rdiff -u -r1.13 -r1.14 src/sys/arch/arm/imx/files.imx51
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/arm/imx/imx51_ipuv3.c \
    src/sys/arch/arm/imx/imx51var.h
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/arm/imx/imx51_ipuv3var.h
cvs rdiff -u -r0 -r1.1 src/sys/arch/arm/imx/imx_genfb.c
cvs rdiff -u -r1.34 -r1.35 src/sys/arch/evbarm/conf/NETWALKER
cvs rdiff -u -r1.9 -r1.10 src/sys/arch/evbarm/conf/files.netwalker
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/evbarm/netwalker/netwalker_backlight.c \
    src/sys/arch/evbarm/netwalker/netwalker_backlightvar.h
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/evbarm/netwalker/netwalker_lcd.c
cvs rdiff -u -r1.18 -r1.19 src/sys/arch/evbarm/netwalker/netwalker_machdep.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/arm/imx/files.imx51
diff -u src/sys/arch/arm/imx/files.imx51:1.13 src/sys/arch/arm/imx/files.imx51:1.14
--- src/sys/arch/arm/imx/files.imx51:1.13	Thu May  7 04:13:47 2015
+++ src/sys/arch/arm/imx/files.imx51	Mon Dec 21 04:26:28 2015
@@ -1,4 +1,4 @@
-#	$NetBSD: files.imx51,v 1.13 2015/05/07 04:13:47 hkenken Exp $
+#	$NetBSD: files.imx51,v 1.14 2015/12/21 04:26:28 hkenken Exp $
 #
 # Configuration info for the Freescale i.MX5x
 #
@@ -76,11 +76,14 @@ file	arch/arm/imx/imx51_iomux.c		imxiomu
 # defparam opt_imx50_epdc.h		EPDC_DEBUG
 
 # IPU v3 controller
-device	ipu : bus_dma_generic, wsemuldisplaydev, rasops16, rasops8, rasops4, rasops_rotation, vcons
-file	arch/arm/imx/imx51_ipuv3.c	ipu	 needs-flag
-defflag	opt_imx51_ipuv3.h		IMXIPUCONSOLE
+device	ipu { }
+file	arch/arm/imx/imx51_ipuv3.c	imx_ipuv3	needs-flag
 defparam opt_imx51_ipuv3.h		IPUV3_DEBUG
 
+# Framebuffer console
+attach	genfb at ipu with imx_genfb
+file	arch/arm/imx/imx_genfb.c	imx_genfb
+
 # iMX M3IF - Multi Master Memory Interface
 # iMX ESDCTL/MDDRC - Enhanced SDRAM/LPDDR memory controller
 # iMX PCMCIA - PCMCIA memory controller

Index: src/sys/arch/arm/imx/imx51_ipuv3.c
diff -u src/sys/arch/arm/imx/imx51_ipuv3.c:1.3 src/sys/arch/arm/imx/imx51_ipuv3.c:1.4
--- src/sys/arch/arm/imx/imx51_ipuv3.c:1.3	Fri Nov  7 11:54:18 2014
+++ src/sys/arch/arm/imx/imx51_ipuv3.c	Mon Dec 21 04:26:28 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: imx51_ipuv3.c,v 1.3 2014/11/07 11:54:18 hkenken Exp $	*/
+/*	$NetBSD: imx51_ipuv3.c,v 1.4 2015/12/21 04:26:28 hkenken Exp $	*/
 
 /*
  * Copyright (c) 2011, 2012  Genetec Corporation.  All rights reserved.
@@ -27,7 +27,9 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: imx51_ipuv3.c,v 1.3 2014/11/07 11:54:18 hkenken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: imx51_ipuv3.c,v 1.4 2015/12/21 04:26:28 hkenken Exp $");
+
+#include "opt_imx51_ipuv3.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -35,17 +37,6 @@ __KERNEL_RCSID(0, "$NetBSD: imx51_ipuv3.
 #include <sys/uio.h>
 #include <sys/malloc.h>
 #include <sys/kernel.h>			/* for cold */
-#include <sys/pmf.h>
-
-#include <uvm/uvm_extern.h>
-
-#include <dev/cons.h>
-#include <dev/wscons/wsconsio.h>
-#include <dev/wscons/wsdisplayvar.h>
-#include <dev/wscons/wscons_callbacks.h>
-#include <dev/rasops/rasops.h>
-#include <dev/wsfont/wsfont.h>
-#include <dev/wscons/wsdisplay_vconsvar.h>
 
 #include <sys/bus.h>
 #include <machine/cpu.h>
@@ -59,19 +50,6 @@ __KERNEL_RCSID(0, "$NetBSD: imx51_ipuv3.
 #include <arm/imx/imx51_ccmreg.h>
 
 #include "imxccm.h"	/* if CCM driver is configured into the kernel */
-#include "wsdisplay.h"
-#include "opt_imx51_ipuv3.h"
-
-/*
- * Console variables. These are necessary since console is setup very early,
- * before devices get attached.
- */
-struct {
-	int is_console;
-	struct imx51_wsscreen_descr *descr;
-	struct wsdisplay_accessops *accessops;
-	const struct lcd_panel_geometry *geom;
-} imx51_ipuv3_console;
 
 #define	IPUV3_READ(ipuv3, module, reg)					      \
 	bus_space_read_4((ipuv3)->iot, (ipuv3)->module##_ioh, (reg))
@@ -89,16 +67,8 @@ int ipuv3intr(void *);
 
 static void imx51_ipuv3_initialize(struct imx51_ipuv3_softc *,
     const struct lcd_panel_geometry *);
-#if NWSDISPLAY > 0
-static void imx51_ipuv3_setup_rasops(struct imx51_ipuv3_softc *,
-    struct rasops_info *, struct imx51_wsscreen_descr *,
-    const struct lcd_panel_geometry *);
-#endif
 static void imx51_ipuv3_set_idma_param(uint32_t *, uint32_t, uint32_t);
 
-static bool imx51_ipuv3_resume(device_t, const pmf_qual_t *);
-static bool imx51_ipuv3_suspend(device_t, const pmf_qual_t *);
-
 #ifdef IPUV3_DEBUG
 static void
 imx51_ipuv3_dump(struct imx51_ipuv3_softc *sc)
@@ -581,34 +551,14 @@ imx51_ipuv3_initialize(struct imx51_ipuv
 	IPUV3_WRITE(sc, cm, IPU_CM_DISP_GEN, reg);
 }
 
-static void
-imx51_ipuv3_init_screen(void *cookie, struct vcons_screen *scr,
-		    int existing, long *defattr)
+static int
+imx51_ipuv3_print(void *aux, const char *pnp)
 {
-	DPRINTFN(5, ("%s : %d\n", __func__, __LINE__));
-
-	struct imx51_ipuv3_softc *sc = cookie;
-	struct rasops_info *ri = &scr->scr_ri;
-	struct imx51_wsscreen_descr *descr = imx51_ipuv3_console.descr;
-
-	if ((scr == &sc->console) && (sc->vd.active != NULL))
-		return;
-
-	ri->ri_bits = sc->active->buf_va;
-
-	scr->scr_flags |= VCONS_DONT_READ;
-	if (existing)
-		ri->ri_flg |= RI_CLEAR;
-
-	imx51_ipuv3_setup_rasops(sc, ri, descr, sc->geometry);
+	const struct imxfb_attach_args * const ifb = aux;
 
-	ri->ri_caps = WSSCREEN_WSCOLORS;
+	aprint_normal(" output %s", device_xname(ifb->ifb_outputdev));
 
-	rasops_reconfig(ri,
-	    ri->ri_height / ri->ri_font->fontheight,
-	    ri->ri_width / ri->ri_font->fontwidth);
-
-	ri->ri_hw = scr;
+	return UNCONF;
 }
 
 /*
@@ -621,7 +571,6 @@ imx51_ipuv3_attach_sub(struct imx51_ipuv
 	DPRINTFN(5, ("%s : %d\n", __func__, __LINE__));
 
 	bus_space_tag_t iot = axia->aa_iot;
-	bus_space_handle_t ioh;
 	int error;
 
 	aprint_normal(": i.MX51 IPUV3 controller\n");
@@ -633,52 +582,44 @@ imx51_ipuv3_attach_sub(struct imx51_ipuv
 	sc->dma_tag = &imx_bus_dma_tag;
 
 	/* map controller registers */
-	error = bus_space_map(iot, IPU_CM_BASE, IPU_CM_SIZE, 0, &ioh);
+	error = bus_space_map(iot, IPU_CM_BASE, IPU_CM_SIZE, 0, &sc->cm_ioh);
 	if (error)
 		goto fail_retarn_cm;
-	sc->cm_ioh = ioh;
 
 	/* map Display Multi FIFO Controller registers */
-	error = bus_space_map(iot, IPU_DMFC_BASE, IPU_DMFC_SIZE, 0, &ioh);
+	error = bus_space_map(iot, IPU_DMFC_BASE, IPU_DMFC_SIZE, 0, &sc->dmfc_ioh);
 	if (error)
 		goto fail_retarn_dmfc;
-	sc->dmfc_ioh = ioh;
 
 	/* map Display Interface registers */
-	error = bus_space_map(iot, IPU_DI0_BASE, IPU_DI0_SIZE, 0, &ioh);
+	error = bus_space_map(iot, IPU_DI0_BASE, IPU_DI0_SIZE, 0, &sc->di0_ioh);
 	if (error)
 		goto fail_retarn_di0;
-	sc->di0_ioh = ioh;
 
 	/* map Display Processor registers */
-	error = bus_space_map(iot, IPU_DP_BASE, IPU_DP_SIZE, 0, &ioh);
+	error = bus_space_map(iot, IPU_DP_BASE, IPU_DP_SIZE, 0, &sc->dp_ioh);
 	if (error)
 		goto fail_retarn_dp;
-	sc->dp_ioh = ioh;
 
 	/* map Display Controller registers */
-	error = bus_space_map(iot, IPU_DC_BASE, IPU_DC_SIZE, 0, &ioh);
+	error = bus_space_map(iot, IPU_DC_BASE, IPU_DC_SIZE, 0, &sc->dc_ioh);
 	if (error)
 		goto fail_retarn_dc;
-	sc->dc_ioh = ioh;
 
 	/* map Image DMA Controller registers */
-	error = bus_space_map(iot, IPU_IDMAC_BASE, IPU_IDMAC_SIZE, 0, &ioh);
+	error = bus_space_map(iot, IPU_IDMAC_BASE, IPU_IDMAC_SIZE, 0, &sc->idmac_ioh);
 	if (error)
 		goto fail_retarn_idmac;
-	sc->idmac_ioh = ioh;
 
 	/* map CPMEM registers */
-	error = bus_space_map(iot, IPU_CPMEM_BASE, IPU_CPMEM_SIZE, 0, &ioh);
+	error = bus_space_map(iot, IPU_CPMEM_BASE, IPU_CPMEM_SIZE, 0, &sc->cpmem_ioh);
 	if (error)
 		goto fail_retarn_cpmem;
-	sc->cpmem_ioh = ioh;
 
 	/* map DCTEMPL registers */
-	error = bus_space_map(iot, IPU_DCTMPL_BASE, IPU_DCTMPL_SIZE, 0, &ioh);
+	error = bus_space_map(iot, IPU_DCTMPL_BASE, IPU_DCTMPL_SIZE, 0, &sc->dctmpl_ioh);
 	if (error)
 		goto fail_retarn_dctmpl;
-	sc->dctmpl_ioh = ioh;
 
 #ifdef notyet
 	sc->ih = imx51_ipuv3_intr_establish(IMX51_INT_IPUV3, IPL_BIO,
@@ -693,12 +634,8 @@ imx51_ipuv3_attach_sub(struct imx51_ipuv
 
 	imx51_ipuv3_initialize(sc, geom);
 
-#if NWSDISPLAY > 0
-	struct imx51_wsscreen_descr *descr = imx51_ipuv3_console.descr;
 	struct imx51_ipuv3_screen *scr;
-
-	sc->mode = WSDISPLAYIO_MODE_EMUL;
-	error = imx51_ipuv3_new_screen(sc, descr->depth, &scr);
+	error = imx51_ipuv3_new_screen(sc, &scr);
 	if (error) {
 		aprint_error_dev(sc->dev,
 		    "unable to create new screen (errno=%d)", error);
@@ -706,41 +643,22 @@ imx51_ipuv3_attach_sub(struct imx51_ipuv
 	}
 	sc->active = scr;
 
-	vcons_init(&sc->vd, sc, &descr->c,
-	    imx51_ipuv3_console.accessops);
-	sc->vd.init_screen = imx51_ipuv3_init_screen;
-
-#ifdef IPUV3_DEBUG
-	printf("%s: IPUV3 console ? %d\n", __func__, imx51_ipuv3_console.is_console);
-#endif
-
-	struct rasops_info *ri;
-	long defattr;
-	ri = &sc->console.scr_ri;
-
-	vcons_init_screen(&sc->vd, &sc->console, 1,
-	    &defattr);
-	sc->console.scr_flags |= VCONS_SCREEN_IS_STATIC;
-
-	descr->c.nrows = ri->ri_rows;
-	descr->c.ncols = ri->ri_cols;
-	descr->c.textops = &ri->ri_ops;
-	descr->c.capabilities = ri->ri_caps;
-
-	if (imx51_ipuv3_console.is_console) {
-		wsdisplay_cnattach(&descr->c, ri, 0, 0, defattr);
-		aprint_normal_dev(sc->dev, "console\n");
-	}
-
-	vcons_replay_msgbuf(&sc->console);
-
 	imx51_ipuv3_start_dma(sc, scr);
-#endif
 
-	if (!pmf_device_register(sc->dev, imx51_ipuv3_suspend,
-		imx51_ipuv3_resume)) {
-		aprint_error_dev(sc->dev, "can't establish power hook\n");
-	}
+	struct imxfb_attach_args ifb = {
+		.ifb_dmat      = sc->dma_tag,
+		.ifb_dmamap    = scr->dma,
+		.ifb_dmasegs   = scr->segs,
+		.ifb_ndmasegs  = scr->nsegs,
+		.ifb_fb	       = scr->buf_va,
+		.ifb_width     = geom->panel_width,
+		.ifb_height    = geom->panel_height,
+		.ifb_depth     = scr->depth,
+		.ifb_stride    = geom->panel_width * (scr->depth / 8),
+		.ifb_outputdev = sc->dev,
+	};
+
+	sc->fbdev = config_found_ia(sc->dev, "ipu", &ifb, imx51_ipuv3_print);
 
 	return;
 
@@ -764,19 +682,6 @@ fail_retarn_cm:
 	return;
 }
 
-int
-imx51_ipuv3_cnattach(bool isconsole, struct imx51_wsscreen_descr *descr,
-    struct wsdisplay_accessops *accessops,
-    const struct lcd_panel_geometry *geom)
-{
-	DPRINTFN(5, ("%s : %d\n", __func__, __LINE__));
-	imx51_ipuv3_console.descr = descr;
-	imx51_ipuv3_console.geom = geom;
-	imx51_ipuv3_console.accessops = accessops;
-	imx51_ipuv3_console.is_console = isconsole;
-	return 0;
-}
-
 #ifdef notyet
 /*
  * Interrupt handler.
@@ -902,8 +807,6 @@ imx51_ipuv3_set_idma_param(uint32_t *par
 	int width = name & 0xff;
 	int index;
 
-	DPRINTFN(5, ("%s : %d\n", __func__, __LINE__));
-
 	index = word * 5;
 	index += shift / 32;
 	shift = shift % 32;
@@ -968,35 +871,64 @@ imx51_ipuv3_start_dma(struct imx51_ipuv3
 #endif
 }
 
-/*
- * Disable screen refresh.
- */
-static void
-imx51_ipuv3_stop_dma(struct imx51_ipuv3_softc *sc)
+static int
+imx51_ipuv3_allocmem(struct imx51_ipuv3_softc *sc,
+    struct imx51_ipuv3_screen *scr)
 {
-	DPRINTFN(5, ("%s : %d\n", __func__, __LINE__));
+	int error;
 
-	return;
+	error = bus_dmamem_alloc(sc->dma_tag, scr->buf_size, PAGE_SIZE, 0,
+	    scr->segs, 1, &scr->nsegs, BUS_DMA_WAITOK);
+	if (error)
+		return error;
+	error = bus_dmamem_map(sc->dma_tag, scr->segs, scr->nsegs, scr->buf_size,
+	    (void **)&scr->buf_va, BUS_DMA_WAITOK | BUS_DMA_COHERENT);
+	if (error)
+		goto free;
+	/* map memory for DMA */
+	error = bus_dmamap_create(sc->dma_tag, scr->buf_size, 1, scr->buf_size, 0,
+	    BUS_DMA_WAITOK, &scr->dma);
+	if (error)
+		goto unmap;
+	error = bus_dmamap_load(sc->dma_tag, scr->dma, scr->buf_va, scr->buf_size,
+	    NULL, BUS_DMA_WAITOK);
+	if (error)
+		goto destroy;
+
+	memset(scr->buf_va, 0, scr->buf_size);
+
+	return 0;
+
+destroy:
+	bus_dmamap_destroy(sc->dma_tag, scr->dma);
+unmap:
+	bus_dmamem_unmap(sc->dma_tag, scr->buf_va, scr->buf_size);
+free:
+	bus_dmamem_free(sc->dma_tag, scr->segs, scr->nsegs);
+
+	scr->buf_size = 0;
+	scr->buf_va = NULL;
+
+	return error;
 }
 
 /*
  * Create and initialize a new screen buffer.
  */
 int
-imx51_ipuv3_new_screen(struct imx51_ipuv3_softc *sc, int depth,
+imx51_ipuv3_new_screen(struct imx51_ipuv3_softc *sc,
     struct imx51_ipuv3_screen **scrpp)
 {
 	const struct lcd_panel_geometry *geometry;
 	struct imx51_ipuv3_screen *scr = NULL;
-	int width, height;
-	bus_size_t size;
+	int depth, width, height;
 	int error;
-	int busdma_flag = (cold ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
 
 	DPRINTFN(5, ("%s : %d\n", __func__, __LINE__));
 
 	geometry = sc->geometry;
 
+	depth = geometry->depth;
 	width = geometry->panel_width;
 	height = geometry->panel_height;
 
@@ -1009,41 +941,17 @@ imx51_ipuv3_new_screen(struct imx51_ipuv
 	scr->nsegs = 0;
 	scr->depth = depth;
 	scr->stride = width * depth / 8;
-	scr->buf_size = size = scr->stride * height;
+	scr->buf_size = scr->stride * height;
 	scr->buf_va = NULL;
 
-	error = bus_dmamem_alloc(sc->dma_tag, size, 16, 0, scr->segs, 1,
-	    &scr->nsegs, busdma_flag);
-
-	if (error || scr->nsegs != 1) {
-		/* XXX:
-		 * Actually we can handle nsegs>1 case by means
-		 * of multiple DMA descriptors for a panel.  It
-		 * will make code here a bit hairly.
-		 */
-		if (error == 0)
-			error = E2BIG;
-		goto bad;
+	error = imx51_ipuv3_allocmem(sc, scr);
+	if (error) {
+		aprint_error_dev(sc->dev,
+		    "failed to allocate %u bytes of video memory: %d\n",
+		    scr->stride * height, error);
+		return error;
 	}
 
-	error = bus_dmamem_map(sc->dma_tag, scr->segs, scr->nsegs, size,
-	    (void **)&scr->buf_va, busdma_flag | BUS_DMA_COHERENT);
-	if (error)
-		goto bad;
-
-	memset(scr->buf_va, 0, scr->buf_size);
-
-	/* map memory for DMA */
-	error = bus_dmamap_create(sc->dma_tag, 1024*1024*2, 1, 1024*1024*2, 0,
-	    busdma_flag, &scr->dma);
-	if (error)
-		goto bad;
-
-	error = bus_dmamap_load(sc->dma_tag, scr->dma, scr->buf_va, size,
-	    NULL, busdma_flag);
-	if (error)
-		goto bad;
-
 	LIST_INSERT_HEAD(&sc->screens, scr, link);
 	sc->n_screens++;
 
@@ -1059,263 +967,9 @@ imx51_ipuv3_new_screen(struct imx51_ipuv
 	    (void *)scr->segs[0].ds_addr);
 #endif
 
-	scr->map_size = size;		/* used when unmap this. */
+	scr->map_size = scr->buf_size;		/* used when unmap this. */
 
 	*scrpp = scr;
 
 	return 0;
-
-bad:
-#ifdef IPUV3_DEBUG
-	printf("%s: error = 0x%08X\n", __func__, error);
-#endif
-	if (scr) {
-		if (scr->buf_va)
-			bus_dmamem_unmap(sc->dma_tag, scr->buf_va, size);
-		if (scr->nsegs)
-			bus_dmamem_free(sc->dma_tag, scr->segs, scr->nsegs);
-		free(scr, M_DEVBUF);
-	}
-	*scrpp = NULL;
-	return error;
-}
-
-#if NWSDISPLAY > 0
-/*
- * Initialize rasops for a screen, as well as struct wsscreen_descr if this
- * is the first screen creation.
- */
-static void
-imx51_ipuv3_setup_rasops(struct imx51_ipuv3_softc *sc, struct rasops_info *rinfo,
-    struct imx51_wsscreen_descr *descr,
-    const struct lcd_panel_geometry *geom)
-{
-
-	DPRINTFN(5, ("%s : %d\n", __func__, __LINE__));
-
-	rinfo->ri_flg = descr->flags;
-	rinfo->ri_depth = descr->depth;
-	rinfo->ri_width = geom->panel_width;
-	rinfo->ri_height = geom->panel_height;
-	rinfo->ri_stride = rinfo->ri_width * rinfo->ri_depth / 8;
-
-	/* swap B and R */
-	if (descr->depth == 16) {
-		rinfo->ri_rnum = 5;
-		rinfo->ri_rpos = 11;
-		rinfo->ri_gnum = 6;
-		rinfo->ri_gpos = 5;
-		rinfo->ri_bnum = 5;
-		rinfo->ri_bpos = 0;
-	}
-
-	if (descr->c.nrows == 0) {
-		/* get rasops to compute screen size the first time */
-		rasops_init(rinfo, 100, 100);
-	} else {
-		rasops_init(rinfo, descr->c.nrows, descr->c.ncols);
-	}
-
-	descr->c.nrows = rinfo->ri_rows;
-	descr->c.ncols = rinfo->ri_cols;
-	descr->c.capabilities = rinfo->ri_caps;
-	descr->c.textops = &rinfo->ri_ops;
-}
-#endif
-/*
- * Power management
- */
-static bool
-imx51_ipuv3_suspend(device_t dv, const pmf_qual_t *qual)
-{
-	struct imx51_ipuv3_softc *sc = device_private(dv);
-	DPRINTFN(5, ("%s : %d\n", __func__, __LINE__));
-	if (sc->active)
-		imx51_ipuv3_stop_dma(sc);
-	return true;
-}
-
-static bool
-imx51_ipuv3_resume(device_t dv, const pmf_qual_t *qual)
-{
-	struct imx51_ipuv3_softc *sc = device_private(dv);
-	DPRINTFN(5, ("%s : %d\n", __func__, __LINE__));
-	if (sc->active) {
-		imx51_ipuv3_initialize(sc, sc->geometry);
-		imx51_ipuv3_start_dma(sc, sc->active);
-	}
-	return true;
-}
-
-#if NWSDISPLAY > 0
-int
-imx51_ipuv3_show_screen(void *v, void *cookie, int waitok,
-    void (*cb)(void *, int, int), void *cbarg)
-{
-	struct vcons_data *vd = v;
-	struct imx51_ipuv3_softc *sc = vd->cookie;
-	struct imx51_ipuv3_screen *scr = cookie, *old;
-	DPRINTFN(5, ("%s : %d\n", __func__, __LINE__));
-
-	old = sc->active;
-	if (old == scr)
-		return 0;
-	if (old)
-		imx51_ipuv3_stop_dma(sc);
-	imx51_ipuv3_start_dma(sc, scr);
-	sc->active = scr;
-	return 0;
-}
-
-int
-imx51_ipuv3_alloc_screen(void *v, const struct wsscreen_descr *_type,
-    void **cookiep, int *curxp, int *curyp, long *attrp)
-{
-	struct vcons_data *vd = v;
-	struct imx51_ipuv3_softc *sc = vd->cookie;
-	struct imx51_ipuv3_screen *scr;
-	const struct imx51_wsscreen_descr *type =
-		(const struct imx51_wsscreen_descr *)_type;
-	int error;
-	DPRINTFN(5, ("%s : %d\n", __func__, __LINE__));
-
-	error = imx51_ipuv3_new_screen(sc, type->depth, &scr);
-	if (error)
-		return error;
-
-	/*
-	 * initialize raster operation for this screen.
-	 */
-	scr->rinfo.ri_flg = 0;
-	scr->rinfo.ri_depth = type->depth;
-	scr->rinfo.ri_bits = scr->buf_va;
-	scr->rinfo.ri_width = sc->geometry->panel_width;
-	scr->rinfo.ri_height = sc->geometry->panel_height;
-	scr->rinfo.ri_stride = scr->rinfo.ri_width * scr->rinfo.ri_depth / 8;
-#ifdef CPU_XSCALE_PXA270
-	if (scr->rinfo.ri_depth > 16)
-		scr->rinfo.ri_stride = scr->rinfo.ri_width * 4;
-#endif
-	scr->rinfo.ri_wsfcookie = -1;	/* XXX */
-
-	rasops_init(&scr->rinfo, type->c.nrows, type->c.ncols);
-
-	(*scr->rinfo.ri_ops.allocattr)(&scr->rinfo, 0, 0, 0, attrp);
-
-	*cookiep = scr;
-	*curxp = 0;
-	*curyp = 0;
-
-	return 0;
-}
-
-void
-imx51_ipuv3_free_screen(void *v, void *cookie)
-{
-	struct vcons_data *vd = v;
-	struct imx51_ipuv3_softc *sc = vd->cookie;
-	struct imx51_ipuv3_screen *scr = cookie;
-	DPRINTFN(5, ("%s : %d\n", __func__, __LINE__));
-
-	LIST_REMOVE(scr, link);
-	sc->n_screens--;
-	if (scr == sc->active) {
-		/* at first, we need to stop LCD DMA */
-		sc->active = NULL;
-
-		printf("lcd_free on active screen\n");
-
-		imx51_ipuv3_stop_dma(sc);
-	}
-
-	if (scr->buf_va)
-		bus_dmamem_unmap(sc->dma_tag, scr->buf_va, scr->map_size);
-	if (scr->nsegs > 0)
-		bus_dmamem_free(sc->dma_tag, scr->segs, scr->nsegs);
-	free(scr, M_DEVBUF);
 }
-
-int
-imx51_ipuv3_ioctl(void *v, void *vs, u_long cmd, void *data, int flag,
-    struct lwp *l)
-{
-	struct vcons_data *vd = v;
-	struct imx51_ipuv3_softc *sc = vd->cookie;
-	struct wsdisplay_fbinfo *wsdisp_info;
-	struct vcons_screen *ms = vd->active;
-
-	DPRINTFN(5, ("%s : cmd 0x%X (%d)\n", __func__, (u_int)cmd, (int)IOCGROUP(cmd)));
-
-	switch (cmd) {
-	case WSDISPLAYIO_GTYPE:
-		*(int *)data = WSDISPLAY_TYPE_IMXIPU;
-		return 0;
-
-	case WSDISPLAYIO_GINFO:
-		wsdisp_info = (struct wsdisplay_fbinfo *)data;
-		wsdisp_info->height = ms->scr_ri.ri_height;
-		wsdisp_info->width = ms->scr_ri.ri_width;
-		wsdisp_info->depth = ms->scr_ri.ri_depth;
-		wsdisp_info->cmsize = 0;
-		return 0;
-
-	case WSDISPLAYIO_LINEBYTES:
-		*(u_int *)data = ms->scr_ri.ri_stride;
-		return 0;
-
-	case WSDISPLAYIO_GETCMAP:
-	case WSDISPLAYIO_PUTCMAP:
-		return EPASSTHROUGH;	/* XXX Colormap */
-
-	case WSDISPLAYIO_SVIDEO:
-		if (*(int *)data == WSDISPLAYIO_VIDEO_ON) {
-			/* turn it on */
-		}
-		else {
-			/* start IPUV3 shutdown */
-			/* sleep until interrupt */
-		}
-		return 0;
-
-	case WSDISPLAYIO_GVIDEO:
-		*(u_int *)data =  WSDISPLAYIO_VIDEO_ON;
-		return 0;
-
-	case WSDISPLAYIO_GCURPOS:
-	case WSDISPLAYIO_SCURPOS:
-	case WSDISPLAYIO_GCURMAX:
-	case WSDISPLAYIO_GCURSOR:
-	case WSDISPLAYIO_SCURSOR:
-		return EPASSTHROUGH;	/* XXX */
-	case WSDISPLAYIO_SMODE:
-		{
-			int new_mode = *(int*)data;
-
-			/* notify the bus backend */
-			if (new_mode != sc->mode) {
-				sc->mode = new_mode;
-				if(new_mode == WSDISPLAYIO_MODE_EMUL)
-					vcons_redraw_screen(ms);
-			}
-		}
-		return 0;
-	}
-
-	return EPASSTHROUGH;
-}
-
-paddr_t
-imx51_ipuv3_mmap(void *v, void *vs, off_t offset, int prot)
-{
-	DPRINTFN(5, ("%s : %d\n", __func__, __LINE__));
-
-	struct vcons_data *vd = v;
-	struct imx51_ipuv3_softc *sc = vd->cookie;
-	struct imx51_ipuv3_screen *scr = sc->active;
-
-	return bus_dmamem_mmap(sc->dma_tag, scr->segs, scr->nsegs,
-	    offset, prot,
-	    BUS_DMA_WAITOK | BUS_DMA_COHERENT);
-}
-#endif /* NWSDISPLAY > 0 */
-
Index: src/sys/arch/arm/imx/imx51var.h
diff -u src/sys/arch/arm/imx/imx51var.h:1.3 src/sys/arch/arm/imx/imx51var.h:1.4
--- src/sys/arch/arm/imx/imx51var.h:1.3	Thu May  7 04:13:47 2015
+++ src/sys/arch/arm/imx/imx51var.h	Mon Dec 21 04:26:28 2015
@@ -1,8 +1,49 @@
-/*	$NetBSD: imx51var.h,v 1.3 2015/05/07 04:13:47 hkenken Exp $ */
+/*	$NetBSD: imx51var.h,v 1.4 2015/12/21 04:26:28 hkenken Exp $ */
+
+/*
+ * Copyright (c) 2015 Genetec Corporation.  All rights reserved.
+ * Written by Hashimoto Kenichi for Genetec Corporation.
+ *
+ * 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 GENETEC CORPORATION ``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 GENETEC CORPORATION
+ * 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_IMX_IMX51VAR_H
 #define	_ARM_IMX_IMX51VAR_H
 
+struct imxfb_attach_args {
+	void			*ifb_fb;
+	bus_dma_tag_t		 ifb_dmat;
+	bus_dmamap_t		 ifb_dmamap;
+	bus_dma_segment_t	*ifb_dmasegs;
+	int			 ifb_ndmasegs;
+	u_int			 ifb_width;
+	u_int			 ifb_height;
+	u_int			 ifb_depth;
+	u_int			 ifb_stride;
+	device_t		 ifb_outputdev;
+};
+
+void	imx_genfb_set_videomode(device_t, u_int, u_int);
+
 extern struct bus_space armv7_generic_bs_tag;
 extern struct bus_space armv7_generic_a4x_bs_tag;
 extern struct arm32_bus_dma_tag imx_bus_dma_tag;

Index: src/sys/arch/arm/imx/imx51_ipuv3var.h
diff -u src/sys/arch/arm/imx/imx51_ipuv3var.h:1.2 src/sys/arch/arm/imx/imx51_ipuv3var.h:1.3
--- src/sys/arch/arm/imx/imx51_ipuv3var.h:1.2	Tue May  6 11:22:53 2014
+++ src/sys/arch/arm/imx/imx51_ipuv3var.h	Mon Dec 21 04:26:28 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: imx51_ipuv3var.h,v 1.2 2014/05/06 11:22:53 hkenken Exp $	*/
+/*	$NetBSD: imx51_ipuv3var.h,v 1.3 2015/12/21 04:26:28 hkenken Exp $	*/
 
 /*
  * Copyright (c) 2009, 2011, 2012  Genetec Corporation.  All rights reserved.
@@ -26,13 +26,13 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
-
 #ifndef _ARM_IMX_IMX51_IPUV3_H
 #define _ARM_IMX_IMX51_IPUV3_H
 
+#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wsdisplayvar.h>
+
 #include <sys/bus.h>
-#include <dev/rasops/rasops.h>
-#include <dev/wscons/wsdisplay_vconsvar.h>
 
 /* IPUV3 Contoroller */
 struct imx51_ipuv3_screen {
@@ -51,12 +51,11 @@ struct imx51_ipuv3_screen {
 	/* DMA frame descriptor */
 	struct	ipuv3_dma_descriptor *dma_desc;
 	paddr_t	dma_desc_pa;
-
-	/* rasterop */
-	struct rasops_info rinfo;
 };
 
 struct lcd_panel_geometry {
+	int depth;
+
 	short panel_width;
 	short panel_height;
 
@@ -100,44 +99,23 @@ struct imx51_ipuv3_softc {
 	struct imx51_ipuv3_screen *active;
 	void *ih;			/* interrupt handler */
 
-	/* virtual console support */
-	struct vcons_data vd;
-	struct vcons_screen console;
-	int mode;
-};
-
-/*
- * we need bits-per-pixel value to configure wsdisplay screen
- */
-struct imx51_wsscreen_descr {
-	struct wsscreen_descr  c;	/* standard descriptor */
-	int depth;			/* bits per pixel */
-	int flags;			/* rasops flags */
+	device_t		fbdev;
 };
 
 struct imx51_ipuv3_softc;
 
 void	imx51_ipuv3_attach_sub(struct imx51_ipuv3_softc *,
-	    struct axi_attach_args *, const struct lcd_panel_geometry *);
-int	imx51_ipuv3_cnattach(bool, struct imx51_wsscreen_descr *,
-	    struct wsdisplay_accessops *,
-	    const struct lcd_panel_geometry *);
+    struct axi_attach_args *, const struct lcd_panel_geometry *);
+int	imx51_ipuv3_cnattach(bool);
 void	imx51_ipuv3_start_dma(struct imx51_ipuv3_softc *,
 	    struct imx51_ipuv3_screen *);
 
 void	imx51_ipuv3_geometry(struct imx51_ipuv3_softc *,
 	    const struct lcd_panel_geometry *);
-int	imx51_ipuv3_new_screen(struct imx51_ipuv3_softc *, int,
+int	imx51_ipuv3_new_screen(struct imx51_ipuv3_softc *,
 	    struct imx51_ipuv3_screen **);
 
-int	imx51_ipuv3_alloc_screen(void *, const struct wsscreen_descr *,
-	    void **, int *, int *, long *);
-void	imx51_ipuv3_free_screen(void *, void *);
-int	imx51_ipuv3_ioctl(void *, void *, u_long, void *, int, struct lwp *);
-paddr_t	imx51_ipuv3_mmap(void *, void *, off_t, int);
 int	imx51_ipuv3_show_screen(void *, void *, int, void (*)(void *, int, int),
 	    void *);
 
-extern const struct wsdisplay_emulops imx51_ipuv3_emulops;
-
 #endif /* _ARM_IMX_IMX51_IPUV3_H */

Index: src/sys/arch/evbarm/conf/NETWALKER
diff -u src/sys/arch/evbarm/conf/NETWALKER:1.34 src/sys/arch/evbarm/conf/NETWALKER:1.35
--- src/sys/arch/evbarm/conf/NETWALKER:1.34	Fri May  1 07:22:42 2015
+++ src/sys/arch/evbarm/conf/NETWALKER	Mon Dec 21 04:26:29 2015
@@ -1,4 +1,4 @@
-#	$NetBSD: NETWALKER,v 1.34 2015/05/01 07:22:42 hkenken Exp $
+#	$NetBSD: NETWALKER,v 1.35 2015/12/21 04:26:29 hkenken Exp $
 #
 #	NETWALKER -- http://www.sharp.co.jp/netwalker/
 #
@@ -30,7 +30,9 @@ makeoptions	COPY_SYMTAB=1
 #  memorydisk=<n>	Set memorydisk size to <n> KB
 #  quiet		Show aprint_naive output
 #  verbose		Show aprint_normal and aprint_verbose output
-#options		BOOT_ARGS="\"verbose\""
+#  console=(fb|serial)	Select console device
+options 	BOOT_ARGS="\"verbose console=fb\""
+#options 	BOOT_ARGS="\"verbose\""
 
 # Kernel root file system and dump configuration.
 config		netbsd		root on ? type ?
@@ -140,20 +142,24 @@ ukphy*		at mii? phy ?
 
 # IPUv3 LCD Controller
 ipu0		at axi?
-wsdisplay0	at wsemuldisplaydev? console ?
-wsdisplay*	at wsemuldisplaydev?
 #options	IPUV3_DEBUG=1
 #options	LCD_DEBUG
-options 	IMXIPUCONSOLE
+
+# Framebuffer console
+genfb*		at ipu?
+wsdisplay*	at genfb?
+#options 	GENFB_SHADOWFB
 
 # various options for wscons - we try to look as much like a standard
 # sun console as possible
+options 	VCONS_DRAW_INTR
 options 	WSEMUL_VT100		# sun terminal emulation
 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 	WS_KERNEL_FG=WSCOL_GREEN
+options 	WS_KERNEL_BG=WSCOL_BLACK
 options 	WSDISPLAY_COMPAT_PCVT		# emulate some ioctls
+options 	WSDISPLAY_COMPAT_SYSCONS	# emulate some more ioctls
 options 	WSDISPLAY_COMPAT_USL		# wsconscfg VT handling
 options 	WSDISPLAY_COMPAT_RAWKBD		# can get raw scancodes
 options 	WSDISPLAY_DEFAULTSCREENS=4

Index: src/sys/arch/evbarm/conf/files.netwalker
diff -u src/sys/arch/evbarm/conf/files.netwalker:1.9 src/sys/arch/evbarm/conf/files.netwalker:1.10
--- src/sys/arch/evbarm/conf/files.netwalker:1.9	Thu May  7 04:13:47 2015
+++ src/sys/arch/evbarm/conf/files.netwalker	Mon Dec 21 04:26:29 2015
@@ -1,4 +1,4 @@
-#	$NetBSD: files.netwalker,v 1.9 2015/05/07 04:13:47 hkenken Exp $
+#	$NetBSD: files.netwalker,v 1.10 2015/12/21 04:26:29 hkenken Exp $
 #
 # Sharp Netwalker configuration info
 #
@@ -16,7 +16,7 @@ attach imxusbc at axi with imxusbc_axi
 file   arch/evbarm/netwalker/netwalker_usb.c	imxusbc_axi
 
 # LCD controller
-attach	ipu at axi with lcd_netwalker
+attach	ipu at axi with lcd_netwalker : imx_ipuv3
 file	arch/evbarm/netwalker/netwalker_lcd.c	lcd_netwalker
 defflag	opt_netwalker_lcd.h			LCD_DEBUG
 

Index: src/sys/arch/evbarm/netwalker/netwalker_backlight.c
diff -u src/sys/arch/evbarm/netwalker/netwalker_backlight.c:1.1 src/sys/arch/evbarm/netwalker/netwalker_backlight.c:1.2
--- src/sys/arch/evbarm/netwalker/netwalker_backlight.c:1.1	Tue May  6 11:22:53 2014
+++ src/sys/arch/evbarm/netwalker/netwalker_backlight.c	Mon Dec 21 04:26:29 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: netwalker_backlight.c,v 1.1 2014/05/06 11:22:53 hkenken Exp $	*/
+/*	$NetBSD: netwalker_backlight.c,v 1.2 2015/12/21 04:26:29 hkenken Exp $	*/
 
 /*
  * Copyright (c) 2014  Genetec Corporation.  All rights reserved.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: netwalker_backlight.c,v 1.1 2014/05/06 11:22:53 hkenken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: netwalker_backlight.c,v 1.2 2015/12/21 04:26:29 hkenken Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -37,6 +37,7 @@ __KERNEL_RCSID(0, "$NetBSD: netwalker_ba
 
 #include <dev/wscons/wsconsio.h>
 #include <dev/wscons/wsdisplayvar.h>
+#include <dev/wsfb/genfbvar.h>
 
 #include <dev/sysmon/sysmonvar.h>
 #include <dev/sysmon/sysmon_taskq.h>
@@ -48,7 +49,7 @@ __KERNEL_RCSID(0, "$NetBSD: netwalker_ba
 
 #include <evbarm/netwalker/netwalker_backlightvar.h>
 
-#define BRIGHTNESS_MAX	16
+#define BRIGHTNESS_MAX	255
 
 struct netwalker_backlight_softc {
 	struct imxpwm_softc sc_imxpwm;
@@ -59,6 +60,9 @@ struct netwalker_backlight_softc {
 
 static struct netwalker_backlight_softc *netwalker_backlight_sc;
 
+static struct genfb_parameter_callback gpc_backlight;
+static struct genfb_parameter_callback gpc_brightness;
+
 static int netwalker_backlight_match(device_t, cfdata_t, void *);
 static void netwalker_backlight_attach(device_t, device_t, void *);
 static int netwalker_backlight_detach(device_t, int);
@@ -144,6 +148,86 @@ netwalker_backlight_detach(device_t self
 	return 0;
 }
 
+static int
+netwalker_backlight_get_backlight(void *cookie, int *state)
+{
+	struct netwalker_backlight_softc *sc = *(struct netwalker_backlight_softc **)cookie;
+	*state = sc->sc_islit;
+	return 0;
+}
+
+static int
+netwalker_backlight_set_backlight(void *cookie, int state)
+{
+	struct netwalker_backlight_softc *sc = *(struct netwalker_backlight_softc **)cookie;
+
+	KASSERT(state >= 0 && state <= 1);
+
+	sc->sc_islit = state;
+	netwalker_set_brightness(sc, sc->sc_brightness);
+
+	return 0;
+}
+
+static int
+netwalker_backlight_get_brightness(void *cookie, int *level)
+{
+	struct netwalker_backlight_softc *sc = *(struct netwalker_backlight_softc **)cookie;
+
+	if (sc->sc_brightness < 0)
+		return ENODEV;
+
+	*level = sc->sc_brightness;
+	return 0;
+}
+
+static int
+netwalker_backlight_set_brightness(void *cookie, int level)
+{
+	struct netwalker_backlight_softc *sc = *(struct netwalker_backlight_softc **)cookie;
+
+	KASSERT(level >= 0 && level <= 255);
+
+	sc->sc_brightness = level;
+	netwalker_set_brightness(sc, sc->sc_brightness);
+
+	return 0;
+}
+
+static int
+netwalker_backlight_upd_brightness(void *cookie, int delta)
+{
+	struct netwalker_backlight_softc *sc = *(struct netwalker_backlight_softc **)cookie;
+
+	if (sc->sc_brightness < 0)
+		return ENODEV;
+
+	sc->sc_brightness += delta;
+	if (sc->sc_brightness < 0) sc->sc_brightness = 0;
+	if (sc->sc_brightness > 255) sc->sc_brightness = 255;
+	netwalker_set_brightness(sc, sc->sc_brightness);
+
+	return 0;
+}
+
+void
+netwalker_backlight_genfb_parameter_set(prop_dictionary_t dict)
+{
+	gpc_backlight.gpc_cookie = (void *)&netwalker_backlight_sc;
+	gpc_backlight.gpc_set_parameter = netwalker_backlight_set_backlight;
+	gpc_backlight.gpc_get_parameter = netwalker_backlight_get_backlight;
+	gpc_backlight.gpc_upd_parameter = NULL;
+	prop_dictionary_set_uint64(dict, "backlight_callback",
+	    (uint64_t)(uintptr_t)&gpc_backlight);
+
+	gpc_brightness.gpc_cookie = (void *)&netwalker_backlight_sc;
+	gpc_brightness.gpc_set_parameter = netwalker_backlight_set_brightness;
+	gpc_brightness.gpc_get_parameter = netwalker_backlight_get_brightness;
+	gpc_brightness.gpc_upd_parameter = netwalker_backlight_upd_brightness;
+	prop_dictionary_set_uint64(dict, "brightness_callback",
+	    (uint64_t)(uintptr_t)&gpc_brightness);
+}
+
 /*
  * Power management
  */
Index: src/sys/arch/evbarm/netwalker/netwalker_backlightvar.h
diff -u src/sys/arch/evbarm/netwalker/netwalker_backlightvar.h:1.1 src/sys/arch/evbarm/netwalker/netwalker_backlightvar.h:1.2
--- src/sys/arch/evbarm/netwalker/netwalker_backlightvar.h:1.1	Tue May  6 11:22:53 2014
+++ src/sys/arch/evbarm/netwalker/netwalker_backlightvar.h	Mon Dec 21 04:26:29 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: netwalker_backlightvar.h,v 1.1 2014/05/06 11:22:53 hkenken Exp $	*/
+/*	$NetBSD: netwalker_backlightvar.h,v 1.2 2015/12/21 04:26:29 hkenken Exp $	*/
 
 /*
  * Copyright (c) 2014  Genetec Corporation.  All rights reserved.
@@ -29,6 +29,10 @@
 #ifndef _EVBARM_NETWALKER_NETWALKER_BACKLIGHTVAR_H
 #define _EVBARM_NETWALKER_NETWALKER_BACKLIGHTVAR_H
 
+#include <dev/wscons/wsconsio.h>
+
 int netwalker_lcd_param_ioctl(u_long cmd, struct wsdisplay_param *dp);
 
+void netwalker_backlight_genfb_parameter_set(prop_dictionary_t);
+
 #endif	/* _EVBARM_NETWALKER_NETWALKER_BACKLIGHTVAR_H */

Index: src/sys/arch/evbarm/netwalker/netwalker_lcd.c
diff -u src/sys/arch/evbarm/netwalker/netwalker_lcd.c:1.4 src/sys/arch/evbarm/netwalker/netwalker_lcd.c:1.5
--- src/sys/arch/evbarm/netwalker/netwalker_lcd.c:1.4	Fri Jul 25 08:10:33 2014
+++ src/sys/arch/evbarm/netwalker/netwalker_lcd.c	Mon Dec 21 04:26:29 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: netwalker_lcd.c,v 1.4 2014/07/25 08:10:33 dholland Exp $	*/
+/*	$NetBSD: netwalker_lcd.c,v 1.5 2015/12/21 04:26:29 hkenken Exp $	*/
 
 /*-
  * Copyright (c) 2011, 2012 Genetec corp. All rights reserved.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: netwalker_lcd.c,v 1.4 2014/07/25 08:10:33 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: netwalker_lcd.c,v 1.5 2015/12/21 04:26:29 hkenken Exp $");
 
 #include "opt_imx51_ipuv3.h"
 #include "opt_netwalker_lcd.h"
@@ -37,17 +37,7 @@ __KERNEL_RCSID(0, "$NetBSD: netwalker_lc
 #include "netwalker_backlight.h"
 
 #include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/conf.h>
-#include <sys/uio.h>
-#include <sys/malloc.h>
 #include <sys/device.h>
-#include <sys/pmf.h>
-
-#include <dev/cons.h>
-#include <dev/wscons/wsconsio.h>
-#include <dev/wscons/wsdisplayvar.h>
-#include <dev/wscons/wscons_callbacks.h>
 
 #include <sys/bus.h>
 #include <arm/imx/imx51var.h>
@@ -61,54 +51,8 @@ __KERNEL_RCSID(0, "$NetBSD: netwalker_lc
 int lcd_match(device_t, cfdata_t, void *);
 void lcd_attach(device_t, device_t, void *);
 
-void netwalker_cnattach(void);
-
-#if NWSDISPLAY > 0
-static int netwalker_lcd_ioctl(void *, void *, u_long, void *, int,
-    struct lwp *);
-static int netwalker_lcd_show_screen(void *, void *, int,
-    void (*)(void *, int, int), void *);
-
-bool netwalker_lcd_console = 0;
-
-/*
- * wsdisplay glue
- */
-static struct imx51_wsscreen_descr netwalker_lcd_stdscreen = {
-	.c = {
-		.name	      = "std",
-		.ncols	      = 0,
-		.nrows	      = 0,
-		.textops      = NULL,
-		.fontwidth    = 8,
-		.fontheight   = 16,
-		.capabilities = WSSCREEN_WSCOLORS | WSSCREEN_HILIT,
-		.modecookie   = NULL
-	},
-	.depth = 16,		/* bits per pixel */
-	.flags = RI_CENTER | RI_FULLCLEAR
-};
-
-static const struct wsscreen_descr *netwalker_lcd_scr_descr[] = {
-	&netwalker_lcd_stdscreen.c,
-};
-
-const struct wsscreen_list netwalker_lcd_screen_list = {
-	sizeof netwalker_lcd_scr_descr / sizeof netwalker_lcd_scr_descr[0],
-	netwalker_lcd_scr_descr
-};
+#if NWSDISPLAY == 0
 
-struct wsdisplay_accessops netwalker_lcd_accessops = {
-	.ioctl	      = netwalker_lcd_ioctl,
-	.mmap	      = imx51_ipuv3_mmap,
-	.alloc_screen = imx51_ipuv3_alloc_screen,
-	.free_screen  = imx51_ipuv3_free_screen,
-	.show_screen  = netwalker_lcd_show_screen,
-	.load_font    = NULL,
-	.pollc	      = NULL,
-	.scroll	      = NULL
-};
-#else
 #ifdef LCD_DEBUG
 static void draw_test_pattern(struct imx51_ipuv3_softc *,
     struct imx51_ipuv3_screen *);
@@ -150,8 +94,9 @@ lcd_match( device_t parent, cfdata_t cf,
 }
 
 /* Sharp's LCD */
-static const struct lcd_panel_geometry sharp_panel =
-{
+static const struct lcd_panel_geometry sharp_panel = {
+	.depth = 16,
+
 	.panel_width = 1024,	/* Width */
 	.panel_height = 600,	/* Height */
 
@@ -176,13 +121,6 @@ void lcd_attach( device_t parent, device
 
 	sc->dev = self;
 
-#if defined(IMXIPUCONSOLE)
-	netwalker_lcd_console = 1;
-#endif
-#if (NWSDISPLAY > 0)
-	netwalker_cnattach();
-#endif
-
 	/* XXX move this to imx51_ipuv3.c */
 	{
 		bus_space_handle_t mipi_ioh;
@@ -220,7 +158,7 @@ void lcd_attach( device_t parent, device
 	struct imx51_ipuv3_screen *screen;
 	int error;
 
-	error = imx51_ipuv3_new_screen(sc, 16, &screen);
+	error = imx51_ipuv3_new_screen(sc, &screen);
 #ifdef LCD_DEBUG
 	draw_test_pattern(sc, screen);
 #endif
@@ -228,66 +166,10 @@ void lcd_attach( device_t parent, device
 		sc->active = screen;
 		imx51_ipuv3_start_dma(sc, screen);
 	}
-#else
-	struct wsemuldisplaydev_attach_args aa;
-
-#if defined(IMXIPUCONSOLE)
-	aa.console = true;
-#else
-	aa.console = false;
-#endif
-	aa.scrdata = &netwalker_lcd_screen_list;
-	aa.accessops = &netwalker_lcd_accessops;
-	aa.accesscookie = &sc->vd;
-
-	(void) config_found(sc->dev, &aa, wsemuldisplaydevprint);
-#endif
-}
-
-#if NWSDISPLAY > 0
-void
-netwalker_cnattach(void)
-{
-	imx51_ipuv3_cnattach(netwalker_lcd_console, &netwalker_lcd_stdscreen,
-	    &netwalker_lcd_accessops, &sharp_panel);
-	return;
-}
-
-/*
- * wsdisplay accessops overrides
- */
-static int
-netwalker_lcd_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, struct lwp *l)
-{
-	int res = EINVAL;
-
-	switch (cmd) {
-#if NNETWALKER_BACKLIGHT > 0
-	case WSDISPLAYIO_GETPARAM:
-	case WSDISPLAYIO_SETPARAM:
-		res = netwalker_lcd_param_ioctl(cmd, (struct wsdisplay_param *)data);
-		break;
 #endif
-	}
-
-	if (res == EINVAL)
-		res = imx51_ipuv3_ioctl(v, vs, cmd, data, flag, l);
-	return res;
 }
 
-static int
-netwalker_lcd_show_screen(void *v, void *cookie, int waitok,
-    void (*cb_func)(void *, int, int), void *cb_arg)
-{
-	int error;
-
-	error = imx51_ipuv3_show_screen(v, cookie, waitok, cb_func, cb_arg);
-	if (error)
-		return (error);
-
-	return 0;
-}
-#else
+#if NWSDISPLAY == 0
 
 int
 lcdopen(dev_t dev, int oflags, int devtype, struct lwp *l)
@@ -363,6 +245,6 @@ draw_test_pattern(struct imx51_ipuv3_sof
 }
 #endif
 
-#endif /* NWSDISPLAY > 0 */
+#endif /* NWSDISPLAY == 0 */
 
 

Index: src/sys/arch/evbarm/netwalker/netwalker_machdep.c
diff -u src/sys/arch/evbarm/netwalker/netwalker_machdep.c:1.18 src/sys/arch/evbarm/netwalker/netwalker_machdep.c:1.19
--- src/sys/arch/evbarm/netwalker/netwalker_machdep.c:1.18	Thu May  7 04:13:47 2015
+++ src/sys/arch/evbarm/netwalker/netwalker_machdep.c	Mon Dec 21 04:26:29 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: netwalker_machdep.c,v 1.18 2015/05/07 04:13:47 hkenken Exp $	*/
+/*	$NetBSD: netwalker_machdep.c,v 1.19 2015/12/21 04:26:29 hkenken Exp $	*/
 
 /*
  * Copyright (c) 2002, 2003, 2005, 2010  Genetec Corporation.
@@ -102,7 +102,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: netwalker_machdep.c,v 1.18 2015/05/07 04:13:47 hkenken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: netwalker_machdep.c,v 1.19 2015/12/21 04:26:29 hkenken Exp $");
 
 #include "opt_evbarm_boardtype.h"
 #include "opt_arm_debug.h"
@@ -115,7 +115,6 @@ __KERNEL_RCSID(0, "$NetBSD: netwalker_ma
 #include "opt_imxuart.h"
 #include "opt_imx.h"
 #include "opt_imx51_ipuv3.h"
-#include "wsdisplay.h"
 #include "opt_machdep.h"
 
 #include <sys/param.h>
@@ -124,12 +123,17 @@ __KERNEL_RCSID(0, "$NetBSD: netwalker_ma
 #include <sys/termios.h>
 #include <sys/bus.h>
 
+#include "genfb.h"
+#include "netwalker_backlight.h"
+#include "netwalker_backlightvar.h"
+
 #include <machine/db_machdep.h>
 #ifdef KGDB
 #include <sys/kgdb.h>
 #endif
 
 #include <machine/bootconfig.h>
+#include <machine/autoconf.h>
 
 #include <arm/arm32/machdep.h>
 
@@ -153,7 +157,7 @@ __KERNEL_RCSID(0, "$NetBSD: netwalker_ma
 #define	KERNEL_TEXT_BASE	(KERNEL_BASE + 0x00100000)
 
 BootConfig bootconfig;		/* Boot config storage */
-static char bootargs[MAX_BOOT_STRING];
+static char bootargs[MAX_BOOT_STRING] = BOOT_ARGS;
 char *boot_args = NULL;
 
 extern char KERNEL_BASE_phys[];
@@ -178,6 +182,8 @@ void	kgdb_port_init(void);
 static void init_clocks(void);
 static void setup_ioports(void);
 
+static void netwalker_device_register(device_t, void *);
+
 #ifndef CONSPEED
 #define CONSPEED B115200	/* What RedBoot uses */
 #endif
@@ -274,7 +280,6 @@ initarm(void *arg)
 	char mi_bootargs[] = BOOT_ARGS;
 	parse_mi_bootargs(mi_bootargs);
 #endif
-	bootargs[0] = '\0';
 
 #if defined(VERBOSE_INIT_ARM) || 1
 	printf("initarm: Configuring system");
@@ -337,6 +342,13 @@ initarm(void *arg)
 	boothowto |= BOOTHOWTO;
 #endif
 
+	boot_args = bootargs;
+	parse_mi_bootargs(boot_args);
+	printf("boot_args : %s\n", boot_args);
+
+	/* we've a specific device_register routine */
+	evbarm_device_register = netwalker_device_register;
+
 #ifdef VERBOSE_INIT_ARM
 	printf("initarm done.\n");
 #endif
@@ -672,19 +684,32 @@ consinit(void)
 		consaddr = IMX51_UART1_BASE;
 #endif
 		imxuart_cons_attach(&armv7_generic_bs_tag, consaddr, consrate, consmode);
-	    return;
+		return;
 	}
 #endif
-
 #endif
+}
+
+static void
+netwalker_device_register(device_t self, void *aux)
+{
+	prop_dictionary_t dict = device_properties(self);
 
-#if (NWSDISPLAY > 0) && defined(IMXIPUCONSOLE)
+#if NGENFB > 0
+	if (device_is_a(self, "genfb")) {
+		char *ptr;
+		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();
+			ukbd_cnattach();
+#endif
+		} else {
+			prop_dictionary_set_bool(dict, "is_console", false);
+		}
+#if NNETWALKER_BACKLIGHT > 0
+		netwalker_backlight_genfb_parameter_set(dict);
 #endif
-	{
-		extern void netwalker_cnattach(void);
-		netwalker_cnattach();
 	}
 #endif
 }

Added files:

Index: src/sys/arch/arm/imx/imx_genfb.c
diff -u /dev/null src/sys/arch/arm/imx/imx_genfb.c:1.1
--- /dev/null	Mon Dec 21 04:26:29 2015
+++ src/sys/arch/arm/imx/imx_genfb.c	Mon Dec 21 04:26:28 2015
@@ -0,0 +1,197 @@
+/*	$NetBSD: imx_genfb.c,v 1.1 2015/12/21 04:26:28 hkenken Exp $	*/
+
+/*
+ * Copyright (c) 2015 Genetec Corporation.  All rights reserved.
+ * Written by Hashimoto Kenichi for Genetec Corporation.
+ *
+ * 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 GENETEC CORPORATION ``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 GENETEC CORPORATION
+ * 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>
+__KERNEL_RCSID(0, "$NetBSD: imx_genfb.c,v 1.1 2015/12/21 04:26:28 hkenken Exp $");
+
+#include "opt_ddb.h"
+#include "opt_genfb.h"
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/device.h>
+#include <sys/intr.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+
+#include <arm/imx/imx51reg.h>
+#include <arm/imx/imx51var.h>
+#include <arm/imx/imx51_ipuv3var.h>
+
+#if defined(DDB)
+#include <machine/db_machdep.h>
+#include <ddb/db_extern.h>
+#endif
+
+#include <dev/videomode/videomode.h>
+#include <dev/wsfb/genfbvar.h>
+
+struct imx_genfb_softc {
+	struct genfb_softc sc_gen;
+
+	bus_dma_tag_t sc_dmat;
+	bus_dma_segment_t *sc_dmasegs;
+	int sc_ndmasegs;
+};
+
+#if defined(DDB)
+static void	imx_genfb_ddb_trap_callback(int);
+static device_t	imx_genfb_consoledev = NULL;
+#endif
+
+static int	imx_genfb_match(device_t, cfdata_t, void *);
+static void	imx_genfb_attach(device_t, device_t, void *);
+
+static int	imx_genfb_ioctl(void *, void *, u_long, void *, int, lwp_t *);
+static paddr_t	imx_genfb_mmap(void *, void *, off_t, int);
+static bool	imx_genfb_shutdown(device_t, int);
+
+CFATTACH_DECL_NEW(imx_genfb, sizeof(struct imx_genfb_softc),
+	imx_genfb_match, imx_genfb_attach, NULL, NULL);
+
+static int
+imx_genfb_match(device_t parent, cfdata_t cf, void *aux)
+{
+	return 1;
+}
+
+static void
+imx_genfb_attach(device_t parent, device_t self, void *aux)
+{
+	struct imx_genfb_softc *sc = device_private(self);
+	struct imxfb_attach_args * const ifb = aux;
+	prop_dictionary_t cfg = device_properties(self);
+	struct genfb_ops ops;
+
+	sc->sc_gen.sc_dev = self;
+	sc->sc_dmat = ifb->ifb_dmat;
+	sc->sc_dmasegs = ifb->ifb_dmasegs;
+	sc->sc_ndmasegs = ifb->ifb_ndmasegs;
+
+	prop_dictionary_set_uint32(cfg, "width", ifb->ifb_width);
+	prop_dictionary_set_uint32(cfg, "height", ifb->ifb_height);
+	prop_dictionary_set_uint8(cfg, "depth", ifb->ifb_depth);
+	prop_dictionary_set_uint16(cfg, "linebytes", ifb->ifb_stride);
+	prop_dictionary_set_uint32(cfg, "address", 0);
+	prop_dictionary_set_uint32(cfg, "virtual_address",
+	    (uintptr_t)ifb->ifb_fb);
+
+	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, imx_genfb_shutdown);
+
+	memset(&ops, 0, sizeof(ops));
+	ops.genfb_ioctl = imx_genfb_ioctl;
+	ops.genfb_mmap = imx_genfb_mmap;
+
+	aprint_naive("\n");
+
+	bool is_console = false;
+	prop_dictionary_get_bool(cfg, "is_console", &is_console);
+
+	if (is_console)
+		aprint_normal(": switching to framebuffer console\n");
+	else
+		aprint_normal("\n");
+
+	genfb_attach(&sc->sc_gen, &ops);
+
+#if defined(DDB)
+	if (is_console) {
+		imx_genfb_consoledev = self;
+		db_trap_callback = imx_genfb_ddb_trap_callback;
+	}
+#endif
+}
+
+static int
+imx_genfb_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, lwp_t *l)
+{
+	struct wsdisplayio_bus_id *busid;
+
+	switch (cmd) {
+	case WSDISPLAYIO_GTYPE:
+		*(u_int *)data = WSDISPLAY_TYPE_IMXIPU;
+		return 0;
+	case WSDISPLAYIO_GET_BUSID:
+		busid = data;
+		busid->bus_type = WSDISPLAYIO_BUS_SOC;
+		return 0;
+	default:
+		return EPASSTHROUGH;
+	}
+}
+
+static paddr_t
+imx_genfb_mmap(void *v, void *vs, off_t offset, int prot)
+{
+	struct imx_genfb_softc *sc = v;
+
+	KASSERT(offset >= 0);
+	KASSERT(offset < sc->sc_dmasegs[0].ds_len);
+
+	return bus_dmamem_mmap(sc->sc_dmat, sc->sc_dmasegs, sc->sc_ndmasegs,
+	    offset, prot, BUS_DMA_PREFETCHABLE);
+}
+
+static bool
+imx_genfb_shutdown(device_t self, int flags)
+{
+	genfb_enable_polling(self);
+	return true;
+}
+
+#if defined(DDB)
+static void
+imx_genfb_ddb_trap_callback(int where)
+{
+	if (imx_genfb_consoledev == NULL)
+		return;
+
+	if (where)
+		genfb_enable_polling(imx_genfb_consoledev);
+	else
+		genfb_disable_polling(imx_genfb_consoledev);
+}
+#endif
+
+void
+imx_genfb_set_videomode(device_t dev, u_int width, u_int height)
+{
+	struct imx_genfb_softc *sc = device_private(dev);
+
+	if (sc->sc_gen.sc_width != width || sc->sc_gen.sc_height != height) {
+		device_printf(sc->sc_gen.sc_dev,
+		    "mode switching not yet supported\n");
+	}
+}

Reply via email to