1 1.1 hkenken /* $NetBSD: imx_genfb.c,v 1.1 2015/12/21 04:26:28 hkenken Exp $ */ 2 1.1 hkenken 3 1.1 hkenken /* 4 1.1 hkenken * Copyright (c) 2015 Genetec Corporation. All rights reserved. 5 1.1 hkenken * Written by Hashimoto Kenichi for Genetec Corporation. 6 1.1 hkenken * 7 1.1 hkenken * Redistribution and use in source and binary forms, with or without 8 1.1 hkenken * modification, are permitted provided that the following conditions 9 1.1 hkenken * are met: 10 1.1 hkenken * 1. Redistributions of source code must retain the above copyright 11 1.1 hkenken * notice, this list of conditions and the following disclaimer. 12 1.1 hkenken * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 hkenken * notice, this list of conditions and the following disclaimer in the 14 1.1 hkenken * documentation and/or other materials provided with the distribution. 15 1.1 hkenken * 16 1.1 hkenken * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND 17 1.1 hkenken * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 1.1 hkenken * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 1.1 hkenken * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENETEC CORPORATION 20 1.1 hkenken * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 1.1 hkenken * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 1.1 hkenken * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 1.1 hkenken * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 1.1 hkenken * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 1.1 hkenken * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 1.1 hkenken * POSSIBILITY OF SUCH DAMAGE. 27 1.1 hkenken */ 28 1.1 hkenken 29 1.1 hkenken #include <sys/cdefs.h> 30 1.1 hkenken __KERNEL_RCSID(0, "$NetBSD: imx_genfb.c,v 1.1 2015/12/21 04:26:28 hkenken Exp $"); 31 1.1 hkenken 32 1.1 hkenken #include "opt_ddb.h" 33 1.1 hkenken #include "opt_genfb.h" 34 1.1 hkenken 35 1.1 hkenken #include <sys/param.h> 36 1.1 hkenken #include <sys/bus.h> 37 1.1 hkenken #include <sys/device.h> 38 1.1 hkenken #include <sys/intr.h> 39 1.1 hkenken #include <sys/systm.h> 40 1.1 hkenken #include <sys/kernel.h> 41 1.1 hkenken 42 1.1 hkenken #include <arm/imx/imx51reg.h> 43 1.1 hkenken #include <arm/imx/imx51var.h> 44 1.1 hkenken #include <arm/imx/imx51_ipuv3var.h> 45 1.1 hkenken 46 1.1 hkenken #if defined(DDB) 47 1.1 hkenken #include <machine/db_machdep.h> 48 1.1 hkenken #include <ddb/db_extern.h> 49 1.1 hkenken #endif 50 1.1 hkenken 51 1.1 hkenken #include <dev/videomode/videomode.h> 52 1.1 hkenken #include <dev/wsfb/genfbvar.h> 53 1.1 hkenken 54 1.1 hkenken struct imx_genfb_softc { 55 1.1 hkenken struct genfb_softc sc_gen; 56 1.1 hkenken 57 1.1 hkenken bus_dma_tag_t sc_dmat; 58 1.1 hkenken bus_dma_segment_t *sc_dmasegs; 59 1.1 hkenken int sc_ndmasegs; 60 1.1 hkenken }; 61 1.1 hkenken 62 1.1 hkenken #if defined(DDB) 63 1.1 hkenken static void imx_genfb_ddb_trap_callback(int); 64 1.1 hkenken static device_t imx_genfb_consoledev = NULL; 65 1.1 hkenken #endif 66 1.1 hkenken 67 1.1 hkenken static int imx_genfb_match(device_t, cfdata_t, void *); 68 1.1 hkenken static void imx_genfb_attach(device_t, device_t, void *); 69 1.1 hkenken 70 1.1 hkenken static int imx_genfb_ioctl(void *, void *, u_long, void *, int, lwp_t *); 71 1.1 hkenken static paddr_t imx_genfb_mmap(void *, void *, off_t, int); 72 1.1 hkenken static bool imx_genfb_shutdown(device_t, int); 73 1.1 hkenken 74 1.1 hkenken CFATTACH_DECL_NEW(imx_genfb, sizeof(struct imx_genfb_softc), 75 1.1 hkenken imx_genfb_match, imx_genfb_attach, NULL, NULL); 76 1.1 hkenken 77 1.1 hkenken static int 78 1.1 hkenken imx_genfb_match(device_t parent, cfdata_t cf, void *aux) 79 1.1 hkenken { 80 1.1 hkenken return 1; 81 1.1 hkenken } 82 1.1 hkenken 83 1.1 hkenken static void 84 1.1 hkenken imx_genfb_attach(device_t parent, device_t self, void *aux) 85 1.1 hkenken { 86 1.1 hkenken struct imx_genfb_softc *sc = device_private(self); 87 1.1 hkenken struct imxfb_attach_args * const ifb = aux; 88 1.1 hkenken prop_dictionary_t cfg = device_properties(self); 89 1.1 hkenken struct genfb_ops ops; 90 1.1 hkenken 91 1.1 hkenken sc->sc_gen.sc_dev = self; 92 1.1 hkenken sc->sc_dmat = ifb->ifb_dmat; 93 1.1 hkenken sc->sc_dmasegs = ifb->ifb_dmasegs; 94 1.1 hkenken sc->sc_ndmasegs = ifb->ifb_ndmasegs; 95 1.1 hkenken 96 1.1 hkenken prop_dictionary_set_uint32(cfg, "width", ifb->ifb_width); 97 1.1 hkenken prop_dictionary_set_uint32(cfg, "height", ifb->ifb_height); 98 1.1 hkenken prop_dictionary_set_uint8(cfg, "depth", ifb->ifb_depth); 99 1.1 hkenken prop_dictionary_set_uint16(cfg, "linebytes", ifb->ifb_stride); 100 1.1 hkenken prop_dictionary_set_uint32(cfg, "address", 0); 101 1.1 hkenken prop_dictionary_set_uint32(cfg, "virtual_address", 102 1.1 hkenken (uintptr_t)ifb->ifb_fb); 103 1.1 hkenken 104 1.1 hkenken genfb_init(&sc->sc_gen); 105 1.1 hkenken 106 1.1 hkenken if (sc->sc_gen.sc_width == 0 || sc->sc_gen.sc_fbsize == 0) { 107 1.1 hkenken aprint_normal(": disabled\n"); 108 1.1 hkenken return; 109 1.1 hkenken } 110 1.1 hkenken 111 1.1 hkenken pmf_device_register1(self, NULL, NULL, imx_genfb_shutdown); 112 1.1 hkenken 113 1.1 hkenken memset(&ops, 0, sizeof(ops)); 114 1.1 hkenken ops.genfb_ioctl = imx_genfb_ioctl; 115 1.1 hkenken ops.genfb_mmap = imx_genfb_mmap; 116 1.1 hkenken 117 1.1 hkenken aprint_naive("\n"); 118 1.1 hkenken 119 1.1 hkenken bool is_console = false; 120 1.1 hkenken prop_dictionary_get_bool(cfg, "is_console", &is_console); 121 1.1 hkenken 122 1.1 hkenken if (is_console) 123 1.1 hkenken aprint_normal(": switching to framebuffer console\n"); 124 1.1 hkenken else 125 1.1 hkenken aprint_normal("\n"); 126 1.1 hkenken 127 1.1 hkenken genfb_attach(&sc->sc_gen, &ops); 128 1.1 hkenken 129 1.1 hkenken #if defined(DDB) 130 1.1 hkenken if (is_console) { 131 1.1 hkenken imx_genfb_consoledev = self; 132 1.1 hkenken db_trap_callback = imx_genfb_ddb_trap_callback; 133 1.1 hkenken } 134 1.1 hkenken #endif 135 1.1 hkenken } 136 1.1 hkenken 137 1.1 hkenken static int 138 1.1 hkenken imx_genfb_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, lwp_t *l) 139 1.1 hkenken { 140 1.1 hkenken struct wsdisplayio_bus_id *busid; 141 1.1 hkenken 142 1.1 hkenken switch (cmd) { 143 1.1 hkenken case WSDISPLAYIO_GTYPE: 144 1.1 hkenken *(u_int *)data = WSDISPLAY_TYPE_IMXIPU; 145 1.1 hkenken return 0; 146 1.1 hkenken case WSDISPLAYIO_GET_BUSID: 147 1.1 hkenken busid = data; 148 1.1 hkenken busid->bus_type = WSDISPLAYIO_BUS_SOC; 149 1.1 hkenken return 0; 150 1.1 hkenken default: 151 1.1 hkenken return EPASSTHROUGH; 152 1.1 hkenken } 153 1.1 hkenken } 154 1.1 hkenken 155 1.1 hkenken static paddr_t 156 1.1 hkenken imx_genfb_mmap(void *v, void *vs, off_t offset, int prot) 157 1.1 hkenken { 158 1.1 hkenken struct imx_genfb_softc *sc = v; 159 1.1 hkenken 160 1.1 hkenken KASSERT(offset >= 0); 161 1.1 hkenken KASSERT(offset < sc->sc_dmasegs[0].ds_len); 162 1.1 hkenken 163 1.1 hkenken return bus_dmamem_mmap(sc->sc_dmat, sc->sc_dmasegs, sc->sc_ndmasegs, 164 1.1 hkenken offset, prot, BUS_DMA_PREFETCHABLE); 165 1.1 hkenken } 166 1.1 hkenken 167 1.1 hkenken static bool 168 1.1 hkenken imx_genfb_shutdown(device_t self, int flags) 169 1.1 hkenken { 170 1.1 hkenken genfb_enable_polling(self); 171 1.1 hkenken return true; 172 1.1 hkenken } 173 1.1 hkenken 174 1.1 hkenken #if defined(DDB) 175 1.1 hkenken static void 176 1.1 hkenken imx_genfb_ddb_trap_callback(int where) 177 1.1 hkenken { 178 1.1 hkenken if (imx_genfb_consoledev == NULL) 179 1.1 hkenken return; 180 1.1 hkenken 181 1.1 hkenken if (where) 182 1.1 hkenken genfb_enable_polling(imx_genfb_consoledev); 183 1.1 hkenken else 184 1.1 hkenken genfb_disable_polling(imx_genfb_consoledev); 185 1.1 hkenken } 186 1.1 hkenken #endif 187 1.1 hkenken 188 1.1 hkenken void 189 1.1 hkenken imx_genfb_set_videomode(device_t dev, u_int width, u_int height) 190 1.1 hkenken { 191 1.1 hkenken struct imx_genfb_softc *sc = device_private(dev); 192 1.1 hkenken 193 1.1 hkenken if (sc->sc_gen.sc_width != width || sc->sc_gen.sc_height != height) { 194 1.1 hkenken device_printf(sc->sc_gen.sc_dev, 195 1.1 hkenken "mode switching not yet supported\n"); 196 1.1 hkenken } 197 1.1 hkenken } 198