1 /* $OpenBSD: exdisplay.c,v 1.2 2015/05/27 00:06:14 jsg Exp $ */ 2 /* 3 * Copyright (c) 2013 Patrick Wildt <patrick@blueri.se> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include "fdt.h" 19 20 #include <sys/param.h> 21 #include <sys/systm.h> 22 #include <sys/queue.h> 23 #include <sys/malloc.h> 24 #include <sys/device.h> 25 #include <sys/evcount.h> 26 #include <sys/socket.h> 27 #include <sys/timeout.h> 28 29 #include <dev/cons.h> 30 #include <dev/wscons/wsconsio.h> 31 #include <dev/wscons/wsdisplayvar.h> 32 #include <dev/wscons/wscons_callbacks.h> 33 #include <dev/wsfont/wsfont.h> 34 #include <dev/rasops/rasops.h> 35 36 #include <machine/intr.h> 37 #include <machine/bus.h> 38 #if NFDT > 0 39 #include <machine/fdt.h> 40 #endif 41 #include <armv7/armv7/armv7var.h> 42 43 /* registers */ 44 45 struct exdisplay_softc { 46 struct device sc_dev; 47 bus_space_tag_t sc_iot; 48 bus_space_handle_t sc_ioh; 49 struct rasops_info *ro; 50 }; 51 52 int exdisplay_match(struct device *parent, void *v, void *aux); 53 void exdisplay_attach(struct device *parent, struct device *self, void *args); 54 int exdisplay_cnattach(bus_space_tag_t iot, bus_addr_t iobase, size_t size); 55 void exdisplay_setup_rasops(struct rasops_info *rinfo, struct wsscreen_descr *descr); 56 57 struct cfattach exdisplay_ca = { 58 sizeof (struct exdisplay_softc), NULL, exdisplay_attach 59 }; 60 struct cfattach exdisplay_fdt_ca = { 61 sizeof (struct exdisplay_softc), exdisplay_match, exdisplay_attach 62 }; 63 64 struct cfdriver exdisplay_cd = { 65 NULL, "exdisplay", DV_DULL 66 }; 67 68 int exdisplay_wsioctl(void *, u_long, caddr_t, int, struct proc *); 69 paddr_t exdisplay_wsmmap(void *, off_t, int); 70 int exdisplay_alloc_screen(void *, const struct wsscreen_descr *, 71 void **, int *, int *, long *); 72 void exdisplay_free_screen(void *, void *); 73 int exdisplay_show_screen(void *, void *, int, 74 void (*)(void *, int, int), void *); 75 void exdisplay_doswitch(void *, void *); 76 int exdisplay_load_font(void *, void *, struct wsdisplay_font *); 77 int exdisplay_list_font(void *, struct wsdisplay_font *); 78 int exdisplay_getchar(void *, int, int, struct wsdisplay_charcell *); 79 void exdisplay_burner(void *, u_int, u_int); 80 81 struct rasops_info exdisplay_ri; 82 struct wsscreen_descr exdisplay_stdscreen = { 83 "std" 84 }; 85 86 const struct wsscreen_descr *exdisplay_scrlist[] = { 87 &exdisplay_stdscreen, 88 }; 89 90 struct wsscreen_list exdisplay_screenlist = { 91 nitems(exdisplay_scrlist), exdisplay_scrlist 92 }; 93 94 struct wsdisplay_accessops exdisplay_accessops = { 95 .ioctl = exdisplay_wsioctl, 96 .mmap = exdisplay_wsmmap, 97 .alloc_screen = exdisplay_alloc_screen, 98 .free_screen = exdisplay_free_screen, 99 .show_screen = exdisplay_show_screen, 100 .getchar = exdisplay_getchar, 101 .load_font = exdisplay_load_font, 102 .list_font = exdisplay_list_font, 103 .burn_screen = exdisplay_burner 104 }; 105 106 int 107 exdisplay_match(struct device *parent, void *v, void *aux) 108 { 109 #if NFDT > 0 110 struct armv7_attach_args *aa = aux; 111 112 if (fdt_node_compatible("samsung,exynos5250-fimd", aa->aa_node)) 113 return 1; 114 #endif 115 116 return 0; 117 } 118 119 void 120 exdisplay_attach(struct device *parent, struct device *self, void *args) 121 { 122 struct armv7_attach_args *aa = args; 123 struct exdisplay_softc *sc = (struct exdisplay_softc *) self; 124 struct wsemuldisplaydev_attach_args waa; 125 struct rasops_info *ri = &exdisplay_ri; 126 struct armv7mem mem; 127 128 sc->sc_iot = aa->aa_iot; 129 #if NFDT > 0 130 if (aa->aa_node) { 131 struct fdt_memory fdtmem; 132 if (fdt_get_memory_address(aa->aa_node, 0, &fdtmem)) 133 panic("%s: could not extract memory data from FDT", 134 __func__); 135 mem.addr = fdtmem.addr; 136 mem.size = fdtmem.size; 137 } else 138 #endif 139 { 140 mem.addr = aa->aa_dev->mem[0].addr; 141 mem.size = aa->aa_dev->mem[0].size; 142 } 143 144 if (bus_space_map(sc->sc_iot, mem.addr, mem.size, 0, &sc->sc_ioh)) 145 panic("%s: bus_space_map failed!", __func__); 146 147 printf("\n"); 148 149 #if notyet 150 /* FIXME: Set up framebuffer instead of re-using. */ 151 if (!fdt_find_compatible("simple-framebuffer")) { 152 long defattr; 153 154 ri->ri_bits = (u_char *)sc->sc_fbioh; 155 exdisplay_setup_rasops(ri, &exdisplay_stdscreen); 156 157 ri->ri_ops.alloc_attr(ri->ri_active, 0, 0, 0, &defattr); 158 wsdisplay_cnattach(&exdisplay_stdscreen, ri->ri_active, 159 0, 0, defattr); 160 } 161 #endif 162 163 sc->ro = ri; 164 165 waa.console = 1; 166 waa.scrdata = &exdisplay_screenlist; 167 waa.accessops = &exdisplay_accessops; 168 waa.accesscookie = sc; 169 waa.defaultscreens = 0; 170 171 printf("%s: %dx%d\n", sc->sc_dev.dv_xname, ri->ri_width, ri->ri_height); 172 173 config_found(self, &waa, wsemuldisplaydevprint); 174 } 175 176 int 177 exdisplay_cnattach(bus_space_tag_t iot, bus_addr_t iobase, size_t size) 178 { 179 struct wsscreen_descr *descr = &exdisplay_stdscreen; 180 struct rasops_info *ri = &exdisplay_ri; 181 long defattr; 182 183 if (bus_space_map(iot, iobase, size, 0, (bus_space_handle_t *)&ri->ri_bits)) 184 return ENOMEM; 185 186 exdisplay_setup_rasops(ri, descr); 187 188 /* assumes 16 bpp */ 189 ri->ri_ops.alloc_attr(ri, 0, 0, 0, &defattr); 190 191 wsdisplay_cnattach(descr, ri, ri->ri_ccol, ri->ri_crow, defattr); 192 193 return 0; 194 } 195 196 void 197 exdisplay_setup_rasops(struct rasops_info *rinfo, struct wsscreen_descr *descr) 198 { 199 rinfo->ri_flg = RI_CLEAR; 200 rinfo->ri_depth = 16; 201 rinfo->ri_width = 1366; 202 rinfo->ri_height = 768; 203 rinfo->ri_stride = rinfo->ri_width * rinfo->ri_depth / 8; 204 205 /* swap B and R */ 206 if (rinfo->ri_depth == 16) { 207 rinfo->ri_rnum = 5; 208 rinfo->ri_rpos = 11; 209 rinfo->ri_gnum = 6; 210 rinfo->ri_gpos = 5; 211 rinfo->ri_bnum = 5; 212 rinfo->ri_bpos = 0; 213 } 214 215 wsfont_init(); 216 rinfo->ri_wsfcookie = wsfont_find(NULL, 8, 0, 0); 217 wsfont_lock(rinfo->ri_wsfcookie, &rinfo->ri_font, 218 WSDISPLAY_FONTORDER_L2R, WSDISPLAY_FONTORDER_L2R); 219 220 /* get rasops to compute screen size the first time */ 221 rasops_init(rinfo, 200, 200); 222 223 descr->nrows = rinfo->ri_rows; 224 descr->ncols = rinfo->ri_cols; 225 descr->capabilities = rinfo->ri_caps; 226 descr->textops = &rinfo->ri_ops; 227 } 228 229 int 230 exdisplay_wsioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p) 231 { 232 return (-1); 233 } 234 235 paddr_t 236 exdisplay_wsmmap(void *v, off_t off, int prot) 237 { 238 return (-1); 239 } 240 241 int 242 exdisplay_alloc_screen(void *v, const struct wsscreen_descr *type, 243 void **cookiep, int *curxp, int *curyp, long *attrp) 244 { 245 struct exdisplay_softc *sc = v; 246 struct rasops_info *ri = sc->ro; 247 248 return rasops_alloc_screen(ri, cookiep, curxp, curyp, attrp); 249 } 250 251 void 252 exdisplay_free_screen(void *v, void *cookie) 253 { 254 struct exdisplay_softc *sc = v; 255 struct rasops_info *ri = sc->ro; 256 257 return rasops_free_screen(ri, cookie); 258 } 259 260 int 261 exdisplay_show_screen(void *v, void *cookie, int waitok, 262 void (*cb)(void *, int, int), void *cbarg) 263 { 264 return (0); 265 } 266 267 void 268 exdisplay_doswitch(void *v, void *dummy) 269 { 270 } 271 272 int 273 exdisplay_getchar(void *v, int row, int col, struct wsdisplay_charcell *cell) 274 { 275 struct exdisplay_softc *sc = v; 276 struct rasops_info *ri = sc->ro; 277 278 return rasops_getchar(ri, row, col, cell); 279 } 280 281 int 282 exdisplay_load_font(void *v, void *cookie, struct wsdisplay_font *font) 283 { 284 struct exdisplay_softc *sc = v; 285 struct rasops_info *ri = sc->ro; 286 287 return rasops_load_font(ri, cookie, font); 288 } 289 290 int 291 exdisplay_list_font(void *v, struct wsdisplay_font *font) 292 { 293 struct exdisplay_softc *sc = v; 294 struct rasops_info *ri = sc->ro; 295 296 return rasops_list_font(ri, font); 297 } 298 299 void 300 exdisplay_burner(void *v, u_int on, u_int flags) 301 { 302 } 303