1 1.24 riastrad /* $NetBSD: hyperfb.c,v 1.24 2025/04/06 03:31:52 riastradh Exp $ */ 2 1.1 macallan 3 1.1 macallan /* 4 1.1 macallan * Copyright (c) 2024 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 AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 1.1 macallan * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 1.1 macallan * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 1.1 macallan * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, 20 1.1 macallan * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 1.1 macallan * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 1.1 macallan * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 1.1 macallan * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 24 1.1 macallan * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 25 1.1 macallan * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 26 1.1 macallan * THE POSSIBILITY OF SUCH DAMAGE. 27 1.1 macallan */ 28 1.7 riastrad 29 1.1 macallan /* 30 1.1 macallan * a native driver for HCRX / hyperdrive cards 31 1.4 macallan * tested on a HCRX24Z in a C360 only so far 32 1.1 macallan */ 33 1.1 macallan 34 1.1 macallan #include <sys/cdefs.h> 35 1.24 riastrad __KERNEL_RCSID(0, "$NetBSD: hyperfb.c,v 1.24 2025/04/06 03:31:52 riastradh Exp $"); 36 1.1 macallan 37 1.1 macallan #include "opt_cputype.h" 38 1.1 macallan #include "opt_hyperfb.h" 39 1.1 macallan 40 1.1 macallan #include <sys/param.h> 41 1.1 macallan #include <sys/systm.h> 42 1.1 macallan #include <sys/device.h> 43 1.1 macallan 44 1.1 macallan #include <sys/bus.h> 45 1.1 macallan #include <machine/iomod.h> 46 1.1 macallan #include <machine/autoconf.h> 47 1.1 macallan 48 1.1 macallan #include <dev/wscons/wsdisplayvar.h> 49 1.1 macallan #include <dev/wscons/wsconsio.h> 50 1.1 macallan #include <dev/wsfont/wsfont.h> 51 1.1 macallan #include <dev/rasops/rasops.h> 52 1.1 macallan #include <dev/wscons/wsdisplay_vconsvar.h> 53 1.1 macallan 54 1.1 macallan #include <dev/ic/stireg.h> 55 1.1 macallan #include <dev/ic/stivar.h> 56 1.1 macallan 57 1.1 macallan #include <hppa/dev/cpudevs.h> 58 1.1 macallan #include <hppa/hppa/machdep.h> 59 1.1 macallan 60 1.1 macallan #ifdef HYPERFB_DEBUG 61 1.1 macallan #define DPRINTF printf 62 1.1 macallan #else 63 1.1 macallan #define DPRINTF if (0) printf 64 1.1 macallan #endif 65 1.1 macallan 66 1.1 macallan #define STI_ROMSIZE (sizeof(struct sti_dd) * 4) 67 1.1 macallan 68 1.1 macallan #define HCRX_FBOFFSET 0x01000000 69 1.1 macallan #define HCRX_FBLEN 0x01000000 70 1.1 macallan #define HCRX_REGOFFSET 0x00100000 71 1.1 macallan #define HCRX_REGLEN 0x00280000 72 1.1 macallan 73 1.1 macallan #define HCRX_CONFIG_24BIT 0x100 74 1.1 macallan 75 1.1 macallan int hyperfb_match(device_t, cfdata_t, void *); 76 1.1 macallan void hyperfb_attach(device_t, device_t, void *); 77 1.1 macallan 78 1.1 macallan struct hyperfb_softc { 79 1.1 macallan device_t sc_dev; 80 1.1 macallan bus_space_tag_t sc_iot; 81 1.1 macallan bus_addr_t sc_base; 82 1.1 macallan bus_space_handle_t sc_hfb, sc_hreg; 83 1.1 macallan void *sc_fb; 84 1.1 macallan 85 1.1 macallan int sc_width, sc_height; 86 1.1 macallan int sc_locked, sc_is_console, sc_24bit; 87 1.1 macallan struct vcons_screen sc_console_screen; 88 1.1 macallan struct wsscreen_descr sc_defaultscreen_descr; 89 1.1 macallan const struct wsscreen_descr *sc_screens[1]; 90 1.1 macallan struct wsscreen_list sc_screenlist; 91 1.1 macallan struct vcons_data vd; 92 1.1 macallan int sc_mode; 93 1.1 macallan u_char sc_cmap_red[256]; 94 1.1 macallan u_char sc_cmap_green[256]; 95 1.1 macallan u_char sc_cmap_blue[256]; 96 1.1 macallan kmutex_t sc_hwlock; 97 1.1 macallan uint32_t sc_hwmode; 98 1.6 macallan #define HW_FB 0 99 1.6 macallan #define HW_FILL 1 100 1.6 macallan #define HW_BLIT 2 101 1.1 macallan /* cursor stuff */ 102 1.1 macallan int sc_cursor_x, sc_cursor_y; 103 1.1 macallan int sc_hot_x, sc_hot_y, sc_enabled; 104 1.1 macallan int sc_video_on; 105 1.1 macallan }; 106 1.1 macallan 107 1.1 macallan extern struct cfdriver hyperfb_cd; 108 1.1 macallan 109 1.1 macallan CFATTACH_DECL_NEW(hyperfb, sizeof(struct hyperfb_softc), hyperfb_match, 110 1.1 macallan hyperfb_attach, NULL, NULL); 111 1.1 macallan 112 1.5 macallan static inline void hyperfb_setup_fb(struct hyperfb_softc *); 113 1.5 macallan static inline void hyperfb_setup_fb24(struct hyperfb_softc *); 114 1.1 macallan static void hyperfb_init_screen(void *, struct vcons_screen *, 115 1.1 macallan int, long *); 116 1.1 macallan static int hyperfb_ioctl(void *, void *, u_long, void *, int, 117 1.1 macallan struct lwp *); 118 1.1 macallan static paddr_t hyperfb_mmap(void *, void *, off_t, int); 119 1.1 macallan 120 1.7 riastrad static int hyperfb_putcmap(struct hyperfb_softc *, 121 1.7 riastrad struct wsdisplay_cmap *); 122 1.7 riastrad static int hyperfb_getcmap(struct hyperfb_softc *, 123 1.7 riastrad struct wsdisplay_cmap *); 124 1.1 macallan static void hyperfb_restore_palette(struct hyperfb_softc *); 125 1.1 macallan static int hyperfb_putpalreg(struct hyperfb_softc *, uint8_t, uint8_t, 126 1.1 macallan uint8_t, uint8_t); 127 1.1 macallan void hyperfb_setup(struct hyperfb_softc *); 128 1.1 macallan static void hyperfb_set_video(struct hyperfb_softc *, int); 129 1.1 macallan 130 1.2 macallan static void hyperfb_rectfill(struct hyperfb_softc *, int, int, int, int, 131 1.2 macallan uint32_t); 132 1.2 macallan static void hyperfb_bitblt(void *, int, int, int, int, int, 133 1.2 macallan int, int); 134 1.2 macallan 135 1.2 macallan static void hyperfb_cursor(void *, int, int, int); 136 1.2 macallan static void hyperfb_putchar(void *, int, int, u_int, long); 137 1.2 macallan static void hyperfb_copycols(void *, int, int, int, int); 138 1.2 macallan static void hyperfb_erasecols(void *, int, int, int, long); 139 1.2 macallan static void hyperfb_copyrows(void *, int, int, int); 140 1.2 macallan static void hyperfb_eraserows(void *, int, int, long); 141 1.2 macallan 142 1.2 macallan static void hyperfb_move_cursor(struct hyperfb_softc *, int, int); 143 1.7 riastrad static int hyperfb_do_cursor(struct hyperfb_softc *, 144 1.7 riastrad struct wsdisplay_cursor *); 145 1.2 macallan 146 1.2 macallan static inline void hyperfb_wait_fifo(struct hyperfb_softc *, uint32_t); 147 1.2 macallan 148 1.1 macallan struct wsdisplay_accessops hyperfb_accessops = { 149 1.1 macallan hyperfb_ioctl, 150 1.1 macallan hyperfb_mmap, 151 1.1 macallan NULL, /* alloc_screen */ 152 1.1 macallan NULL, /* free_screen */ 153 1.1 macallan NULL, /* show_screen */ 154 1.1 macallan NULL, /* load_font */ 155 1.1 macallan NULL, /* pollc */ 156 1.1 macallan NULL /* scroll */ 157 1.1 macallan }; 158 1.1 macallan 159 1.1 macallan static inline uint32_t 160 1.1 macallan hyperfb_read4(struct hyperfb_softc *sc, uint32_t offset) 161 1.1 macallan { 162 1.1 macallan return bus_space_read_4(sc->sc_iot, sc->sc_hreg, offset); 163 1.1 macallan } 164 1.1 macallan 165 1.1 macallan static inline uint8_t 166 1.1 macallan hyperfb_read1(struct hyperfb_softc *sc, uint32_t offset) 167 1.1 macallan { 168 1.1 macallan return bus_space_read_1(sc->sc_iot, sc->sc_hreg, offset); 169 1.1 macallan } 170 1.1 macallan 171 1.1 macallan static inline void 172 1.1 macallan hyperfb_write4(struct hyperfb_softc *sc, uint32_t offset, uint32_t val) 173 1.1 macallan { 174 1.1 macallan bus_space_write_4(sc->sc_iot, sc->sc_hreg, offset, val); 175 1.1 macallan } 176 1.1 macallan 177 1.1 macallan static inline void 178 1.1 macallan hyperfb_write1(struct hyperfb_softc *sc, uint32_t offset, uint8_t val) 179 1.1 macallan { 180 1.1 macallan bus_space_write_1(sc->sc_iot, sc->sc_hreg, offset, val); 181 1.1 macallan } 182 1.1 macallan 183 1.1 macallan static inline void 184 1.1 macallan hyperfb_wait(struct hyperfb_softc *sc) 185 1.1 macallan { 186 1.1 macallan uint8_t stat; 187 1.1 macallan 188 1.1 macallan do { 189 1.1 macallan stat = hyperfb_read1(sc, NGLE_REG_15b0); 190 1.1 macallan if (stat == 0) 191 1.1 macallan stat = hyperfb_read1(sc, NGLE_REG_15b0); 192 1.1 macallan } while (stat != 0); 193 1.1 macallan } 194 1.1 macallan 195 1.2 macallan static inline void 196 1.2 macallan hyperfb_wait_fifo(struct hyperfb_softc *sc, uint32_t slots) 197 1.2 macallan { 198 1.2 macallan uint32_t reg; 199 1.2 macallan 200 1.2 macallan do { 201 1.2 macallan reg = hyperfb_read4(sc, NGLE_REG_34); 202 1.2 macallan } while (reg < slots); 203 1.2 macallan } 204 1.2 macallan 205 1.5 macallan static inline void 206 1.1 macallan hyperfb_setup_fb(struct hyperfb_softc *sc) 207 1.1 macallan { 208 1.1 macallan 209 1.6 macallan /* 210 1.6 macallan * turns out the plane mask is applied to everything, including 211 1.6 macallan * direct framebuffer writes, so make sure we always set it 212 1.6 macallan */ 213 1.1 macallan hyperfb_wait(sc); 214 1.5 macallan if ((sc->sc_mode != WSDISPLAYIO_MODE_EMUL) && sc->sc_24bit) { 215 1.11 riastrad hyperfb_write4(sc, NGLE_REG_10, 216 1.10 macallan BA(FractDcd, Otc24, Ots08, AddrLong, 0, BINapp0F8, 0)); 217 1.5 macallan hyperfb_write4(sc, NGLE_REG_13, 0xffffffff); 218 1.6 macallan } else { 219 1.11 riastrad hyperfb_write4(sc, NGLE_REG_10, 220 1.10 macallan BA(IndexedDcd, Otc04, Ots08, AddrByte, 0, BINovly, 0)); 221 1.6 macallan hyperfb_write4(sc, NGLE_REG_13, 0xff); 222 1.6 macallan } 223 1.5 macallan hyperfb_write4(sc, NGLE_REG_14, 0x83000300); 224 1.5 macallan hyperfb_wait(sc); 225 1.5 macallan hyperfb_write1(sc, NGLE_REG_16b1, 1); 226 1.5 macallan sc->sc_hwmode = HW_FB; 227 1.5 macallan } 228 1.5 macallan 229 1.5 macallan static inline void 230 1.5 macallan hyperfb_setup_fb24(struct hyperfb_softc *sc) 231 1.5 macallan { 232 1.5 macallan 233 1.5 macallan hyperfb_wait(sc); 234 1.11 riastrad hyperfb_write4(sc, NGLE_REG_10, 235 1.10 macallan BA(FractDcd, Otc24, Ots08, AddrLong, 0, BINapp0F8, 0)); 236 1.5 macallan hyperfb_write4(sc, NGLE_REG_13, 0xffffffff); 237 1.1 macallan hyperfb_write4(sc, NGLE_REG_14, 0x83000300); 238 1.5 macallan //IBOvals(RopSrc,0,BitmapExtent08,0,DataDynamic,MaskDynamic,0,0) 239 1.1 macallan hyperfb_wait(sc); 240 1.1 macallan hyperfb_write1(sc, NGLE_REG_16b1, 1); 241 1.1 macallan sc->sc_hwmode = HW_FB; 242 1.1 macallan } 243 1.1 macallan 244 1.1 macallan int 245 1.1 macallan hyperfb_match(device_t parent, cfdata_t cf, void *aux) 246 1.1 macallan { 247 1.1 macallan struct confargs *ca = aux; 248 1.1 macallan bus_space_handle_t romh; 249 1.1 macallan paddr_t rom; 250 1.1 macallan uint32_t id = 0; 251 1.1 macallan u_char devtype; 252 1.1 macallan int rv = 0, romunmapped = 0; 253 1.1 macallan 254 1.1 macallan if (ca->ca_type.iodc_type != HPPA_TYPE_FIO) 255 1.1 macallan return 0; 256 1.1 macallan 257 1.1 macallan /* these need further checking for the graphics id */ 258 1.1 macallan if (ca->ca_type.iodc_sv_model != HPPA_FIO_GSGC && 259 1.1 macallan ca->ca_type.iodc_sv_model != HPPA_FIO_SGC) 260 1.1 macallan return 0; 261 1.1 macallan 262 1.1 macallan if (ca->ca_naddrs > 0) 263 1.1 macallan rom = ca->ca_addrs[0].addr; 264 1.1 macallan else 265 1.1 macallan rom = ca->ca_hpa; 266 1.1 macallan 267 1.1 macallan DPRINTF("%s: hpa=%x, rom=%x\n", __func__, (uint)ca->ca_hpa, 268 1.1 macallan (uint)rom); 269 1.1 macallan 270 1.1 macallan /* if it does not map, probably part of the lasi space */ 271 1.1 macallan if (bus_space_map(ca->ca_iot, rom, STI_ROMSIZE, 0, &romh)) { 272 1.1 macallan DPRINTF("%s: can't map rom space (%d)\n", __func__, rv); 273 1.1 macallan 274 1.1 macallan if ((rom & HPPA_IOBEGIN) == HPPA_IOBEGIN) { 275 1.1 macallan romh = rom; 276 1.1 macallan romunmapped++; 277 1.1 macallan } else { 278 1.1 macallan /* in this case nobody has no freaking idea */ 279 1.1 macallan return 0; 280 1.1 macallan } 281 1.1 macallan } 282 1.1 macallan 283 1.1 macallan devtype = bus_space_read_1(ca->ca_iot, romh, 3); 284 1.1 macallan DPRINTF("%s: devtype=%d\n", __func__, devtype); 285 1.1 macallan rv = 1; 286 1.1 macallan switch (devtype) { 287 1.1 macallan case STI_DEVTYPE4: 288 1.1 macallan id = bus_space_read_4(ca->ca_iot, romh, STI_DEV4_DD_GRID); 289 1.1 macallan break; 290 1.1 macallan case STI_DEVTYPE1: 291 1.1 macallan id = (bus_space_read_1(ca->ca_iot, romh, STI_DEV1_DD_GRID 292 1.1 macallan + 3) << 24) | 293 1.1 macallan (bus_space_read_1(ca->ca_iot, romh, STI_DEV1_DD_GRID 294 1.1 macallan + 7) << 16) | 295 1.1 macallan (bus_space_read_1(ca->ca_iot, romh, STI_DEV1_DD_GRID 296 1.1 macallan + 11) << 8) | 297 1.1 macallan (bus_space_read_1(ca->ca_iot, romh, STI_DEV1_DD_GRID 298 1.1 macallan + 15)); 299 1.1 macallan break; 300 1.1 macallan default: 301 1.1 macallan DPRINTF("%s: unknown type (%x)\n", __func__, devtype); 302 1.1 macallan rv = 0; 303 1.1 macallan } 304 1.1 macallan 305 1.1 macallan if (id == STI_DD_HCRX) 306 1.1 macallan rv = 100; /* beat out sti */ 307 1.1 macallan 308 1.1 macallan ca->ca_addrs[ca->ca_naddrs].addr = rom; 309 1.1 macallan ca->ca_addrs[ca->ca_naddrs].size = sti_rom_size(ca->ca_iot, romh); 310 1.1 macallan ca->ca_naddrs++; 311 1.1 macallan 312 1.1 macallan if (!romunmapped) 313 1.1 macallan bus_space_unmap(ca->ca_iot, romh, STI_ROMSIZE); 314 1.1 macallan return rv; 315 1.1 macallan } 316 1.1 macallan 317 1.1 macallan void 318 1.1 macallan hyperfb_attach(device_t parent, device_t self, void *aux) 319 1.1 macallan { 320 1.1 macallan struct hyperfb_softc *sc = device_private(self); 321 1.1 macallan struct confargs *ca = aux; 322 1.1 macallan struct rasops_info *ri; 323 1.1 macallan struct wsemuldisplaydev_attach_args aa; 324 1.1 macallan bus_space_handle_t hrom; 325 1.1 macallan hppa_hpa_t consaddr; 326 1.1 macallan long defattr; 327 1.1 macallan int pagezero_cookie; 328 1.1 macallan paddr_t rom; 329 1.1 macallan uint32_t config; 330 1.1 macallan 331 1.1 macallan pagezero_cookie = hppa_pagezero_map(); 332 1.1 macallan consaddr = (hppa_hpa_t)PAGE0->mem_cons.pz_hpa; 333 1.1 macallan hppa_pagezero_unmap(pagezero_cookie); 334 1.1 macallan 335 1.1 macallan sc->sc_dev = self; 336 1.1 macallan sc->sc_base = ca->ca_hpa; 337 1.1 macallan sc->sc_iot = ca->ca_iot; 338 1.1 macallan sc->sc_is_console =(ca->ca_hpa == consaddr); 339 1.1 macallan sc->sc_width = 1280; 340 1.1 macallan sc->sc_height = 1024; 341 1.7 riastrad 342 1.1 macallan /* we can *not* be interrupted when doing colour map accesses */ 343 1.1 macallan mutex_init(&sc->sc_hwlock, MUTEX_DEFAULT, IPL_HIGH); 344 1.1 macallan 345 1.1 macallan /* we stashed rom addr/len into the last slot during probe */ 346 1.1 macallan rom = ca->ca_addrs[ca->ca_naddrs - 1].addr; 347 1.1 macallan 348 1.1 macallan if (bus_space_map(sc->sc_iot, 349 1.1 macallan sc->sc_base + HCRX_FBOFFSET, HCRX_FBLEN, 350 1.1 macallan BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_PREFETCHABLE, 351 1.1 macallan &sc->sc_hfb)) { 352 1.7 riastrad aprint_error_dev(sc->sc_dev, 353 1.7 riastrad "failed to map the framebuffer\n"); 354 1.1 macallan return; 355 1.1 macallan } 356 1.1 macallan sc->sc_fb = bus_space_vaddr(sc->sc_iot, sc->sc_hfb); 357 1.1 macallan 358 1.1 macallan if (bus_space_map(sc->sc_iot, 359 1.1 macallan sc->sc_base + HCRX_REGOFFSET, HCRX_REGLEN, 0, &sc->sc_hreg)) { 360 1.1 macallan aprint_error_dev(sc->sc_dev, "failed to map registers\n"); 361 1.1 macallan return; 362 1.1 macallan } 363 1.1 macallan 364 1.1 macallan /* 365 1.1 macallan * we really only need the first word so we can grab the config bits 366 1.1 macallan * between the bytes 367 1.1 macallan */ 368 1.7 riastrad if (bus_space_map(sc->sc_iot, rom, 4, 0, &hrom)) { 369 1.7 riastrad aprint_error_dev(sc->sc_dev, 370 1.7 riastrad "failed to map ROM, assuming 8bit\n"); 371 1.1 macallan config = 0; 372 1.1 macallan } else { 373 1.1 macallan /* alright, we got the ROM. now do the idle dance. */ 374 1.1 macallan volatile uint32_t r = hyperfb_read4(sc, NGLE_REG_15); 375 1.1 macallan __USE(r); 376 1.1 macallan hyperfb_wait(sc); 377 1.1 macallan config = bus_space_read_4(sc->sc_iot, hrom, 0); 378 1.1 macallan bus_space_unmap(sc->sc_iot, hrom, 4); 379 1.1 macallan } 380 1.1 macallan sc->sc_24bit = ((config & HCRX_CONFIG_24BIT) != 0); 381 1.1 macallan 382 1.1 macallan printf(" %s\n", sc->sc_24bit ? "HCRX24" : "HCRX"); 383 1.1 macallan #ifdef HP7300LC_CPU 384 1.1 macallan /* 385 1.1 macallan * PCXL2: enable accel I/O for this space, see PCX-L2 ERS "ACCEL_IO". 386 1.1 macallan * "pcxl2_ers.{ps,pdf}", (section / chapter . rel. page / abs. page) 387 1.1 macallan * 8.7.4 / 8-12 / 92, 11.3.14 / 11-14 / 122 and 14.8 / 14-5 / 203. 388 1.1 macallan */ 389 1.1 macallan if (hppa_cpu_info->hci_cputype == hpcxl2 390 1.1 macallan && ca->ca_hpa >= PCXL2_ACCEL_IO_START 391 1.1 macallan && ca->ca_hpa <= PCXL2_ACCEL_IO_END) 392 1.1 macallan eaio_l2(PCXL2_ACCEL_IO_ADDR2MASK(ca->ca_hpa)); 393 1.1 macallan #endif /* HP7300LC_CPU */ 394 1.1 macallan 395 1.5 macallan sc->sc_mode = WSDISPLAYIO_MODE_EMUL; 396 1.5 macallan sc->sc_locked = 0; 397 1.5 macallan 398 1.1 macallan hyperfb_setup(sc); 399 1.1 macallan hyperfb_setup_fb(sc); 400 1.1 macallan 401 1.1 macallan sc->sc_defaultscreen_descr = (struct wsscreen_descr){ 402 1.1 macallan "default", 403 1.1 macallan 0, 0, 404 1.1 macallan NULL, 405 1.1 macallan 8, 16, 406 1.1 macallan WSSCREEN_WSCOLORS | WSSCREEN_HILIT | WSSCREEN_UNDERLINE | 407 1.1 macallan WSSCREEN_RESIZE, 408 1.1 macallan NULL 409 1.1 macallan }; 410 1.1 macallan 411 1.1 macallan sc->sc_screens[0] = &sc->sc_defaultscreen_descr; 412 1.1 macallan sc->sc_screenlist = (struct wsscreen_list){1, sc->sc_screens}; 413 1.1 macallan 414 1.1 macallan vcons_init(&sc->vd, sc, &sc->sc_defaultscreen_descr, 415 1.1 macallan &hyperfb_accessops); 416 1.1 macallan sc->vd.init_screen = hyperfb_init_screen; 417 1.1 macallan 418 1.1 macallan ri = &sc->sc_console_screen.scr_ri; 419 1.1 macallan 420 1.19 macallan vcons_init_screen(&sc->vd, &sc->sc_console_screen, 1, &defattr); 421 1.19 macallan sc->sc_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC; 422 1.19 macallan 423 1.19 macallan sc->sc_defaultscreen_descr.textops = &ri->ri_ops; 424 1.19 macallan sc->sc_defaultscreen_descr.capabilities = ri->ri_caps; 425 1.19 macallan sc->sc_defaultscreen_descr.nrows = ri->ri_rows; 426 1.19 macallan sc->sc_defaultscreen_descr.ncols = ri->ri_cols; 427 1.1 macallan 428 1.19 macallan hyperfb_rectfill(sc, 0, 0, sc->sc_width, sc->sc_height, 429 1.19 macallan ri->ri_devcmap[(defattr >> 16) & 0xff]); 430 1.19 macallan hyperfb_restore_palette(sc); 431 1.19 macallan 432 1.19 macallan if (sc->sc_is_console) { 433 1.19 macallan 434 1.1 macallan wsdisplay_cnattach(&sc->sc_defaultscreen_descr, ri, 0, 0, 435 1.1 macallan defattr); 436 1.1 macallan vcons_replay_msgbuf(&sc->sc_console_screen); 437 1.1 macallan } 438 1.1 macallan 439 1.1 macallan /* no suspend/resume support yet */ 440 1.1 macallan if (!pmf_device_register(sc->sc_dev, NULL, NULL)) 441 1.1 macallan aprint_error_dev(sc->sc_dev, 442 1.1 macallan "couldn't establish power handler\n"); 443 1.1 macallan 444 1.1 macallan aa.console = sc->sc_is_console; 445 1.1 macallan aa.scrdata = &sc->sc_screenlist; 446 1.1 macallan aa.accessops = &hyperfb_accessops; 447 1.1 macallan aa.accesscookie = &sc->vd; 448 1.1 macallan 449 1.1 macallan config_found(sc->sc_dev, &aa, wsemuldisplaydevprint, CFARGS_NONE); 450 1.1 macallan 451 1.5 macallan hyperfb_setup_fb(sc); 452 1.1 macallan } 453 1.1 macallan 454 1.1 macallan static void 455 1.1 macallan hyperfb_init_screen(void *cookie, struct vcons_screen *scr, 456 1.1 macallan int existing, long *defattr) 457 1.1 macallan { 458 1.1 macallan struct hyperfb_softc *sc = cookie; 459 1.1 macallan struct rasops_info *ri = &scr->scr_ri; 460 1.1 macallan 461 1.1 macallan ri->ri_depth = 8; 462 1.1 macallan ri->ri_width = 1280; 463 1.14 macallan #ifdef HYPERFB_DEBUG 464 1.14 macallan ri->ri_height = 900; 465 1.14 macallan #else 466 1.1 macallan ri->ri_height = 1024; 467 1.14 macallan #endif 468 1.1 macallan ri->ri_stride = 2048; 469 1.7 riastrad ri->ri_flg = RI_CENTER | RI_8BIT_IS_RGB /*| 470 1.1 macallan RI_ENABLE_ALPHA | RI_PREFER_ALPHA*/; 471 1.1 macallan 472 1.1 macallan ri->ri_bits = (void *)sc->sc_fb; 473 1.1 macallan rasops_init(ri, 0, 0); 474 1.1 macallan ri->ri_caps = WSSCREEN_WSCOLORS | WSSCREEN_HILIT | WSSCREEN_UNDERLINE | 475 1.1 macallan WSSCREEN_RESIZE; 476 1.2 macallan scr->scr_flags |= VCONS_LOADFONT; 477 1.1 macallan 478 1.1 macallan rasops_reconfig(ri, sc->sc_height / ri->ri_font->fontheight, 479 1.1 macallan sc->sc_width / ri->ri_font->fontwidth); 480 1.1 macallan 481 1.1 macallan ri->ri_hw = scr; 482 1.2 macallan 483 1.2 macallan ri->ri_ops.copyrows = hyperfb_copyrows; 484 1.2 macallan ri->ri_ops.copycols = hyperfb_copycols; 485 1.2 macallan ri->ri_ops.eraserows = hyperfb_eraserows; 486 1.2 macallan ri->ri_ops.erasecols = hyperfb_erasecols; 487 1.2 macallan ri->ri_ops.cursor = hyperfb_cursor; 488 1.2 macallan ri->ri_ops.putchar = hyperfb_putchar; 489 1.1 macallan } 490 1.1 macallan 491 1.1 macallan static int 492 1.1 macallan hyperfb_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, 493 1.7 riastrad struct lwp *l) 494 1.1 macallan { 495 1.1 macallan struct vcons_data *vd = v; 496 1.1 macallan struct hyperfb_softc *sc = vd->cookie; 497 1.1 macallan struct wsdisplay_fbinfo *wdf; 498 1.1 macallan struct vcons_screen *ms = vd->active; 499 1.1 macallan 500 1.1 macallan switch (cmd) { 501 1.1 macallan case WSDISPLAYIO_GTYPE: 502 1.1 macallan *(u_int *)data = WSDISPLAY_TYPE_STI; 503 1.1 macallan return 0; 504 1.1 macallan 505 1.12 macallan case GCID: 506 1.12 macallan *(u_int *)data = STI_DD_HCRX; 507 1.12 macallan return 0; 508 1.12 macallan 509 1.1 macallan case WSDISPLAYIO_GINFO: 510 1.1 macallan if (ms == NULL) 511 1.1 macallan return ENODEV; 512 1.1 macallan wdf = (void *)data; 513 1.1 macallan wdf->height = ms->scr_ri.ri_height; 514 1.7 riastrad wdf->width = sc->sc_24bit ? ms->scr_ri.ri_width << 2 515 1.7 riastrad : ms->scr_ri.ri_width; 516 1.1 macallan wdf->depth = ms->scr_ri.ri_depth; 517 1.1 macallan wdf->cmsize = 256; 518 1.1 macallan return 0; 519 1.1 macallan 520 1.1 macallan case WSDISPLAYIO_GETCMAP: 521 1.1 macallan return hyperfb_getcmap(sc, 522 1.1 macallan (struct wsdisplay_cmap *)data); 523 1.1 macallan 524 1.1 macallan case WSDISPLAYIO_PUTCMAP: 525 1.1 macallan return hyperfb_putcmap(sc, 526 1.1 macallan (struct wsdisplay_cmap *)data); 527 1.1 macallan case WSDISPLAYIO_LINEBYTES: 528 1.5 macallan *(u_int *)data = sc->sc_24bit ? 8192 : 2048; 529 1.1 macallan return 0; 530 1.1 macallan 531 1.1 macallan case WSDISPLAYIO_SMODE: { 532 1.1 macallan int new_mode = *(int*)data; 533 1.1 macallan if (new_mode != sc->sc_mode) { 534 1.1 macallan sc->sc_mode = new_mode; 535 1.7 riastrad if (new_mode == WSDISPLAYIO_MODE_EMUL) { 536 1.1 macallan hyperfb_setup(sc); 537 1.1 macallan hyperfb_restore_palette(sc); 538 1.1 macallan hyperfb_rectfill(sc, 0, 0, sc->sc_width, 539 1.1 macallan sc->sc_height, ms->scr_ri.ri_devcmap[ 540 1.1 macallan (ms->scr_defattr >> 16) & 0xff]); 541 1.1 macallan vcons_redraw_screen(ms); 542 1.1 macallan hyperfb_set_video(sc, 1); 543 1.5 macallan } else { 544 1.5 macallan hyperfb_setup(sc); 545 1.5 macallan hyperfb_rectfill(sc, 0, 0, sc->sc_width, 546 1.5 macallan sc->sc_height, 0xff); 547 1.5 macallan hyperfb_setup_fb24(sc); 548 1.1 macallan } 549 1.1 macallan } 550 1.1 macallan } 551 1.1 macallan return 0; 552 1.1 macallan 553 1.7 riastrad case WSDISPLAYIO_GET_FBINFO: { 554 1.7 riastrad struct wsdisplayio_fbinfo *fbi = data; 555 1.7 riastrad int ret; 556 1.7 riastrad 557 1.7 riastrad ret = wsdisplayio_get_fbinfo(&ms->scr_ri, fbi); 558 1.7 riastrad fbi->fbi_fbsize = sc->sc_height * 2048; 559 1.7 riastrad if (sc->sc_24bit) { 560 1.7 riastrad fbi->fbi_stride = 8192; 561 1.7 riastrad fbi->fbi_bitsperpixel = 32; 562 1.7 riastrad fbi->fbi_pixeltype = WSFB_RGB; 563 1.7 riastrad fbi->fbi_subtype.fbi_rgbmasks.red_offset = 16; 564 1.7 riastrad fbi->fbi_subtype.fbi_rgbmasks.red_size = 8; 565 1.7 riastrad fbi->fbi_subtype.fbi_rgbmasks.green_offset = 8; 566 1.7 riastrad fbi->fbi_subtype.fbi_rgbmasks.green_size = 8; 567 1.7 riastrad fbi->fbi_subtype.fbi_rgbmasks.blue_offset = 0; 568 1.7 riastrad fbi->fbi_subtype.fbi_rgbmasks.blue_size = 8; 569 1.7 riastrad fbi->fbi_subtype.fbi_rgbmasks.alpha_size = 0; 570 1.5 macallan fbi->fbi_fbsize = sc->sc_height * 8192; 571 1.1 macallan } 572 1.7 riastrad return ret; 573 1.7 riastrad } 574 1.1 macallan 575 1.7 riastrad case WSDISPLAYIO_GCURPOS: { 576 1.7 riastrad struct wsdisplay_curpos *cp = (void *)data; 577 1.1 macallan 578 1.7 riastrad cp->x = sc->sc_cursor_x; 579 1.7 riastrad cp->y = sc->sc_cursor_y; 580 1.7 riastrad } 581 1.1 macallan return 0; 582 1.1 macallan 583 1.7 riastrad case WSDISPLAYIO_SCURPOS: { 584 1.7 riastrad struct wsdisplay_curpos *cp = (void *)data; 585 1.1 macallan 586 1.7 riastrad hyperfb_move_cursor(sc, cp->x, cp->y); 587 1.7 riastrad } 588 1.1 macallan return 0; 589 1.1 macallan 590 1.7 riastrad case WSDISPLAYIO_GCURMAX: { 591 1.7 riastrad struct wsdisplay_curpos *cp = (void *)data; 592 1.1 macallan 593 1.7 riastrad cp->x = 64; 594 1.7 riastrad cp->y = 64; 595 1.7 riastrad } 596 1.1 macallan return 0; 597 1.1 macallan 598 1.7 riastrad case WSDISPLAYIO_SCURSOR: { 599 1.7 riastrad struct wsdisplay_cursor *cursor = (void *)data; 600 1.1 macallan 601 1.7 riastrad return hyperfb_do_cursor(sc, cursor); 602 1.7 riastrad } 603 1.1 macallan 604 1.1 macallan case WSDISPLAYIO_SVIDEO: 605 1.1 macallan hyperfb_set_video(sc, *(int *)data); 606 1.1 macallan return 0; 607 1.1 macallan case WSDISPLAYIO_GVIDEO: 608 1.13 macallan *(u_int *)data = sc->sc_video_on ? 609 1.1 macallan WSDISPLAYIO_VIDEO_ON : WSDISPLAYIO_VIDEO_OFF; 610 1.13 macallan return 0; 611 1.1 macallan } 612 1.1 macallan return EPASSTHROUGH; 613 1.1 macallan } 614 1.1 macallan 615 1.1 macallan static paddr_t 616 1.1 macallan hyperfb_mmap(void *v, void *vs, off_t offset, int prot) 617 1.1 macallan { 618 1.1 macallan struct vcons_data *vd = v; 619 1.1 macallan struct hyperfb_softc *sc = vd->cookie; 620 1.1 macallan paddr_t pa = -1; 621 1.1 macallan 622 1.1 macallan 623 1.1 macallan if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) 624 1.1 macallan return -1; 625 1.1 macallan 626 1.8 macallan /* GSC framebuffer space is 16MB */ 627 1.8 macallan if (offset >= 0 && offset < 0x1000000) { 628 1.1 macallan /* framebuffer */ 629 1.7 riastrad pa = bus_space_mmap(sc->sc_iot, sc->sc_base + HCRX_FBOFFSET, 630 1.7 riastrad offset, prot, 631 1.7 riastrad BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_PREFETCHABLE); 632 1.18 macallan } else if (offset >= 0x80000000 && offset < 0x80400000) { 633 1.1 macallan /* blitter registers etc. */ 634 1.1 macallan pa = bus_space_mmap(sc->sc_iot, sc->sc_base + HCRX_REGOFFSET, 635 1.1 macallan offset - 0x80000000, prot, BUS_SPACE_MAP_LINEAR); 636 1.1 macallan } 637 1.1 macallan 638 1.1 macallan return pa; 639 1.1 macallan } 640 1.1 macallan 641 1.1 macallan static int 642 1.1 macallan hyperfb_putcmap(struct hyperfb_softc *sc, struct wsdisplay_cmap *cm) 643 1.1 macallan { 644 1.1 macallan u_char *r, *g, *b; 645 1.1 macallan u_int index = cm->index; 646 1.1 macallan u_int count = cm->count; 647 1.1 macallan int i, error; 648 1.1 macallan u_char rbuf[256], gbuf[256], bbuf[256]; 649 1.1 macallan 650 1.1 macallan if (cm->index >= 256 || cm->count > 256 || 651 1.1 macallan (cm->index + cm->count) > 256) 652 1.1 macallan return EINVAL; 653 1.1 macallan error = copyin(cm->red, &rbuf[index], count); 654 1.1 macallan if (error) 655 1.1 macallan return error; 656 1.1 macallan error = copyin(cm->green, &gbuf[index], count); 657 1.1 macallan if (error) 658 1.1 macallan return error; 659 1.1 macallan error = copyin(cm->blue, &bbuf[index], count); 660 1.1 macallan if (error) 661 1.1 macallan return error; 662 1.1 macallan 663 1.1 macallan memcpy(&sc->sc_cmap_red[index], &rbuf[index], count); 664 1.1 macallan memcpy(&sc->sc_cmap_green[index], &gbuf[index], count); 665 1.1 macallan memcpy(&sc->sc_cmap_blue[index], &bbuf[index], count); 666 1.1 macallan 667 1.1 macallan r = &sc->sc_cmap_red[index]; 668 1.1 macallan g = &sc->sc_cmap_green[index]; 669 1.1 macallan b = &sc->sc_cmap_blue[index]; 670 1.1 macallan 671 1.1 macallan for (i = 0; i < count; i++) { 672 1.1 macallan hyperfb_putpalreg(sc, index, *r, *g, *b); 673 1.1 macallan index++; 674 1.1 macallan r++, g++, b++; 675 1.1 macallan } 676 1.1 macallan return 0; 677 1.1 macallan } 678 1.1 macallan 679 1.1 macallan static int 680 1.1 macallan hyperfb_getcmap(struct hyperfb_softc *sc, struct wsdisplay_cmap *cm) 681 1.1 macallan { 682 1.1 macallan u_int index = cm->index; 683 1.1 macallan u_int count = cm->count; 684 1.1 macallan int error; 685 1.1 macallan 686 1.1 macallan if (index >= 255 || count > 256 || index + count > 256) 687 1.1 macallan return EINVAL; 688 1.1 macallan 689 1.1 macallan error = copyout(&sc->sc_cmap_red[index], cm->red, count); 690 1.1 macallan if (error) 691 1.1 macallan return error; 692 1.1 macallan error = copyout(&sc->sc_cmap_green[index], cm->green, count); 693 1.1 macallan if (error) 694 1.1 macallan return error; 695 1.1 macallan error = copyout(&sc->sc_cmap_blue[index], cm->blue, count); 696 1.1 macallan if (error) 697 1.1 macallan return error; 698 1.1 macallan 699 1.1 macallan return 0; 700 1.1 macallan } 701 1.1 macallan 702 1.1 macallan static void 703 1.1 macallan hyperfb_restore_palette(struct hyperfb_softc *sc) 704 1.1 macallan { 705 1.1 macallan uint8_t cmap[768]; 706 1.1 macallan int i, j; 707 1.1 macallan 708 1.1 macallan j = 0; 709 1.1 macallan rasops_get_cmap(&sc->sc_console_screen.scr_ri, cmap, sizeof(cmap)); 710 1.1 macallan for (i = 0; i < 256; i++) { 711 1.1 macallan sc->sc_cmap_red[i] = cmap[j]; 712 1.1 macallan sc->sc_cmap_green[i] = cmap[j + 1]; 713 1.1 macallan sc->sc_cmap_blue[i] = cmap[j + 2]; 714 1.1 macallan hyperfb_putpalreg(sc, i, cmap[j], cmap[j + 1], cmap[j + 2]); 715 1.1 macallan j += 3; 716 1.1 macallan } 717 1.1 macallan } 718 1.1 macallan 719 1.1 macallan static int 720 1.1 macallan hyperfb_putpalreg(struct hyperfb_softc *sc, uint8_t idx, uint8_t r, uint8_t g, 721 1.1 macallan uint8_t b) 722 1.1 macallan { 723 1.1 macallan 724 1.1 macallan mutex_enter(&sc->sc_hwlock); 725 1.1 macallan hyperfb_wait(sc); 726 1.1 macallan hyperfb_write4(sc, NGLE_REG_10, 0xbbe0f000); 727 1.1 macallan hyperfb_write4(sc, NGLE_REG_14, 0x03000300); 728 1.1 macallan hyperfb_write4(sc, NGLE_REG_13, 0xffffffff); 729 1.1 macallan 730 1.1 macallan hyperfb_wait(sc); 731 1.1 macallan hyperfb_write4(sc, NGLE_REG_3, 0x400 | (idx << 2)); 732 1.1 macallan hyperfb_write4(sc, NGLE_REG_4, (r << 16) | (g << 8) | b); 733 1.1 macallan 734 1.1 macallan hyperfb_write4(sc, NGLE_REG_2, 0x400); 735 1.1 macallan hyperfb_write4(sc, NGLE_REG_38, 0x82000100); 736 1.1 macallan hyperfb_setup_fb(sc); 737 1.1 macallan mutex_exit(&sc->sc_hwlock); 738 1.1 macallan return 0; 739 1.1 macallan } 740 1.1 macallan 741 1.1 macallan void 742 1.1 macallan hyperfb_setup(struct hyperfb_softc *sc) 743 1.1 macallan { 744 1.1 macallan int i; 745 1.1 macallan 746 1.1 macallan sc->sc_hwmode = HW_FB; 747 1.1 macallan sc->sc_hot_x = 0; 748 1.1 macallan sc->sc_hot_y = 0; 749 1.1 macallan sc->sc_enabled = 0; 750 1.1 macallan sc->sc_video_on = 1; 751 1.1 macallan 752 1.23 macallan /* first enable all planes */ 753 1.1 macallan hyperfb_wait(sc); 754 1.5 macallan hyperfb_write4(sc, NGLE_REG_32, 0xffffffff); 755 1.5 macallan 756 1.5 macallan /* hyperbowl */ 757 1.7 riastrad if (sc->sc_24bit) { 758 1.5 macallan /* write must happen twice because hw bug */ 759 1.7 riastrad hyperfb_write4(sc, NGLE_REG_40, 760 1.7 riastrad HYPERBOWL_MODE01_8_24_LUT0_TRANSPARENT_LUT1_OPAQUE); 761 1.7 riastrad hyperfb_write4(sc, NGLE_REG_40, 762 1.7 riastrad HYPERBOWL_MODE01_8_24_LUT0_TRANSPARENT_LUT1_OPAQUE); 763 1.5 macallan hyperfb_write4(sc, NGLE_REG_39, HYPERBOWL_MODE2_8_24); 764 1.7 riastrad /* Set lut 0 to be the direct color */ 765 1.7 riastrad hyperfb_write4(sc, NGLE_REG_42, 0x014c0148); 766 1.5 macallan hyperfb_write4(sc, NGLE_REG_43, 0x404c4048); 767 1.5 macallan hyperfb_write4(sc, NGLE_REG_44, 0x034c0348); 768 1.5 macallan hyperfb_write4(sc, NGLE_REG_45, 0x444c4448); 769 1.5 macallan } else { 770 1.7 riastrad hyperfb_write4(sc, NGLE_REG_40, 771 1.7 riastrad HYPERBOWL_MODE_FOR_8_OVER_88_LUT0_NO_TRANSPARENCIES); 772 1.7 riastrad hyperfb_write4(sc, NGLE_REG_40, 773 1.7 riastrad HYPERBOWL_MODE_FOR_8_OVER_88_LUT0_NO_TRANSPARENCIES); 774 1.1 macallan 775 1.5 macallan hyperfb_write4(sc, NGLE_REG_42, 0); 776 1.5 macallan hyperfb_write4(sc, NGLE_REG_43, 0); 777 1.5 macallan hyperfb_write4(sc, NGLE_REG_44, 0); 778 1.5 macallan hyperfb_write4(sc, NGLE_REG_45, 0x444c4048); 779 1.7 riastrad } 780 1.1 macallan 781 1.1 macallan /* attr. planes */ 782 1.23 macallan /* 783 1.23 macallan * XXX 784 1.23 macallan * This is odd. 785 1.23 macallan * We tell the blitter to write 8 bit deep but expect a 32bit value 786 1.24 riastrad * to be written. Then again, writing to BINattr is already special 787 1.24 riastrad * by using NGLE_REG_12 as source instead of the fg/bg registers, it 788 1.23 macallan * may always write all planes, who knows. This is what the NGLE code 789 1.23 macallan * in XFree86 3.3 does. 790 1.23 macallan * Also, the value itself is not one of the CMAP defines in nglehdw.h, 791 1.23 macallan * but it's used in hyperResetPlanes() and does what we want. 792 1.24 riastrad * Then there are HYPER_CMAP* defines with yet another set of 793 1.23 macallan * different values that aren't used anywhere. 794 1.23 macallan */ 795 1.1 macallan hyperfb_wait(sc); 796 1.5 macallan hyperfb_write4(sc, NGLE_REG_11, 797 1.5 macallan BA(IndexedDcd, Otc32, OtsIndirect, AddrLong, 0, BINattr, 0)); 798 1.5 macallan hyperfb_write4(sc, NGLE_REG_14, 799 1.5 macallan IBOvals(RopSrc, 0, BitmapExtent08, 1, DataDynamic, MaskOtc, 1, 0)); 800 1.23 macallan hyperfb_write4(sc, NGLE_REG_12, 0x04000F00); 801 1.1 macallan hyperfb_write4(sc, NGLE_REG_8, 0xffffffff); 802 1.1 macallan 803 1.1 macallan hyperfb_wait(sc); 804 1.1 macallan hyperfb_write4(sc, NGLE_REG_6, 0x00000000); 805 1.1 macallan hyperfb_write4(sc, NGLE_REG_9, 806 1.1 macallan (sc->sc_width << 16) | sc->sc_height); 807 1.1 macallan /* 808 1.7 riastrad * blit into offscreen memory to force flush previous - apparently 809 1.1 macallan * some chips have a bug this works around 810 1.1 macallan */ 811 1.5 macallan hyperfb_wait(sc); 812 1.1 macallan hyperfb_write4(sc, NGLE_REG_6, 0x05000000); 813 1.1 macallan hyperfb_write4(sc, NGLE_REG_9, 0x00040001); 814 1.1 macallan 815 1.7 riastrad /* 816 1.5 macallan * on 24bit-capable hardware we: 817 1.5 macallan * - make overlay colour 255 transparent 818 1.5 macallan * - blit the 24bit buffer all white 819 1.5 macallan * - install a linear ramp in CMAP 0 820 1.7 riastrad */ 821 1.7 riastrad if (sc->sc_24bit) { 822 1.7 riastrad /* overlay transparency */ 823 1.5 macallan hyperfb_wait_fifo(sc, 7); 824 1.11 riastrad hyperfb_write4(sc, NGLE_REG_11, 825 1.10 macallan BA(IndexedDcd, Otc04, Ots08, AddrLong, 0, BINovly, 0)); 826 1.24 riastrad hyperfb_write4(sc, NGLE_REG_14, 827 1.23 macallan IBOvals(RopSrc, 0, BitmapExtent08, 0, DataDynamic, MaskOtc, 828 1.23 macallan 0, 0)); //0x03000300 829 1.23 macallan /* 830 1.23 macallan * apparently the overlay transparency register lives at a 831 1.23 macallan * magical location in the overlay plane, outside visible 832 1.23 macallan * memory. Normal blits cut off beyond X 1280. 833 1.23 macallan */ 834 1.23 macallan hyperfb_write4(sc, NGLE_REG_3, 0x000017f0); // BINC dst 835 1.5 macallan hyperfb_write4(sc, NGLE_REG_13, 0xffffffff); 836 1.5 macallan hyperfb_write4(sc, NGLE_REG_22, 0xffffffff); 837 1.23 macallan hyperfb_write4(sc, NGLE_REG_23, 0x0); // BINC data 838 1.5 macallan 839 1.5 macallan hyperfb_wait(sc); 840 1.5 macallan hyperfb_write4(sc, NGLE_REG_12, 0x00000000); 841 1.5 macallan 842 1.5 macallan /* clear 24bit buffer */ 843 1.5 macallan hyperfb_wait(sc); 844 1.5 macallan /* plane mask */ 845 1.5 macallan hyperfb_write4(sc, NGLE_REG_13, 0xffffffff); 846 1.7 riastrad hyperfb_write4(sc, NGLE_REG_8, 0xffffffff); /* transfer data */ 847 1.5 macallan /* bitmap op */ 848 1.7 riastrad hyperfb_write4(sc, NGLE_REG_14, 849 1.7 riastrad IBOvals(RopSrc, 0, BitmapExtent32, 0, DataDynamic, MaskOtc, 850 1.7 riastrad 0, 0)); 851 1.5 macallan /* dst bitmap access */ 852 1.5 macallan hyperfb_write4(sc, NGLE_REG_11, 853 1.19 macallan BA(FractDcd, Otc32, OtsIndirect, AddrLong, 0, BINapp0F8, 854 1.7 riastrad 0)); 855 1.5 macallan hyperfb_wait_fifo(sc, 3); 856 1.5 macallan hyperfb_write4(sc, NGLE_REG_35, 0x00ffffff); /* fg colour */ 857 1.5 macallan hyperfb_write4(sc, NGLE_REG_6, 0x00000000); /* dst xy */ 858 1.5 macallan hyperfb_write4(sc, NGLE_REG_9, 859 1.5 macallan (sc->sc_width << 16) | sc->sc_height); 860 1.5 macallan 861 1.5 macallan /* write a linear ramp into CMAP0 */ 862 1.5 macallan hyperfb_wait(sc); 863 1.5 macallan hyperfb_write4(sc, NGLE_REG_10, 0xbbe0f000); 864 1.5 macallan hyperfb_write4(sc, NGLE_REG_14, 0x03000300); 865 1.5 macallan hyperfb_write4(sc, NGLE_REG_13, 0xffffffff); 866 1.5 macallan 867 1.5 macallan hyperfb_wait(sc); 868 1.5 macallan hyperfb_write4(sc, NGLE_REG_3, 0); 869 1.5 macallan for (i = 0; i < 256; i++) { 870 1.5 macallan hyperfb_wait(sc); 871 1.7 riastrad hyperfb_write4(sc, NGLE_REG_4, 872 1.7 riastrad (i << 16) | (i << 8) | i); 873 1.5 macallan } 874 1.5 macallan hyperfb_write4(sc, NGLE_REG_2, 0x0); 875 1.7 riastrad hyperfb_write4(sc, NGLE_REG_38, 876 1.7 riastrad LBC_ENABLE | LBC_TYPE_CMAP | 0x100); 877 1.5 macallan hyperfb_wait(sc); 878 1.5 macallan } 879 1.1 macallan 880 1.1 macallan hyperfb_setup_fb(sc); 881 1.1 macallan 882 1.1 macallan /* make sure video output is enabled */ 883 1.1 macallan hyperfb_wait(sc); 884 1.1 macallan hyperfb_write4(sc, NGLE_REG_33, 885 1.1 macallan hyperfb_read4(sc, NGLE_REG_33) | 0x0a000000); 886 1.7 riastrad 887 1.1 macallan /* cursor mask */ 888 1.1 macallan hyperfb_wait(sc); 889 1.1 macallan hyperfb_write4(sc, NGLE_REG_30, 0); 890 1.1 macallan for (i = 0; i < 64; i++) { 891 1.1 macallan hyperfb_write4(sc, NGLE_REG_31, 0xffffffff); 892 1.1 macallan hyperfb_write4(sc, NGLE_REG_31, 0xffffffff); 893 1.1 macallan } 894 1.1 macallan 895 1.1 macallan /* cursor image */ 896 1.1 macallan hyperfb_wait(sc); 897 1.1 macallan hyperfb_write4(sc, NGLE_REG_30, 0x80); 898 1.1 macallan for (i = 0; i < 64; i++) { 899 1.1 macallan hyperfb_write4(sc, NGLE_REG_31, 0xff00ff00); 900 1.1 macallan hyperfb_write4(sc, NGLE_REG_31, 0xff00ff00); 901 1.1 macallan } 902 1.1 macallan 903 1.5 macallan /* colour map */ 904 1.1 macallan hyperfb_wait(sc); 905 1.1 macallan hyperfb_write4(sc, NGLE_REG_10, 0xBBE0F000); 906 1.1 macallan hyperfb_write4(sc, NGLE_REG_14, 0x03000300); 907 1.1 macallan hyperfb_write4(sc, NGLE_REG_13, 0xffffffff); 908 1.1 macallan hyperfb_wait(sc); 909 1.1 macallan hyperfb_write4(sc, NGLE_REG_3, 0); 910 1.1 macallan hyperfb_write4(sc, NGLE_REG_4, 0x000000ff); /* BG */ 911 1.1 macallan hyperfb_write4(sc, NGLE_REG_4, 0x00ff0000); /* FG */ 912 1.1 macallan hyperfb_wait(sc); 913 1.1 macallan hyperfb_write4(sc, NGLE_REG_2, 0); 914 1.3 macallan hyperfb_write4(sc, NGLE_REG_38, LBC_ENABLE | LBC_TYPE_CURSOR | 4); 915 1.7 riastrad hyperfb_setup_fb(sc); 916 1.1 macallan 917 1.3 macallan hyperfb_move_cursor(sc, 100, 100); 918 1.1 macallan } 919 1.1 macallan 920 1.1 macallan static void 921 1.1 macallan hyperfb_set_video(struct hyperfb_softc *sc, int on) 922 1.1 macallan { 923 1.1 macallan uint32_t reg; 924 1.7 riastrad 925 1.1 macallan if (sc->sc_video_on == on) 926 1.1 macallan return; 927 1.7 riastrad 928 1.1 macallan sc->sc_video_on = on; 929 1.1 macallan 930 1.1 macallan hyperfb_wait(sc); 931 1.1 macallan reg = hyperfb_read4(sc, NGLE_REG_33); 932 1.7 riastrad 933 1.1 macallan if (on) { 934 1.3 macallan hyperfb_write4(sc, NGLE_REG_33, reg | HCRX_VIDEO_ENABLE); 935 1.1 macallan } else { 936 1.3 macallan hyperfb_write4(sc, NGLE_REG_33, reg & ~HCRX_VIDEO_ENABLE); 937 1.1 macallan } 938 1.1 macallan } 939 1.2 macallan 940 1.21 macallan static inline void 941 1.21 macallan hyperfb_fillmode(struct hyperfb_softc *sc) 942 1.2 macallan { 943 1.2 macallan if (sc->sc_hwmode != HW_FILL) { 944 1.14 macallan hyperfb_wait_fifo(sc, 3); 945 1.2 macallan /* plane mask */ 946 1.2 macallan hyperfb_write4(sc, NGLE_REG_13, 0xff); 947 1.2 macallan /* bitmap op */ 948 1.7 riastrad hyperfb_write4(sc, NGLE_REG_14, 949 1.20 macallan IBOvals(RopSrc, 0, BitmapExtent08, 1, DataDynamic, 0, 950 1.21 macallan 0, 0)); 951 1.2 macallan /* dst bitmap access */ 952 1.2 macallan hyperfb_write4(sc, NGLE_REG_11, 953 1.7 riastrad BA(IndexedDcd, Otc32, OtsIndirect, AddrLong, 0, BINovly, 954 1.7 riastrad 0)); 955 1.2 macallan sc->sc_hwmode = HW_FILL; 956 1.2 macallan } 957 1.21 macallan } 958 1.21 macallan 959 1.21 macallan static void 960 1.21 macallan hyperfb_rectfill(struct hyperfb_softc *sc, int x, int y, int wi, int he, 961 1.21 macallan uint32_t bg) 962 1.21 macallan { 963 1.21 macallan 964 1.21 macallan hyperfb_fillmode(sc); 965 1.21 macallan 966 1.14 macallan hyperfb_wait_fifo(sc, 4); 967 1.14 macallan /* 968 1.14 macallan * XXX - the NGLE code calls this 'transfer data' 969 1.24 riastrad * in reality it's a bit mask applied per pixel, 970 1.14 macallan * foreground colour in reg 35, bg in 36 971 1.14 macallan */ 972 1.20 macallan hyperfb_write4(sc, NGLE_REG_8, 0xffffffff); 973 1.14 macallan 974 1.2 macallan hyperfb_write4(sc, NGLE_REG_35, bg); 975 1.2 macallan /* dst XY */ 976 1.2 macallan hyperfb_write4(sc, NGLE_REG_6, (x << 16) | y); 977 1.2 macallan /* len XY start */ 978 1.2 macallan hyperfb_write4(sc, NGLE_REG_9, (wi << 16) | he); 979 1.2 macallan } 980 1.2 macallan 981 1.2 macallan static void 982 1.2 macallan hyperfb_bitblt(void *cookie, int xs, int ys, int xd, int yd, int wi, 983 1.7 riastrad int he, int rop) 984 1.2 macallan { 985 1.2 macallan struct hyperfb_softc *sc = cookie; 986 1.2 macallan 987 1.2 macallan if (sc->sc_hwmode != HW_BLIT) { 988 1.2 macallan hyperfb_wait(sc); 989 1.11 riastrad hyperfb_write4(sc, NGLE_REG_10, 990 1.10 macallan BA(IndexedDcd, Otc04, Ots08, AddrLong, 0, BINovly, 0)); 991 1.2 macallan hyperfb_write4(sc, NGLE_REG_13, 0xff); 992 1.2 macallan sc->sc_hwmode = HW_BLIT; 993 1.2 macallan } 994 1.2 macallan hyperfb_wait_fifo(sc, 4); 995 1.2 macallan hyperfb_write4(sc, NGLE_REG_14, ((rop << 8) & 0xf00) | 0x23000000); 996 1.2 macallan /* IBOvals(rop, 0, BitmapExtent08, 1, DataDynamic, MaskOtc, 0, 0) */ 997 1.2 macallan hyperfb_write4(sc, NGLE_REG_24, (xs << 16) | ys); 998 1.2 macallan hyperfb_write4(sc, NGLE_REG_7, (wi << 16) | he); 999 1.2 macallan hyperfb_write4(sc, NGLE_REG_25, (xd << 16) | yd); 1000 1.2 macallan } 1001 1.2 macallan 1002 1.2 macallan static void 1003 1.2 macallan hyperfb_nuke_cursor(struct rasops_info *ri) 1004 1.2 macallan { 1005 1.2 macallan struct vcons_screen *scr = ri->ri_hw; 1006 1.2 macallan struct hyperfb_softc *sc = scr->scr_cookie; 1007 1.2 macallan int wi, he, x, y; 1008 1.7 riastrad 1009 1.2 macallan if (ri->ri_flg & RI_CURSOR) { 1010 1.2 macallan wi = ri->ri_font->fontwidth; 1011 1.2 macallan he = ri->ri_font->fontheight; 1012 1.2 macallan x = ri->ri_ccol * wi + ri->ri_xorigin; 1013 1.2 macallan y = ri->ri_crow * he + ri->ri_yorigin; 1014 1.2 macallan hyperfb_bitblt(sc, x, y, x, y, wi, he, RopInv); 1015 1.2 macallan ri->ri_flg &= ~RI_CURSOR; 1016 1.2 macallan } 1017 1.2 macallan } 1018 1.2 macallan 1019 1.2 macallan static void 1020 1.2 macallan hyperfb_cursor(void *cookie, int on, int row, int col) 1021 1.2 macallan { 1022 1.2 macallan struct rasops_info *ri = cookie; 1023 1.2 macallan struct vcons_screen *scr = ri->ri_hw; 1024 1.2 macallan struct hyperfb_softc *sc = scr->scr_cookie; 1025 1.2 macallan int x, y, wi, he; 1026 1.7 riastrad 1027 1.2 macallan wi = ri->ri_font->fontwidth; 1028 1.2 macallan he = ri->ri_font->fontheight; 1029 1.7 riastrad 1030 1.2 macallan if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) { 1031 1.2 macallan if (on) { 1032 1.2 macallan if (ri->ri_flg & RI_CURSOR) { 1033 1.2 macallan hyperfb_nuke_cursor(ri); 1034 1.2 macallan } 1035 1.2 macallan x = col * wi + ri->ri_xorigin; 1036 1.2 macallan y = row * he + ri->ri_yorigin; 1037 1.2 macallan hyperfb_bitblt(sc, x, y, x, y, wi, he, RopInv); 1038 1.2 macallan ri->ri_flg |= RI_CURSOR; 1039 1.2 macallan } 1040 1.2 macallan ri->ri_crow = row; 1041 1.2 macallan ri->ri_ccol = col; 1042 1.7 riastrad } else { 1043 1.2 macallan ri->ri_crow = row; 1044 1.2 macallan ri->ri_ccol = col; 1045 1.2 macallan ri->ri_flg &= ~RI_CURSOR; 1046 1.2 macallan } 1047 1.2 macallan } 1048 1.2 macallan 1049 1.2 macallan static void 1050 1.2 macallan hyperfb_putchar(void *cookie, int row, int col, u_int c, long attr) 1051 1.2 macallan { 1052 1.2 macallan struct rasops_info *ri = cookie; 1053 1.2 macallan struct wsdisplay_font *font = PICK_FONT(ri, c); 1054 1.2 macallan struct vcons_screen *scr = ri->ri_hw; 1055 1.2 macallan struct hyperfb_softc *sc = scr->scr_cookie; 1056 1.17 macallan void *data; 1057 1.15 macallan int i, x, y, wi, he/*, rv = GC_NOPE*/; 1058 1.15 macallan uint32_t bg, fg, mask; 1059 1.2 macallan 1060 1.2 macallan if (sc->sc_mode != WSDISPLAYIO_MODE_EMUL) 1061 1.2 macallan return; 1062 1.2 macallan 1063 1.2 macallan if (!CHAR_IN_FONT(c, font)) 1064 1.2 macallan return; 1065 1.2 macallan 1066 1.2 macallan if (row == ri->ri_crow && col == ri->ri_ccol) { 1067 1.2 macallan ri->ri_flg &= ~RI_CURSOR; 1068 1.2 macallan } 1069 1.2 macallan 1070 1.2 macallan wi = font->fontwidth; 1071 1.2 macallan he = font->fontheight; 1072 1.2 macallan 1073 1.2 macallan x = ri->ri_xorigin + col * wi; 1074 1.2 macallan y = ri->ri_yorigin + row * he; 1075 1.2 macallan 1076 1.2 macallan bg = ri->ri_devcmap[(attr >> 16) & 0xf]; 1077 1.15 macallan fg = ri->ri_devcmap[(attr >> 24) & 0x0f]; 1078 1.2 macallan 1079 1.15 macallan 1080 1.15 macallan /* if we're drawing a space we're done here */ 1081 1.24 riastrad if (c == 0x20) { 1082 1.21 macallan /* clear the character cell */ 1083 1.21 macallan hyperfb_rectfill(sc, x, y, wi, he, bg); 1084 1.2 macallan return; 1085 1.21 macallan } 1086 1.2 macallan 1087 1.15 macallan data = WSFONT_GLYPH(c, font); 1088 1.15 macallan 1089 1.21 macallan hyperfb_fillmode(sc); 1090 1.21 macallan 1091 1.21 macallan hyperfb_wait_fifo(sc, 3); 1092 1.15 macallan 1093 1.15 macallan /* character colour */ 1094 1.15 macallan hyperfb_write4(sc, NGLE_REG_35, fg); 1095 1.21 macallan hyperfb_write4(sc, NGLE_REG_36, bg); 1096 1.15 macallan /* dst XY */ 1097 1.15 macallan hyperfb_write4(sc, NGLE_REG_6, (x << 16) | y); 1098 1.15 macallan 1099 1.15 macallan /* 1100 1.15 macallan * drawing a rectangle moves the starting coordinates down the 1101 1.15 macallan * y-axis so we can just hammer the wi/he register to draw a full 1102 1.15 macallan * character 1103 1.15 macallan */ 1104 1.15 macallan if (ri->ri_font->stride == 1) { 1105 1.17 macallan uint8_t *data8 = data; 1106 1.15 macallan for (i = 0; i < he; i++) { 1107 1.15 macallan hyperfb_wait_fifo(sc, 2); 1108 1.17 macallan mask = *data8; 1109 1.24 riastrad hyperfb_write4(sc, NGLE_REG_8, mask << 24); 1110 1.15 macallan hyperfb_write4(sc, NGLE_REG_9, (wi << 16) | 1); 1111 1.17 macallan data8++; 1112 1.15 macallan } 1113 1.15 macallan } else { 1114 1.17 macallan uint16_t *data16 = data; 1115 1.15 macallan for (i = 0; i < he; i++) { 1116 1.15 macallan hyperfb_wait_fifo(sc, 2); 1117 1.17 macallan mask = *data16; 1118 1.24 riastrad hyperfb_write4(sc, NGLE_REG_8, mask << 16); 1119 1.15 macallan hyperfb_write4(sc, NGLE_REG_9, (wi << 16) | 1); 1120 1.17 macallan data16++; 1121 1.15 macallan } 1122 1.15 macallan } 1123 1.2 macallan } 1124 1.2 macallan 1125 1.2 macallan static void 1126 1.2 macallan hyperfb_copycols(void *cookie, int row, int srccol, int dstcol, int ncols) 1127 1.2 macallan { 1128 1.2 macallan struct rasops_info *ri = cookie; 1129 1.2 macallan struct vcons_screen *scr = ri->ri_hw; 1130 1.2 macallan struct hyperfb_softc *sc = scr->scr_cookie; 1131 1.2 macallan int32_t xs, xd, y, width, height; 1132 1.7 riastrad 1133 1.2 macallan if ((sc->sc_locked == 0) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) { 1134 1.7 riastrad if (ri->ri_crow == row && 1135 1.2 macallan (ri->ri_ccol >= srccol && ri->ri_ccol < (srccol + ncols)) && 1136 1.2 macallan (ri->ri_flg & RI_CURSOR)) { 1137 1.2 macallan hyperfb_nuke_cursor(ri); 1138 1.2 macallan } 1139 1.2 macallan 1140 1.2 macallan xs = ri->ri_xorigin + ri->ri_font->fontwidth * srccol; 1141 1.2 macallan xd = ri->ri_xorigin + ri->ri_font->fontwidth * dstcol; 1142 1.2 macallan y = ri->ri_yorigin + ri->ri_font->fontheight * row; 1143 1.2 macallan width = ri->ri_font->fontwidth * ncols; 1144 1.2 macallan height = ri->ri_font->fontheight; 1145 1.2 macallan hyperfb_bitblt(sc, xs, y, xd, y, width, height, RopSrc); 1146 1.7 riastrad if (ri->ri_crow == row && 1147 1.2 macallan (ri->ri_ccol >= dstcol && ri->ri_ccol < (dstcol + ncols))) 1148 1.2 macallan ri->ri_flg &= ~RI_CURSOR; 1149 1.2 macallan } 1150 1.2 macallan } 1151 1.2 macallan 1152 1.2 macallan static void 1153 1.7 riastrad hyperfb_erasecols(void *cookie, int row, int startcol, int ncols, 1154 1.7 riastrad long fillattr) 1155 1.2 macallan { 1156 1.2 macallan struct rasops_info *ri = cookie; 1157 1.2 macallan struct vcons_screen *scr = ri->ri_hw; 1158 1.2 macallan struct hyperfb_softc *sc = scr->scr_cookie; 1159 1.2 macallan int32_t x, y, width, height, fg, bg, ul; 1160 1.7 riastrad 1161 1.2 macallan if ((sc->sc_locked == 0) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) { 1162 1.2 macallan x = ri->ri_xorigin + ri->ri_font->fontwidth * startcol; 1163 1.2 macallan y = ri->ri_yorigin + ri->ri_font->fontheight * row; 1164 1.2 macallan width = ri->ri_font->fontwidth * ncols; 1165 1.2 macallan height = ri->ri_font->fontheight; 1166 1.2 macallan rasops_unpack_attr(fillattr, &fg, &bg, &ul); 1167 1.2 macallan 1168 1.2 macallan hyperfb_rectfill(sc, x, y, width, height, ri->ri_devcmap[bg]); 1169 1.7 riastrad if (ri->ri_crow == row && 1170 1.7 riastrad (ri->ri_ccol >= startcol && 1171 1.7 riastrad ri->ri_ccol < (startcol + ncols))) 1172 1.2 macallan ri->ri_flg &= ~RI_CURSOR; 1173 1.2 macallan } 1174 1.2 macallan } 1175 1.2 macallan 1176 1.2 macallan static void 1177 1.2 macallan hyperfb_copyrows(void *cookie, int srcrow, int dstrow, int nrows) 1178 1.2 macallan { 1179 1.2 macallan struct rasops_info *ri = cookie; 1180 1.2 macallan struct vcons_screen *scr = ri->ri_hw; 1181 1.2 macallan struct hyperfb_softc *sc = scr->scr_cookie; 1182 1.2 macallan int32_t x, ys, yd, width, height; 1183 1.2 macallan 1184 1.2 macallan if ((sc->sc_locked == 0) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) { 1185 1.7 riastrad if ((ri->ri_crow >= srcrow && 1186 1.7 riastrad ri->ri_crow < (srcrow + nrows)) && 1187 1.7 riastrad (ri->ri_flg & RI_CURSOR)) { 1188 1.2 macallan hyperfb_nuke_cursor(ri); 1189 1.2 macallan } 1190 1.2 macallan x = ri->ri_xorigin; 1191 1.2 macallan ys = ri->ri_yorigin + ri->ri_font->fontheight * srcrow; 1192 1.2 macallan yd = ri->ri_yorigin + ri->ri_font->fontheight * dstrow; 1193 1.2 macallan width = ri->ri_emuwidth; 1194 1.2 macallan height = ri->ri_font->fontheight * nrows; 1195 1.2 macallan hyperfb_bitblt(sc, x, ys, x, yd, width, height, RopSrc); 1196 1.2 macallan if (ri->ri_crow >= dstrow && ri->ri_crow < (dstrow + nrows)) 1197 1.2 macallan ri->ri_flg &= ~RI_CURSOR; 1198 1.2 macallan } 1199 1.2 macallan } 1200 1.2 macallan 1201 1.2 macallan static void 1202 1.2 macallan hyperfb_eraserows(void *cookie, int row, int nrows, long fillattr) 1203 1.2 macallan { 1204 1.2 macallan struct rasops_info *ri = cookie; 1205 1.2 macallan struct vcons_screen *scr = ri->ri_hw; 1206 1.2 macallan struct hyperfb_softc *sc = scr->scr_cookie; 1207 1.2 macallan int32_t x, y, width, height, fg, bg, ul; 1208 1.7 riastrad 1209 1.2 macallan if ((sc->sc_locked == 0) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) { 1210 1.2 macallan x = ri->ri_xorigin; 1211 1.2 macallan y = ri->ri_yorigin + ri->ri_font->fontheight * row; 1212 1.2 macallan width = ri->ri_emuwidth; 1213 1.2 macallan height = ri->ri_font->fontheight * nrows; 1214 1.2 macallan rasops_unpack_attr(fillattr, &fg, &bg, &ul); 1215 1.2 macallan 1216 1.2 macallan hyperfb_rectfill(sc, x, y, width, height, ri->ri_devcmap[bg]); 1217 1.2 macallan 1218 1.2 macallan if (ri->ri_crow >= row && ri->ri_crow < (row + nrows)) 1219 1.2 macallan ri->ri_flg &= ~RI_CURSOR; 1220 1.2 macallan } 1221 1.2 macallan } 1222 1.3 macallan 1223 1.3 macallan static void 1224 1.3 macallan hyperfb_move_cursor(struct hyperfb_softc *sc, int x, int y) 1225 1.3 macallan { 1226 1.3 macallan uint32_t pos; 1227 1.3 macallan 1228 1.3 macallan sc->sc_cursor_x = x; 1229 1.3 macallan x -= sc->sc_hot_x; 1230 1.3 macallan sc->sc_cursor_y = y; 1231 1.3 macallan y -= sc->sc_hot_y; 1232 1.3 macallan 1233 1.3 macallan if (x < 0) x = 0x1000 - x; 1234 1.3 macallan if (y < 0) y = 0x1000 - y; 1235 1.3 macallan pos = (x << 16) | y; 1236 1.3 macallan if (sc->sc_enabled) pos |= HCRX_ENABLE_CURSOR; 1237 1.9 macallan hyperfb_wait_fifo(sc, 2); 1238 1.9 macallan hyperfb_write4(sc, NGLE_REG_28, 0); 1239 1.3 macallan hyperfb_write4(sc, NGLE_REG_29, pos); 1240 1.3 macallan } 1241 1.3 macallan 1242 1.3 macallan static int 1243 1.3 macallan hyperfb_do_cursor(struct hyperfb_softc *sc, struct wsdisplay_cursor *cur) 1244 1.3 macallan { 1245 1.3 macallan 1246 1.3 macallan if (cur->which & WSDISPLAY_CURSOR_DOCUR) { 1247 1.3 macallan 1248 1.3 macallan sc->sc_enabled = cur->enable; 1249 1.3 macallan cur->which |= WSDISPLAY_CURSOR_DOPOS; 1250 1.3 macallan } 1251 1.3 macallan if (cur->which & WSDISPLAY_CURSOR_DOHOT) { 1252 1.3 macallan 1253 1.3 macallan sc->sc_hot_x = cur->hot.x; 1254 1.3 macallan sc->sc_hot_y = cur->hot.y; 1255 1.3 macallan cur->which |= WSDISPLAY_CURSOR_DOPOS; 1256 1.3 macallan } 1257 1.3 macallan if (cur->which & WSDISPLAY_CURSOR_DOPOS) { 1258 1.3 macallan 1259 1.3 macallan hyperfb_move_cursor(sc, cur->pos.x, cur->pos.y); 1260 1.3 macallan } 1261 1.3 macallan if (cur->which & WSDISPLAY_CURSOR_DOCMAP) { 1262 1.3 macallan uint32_t rgb; 1263 1.3 macallan uint8_t r[2], g[2], b[2]; 1264 1.3 macallan 1265 1.3 macallan copyin(cur->cmap.blue, b, 2); 1266 1.3 macallan copyin(cur->cmap.green, g, 2); 1267 1.3 macallan copyin(cur->cmap.red, r, 2); 1268 1.3 macallan mutex_enter(&sc->sc_hwlock); 1269 1.3 macallan hyperfb_wait(sc); 1270 1.3 macallan hyperfb_write4(sc, NGLE_REG_10, 0xBBE0F000); 1271 1.3 macallan hyperfb_write4(sc, NGLE_REG_14, 0x03000300); 1272 1.3 macallan hyperfb_write4(sc, NGLE_REG_13, 0xffffffff); 1273 1.3 macallan hyperfb_wait(sc); 1274 1.3 macallan hyperfb_write4(sc, NGLE_REG_3, 0); 1275 1.3 macallan rgb = (r[0] << 16) | (g[0] << 8) | b[0]; 1276 1.3 macallan hyperfb_write4(sc, NGLE_REG_4, rgb); /* BG */ 1277 1.3 macallan rgb = (r[1] << 16) | (g[1] << 8) | b[1]; 1278 1.3 macallan hyperfb_write4(sc, NGLE_REG_4, rgb); /* FG */ 1279 1.3 macallan hyperfb_write4(sc, NGLE_REG_2, 0); 1280 1.7 riastrad hyperfb_write4(sc, NGLE_REG_38, 1281 1.7 riastrad LBC_ENABLE | LBC_TYPE_CURSOR | 4); 1282 1.3 macallan 1283 1.7 riastrad hyperfb_setup_fb(sc); 1284 1.3 macallan mutex_exit(&sc->sc_hwlock); 1285 1.3 macallan 1286 1.3 macallan } 1287 1.3 macallan if (cur->which & WSDISPLAY_CURSOR_DOSHAPE) { 1288 1.3 macallan uint32_t buffer[128], latch, tmp; 1289 1.3 macallan int i; 1290 1.3 macallan 1291 1.3 macallan copyin(cur->mask, buffer, 512); 1292 1.3 macallan hyperfb_wait(sc); 1293 1.3 macallan hyperfb_write4(sc, NGLE_REG_30, 0); 1294 1.3 macallan for (i = 0; i < 128; i += 2) { 1295 1.3 macallan latch = 0; 1296 1.3 macallan tmp = buffer[i] & 0x80808080; 1297 1.3 macallan latch |= tmp >> 7; 1298 1.3 macallan tmp = buffer[i] & 0x40404040; 1299 1.3 macallan latch |= tmp >> 5; 1300 1.3 macallan tmp = buffer[i] & 0x20202020; 1301 1.3 macallan latch |= tmp >> 3; 1302 1.3 macallan tmp = buffer[i] & 0x10101010; 1303 1.3 macallan latch |= tmp >> 1; 1304 1.3 macallan tmp = buffer[i] & 0x08080808; 1305 1.3 macallan latch |= tmp << 1; 1306 1.3 macallan tmp = buffer[i] & 0x04040404; 1307 1.3 macallan latch |= tmp << 3; 1308 1.3 macallan tmp = buffer[i] & 0x02020202; 1309 1.3 macallan latch |= tmp << 5; 1310 1.3 macallan tmp = buffer[i] & 0x01010101; 1311 1.3 macallan latch |= tmp << 7; 1312 1.3 macallan hyperfb_write4(sc, NGLE_REG_31, latch); 1313 1.3 macallan latch = 0; 1314 1.3 macallan tmp = buffer[i + 1] & 0x80808080; 1315 1.3 macallan latch |= tmp >> 7; 1316 1.3 macallan tmp = buffer[i + 1] & 0x40404040; 1317 1.3 macallan latch |= tmp >> 5; 1318 1.3 macallan tmp = buffer[i + 1] & 0x20202020; 1319 1.3 macallan latch |= tmp >> 3; 1320 1.3 macallan tmp = buffer[i + 1] & 0x10101010; 1321 1.3 macallan latch |= tmp >> 1; 1322 1.3 macallan tmp = buffer[i + 1] & 0x08080808; 1323 1.3 macallan latch |= tmp << 1; 1324 1.3 macallan tmp = buffer[i + 1] & 0x04040404; 1325 1.3 macallan latch |= tmp << 3; 1326 1.3 macallan tmp = buffer[i + 1] & 0x02020202; 1327 1.3 macallan latch |= tmp << 5; 1328 1.3 macallan tmp = buffer[i + 1] & 0x01010101; 1329 1.3 macallan latch |= tmp << 7; 1330 1.3 macallan hyperfb_write4(sc, NGLE_REG_31, latch); 1331 1.3 macallan } 1332 1.3 macallan 1333 1.3 macallan copyin(cur->image, buffer, 512); 1334 1.3 macallan hyperfb_wait(sc); 1335 1.3 macallan hyperfb_write4(sc, NGLE_REG_30, 0x80); 1336 1.3 macallan for (i = 0; i < 128; i += 2) { 1337 1.3 macallan latch = 0; 1338 1.3 macallan tmp = buffer[i] & 0x80808080; 1339 1.3 macallan latch |= tmp >> 7; 1340 1.3 macallan tmp = buffer[i] & 0x40404040; 1341 1.3 macallan latch |= tmp >> 5; 1342 1.3 macallan tmp = buffer[i] & 0x20202020; 1343 1.3 macallan latch |= tmp >> 3; 1344 1.3 macallan tmp = buffer[i] & 0x10101010; 1345 1.3 macallan latch |= tmp >> 1; 1346 1.3 macallan tmp = buffer[i] & 0x08080808; 1347 1.3 macallan latch |= tmp << 1; 1348 1.3 macallan tmp = buffer[i] & 0x04040404; 1349 1.3 macallan latch |= tmp << 3; 1350 1.3 macallan tmp = buffer[i] & 0x02020202; 1351 1.3 macallan latch |= tmp << 5; 1352 1.3 macallan tmp = buffer[i] & 0x01010101; 1353 1.3 macallan latch |= tmp << 7; 1354 1.3 macallan hyperfb_write4(sc, NGLE_REG_31, latch); 1355 1.3 macallan latch = 0; 1356 1.3 macallan tmp = buffer[i + 1] & 0x80808080; 1357 1.3 macallan latch |= tmp >> 7; 1358 1.3 macallan tmp = buffer[i + 1] & 0x40404040; 1359 1.3 macallan latch |= tmp >> 5; 1360 1.3 macallan tmp = buffer[i + 1] & 0x20202020; 1361 1.3 macallan latch |= tmp >> 3; 1362 1.3 macallan tmp = buffer[i + 1] & 0x10101010; 1363 1.3 macallan latch |= tmp >> 1; 1364 1.3 macallan tmp = buffer[i + 1] & 0x08080808; 1365 1.3 macallan latch |= tmp << 1; 1366 1.3 macallan tmp = buffer[i + 1] & 0x04040404; 1367 1.3 macallan latch |= tmp << 3; 1368 1.3 macallan tmp = buffer[i + 1] & 0x02020202; 1369 1.3 macallan latch |= tmp << 5; 1370 1.3 macallan tmp = buffer[i + 1] & 0x01010101; 1371 1.3 macallan latch |= tmp << 7; 1372 1.3 macallan hyperfb_write4(sc, NGLE_REG_31, latch); 1373 1.3 macallan } 1374 1.3 macallan hyperfb_setup_fb(sc); 1375 1.3 macallan } 1376 1.3 macallan 1377 1.3 macallan return 0; 1378 1.3 macallan } 1379