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