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"); + } +}