1 1.24 macallan /* $NetBSD: mgx.c,v 1.24 2023/07/19 10:22:15 macallan Exp $ */ 2 1.1 macallan 3 1.1 macallan /*- 4 1.1 macallan * Copyright (c) 2014 Michael Lorenz 5 1.1 macallan * All rights reserved. 6 1.1 macallan * 7 1.1 macallan * Redistribution and use in source and binary forms, with or without 8 1.1 macallan * modification, are permitted provided that the following conditions 9 1.1 macallan * are met: 10 1.1 macallan * 1. Redistributions of source code must retain the above copyright 11 1.1 macallan * notice, this list of conditions and the following disclaimer. 12 1.1 macallan * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 macallan * notice, this list of conditions and the following disclaimer in the 14 1.1 macallan * documentation and/or other materials provided with the distribution. 15 1.1 macallan * 16 1.1 macallan * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 17 1.1 macallan * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 1.1 macallan * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 1.1 macallan * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 20 1.1 macallan * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 1.1 macallan * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 1.1 macallan * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 1.1 macallan * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 1.1 macallan * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 1.1 macallan * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 1.1 macallan * POSSIBILITY OF SUCH DAMAGE. 27 1.1 macallan */ 28 1.1 macallan 29 1.1 macallan /* a console driver for the SSB 4096V-MGX graphics card */ 30 1.1 macallan 31 1.1 macallan #include <sys/cdefs.h> 32 1.24 macallan __KERNEL_RCSID(0, "$NetBSD: mgx.c,v 1.24 2023/07/19 10:22:15 macallan Exp $"); 33 1.1 macallan 34 1.1 macallan #include <sys/param.h> 35 1.1 macallan #include <sys/systm.h> 36 1.1 macallan #include <sys/buf.h> 37 1.1 macallan #include <sys/device.h> 38 1.1 macallan #include <sys/ioctl.h> 39 1.1 macallan #include <sys/conf.h> 40 1.1 macallan #include <sys/kmem.h> 41 1.8 macallan #include <sys/kauth.h> 42 1.10 macallan #include <sys/atomic.h> 43 1.1 macallan 44 1.1 macallan #include <sys/bus.h> 45 1.1 macallan #include <machine/autoconf.h> 46 1.1 macallan 47 1.1 macallan #include <dev/sbus/sbusvar.h> 48 1.1 macallan #include <dev/sun/fbio.h> 49 1.1 macallan #include <dev/sun/fbvar.h> 50 1.1 macallan 51 1.1 macallan #include <dev/wscons/wsdisplayvar.h> 52 1.1 macallan #include <dev/wscons/wsconsio.h> 53 1.1 macallan #include <dev/wsfont/wsfont.h> 54 1.1 macallan #include <dev/rasops/rasops.h> 55 1.1 macallan 56 1.1 macallan #include <dev/wscons/wsdisplay_vconsvar.h> 57 1.2 macallan #include <dev/wscons/wsdisplay_glyphcachevar.h> 58 1.1 macallan 59 1.1 macallan #include <dev/ic/vgareg.h> 60 1.1 macallan #include <dev/sbus/mgxreg.h> 61 1.1 macallan 62 1.9 macallan #include "ioconf.h" 63 1.9 macallan 64 1.1 macallan #include "opt_wsemul.h" 65 1.5 macallan #include "opt_mgx.h" 66 1.1 macallan 67 1.1 macallan struct mgx_softc { 68 1.1 macallan device_t sc_dev; 69 1.9 macallan struct fbdevice sc_fb; /* frame buffer device */ 70 1.1 macallan bus_space_tag_t sc_tag; 71 1.1 macallan bus_space_handle_t sc_blith; 72 1.1 macallan bus_space_handle_t sc_vgah; 73 1.8 macallan bus_addr_t sc_paddr, sc_rpaddr; 74 1.1 macallan void *sc_fbaddr; 75 1.6 macallan uint8_t *sc_cursor; 76 1.1 macallan int sc_width; 77 1.1 macallan int sc_height; 78 1.1 macallan int sc_stride; 79 1.5 macallan int sc_depth; 80 1.1 macallan int sc_fbsize; 81 1.1 macallan int sc_mode; 82 1.5 macallan char sc_name[8]; 83 1.23 macallan uint32_t sc_dec, sc_r_dec, sc_r_fg; 84 1.1 macallan u_char sc_cmap_red[256]; 85 1.1 macallan u_char sc_cmap_green[256]; 86 1.1 macallan u_char sc_cmap_blue[256]; 87 1.6 macallan int sc_cursor_x, sc_cursor_y; 88 1.6 macallan int sc_hotspot_x, sc_hotspot_y; 89 1.10 macallan int sc_video, sc_buf; 90 1.2 macallan void (*sc_putchar)(void *, int, int, u_int, long); 91 1.1 macallan struct vcons_screen sc_console_screen; 92 1.1 macallan struct wsscreen_descr sc_defaultscreen_descr; 93 1.1 macallan const struct wsscreen_descr *sc_screens[1]; 94 1.1 macallan struct wsscreen_list sc_screenlist; 95 1.1 macallan struct vcons_data vd; 96 1.2 macallan glyphcache sc_gc; 97 1.12 macallan uint8_t sc_in[256]; 98 1.1 macallan }; 99 1.1 macallan 100 1.1 macallan static int mgx_match(device_t, cfdata_t, void *); 101 1.1 macallan static void mgx_attach(device_t, device_t, void *); 102 1.1 macallan static int mgx_ioctl(void *, void *, u_long, void *, int, 103 1.1 macallan struct lwp*); 104 1.1 macallan static paddr_t mgx_mmap(void *, void *, off_t, int); 105 1.1 macallan static void mgx_init_screen(void *, struct vcons_screen *, int, 106 1.1 macallan long *); 107 1.1 macallan static void mgx_write_dac(struct mgx_softc *, int, int, int, int); 108 1.1 macallan static void mgx_setup(struct mgx_softc *, int); 109 1.1 macallan static void mgx_init_palette(struct mgx_softc *); 110 1.4 macallan static int mgx_putcmap(struct mgx_softc *, struct wsdisplay_cmap *); 111 1.4 macallan static int mgx_getcmap(struct mgx_softc *, struct wsdisplay_cmap *); 112 1.2 macallan static int mgx_wait_engine(struct mgx_softc *); 113 1.7 joerg __unused static int mgx_wait_host(struct mgx_softc *); 114 1.12 macallan /*static*/ int mgx_wait_fifo(struct mgx_softc *, unsigned int); 115 1.2 macallan 116 1.2 macallan static void mgx_bitblt(void *, int, int, int, int, int, int, int); 117 1.2 macallan static void mgx_rectfill(void *, int, int, int, int, long); 118 1.2 macallan 119 1.10 macallan static void mgx_putchar_aa(void *, int, int, u_int, long); 120 1.10 macallan static void mgx_putchar_mono(void *, int, int, u_int, long); 121 1.2 macallan static void mgx_cursor(void *, int, int, int); 122 1.2 macallan static void mgx_copycols(void *, int, int, int, int); 123 1.2 macallan static void mgx_erasecols(void *, int, int, int, long); 124 1.2 macallan static void mgx_copyrows(void *, int, int, int); 125 1.2 macallan static void mgx_eraserows(void *, int, int, long); 126 1.12 macallan static void mgx_adapt(struct vcons_screen *, void *); 127 1.1 macallan 128 1.6 macallan static int mgx_do_cursor(struct mgx_softc *, struct wsdisplay_cursor *); 129 1.6 macallan static void mgx_set_cursor(struct mgx_softc *); 130 1.6 macallan static void mgx_set_video(struct mgx_softc *, int); 131 1.6 macallan 132 1.1 macallan CFATTACH_DECL_NEW(mgx, sizeof(struct mgx_softc), 133 1.1 macallan mgx_match, mgx_attach, NULL, NULL); 134 1.1 macallan 135 1.1 macallan struct wsdisplay_accessops mgx_accessops = { 136 1.1 macallan mgx_ioctl, 137 1.1 macallan mgx_mmap, 138 1.1 macallan NULL, /* vcons_alloc_screen */ 139 1.1 macallan NULL, /* vcons_free_screen */ 140 1.1 macallan NULL, /* vcons_show_screen */ 141 1.1 macallan NULL, /* load_font */ 142 1.1 macallan NULL, /* polls */ 143 1.1 macallan NULL, /* scroll */ 144 1.1 macallan }; 145 1.1 macallan 146 1.9 macallan static void mgx_unblank(device_t); 147 1.9 macallan 148 1.9 macallan dev_type_open(mgxopen); 149 1.9 macallan dev_type_close(mgxclose); 150 1.9 macallan dev_type_ioctl(mgxioctl); 151 1.9 macallan dev_type_mmap(mgxmmap); 152 1.9 macallan 153 1.9 macallan const struct cdevsw mgx_cdevsw = { 154 1.9 macallan .d_open = mgxopen, 155 1.9 macallan .d_close = mgxclose, 156 1.9 macallan .d_read = noread, 157 1.9 macallan .d_write = nowrite, 158 1.9 macallan .d_ioctl = mgxioctl, 159 1.9 macallan .d_stop = nostop, 160 1.9 macallan .d_tty = notty, 161 1.9 macallan .d_poll = nopoll, 162 1.9 macallan .d_mmap = mgxmmap, 163 1.9 macallan .d_kqfilter = nokqfilter, 164 1.9 macallan .d_discard = nodiscard, 165 1.9 macallan .d_flag = D_OTHER 166 1.9 macallan }; 167 1.9 macallan 168 1.9 macallan /* frame buffer generic driver */ 169 1.9 macallan static struct fbdriver mgx_fbdriver = { 170 1.9 macallan mgx_unblank, mgxopen, mgxclose, mgxioctl, nopoll, mgxmmap, 171 1.9 macallan nokqfilter 172 1.9 macallan }; 173 1.9 macallan 174 1.9 macallan 175 1.5 macallan static inline void 176 1.5 macallan mgx_write_vga(struct mgx_softc *sc, uint32_t reg, uint8_t val) 177 1.5 macallan { 178 1.5 macallan bus_space_write_1(sc->sc_tag, sc->sc_vgah, reg ^ 3, val); 179 1.5 macallan } 180 1.5 macallan 181 1.5 macallan static inline uint8_t 182 1.5 macallan mgx_read_vga(struct mgx_softc *sc, uint32_t reg) 183 1.5 macallan { 184 1.5 macallan return bus_space_read_1(sc->sc_tag, sc->sc_vgah, reg ^ 3); 185 1.5 macallan } 186 1.5 macallan 187 1.5 macallan static inline void 188 1.5 macallan mgx_write_1(struct mgx_softc *sc, uint32_t reg, uint8_t val) 189 1.5 macallan { 190 1.5 macallan bus_space_write_1(sc->sc_tag, sc->sc_blith, reg ^ 3, val); 191 1.5 macallan } 192 1.5 macallan 193 1.5 macallan static inline uint8_t 194 1.5 macallan mgx_read_1(struct mgx_softc *sc, uint32_t reg) 195 1.5 macallan { 196 1.5 macallan return bus_space_read_1(sc->sc_tag, sc->sc_blith, reg ^ 3); 197 1.5 macallan } 198 1.5 macallan 199 1.8 macallan #if 0 200 1.8 macallan static inline uint32_t 201 1.8 macallan mgx_read_4(struct mgx_softc *sc, uint32_t reg) 202 1.8 macallan { 203 1.8 macallan return bus_space_read_4(sc->sc_tag, sc->sc_blith, reg); 204 1.8 macallan } 205 1.8 macallan #endif 206 1.8 macallan 207 1.5 macallan static inline void 208 1.6 macallan mgx_write_2(struct mgx_softc *sc, uint32_t reg, uint16_t val) 209 1.6 macallan { 210 1.6 macallan bus_space_write_2(sc->sc_tag, sc->sc_blith, reg ^ 2, val); 211 1.6 macallan } 212 1.6 macallan 213 1.6 macallan static inline void 214 1.5 macallan mgx_write_4(struct mgx_softc *sc, uint32_t reg, uint32_t val) 215 1.5 macallan { 216 1.5 macallan bus_space_write_4(sc->sc_tag, sc->sc_blith, reg, val); 217 1.5 macallan } 218 1.5 macallan 219 1.23 macallan static inline void 220 1.23 macallan mgx_set_dec(struct mgx_softc *sc, uint32_t dec) 221 1.23 macallan { 222 1.23 macallan if (dec == sc->sc_r_dec) return; 223 1.23 macallan sc->sc_r_dec = dec; 224 1.23 macallan mgx_wait_engine(sc); 225 1.23 macallan mgx_write_4(sc, ATR_DEC, dec); 226 1.23 macallan } 227 1.23 macallan 228 1.23 macallan static inline void 229 1.23 macallan mgx_set_fg(struct mgx_softc *sc, uint32_t fg) 230 1.23 macallan { 231 1.23 macallan if (fg == sc->sc_r_fg) return; 232 1.23 macallan sc->sc_r_fg = fg; 233 1.23 macallan mgx_wait_fifo(sc, 1); 234 1.23 macallan mgx_write_4(sc, ATR_FG, fg); 235 1.23 macallan } 236 1.23 macallan 237 1.1 macallan static int 238 1.1 macallan mgx_match(device_t parent, cfdata_t cf, void *aux) 239 1.1 macallan { 240 1.1 macallan struct sbus_attach_args *sa = aux; 241 1.1 macallan 242 1.1 macallan if (strcmp("SMSI,mgx", sa->sa_name) == 0) 243 1.1 macallan return 100; 244 1.1 macallan return 0; 245 1.1 macallan } 246 1.1 macallan 247 1.1 macallan /* 248 1.1 macallan * Attach a display. We need to notice if it is the console, too. 249 1.1 macallan */ 250 1.1 macallan static void 251 1.1 macallan mgx_attach(device_t parent, device_t self, void *args) 252 1.1 macallan { 253 1.1 macallan struct mgx_softc *sc = device_private(self); 254 1.1 macallan struct sbus_attach_args *sa = args; 255 1.1 macallan struct wsemuldisplaydev_attach_args aa; 256 1.9 macallan struct fbdevice *fb = &sc->sc_fb; 257 1.1 macallan struct rasops_info *ri; 258 1.1 macallan unsigned long defattr; 259 1.1 macallan bus_space_handle_t bh; 260 1.12 macallan int node = sa->sa_node, bsize; 261 1.1 macallan int isconsole; 262 1.1 macallan 263 1.1 macallan aprint_normal("\n"); 264 1.1 macallan sc->sc_dev = self; 265 1.1 macallan sc->sc_tag = sa->sa_bustag; 266 1.1 macallan 267 1.1 macallan sc->sc_paddr = sbus_bus_addr(sa->sa_bustag, sa->sa_slot, 268 1.1 macallan sa->sa_reg[8].oa_base); 269 1.8 macallan sc->sc_rpaddr = sbus_bus_addr(sa->sa_bustag, sa->sa_slot, 270 1.8 macallan sa->sa_reg[5].oa_base + MGX_REG_ATREG_OFFSET); 271 1.1 macallan 272 1.1 macallan /* read geometry information from the device tree */ 273 1.1 macallan sc->sc_width = prom_getpropint(sa->sa_node, "width", 1152); 274 1.1 macallan sc->sc_height = prom_getpropint(sa->sa_node, "height", 900); 275 1.5 macallan sc->sc_stride = prom_getpropint(sa->sa_node, "linebytes", 1152); 276 1.5 macallan sc->sc_fbsize = prom_getpropint(sa->sa_node, "fb_size", 0x00400000); 277 1.2 macallan sc->sc_fbaddr = NULL; 278 1.1 macallan if (sc->sc_fbaddr == NULL) { 279 1.1 macallan if (sbus_bus_map(sa->sa_bustag, 280 1.1 macallan sa->sa_slot, 281 1.1 macallan sa->sa_reg[8].oa_base, 282 1.1 macallan sc->sc_fbsize, 283 1.2 macallan BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_LARGE, 284 1.2 macallan &bh) != 0) { 285 1.5 macallan aprint_error_dev(self, "couldn't map framebuffer\n"); 286 1.1 macallan return; 287 1.1 macallan } 288 1.1 macallan sc->sc_fbaddr = bus_space_vaddr(sa->sa_bustag, bh); 289 1.1 macallan } 290 1.12 macallan 291 1.1 macallan if (sbus_bus_map(sa->sa_bustag, 292 1.1 macallan sa->sa_slot, 293 1.1 macallan sa->sa_reg[4].oa_base, 0x1000, 0, 294 1.1 macallan &sc->sc_vgah) != 0) { 295 1.1 macallan aprint_error("%s: couldn't map VGA registers\n", 296 1.1 macallan device_xname(sc->sc_dev)); 297 1.1 macallan return; 298 1.1 macallan } 299 1.1 macallan 300 1.1 macallan if (sbus_bus_map(sa->sa_bustag, 301 1.1 macallan sa->sa_slot, 302 1.2 macallan sa->sa_reg[5].oa_base + MGX_REG_ATREG_OFFSET, 0x1000, 303 1.2 macallan 0, &sc->sc_blith) != 0) { 304 1.1 macallan aprint_error("%s: couldn't map blitter registers\n", 305 1.1 macallan device_xname(sc->sc_dev)); 306 1.1 macallan return; 307 1.1 macallan } 308 1.1 macallan 309 1.5 macallan mgx_setup(sc, MGX_DEPTH); 310 1.5 macallan 311 1.5 macallan aprint_normal_dev(self, "[%s] %d MB framebuffer, %d x %d\n", 312 1.5 macallan sc->sc_name, sc->sc_fbsize >> 20, sc->sc_width, sc->sc_height); 313 1.5 macallan 314 1.1 macallan 315 1.1 macallan sc->sc_defaultscreen_descr = (struct wsscreen_descr) { 316 1.1 macallan "default", 317 1.1 macallan 0, 0, 318 1.1 macallan NULL, 319 1.1 macallan 8, 16, 320 1.10 macallan WSSCREEN_WSCOLORS | WSSCREEN_HILIT | WSSCREEN_UNDERLINE | 321 1.10 macallan WSSCREEN_RESIZE, 322 1.1 macallan NULL 323 1.1 macallan }; 324 1.6 macallan 325 1.6 macallan sc->sc_cursor_x = 0; 326 1.6 macallan sc->sc_cursor_y = 0; 327 1.6 macallan sc->sc_hotspot_x = 0; 328 1.6 macallan sc->sc_hotspot_y = 0; 329 1.6 macallan sc->sc_video = WSDISPLAYIO_VIDEO_ON; 330 1.6 macallan 331 1.1 macallan sc->sc_screens[0] = &sc->sc_defaultscreen_descr; 332 1.1 macallan sc->sc_screenlist = (struct wsscreen_list){1, sc->sc_screens}; 333 1.1 macallan 334 1.1 macallan isconsole = fb_is_console(node); 335 1.1 macallan 336 1.1 macallan sc->sc_mode = WSDISPLAYIO_MODE_EMUL; 337 1.1 macallan wsfont_init(); 338 1.1 macallan 339 1.1 macallan vcons_init(&sc->vd, sc, &sc->sc_defaultscreen_descr, &mgx_accessops); 340 1.1 macallan sc->vd.init_screen = mgx_init_screen; 341 1.12 macallan sc->vd.show_screen_cookie = sc; 342 1.12 macallan sc->vd.show_screen_cb = mgx_adapt; 343 1.1 macallan 344 1.1 macallan vcons_init_screen(&sc->vd, &sc->sc_console_screen, 1, &defattr); 345 1.1 macallan sc->sc_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC; 346 1.1 macallan 347 1.1 macallan ri = &sc->sc_console_screen.scr_ri; 348 1.1 macallan 349 1.1 macallan sc->sc_defaultscreen_descr.nrows = ri->ri_rows; 350 1.1 macallan sc->sc_defaultscreen_descr.ncols = ri->ri_cols; 351 1.1 macallan sc->sc_defaultscreen_descr.textops = &ri->ri_ops; 352 1.1 macallan sc->sc_defaultscreen_descr.capabilities = ri->ri_caps; 353 1.1 macallan 354 1.2 macallan sc->sc_gc.gc_bitblt = mgx_bitblt; 355 1.2 macallan sc->sc_gc.gc_rectfill = mgx_rectfill; 356 1.2 macallan sc->sc_gc.gc_blitcookie = sc; 357 1.2 macallan sc->sc_gc.gc_rop = ROP_SRC; 358 1.2 macallan 359 1.10 macallan /* 360 1.10 macallan * leave some room between visible screen and glyph cache for upload 361 1.10 macallan * buffers used by putchar_mono() 362 1.10 macallan */ 363 1.21 macallan bsize = (32 * 1024 + sc->sc_stride - 1) / sc->sc_stride; 364 1.2 macallan glyphcache_init(&sc->sc_gc, 365 1.12 macallan sc->sc_height + bsize, 366 1.12 macallan (0x400000 / sc->sc_stride) - (sc->sc_height + bsize), 367 1.2 macallan sc->sc_width, 368 1.2 macallan ri->ri_font->fontwidth, 369 1.2 macallan ri->ri_font->fontheight, 370 1.2 macallan defattr); 371 1.2 macallan 372 1.1 macallan mgx_init_palette(sc); 373 1.1 macallan 374 1.1 macallan if(isconsole) { 375 1.2 macallan wsdisplay_cnattach(&sc->sc_defaultscreen_descr, ri, 0, 0, 376 1.2 macallan defattr); 377 1.1 macallan vcons_replay_msgbuf(&sc->sc_console_screen); 378 1.1 macallan } 379 1.1 macallan 380 1.1 macallan aa.console = isconsole; 381 1.1 macallan aa.scrdata = &sc->sc_screenlist; 382 1.1 macallan aa.accessops = &mgx_accessops; 383 1.1 macallan aa.accesscookie = &sc->vd; 384 1.1 macallan 385 1.16 thorpej config_found(self, &aa, wsemuldisplaydevprint, CFARGS_NONE); 386 1.1 macallan 387 1.9 macallan /* now the Sun fb goop */ 388 1.9 macallan fb->fb_driver = &mgx_fbdriver; 389 1.9 macallan fb->fb_device = sc->sc_dev; 390 1.9 macallan fb->fb_flags = device_cfdata(sc->sc_dev)->cf_flags & FB_USERMASK; 391 1.9 macallan fb->fb_type.fb_type = FBTYPE_MGX; 392 1.9 macallan fb->fb_pixels = NULL; 393 1.9 macallan 394 1.9 macallan fb->fb_type.fb_depth = 32; 395 1.9 macallan fb->fb_type.fb_width = sc->sc_width; 396 1.9 macallan fb->fb_type.fb_height = sc->sc_height; 397 1.9 macallan fb->fb_linebytes = sc->sc_stride * 4; 398 1.9 macallan 399 1.9 macallan fb->fb_type.fb_cmsize = 256; 400 1.9 macallan fb->fb_type.fb_size = sc->sc_fbsize; 401 1.9 macallan fb_attach(&sc->sc_fb, isconsole); 402 1.2 macallan } 403 1.2 macallan 404 1.1 macallan static void 405 1.1 macallan mgx_write_dac(struct mgx_softc *sc, int idx, int r, int g, int b) 406 1.1 macallan { 407 1.1 macallan mgx_write_vga(sc, VGA_BASE + VGA_DAC_ADDRW, idx); 408 1.1 macallan mgx_write_vga(sc, VGA_BASE + VGA_DAC_PALETTE, r); 409 1.1 macallan mgx_write_vga(sc, VGA_BASE + VGA_DAC_PALETTE, g); 410 1.1 macallan mgx_write_vga(sc, VGA_BASE + VGA_DAC_PALETTE, b); 411 1.1 macallan } 412 1.1 macallan 413 1.1 macallan static void 414 1.1 macallan mgx_init_palette(struct mgx_softc *sc) 415 1.1 macallan { 416 1.1 macallan struct rasops_info *ri = &sc->sc_console_screen.scr_ri; 417 1.1 macallan int i, j = 0; 418 1.1 macallan uint8_t cmap[768]; 419 1.1 macallan 420 1.5 macallan if (sc->sc_depth == 8) { 421 1.5 macallan rasops_get_cmap(ri, cmap, sizeof(cmap)); 422 1.5 macallan for (i = 0; i < 256; i++) { 423 1.5 macallan sc->sc_cmap_red[i] = cmap[j]; 424 1.5 macallan sc->sc_cmap_green[i] = cmap[j + 1]; 425 1.5 macallan sc->sc_cmap_blue[i] = cmap[j + 2]; 426 1.5 macallan mgx_write_dac(sc, i, cmap[j], cmap[j + 1], cmap[j + 2]); 427 1.5 macallan j += 3; 428 1.5 macallan } 429 1.5 macallan } else { 430 1.5 macallan /* linear ramp for true colour modes */ 431 1.5 macallan for (i = 0; i < 256; i++) { 432 1.5 macallan mgx_write_dac(sc, i, i, i, i); 433 1.5 macallan } 434 1.1 macallan } 435 1.1 macallan } 436 1.1 macallan 437 1.2 macallan static int 438 1.4 macallan mgx_putcmap(struct mgx_softc *sc, struct wsdisplay_cmap *cm) 439 1.4 macallan { 440 1.4 macallan u_char *r, *g, *b; 441 1.4 macallan u_int index = cm->index; 442 1.4 macallan u_int count = cm->count; 443 1.4 macallan int i, error; 444 1.4 macallan u_char rbuf[256], gbuf[256], bbuf[256]; 445 1.4 macallan 446 1.4 macallan if (cm->index >= 256 || cm->count > 256 || 447 1.4 macallan (cm->index + cm->count) > 256) 448 1.4 macallan return EINVAL; 449 1.4 macallan error = copyin(cm->red, &rbuf[index], count); 450 1.4 macallan if (error) 451 1.4 macallan return error; 452 1.4 macallan error = copyin(cm->green, &gbuf[index], count); 453 1.4 macallan if (error) 454 1.4 macallan return error; 455 1.4 macallan error = copyin(cm->blue, &bbuf[index], count); 456 1.4 macallan if (error) 457 1.4 macallan return error; 458 1.4 macallan 459 1.4 macallan memcpy(&sc->sc_cmap_red[index], &rbuf[index], count); 460 1.4 macallan memcpy(&sc->sc_cmap_green[index], &gbuf[index], count); 461 1.4 macallan memcpy(&sc->sc_cmap_blue[index], &bbuf[index], count); 462 1.4 macallan 463 1.4 macallan r = &sc->sc_cmap_red[index]; 464 1.4 macallan g = &sc->sc_cmap_green[index]; 465 1.4 macallan b = &sc->sc_cmap_blue[index]; 466 1.4 macallan 467 1.4 macallan for (i = 0; i < count; i++) { 468 1.4 macallan mgx_write_dac(sc, index, *r, *g, *b); 469 1.4 macallan index++; 470 1.4 macallan r++, g++, b++; 471 1.4 macallan } 472 1.4 macallan return 0; 473 1.4 macallan } 474 1.4 macallan 475 1.4 macallan static int 476 1.4 macallan mgx_getcmap(struct mgx_softc *sc, struct wsdisplay_cmap *cm) 477 1.4 macallan { 478 1.4 macallan u_int index = cm->index; 479 1.4 macallan u_int count = cm->count; 480 1.4 macallan int error; 481 1.4 macallan 482 1.4 macallan if (index >= 255 || count > 256 || index + count > 256) 483 1.4 macallan return EINVAL; 484 1.4 macallan 485 1.4 macallan error = copyout(&sc->sc_cmap_red[index], cm->red, count); 486 1.4 macallan if (error) 487 1.4 macallan return error; 488 1.4 macallan error = copyout(&sc->sc_cmap_green[index], cm->green, count); 489 1.4 macallan if (error) 490 1.4 macallan return error; 491 1.4 macallan error = copyout(&sc->sc_cmap_blue[index], cm->blue, count); 492 1.4 macallan if (error) 493 1.4 macallan return error; 494 1.4 macallan 495 1.4 macallan return 0; 496 1.4 macallan } 497 1.4 macallan 498 1.4 macallan static int 499 1.2 macallan mgx_wait_engine(struct mgx_softc *sc) 500 1.2 macallan { 501 1.2 macallan unsigned int i; 502 1.2 macallan uint8_t stat; 503 1.2 macallan 504 1.2 macallan for (i = 100000; i != 0; i--) { 505 1.2 macallan stat = mgx_read_1(sc, ATR_BLT_STATUS); 506 1.2 macallan if ((stat & (BLT_HOST_BUSY | BLT_ENGINE_BUSY)) == 0) 507 1.2 macallan break; 508 1.2 macallan } 509 1.2 macallan 510 1.2 macallan return i; 511 1.2 macallan } 512 1.2 macallan 513 1.5 macallan static inline int 514 1.5 macallan mgx_wait_host(struct mgx_softc *sc) 515 1.5 macallan { 516 1.5 macallan unsigned int i; 517 1.5 macallan uint8_t stat; 518 1.5 macallan 519 1.5 macallan for (i = 10000; i != 0; i--) { 520 1.5 macallan stat = mgx_read_1(sc, ATR_BLT_STATUS); 521 1.5 macallan if ((stat & BLT_HOST_BUSY) == 0) 522 1.5 macallan break; 523 1.5 macallan } 524 1.5 macallan 525 1.5 macallan return i; 526 1.5 macallan } 527 1.5 macallan 528 1.12 macallan /*static inline*/ int 529 1.2 macallan mgx_wait_fifo(struct mgx_softc *sc, unsigned int nfifo) 530 1.2 macallan { 531 1.2 macallan unsigned int i; 532 1.2 macallan uint8_t stat; 533 1.2 macallan 534 1.2 macallan for (i = 100000; i != 0; i--) { 535 1.2 macallan stat = mgx_read_1(sc, ATR_FIFO_STATUS); 536 1.2 macallan stat = (stat & FIFO_MASK) >> FIFO_SHIFT; 537 1.2 macallan if (stat >= nfifo) 538 1.2 macallan break; 539 1.2 macallan mgx_write_1(sc, ATR_FIFO_STATUS, 0); 540 1.2 macallan } 541 1.2 macallan 542 1.2 macallan return i; 543 1.2 macallan } 544 1.2 macallan 545 1.1 macallan static void 546 1.1 macallan mgx_setup(struct mgx_softc *sc, int depth) 547 1.1 macallan { 548 1.5 macallan uint32_t stride; 549 1.5 macallan int i; 550 1.5 macallan uint8_t reg; 551 1.5 macallan 552 1.23 macallan sc->sc_r_dec = 0xffffffff; 553 1.23 macallan sc->sc_r_fg = 0x12345678; 554 1.2 macallan /* wait for everything to go idle */ 555 1.2 macallan if (mgx_wait_engine(sc) == 0) 556 1.2 macallan return; 557 1.2 macallan if (mgx_wait_fifo(sc, FIFO_AT24) == 0) 558 1.2 macallan return; 559 1.5 macallan 560 1.10 macallan sc->sc_buf = 0; 561 1.5 macallan /* read name from sequencer */ 562 1.5 macallan for (i = 0; i < 8; i++) { 563 1.5 macallan mgx_write_vga(sc, SEQ_INDEX, i + 0x11); 564 1.5 macallan sc->sc_name[i] = mgx_read_vga(sc, SEQ_DATA); 565 1.5 macallan } 566 1.5 macallan sc->sc_name[7] = 0; 567 1.5 macallan 568 1.5 macallan reg = mgx_read_1(sc, ATR_PIXEL); 569 1.5 macallan reg &= ~PIXEL_DEPTH_MASK; 570 1.2 macallan 571 1.2 macallan switch (depth) { 572 1.2 macallan case 8: 573 1.2 macallan sc->sc_dec = DEC_DEPTH_8 << DEC_DEPTH_SHIFT; 574 1.5 macallan reg |= PIXEL_8; 575 1.2 macallan break; 576 1.2 macallan case 15: 577 1.5 macallan sc->sc_dec = DEC_DEPTH_16 << DEC_DEPTH_SHIFT; 578 1.5 macallan reg |= PIXEL_15; 579 1.5 macallan break; 580 1.2 macallan case 16: 581 1.2 macallan sc->sc_dec = DEC_DEPTH_16 << DEC_DEPTH_SHIFT; 582 1.5 macallan reg |= PIXEL_16; 583 1.2 macallan break; 584 1.2 macallan case 32: 585 1.2 macallan sc->sc_dec = DEC_DEPTH_32 << DEC_DEPTH_SHIFT; 586 1.5 macallan reg |= PIXEL_32; 587 1.2 macallan break; 588 1.2 macallan default: 589 1.2 macallan return; /* not supported */ 590 1.2 macallan } 591 1.2 macallan 592 1.5 macallan /* the chip wants stride in units of 8 bytes */ 593 1.5 macallan sc->sc_stride = sc->sc_width * (depth >> 3); 594 1.5 macallan stride = sc->sc_stride >> 3; 595 1.5 macallan #ifdef MGX_DEBUG 596 1.12 macallan sc->sc_height -= 150; 597 1.5 macallan #endif 598 1.5 macallan 599 1.5 macallan sc->sc_depth = depth; 600 1.5 macallan 601 1.5 macallan switch (sc->sc_width) { 602 1.2 macallan case 640: 603 1.2 macallan sc->sc_dec |= DEC_WIDTH_640 << DEC_WIDTH_SHIFT; 604 1.2 macallan break; 605 1.2 macallan case 800: 606 1.2 macallan sc->sc_dec |= DEC_WIDTH_800 << DEC_WIDTH_SHIFT; 607 1.2 macallan break; 608 1.2 macallan case 1024: 609 1.2 macallan sc->sc_dec |= DEC_WIDTH_1024 << DEC_WIDTH_SHIFT; 610 1.2 macallan break; 611 1.2 macallan case 1152: 612 1.2 macallan sc->sc_dec |= DEC_WIDTH_1152 << DEC_WIDTH_SHIFT; 613 1.2 macallan break; 614 1.2 macallan case 1280: 615 1.2 macallan sc->sc_dec |= DEC_WIDTH_1280 << DEC_WIDTH_SHIFT; 616 1.2 macallan break; 617 1.2 macallan case 1600: 618 1.2 macallan sc->sc_dec |= DEC_WIDTH_1600 << DEC_WIDTH_SHIFT; 619 1.2 macallan break; 620 1.2 macallan default: 621 1.2 macallan return; /* not supported */ 622 1.2 macallan } 623 1.10 macallan mgx_wait_fifo(sc, 4); 624 1.2 macallan mgx_write_1(sc, ATR_CLIP_CONTROL, 0); 625 1.2 macallan mgx_write_1(sc, ATR_BYTEMASK, 0xff); 626 1.5 macallan mgx_write_1(sc, ATR_PIXEL, reg); 627 1.10 macallan mgx_write_4(sc, ATR_OFFSET, 0); 628 1.10 macallan mgx_wait_fifo(sc, 4); 629 1.5 macallan mgx_write_vga(sc, CRTC_INDEX, 0x13); 630 1.5 macallan mgx_write_vga(sc, CRTC_DATA, stride & 0xff); 631 1.5 macallan mgx_write_vga(sc, CRTC_INDEX, 0x1c); 632 1.5 macallan mgx_write_vga(sc, CRTC_DATA, (stride & 0xf00) >> 4); 633 1.6 macallan 634 1.6 macallan /* clean up the screen if we're switching to != 8bit */ 635 1.6 macallan if (depth != MGX_DEPTH) 636 1.6 macallan mgx_rectfill(sc, 0, 0, sc->sc_width, sc->sc_height, 0); 637 1.6 macallan 638 1.10 macallan mgx_wait_fifo(sc, 4); 639 1.6 macallan /* initialize hardware cursor stuff */ 640 1.6 macallan mgx_write_2(sc, ATR_CURSOR_ADDRESS, (sc->sc_fbsize - 1024) >> 10); 641 1.6 macallan mgx_write_1(sc, ATR_CURSOR_ENABLE, 0); 642 1.6 macallan sc->sc_cursor = (uint8_t *)sc->sc_fbaddr + sc->sc_fbsize - 1024; 643 1.6 macallan memset(sc->sc_cursor, 0xf0, 1024); 644 1.12 macallan memset(sc->sc_in, 0, sizeof(sc->sc_in)); 645 1.2 macallan } 646 1.2 macallan 647 1.2 macallan static void 648 1.2 macallan mgx_bitblt(void *cookie, int xs, int ys, int xd, int yd, int wi, int he, 649 1.2 macallan int rop) 650 1.2 macallan { 651 1.2 macallan struct mgx_softc *sc = cookie; 652 1.2 macallan uint32_t dec = sc->sc_dec; 653 1.2 macallan 654 1.2 macallan dec |= (DEC_COMMAND_BLT << DEC_COMMAND_SHIFT) | 655 1.2 macallan (DEC_START_DIMX << DEC_START_SHIFT); 656 1.2 macallan if (xs < xd) { 657 1.2 macallan xs += wi - 1; 658 1.2 macallan xd += wi - 1; 659 1.2 macallan dec |= DEC_DIR_X_REVERSE; 660 1.2 macallan } 661 1.2 macallan if (ys < yd) { 662 1.2 macallan ys += he - 1; 663 1.2 macallan yd += he - 1; 664 1.2 macallan dec |= DEC_DIR_Y_REVERSE; 665 1.2 macallan } 666 1.23 macallan mgx_set_dec(sc, dec); 667 1.23 macallan mgx_wait_fifo(sc, 4); 668 1.2 macallan mgx_write_1(sc, ATR_ROP, rop); 669 1.2 macallan mgx_write_4(sc, ATR_SRC_XY, (ys << 16) | xs); 670 1.2 macallan mgx_write_4(sc, ATR_DST_XY, (yd << 16) | xd); 671 1.2 macallan mgx_write_4(sc, ATR_WH, (he << 16) | wi); 672 1.2 macallan } 673 1.2 macallan 674 1.2 macallan static void 675 1.2 macallan mgx_rectfill(void *cookie, int x, int y, int wi, int he, long fg) 676 1.2 macallan { 677 1.2 macallan struct mgx_softc *sc = cookie; 678 1.2 macallan struct vcons_screen *scr = sc->vd.active; 679 1.2 macallan uint32_t dec = sc->sc_dec; 680 1.2 macallan uint32_t col; 681 1.2 macallan 682 1.2 macallan if (scr == NULL) 683 1.2 macallan return; 684 1.2 macallan col = scr->scr_ri.ri_devcmap[fg]; 685 1.2 macallan 686 1.2 macallan dec = sc->sc_dec; 687 1.2 macallan dec |= (DEC_COMMAND_RECT << DEC_COMMAND_SHIFT) | 688 1.2 macallan (DEC_START_DIMX << DEC_START_SHIFT); 689 1.23 macallan mgx_set_dec(sc, dec); 690 1.23 macallan mgx_set_fg(sc, col); 691 1.23 macallan mgx_wait_fifo(sc, 3); 692 1.2 macallan mgx_write_1(sc, ATR_ROP, ROP_SRC); 693 1.2 macallan mgx_write_4(sc, ATR_DST_XY, (y << 16) | x); 694 1.2 macallan mgx_write_4(sc, ATR_WH, (he << 16) | wi); 695 1.2 macallan } 696 1.2 macallan 697 1.2 macallan static void 698 1.10 macallan mgx_putchar_aa(void *cookie, int row, int col, u_int c, long attr) 699 1.2 macallan { 700 1.2 macallan struct rasops_info *ri = cookie; 701 1.2 macallan struct wsdisplay_font *font = PICK_FONT(ri, c); 702 1.2 macallan struct vcons_screen *scr = ri->ri_hw; 703 1.2 macallan struct mgx_softc *sc = scr->scr_cookie; 704 1.2 macallan uint32_t fg, bg; 705 1.2 macallan int x, y, wi, he, rv; 706 1.2 macallan 707 1.2 macallan wi = font->fontwidth; 708 1.2 macallan he = font->fontheight; 709 1.2 macallan 710 1.2 macallan bg = (attr >> 16) & 0xf; 711 1.2 macallan fg = (attr >> 24) & 0xf; 712 1.2 macallan 713 1.2 macallan x = ri->ri_xorigin + col * wi; 714 1.2 macallan y = ri->ri_yorigin + row * he; 715 1.2 macallan 716 1.2 macallan if (c == 0x20) { 717 1.2 macallan mgx_rectfill(sc, x, y, wi, he, bg); 718 1.2 macallan if (attr & 1) 719 1.2 macallan mgx_rectfill(sc, x, y + he - 2, wi, 1, fg); 720 1.2 macallan return; 721 1.2 macallan } 722 1.10 macallan 723 1.2 macallan rv = glyphcache_try(&sc->sc_gc, c, x, y, attr); 724 1.3 macallan if (rv != GC_OK) { 725 1.3 macallan volatile uint32_t junk; 726 1.2 macallan 727 1.3 macallan mgx_wait_engine(sc); 728 1.3 macallan sc->sc_putchar(cookie, row, col, c, attr & ~1); 729 1.5 macallan if (rv == GC_ADD) { 730 1.8 macallan /* 731 1.8 macallan * try to make sure the glyph made it all the way to 732 1.8 macallan * video memory before trying to blit it into the cache 733 1.8 macallan */ 734 1.5 macallan junk = *(uint32_t *)sc->sc_fbaddr; 735 1.5 macallan __USE(junk); 736 1.3 macallan glyphcache_add(&sc->sc_gc, c, x, y); 737 1.5 macallan } 738 1.2 macallan } 739 1.3 macallan if (attr & 1) 740 1.3 macallan mgx_rectfill(sc, x, y + he - 2, wi, 1, fg); 741 1.2 macallan } 742 1.2 macallan 743 1.2 macallan static void 744 1.10 macallan mgx_putchar_mono(void *cookie, int row, int col, u_int c, long attr) 745 1.10 macallan { 746 1.10 macallan struct rasops_info *ri = cookie; 747 1.10 macallan struct wsdisplay_font *font = PICK_FONT(ri, c); 748 1.10 macallan struct vcons_screen *scr = ri->ri_hw; 749 1.10 macallan struct mgx_softc *sc = scr->scr_cookie; 750 1.12 macallan uint8_t *s, *d; 751 1.12 macallan uint32_t fg, bg, scratch = ((sc->sc_stride * sc->sc_height) + 7) & ~7; 752 1.12 macallan int x, y, wi, he, len, i; 753 1.10 macallan 754 1.10 macallan wi = font->fontwidth; 755 1.10 macallan he = font->fontheight; 756 1.10 macallan 757 1.10 macallan bg = (attr >> 16) & 0xf; 758 1.10 macallan fg = (attr >> 24) & 0xf; 759 1.10 macallan 760 1.10 macallan x = ri->ri_xorigin + col * wi; 761 1.10 macallan y = ri->ri_yorigin + row * he; 762 1.10 macallan 763 1.12 macallan if (!CHAR_IN_FONT(c, font)) { 764 1.12 macallan c = 0x20; 765 1.12 macallan #ifdef MGX_DEBUG 766 1.12 macallan bg = WSCOL_LIGHT_BLUE; 767 1.12 macallan #endif 768 1.12 macallan } 769 1.10 macallan if (c == 0x20) { 770 1.10 macallan mgx_rectfill(sc, x, y, wi, he, bg); 771 1.10 macallan if (attr & 1) 772 1.10 macallan mgx_rectfill(sc, x, y + he - 2, wi, 1, fg); 773 1.10 macallan return; 774 1.10 macallan } 775 1.10 macallan 776 1.23 macallan mgx_set_fg(sc, ri->ri_devcmap[fg]); 777 1.23 macallan mgx_wait_fifo(sc, 2); 778 1.12 macallan mgx_write_4(sc, ATR_BG, ri->ri_devcmap[bg]); 779 1.12 macallan mgx_write_1(sc, ATR_ROP, ROP_SRC); 780 1.12 macallan 781 1.10 macallan /* 782 1.10 macallan * do hardware colour expansion 783 1.12 macallan * there has to be an upload port somewhere, since there are host blit 784 1.10 macallan * commands, but it's not used or mentioned in the xf86-video-apm driver 785 1.10 macallan * so for now we use the vram-to-vram blits to draw characters. 786 1.12 macallan * stash most of the font in vram for speed, also: 787 1.12 macallan * - the sbus-pci bridge doesn't seem to support 64bit accesses, 788 1.12 macallan * they will cause occasional data corruption and all sorts of weird 789 1.12 macallan * side effects, so copy font bitmaps byte-wise 790 1.12 macallan * - at least it doesn't seem to need any kind of buffer flushing 791 1.12 macallan * - still use rotation buffers for characters that don't fall into the 792 1.12 macallan * 8 bit range 793 1.10 macallan */ 794 1.12 macallan 795 1.12 macallan len = (ri->ri_fontscale + 7) & ~7; 796 1.10 macallan s = WSFONT_GLYPH(c, font); 797 1.12 macallan if ((c > 32) && (c < 256)) { 798 1.12 macallan scratch += len * c; 799 1.12 macallan if (sc->sc_in[c] == 0) { 800 1.12 macallan d = (uint8_t *)sc->sc_fbaddr + scratch; 801 1.12 macallan for (i = 0; i < ri->ri_fontscale; i++) 802 1.12 macallan d[i] = s[i]; 803 1.12 macallan sc->sc_in[c] = 1; 804 1.12 macallan } 805 1.12 macallan } else { 806 1.12 macallan sc->sc_buf = (sc->sc_buf + 1) & 7; /* rotate through 8 buffers */ 807 1.12 macallan scratch += sc->sc_buf * len; 808 1.12 macallan d = (uint8_t *)sc->sc_fbaddr + scratch; 809 1.12 macallan for (i = 0; i < ri->ri_fontscale; i++) 810 1.12 macallan d[i] = s[i]; 811 1.12 macallan } 812 1.23 macallan mgx_set_dec(sc, sc->sc_dec | (DEC_COMMAND_BLT << DEC_COMMAND_SHIFT) | 813 1.10 macallan (DEC_START_DIMX << DEC_START_SHIFT) | 814 1.10 macallan DEC_SRC_LINEAR | DEC_SRC_CONTIGUOUS | DEC_MONOCHROME); 815 1.23 macallan mgx_wait_fifo(sc, 3); 816 1.10 macallan mgx_write_4(sc, ATR_SRC_XY, ((scratch & 0xfff000) << 4) | (scratch & 0xfff)); 817 1.10 macallan mgx_write_4(sc, ATR_DST_XY, (y << 16) | x); 818 1.10 macallan mgx_write_4(sc, ATR_WH, (he << 16) | wi); 819 1.10 macallan 820 1.10 macallan if (attr & 1) 821 1.10 macallan mgx_rectfill(sc, x, y + he - 2, wi, 1, fg); 822 1.10 macallan } 823 1.10 macallan 824 1.10 macallan static void 825 1.2 macallan mgx_cursor(void *cookie, int on, int row, int col) 826 1.2 macallan { 827 1.2 macallan struct rasops_info *ri = cookie; 828 1.2 macallan struct vcons_screen *scr = ri->ri_hw; 829 1.2 macallan struct mgx_softc *sc = scr->scr_cookie; 830 1.2 macallan int x, y, wi,he; 831 1.2 macallan 832 1.2 macallan wi = ri->ri_font->fontwidth; 833 1.2 macallan he = ri->ri_font->fontheight; 834 1.2 macallan 835 1.2 macallan if (ri->ri_flg & RI_CURSOR) { 836 1.2 macallan x = ri->ri_ccol * wi + ri->ri_xorigin; 837 1.2 macallan y = ri->ri_crow * he + ri->ri_yorigin; 838 1.2 macallan mgx_bitblt(sc, x, y, x, y, wi, he, ROP_INV); 839 1.2 macallan ri->ri_flg &= ~RI_CURSOR; 840 1.2 macallan } 841 1.2 macallan 842 1.2 macallan ri->ri_crow = row; 843 1.2 macallan ri->ri_ccol = col; 844 1.2 macallan 845 1.2 macallan if (on) 846 1.2 macallan { 847 1.2 macallan x = ri->ri_ccol * wi + ri->ri_xorigin; 848 1.2 macallan y = ri->ri_crow * he + ri->ri_yorigin; 849 1.2 macallan mgx_bitblt(sc, x, y, x, y, wi, he, ROP_INV); 850 1.2 macallan ri->ri_flg |= RI_CURSOR; 851 1.2 macallan } 852 1.2 macallan } 853 1.2 macallan 854 1.2 macallan static void 855 1.2 macallan mgx_copycols(void *cookie, int row, int srccol, int dstcol, int ncols) 856 1.2 macallan { 857 1.2 macallan struct rasops_info *ri = cookie; 858 1.2 macallan struct vcons_screen *scr = ri->ri_hw; 859 1.2 macallan struct mgx_softc *sc = scr->scr_cookie; 860 1.2 macallan int32_t xs, xd, y, width, height; 861 1.2 macallan 862 1.2 macallan xs = ri->ri_xorigin + ri->ri_font->fontwidth * srccol; 863 1.2 macallan xd = ri->ri_xorigin + ri->ri_font->fontwidth * dstcol; 864 1.2 macallan y = ri->ri_yorigin + ri->ri_font->fontheight * row; 865 1.2 macallan width = ri->ri_font->fontwidth * ncols; 866 1.2 macallan height = ri->ri_font->fontheight; 867 1.2 macallan mgx_bitblt(sc, xs, y, xd, y, width, height, ROP_SRC); 868 1.2 macallan } 869 1.2 macallan 870 1.2 macallan static void 871 1.2 macallan mgx_erasecols(void *cookie, int row, int startcol, int ncols, long fillattr) 872 1.2 macallan { 873 1.2 macallan struct rasops_info *ri = cookie; 874 1.2 macallan struct vcons_screen *scr = ri->ri_hw; 875 1.2 macallan struct mgx_softc *sc = scr->scr_cookie; 876 1.2 macallan int32_t x, y, width, height, bg; 877 1.2 macallan 878 1.2 macallan x = ri->ri_xorigin + ri->ri_font->fontwidth * startcol; 879 1.2 macallan y = ri->ri_yorigin + ri->ri_font->fontheight * row; 880 1.2 macallan width = ri->ri_font->fontwidth * ncols; 881 1.2 macallan height = ri->ri_font->fontheight; 882 1.2 macallan bg = (fillattr >> 16) & 0xff; 883 1.2 macallan mgx_rectfill(sc, x, y, width, height, bg); 884 1.2 macallan } 885 1.2 macallan 886 1.2 macallan static void 887 1.2 macallan mgx_copyrows(void *cookie, int srcrow, int dstrow, int nrows) 888 1.2 macallan { 889 1.2 macallan struct rasops_info *ri = cookie; 890 1.2 macallan struct vcons_screen *scr = ri->ri_hw; 891 1.2 macallan struct mgx_softc *sc = scr->scr_cookie; 892 1.2 macallan int32_t x, ys, yd, width, height; 893 1.2 macallan 894 1.2 macallan x = ri->ri_xorigin; 895 1.2 macallan ys = ri->ri_yorigin + ri->ri_font->fontheight * srcrow; 896 1.2 macallan yd = ri->ri_yorigin + ri->ri_font->fontheight * dstrow; 897 1.2 macallan width = ri->ri_emuwidth; 898 1.2 macallan height = ri->ri_font->fontheight * nrows; 899 1.2 macallan mgx_bitblt(sc, x, ys, x, yd, width, height, ROP_SRC); 900 1.2 macallan } 901 1.2 macallan 902 1.2 macallan static void 903 1.2 macallan mgx_eraserows(void *cookie, int row, int nrows, long fillattr) 904 1.2 macallan { 905 1.2 macallan struct rasops_info *ri = cookie; 906 1.2 macallan struct vcons_screen *scr = ri->ri_hw; 907 1.2 macallan struct mgx_softc *sc = scr->scr_cookie; 908 1.2 macallan int32_t x, y, width, height, bg; 909 1.2 macallan 910 1.2 macallan if ((row == 0) && (nrows == ri->ri_rows)) { 911 1.2 macallan x = y = 0; 912 1.2 macallan width = ri->ri_width; 913 1.2 macallan height = ri->ri_height; 914 1.2 macallan } else { 915 1.2 macallan x = ri->ri_xorigin; 916 1.2 macallan y = ri->ri_yorigin + ri->ri_font->fontheight * row; 917 1.2 macallan width = ri->ri_emuwidth; 918 1.2 macallan height = ri->ri_font->fontheight * nrows; 919 1.2 macallan } 920 1.2 macallan bg = (fillattr >> 16) & 0xff; 921 1.2 macallan mgx_rectfill(sc, x, y, width, height, bg); 922 1.1 macallan } 923 1.1 macallan 924 1.1 macallan static void 925 1.12 macallan mgx_adapt(struct vcons_screen *scr, void *cookie) 926 1.12 macallan { 927 1.12 macallan struct mgx_softc *sc = cookie; 928 1.12 macallan memset(sc->sc_in, 0, sizeof(sc->sc_in)); 929 1.12 macallan glyphcache_adapt(scr, &sc->sc_gc); 930 1.12 macallan } 931 1.12 macallan 932 1.12 macallan static void 933 1.1 macallan mgx_init_screen(void *cookie, struct vcons_screen *scr, 934 1.1 macallan int existing, long *defattr) 935 1.1 macallan { 936 1.1 macallan struct mgx_softc *sc = cookie; 937 1.1 macallan struct rasops_info *ri = &scr->scr_ri; 938 1.1 macallan 939 1.5 macallan ri->ri_depth = sc->sc_depth; 940 1.1 macallan ri->ri_width = sc->sc_width; 941 1.1 macallan ri->ri_height = sc->sc_height; 942 1.1 macallan ri->ri_stride = sc->sc_stride; 943 1.3 macallan ri->ri_flg = RI_CENTER | RI_ENABLE_ALPHA; 944 1.1 macallan 945 1.1 macallan if (ri->ri_depth == 8) 946 1.3 macallan ri->ri_flg |= RI_8BIT_IS_RGB; 947 1.1 macallan 948 1.5 macallan #ifdef MGX_NOACCEL 949 1.5 macallan scr->scr_flags |= VCONS_DONT_READ; 950 1.5 macallan #endif 951 1.10 macallan scr->scr_flags |= VCONS_LOADFONT; 952 1.5 macallan 953 1.5 macallan ri->ri_rnum = 8; 954 1.5 macallan ri->ri_rpos = 0; 955 1.5 macallan ri->ri_gnum = 8; 956 1.5 macallan ri->ri_gpos = 8; 957 1.5 macallan ri->ri_bnum = 8; 958 1.5 macallan ri->ri_bpos = 16; 959 1.5 macallan 960 1.1 macallan ri->ri_bits = sc->sc_fbaddr; 961 1.1 macallan 962 1.1 macallan rasops_init(ri, 0, 0); 963 1.1 macallan 964 1.13 macallan ri->ri_caps = WSSCREEN_REVERSE | WSSCREEN_WSCOLORS | 965 1.13 macallan WSSCREEN_UNDERLINE | WSSCREEN_RESIZE; 966 1.1 macallan 967 1.1 macallan rasops_reconfig(ri, ri->ri_height / ri->ri_font->fontheight, 968 1.1 macallan ri->ri_width / ri->ri_font->fontwidth); 969 1.2 macallan 970 1.2 macallan ri->ri_hw = scr; 971 1.12 macallan 972 1.5 macallan #ifdef MGX_NOACCEL 973 1.5 macallan if (0) 974 1.5 macallan #endif 975 1.5 macallan { 976 1.10 macallan if (FONT_IS_ALPHA(ri->ri_font)) { 977 1.10 macallan sc->sc_putchar = ri->ri_ops.putchar; 978 1.10 macallan ri->ri_ops.putchar = mgx_putchar_aa; 979 1.10 macallan } else { 980 1.10 macallan ri->ri_ops.putchar = mgx_putchar_mono; 981 1.10 macallan } 982 1.5 macallan ri->ri_ops.cursor = mgx_cursor; 983 1.5 macallan ri->ri_ops.copyrows = mgx_copyrows; 984 1.5 macallan ri->ri_ops.eraserows = mgx_eraserows; 985 1.5 macallan ri->ri_ops.copycols = mgx_copycols; 986 1.5 macallan ri->ri_ops.erasecols = mgx_erasecols; 987 1.5 macallan } 988 1.1 macallan } 989 1.1 macallan 990 1.1 macallan static int 991 1.1 macallan mgx_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, 992 1.1 macallan struct lwp *l) 993 1.1 macallan { 994 1.1 macallan struct vcons_data *vd = v; 995 1.1 macallan struct mgx_softc *sc = vd->cookie; 996 1.1 macallan struct wsdisplay_fbinfo *wdf; 997 1.1 macallan struct vcons_screen *ms = vd->active; 998 1.1 macallan 999 1.1 macallan switch (cmd) { 1000 1.17 macallan case WSDISPLAYIO_GTYPE: 1001 1.17 macallan *(u_int *)data = WSDISPLAY_TYPE_MGX; 1002 1.17 macallan return 0; 1003 1.1 macallan 1004 1.17 macallan case WSDISPLAYIO_GINFO: 1005 1.17 macallan wdf = (void *)data; 1006 1.17 macallan wdf->height = sc->sc_height; 1007 1.17 macallan wdf->width = sc->sc_width; 1008 1.17 macallan wdf->depth = 8; 1009 1.17 macallan wdf->cmsize = 256; 1010 1.17 macallan return 0; 1011 1.1 macallan 1012 1.9 macallan case FBIOGTYPE: 1013 1.9 macallan *(struct fbtype *)data = sc->sc_fb.fb_type; 1014 1.17 macallan return 0; 1015 1.9 macallan 1016 1.9 macallan case FBIOGATTR: 1017 1.9 macallan #define fba ((struct fbgattr *)data) 1018 1.9 macallan fba->real_type = sc->sc_fb.fb_type.fb_type; 1019 1.9 macallan fba->owner = 0; /* XXX ??? */ 1020 1.9 macallan fba->fbtype = sc->sc_fb.fb_type; 1021 1.9 macallan fba->sattr.flags = 0; 1022 1.9 macallan fba->sattr.emu_type = sc->sc_fb.fb_type.fb_type; 1023 1.9 macallan fba->sattr.dev_specific[0] = -1; 1024 1.9 macallan fba->emu_types[0] = sc->sc_fb.fb_type.fb_type; 1025 1.9 macallan fba->emu_types[1] = -1; 1026 1.9 macallan #undef fba 1027 1.17 macallan return 0; 1028 1.17 macallan case FBIOGVIDEO: 1029 1.17 macallan case WSDISPLAYIO_GVIDEO: 1030 1.17 macallan *(int *)data = sc->sc_video; 1031 1.17 macallan return 0; 1032 1.1 macallan 1033 1.17 macallan case WSDISPLAYIO_SVIDEO: 1034 1.17 macallan case FBIOSVIDEO: 1035 1.17 macallan mgx_set_video(sc, *(int *)data); 1036 1.17 macallan return 0; 1037 1.1 macallan 1038 1.17 macallan case WSDISPLAYIO_LINEBYTES: 1039 1.17 macallan { 1040 1.17 macallan int *ret = (int *)data; 1041 1.17 macallan *ret = sc->sc_stride; 1042 1.17 macallan } 1043 1.17 macallan return 0; 1044 1.1 macallan 1045 1.17 macallan case WSDISPLAYIO_SMODE: 1046 1.17 macallan { 1047 1.17 macallan int new_mode = *(int*)data; 1048 1.17 macallan if (new_mode != sc->sc_mode) 1049 1.1 macallan { 1050 1.17 macallan sc->sc_mode = new_mode; 1051 1.17 macallan if (new_mode == WSDISPLAYIO_MODE_EMUL) 1052 1.1 macallan { 1053 1.17 macallan mgx_setup(sc, MGX_DEPTH); 1054 1.17 macallan glyphcache_wipe(&sc->sc_gc); 1055 1.17 macallan mgx_init_palette(sc); 1056 1.17 macallan vcons_redraw_screen(ms); 1057 1.17 macallan } else { 1058 1.24 macallan mgx_setup(sc, MGX_X_DEPTH); 1059 1.17 macallan mgx_init_palette(sc); 1060 1.1 macallan } 1061 1.1 macallan } 1062 1.17 macallan } 1063 1.17 macallan return 0; 1064 1.17 macallan 1065 1.17 macallan case WSDISPLAYIO_GETCMAP: 1066 1.17 macallan return mgx_getcmap(sc, (struct wsdisplay_cmap *)data); 1067 1.4 macallan 1068 1.17 macallan case WSDISPLAYIO_PUTCMAP: 1069 1.17 macallan return mgx_putcmap(sc, (struct wsdisplay_cmap *)data); 1070 1.4 macallan 1071 1.24 macallan case FBIOGETCMAP: 1072 1.24 macallan #define p ((struct fbcmap *)data) 1073 1.24 macallan { 1074 1.24 macallan struct wsdisplay_cmap c = { 1075 1.24 macallan .index = p->index, 1076 1.24 macallan .count = p->count, 1077 1.24 macallan .red = p->red, 1078 1.24 macallan .green = p->green, 1079 1.24 macallan .blue = p->blue 1080 1.24 macallan }; 1081 1.24 macallan return mgx_getcmap(sc, &c); 1082 1.24 macallan } 1083 1.24 macallan break; 1084 1.24 macallan case FBIOPUTCMAP: 1085 1.24 macallan { 1086 1.24 macallan struct wsdisplay_cmap c = { 1087 1.24 macallan .index = p->index, 1088 1.24 macallan .count = p->count, 1089 1.24 macallan .red = p->red, 1090 1.24 macallan .green = p->green, 1091 1.24 macallan .blue = p->blue 1092 1.24 macallan }; 1093 1.24 macallan return mgx_putcmap(sc, &c); 1094 1.24 macallan } 1095 1.24 macallan break; 1096 1.24 macallan #undef p 1097 1.17 macallan case WSDISPLAYIO_GCURPOS: 1098 1.17 macallan { 1099 1.17 macallan struct wsdisplay_curpos *cp = (void *)data; 1100 1.4 macallan 1101 1.17 macallan cp->x = sc->sc_cursor_x; 1102 1.17 macallan cp->y = sc->sc_cursor_y; 1103 1.17 macallan } 1104 1.17 macallan return 0; 1105 1.6 macallan 1106 1.17 macallan case WSDISPLAYIO_SCURPOS: 1107 1.17 macallan { 1108 1.17 macallan struct wsdisplay_curpos *cp = (void *)data; 1109 1.6 macallan 1110 1.17 macallan sc->sc_cursor_x = cp->x; 1111 1.17 macallan sc->sc_cursor_y = cp->y; 1112 1.17 macallan mgx_set_cursor(sc); 1113 1.17 macallan } 1114 1.17 macallan return 0; 1115 1.6 macallan 1116 1.17 macallan case WSDISPLAYIO_GCURMAX: 1117 1.17 macallan { 1118 1.17 macallan struct wsdisplay_curpos *cp = (void *)data; 1119 1.6 macallan 1120 1.17 macallan cp->x = 64; 1121 1.17 macallan cp->y = 64; 1122 1.17 macallan } 1123 1.17 macallan return 0; 1124 1.6 macallan 1125 1.17 macallan case WSDISPLAYIO_SCURSOR: 1126 1.17 macallan { 1127 1.17 macallan struct wsdisplay_cursor *cursor = (void *)data; 1128 1.6 macallan 1129 1.17 macallan return mgx_do_cursor(sc, cursor); 1130 1.17 macallan } 1131 1.6 macallan 1132 1.17 macallan case WSDISPLAYIO_GET_FBINFO: 1133 1.17 macallan { 1134 1.17 macallan struct wsdisplayio_fbinfo *fbi = data; 1135 1.8 macallan 1136 1.17 macallan fbi->fbi_fbsize = sc->sc_fbsize - 1024; 1137 1.17 macallan fbi->fbi_width = sc->sc_width; 1138 1.17 macallan fbi->fbi_height = sc->sc_height; 1139 1.17 macallan fbi->fbi_bitsperpixel = sc->sc_depth; 1140 1.17 macallan fbi->fbi_stride = sc->sc_stride; 1141 1.17 macallan fbi->fbi_pixeltype = WSFB_RGB; 1142 1.17 macallan fbi->fbi_subtype.fbi_rgbmasks.red_offset = 8; 1143 1.17 macallan fbi->fbi_subtype.fbi_rgbmasks.red_size = 8; 1144 1.17 macallan fbi->fbi_subtype.fbi_rgbmasks.green_offset = 16; 1145 1.17 macallan fbi->fbi_subtype.fbi_rgbmasks.green_size = 8; 1146 1.17 macallan fbi->fbi_subtype.fbi_rgbmasks.blue_offset = 24; 1147 1.17 macallan fbi->fbi_subtype.fbi_rgbmasks.blue_size = 8; 1148 1.17 macallan fbi->fbi_subtype.fbi_rgbmasks.alpha_offset = 0; 1149 1.17 macallan fbi->fbi_subtype.fbi_rgbmasks.alpha_size = 8; 1150 1.17 macallan return 0; 1151 1.17 macallan } 1152 1.1 macallan } 1153 1.1 macallan return EPASSTHROUGH; 1154 1.1 macallan } 1155 1.1 macallan 1156 1.1 macallan static paddr_t 1157 1.1 macallan mgx_mmap(void *v, void *vs, off_t offset, int prot) 1158 1.1 macallan { 1159 1.1 macallan struct vcons_data *vd = v; 1160 1.1 macallan struct mgx_softc *sc = vd->cookie; 1161 1.20 macallan uint32_t flags = BUS_SPACE_MAP_LINEAR; 1162 1.20 macallan 1163 1.20 macallan #ifdef BUS_SPACE_MAP_LITTLE 1164 1.20 macallan if (offset & MGX_FLIPOFFSET) { 1165 1.20 macallan offset &= ~MGX_FLIPOFFSET; 1166 1.20 macallan flags |= BUS_SPACE_MAP_LITTLE; 1167 1.20 macallan } 1168 1.20 macallan #endif 1169 1.1 macallan 1170 1.1 macallan /* regular fb mapping at 0 */ 1171 1.5 macallan if ((offset >= 0) && (offset < sc->sc_fbsize)) { 1172 1.1 macallan return bus_space_mmap(sc->sc_tag, sc->sc_paddr, 1173 1.20 macallan offset, prot, flags); 1174 1.1 macallan } 1175 1.1 macallan 1176 1.8 macallan /* 1177 1.18 macallan * Blitter registers at 0x00800000, only in mapped mode. 1178 1.8 macallan * Restrict to root, even though I'm fairly sure the DMA engine lives 1179 1.8 macallan * elsewhere ( and isn't documented anyway ) 1180 1.8 macallan */ 1181 1.8 macallan if (kauth_authorize_machdep(kauth_cred_get(), 1182 1.8 macallan KAUTH_MACHDEP_UNMANAGEDMEM, 1183 1.8 macallan NULL, NULL, NULL, NULL) != 0) { 1184 1.8 macallan aprint_normal("%s: mmap() rejected.\n", 1185 1.8 macallan device_xname(sc->sc_dev)); 1186 1.8 macallan return -1; 1187 1.8 macallan } 1188 1.8 macallan if ((sc->sc_mode == WSDISPLAYIO_MODE_MAPPED) && 1189 1.18 macallan (offset >= MGX_BLTOFFSET) && (offset < MGX_BLTOFFSET + 0x1000)) { 1190 1.8 macallan return bus_space_mmap(sc->sc_tag, sc->sc_rpaddr, 1191 1.18 macallan offset - MGX_BLTOFFSET, prot, BUS_SPACE_MAP_LINEAR); 1192 1.8 macallan } 1193 1.1 macallan return -1; 1194 1.1 macallan } 1195 1.6 macallan 1196 1.6 macallan static int 1197 1.6 macallan mgx_do_cursor(struct mgx_softc *sc, struct wsdisplay_cursor *cur) 1198 1.6 macallan { 1199 1.6 macallan int i; 1200 1.6 macallan if (cur->which & WSDISPLAY_CURSOR_DOCUR) { 1201 1.6 macallan 1202 1.6 macallan if (cur->enable) { 1203 1.6 macallan mgx_set_cursor(sc); 1204 1.6 macallan mgx_write_1(sc, ATR_CURSOR_ENABLE, 1); 1205 1.6 macallan } else { 1206 1.6 macallan mgx_write_1(sc, ATR_CURSOR_ENABLE, 0); 1207 1.6 macallan } 1208 1.6 macallan } 1209 1.6 macallan if (cur->which & WSDISPLAY_CURSOR_DOHOT) { 1210 1.6 macallan 1211 1.6 macallan sc->sc_hotspot_x = cur->hot.x; 1212 1.6 macallan sc->sc_hotspot_y = cur->hot.y; 1213 1.6 macallan mgx_set_cursor(sc); 1214 1.6 macallan } 1215 1.6 macallan if (cur->which & WSDISPLAY_CURSOR_DOPOS) { 1216 1.6 macallan 1217 1.6 macallan sc->sc_cursor_x = cur->pos.x; 1218 1.6 macallan sc->sc_cursor_y = cur->pos.y; 1219 1.6 macallan mgx_set_cursor(sc); 1220 1.6 macallan } 1221 1.6 macallan if (cur->which & WSDISPLAY_CURSOR_DOCMAP) { 1222 1.14 riastrad int cnt = uimin(2, cur->cmap.count); 1223 1.6 macallan uint8_t c; 1224 1.6 macallan uint8_t r[2], g[2], b[2]; 1225 1.6 macallan 1226 1.6 macallan copyin(cur->cmap.red, r, cnt); 1227 1.6 macallan copyin(cur->cmap.green, g, cnt); 1228 1.6 macallan copyin(cur->cmap.blue, b, cnt); 1229 1.6 macallan 1230 1.6 macallan for (i = 0; i < cnt; i++) { 1231 1.6 macallan c = r[i] & 0xe0; 1232 1.6 macallan c |= (g[i] & 0xe0) >> 3; 1233 1.6 macallan c |= (b[i] & 0xc0) >> 6; 1234 1.6 macallan mgx_write_1(sc, ATR_CURSOR_FG + i, c); 1235 1.6 macallan } 1236 1.6 macallan } 1237 1.6 macallan if (cur->which & WSDISPLAY_CURSOR_DOSHAPE) { 1238 1.6 macallan int j; 1239 1.6 macallan uint8_t *fb = sc->sc_cursor; 1240 1.6 macallan uint8_t temp; 1241 1.6 macallan uint8_t im, ma, px; 1242 1.6 macallan 1243 1.6 macallan for (i = 0; i < 512; i++) { 1244 1.6 macallan temp = 0; 1245 1.6 macallan copyin(&cur->image[i], &im, 1); 1246 1.6 macallan copyin(&cur->mask[i], &ma, 1); 1247 1.6 macallan for (j = 0; j < 4; j++) { 1248 1.6 macallan temp >>= 2; 1249 1.6 macallan px = (ma & 1) ? 0 : 0x80; 1250 1.6 macallan if (px == 0) 1251 1.6 macallan px |= (im & 1) ? 0 : 0x40; 1252 1.6 macallan temp |= px; 1253 1.6 macallan im >>= 1; 1254 1.6 macallan ma >>= 1; 1255 1.6 macallan } 1256 1.6 macallan *fb = temp; 1257 1.6 macallan fb++; 1258 1.6 macallan temp = 0; 1259 1.6 macallan for (j = 0; j < 4; j++) { 1260 1.6 macallan temp >>= 2; 1261 1.6 macallan px = (ma & 1) ? 0 : 0x80; 1262 1.6 macallan if (px == 0) 1263 1.6 macallan px |= (im & 1) ? 0 : 0x40; 1264 1.6 macallan temp |= px; 1265 1.6 macallan im >>= 1; 1266 1.6 macallan ma >>= 1; 1267 1.6 macallan } 1268 1.6 macallan *fb = temp; 1269 1.6 macallan fb++; 1270 1.6 macallan } 1271 1.6 macallan } 1272 1.6 macallan return 0; 1273 1.6 macallan } 1274 1.6 macallan 1275 1.6 macallan static void 1276 1.6 macallan mgx_set_cursor(struct mgx_softc *sc) 1277 1.6 macallan { 1278 1.6 macallan uint32_t reg; 1279 1.6 macallan uint16_t hot; 1280 1.6 macallan 1281 1.6 macallan reg = (sc->sc_cursor_y << 16) | (sc->sc_cursor_x & 0xffff); 1282 1.6 macallan mgx_write_4(sc, ATR_CURSOR_POSITION, reg); 1283 1.6 macallan hot = (sc->sc_hotspot_y << 8) | (sc->sc_hotspot_x & 0xff); 1284 1.6 macallan mgx_write_2(sc, ATR_CURSOR_HOTSPOT, hot); 1285 1.6 macallan } 1286 1.6 macallan 1287 1.6 macallan static void 1288 1.6 macallan mgx_set_video(struct mgx_softc *sc, int v) 1289 1.6 macallan { 1290 1.6 macallan uint8_t reg; 1291 1.6 macallan 1292 1.6 macallan if (sc->sc_video == v) 1293 1.6 macallan return; 1294 1.6 macallan 1295 1.6 macallan sc->sc_video = v; 1296 1.6 macallan reg = mgx_read_1(sc, ATR_DPMS); 1297 1.6 macallan 1298 1.6 macallan if (v == WSDISPLAYIO_VIDEO_ON) { 1299 1.6 macallan reg &= ~DPMS_SYNC_DISABLE_ALL; 1300 1.6 macallan } else { 1301 1.6 macallan reg |= DPMS_SYNC_DISABLE_ALL; 1302 1.6 macallan } 1303 1.6 macallan mgx_write_1(sc, ATR_DPMS, reg); 1304 1.6 macallan } 1305 1.9 macallan 1306 1.9 macallan /* Sun fb dev goop */ 1307 1.9 macallan static void 1308 1.9 macallan mgx_unblank(device_t dev) 1309 1.9 macallan { 1310 1.9 macallan struct mgx_softc *sc = device_private(dev); 1311 1.9 macallan 1312 1.9 macallan mgx_set_video(sc, WSDISPLAYIO_VIDEO_ON); 1313 1.9 macallan } 1314 1.9 macallan 1315 1.9 macallan paddr_t 1316 1.9 macallan mgxmmap(dev_t dev, off_t offset, int prot) 1317 1.9 macallan { 1318 1.9 macallan struct mgx_softc *sc = device_lookup_private(&mgx_cd, minor(dev)); 1319 1.20 macallan uint32_t flags = BUS_SPACE_MAP_LINEAR; 1320 1.20 macallan 1321 1.20 macallan #ifdef BUS_SPACE_MAP_LITTLE 1322 1.20 macallan if (offset & MGX_FLIPOFFSET) { 1323 1.20 macallan offset &= ~MGX_FLIPOFFSET; 1324 1.20 macallan flags |= BUS_SPACE_MAP_LITTLE; 1325 1.20 macallan } 1326 1.20 macallan #endif 1327 1.9 macallan 1328 1.9 macallan /* regular fb mapping at 0 */ 1329 1.9 macallan if ((offset >= 0) && (offset < sc->sc_fbsize)) { 1330 1.9 macallan return bus_space_mmap(sc->sc_tag, sc->sc_paddr, 1331 1.20 macallan offset, prot, flags); 1332 1.9 macallan } 1333 1.9 macallan 1334 1.9 macallan /* 1335 1.18 macallan * Blitter registers at 0x00800000, only in mapped mode. 1336 1.9 macallan * Restrict to root, even though I'm fairly sure the DMA engine lives 1337 1.9 macallan * elsewhere ( and isn't documented anyway ) 1338 1.9 macallan */ 1339 1.9 macallan if (kauth_authorize_machdep(kauth_cred_get(), 1340 1.9 macallan KAUTH_MACHDEP_UNMANAGEDMEM, 1341 1.9 macallan NULL, NULL, NULL, NULL) != 0) { 1342 1.9 macallan aprint_normal("%s: mmap() rejected.\n", 1343 1.9 macallan device_xname(sc->sc_dev)); 1344 1.9 macallan return -1; 1345 1.9 macallan } 1346 1.9 macallan if ((sc->sc_mode == WSDISPLAYIO_MODE_MAPPED) && 1347 1.18 macallan (offset >= MGX_BLTOFFSET) && (offset < MGX_BLTOFFSET + 0x1000)) { 1348 1.9 macallan return bus_space_mmap(sc->sc_tag, sc->sc_rpaddr, 1349 1.18 macallan offset - MGX_BLTOFFSET, prot, BUS_SPACE_MAP_LINEAR); 1350 1.9 macallan } 1351 1.9 macallan return -1; 1352 1.9 macallan } 1353 1.9 macallan 1354 1.9 macallan int 1355 1.9 macallan mgxopen(dev_t dev, int flags, int mode, struct lwp *l) 1356 1.9 macallan { 1357 1.9 macallan device_t dv = device_lookup(&mgx_cd, minor(dev)); 1358 1.9 macallan struct mgx_softc *sc = device_private(dv); 1359 1.9 macallan 1360 1.9 macallan if (dv == NULL) 1361 1.9 macallan return ENXIO; 1362 1.9 macallan if (sc->sc_mode == WSDISPLAYIO_MODE_MAPPED) 1363 1.9 macallan return 0; 1364 1.9 macallan sc->sc_mode = WSDISPLAYIO_MODE_MAPPED; 1365 1.24 macallan mgx_setup(sc, MGX_X_DEPTH); 1366 1.9 macallan mgx_init_palette(sc); 1367 1.9 macallan return 0; 1368 1.9 macallan } 1369 1.9 macallan 1370 1.9 macallan int 1371 1.9 macallan mgxclose(dev_t dev, int flags, int mode, struct lwp *l) 1372 1.9 macallan { 1373 1.9 macallan device_t dv = device_lookup(&mgx_cd, minor(dev)); 1374 1.9 macallan struct mgx_softc *sc = device_private(dv); 1375 1.9 macallan struct vcons_screen *ms = sc->vd.active; 1376 1.9 macallan 1377 1.9 macallan if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) 1378 1.9 macallan return 0; 1379 1.9 macallan 1380 1.9 macallan sc->sc_mode = WSDISPLAYIO_MODE_EMUL; 1381 1.9 macallan 1382 1.9 macallan mgx_setup(sc, MGX_DEPTH); 1383 1.9 macallan glyphcache_wipe(&sc->sc_gc); 1384 1.9 macallan mgx_init_palette(sc); 1385 1.9 macallan if (ms != NULL) { 1386 1.9 macallan vcons_redraw_screen(ms); 1387 1.9 macallan } 1388 1.9 macallan return 0; 1389 1.9 macallan } 1390 1.9 macallan 1391 1.9 macallan int 1392 1.9 macallan mgxioctl(dev_t dev, u_long cmd, void *data, int flags, struct lwp *l) 1393 1.9 macallan { 1394 1.9 macallan struct mgx_softc *sc = device_lookup_private(&mgx_cd, minor(dev)); 1395 1.9 macallan 1396 1.9 macallan return mgx_ioctl(&sc->vd, NULL, cmd, data, flags, l); 1397 1.9 macallan } 1398