1 1.47 tsutsui /* $NetBSD: sti.c,v 1.47 2025/05/30 19:42:28 tsutsui Exp $ */ 2 1.1 jkunz 3 1.13 skrll /* $OpenBSD: sti.c,v 1.61 2009/09/05 14:09:35 miod Exp $ */ 4 1.1 jkunz 5 1.1 jkunz /* 6 1.1 jkunz * Copyright (c) 2000-2003 Michael Shalayeff 7 1.1 jkunz * All rights reserved. 8 1.1 jkunz * 9 1.1 jkunz * Redistribution and use in source and binary forms, with or without 10 1.1 jkunz * modification, are permitted provided that the following conditions 11 1.1 jkunz * are met: 12 1.1 jkunz * 1. Redistributions of source code must retain the above copyright 13 1.1 jkunz * notice, this list of conditions and the following disclaimer. 14 1.1 jkunz * 2. Redistributions in binary form must reproduce the above copyright 15 1.1 jkunz * notice, this list of conditions and the following disclaimer in the 16 1.1 jkunz * documentation and/or other materials provided with the distribution. 17 1.1 jkunz * 18 1.1 jkunz * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 1.1 jkunz * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 1.1 jkunz * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 1.1 jkunz * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, 22 1.1 jkunz * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 1.1 jkunz * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 1.1 jkunz * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 1.1 jkunz * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 1.1 jkunz * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 27 1.1 jkunz * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 28 1.1 jkunz * THE POSSIBILITY OF SUCH DAMAGE. 29 1.1 jkunz */ 30 1.1 jkunz /* 31 1.1 jkunz * TODO: 32 1.1 jkunz * call sti procs asynchronously; 33 1.1 jkunz * implement console scroll-back; 34 1.23 tsutsui * X11 support on more models. 35 1.1 jkunz */ 36 1.1 jkunz 37 1.1 jkunz #include <sys/cdefs.h> 38 1.47 tsutsui __KERNEL_RCSID(0, "$NetBSD: sti.c,v 1.47 2025/05/30 19:42:28 tsutsui Exp $"); 39 1.1 jkunz 40 1.1 jkunz #include "wsdisplay.h" 41 1.1 jkunz 42 1.1 jkunz #include <sys/param.h> 43 1.1 jkunz #include <sys/systm.h> 44 1.1 jkunz #include <sys/device.h> 45 1.1 jkunz #include <sys/malloc.h> 46 1.1 jkunz 47 1.22 riastrad #include <uvm/uvm_extern.h> 48 1.1 jkunz 49 1.8 ad #include <sys/bus.h> 50 1.1 jkunz 51 1.1 jkunz #include <dev/wscons/wsdisplayvar.h> 52 1.1 jkunz #include <dev/wscons/wsconsio.h> 53 1.1 jkunz 54 1.1 jkunz #include <dev/ic/stireg.h> 55 1.40 macallan #include <dev/ic/summitreg.h> 56 1.1 jkunz #include <dev/ic/stivar.h> 57 1.1 jkunz 58 1.13 skrll #ifdef STIDEBUG 59 1.13 skrll 60 1.13 skrll #define DPRINTF(s) do { \ 61 1.13 skrll if (stidebug) \ 62 1.13 skrll printf s; \ 63 1.13 skrll } while(0) 64 1.13 skrll 65 1.13 skrll int stidebug = 1; 66 1.13 skrll #else 67 1.13 skrll #define DPRINTF(s) /* */ 68 1.13 skrll #endif 69 1.13 skrll 70 1.1 jkunz void sti_cursor(void *, int, int, int); 71 1.1 jkunz int sti_mapchar(void *, int, u_int *); 72 1.1 jkunz void sti_putchar(void *, int, int, u_int, long); 73 1.1 jkunz void sti_copycols(void *, int, int, int, int); 74 1.1 jkunz void sti_erasecols(void *, int, int, int, long); 75 1.1 jkunz void sti_copyrows(void *, int, int, int); 76 1.1 jkunz void sti_eraserows(void *, int, int, long); 77 1.1 jkunz int sti_alloc_attr(void *, int, int, int, long *); 78 1.1 jkunz 79 1.24 tsutsui /* pseudo attribute ops for sti ROM putchar function */ 80 1.24 tsutsui #define WSATTR_FG_SHIFT 24 81 1.24 tsutsui #define WSATTR_BG_SHIFT 16 82 1.24 tsutsui #define WSATTR_UNPACK_FG(attr) (((attr) >> WSATTR_FG_SHIFT) & 0xff) 83 1.24 tsutsui #define WSATTR_UNPACK_BG(attr) (((attr) >> WSATTR_BG_SHIFT) & 0xff) 84 1.24 tsutsui #define WSATTR_UNPACK_FLAG(attr) ((attr) & WSATTR_USERMASK) 85 1.24 tsutsui #define WSATTR_PACK_FG(fg) ((fg) << WSATTR_FG_SHIFT) 86 1.24 tsutsui #define WSATTR_PACK_BG(bg) ((bg) << WSATTR_BG_SHIFT) 87 1.24 tsutsui #define WSATTR_PACK_FLAG(flag) ((flag)) 88 1.24 tsutsui #define WSATTR_PACK(fg, bg, flag) \ 89 1.24 tsutsui (WSATTR_PACK_FG(fg) | WSATTR_PACK_BG(bg) | WSATTR_PACK_FLAG(flag)) 90 1.24 tsutsui 91 1.1 jkunz struct wsdisplay_emulops sti_emulops = { 92 1.23 tsutsui .cursor = sti_cursor, 93 1.23 tsutsui .mapchar = sti_mapchar, 94 1.23 tsutsui .putchar = sti_putchar, 95 1.23 tsutsui .copycols = sti_copycols, 96 1.23 tsutsui .erasecols = sti_erasecols, 97 1.23 tsutsui .copyrows = sti_copyrows, 98 1.23 tsutsui .eraserows = sti_eraserows, 99 1.23 tsutsui .allocattr = sti_alloc_attr 100 1.1 jkunz }; 101 1.1 jkunz 102 1.1 jkunz const struct wsdisplay_accessops sti_accessops = { 103 1.23 tsutsui .ioctl = sti_ioctl, 104 1.23 tsutsui .mmap = sti_mmap, 105 1.23 tsutsui .alloc_screen = sti_alloc_screen, 106 1.23 tsutsui .free_screen = sti_free_screen, 107 1.23 tsutsui .show_screen = sti_show_screen, 108 1.23 tsutsui .load_font = sti_load_font 109 1.1 jkunz }; 110 1.1 jkunz 111 1.13 skrll enum sti_bmove_funcs { 112 1.13 skrll bmf_clear, bmf_copy, bmf_invert, bmf_underline 113 1.1 jkunz }; 114 1.1 jkunz 115 1.13 skrll void sti_bmove(struct sti_screen *, int, int, int, int, int, int, 116 1.13 skrll enum sti_bmove_funcs); 117 1.23 tsutsui int sti_inqcfg(struct sti_screen *, struct sti_inqconfout *); 118 1.13 skrll int sti_setcment(struct sti_screen *, u_int, u_char, u_char, u_char); 119 1.13 skrll 120 1.13 skrll struct sti_screen *sti_attach_screen(struct sti_softc *, int); 121 1.13 skrll void sti_describe_screen(struct sti_softc *, struct sti_screen *); 122 1.13 skrll 123 1.13 skrll int sti_fetchfonts(struct sti_screen *, struct sti_inqconfout *, uint32_t, 124 1.13 skrll u_int); 125 1.13 skrll void sti_region_setup(struct sti_screen *); 126 1.13 skrll int sti_rom_setup(struct sti_rom *, bus_space_tag_t, bus_space_tag_t, 127 1.13 skrll bus_space_handle_t, bus_addr_t *, u_int); 128 1.13 skrll int sti_screen_setup(struct sti_screen *, int); 129 1.13 skrll 130 1.23 tsutsui int ngle_default_putcmap(struct sti_screen *, u_int, u_int); 131 1.23 tsutsui 132 1.23 tsutsui #ifndef SMALL_KERNEL 133 1.23 tsutsui void ngle_artist_setupfb(struct sti_screen *); 134 1.23 tsutsui void ngle_elk_setupfb(struct sti_screen *); 135 1.23 tsutsui void ngle_timber_setupfb(struct sti_screen *); 136 1.40 macallan void summit_setupfb(struct sti_screen *); 137 1.23 tsutsui int ngle_putcmap(struct sti_screen *, u_int, u_int); 138 1.37 macallan int ngle_hcrx_putcmap(struct sti_screen *, u_int, u_int); 139 1.40 macallan int summit_putcmap(struct sti_screen *, u_int, u_int); 140 1.23 tsutsui #endif 141 1.23 tsutsui 142 1.13 skrll #define STI_ENABLE_ROM(sc) \ 143 1.13 skrll do { \ 144 1.13 skrll if ((sc) != NULL && (sc)->sc_enable_rom != NULL) \ 145 1.13 skrll (*(sc)->sc_enable_rom)(sc); \ 146 1.13 skrll } while (0) 147 1.13 skrll #define STI_DISABLE_ROM(sc) \ 148 1.13 skrll do { \ 149 1.13 skrll if ((sc) != NULL && (sc)->sc_disable_rom != NULL) \ 150 1.13 skrll (*(sc)->sc_disable_rom)(sc); \ 151 1.13 skrll } while (0) 152 1.13 skrll 153 1.13 skrll /* Macros to read larger than 8 bit values from byte roms */ 154 1.13 skrll #define parseshort(o) \ 155 1.13 skrll ((bus_space_read_1(memt, romh, (o) + 3) << 8) | \ 156 1.13 skrll (bus_space_read_1(memt, romh, (o) + 7))) 157 1.13 skrll #define parseword(o) \ 158 1.13 skrll ((bus_space_read_1(memt, romh, (o) + 3) << 24) | \ 159 1.13 skrll (bus_space_read_1(memt, romh, (o) + 7) << 16) | \ 160 1.13 skrll (bus_space_read_1(memt, romh, (o) + 11) << 8) | \ 161 1.13 skrll (bus_space_read_1(memt, romh, (o) + 15))) 162 1.13 skrll 163 1.13 skrll int 164 1.13 skrll sti_attach_common(struct sti_softc *sc, bus_space_tag_t iot, 165 1.13 skrll bus_space_tag_t memt, bus_space_handle_t romh, u_int codebase) 166 1.13 skrll { 167 1.13 skrll struct sti_rom *rom; 168 1.13 skrll int rc; 169 1.13 skrll 170 1.13 skrll rom = (struct sti_rom *)malloc(sizeof(*rom), M_DEVBUF, 171 1.20 chs M_WAITOK | M_ZERO); 172 1.13 skrll rom->rom_softc = sc; 173 1.13 skrll rc = sti_rom_setup(rom, iot, memt, romh, sc->bases, codebase); 174 1.13 skrll if (rc != 0) { 175 1.13 skrll free(rom, M_DEVBUF); 176 1.13 skrll return rc; 177 1.13 skrll } 178 1.13 skrll 179 1.13 skrll sc->sc_rom = rom; 180 1.13 skrll 181 1.13 skrll sti_describe(sc); 182 1.13 skrll 183 1.13 skrll sc->sc_scr = sti_attach_screen(sc, 184 1.13 skrll sc->sc_flags & STI_CONSOLE ? 0 : STI_CLEARSCR); 185 1.13 skrll if (sc->sc_scr == NULL) 186 1.13 skrll rc = ENOMEM; 187 1.13 skrll 188 1.13 skrll return rc; 189 1.13 skrll } 190 1.13 skrll 191 1.13 skrll struct sti_screen * 192 1.13 skrll sti_attach_screen(struct sti_softc *sc, int flags) 193 1.13 skrll { 194 1.13 skrll struct sti_screen *scr; 195 1.13 skrll int rc; 196 1.13 skrll 197 1.13 skrll scr = (struct sti_screen *)malloc(sizeof(*scr), M_DEVBUF, 198 1.20 chs M_WAITOK | M_ZERO); 199 1.13 skrll scr->scr_rom = sc->sc_rom; 200 1.13 skrll rc = sti_screen_setup(scr, flags); 201 1.13 skrll if (rc != 0) { 202 1.13 skrll free(scr, M_DEVBUF); 203 1.13 skrll return NULL; 204 1.13 skrll } 205 1.1 jkunz 206 1.13 skrll sti_describe_screen(sc, scr); 207 1.1 jkunz 208 1.13 skrll return scr; 209 1.13 skrll } 210 1.1 jkunz 211 1.13 skrll int 212 1.13 skrll sti_rom_setup(struct sti_rom *rom, bus_space_tag_t iot, bus_space_tag_t memt, 213 1.13 skrll bus_space_handle_t romh, bus_addr_t *bases, u_int codebase) 214 1.1 jkunz { 215 1.1 jkunz struct sti_dd *dd; 216 1.1 jkunz int error, size, i; 217 1.1 jkunz 218 1.13 skrll KASSERT(rom != NULL); 219 1.13 skrll STI_ENABLE_ROM(rom->rom_softc); 220 1.13 skrll 221 1.13 skrll rom->iot = iot; 222 1.13 skrll rom->memt = memt; 223 1.13 skrll rom->romh = romh; 224 1.13 skrll rom->bases = bases; 225 1.13 skrll 226 1.13 skrll /* 227 1.13 skrll * Get ROM header and code function pointers. 228 1.13 skrll */ 229 1.23 tsutsui 230 1.13 skrll dd = &rom->rom_dd; 231 1.13 skrll rom->rom_devtype = bus_space_read_1(memt, romh, 3); 232 1.13 skrll if (rom->rom_devtype == STI_DEVTYPE1) { 233 1.23 tsutsui dd->dd_type = bus_space_read_1(memt, romh, 0x03); 234 1.23 tsutsui dd->dd_nmon = bus_space_read_1(memt, romh, 0x07); 235 1.23 tsutsui dd->dd_grrev = bus_space_read_1(memt, romh, 0x0b); 236 1.23 tsutsui dd->dd_lrrev = bus_space_read_1(memt, romh, 0x0f); 237 1.23 tsutsui dd->dd_grid[0] = parseword(0x10); 238 1.23 tsutsui dd->dd_grid[1] = parseword(0x20); 239 1.23 tsutsui dd->dd_fntaddr = parseword(0x30) & ~3; 240 1.23 tsutsui dd->dd_maxst = parseword(0x40); 241 1.23 tsutsui dd->dd_romend = parseword(0x50) & ~3; 242 1.23 tsutsui dd->dd_reglst = parseword(0x60) & ~3; 243 1.23 tsutsui dd->dd_maxreent = parseshort(0x70); 244 1.23 tsutsui dd->dd_maxtimo = parseshort(0x78); 245 1.23 tsutsui dd->dd_montbl = parseword(0x80) & ~3; 246 1.23 tsutsui dd->dd_udaddr = parseword(0x90) & ~3; 247 1.23 tsutsui dd->dd_stimemreq = parseword(0xa0); 248 1.23 tsutsui dd->dd_udsize = parseword(0xb0); 249 1.23 tsutsui dd->dd_pwruse = parseshort(0xc0); 250 1.23 tsutsui dd->dd_bussup = bus_space_read_1(memt, romh, 0xcb); 251 1.23 tsutsui dd->dd_ebussup = bus_space_read_1(memt, romh, 0xcf); 252 1.23 tsutsui dd->dd_altcodet = bus_space_read_1(memt, romh, 0xd3); 253 1.23 tsutsui dd->dd_eddst[0] = bus_space_read_1(memt, romh, 0xd7); 254 1.23 tsutsui dd->dd_eddst[1] = bus_space_read_1(memt, romh, 0xdb); 255 1.23 tsutsui dd->dd_eddst[2] = bus_space_read_1(memt, romh, 0xdf); 256 1.23 tsutsui dd->dd_cfbaddr = parseword(0xe0) & ~3; 257 1.1 jkunz 258 1.13 skrll codebase <<= 2; 259 1.23 tsutsui dd->dd_pacode[0x0] = parseword(codebase + 0x000) & ~3; 260 1.23 tsutsui dd->dd_pacode[0x1] = parseword(codebase + 0x010) & ~3; 261 1.23 tsutsui dd->dd_pacode[0x2] = parseword(codebase + 0x020) & ~3; 262 1.23 tsutsui dd->dd_pacode[0x3] = parseword(codebase + 0x030) & ~3; 263 1.23 tsutsui dd->dd_pacode[0x4] = parseword(codebase + 0x040) & ~3; 264 1.23 tsutsui dd->dd_pacode[0x5] = parseword(codebase + 0x050) & ~3; 265 1.23 tsutsui dd->dd_pacode[0x6] = parseword(codebase + 0x060) & ~3; 266 1.23 tsutsui dd->dd_pacode[0x7] = parseword(codebase + 0x070) & ~3; 267 1.23 tsutsui dd->dd_pacode[0x8] = parseword(codebase + 0x080) & ~3; 268 1.23 tsutsui dd->dd_pacode[0x9] = parseword(codebase + 0x090) & ~3; 269 1.23 tsutsui dd->dd_pacode[0xa] = parseword(codebase + 0x0a0) & ~3; 270 1.23 tsutsui dd->dd_pacode[0xb] = parseword(codebase + 0x0b0) & ~3; 271 1.23 tsutsui dd->dd_pacode[0xc] = parseword(codebase + 0x0c0) & ~3; 272 1.23 tsutsui dd->dd_pacode[0xd] = parseword(codebase + 0x0d0) & ~3; 273 1.23 tsutsui dd->dd_pacode[0xe] = parseword(codebase + 0x0e0) & ~3; 274 1.23 tsutsui dd->dd_pacode[0xf] = parseword(codebase + 0x0f0) & ~3; 275 1.13 skrll } else { /* STI_DEVTYPE4 */ 276 1.13 skrll bus_space_read_region_stream_4(memt, romh, 0, (uint32_t *)dd, 277 1.1 jkunz sizeof(*dd) / 4); 278 1.13 skrll /* fix pacode... */ 279 1.13 skrll bus_space_read_region_stream_4(memt, romh, codebase, 280 1.13 skrll (uint32_t *)dd->dd_pacode, sizeof(dd->dd_pacode) / 4); 281 1.13 skrll } 282 1.13 skrll 283 1.13 skrll STI_DISABLE_ROM(rom->rom_softc); 284 1.1 jkunz 285 1.13 skrll DPRINTF(("dd:\n" 286 1.13 skrll "devtype=%x, rev=%x;%d, altt=%x, gid=%08x%08x, font=%x, mss=%x\n" 287 1.1 jkunz "end=%x, regions=%x, msto=%x, timo=%d, mont=%x, user=%x[%x]\n" 288 1.1 jkunz "memrq=%x, pwr=%d, bus=%x, ebus=%x, cfb=%x\n" 289 1.1 jkunz "code=", 290 1.1 jkunz dd->dd_type & 0xff, dd->dd_grrev, dd->dd_lrrev, dd->dd_altcodet, 291 1.13 skrll dd->dd_grid[0], dd->dd_grid[1], dd->dd_fntaddr, dd->dd_maxst, 292 1.1 jkunz dd->dd_romend, dd->dd_reglst, dd->dd_maxreent, dd->dd_maxtimo, 293 1.1 jkunz dd->dd_montbl, dd->dd_udaddr, dd->dd_udsize, dd->dd_stimemreq, 294 1.13 skrll dd->dd_pwruse, dd->dd_bussup, dd->dd_ebussup, dd->dd_cfbaddr)); 295 1.13 skrll DPRINTF(("%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x\n", 296 1.1 jkunz dd->dd_pacode[0x0], dd->dd_pacode[0x1], dd->dd_pacode[0x2], 297 1.1 jkunz dd->dd_pacode[0x3], dd->dd_pacode[0x4], dd->dd_pacode[0x5], 298 1.1 jkunz dd->dd_pacode[0x6], dd->dd_pacode[0x7], dd->dd_pacode[0x8], 299 1.1 jkunz dd->dd_pacode[0x9], dd->dd_pacode[0xa], dd->dd_pacode[0xb], 300 1.1 jkunz dd->dd_pacode[0xc], dd->dd_pacode[0xd], dd->dd_pacode[0xe], 301 1.13 skrll dd->dd_pacode[0xf])); 302 1.13 skrll 303 1.13 skrll /* 304 1.13 skrll * Figure out how many bytes we need for the STI code. 305 1.13 skrll * Note there could be fewer than STI_END pointer entries 306 1.13 skrll * populated, especially on older devices. 307 1.13 skrll */ 308 1.23 tsutsui for (i = STI_END; dd->dd_pacode[i] == 0; i--) 309 1.13 skrll ; 310 1.13 skrll 311 1.1 jkunz size = dd->dd_pacode[i] - dd->dd_pacode[STI_BEGIN]; 312 1.13 skrll 313 1.13 skrll if (rom->rom_devtype == STI_DEVTYPE1) 314 1.1 jkunz size = (size + 3) / 4; 315 1.13 skrll if (size == 0) { 316 1.13 skrll aprint_error(": no code for the requested platform\n"); 317 1.13 skrll return EINVAL; 318 1.13 skrll } 319 1.13 skrll 320 1.13 skrll if (!(rom->rom_code = uvm_km_alloc(kernel_map, round_page(size), 0, 321 1.4 yamt UVM_KMF_WIRED))) { 322 1.13 skrll aprint_error(": cannot allocate %u bytes for code\n", size); 323 1.13 skrll return ENOMEM; 324 1.1 jkunz } 325 1.23 tsutsui DPRINTF(("code=0x%lx[%x]\n", rom->rom_code, size)); 326 1.1 jkunz 327 1.13 skrll /* 328 1.13 skrll * Copy code into memory and make it executable. 329 1.13 skrll */ 330 1.13 skrll 331 1.13 skrll STI_ENABLE_ROM(rom->rom_softc); 332 1.13 skrll 333 1.13 skrll if (rom->rom_devtype == STI_DEVTYPE1) { 334 1.13 skrll uint8_t *p; 335 1.13 skrll uint32_t addr, eaddr; 336 1.13 skrll 337 1.13 skrll p = (uint8_t *)rom->rom_code; 338 1.13 skrll 339 1.1 jkunz for (addr = dd->dd_pacode[STI_BEGIN], eaddr = addr + size * 4; 340 1.13 skrll addr < eaddr; addr += 4 ) { 341 1.23 tsutsui *p++ = bus_space_read_4(memt, romh, addr) & 0xff; 342 1.13 skrll } 343 1.13 skrll } else { /* STI_DEVTYPE4 */ 344 1.13 skrll bus_space_read_region_stream_4(memt, romh, 345 1.13 skrll dd->dd_pacode[STI_BEGIN], (uint32_t *)rom->rom_code, 346 1.13 skrll size / 4); 347 1.13 skrll } 348 1.1 jkunz 349 1.13 skrll STI_DISABLE_ROM(rom->rom_softc); 350 1.1 jkunz 351 1.13 skrll if ((error = uvm_map_protect(kernel_map, rom->rom_code, 352 1.13 skrll rom->rom_code + round_page(size), UVM_PROT_RX, FALSE))) { 353 1.13 skrll aprint_error(": uvm_map_protect failed (%d)\n", error); 354 1.13 skrll uvm_km_free(kernel_map, rom->rom_code, round_page(size), 355 1.4 yamt UVM_KMF_WIRED); 356 1.13 skrll return error; 357 1.13 skrll } 358 1.13 skrll 359 1.13 skrll /* 360 1.13 skrll * Setup code function pointers. 361 1.13 skrll */ 362 1.13 skrll 363 1.13 skrll #define O(i) \ 364 1.13 skrll (dd->dd_pacode[(i)] == 0 ? 0 : \ 365 1.13 skrll (rom->rom_code + (dd->dd_pacode[(i)] - dd->dd_pacode[0]) / \ 366 1.13 skrll (rom->rom_devtype == STI_DEVTYPE1 ? 4 : 1))) 367 1.23 tsutsui 368 1.23 tsutsui rom->init = (sti_init_t)O(STI_INIT_GRAPH); 369 1.23 tsutsui rom->mgmt = (sti_mgmt_t)O(STI_STATE_MGMT); 370 1.23 tsutsui rom->unpmv = (sti_unpmv_t)O(STI_FONT_UNPMV); 371 1.23 tsutsui rom->blkmv = (sti_blkmv_t)O(STI_BLOCK_MOVE); 372 1.23 tsutsui rom->test = (sti_test_t)O(STI_SELF_TEST); 373 1.23 tsutsui rom->exhdl = (sti_exhdl_t)O(STI_EXCEP_HDLR); 374 1.13 skrll rom->inqconf = (sti_inqconf_t)O(STI_INQ_CONF); 375 1.13 skrll rom->scment = (sti_scment_t)O(STI_SCM_ENT); 376 1.23 tsutsui rom->dmac = (sti_dmac_t)O(STI_DMA_CTRL); 377 1.23 tsutsui rom->flowc = (sti_flowc_t)O(STI_FLOW_CTRL); 378 1.13 skrll rom->utiming = (sti_utiming_t)O(STI_UTIMING); 379 1.23 tsutsui rom->pmgr = (sti_pmgr_t)O(STI_PROC_MGR); 380 1.23 tsutsui rom->util = (sti_util_t)O(STI_UTIL); 381 1.13 skrll 382 1.13 skrll #undef O 383 1.23 tsutsui 384 1.13 skrll /* 385 1.13 skrll * Set colormap entry is not implemented until 8.04, so force 386 1.13 skrll * a NULL pointer here. 387 1.13 skrll */ 388 1.13 skrll if (dd->dd_grrev < STI_REVISION(8, 4)) { 389 1.13 skrll rom->scment = NULL; 390 1.13 skrll } 391 1.13 skrll 392 1.13 skrll return 0; 393 1.13 skrll } 394 1.13 skrll 395 1.13 skrll /* 396 1.13 skrll * Map all regions. 397 1.13 skrll */ 398 1.13 skrll void 399 1.13 skrll sti_region_setup(struct sti_screen *scr) 400 1.13 skrll { 401 1.13 skrll struct sti_rom *rom = scr->scr_rom; 402 1.13 skrll bus_space_tag_t memt = rom->memt; 403 1.13 skrll bus_space_handle_t romh = rom->romh; 404 1.13 skrll bus_addr_t *bases = rom->bases; 405 1.13 skrll struct sti_dd *dd = &rom->rom_dd; 406 1.13 skrll struct sti_cfg *cc = &scr->scr_cfg; 407 1.13 skrll struct sti_region regions[STI_REGION_MAX], *r; 408 1.13 skrll u_int regno, regcnt; 409 1.13 skrll bus_addr_t addr; 410 1.13 skrll 411 1.13 skrll DPRINTF(("stiregions @ %x:\n", dd->dd_reglst)); 412 1.13 skrll 413 1.13 skrll /* 414 1.13 skrll * Read the region information. 415 1.13 skrll */ 416 1.13 skrll 417 1.13 skrll STI_ENABLE_ROM(rom->rom_softc); 418 1.13 skrll 419 1.13 skrll if (rom->rom_devtype == STI_DEVTYPE1) { 420 1.13 skrll for (regno = 0; regno < STI_REGION_MAX; regno++) 421 1.13 skrll *(u_int *)(regions + regno) = 422 1.13 skrll parseword(dd->dd_reglst + regno * 0x10); 423 1.13 skrll } else { 424 1.13 skrll bus_space_read_region_stream_4(memt, romh, dd->dd_reglst, 425 1.13 skrll (uint32_t *)regions, sizeof(regions) / 4); 426 1.1 jkunz } 427 1.1 jkunz 428 1.13 skrll STI_DISABLE_ROM(rom->rom_softc); 429 1.13 skrll 430 1.13 skrll /* 431 1.13 skrll * Count them. 432 1.13 skrll */ 433 1.13 skrll 434 1.13 skrll for (regcnt = 0, r = regions; regcnt < STI_REGION_MAX; regcnt++, r++) 435 1.13 skrll if (r->last) 436 1.13 skrll break; 437 1.13 skrll regcnt++; 438 1.13 skrll 439 1.13 skrll /* 440 1.13 skrll * Map them. 441 1.13 skrll */ 442 1.13 skrll 443 1.13 skrll for (regno = 0, r = regions; regno < regcnt; regno++, r++) { 444 1.13 skrll if (r->length == 0) 445 1.13 skrll continue; 446 1.13 skrll 447 1.13 skrll /* 448 1.13 skrll * Assume an existing mapping exists. 449 1.13 skrll */ 450 1.46 tsutsui addr = bases[regno] + (r->offset << STI_PGSHIFT); 451 1.13 skrll DPRINTF(("%08x @ 0x%08x%s%s%s%s", 452 1.46 tsutsui r->length << STI_PGSHIFT, (int)addr, 453 1.46 tsutsui r->sys_only ? " sys" : "", 454 1.13 skrll r->cache ? " cache" : "", r->btlb ? " btlb" : "", 455 1.13 skrll r->last ? " last" : "")); 456 1.13 skrll 457 1.13 skrll /* 458 1.13 skrll * Region #0 is always the rom, and it should have been 459 1.13 skrll * mapped already. 460 1.13 skrll * XXX This expects a 1:1 mapping... 461 1.13 skrll */ 462 1.13 skrll if (regno == 0 && romh == bases[0]) { 463 1.13 skrll cc->regions[0] = addr; 464 1.14 skrll DPRINTF(("\n")); 465 1.13 skrll continue; 466 1.13 skrll } 467 1.13 skrll 468 1.46 tsutsui if (bus_space_map(memt, addr, r->length << STI_PGSHIFT, 469 1.23 tsutsui BUS_SPACE_MAP_LINEAR | (r->cache ? 470 1.23 tsutsui BUS_SPACE_MAP_CACHEABLE : 0), &rom->regh[regno]) != 0) { 471 1.23 tsutsui rom->regh[regno] = romh; /* XXX */ 472 1.13 skrll DPRINTF((" - already mapped region\n")); 473 1.13 skrll } else { 474 1.23 tsutsui addr = (bus_addr_t) 475 1.23 tsutsui bus_space_vaddr(memt, rom->regh[regno]); 476 1.13 skrll if (regno == 1) { 477 1.14 skrll DPRINTF((" - fb")); 478 1.13 skrll scr->fbaddr = addr; 479 1.46 tsutsui scr->fblen = r->length << STI_PGSHIFT; 480 1.13 skrll } 481 1.14 skrll DPRINTF(("\n")); 482 1.13 skrll } 483 1.1 jkunz 484 1.13 skrll cc->regions[regno] = addr; 485 1.13 skrll } 486 1.1 jkunz 487 1.1 jkunz #ifdef STIDEBUG 488 1.13 skrll /* 489 1.13 skrll * Make sure we'll trap accessing unmapped regions 490 1.13 skrll */ 491 1.13 skrll for (regno = 0; regno < STI_REGION_MAX; regno++) 492 1.13 skrll if (cc->regions[regno] == 0) 493 1.47 tsutsui cc->regions[regno] = 0x81234567; 494 1.1 jkunz #endif 495 1.13 skrll } 496 1.1 jkunz 497 1.13 skrll int 498 1.13 skrll sti_screen_setup(struct sti_screen *scr, int flags) 499 1.13 skrll { 500 1.13 skrll struct sti_rom *rom = scr->scr_rom; 501 1.13 skrll bus_space_tag_t memt = rom->memt; 502 1.13 skrll bus_space_handle_t romh = rom->romh; 503 1.13 skrll struct sti_dd *dd = &rom->rom_dd; 504 1.13 skrll struct sti_cfg *cc = &scr->scr_cfg; 505 1.13 skrll struct sti_inqconfout cfg; 506 1.13 skrll struct sti_einqconfout ecfg; 507 1.1 jkunz #ifdef STIDEBUG 508 1.13 skrll char buf[256]; 509 1.1 jkunz #endif 510 1.13 skrll int error, i; 511 1.13 skrll int geometry_kluge = 0; 512 1.13 skrll u_int fontindex = 0; 513 1.13 skrll 514 1.13 skrll KASSERT(scr != NULL); 515 1.13 skrll memset(cc, 0, sizeof(*cc)); 516 1.13 skrll cc->ext_cfg = &scr->scr_ecfg; 517 1.13 skrll memset(cc->ext_cfg, 0, sizeof(*cc->ext_cfg)); 518 1.13 skrll 519 1.13 skrll if (dd->dd_stimemreq) { 520 1.13 skrll scr->scr_ecfg.addr = 521 1.20 chs malloc(dd->dd_stimemreq, M_DEVBUF, M_WAITOK); 522 1.1 jkunz } 523 1.1 jkunz 524 1.13 skrll sti_region_setup(scr); 525 1.13 skrll 526 1.13 skrll if ((error = sti_init(scr, 0))) { 527 1.13 skrll aprint_error(": cannot initialize (%d)\n", error); 528 1.13 skrll goto fail; 529 1.1 jkunz } 530 1.1 jkunz 531 1.1 jkunz memset(&cfg, 0, sizeof(cfg)); 532 1.1 jkunz memset(&ecfg, 0, sizeof(ecfg)); 533 1.1 jkunz cfg.ext = &ecfg; 534 1.13 skrll if ((error = sti_inqcfg(scr, &cfg))) { 535 1.13 skrll aprint_error(": error %d inquiring config\n", error); 536 1.13 skrll goto fail; 537 1.1 jkunz } 538 1.1 jkunz 539 1.13 skrll /* 540 1.13 skrll * Older (rev 8.02) boards report wrong offset values, 541 1.13 skrll * similar to the displayable area size, at least in m68k mode. 542 1.13 skrll * Attempt to detect this and adjust here. 543 1.13 skrll */ 544 1.13 skrll if (cfg.owidth == cfg.width && 545 1.13 skrll cfg.oheight == cfg.height) 546 1.13 skrll geometry_kluge = 1; 547 1.13 skrll 548 1.13 skrll if (geometry_kluge) { 549 1.13 skrll scr->scr_cfg.oscr_width = cfg.owidth = 550 1.13 skrll cfg.fbwidth - cfg.width; 551 1.13 skrll scr->scr_cfg.oscr_height = cfg.oheight = 552 1.13 skrll cfg.fbheight - cfg.height; 553 1.1 jkunz } 554 1.1 jkunz 555 1.13 skrll /* 556 1.13 skrll * Save a few fields for sti_describe_screen() later 557 1.13 skrll */ 558 1.13 skrll scr->fbheight = cfg.fbheight; 559 1.13 skrll scr->fbwidth = cfg.fbwidth; 560 1.13 skrll scr->oheight = cfg.oheight; 561 1.13 skrll scr->owidth = cfg.owidth; 562 1.13 skrll memcpy(scr->name, cfg.name, sizeof(scr->name)); 563 1.13 skrll 564 1.35 macallan if (flags & STI_FBMODE) { 565 1.35 macallan /* we're done here */ 566 1.35 macallan sti_init(scr, STI_FBMODE); 567 1.35 macallan return 0; 568 1.35 macallan } 569 1.35 macallan 570 1.13 skrll if ((error = sti_init(scr, STI_TEXTMODE | flags))) { 571 1.13 skrll aprint_error(": cannot initialize (%d)\n", error); 572 1.13 skrll goto fail; 573 1.13 skrll } 574 1.1 jkunz #ifdef STIDEBUG 575 1.13 skrll snprintb(buf, sizeof(buf), STI_INQCONF_BITS, cfg.attributes); 576 1.13 skrll DPRINTF(("conf: bpp=%d planes=%d attr=%s\n" 577 1.13 skrll "crt=0x%x:0x%x:0x%x hw=0x%x:0x%x:0x%x\n", cfg.bpp, 578 1.13 skrll cfg.planes, buf, 579 1.1 jkunz ecfg.crt_config[0], ecfg.crt_config[1], ecfg.crt_config[2], 580 1.13 skrll ecfg.crt_hw[0], ecfg.crt_hw[1], ecfg.crt_hw[2])); 581 1.1 jkunz #endif 582 1.13 skrll scr->scr_bpp = cfg.bppu; 583 1.13 skrll 584 1.13 skrll /* 585 1.13 skrll * Although scr->scr_ecfg.current_monitor is not filled by 586 1.13 skrll * sti_init() as expected, we can nevertheless walk the monitor 587 1.13 skrll * list, if there is any, and if we find a mode matching our 588 1.13 skrll * resolution, pick its font index. 589 1.13 skrll */ 590 1.13 skrll if (dd->dd_montbl != 0) { 591 1.13 skrll STI_ENABLE_ROM(rom->rom_softc); 592 1.13 skrll 593 1.13 skrll for (i = 0; i < dd->dd_nmon; i++) { 594 1.13 skrll u_int offs = dd->dd_montbl + 8 * i; 595 1.13 skrll uint32_t m[2]; 596 1.13 skrll sti_mon_t mon = (void *)m; 597 1.13 skrll if (rom->rom_devtype == STI_DEVTYPE1) { 598 1.13 skrll m[0] = parseword(4 * offs); 599 1.13 skrll m[1] = parseword(4 * (offs + 4)); 600 1.13 skrll } else { 601 1.13 skrll bus_space_read_region_stream_4(memt, romh, offs, 602 1.13 skrll (uint32_t *)mon, sizeof(*mon) / 4); 603 1.13 skrll } 604 1.13 skrll 605 1.13 skrll if (mon->width == scr->scr_cfg.scr_width && 606 1.13 skrll mon->height == scr->scr_cfg.scr_height) { 607 1.13 skrll fontindex = mon->font; 608 1.13 skrll break; 609 1.13 skrll } 610 1.13 skrll } 611 1.13 skrll 612 1.13 skrll STI_DISABLE_ROM(rom->rom_softc); 613 1.13 skrll 614 1.13 skrll DPRINTF(("font index: %d\n", fontindex)); 615 1.13 skrll } 616 1.13 skrll 617 1.13 skrll if ((error = sti_fetchfonts(scr, &cfg, dd->dd_fntaddr, fontindex))) { 618 1.13 skrll aprint_error(": cannot fetch fonts (%d)\n", error); 619 1.13 skrll goto fail; 620 1.1 jkunz } 621 1.1 jkunz 622 1.1 jkunz /* 623 1.13 skrll * setup screen descriptions: 624 1.1 jkunz * figure number of fonts supported; 625 1.1 jkunz * allocate wscons structures; 626 1.1 jkunz * calculate dimensions. 627 1.1 jkunz */ 628 1.1 jkunz 629 1.13 skrll scr->scr_wsd.name = "std"; 630 1.13 skrll scr->scr_wsd.ncols = cfg.width / scr->scr_curfont.width; 631 1.13 skrll scr->scr_wsd.nrows = cfg.height / scr->scr_curfont.height; 632 1.13 skrll scr->scr_wsd.textops = &sti_emulops; 633 1.13 skrll scr->scr_wsd.fontwidth = scr->scr_curfont.width; 634 1.13 skrll scr->scr_wsd.fontheight = scr->scr_curfont.height; 635 1.24 tsutsui scr->scr_wsd.capabilities = WSSCREEN_REVERSE; 636 1.13 skrll 637 1.13 skrll scr->scr_scrlist[0] = &scr->scr_wsd; 638 1.13 skrll scr->scr_screenlist.nscreens = 1; 639 1.16 matt scr->scr_screenlist.screens = scr->scr_scrlist; 640 1.1 jkunz 641 1.23 tsutsui #ifndef SMALL_KERNEL 642 1.23 tsutsui /* 643 1.23 tsutsui * Decide which board-specific routines to use. 644 1.23 tsutsui */ 645 1.23 tsutsui 646 1.23 tsutsui switch (dd->dd_grid[0]) { 647 1.23 tsutsui case STI_DD_CRX: 648 1.23 tsutsui scr->setupfb = ngle_elk_setupfb; 649 1.23 tsutsui scr->putcmap = ngle_putcmap; 650 1.23 tsutsui 651 1.23 tsutsui scr->reg10_value = 0x13601000; 652 1.23 tsutsui if (scr->scr_bpp > 8) 653 1.23 tsutsui scr->reg12_value = NGLE_BUFF1_CMAP3; 654 1.23 tsutsui else 655 1.23 tsutsui scr->reg12_value = NGLE_BUFF1_CMAP0; 656 1.23 tsutsui scr->cmap_finish_register = NGLE_REG_1; 657 1.23 tsutsui break; 658 1.23 tsutsui 659 1.23 tsutsui case STI_DD_TIMBER: 660 1.23 tsutsui scr->setupfb = ngle_timber_setupfb; 661 1.23 tsutsui scr->putcmap = ngle_putcmap; 662 1.23 tsutsui 663 1.23 tsutsui scr->reg10_value = 0x13602000; 664 1.23 tsutsui scr->reg12_value = NGLE_BUFF1_CMAP0; 665 1.23 tsutsui scr->cmap_finish_register = NGLE_REG_1; 666 1.23 tsutsui break; 667 1.23 tsutsui 668 1.23 tsutsui case STI_DD_ARTIST: 669 1.23 tsutsui scr->setupfb = ngle_artist_setupfb; 670 1.23 tsutsui scr->putcmap = ngle_putcmap; 671 1.23 tsutsui 672 1.23 tsutsui scr->reg10_value = 0x13601000; 673 1.23 tsutsui scr->reg12_value = NGLE_ARTIST_CMAP0; 674 1.23 tsutsui scr->cmap_finish_register = NGLE_REG_26; 675 1.23 tsutsui break; 676 1.23 tsutsui 677 1.23 tsutsui case STI_DD_EG: 678 1.23 tsutsui scr->setupfb = ngle_artist_setupfb; 679 1.23 tsutsui scr->putcmap = ngle_putcmap; 680 1.23 tsutsui 681 1.23 tsutsui scr->reg10_value = 0x13601000; 682 1.23 tsutsui if (scr->scr_bpp > 8) { 683 1.23 tsutsui scr->reg12_value = NGLE_BUFF1_CMAP3; 684 1.23 tsutsui scr->cmap_finish_register = NGLE_REG_1; 685 1.23 tsutsui } else { 686 1.23 tsutsui scr->reg12_value = NGLE_ARTIST_CMAP0; 687 1.23 tsutsui scr->cmap_finish_register = NGLE_REG_26; 688 1.23 tsutsui } 689 1.23 tsutsui break; 690 1.23 tsutsui 691 1.36 macallan case STI_DD_HCRX: 692 1.36 macallan scr->setupfb = ngle_elk_setupfb; 693 1.37 macallan scr->putcmap = ngle_hcrx_putcmap; 694 1.36 macallan 695 1.36 macallan if (scr->scr_bpp > 8) { 696 1.36 macallan scr->reg12_value = NGLE_BUFF1_CMAP3; 697 1.36 macallan scr->reg10_value = 0xBBA0A000; 698 1.36 macallan } else { 699 1.36 macallan scr->reg12_value = NGLE_BUFF1_CMAP0; 700 1.36 macallan scr->reg10_value = 0x13602000; 701 1.36 macallan } 702 1.37 macallan scr->cmap_finish_register = NGLE_REG_38; 703 1.36 macallan break; 704 1.36 macallan 705 1.40 macallan case STI_DD_SUMMIT: 706 1.42 macallan case STI_DD_LEGO: 707 1.40 macallan scr->setupfb = summit_setupfb; 708 1.40 macallan scr->putcmap = summit_putcmap; 709 1.40 macallan scr->scr_bpp = 8; /* for now */ 710 1.40 macallan break; 711 1.40 macallan 712 1.44 tsutsui case STI_DD_EVRX: 713 1.44 tsutsui case STI_DD_382C: 714 1.44 tsutsui case STI_DD_3X2V: 715 1.44 tsutsui /* 716 1.44 tsutsui * EVRX, 382C, and 3X2V are available only on hp300 models 717 1.44 tsutsui * and board specific routines are handled by MD 718 1.44 tsutsui * sti_machdep_attach() in arch/hp300/dev/sti_machdep.c. 719 1.44 tsutsui */ 720 1.44 tsutsui break; 721 1.44 tsutsui 722 1.23 tsutsui case STI_DD_GRX: 723 1.23 tsutsui case STI_DD_CRX24: 724 1.23 tsutsui case STI_DD_DUAL_CRX: 725 1.23 tsutsui case STI_DD_PINNACLE: 726 1.23 tsutsui default: 727 1.23 tsutsui scr->setupfb = NULL; 728 1.23 tsutsui scr->putcmap = 729 1.23 tsutsui rom->scment == NULL ? NULL : ngle_default_putcmap; 730 1.23 tsutsui break; 731 1.23 tsutsui } 732 1.23 tsutsui #endif 733 1.23 tsutsui 734 1.13 skrll return 0; 735 1.13 skrll 736 1.13 skrll fail: 737 1.13 skrll /* XXX free resources */ 738 1.13 skrll if (scr->scr_ecfg.addr != NULL) { 739 1.13 skrll free(scr->scr_ecfg.addr, M_DEVBUF); 740 1.13 skrll scr->scr_ecfg.addr = NULL; 741 1.13 skrll } 742 1.13 skrll 743 1.13 skrll return ENXIO; 744 1.13 skrll } 745 1.13 skrll 746 1.13 skrll void 747 1.13 skrll sti_describe_screen(struct sti_softc *sc, struct sti_screen *scr) 748 1.13 skrll { 749 1.13 skrll struct sti_font *fp = &scr->scr_curfont; 750 1.13 skrll 751 1.13 skrll aprint_normal("%s: %s, %dx%d frame buffer, %dx%dx%d display\n", 752 1.13 skrll device_xname(sc->sc_dev), scr->name, scr->fbwidth, scr->fbheight, 753 1.13 skrll scr->scr_cfg.scr_width, scr->scr_cfg.scr_height, scr->scr_bpp); 754 1.13 skrll 755 1.13 skrll aprint_normal("%s: %dx%d font type %d, %d bpc, charset %d-%d\n", 756 1.13 skrll device_xname(sc->sc_dev), fp->width, fp->height, 757 1.13 skrll fp->type, fp->bpc, fp->first, fp->last); 758 1.13 skrll } 759 1.13 skrll 760 1.13 skrll void 761 1.13 skrll sti_describe(struct sti_softc *sc) 762 1.13 skrll { 763 1.13 skrll struct sti_rom *rom = sc->sc_rom; 764 1.13 skrll struct sti_dd *dd = &rom->rom_dd; 765 1.13 skrll 766 1.13 skrll aprint_normal(": rev %d.%02d;%d, ID 0x%08X%08X\n", 767 1.13 skrll dd->dd_grrev >> 4, dd->dd_grrev & 0xf, 768 1.13 skrll dd->dd_lrrev, dd->dd_grid[0], dd->dd_grid[1]); 769 1.1 jkunz 770 1.13 skrll if (sc->sc_scr != NULL) 771 1.13 skrll sti_describe_screen(sc, sc->sc_scr); 772 1.1 jkunz } 773 1.1 jkunz 774 1.23 tsutsui /* 775 1.23 tsutsui * Final part of attachment. On hppa where we use the PDC console 776 1.23 tsutsui * during autoconf, this has to be postponed until autoconf has 777 1.23 tsutsui * completed. 778 1.23 tsutsui */ 779 1.1 jkunz void 780 1.13 skrll sti_end_attach(struct sti_softc *sc) 781 1.1 jkunz { 782 1.13 skrll struct sti_screen *scr = sc->sc_scr; 783 1.13 skrll 784 1.13 skrll if (scr == NULL) 785 1.13 skrll return; 786 1.13 skrll #if NWSDISPLAY > 0 787 1.13 skrll else { 788 1.13 skrll struct wsemuldisplaydev_attach_args waa; 789 1.13 skrll scr->scr_wsmode = WSDISPLAYIO_MODE_EMUL; 790 1.13 skrll 791 1.13 skrll waa.console = sc->sc_flags & STI_CONSOLE ? 1 : 0; 792 1.13 skrll waa.scrdata = &scr->scr_screenlist; 793 1.13 skrll waa.accessops = &sti_accessops; 794 1.13 skrll waa.accesscookie = scr; 795 1.13 skrll 796 1.13 skrll /* attach as console if required */ 797 1.13 skrll if (waa.console && !ISSET(sc->sc_flags, STI_ATTACHED)) { 798 1.13 skrll long defattr; 799 1.13 skrll 800 1.13 skrll sti_alloc_attr(scr, 0, 0, 0, &defattr); 801 1.13 skrll wsdisplay_cnattach(&scr->scr_wsd, scr, 802 1.13 skrll 0, scr->scr_wsd.nrows - 1, defattr); 803 1.13 skrll sc->sc_flags |= STI_ATTACHED; 804 1.13 skrll } 805 1.13 skrll 806 1.30 thorpej config_found(sc->sc_dev, &waa, wsemuldisplaydevprint, 807 1.31 thorpej CFARGS_NONE); 808 1.13 skrll } 809 1.13 skrll #endif 810 1.13 skrll } 811 1.1 jkunz 812 1.13 skrll u_int 813 1.13 skrll sti_rom_size(bus_space_tag_t memt, bus_space_handle_t romh) 814 1.13 skrll { 815 1.13 skrll int devtype; 816 1.13 skrll u_int romend; 817 1.1 jkunz 818 1.13 skrll devtype = bus_space_read_1(memt, romh, 3); 819 1.13 skrll if (devtype == STI_DEVTYPE4) { 820 1.13 skrll bus_space_read_region_stream_4(memt, romh, STI_DEV4_DD_ROMEND, 821 1.13 skrll (uint32_t *)&romend, 1); 822 1.13 skrll } else { 823 1.13 skrll romend = parseword(STI_DEV1_DD_ROMEND); 824 1.1 jkunz } 825 1.1 jkunz 826 1.13 skrll DPRINTF(("%s: %08x (%08x)\n", __func__, romend, round_page(romend))); 827 1.13 skrll 828 1.13 skrll return round_page(romend); 829 1.1 jkunz } 830 1.1 jkunz 831 1.1 jkunz int 832 1.13 skrll sti_fetchfonts(struct sti_screen *scr, struct sti_inqconfout *cfg, 833 1.13 skrll uint32_t baseaddr, u_int fontindex) 834 1.1 jkunz { 835 1.13 skrll struct sti_rom *rom = scr->scr_rom; 836 1.13 skrll bus_space_tag_t memt = rom->memt; 837 1.13 skrll bus_space_handle_t romh = rom->romh; 838 1.13 skrll struct sti_font *fp = &scr->scr_curfont; 839 1.13 skrll uint32_t addr; 840 1.1 jkunz int size; 841 1.1 jkunz #ifdef notyet 842 1.1 jkunz int uc; 843 1.1 jkunz struct { 844 1.1 jkunz struct sti_unpmvflags flags; 845 1.1 jkunz struct sti_unpmvin in; 846 1.1 jkunz struct sti_unpmvout out; 847 1.1 jkunz } a; 848 1.1 jkunz #endif 849 1.1 jkunz 850 1.1 jkunz /* 851 1.1 jkunz * Get the first PROM font in memory 852 1.1 jkunz */ 853 1.13 skrll 854 1.13 skrll STI_ENABLE_ROM(rom->rom_softc); 855 1.13 skrll 856 1.13 skrll rescan: 857 1.13 skrll addr = baseaddr; 858 1.1 jkunz do { 859 1.13 skrll if (rom->rom_devtype == STI_DEVTYPE1) { 860 1.1 jkunz fp->first = parseshort(addr + 0x00); 861 1.1 jkunz fp->last = parseshort(addr + 0x08); 862 1.13 skrll fp->width = bus_space_read_1(memt, romh, addr + 0x13); 863 1.13 skrll fp->height = bus_space_read_1(memt, romh, addr + 0x17); 864 1.13 skrll fp->type = bus_space_read_1(memt, romh, addr + 0x1b); 865 1.13 skrll fp->bpc = bus_space_read_1(memt, romh, addr + 0x1f); 866 1.13 skrll fp->next = parseword(addr + 0x20); 867 1.13 skrll fp->uheight= bus_space_read_1(memt, romh, addr + 0x33); 868 1.13 skrll fp->uoffset= bus_space_read_1(memt, romh, addr + 0x37); 869 1.13 skrll } else { /* STI_DEVTYPE4 */ 870 1.13 skrll bus_space_read_region_stream_4(memt, romh, addr, 871 1.12 skrll (uint32_t *)fp, sizeof(struct sti_font) / 4); 872 1.13 skrll } 873 1.1 jkunz 874 1.13 skrll #ifdef STIDEBUG 875 1.13 skrll STI_DISABLE_ROM(rom->rom_softc); 876 1.13 skrll DPRINTF(("%s: %dx%d font type %d, %d bpc, charset %d-%d\n", 877 1.45 tsutsui scr->scr_rom->rom_softc == NULL ? __func__ : 878 1.13 skrll device_xname(scr->scr_rom->rom_softc->sc_dev), fp->width, 879 1.13 skrll fp->height, fp->type, fp->bpc, fp->first, fp->last)); 880 1.13 skrll STI_ENABLE_ROM(rom->rom_softc); 881 1.13 skrll #endif 882 1.1 jkunz 883 1.13 skrll if (fontindex == 0) { 884 1.13 skrll size = sizeof(struct sti_font) + 885 1.13 skrll (fp->last - fp->first + 1) * fp->bpc; 886 1.13 skrll if (rom->rom_devtype == STI_DEVTYPE1) 887 1.13 skrll size *= 4; 888 1.20 chs scr->scr_romfont = malloc(size, M_DEVBUF, M_WAITOK); 889 1.1 jkunz 890 1.13 skrll bus_space_read_region_stream_4(memt, romh, addr, 891 1.13 skrll (uint32_t *)scr->scr_romfont, size / 4); 892 1.13 skrll break; 893 1.13 skrll } 894 1.13 skrll 895 1.13 skrll addr = baseaddr + fp->next; 896 1.13 skrll fontindex--; 897 1.13 skrll } while (fp->next != 0); 898 1.13 skrll 899 1.13 skrll /* 900 1.13 skrll * If our font index was bogus, we did not find the expected font. 901 1.13 skrll * In this case, pick the first one and be done with it. 902 1.13 skrll */ 903 1.13 skrll if (fp->next == 0 && scr->scr_romfont == NULL) { 904 1.13 skrll fontindex = 0; 905 1.13 skrll goto rescan; 906 1.13 skrll } 907 1.13 skrll 908 1.13 skrll STI_DISABLE_ROM(rom->rom_softc); 909 1.1 jkunz 910 1.1 jkunz #ifdef notyet 911 1.1 jkunz /* 912 1.1 jkunz * If there is enough room in the off-screen framebuffer memory, 913 1.1 jkunz * display all the characters there in order to display them 914 1.1 jkunz * faster with blkmv operations rather than unpmv later on. 915 1.1 jkunz */ 916 1.1 jkunz if (size <= cfg->fbheight * 917 1.1 jkunz (cfg->fbwidth - cfg->width - cfg->owidth)) { 918 1.1 jkunz memset(&a, 0, sizeof(a)); 919 1.1 jkunz a.flags.flags = STI_UNPMVF_WAIT; 920 1.1 jkunz a.in.fg_colour = STI_COLOUR_WHITE; 921 1.1 jkunz a.in.bg_colour = STI_COLOUR_BLACK; 922 1.13 skrll a.in.font_addr = scr->scr_romfont; 923 1.1 jkunz 924 1.13 skrll scr->scr_fontmaxcol = cfg->fbheight / fp->height; 925 1.13 skrll scr->scr_fontbase = cfg->width + cfg->owidth; 926 1.1 jkunz for (uc = fp->first; uc <= fp->last; uc++) { 927 1.13 skrll a.in.x = ((uc - fp->first) / scr->scr_fontmaxcol) * 928 1.13 skrll fp->width + scr->scr_fontbase; 929 1.13 skrll a.in.y = ((uc - fp->first) % scr->scr_fontmaxcol) * 930 1.1 jkunz fp->height; 931 1.1 jkunz a.in.index = uc; 932 1.1 jkunz 933 1.13 skrll (*scr->unpmv)(&a.flags, &a.in, &a.out, &scr->scr_cfg); 934 1.1 jkunz if (a.out.errno) { 935 1.13 skrll aprint_error_dev(sc->sc_dev, "unpmv %d " 936 1.13 skrll "returned %d\n", uc, a.out.errno); 937 1.13 skrll return 0; 938 1.1 jkunz } 939 1.1 jkunz } 940 1.1 jkunz 941 1.13 skrll free(scr->scr_romfont, M_DEVBUF); 942 1.13 skrll scr->scr_romfont = NULL; 943 1.1 jkunz } 944 1.1 jkunz #endif 945 1.1 jkunz 946 1.13 skrll return 0; 947 1.1 jkunz } 948 1.1 jkunz 949 1.13 skrll /* 950 1.13 skrll * Wrappers around STI code pointers 951 1.13 skrll */ 952 1.23 tsutsui 953 1.1 jkunz int 954 1.13 skrll sti_init(struct sti_screen *scr, int mode) 955 1.1 jkunz { 956 1.13 skrll struct sti_rom *rom = scr->scr_rom; 957 1.1 jkunz struct { 958 1.1 jkunz struct sti_initflags flags; 959 1.1 jkunz struct sti_initin in; 960 1.13 skrll struct sti_einitin ein; 961 1.1 jkunz struct sti_initout out; 962 1.1 jkunz } a; 963 1.1 jkunz 964 1.13 skrll KASSERT(rom != NULL); 965 1.1 jkunz memset(&a, 0, sizeof(a)); 966 1.1 jkunz 967 1.32 macallan a.flags.flags = STI_INITF_WAIT | STI_INITF_PBET | STI_INITF_PBETI; 968 1.21 tsutsui if ((mode & STI_TEXTMODE) != 0) { 969 1.21 tsutsui a.flags.flags |= STI_INITF_TEXT | STI_INITF_CMB | 970 1.21 tsutsui STI_INITF_PBET | STI_INITF_PBETI | STI_INITF_ICMT; 971 1.32 macallan a.in.text_planes = 1; 972 1.21 tsutsui } else { 973 1.32 macallan a.flags.flags |= STI_INITF_TEXT | STI_INITF_NTEXT; 974 1.34 skrll /* 975 1.34 skrll * Request as many text planes as STI will allow. 976 1.32 macallan * The reason to do this - when switching to framebuffer mode 977 1.32 macallan * for X we need access to all planes. In theory STI should do 978 1.32 macallan * just that when we request access to both text and non-text 979 1.32 macallan * planes as above. 980 1.32 macallan * In reality though, at least on my PCI Visualize EG, some 981 1.32 macallan * planes and/or colour registers remain inaccessible if we 982 1.32 macallan * request only one text plane. 983 1.32 macallan * Clearly we're missing a register write or two here, but so 984 1.32 macallan * far I haven't found it. 985 1.32 macallan */ 986 1.32 macallan a.in.text_planes = 3; 987 1.21 tsutsui } 988 1.21 tsutsui if ((mode & STI_CLEARSCR) != 0) 989 1.21 tsutsui a.flags.flags |= STI_INITF_CLEAR; 990 1.21 tsutsui 991 1.13 skrll a.in.ext_in = &a.ein; 992 1.13 skrll 993 1.13 skrll DPRINTF(("%s: init,%p(%x, %p, %p, %p)\n", 994 1.45 tsutsui rom->rom_softc == NULL ? __func__ : 995 1.13 skrll device_xname(rom->rom_softc->sc_dev), rom->init, a.flags.flags, 996 1.13 skrll &a.in, &a.out, &scr->scr_cfg)); 997 1.13 skrll 998 1.13 skrll (*rom->init)(&a.flags, &a.in, &a.out, &scr->scr_cfg); 999 1.13 skrll 1000 1.13 skrll if (a.out.text_planes != a.in.text_planes) 1001 1.13 skrll return -1; /* not colliding with sti errno values */ 1002 1.13 skrll return a.out.errno; 1003 1.1 jkunz } 1004 1.1 jkunz 1005 1.1 jkunz int 1006 1.13 skrll sti_inqcfg(struct sti_screen *scr, struct sti_inqconfout *out) 1007 1.1 jkunz { 1008 1.13 skrll struct sti_rom *rom = scr->scr_rom; 1009 1.1 jkunz struct { 1010 1.1 jkunz struct sti_inqconfflags flags; 1011 1.1 jkunz struct sti_inqconfin in; 1012 1.1 jkunz } a; 1013 1.1 jkunz 1014 1.1 jkunz memset(&a, 0, sizeof(a)); 1015 1.1 jkunz 1016 1.1 jkunz a.flags.flags = STI_INQCONFF_WAIT; 1017 1.13 skrll (*rom->inqconf)(&a.flags, &a.in, out, &scr->scr_cfg); 1018 1.1 jkunz 1019 1.1 jkunz return out->errno; 1020 1.1 jkunz } 1021 1.1 jkunz 1022 1.1 jkunz void 1023 1.13 skrll sti_bmove(struct sti_screen *scr, int x1, int y1, int x2, int y2, int h, int w, 1024 1.1 jkunz enum sti_bmove_funcs f) 1025 1.1 jkunz { 1026 1.13 skrll struct sti_rom *rom = scr->scr_rom; 1027 1.1 jkunz struct { 1028 1.1 jkunz struct sti_blkmvflags flags; 1029 1.1 jkunz struct sti_blkmvin in; 1030 1.1 jkunz struct sti_blkmvout out; 1031 1.1 jkunz } a; 1032 1.1 jkunz 1033 1.1 jkunz memset(&a, 0, sizeof(a)); 1034 1.1 jkunz 1035 1.1 jkunz a.flags.flags = STI_BLKMVF_WAIT; 1036 1.1 jkunz switch (f) { 1037 1.1 jkunz case bmf_clear: 1038 1.1 jkunz a.flags.flags |= STI_BLKMVF_CLR; 1039 1.1 jkunz a.in.bg_colour = STI_COLOUR_BLACK; 1040 1.1 jkunz break; 1041 1.1 jkunz case bmf_underline: 1042 1.1 jkunz case bmf_copy: 1043 1.1 jkunz a.in.fg_colour = STI_COLOUR_WHITE; 1044 1.1 jkunz a.in.bg_colour = STI_COLOUR_BLACK; 1045 1.1 jkunz break; 1046 1.1 jkunz case bmf_invert: 1047 1.1 jkunz a.flags.flags |= STI_BLKMVF_COLR; 1048 1.1 jkunz a.in.fg_colour = STI_COLOUR_BLACK; 1049 1.1 jkunz a.in.bg_colour = STI_COLOUR_WHITE; 1050 1.1 jkunz break; 1051 1.1 jkunz } 1052 1.1 jkunz a.in.srcx = x1; 1053 1.1 jkunz a.in.srcy = y1; 1054 1.1 jkunz a.in.dstx = x2; 1055 1.1 jkunz a.in.dsty = y2; 1056 1.1 jkunz a.in.height = h; 1057 1.1 jkunz a.in.width = w; 1058 1.1 jkunz 1059 1.13 skrll (*rom->blkmv)(&a.flags, &a.in, &a.out, &scr->scr_cfg); 1060 1.1 jkunz #ifdef STIDEBUG 1061 1.1 jkunz if (a.out.errno) 1062 1.13 skrll printf("%s: blkmv returned %d\n", 1063 1.45 tsutsui rom->rom_softc == NULL ? __func__ : 1064 1.13 skrll device_xname(rom->rom_softc->sc_dev), a.out.errno); 1065 1.1 jkunz #endif 1066 1.1 jkunz } 1067 1.1 jkunz 1068 1.1 jkunz int 1069 1.13 skrll sti_setcment(struct sti_screen *scr, u_int i, u_char r, u_char g, u_char b) 1070 1.1 jkunz { 1071 1.13 skrll struct sti_rom *rom = scr->scr_rom; 1072 1.1 jkunz struct { 1073 1.1 jkunz struct sti_scmentflags flags; 1074 1.1 jkunz struct sti_scmentin in; 1075 1.1 jkunz struct sti_scmentout out; 1076 1.1 jkunz } a; 1077 1.1 jkunz 1078 1.1 jkunz memset(&a, 0, sizeof(a)); 1079 1.1 jkunz 1080 1.1 jkunz a.flags.flags = STI_SCMENTF_WAIT; 1081 1.1 jkunz a.in.entry = i; 1082 1.1 jkunz a.in.value = (r << 16) | (g << 8) | b; 1083 1.1 jkunz 1084 1.13 skrll (*rom->scment)(&a.flags, &a.in, &a.out, &scr->scr_cfg); 1085 1.1 jkunz 1086 1.1 jkunz return a.out.errno; 1087 1.1 jkunz } 1088 1.1 jkunz 1089 1.13 skrll /* 1090 1.13 skrll * wsdisplay accessops 1091 1.13 skrll */ 1092 1.1 jkunz int 1093 1.7 christos sti_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, struct lwp *l) 1094 1.1 jkunz { 1095 1.13 skrll struct sti_screen *scr = (struct sti_screen *)v; 1096 1.38 macallan struct sti_rom *rom = scr->scr_rom; 1097 1.1 jkunz struct wsdisplay_fbinfo *wdf; 1098 1.1 jkunz struct wsdisplay_cmap *cmapp; 1099 1.1 jkunz u_int mode, idx, count; 1100 1.23 tsutsui int ret; 1101 1.1 jkunz 1102 1.1 jkunz ret = 0; 1103 1.1 jkunz switch (cmd) { 1104 1.38 macallan case GCID: 1105 1.39 skrll *(u_int *)data = rom->rom_dd.dd_grid[0]; 1106 1.38 macallan break; 1107 1.38 macallan 1108 1.1 jkunz case WSDISPLAYIO_GMODE: 1109 1.13 skrll *(u_int *)data = scr->scr_wsmode; 1110 1.1 jkunz break; 1111 1.1 jkunz 1112 1.1 jkunz case WSDISPLAYIO_SMODE: 1113 1.1 jkunz mode = *(u_int *)data; 1114 1.23 tsutsui switch (mode) { 1115 1.23 tsutsui case WSDISPLAYIO_MODE_EMUL: 1116 1.23 tsutsui if (scr->scr_wsmode != WSDISPLAYIO_MODE_EMUL) 1117 1.23 tsutsui ret = sti_init(scr, STI_TEXTMODE); 1118 1.23 tsutsui break; 1119 1.23 tsutsui case WSDISPLAYIO_MODE_DUMBFB: 1120 1.23 tsutsui if (scr->scr_wsmode != WSDISPLAYIO_MODE_DUMBFB) { 1121 1.32 macallan ret = sti_init(scr, 0); 1122 1.23 tsutsui if (scr->setupfb != NULL) 1123 1.23 tsutsui scr->setupfb(scr); 1124 1.23 tsutsui else 1125 1.23 tsutsui #if 0 1126 1.23 tsutsui ret = sti_init(scr, STI_FBMODE); 1127 1.23 tsutsui #else 1128 1.23 tsutsui ret = EINVAL; 1129 1.23 tsutsui #endif 1130 1.23 tsutsui } 1131 1.23 tsutsui break; 1132 1.23 tsutsui case WSDISPLAYIO_MODE_MAPPED: 1133 1.23 tsutsui default: 1134 1.23 tsutsui ret = EINVAL; 1135 1.23 tsutsui break; 1136 1.23 tsutsui } 1137 1.23 tsutsui if (ret == 0) 1138 1.23 tsutsui scr->scr_wsmode = mode; 1139 1.1 jkunz break; 1140 1.1 jkunz 1141 1.1 jkunz case WSDISPLAYIO_GTYPE: 1142 1.1 jkunz *(u_int *)data = WSDISPLAY_TYPE_STI; 1143 1.1 jkunz break; 1144 1.1 jkunz 1145 1.1 jkunz case WSDISPLAYIO_GINFO: 1146 1.1 jkunz wdf = (struct wsdisplay_fbinfo *)data; 1147 1.13 skrll wdf->height = scr->scr_cfg.scr_height; 1148 1.13 skrll wdf->width = scr->scr_cfg.scr_width; 1149 1.13 skrll wdf->depth = scr->scr_bpp; 1150 1.23 tsutsui if (scr->putcmap == NULL || scr->scr_bpp > 8) 1151 1.13 skrll wdf->cmsize = 0; 1152 1.13 skrll else 1153 1.13 skrll wdf->cmsize = STI_NCMAP; 1154 1.1 jkunz break; 1155 1.1 jkunz 1156 1.1 jkunz case WSDISPLAYIO_LINEBYTES: 1157 1.23 tsutsui if (scr->scr_bpp > 8) 1158 1.23 tsutsui *(u_int *)data = scr->scr_cfg.fb_width * 4; 1159 1.23 tsutsui else 1160 1.23 tsutsui *(u_int *)data = scr->scr_cfg.fb_width; 1161 1.1 jkunz break; 1162 1.1 jkunz 1163 1.1 jkunz case WSDISPLAYIO_GETCMAP: 1164 1.23 tsutsui if (scr->putcmap == NULL || scr->scr_bpp > 8) 1165 1.23 tsutsui return ENODEV; 1166 1.1 jkunz cmapp = (struct wsdisplay_cmap *)data; 1167 1.1 jkunz idx = cmapp->index; 1168 1.1 jkunz count = cmapp->count; 1169 1.19 spz if (idx >= STI_NCMAP || count > STI_NCMAP - idx) 1170 1.1 jkunz return EINVAL; 1171 1.13 skrll if ((ret = copyout(&scr->scr_rcmap[idx], cmapp->red, count))) 1172 1.1 jkunz break; 1173 1.13 skrll if ((ret = copyout(&scr->scr_gcmap[idx], cmapp->green, count))) 1174 1.1 jkunz break; 1175 1.13 skrll if ((ret = copyout(&scr->scr_bcmap[idx], cmapp->blue, count))) 1176 1.1 jkunz break; 1177 1.1 jkunz break; 1178 1.1 jkunz 1179 1.1 jkunz case WSDISPLAYIO_PUTCMAP: 1180 1.23 tsutsui if (scr->putcmap == NULL || scr->scr_bpp > 8) 1181 1.23 tsutsui return ENODEV; 1182 1.25 tsutsui if (scr->scr_wsmode == WSDISPLAYIO_MODE_EMUL) { 1183 1.25 tsutsui /* 1184 1.25 tsutsui * The hardware palette settings are handled by 1185 1.25 tsutsui * the STI ROM in STI_TEXTMODE and changing cmap 1186 1.25 tsutsui * could cause mangled text colors at least on CRX. 1187 1.25 tsutsui * Updating CMAP in EMUL mode isn't expected anyway 1188 1.25 tsutsui * so just ignore it. 1189 1.25 tsutsui */ 1190 1.25 tsutsui return 0; 1191 1.25 tsutsui } 1192 1.1 jkunz cmapp = (struct wsdisplay_cmap *)data; 1193 1.1 jkunz idx = cmapp->index; 1194 1.1 jkunz count = cmapp->count; 1195 1.19 spz if (idx >= STI_NCMAP || count > STI_NCMAP - idx) 1196 1.1 jkunz return EINVAL; 1197 1.13 skrll if ((ret = copyin(cmapp->red, &scr->scr_rcmap[idx], count))) 1198 1.1 jkunz break; 1199 1.13 skrll if ((ret = copyin(cmapp->green, &scr->scr_gcmap[idx], count))) 1200 1.1 jkunz break; 1201 1.13 skrll if ((ret = copyin(cmapp->blue, &scr->scr_bcmap[idx], count))) 1202 1.1 jkunz break; 1203 1.23 tsutsui ret = scr->putcmap(scr, idx, count); 1204 1.1 jkunz break; 1205 1.1 jkunz 1206 1.1 jkunz case WSDISPLAYIO_SVIDEO: 1207 1.1 jkunz case WSDISPLAYIO_GVIDEO: 1208 1.1 jkunz case WSDISPLAYIO_GCURPOS: 1209 1.1 jkunz case WSDISPLAYIO_SCURPOS: 1210 1.1 jkunz case WSDISPLAYIO_GCURMAX: 1211 1.1 jkunz case WSDISPLAYIO_GCURSOR: 1212 1.1 jkunz case WSDISPLAYIO_SCURSOR: 1213 1.1 jkunz default: 1214 1.13 skrll return ENOTTY; /* not supported yet */ 1215 1.1 jkunz } 1216 1.1 jkunz 1217 1.13 skrll return ret; 1218 1.1 jkunz } 1219 1.1 jkunz 1220 1.1 jkunz paddr_t 1221 1.6 jmmv sti_mmap(void *v, void *vs, off_t offset, int prot) 1222 1.1 jkunz { 1223 1.23 tsutsui struct sti_screen *scr = (struct sti_screen *)v; 1224 1.23 tsutsui struct sti_rom *rom = scr->scr_rom; 1225 1.23 tsutsui paddr_t pa; 1226 1.23 tsutsui 1227 1.23 tsutsui if ((offset & PAGE_MASK) != 0) 1228 1.23 tsutsui return -1; 1229 1.23 tsutsui 1230 1.23 tsutsui if (offset < 0 || offset >= scr->fblen) 1231 1.23 tsutsui return -1; 1232 1.23 tsutsui 1233 1.27 skrll if (scr->scr_wsmode != WSDISPLAYIO_MODE_DUMBFB) 1234 1.27 skrll return -1; 1235 1.27 skrll 1236 1.23 tsutsui pa = bus_space_mmap(rom->memt, scr->fbaddr, offset, prot, 1237 1.23 tsutsui BUS_SPACE_MAP_LINEAR); 1238 1.27 skrll 1239 1.27 skrll if (pa == -1) 1240 1.27 skrll pa = scr->fbaddr + offset; 1241 1.23 tsutsui 1242 1.23 tsutsui return pa; 1243 1.1 jkunz } 1244 1.1 jkunz 1245 1.1 jkunz int 1246 1.3 perry sti_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep, 1247 1.1 jkunz int *cxp, int *cyp, long *defattr) 1248 1.1 jkunz { 1249 1.13 skrll struct sti_screen *scr = (struct sti_screen *)v; 1250 1.1 jkunz 1251 1.13 skrll if (scr->scr_nscreens > 0) 1252 1.1 jkunz return ENOMEM; 1253 1.1 jkunz 1254 1.13 skrll *cookiep = scr; 1255 1.1 jkunz *cxp = 0; 1256 1.1 jkunz *cyp = 0; 1257 1.13 skrll sti_alloc_attr(scr, 0, 0, 0, defattr); 1258 1.13 skrll scr->scr_nscreens++; 1259 1.1 jkunz return 0; 1260 1.1 jkunz } 1261 1.1 jkunz 1262 1.1 jkunz void 1263 1.1 jkunz sti_free_screen(void *v, void *cookie) 1264 1.1 jkunz { 1265 1.13 skrll struct sti_screen *scr = (struct sti_screen *)v; 1266 1.1 jkunz 1267 1.13 skrll scr->scr_nscreens--; 1268 1.1 jkunz } 1269 1.1 jkunz 1270 1.1 jkunz int 1271 1.13 skrll sti_show_screen(void *v, void *cookie, int waitok, void (*cb)(void *, int, int), 1272 1.13 skrll void *cbarg) 1273 1.1 jkunz { 1274 1.13 skrll #if 0 1275 1.13 skrll struct sti_screen *scr = (struct sti_screen *)v; 1276 1.13 skrll #endif 1277 1.13 skrll 1278 1.1 jkunz return 0; 1279 1.1 jkunz } 1280 1.1 jkunz 1281 1.1 jkunz int 1282 1.1 jkunz sti_load_font(void *v, void *cookie, struct wsdisplay_font *font) 1283 1.1 jkunz { 1284 1.13 skrll #if 0 1285 1.13 skrll struct sti_screen *scr = (struct sti_screen *)v; 1286 1.13 skrll #endif 1287 1.13 skrll 1288 1.1 jkunz return -1; 1289 1.1 jkunz } 1290 1.1 jkunz 1291 1.13 skrll /* 1292 1.13 skrll * wsdisplay emulops 1293 1.13 skrll */ 1294 1.1 jkunz void 1295 1.1 jkunz sti_cursor(void *v, int on, int row, int col) 1296 1.1 jkunz { 1297 1.13 skrll struct sti_screen *scr = (struct sti_screen *)v; 1298 1.13 skrll struct sti_font *fp = &scr->scr_curfont; 1299 1.1 jkunz 1300 1.23 tsutsui sti_bmove(scr, 1301 1.23 tsutsui col * fp->width, row * fp->height, 1302 1.23 tsutsui col * fp->width, row * fp->height, 1303 1.23 tsutsui fp->height, fp->width, bmf_invert); 1304 1.1 jkunz } 1305 1.1 jkunz 1306 1.13 skrll /* 1307 1.13 skrll * ISO 8859-1 part of Unicode to HP Roman font index conversion array. 1308 1.13 skrll */ 1309 1.43 macallan const uint8_t 1310 1.13 skrll sti_unitoroman[0x100 - 0xa0] = { 1311 1.13 skrll 0xa0, 0xb8, 0xbf, 0xbb, 0xba, 0xbc, 0, 0xbd, 1312 1.13 skrll 0xab, 0, 0xf9, 0xfb, 0, 0xf6, 0, 0xb0, 1313 1.26 skrll 1314 1.13 skrll 0xb3, 0xfe, 0, 0, 0xa8, 0xf3, 0xf4, 0xf2, 1315 1.13 skrll 0, 0, 0xfa, 0xfd, 0xf7, 0xf8, 0, 0xb9, 1316 1.13 skrll 1317 1.13 skrll 0xa1, 0xe0, 0xa2, 0xe1, 0xd8, 0xd0, 0xd3, 0xb4, 1318 1.13 skrll 0xa3, 0xdc, 0xa4, 0xa5, 0xe6, 0xe5, 0xa6, 0xa7, 1319 1.13 skrll 1320 1.13 skrll 0xe3, 0xb6, 0xe8, 0xe7, 0xdf, 0xe9, 0xda, 0, 1321 1.13 skrll 0xd2, 0xad, 0xed, 0xae, 0xdb, 0xb1, 0xf0, 0xde, 1322 1.13 skrll 1323 1.13 skrll 0xc8, 0xc4, 0xc0, 0xe2, 0xcc, 0xd4, 0xd7, 0xb5, 1324 1.13 skrll 0xc9, 0xc5, 0xc1, 0xcd, 0xd9, 0xd5, 0xd1, 0xdd, 1325 1.13 skrll 1326 1.13 skrll 0xe4, 0xb7, 0xca, 0xc6, 0xc2, 0xea, 0xce, 0, 1327 1.13 skrll 0xd6, 0xcb, 0xc7, 0xc3, 0xcf, 0xb2, 0xf1, 0xef 1328 1.13 skrll }; 1329 1.13 skrll 1330 1.1 jkunz int 1331 1.1 jkunz sti_mapchar(void *v, int uni, u_int *index) 1332 1.1 jkunz { 1333 1.13 skrll struct sti_screen *scr = (struct sti_screen *)v; 1334 1.13 skrll struct sti_font *fp = &scr->scr_curfont; 1335 1.13 skrll int c; 1336 1.13 skrll 1337 1.13 skrll switch (fp->type) { 1338 1.13 skrll case STI_FONT_HPROMAN8: 1339 1.13 skrll if (uni >= 0x80 && uni < 0xa0) 1340 1.13 skrll c = -1; 1341 1.13 skrll else if (uni >= 0xa0 && uni < 0x100) { 1342 1.13 skrll c = (int)sti_unitoroman[uni - 0xa0]; 1343 1.13 skrll if (c == 0) 1344 1.13 skrll c = -1; 1345 1.13 skrll } else 1346 1.13 skrll c = uni; 1347 1.13 skrll break; 1348 1.13 skrll default: 1349 1.13 skrll c = uni; 1350 1.13 skrll break; 1351 1.13 skrll } 1352 1.1 jkunz 1353 1.13 skrll if (c == -1 || c < fp->first || c > fp->last) { 1354 1.13 skrll *index = ' '; 1355 1.13 skrll return 0; 1356 1.13 skrll } 1357 1.13 skrll 1358 1.13 skrll *index = c; 1359 1.13 skrll return 5; 1360 1.1 jkunz } 1361 1.1 jkunz 1362 1.1 jkunz void 1363 1.1 jkunz sti_putchar(void *v, int row, int col, u_int uc, long attr) 1364 1.1 jkunz { 1365 1.13 skrll struct sti_screen *scr = (struct sti_screen *)v; 1366 1.13 skrll struct sti_rom *rom = scr->scr_rom; 1367 1.13 skrll struct sti_font *fp = &scr->scr_curfont; 1368 1.24 tsutsui int bg, fg; 1369 1.24 tsutsui 1370 1.24 tsutsui fg = WSATTR_UNPACK_FG(attr); 1371 1.24 tsutsui bg = WSATTR_UNPACK_BG(attr); 1372 1.1 jkunz 1373 1.13 skrll if (scr->scr_romfont != NULL) { 1374 1.1 jkunz /* 1375 1.1 jkunz * Font is in memory, use unpmv 1376 1.1 jkunz */ 1377 1.1 jkunz struct { 1378 1.1 jkunz struct sti_unpmvflags flags; 1379 1.1 jkunz struct sti_unpmvin in; 1380 1.1 jkunz struct sti_unpmvout out; 1381 1.1 jkunz } a; 1382 1.1 jkunz 1383 1.1 jkunz memset(&a, 0, sizeof(a)); 1384 1.1 jkunz 1385 1.1 jkunz a.flags.flags = STI_UNPMVF_WAIT; 1386 1.24 tsutsui a.in.fg_colour = fg; 1387 1.24 tsutsui a.in.bg_colour = bg; 1388 1.1 jkunz a.in.x = col * fp->width; 1389 1.1 jkunz a.in.y = row * fp->height; 1390 1.13 skrll a.in.font_addr = scr->scr_romfont; 1391 1.1 jkunz a.in.index = uc; 1392 1.1 jkunz 1393 1.13 skrll (*rom->unpmv)(&a.flags, &a.in, &a.out, &scr->scr_cfg); 1394 1.1 jkunz } else { 1395 1.1 jkunz /* 1396 1.1 jkunz * Font is in frame buffer, use blkmv 1397 1.1 jkunz */ 1398 1.1 jkunz struct { 1399 1.1 jkunz struct sti_blkmvflags flags; 1400 1.1 jkunz struct sti_blkmvin in; 1401 1.1 jkunz struct sti_blkmvout out; 1402 1.1 jkunz } a; 1403 1.1 jkunz 1404 1.1 jkunz memset(&a, 0, sizeof(a)); 1405 1.1 jkunz 1406 1.1 jkunz a.flags.flags = STI_BLKMVF_WAIT; 1407 1.24 tsutsui a.in.fg_colour = fg; 1408 1.24 tsutsui a.in.bg_colour = bg; 1409 1.1 jkunz 1410 1.13 skrll a.in.srcx = ((uc - fp->first) / scr->scr_fontmaxcol) * 1411 1.13 skrll fp->width + scr->scr_fontbase; 1412 1.13 skrll a.in.srcy = ((uc - fp->first) % scr->scr_fontmaxcol) * 1413 1.1 jkunz fp->height; 1414 1.1 jkunz a.in.dstx = col * fp->width; 1415 1.1 jkunz a.in.dsty = row * fp->height; 1416 1.1 jkunz a.in.height = fp->height; 1417 1.1 jkunz a.in.width = fp->width; 1418 1.1 jkunz 1419 1.13 skrll (*rom->blkmv)(&a.flags, &a.in, &a.out, &scr->scr_cfg); 1420 1.1 jkunz } 1421 1.1 jkunz } 1422 1.1 jkunz 1423 1.1 jkunz void 1424 1.1 jkunz sti_copycols(void *v, int row, int srccol, int dstcol, int ncols) 1425 1.1 jkunz { 1426 1.13 skrll struct sti_screen *scr = (struct sti_screen *)v; 1427 1.13 skrll struct sti_font *fp = &scr->scr_curfont; 1428 1.1 jkunz 1429 1.23 tsutsui sti_bmove(scr, 1430 1.23 tsutsui srccol * fp->width, row * fp->height, 1431 1.23 tsutsui dstcol * fp->width, row * fp->height, 1432 1.23 tsutsui fp->height, ncols * fp->width, bmf_copy); 1433 1.1 jkunz } 1434 1.1 jkunz 1435 1.1 jkunz void 1436 1.1 jkunz sti_erasecols(void *v, int row, int startcol, int ncols, long attr) 1437 1.1 jkunz { 1438 1.13 skrll struct sti_screen *scr = (struct sti_screen *)v; 1439 1.13 skrll struct sti_font *fp = &scr->scr_curfont; 1440 1.1 jkunz 1441 1.23 tsutsui sti_bmove(scr, 1442 1.23 tsutsui startcol * fp->width, row * fp->height, 1443 1.23 tsutsui startcol * fp->width, row * fp->height, 1444 1.23 tsutsui fp->height, ncols * fp->width, bmf_clear); 1445 1.1 jkunz } 1446 1.1 jkunz 1447 1.1 jkunz void 1448 1.1 jkunz sti_copyrows(void *v, int srcrow, int dstrow, int nrows) 1449 1.1 jkunz { 1450 1.13 skrll struct sti_screen *scr = (struct sti_screen *)v; 1451 1.13 skrll struct sti_font *fp = &scr->scr_curfont; 1452 1.1 jkunz 1453 1.13 skrll sti_bmove(scr, 0, srcrow * fp->height, 0, dstrow * fp->height, 1454 1.13 skrll nrows * fp->height, scr->scr_cfg.scr_width, bmf_copy); 1455 1.1 jkunz } 1456 1.1 jkunz 1457 1.1 jkunz void 1458 1.1 jkunz sti_eraserows(void *v, int srcrow, int nrows, long attr) 1459 1.1 jkunz { 1460 1.13 skrll struct sti_screen *scr = (struct sti_screen *)v; 1461 1.13 skrll struct sti_font *fp = &scr->scr_curfont; 1462 1.1 jkunz 1463 1.13 skrll sti_bmove(scr, 0, srcrow * fp->height, 0, srcrow * fp->height, 1464 1.13 skrll nrows * fp->height, scr->scr_cfg.scr_width, bmf_clear); 1465 1.1 jkunz } 1466 1.1 jkunz 1467 1.1 jkunz int 1468 1.1 jkunz sti_alloc_attr(void *v, int fg, int bg, int flags, long *pattr) 1469 1.1 jkunz { 1470 1.13 skrll #if 0 1471 1.13 skrll struct sti_screen *scr = (struct sti_screen *)v; 1472 1.13 skrll #endif 1473 1.1 jkunz 1474 1.24 tsutsui if ((flags & (WSATTR_HILIT | WSATTR_BLINK | 1475 1.24 tsutsui WSATTR_UNDERLINE | WSATTR_WSCOLORS)) != 0) 1476 1.24 tsutsui return EINVAL; 1477 1.24 tsutsui if ((flags & WSATTR_REVERSE) != 0) { 1478 1.26 skrll fg = STI_COLOUR_BLACK; 1479 1.24 tsutsui bg = STI_COLOUR_WHITE; 1480 1.24 tsutsui } else { 1481 1.24 tsutsui fg = STI_COLOUR_WHITE; 1482 1.26 skrll bg = STI_COLOUR_BLACK; 1483 1.24 tsutsui } 1484 1.1 jkunz 1485 1.24 tsutsui *pattr = WSATTR_PACK(fg, bg, flags); 1486 1.1 jkunz return 0; 1487 1.1 jkunz } 1488 1.17 tsutsui 1489 1.17 tsutsui /* 1490 1.29 skrll * Early console support. Only used on hp300, currently 1491 1.17 tsutsui */ 1492 1.17 tsutsui int 1493 1.17 tsutsui sti_cnattach(struct sti_rom *rom, struct sti_screen *scr, bus_space_tag_t memt, 1494 1.17 tsutsui bus_addr_t *bases, u_int codebase) 1495 1.17 tsutsui { 1496 1.17 tsutsui bus_space_handle_t romh; 1497 1.17 tsutsui u_int romend; 1498 1.17 tsutsui int error; 1499 1.17 tsutsui long defattr; 1500 1.17 tsutsui 1501 1.17 tsutsui if ((error = bus_space_map(memt, bases[0], PAGE_SIZE, 0, &romh)) != 0) 1502 1.17 tsutsui return error; 1503 1.17 tsutsui 1504 1.17 tsutsui /* 1505 1.17 tsutsui * Compute real PROM size 1506 1.17 tsutsui */ 1507 1.17 tsutsui romend = sti_rom_size(memt, romh); 1508 1.17 tsutsui 1509 1.17 tsutsui bus_space_unmap(memt, romh, PAGE_SIZE); 1510 1.17 tsutsui 1511 1.17 tsutsui if ((error = bus_space_map(memt, bases[0], romend, 0, &romh)) != 0) 1512 1.17 tsutsui return error; 1513 1.17 tsutsui 1514 1.17 tsutsui bases[0] = romh; 1515 1.17 tsutsui if (sti_rom_setup(rom, memt, memt, romh, bases, codebase) != 0) 1516 1.17 tsutsui return -1; 1517 1.17 tsutsui scr->scr_rom = rom; 1518 1.17 tsutsui if (sti_screen_setup(scr, STI_CLEARSCR) != 0) 1519 1.17 tsutsui return -1; 1520 1.17 tsutsui 1521 1.17 tsutsui sti_alloc_attr(scr, 0, 0, 0, &defattr); 1522 1.17 tsutsui wsdisplay_cnattach(&scr->scr_wsd, scr, 0, 0, defattr); 1523 1.17 tsutsui 1524 1.17 tsutsui return 0; 1525 1.17 tsutsui } 1526 1.23 tsutsui 1527 1.23 tsutsui int 1528 1.23 tsutsui ngle_default_putcmap(struct sti_screen *scr, u_int idx, u_int count) 1529 1.23 tsutsui { 1530 1.23 tsutsui int i, ret; 1531 1.23 tsutsui 1532 1.23 tsutsui for (i = idx + count - 1; i >= (int)idx; i--) 1533 1.23 tsutsui if ((ret = sti_setcment(scr, i, scr->scr_rcmap[i], 1534 1.23 tsutsui scr->scr_gcmap[i], scr->scr_bcmap[i]))) 1535 1.23 tsutsui return EINVAL; 1536 1.23 tsutsui 1537 1.23 tsutsui return 0; 1538 1.23 tsutsui } 1539 1.23 tsutsui 1540 1.23 tsutsui #ifndef SMALL_KERNEL 1541 1.23 tsutsui 1542 1.23 tsutsui void ngle_setup_hw(bus_space_tag_t, bus_space_handle_t); 1543 1.23 tsutsui void ngle_setup_fb(bus_space_tag_t, bus_space_handle_t, uint32_t); 1544 1.23 tsutsui void ngle_setup_attr_planes(struct sti_screen *scr); 1545 1.23 tsutsui void ngle_setup_bt458(struct sti_screen *scr); 1546 1.23 tsutsui 1547 1.23 tsutsui #define ngle_bt458_write(memt, memh, r, v) \ 1548 1.32 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_RAMDAC + ((r) << 2), (v) << 24) 1549 1.23 tsutsui 1550 1.23 tsutsui void 1551 1.23 tsutsui ngle_artist_setupfb(struct sti_screen *scr) 1552 1.23 tsutsui { 1553 1.23 tsutsui struct sti_rom *rom = scr->scr_rom; 1554 1.23 tsutsui bus_space_tag_t memt = rom->memt; 1555 1.23 tsutsui bus_space_handle_t memh = rom->regh[2]; 1556 1.23 tsutsui 1557 1.23 tsutsui ngle_setup_bt458(scr); 1558 1.23 tsutsui 1559 1.23 tsutsui ngle_setup_hw(memt, memh); 1560 1.23 tsutsui ngle_setup_fb(memt, memh, scr->reg10_value); 1561 1.23 tsutsui 1562 1.23 tsutsui ngle_setup_attr_planes(scr); 1563 1.23 tsutsui 1564 1.23 tsutsui ngle_setup_hw(memt, memh); 1565 1.32 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_21, 1566 1.32 macallan bus_space_read_stream_4(memt, memh, NGLE_REG_21) | 0x0a000000); 1567 1.32 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_27, 1568 1.32 macallan bus_space_read_stream_4(memt, memh, NGLE_REG_27) | 0x00800000); 1569 1.23 tsutsui } 1570 1.23 tsutsui 1571 1.23 tsutsui void 1572 1.23 tsutsui ngle_elk_setupfb(struct sti_screen *scr) 1573 1.23 tsutsui { 1574 1.23 tsutsui struct sti_rom *rom = scr->scr_rom; 1575 1.23 tsutsui bus_space_tag_t memt = rom->memt; 1576 1.23 tsutsui bus_space_handle_t memh = rom->regh[2]; 1577 1.23 tsutsui 1578 1.23 tsutsui ngle_setup_bt458(scr); 1579 1.23 tsutsui 1580 1.23 tsutsui ngle_setup_hw(memt, memh); 1581 1.23 tsutsui ngle_setup_fb(memt, memh, scr->reg10_value); 1582 1.23 tsutsui 1583 1.23 tsutsui ngle_setup_attr_planes(scr); 1584 1.23 tsutsui 1585 1.23 tsutsui ngle_setup_hw(memt, memh); 1586 1.23 tsutsui /* enable overlay planes in Bt458 command register */ 1587 1.23 tsutsui ngle_bt458_write(memt, memh, 0x0c, 0x06); 1588 1.23 tsutsui ngle_bt458_write(memt, memh, 0x0e, 0x43); 1589 1.23 tsutsui } 1590 1.23 tsutsui 1591 1.23 tsutsui void 1592 1.23 tsutsui ngle_timber_setupfb(struct sti_screen *scr) 1593 1.23 tsutsui { 1594 1.23 tsutsui struct sti_rom *rom = scr->scr_rom; 1595 1.23 tsutsui bus_space_tag_t memt = rom->memt; 1596 1.23 tsutsui bus_space_handle_t memh = rom->regh[2]; 1597 1.23 tsutsui 1598 1.23 tsutsui ngle_setup_bt458(scr); 1599 1.23 tsutsui 1600 1.23 tsutsui ngle_setup_hw(memt, memh); 1601 1.23 tsutsui /* enable overlay planes in Bt458 command register */ 1602 1.23 tsutsui ngle_bt458_write(memt, memh, 0x0c, 0x06); 1603 1.23 tsutsui ngle_bt458_write(memt, memh, 0x0e, 0x43); 1604 1.23 tsutsui } 1605 1.23 tsutsui 1606 1.40 macallan static void 1607 1.40 macallan summit_wait(struct sti_screen *scr) 1608 1.40 macallan { 1609 1.40 macallan struct sti_rom *rom = scr->scr_rom; 1610 1.40 macallan bus_space_tag_t memt = rom->memt; 1611 1.40 macallan bus_space_handle_t memh = rom->regh[0]; 1612 1.40 macallan 1613 1.40 macallan while (bus_space_read_stream_4(memt, memh, VISFX_STATUS) != 0) 1614 1.40 macallan continue; 1615 1.40 macallan } 1616 1.40 macallan 1617 1.40 macallan void 1618 1.40 macallan summit_setupfb(struct sti_screen *scr) 1619 1.40 macallan { 1620 1.40 macallan struct sti_rom *rom = scr->scr_rom; 1621 1.40 macallan bus_space_tag_t memt = rom->memt; 1622 1.40 macallan bus_space_handle_t memh = rom->regh[0]; 1623 1.40 macallan 1624 1.40 macallan summit_wait(scr); 1625 1.40 macallan bus_space_write_stream_4(memt, memh, 0xb08044, 0x1b); 1626 1.40 macallan bus_space_write_stream_4(memt, memh, 0xb08048, 0x1b); 1627 1.40 macallan bus_space_write_stream_4(memt, memh, 0x920860, 0xe4); 1628 1.40 macallan bus_space_write_stream_4(memt, memh, 0xa00818, 0); 1629 1.40 macallan bus_space_write_stream_4(memt, memh, 0xa00404, 0); 1630 1.40 macallan bus_space_write_stream_4(memt, memh, 0x921110, 0); 1631 1.40 macallan bus_space_write_stream_4(memt, memh, 0x9211d8, 0); 1632 1.40 macallan bus_space_write_stream_4(memt, memh, 0xa0086c, 0); 1633 1.40 macallan bus_space_write_stream_4(memt, memh, 0x921114, 0); 1634 1.40 macallan bus_space_write_stream_4(memt, memh, 0xac1050, 0); 1635 1.41 macallan 1636 1.41 macallan bus_space_write_stream_4(memt, memh, VISFX_APERTURE_ACCESS, 1637 1.41 macallan VISFX_DEPTH_8); 1638 1.40 macallan 1639 1.40 macallan bus_space_write_stream_4(memt, memh, VISFX_PIXEL_MASK, 0xffffffff); 1640 1.40 macallan bus_space_write_stream_4(memt, memh, VISFX_PLANE_MASK, 0xffffffff); 1641 1.40 macallan bus_space_write_stream_4(memt, memh, VISFX_VRAM_WRITE_MODE, 1642 1.40 macallan VISFX_WRITE_MODE_PLAIN); 1643 1.41 macallan bus_space_write_stream_4(memt, memh, VISFX_VRAM_READ_MODE, 1644 1.41 macallan VISFX_READ_MODE_COPY); 1645 1.40 macallan } 1646 1.40 macallan 1647 1.23 tsutsui void 1648 1.23 tsutsui ngle_setup_bt458(struct sti_screen *scr) 1649 1.23 tsutsui { 1650 1.23 tsutsui struct sti_rom *rom = scr->scr_rom; 1651 1.23 tsutsui bus_space_tag_t memt = rom->memt; 1652 1.23 tsutsui bus_space_handle_t memh = rom->regh[2]; 1653 1.23 tsutsui 1654 1.23 tsutsui ngle_setup_hw(memt, memh); 1655 1.23 tsutsui /* set Bt458 read mask register to all planes */ 1656 1.23 tsutsui ngle_bt458_write(memt, memh, 0x08, 0x04); 1657 1.23 tsutsui ngle_bt458_write(memt, memh, 0x0a, 0xff); 1658 1.23 tsutsui } 1659 1.23 tsutsui 1660 1.23 tsutsui void 1661 1.23 tsutsui ngle_setup_attr_planes(struct sti_screen *scr) 1662 1.23 tsutsui { 1663 1.23 tsutsui struct sti_rom *rom = scr->scr_rom; 1664 1.23 tsutsui bus_space_tag_t memt = rom->memt; 1665 1.23 tsutsui bus_space_handle_t memh = rom->regh[2]; 1666 1.23 tsutsui 1667 1.23 tsutsui ngle_setup_hw(memt, memh); 1668 1.32 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_11, 0x2ea0d000); 1669 1.32 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_14, 0x23000302); 1670 1.32 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_12, scr->reg12_value); 1671 1.32 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_8, 0xffffffff); 1672 1.23 tsutsui 1673 1.32 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_6, 0x00000000); 1674 1.32 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_9, 1675 1.23 tsutsui (scr->scr_cfg.scr_width << 16) | scr->scr_cfg.scr_height); 1676 1.32 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_6, 0x05000000); 1677 1.32 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_9, 0x00040001); 1678 1.23 tsutsui 1679 1.23 tsutsui ngle_setup_hw(memt, memh); 1680 1.32 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_12, 0x00000000); 1681 1.23 tsutsui 1682 1.23 tsutsui ngle_setup_fb(memt, memh, scr->reg10_value); 1683 1.23 tsutsui } 1684 1.23 tsutsui 1685 1.23 tsutsui int 1686 1.23 tsutsui ngle_putcmap(struct sti_screen *scr, u_int idx, u_int count) 1687 1.23 tsutsui { 1688 1.23 tsutsui struct sti_rom *rom = scr->scr_rom; 1689 1.23 tsutsui bus_space_tag_t memt = rom->memt; 1690 1.23 tsutsui bus_space_handle_t memh = rom->regh[2]; 1691 1.23 tsutsui uint8_t *r, *g, *b; 1692 1.23 tsutsui uint32_t cmap_finish; 1693 1.23 tsutsui 1694 1.23 tsutsui if (scr->scr_bpp > 8) 1695 1.23 tsutsui cmap_finish = 0x83000100; 1696 1.23 tsutsui else 1697 1.23 tsutsui cmap_finish = 0x80000100; 1698 1.23 tsutsui 1699 1.23 tsutsui r = scr->scr_rcmap + idx; 1700 1.23 tsutsui g = scr->scr_gcmap + idx; 1701 1.23 tsutsui b = scr->scr_bcmap + idx; 1702 1.23 tsutsui 1703 1.23 tsutsui ngle_setup_hw(memt, memh); 1704 1.32 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_10, 0xbbe0f000); 1705 1.32 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_14, 0x03000300); 1706 1.32 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_13, 0xffffffff); 1707 1.23 tsutsui 1708 1.23 tsutsui while (count-- != 0) { 1709 1.23 tsutsui ngle_setup_hw(memt, memh); 1710 1.32 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_3, 1711 1.32 macallan 0x400 | (idx << 2)); 1712 1.32 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_4, 1713 1.23 tsutsui (*r << 16) | (*g << 8) | *b); 1714 1.23 tsutsui 1715 1.23 tsutsui idx++; 1716 1.23 tsutsui r++, g++, b++; 1717 1.23 tsutsui } 1718 1.23 tsutsui 1719 1.37 macallan 1720 1.32 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_2, 0x400); 1721 1.32 macallan bus_space_write_stream_4(memt, memh, scr->cmap_finish_register, 1722 1.32 macallan cmap_finish); 1723 1.23 tsutsui ngle_setup_fb(memt, memh, scr->reg10_value); 1724 1.23 tsutsui 1725 1.23 tsutsui 1726 1.23 tsutsui return 0; 1727 1.23 tsutsui } 1728 1.23 tsutsui 1729 1.37 macallan int 1730 1.37 macallan ngle_hcrx_putcmap(struct sti_screen *scr, u_int idx, u_int count) 1731 1.37 macallan { 1732 1.37 macallan struct sti_rom *rom = scr->scr_rom; 1733 1.37 macallan bus_space_tag_t memt = rom->memt; 1734 1.37 macallan bus_space_handle_t memh = rom->regh[2]; 1735 1.37 macallan uint8_t *r, *g, *b; 1736 1.37 macallan uint32_t cmap_finish; 1737 1.37 macallan 1738 1.37 macallan if (scr->scr_bpp > 8) 1739 1.37 macallan cmap_finish = 0x80000100; 1740 1.37 macallan else 1741 1.37 macallan cmap_finish = 0x82000100; 1742 1.37 macallan 1743 1.37 macallan r = scr->scr_rcmap + idx; 1744 1.37 macallan g = scr->scr_gcmap + idx; 1745 1.37 macallan b = scr->scr_bcmap + idx; 1746 1.37 macallan 1747 1.37 macallan ngle_setup_hw(memt, memh); 1748 1.37 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_10, 0xbbe0f000); 1749 1.37 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_14, 0x03000300); 1750 1.37 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_13, 0xffffffff); 1751 1.37 macallan 1752 1.37 macallan while (count-- != 0) { 1753 1.37 macallan ngle_setup_hw(memt, memh); 1754 1.37 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_3, 1755 1.37 macallan 0x400 | (idx << 2)); 1756 1.37 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_4, 1757 1.37 macallan (*r << 16) | (*g << 8) | *b); 1758 1.37 macallan 1759 1.37 macallan idx++; 1760 1.37 macallan r++, g++, b++; 1761 1.37 macallan } 1762 1.37 macallan 1763 1.37 macallan 1764 1.37 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_2, 0x400); 1765 1.37 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_38, cmap_finish); 1766 1.37 macallan ngle_setup_fb(memt, memh, scr->reg10_value); 1767 1.37 macallan 1768 1.37 macallan 1769 1.37 macallan return 0; 1770 1.37 macallan } 1771 1.37 macallan 1772 1.40 macallan int 1773 1.40 macallan summit_putcmap(struct sti_screen *scr, u_int idx, u_int count) 1774 1.40 macallan { 1775 1.40 macallan struct sti_rom *rom = scr->scr_rom; 1776 1.40 macallan bus_space_tag_t memt = rom->memt; 1777 1.40 macallan bus_space_handle_t memh = rom->regh[0]; 1778 1.40 macallan uint8_t *r, *g, *b; 1779 1.40 macallan 1780 1.40 macallan r = scr->scr_rcmap + idx; 1781 1.40 macallan g = scr->scr_gcmap + idx; 1782 1.40 macallan b = scr->scr_bcmap + idx; 1783 1.40 macallan 1784 1.42 macallan if (rom->rom_dd.dd_grid[0] == STI_DD_LEGO) { 1785 1.42 macallan bus_space_write_stream_4(memt, memh, VISFX_COLOR_INDEX, idx); 1786 1.42 macallan } else 1787 1.42 macallan bus_space_write_stream_4(memt, memh, VISFX_COLOR_INDEX, 1788 1.42 macallan 0xc0005100 + idx); 1789 1.40 macallan 1790 1.40 macallan while (count-- != 0) { 1791 1.40 macallan bus_space_write_stream_4(memt, memh, 1792 1.40 macallan VISFX_COLOR_VALUE, (*r << 16) | (*g << 8) | *b); 1793 1.40 macallan r++, g++, b++; 1794 1.40 macallan } 1795 1.40 macallan bus_space_write_stream_4(memt, memh, VISFX_COLOR_MASK, 0xff); 1796 1.40 macallan bus_space_write_stream_4(memt, memh, 0x80004c, 0xc); 1797 1.40 macallan bus_space_write_stream_4(memt, memh, 0x800000, 0); 1798 1.40 macallan 1799 1.40 macallan return 0; 1800 1.40 macallan } 1801 1.40 macallan 1802 1.23 tsutsui void 1803 1.23 tsutsui ngle_setup_hw(bus_space_tag_t memt, bus_space_handle_t memh) 1804 1.23 tsutsui { 1805 1.23 tsutsui uint8_t stat; 1806 1.23 tsutsui 1807 1.23 tsutsui do { 1808 1.23 tsutsui stat = bus_space_read_1(memt, memh, NGLE_REG_15b0); 1809 1.23 tsutsui if (stat == 0) 1810 1.23 tsutsui stat = bus_space_read_1(memt, memh, NGLE_REG_15b0); 1811 1.23 tsutsui } while (stat != 0); 1812 1.23 tsutsui } 1813 1.23 tsutsui 1814 1.23 tsutsui void 1815 1.23 tsutsui ngle_setup_fb(bus_space_tag_t memt, bus_space_handle_t memh, uint32_t reg10) 1816 1.23 tsutsui { 1817 1.23 tsutsui 1818 1.23 tsutsui ngle_setup_hw(memt, memh); 1819 1.32 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_10, reg10); 1820 1.32 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_14, 0x83000300); 1821 1.23 tsutsui ngle_setup_hw(memt, memh); 1822 1.23 tsutsui bus_space_write_1(memt, memh, NGLE_REG_16b1, 1); 1823 1.23 tsutsui } 1824 1.23 tsutsui #endif /* SMALL_KERNEL */ 1825