sti.c revision 1.44 1 1.44 tsutsui /* $NetBSD: sti.c,v 1.44 2025/05/25 16:41:27 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.44 tsutsui __KERNEL_RCSID(0, "$NetBSD: sti.c,v 1.44 2025/05/25 16:41:27 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.13 skrll addr = bases[regno] + (r->offset << PGSHIFT);
451 1.13 skrll DPRINTF(("%08x @ 0x%08x%s%s%s%s",
452 1.13 skrll r->length << PGSHIFT, (int)addr, r->sys_only ? " sys" : "",
453 1.13 skrll r->cache ? " cache" : "", r->btlb ? " btlb" : "",
454 1.13 skrll r->last ? " last" : ""));
455 1.13 skrll
456 1.13 skrll /*
457 1.13 skrll * Region #0 is always the rom, and it should have been
458 1.13 skrll * mapped already.
459 1.13 skrll * XXX This expects a 1:1 mapping...
460 1.13 skrll */
461 1.13 skrll if (regno == 0 && romh == bases[0]) {
462 1.13 skrll cc->regions[0] = addr;
463 1.14 skrll DPRINTF(("\n"));
464 1.13 skrll continue;
465 1.13 skrll }
466 1.13 skrll
467 1.13 skrll if (bus_space_map(memt, addr, r->length << PGSHIFT,
468 1.23 tsutsui BUS_SPACE_MAP_LINEAR | (r->cache ?
469 1.23 tsutsui BUS_SPACE_MAP_CACHEABLE : 0), &rom->regh[regno]) != 0) {
470 1.23 tsutsui rom->regh[regno] = romh; /* XXX */
471 1.13 skrll DPRINTF((" - already mapped region\n"));
472 1.13 skrll } else {
473 1.23 tsutsui addr = (bus_addr_t)
474 1.23 tsutsui bus_space_vaddr(memt, rom->regh[regno]);
475 1.13 skrll if (regno == 1) {
476 1.14 skrll DPRINTF((" - fb"));
477 1.13 skrll scr->fbaddr = addr;
478 1.13 skrll scr->fblen = r->length << PGSHIFT;
479 1.13 skrll }
480 1.14 skrll DPRINTF(("\n"));
481 1.13 skrll }
482 1.1 jkunz
483 1.13 skrll cc->regions[regno] = addr;
484 1.13 skrll }
485 1.1 jkunz
486 1.1 jkunz #ifdef STIDEBUG
487 1.13 skrll /*
488 1.13 skrll * Make sure we'll trap accessing unmapped regions
489 1.13 skrll */
490 1.13 skrll for (regno = 0; regno < STI_REGION_MAX; regno++)
491 1.13 skrll if (cc->regions[regno] == 0)
492 1.13 skrll cc->regions[regno] = 0x81234567;
493 1.1 jkunz #endif
494 1.13 skrll }
495 1.1 jkunz
496 1.13 skrll int
497 1.13 skrll sti_screen_setup(struct sti_screen *scr, int flags)
498 1.13 skrll {
499 1.13 skrll struct sti_rom *rom = scr->scr_rom;
500 1.13 skrll bus_space_tag_t memt = rom->memt;
501 1.13 skrll bus_space_handle_t romh = rom->romh;
502 1.13 skrll struct sti_dd *dd = &rom->rom_dd;
503 1.13 skrll struct sti_cfg *cc = &scr->scr_cfg;
504 1.13 skrll struct sti_inqconfout cfg;
505 1.13 skrll struct sti_einqconfout ecfg;
506 1.1 jkunz #ifdef STIDEBUG
507 1.13 skrll char buf[256];
508 1.1 jkunz #endif
509 1.13 skrll int error, i;
510 1.13 skrll int geometry_kluge = 0;
511 1.13 skrll u_int fontindex = 0;
512 1.13 skrll
513 1.13 skrll KASSERT(scr != NULL);
514 1.13 skrll memset(cc, 0, sizeof(*cc));
515 1.13 skrll cc->ext_cfg = &scr->scr_ecfg;
516 1.13 skrll memset(cc->ext_cfg, 0, sizeof(*cc->ext_cfg));
517 1.13 skrll
518 1.13 skrll if (dd->dd_stimemreq) {
519 1.13 skrll scr->scr_ecfg.addr =
520 1.20 chs malloc(dd->dd_stimemreq, M_DEVBUF, M_WAITOK);
521 1.1 jkunz }
522 1.1 jkunz
523 1.13 skrll sti_region_setup(scr);
524 1.13 skrll
525 1.13 skrll if ((error = sti_init(scr, 0))) {
526 1.13 skrll aprint_error(": cannot initialize (%d)\n", error);
527 1.13 skrll goto fail;
528 1.1 jkunz }
529 1.1 jkunz
530 1.1 jkunz memset(&cfg, 0, sizeof(cfg));
531 1.1 jkunz memset(&ecfg, 0, sizeof(ecfg));
532 1.1 jkunz cfg.ext = &ecfg;
533 1.13 skrll if ((error = sti_inqcfg(scr, &cfg))) {
534 1.13 skrll aprint_error(": error %d inquiring config\n", error);
535 1.13 skrll goto fail;
536 1.1 jkunz }
537 1.1 jkunz
538 1.13 skrll /*
539 1.13 skrll * Older (rev 8.02) boards report wrong offset values,
540 1.13 skrll * similar to the displayable area size, at least in m68k mode.
541 1.13 skrll * Attempt to detect this and adjust here.
542 1.13 skrll */
543 1.13 skrll if (cfg.owidth == cfg.width &&
544 1.13 skrll cfg.oheight == cfg.height)
545 1.13 skrll geometry_kluge = 1;
546 1.13 skrll
547 1.13 skrll if (geometry_kluge) {
548 1.13 skrll scr->scr_cfg.oscr_width = cfg.owidth =
549 1.13 skrll cfg.fbwidth - cfg.width;
550 1.13 skrll scr->scr_cfg.oscr_height = cfg.oheight =
551 1.13 skrll cfg.fbheight - cfg.height;
552 1.1 jkunz }
553 1.1 jkunz
554 1.13 skrll /*
555 1.13 skrll * Save a few fields for sti_describe_screen() later
556 1.13 skrll */
557 1.13 skrll scr->fbheight = cfg.fbheight;
558 1.13 skrll scr->fbwidth = cfg.fbwidth;
559 1.13 skrll scr->oheight = cfg.oheight;
560 1.13 skrll scr->owidth = cfg.owidth;
561 1.13 skrll memcpy(scr->name, cfg.name, sizeof(scr->name));
562 1.13 skrll
563 1.35 macallan if (flags & STI_FBMODE) {
564 1.35 macallan /* we're done here */
565 1.35 macallan sti_init(scr, STI_FBMODE);
566 1.35 macallan return 0;
567 1.35 macallan }
568 1.35 macallan
569 1.13 skrll if ((error = sti_init(scr, STI_TEXTMODE | flags))) {
570 1.13 skrll aprint_error(": cannot initialize (%d)\n", error);
571 1.13 skrll goto fail;
572 1.13 skrll }
573 1.1 jkunz #ifdef STIDEBUG
574 1.13 skrll snprintb(buf, sizeof(buf), STI_INQCONF_BITS, cfg.attributes);
575 1.13 skrll DPRINTF(("conf: bpp=%d planes=%d attr=%s\n"
576 1.13 skrll "crt=0x%x:0x%x:0x%x hw=0x%x:0x%x:0x%x\n", cfg.bpp,
577 1.13 skrll cfg.planes, buf,
578 1.1 jkunz ecfg.crt_config[0], ecfg.crt_config[1], ecfg.crt_config[2],
579 1.13 skrll ecfg.crt_hw[0], ecfg.crt_hw[1], ecfg.crt_hw[2]));
580 1.1 jkunz #endif
581 1.13 skrll scr->scr_bpp = cfg.bppu;
582 1.13 skrll
583 1.13 skrll /*
584 1.13 skrll * Although scr->scr_ecfg.current_monitor is not filled by
585 1.13 skrll * sti_init() as expected, we can nevertheless walk the monitor
586 1.13 skrll * list, if there is any, and if we find a mode matching our
587 1.13 skrll * resolution, pick its font index.
588 1.13 skrll */
589 1.13 skrll if (dd->dd_montbl != 0) {
590 1.13 skrll STI_ENABLE_ROM(rom->rom_softc);
591 1.13 skrll
592 1.13 skrll for (i = 0; i < dd->dd_nmon; i++) {
593 1.13 skrll u_int offs = dd->dd_montbl + 8 * i;
594 1.13 skrll uint32_t m[2];
595 1.13 skrll sti_mon_t mon = (void *)m;
596 1.13 skrll if (rom->rom_devtype == STI_DEVTYPE1) {
597 1.13 skrll m[0] = parseword(4 * offs);
598 1.13 skrll m[1] = parseword(4 * (offs + 4));
599 1.13 skrll } else {
600 1.13 skrll bus_space_read_region_stream_4(memt, romh, offs,
601 1.13 skrll (uint32_t *)mon, sizeof(*mon) / 4);
602 1.13 skrll }
603 1.13 skrll
604 1.13 skrll if (mon->width == scr->scr_cfg.scr_width &&
605 1.13 skrll mon->height == scr->scr_cfg.scr_height) {
606 1.13 skrll fontindex = mon->font;
607 1.13 skrll break;
608 1.13 skrll }
609 1.13 skrll }
610 1.13 skrll
611 1.13 skrll STI_DISABLE_ROM(rom->rom_softc);
612 1.13 skrll
613 1.13 skrll DPRINTF(("font index: %d\n", fontindex));
614 1.13 skrll }
615 1.13 skrll
616 1.13 skrll if ((error = sti_fetchfonts(scr, &cfg, dd->dd_fntaddr, fontindex))) {
617 1.13 skrll aprint_error(": cannot fetch fonts (%d)\n", error);
618 1.13 skrll goto fail;
619 1.1 jkunz }
620 1.1 jkunz
621 1.1 jkunz /*
622 1.13 skrll * setup screen descriptions:
623 1.1 jkunz * figure number of fonts supported;
624 1.1 jkunz * allocate wscons structures;
625 1.1 jkunz * calculate dimensions.
626 1.1 jkunz */
627 1.1 jkunz
628 1.13 skrll scr->scr_wsd.name = "std";
629 1.13 skrll scr->scr_wsd.ncols = cfg.width / scr->scr_curfont.width;
630 1.13 skrll scr->scr_wsd.nrows = cfg.height / scr->scr_curfont.height;
631 1.13 skrll scr->scr_wsd.textops = &sti_emulops;
632 1.13 skrll scr->scr_wsd.fontwidth = scr->scr_curfont.width;
633 1.13 skrll scr->scr_wsd.fontheight = scr->scr_curfont.height;
634 1.24 tsutsui scr->scr_wsd.capabilities = WSSCREEN_REVERSE;
635 1.13 skrll
636 1.13 skrll scr->scr_scrlist[0] = &scr->scr_wsd;
637 1.13 skrll scr->scr_screenlist.nscreens = 1;
638 1.16 matt scr->scr_screenlist.screens = scr->scr_scrlist;
639 1.1 jkunz
640 1.23 tsutsui #ifndef SMALL_KERNEL
641 1.23 tsutsui /*
642 1.23 tsutsui * Decide which board-specific routines to use.
643 1.23 tsutsui */
644 1.23 tsutsui
645 1.23 tsutsui switch (dd->dd_grid[0]) {
646 1.23 tsutsui case STI_DD_CRX:
647 1.23 tsutsui scr->setupfb = ngle_elk_setupfb;
648 1.23 tsutsui scr->putcmap = ngle_putcmap;
649 1.23 tsutsui
650 1.23 tsutsui scr->reg10_value = 0x13601000;
651 1.23 tsutsui if (scr->scr_bpp > 8)
652 1.23 tsutsui scr->reg12_value = NGLE_BUFF1_CMAP3;
653 1.23 tsutsui else
654 1.23 tsutsui scr->reg12_value = NGLE_BUFF1_CMAP0;
655 1.23 tsutsui scr->cmap_finish_register = NGLE_REG_1;
656 1.23 tsutsui break;
657 1.23 tsutsui
658 1.23 tsutsui case STI_DD_TIMBER:
659 1.23 tsutsui scr->setupfb = ngle_timber_setupfb;
660 1.23 tsutsui scr->putcmap = ngle_putcmap;
661 1.23 tsutsui
662 1.23 tsutsui scr->reg10_value = 0x13602000;
663 1.23 tsutsui scr->reg12_value = NGLE_BUFF1_CMAP0;
664 1.23 tsutsui scr->cmap_finish_register = NGLE_REG_1;
665 1.23 tsutsui break;
666 1.23 tsutsui
667 1.23 tsutsui case STI_DD_ARTIST:
668 1.23 tsutsui scr->setupfb = ngle_artist_setupfb;
669 1.23 tsutsui scr->putcmap = ngle_putcmap;
670 1.23 tsutsui
671 1.23 tsutsui scr->reg10_value = 0x13601000;
672 1.23 tsutsui scr->reg12_value = NGLE_ARTIST_CMAP0;
673 1.23 tsutsui scr->cmap_finish_register = NGLE_REG_26;
674 1.23 tsutsui break;
675 1.23 tsutsui
676 1.23 tsutsui case STI_DD_EG:
677 1.23 tsutsui scr->setupfb = ngle_artist_setupfb;
678 1.23 tsutsui scr->putcmap = ngle_putcmap;
679 1.23 tsutsui
680 1.23 tsutsui scr->reg10_value = 0x13601000;
681 1.23 tsutsui if (scr->scr_bpp > 8) {
682 1.23 tsutsui scr->reg12_value = NGLE_BUFF1_CMAP3;
683 1.23 tsutsui scr->cmap_finish_register = NGLE_REG_1;
684 1.23 tsutsui } else {
685 1.23 tsutsui scr->reg12_value = NGLE_ARTIST_CMAP0;
686 1.23 tsutsui scr->cmap_finish_register = NGLE_REG_26;
687 1.23 tsutsui }
688 1.23 tsutsui break;
689 1.23 tsutsui
690 1.36 macallan case STI_DD_HCRX:
691 1.36 macallan scr->setupfb = ngle_elk_setupfb;
692 1.37 macallan scr->putcmap = ngle_hcrx_putcmap;
693 1.36 macallan
694 1.36 macallan if (scr->scr_bpp > 8) {
695 1.36 macallan scr->reg12_value = NGLE_BUFF1_CMAP3;
696 1.36 macallan scr->reg10_value = 0xBBA0A000;
697 1.36 macallan } else {
698 1.36 macallan scr->reg12_value = NGLE_BUFF1_CMAP0;
699 1.36 macallan scr->reg10_value = 0x13602000;
700 1.36 macallan }
701 1.37 macallan scr->cmap_finish_register = NGLE_REG_38;
702 1.36 macallan break;
703 1.36 macallan
704 1.40 macallan case STI_DD_SUMMIT:
705 1.42 macallan case STI_DD_LEGO:
706 1.40 macallan scr->setupfb = summit_setupfb;
707 1.40 macallan scr->putcmap = summit_putcmap;
708 1.40 macallan scr->scr_bpp = 8; /* for now */
709 1.40 macallan break;
710 1.40 macallan
711 1.44 tsutsui case STI_DD_EVRX:
712 1.44 tsutsui case STI_DD_382C:
713 1.44 tsutsui case STI_DD_3X2V:
714 1.44 tsutsui /*
715 1.44 tsutsui * EVRX, 382C, and 3X2V are available only on hp300 models
716 1.44 tsutsui * and board specific routines are handled by MD
717 1.44 tsutsui * sti_machdep_attach() in arch/hp300/dev/sti_machdep.c.
718 1.44 tsutsui */
719 1.44 tsutsui break;
720 1.44 tsutsui
721 1.23 tsutsui case STI_DD_GRX:
722 1.23 tsutsui case STI_DD_CRX24:
723 1.23 tsutsui case STI_DD_DUAL_CRX:
724 1.23 tsutsui case STI_DD_PINNACLE:
725 1.23 tsutsui default:
726 1.23 tsutsui scr->setupfb = NULL;
727 1.23 tsutsui scr->putcmap =
728 1.23 tsutsui rom->scment == NULL ? NULL : ngle_default_putcmap;
729 1.23 tsutsui break;
730 1.23 tsutsui }
731 1.23 tsutsui #endif
732 1.23 tsutsui
733 1.13 skrll return 0;
734 1.13 skrll
735 1.13 skrll fail:
736 1.13 skrll /* XXX free resources */
737 1.13 skrll if (scr->scr_ecfg.addr != NULL) {
738 1.13 skrll free(scr->scr_ecfg.addr, M_DEVBUF);
739 1.13 skrll scr->scr_ecfg.addr = NULL;
740 1.13 skrll }
741 1.13 skrll
742 1.13 skrll return ENXIO;
743 1.13 skrll }
744 1.13 skrll
745 1.13 skrll void
746 1.13 skrll sti_describe_screen(struct sti_softc *sc, struct sti_screen *scr)
747 1.13 skrll {
748 1.13 skrll struct sti_font *fp = &scr->scr_curfont;
749 1.13 skrll
750 1.13 skrll aprint_normal("%s: %s, %dx%d frame buffer, %dx%dx%d display\n",
751 1.13 skrll device_xname(sc->sc_dev), scr->name, scr->fbwidth, scr->fbheight,
752 1.13 skrll scr->scr_cfg.scr_width, scr->scr_cfg.scr_height, scr->scr_bpp);
753 1.13 skrll
754 1.13 skrll aprint_normal("%s: %dx%d font type %d, %d bpc, charset %d-%d\n",
755 1.13 skrll device_xname(sc->sc_dev), fp->width, fp->height,
756 1.13 skrll fp->type, fp->bpc, fp->first, fp->last);
757 1.13 skrll }
758 1.13 skrll
759 1.13 skrll void
760 1.13 skrll sti_describe(struct sti_softc *sc)
761 1.13 skrll {
762 1.13 skrll struct sti_rom *rom = sc->sc_rom;
763 1.13 skrll struct sti_dd *dd = &rom->rom_dd;
764 1.13 skrll
765 1.13 skrll aprint_normal(": rev %d.%02d;%d, ID 0x%08X%08X\n",
766 1.13 skrll dd->dd_grrev >> 4, dd->dd_grrev & 0xf,
767 1.13 skrll dd->dd_lrrev, dd->dd_grid[0], dd->dd_grid[1]);
768 1.1 jkunz
769 1.13 skrll if (sc->sc_scr != NULL)
770 1.13 skrll sti_describe_screen(sc, sc->sc_scr);
771 1.1 jkunz }
772 1.1 jkunz
773 1.23 tsutsui /*
774 1.23 tsutsui * Final part of attachment. On hppa where we use the PDC console
775 1.23 tsutsui * during autoconf, this has to be postponed until autoconf has
776 1.23 tsutsui * completed.
777 1.23 tsutsui */
778 1.1 jkunz void
779 1.13 skrll sti_end_attach(struct sti_softc *sc)
780 1.1 jkunz {
781 1.13 skrll struct sti_screen *scr = sc->sc_scr;
782 1.13 skrll
783 1.13 skrll if (scr == NULL)
784 1.13 skrll return;
785 1.13 skrll #if NWSDISPLAY > 0
786 1.13 skrll else {
787 1.13 skrll struct wsemuldisplaydev_attach_args waa;
788 1.13 skrll scr->scr_wsmode = WSDISPLAYIO_MODE_EMUL;
789 1.13 skrll
790 1.13 skrll waa.console = sc->sc_flags & STI_CONSOLE ? 1 : 0;
791 1.13 skrll waa.scrdata = &scr->scr_screenlist;
792 1.13 skrll waa.accessops = &sti_accessops;
793 1.13 skrll waa.accesscookie = scr;
794 1.13 skrll
795 1.13 skrll /* attach as console if required */
796 1.13 skrll if (waa.console && !ISSET(sc->sc_flags, STI_ATTACHED)) {
797 1.13 skrll long defattr;
798 1.13 skrll
799 1.13 skrll sti_alloc_attr(scr, 0, 0, 0, &defattr);
800 1.13 skrll wsdisplay_cnattach(&scr->scr_wsd, scr,
801 1.13 skrll 0, scr->scr_wsd.nrows - 1, defattr);
802 1.13 skrll sc->sc_flags |= STI_ATTACHED;
803 1.13 skrll }
804 1.13 skrll
805 1.30 thorpej config_found(sc->sc_dev, &waa, wsemuldisplaydevprint,
806 1.31 thorpej CFARGS_NONE);
807 1.13 skrll }
808 1.13 skrll #endif
809 1.13 skrll }
810 1.1 jkunz
811 1.13 skrll u_int
812 1.13 skrll sti_rom_size(bus_space_tag_t memt, bus_space_handle_t romh)
813 1.13 skrll {
814 1.13 skrll int devtype;
815 1.13 skrll u_int romend;
816 1.1 jkunz
817 1.13 skrll devtype = bus_space_read_1(memt, romh, 3);
818 1.13 skrll if (devtype == STI_DEVTYPE4) {
819 1.13 skrll bus_space_read_region_stream_4(memt, romh, STI_DEV4_DD_ROMEND,
820 1.13 skrll (uint32_t *)&romend, 1);
821 1.13 skrll } else {
822 1.13 skrll romend = parseword(STI_DEV1_DD_ROMEND);
823 1.1 jkunz }
824 1.1 jkunz
825 1.13 skrll DPRINTF(("%s: %08x (%08x)\n", __func__, romend, round_page(romend)));
826 1.13 skrll
827 1.13 skrll return round_page(romend);
828 1.1 jkunz }
829 1.1 jkunz
830 1.1 jkunz int
831 1.13 skrll sti_fetchfonts(struct sti_screen *scr, struct sti_inqconfout *cfg,
832 1.13 skrll uint32_t baseaddr, u_int fontindex)
833 1.1 jkunz {
834 1.13 skrll struct sti_rom *rom = scr->scr_rom;
835 1.13 skrll bus_space_tag_t memt = rom->memt;
836 1.13 skrll bus_space_handle_t romh = rom->romh;
837 1.13 skrll struct sti_font *fp = &scr->scr_curfont;
838 1.13 skrll uint32_t addr;
839 1.1 jkunz int size;
840 1.1 jkunz #ifdef notyet
841 1.1 jkunz int uc;
842 1.1 jkunz struct {
843 1.1 jkunz struct sti_unpmvflags flags;
844 1.1 jkunz struct sti_unpmvin in;
845 1.1 jkunz struct sti_unpmvout out;
846 1.1 jkunz } a;
847 1.1 jkunz #endif
848 1.1 jkunz
849 1.1 jkunz /*
850 1.1 jkunz * Get the first PROM font in memory
851 1.1 jkunz */
852 1.13 skrll
853 1.13 skrll STI_ENABLE_ROM(rom->rom_softc);
854 1.13 skrll
855 1.13 skrll rescan:
856 1.13 skrll addr = baseaddr;
857 1.1 jkunz do {
858 1.13 skrll if (rom->rom_devtype == STI_DEVTYPE1) {
859 1.1 jkunz fp->first = parseshort(addr + 0x00);
860 1.1 jkunz fp->last = parseshort(addr + 0x08);
861 1.13 skrll fp->width = bus_space_read_1(memt, romh, addr + 0x13);
862 1.13 skrll fp->height = bus_space_read_1(memt, romh, addr + 0x17);
863 1.13 skrll fp->type = bus_space_read_1(memt, romh, addr + 0x1b);
864 1.13 skrll fp->bpc = bus_space_read_1(memt, romh, addr + 0x1f);
865 1.13 skrll fp->next = parseword(addr + 0x20);
866 1.13 skrll fp->uheight= bus_space_read_1(memt, romh, addr + 0x33);
867 1.13 skrll fp->uoffset= bus_space_read_1(memt, romh, addr + 0x37);
868 1.13 skrll } else { /* STI_DEVTYPE4 */
869 1.13 skrll bus_space_read_region_stream_4(memt, romh, addr,
870 1.12 skrll (uint32_t *)fp, sizeof(struct sti_font) / 4);
871 1.13 skrll }
872 1.1 jkunz
873 1.13 skrll #ifdef STIDEBUG
874 1.13 skrll STI_DISABLE_ROM(rom->rom_softc);
875 1.13 skrll DPRINTF(("%s: %dx%d font type %d, %d bpc, charset %d-%d\n",
876 1.13 skrll device_xname(scr->scr_rom->rom_softc->sc_dev), fp->width,
877 1.13 skrll fp->height, fp->type, fp->bpc, fp->first, fp->last));
878 1.13 skrll STI_ENABLE_ROM(rom->rom_softc);
879 1.13 skrll #endif
880 1.1 jkunz
881 1.13 skrll if (fontindex == 0) {
882 1.13 skrll size = sizeof(struct sti_font) +
883 1.13 skrll (fp->last - fp->first + 1) * fp->bpc;
884 1.13 skrll if (rom->rom_devtype == STI_DEVTYPE1)
885 1.13 skrll size *= 4;
886 1.20 chs scr->scr_romfont = malloc(size, M_DEVBUF, M_WAITOK);
887 1.1 jkunz
888 1.13 skrll bus_space_read_region_stream_4(memt, romh, addr,
889 1.13 skrll (uint32_t *)scr->scr_romfont, size / 4);
890 1.13 skrll break;
891 1.13 skrll }
892 1.13 skrll
893 1.13 skrll addr = baseaddr + fp->next;
894 1.13 skrll fontindex--;
895 1.13 skrll } while (fp->next != 0);
896 1.13 skrll
897 1.13 skrll /*
898 1.13 skrll * If our font index was bogus, we did not find the expected font.
899 1.13 skrll * In this case, pick the first one and be done with it.
900 1.13 skrll */
901 1.13 skrll if (fp->next == 0 && scr->scr_romfont == NULL) {
902 1.13 skrll fontindex = 0;
903 1.13 skrll goto rescan;
904 1.13 skrll }
905 1.13 skrll
906 1.13 skrll STI_DISABLE_ROM(rom->rom_softc);
907 1.1 jkunz
908 1.1 jkunz #ifdef notyet
909 1.1 jkunz /*
910 1.1 jkunz * If there is enough room in the off-screen framebuffer memory,
911 1.1 jkunz * display all the characters there in order to display them
912 1.1 jkunz * faster with blkmv operations rather than unpmv later on.
913 1.1 jkunz */
914 1.1 jkunz if (size <= cfg->fbheight *
915 1.1 jkunz (cfg->fbwidth - cfg->width - cfg->owidth)) {
916 1.1 jkunz memset(&a, 0, sizeof(a));
917 1.1 jkunz a.flags.flags = STI_UNPMVF_WAIT;
918 1.1 jkunz a.in.fg_colour = STI_COLOUR_WHITE;
919 1.1 jkunz a.in.bg_colour = STI_COLOUR_BLACK;
920 1.13 skrll a.in.font_addr = scr->scr_romfont;
921 1.1 jkunz
922 1.13 skrll scr->scr_fontmaxcol = cfg->fbheight / fp->height;
923 1.13 skrll scr->scr_fontbase = cfg->width + cfg->owidth;
924 1.1 jkunz for (uc = fp->first; uc <= fp->last; uc++) {
925 1.13 skrll a.in.x = ((uc - fp->first) / scr->scr_fontmaxcol) *
926 1.13 skrll fp->width + scr->scr_fontbase;
927 1.13 skrll a.in.y = ((uc - fp->first) % scr->scr_fontmaxcol) *
928 1.1 jkunz fp->height;
929 1.1 jkunz a.in.index = uc;
930 1.1 jkunz
931 1.13 skrll (*scr->unpmv)(&a.flags, &a.in, &a.out, &scr->scr_cfg);
932 1.1 jkunz if (a.out.errno) {
933 1.13 skrll aprint_error_dev(sc->sc_dev, "unpmv %d "
934 1.13 skrll "returned %d\n", uc, a.out.errno);
935 1.13 skrll return 0;
936 1.1 jkunz }
937 1.1 jkunz }
938 1.1 jkunz
939 1.13 skrll free(scr->scr_romfont, M_DEVBUF);
940 1.13 skrll scr->scr_romfont = NULL;
941 1.1 jkunz }
942 1.1 jkunz #endif
943 1.1 jkunz
944 1.13 skrll return 0;
945 1.1 jkunz }
946 1.1 jkunz
947 1.13 skrll /*
948 1.13 skrll * Wrappers around STI code pointers
949 1.13 skrll */
950 1.23 tsutsui
951 1.1 jkunz int
952 1.13 skrll sti_init(struct sti_screen *scr, int mode)
953 1.1 jkunz {
954 1.13 skrll struct sti_rom *rom = scr->scr_rom;
955 1.1 jkunz struct {
956 1.1 jkunz struct sti_initflags flags;
957 1.1 jkunz struct sti_initin in;
958 1.13 skrll struct sti_einitin ein;
959 1.1 jkunz struct sti_initout out;
960 1.1 jkunz } a;
961 1.1 jkunz
962 1.13 skrll KASSERT(rom != NULL);
963 1.1 jkunz memset(&a, 0, sizeof(a));
964 1.1 jkunz
965 1.32 macallan a.flags.flags = STI_INITF_WAIT | STI_INITF_PBET | STI_INITF_PBETI;
966 1.21 tsutsui if ((mode & STI_TEXTMODE) != 0) {
967 1.21 tsutsui a.flags.flags |= STI_INITF_TEXT | STI_INITF_CMB |
968 1.21 tsutsui STI_INITF_PBET | STI_INITF_PBETI | STI_INITF_ICMT;
969 1.32 macallan a.in.text_planes = 1;
970 1.21 tsutsui } else {
971 1.32 macallan a.flags.flags |= STI_INITF_TEXT | STI_INITF_NTEXT;
972 1.34 skrll /*
973 1.34 skrll * Request as many text planes as STI will allow.
974 1.32 macallan * The reason to do this - when switching to framebuffer mode
975 1.32 macallan * for X we need access to all planes. In theory STI should do
976 1.32 macallan * just that when we request access to both text and non-text
977 1.32 macallan * planes as above.
978 1.32 macallan * In reality though, at least on my PCI Visualize EG, some
979 1.32 macallan * planes and/or colour registers remain inaccessible if we
980 1.32 macallan * request only one text plane.
981 1.32 macallan * Clearly we're missing a register write or two here, but so
982 1.32 macallan * far I haven't found it.
983 1.32 macallan */
984 1.32 macallan a.in.text_planes = 3;
985 1.21 tsutsui }
986 1.21 tsutsui if ((mode & STI_CLEARSCR) != 0)
987 1.21 tsutsui a.flags.flags |= STI_INITF_CLEAR;
988 1.21 tsutsui
989 1.13 skrll a.in.ext_in = &a.ein;
990 1.13 skrll
991 1.13 skrll DPRINTF(("%s: init,%p(%x, %p, %p, %p)\n",
992 1.13 skrll device_xname(rom->rom_softc->sc_dev), rom->init, a.flags.flags,
993 1.13 skrll &a.in, &a.out, &scr->scr_cfg));
994 1.13 skrll
995 1.13 skrll (*rom->init)(&a.flags, &a.in, &a.out, &scr->scr_cfg);
996 1.13 skrll
997 1.13 skrll if (a.out.text_planes != a.in.text_planes)
998 1.13 skrll return -1; /* not colliding with sti errno values */
999 1.13 skrll return a.out.errno;
1000 1.1 jkunz }
1001 1.1 jkunz
1002 1.1 jkunz int
1003 1.13 skrll sti_inqcfg(struct sti_screen *scr, struct sti_inqconfout *out)
1004 1.1 jkunz {
1005 1.13 skrll struct sti_rom *rom = scr->scr_rom;
1006 1.1 jkunz struct {
1007 1.1 jkunz struct sti_inqconfflags flags;
1008 1.1 jkunz struct sti_inqconfin in;
1009 1.1 jkunz } a;
1010 1.1 jkunz
1011 1.1 jkunz memset(&a, 0, sizeof(a));
1012 1.1 jkunz
1013 1.1 jkunz a.flags.flags = STI_INQCONFF_WAIT;
1014 1.13 skrll (*rom->inqconf)(&a.flags, &a.in, out, &scr->scr_cfg);
1015 1.1 jkunz
1016 1.1 jkunz return out->errno;
1017 1.1 jkunz }
1018 1.1 jkunz
1019 1.1 jkunz void
1020 1.13 skrll sti_bmove(struct sti_screen *scr, int x1, int y1, int x2, int y2, int h, int w,
1021 1.1 jkunz enum sti_bmove_funcs f)
1022 1.1 jkunz {
1023 1.13 skrll struct sti_rom *rom = scr->scr_rom;
1024 1.1 jkunz struct {
1025 1.1 jkunz struct sti_blkmvflags flags;
1026 1.1 jkunz struct sti_blkmvin in;
1027 1.1 jkunz struct sti_blkmvout out;
1028 1.1 jkunz } a;
1029 1.1 jkunz
1030 1.1 jkunz memset(&a, 0, sizeof(a));
1031 1.1 jkunz
1032 1.1 jkunz a.flags.flags = STI_BLKMVF_WAIT;
1033 1.1 jkunz switch (f) {
1034 1.1 jkunz case bmf_clear:
1035 1.1 jkunz a.flags.flags |= STI_BLKMVF_CLR;
1036 1.1 jkunz a.in.bg_colour = STI_COLOUR_BLACK;
1037 1.1 jkunz break;
1038 1.1 jkunz case bmf_underline:
1039 1.1 jkunz case bmf_copy:
1040 1.1 jkunz a.in.fg_colour = STI_COLOUR_WHITE;
1041 1.1 jkunz a.in.bg_colour = STI_COLOUR_BLACK;
1042 1.1 jkunz break;
1043 1.1 jkunz case bmf_invert:
1044 1.1 jkunz a.flags.flags |= STI_BLKMVF_COLR;
1045 1.1 jkunz a.in.fg_colour = STI_COLOUR_BLACK;
1046 1.1 jkunz a.in.bg_colour = STI_COLOUR_WHITE;
1047 1.1 jkunz break;
1048 1.1 jkunz }
1049 1.1 jkunz a.in.srcx = x1;
1050 1.1 jkunz a.in.srcy = y1;
1051 1.1 jkunz a.in.dstx = x2;
1052 1.1 jkunz a.in.dsty = y2;
1053 1.1 jkunz a.in.height = h;
1054 1.1 jkunz a.in.width = w;
1055 1.1 jkunz
1056 1.13 skrll (*rom->blkmv)(&a.flags, &a.in, &a.out, &scr->scr_cfg);
1057 1.1 jkunz #ifdef STIDEBUG
1058 1.1 jkunz if (a.out.errno)
1059 1.13 skrll printf("%s: blkmv returned %d\n",
1060 1.13 skrll device_xname(rom->rom_softc->sc_dev), a.out.errno);
1061 1.1 jkunz #endif
1062 1.1 jkunz }
1063 1.1 jkunz
1064 1.1 jkunz int
1065 1.13 skrll sti_setcment(struct sti_screen *scr, u_int i, u_char r, u_char g, u_char b)
1066 1.1 jkunz {
1067 1.13 skrll struct sti_rom *rom = scr->scr_rom;
1068 1.1 jkunz struct {
1069 1.1 jkunz struct sti_scmentflags flags;
1070 1.1 jkunz struct sti_scmentin in;
1071 1.1 jkunz struct sti_scmentout out;
1072 1.1 jkunz } a;
1073 1.1 jkunz
1074 1.1 jkunz memset(&a, 0, sizeof(a));
1075 1.1 jkunz
1076 1.1 jkunz a.flags.flags = STI_SCMENTF_WAIT;
1077 1.1 jkunz a.in.entry = i;
1078 1.1 jkunz a.in.value = (r << 16) | (g << 8) | b;
1079 1.1 jkunz
1080 1.13 skrll (*rom->scment)(&a.flags, &a.in, &a.out, &scr->scr_cfg);
1081 1.1 jkunz
1082 1.1 jkunz return a.out.errno;
1083 1.1 jkunz }
1084 1.1 jkunz
1085 1.13 skrll /*
1086 1.13 skrll * wsdisplay accessops
1087 1.13 skrll */
1088 1.1 jkunz int
1089 1.7 christos sti_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, struct lwp *l)
1090 1.1 jkunz {
1091 1.13 skrll struct sti_screen *scr = (struct sti_screen *)v;
1092 1.38 macallan struct sti_rom *rom = scr->scr_rom;
1093 1.1 jkunz struct wsdisplay_fbinfo *wdf;
1094 1.1 jkunz struct wsdisplay_cmap *cmapp;
1095 1.1 jkunz u_int mode, idx, count;
1096 1.23 tsutsui int ret;
1097 1.1 jkunz
1098 1.1 jkunz ret = 0;
1099 1.1 jkunz switch (cmd) {
1100 1.38 macallan case GCID:
1101 1.39 skrll *(u_int *)data = rom->rom_dd.dd_grid[0];
1102 1.38 macallan break;
1103 1.38 macallan
1104 1.1 jkunz case WSDISPLAYIO_GMODE:
1105 1.13 skrll *(u_int *)data = scr->scr_wsmode;
1106 1.1 jkunz break;
1107 1.1 jkunz
1108 1.1 jkunz case WSDISPLAYIO_SMODE:
1109 1.1 jkunz mode = *(u_int *)data;
1110 1.23 tsutsui switch (mode) {
1111 1.23 tsutsui case WSDISPLAYIO_MODE_EMUL:
1112 1.23 tsutsui if (scr->scr_wsmode != WSDISPLAYIO_MODE_EMUL)
1113 1.23 tsutsui ret = sti_init(scr, STI_TEXTMODE);
1114 1.23 tsutsui break;
1115 1.23 tsutsui case WSDISPLAYIO_MODE_DUMBFB:
1116 1.23 tsutsui if (scr->scr_wsmode != WSDISPLAYIO_MODE_DUMBFB) {
1117 1.32 macallan ret = sti_init(scr, 0);
1118 1.23 tsutsui if (scr->setupfb != NULL)
1119 1.23 tsutsui scr->setupfb(scr);
1120 1.23 tsutsui else
1121 1.23 tsutsui #if 0
1122 1.23 tsutsui ret = sti_init(scr, STI_FBMODE);
1123 1.23 tsutsui #else
1124 1.23 tsutsui ret = EINVAL;
1125 1.23 tsutsui #endif
1126 1.23 tsutsui }
1127 1.23 tsutsui break;
1128 1.23 tsutsui case WSDISPLAYIO_MODE_MAPPED:
1129 1.23 tsutsui default:
1130 1.23 tsutsui ret = EINVAL;
1131 1.23 tsutsui break;
1132 1.23 tsutsui }
1133 1.23 tsutsui if (ret == 0)
1134 1.23 tsutsui scr->scr_wsmode = mode;
1135 1.1 jkunz break;
1136 1.1 jkunz
1137 1.1 jkunz case WSDISPLAYIO_GTYPE:
1138 1.1 jkunz *(u_int *)data = WSDISPLAY_TYPE_STI;
1139 1.1 jkunz break;
1140 1.1 jkunz
1141 1.1 jkunz case WSDISPLAYIO_GINFO:
1142 1.1 jkunz wdf = (struct wsdisplay_fbinfo *)data;
1143 1.13 skrll wdf->height = scr->scr_cfg.scr_height;
1144 1.13 skrll wdf->width = scr->scr_cfg.scr_width;
1145 1.13 skrll wdf->depth = scr->scr_bpp;
1146 1.23 tsutsui if (scr->putcmap == NULL || scr->scr_bpp > 8)
1147 1.13 skrll wdf->cmsize = 0;
1148 1.13 skrll else
1149 1.13 skrll wdf->cmsize = STI_NCMAP;
1150 1.1 jkunz break;
1151 1.1 jkunz
1152 1.1 jkunz case WSDISPLAYIO_LINEBYTES:
1153 1.23 tsutsui if (scr->scr_bpp > 8)
1154 1.23 tsutsui *(u_int *)data = scr->scr_cfg.fb_width * 4;
1155 1.23 tsutsui else
1156 1.23 tsutsui *(u_int *)data = scr->scr_cfg.fb_width;
1157 1.1 jkunz break;
1158 1.1 jkunz
1159 1.1 jkunz case WSDISPLAYIO_GETCMAP:
1160 1.23 tsutsui if (scr->putcmap == NULL || scr->scr_bpp > 8)
1161 1.23 tsutsui return ENODEV;
1162 1.1 jkunz cmapp = (struct wsdisplay_cmap *)data;
1163 1.1 jkunz idx = cmapp->index;
1164 1.1 jkunz count = cmapp->count;
1165 1.19 spz if (idx >= STI_NCMAP || count > STI_NCMAP - idx)
1166 1.1 jkunz return EINVAL;
1167 1.13 skrll if ((ret = copyout(&scr->scr_rcmap[idx], cmapp->red, count)))
1168 1.1 jkunz break;
1169 1.13 skrll if ((ret = copyout(&scr->scr_gcmap[idx], cmapp->green, count)))
1170 1.1 jkunz break;
1171 1.13 skrll if ((ret = copyout(&scr->scr_bcmap[idx], cmapp->blue, count)))
1172 1.1 jkunz break;
1173 1.1 jkunz break;
1174 1.1 jkunz
1175 1.1 jkunz case WSDISPLAYIO_PUTCMAP:
1176 1.23 tsutsui if (scr->putcmap == NULL || scr->scr_bpp > 8)
1177 1.23 tsutsui return ENODEV;
1178 1.25 tsutsui if (scr->scr_wsmode == WSDISPLAYIO_MODE_EMUL) {
1179 1.25 tsutsui /*
1180 1.25 tsutsui * The hardware palette settings are handled by
1181 1.25 tsutsui * the STI ROM in STI_TEXTMODE and changing cmap
1182 1.25 tsutsui * could cause mangled text colors at least on CRX.
1183 1.25 tsutsui * Updating CMAP in EMUL mode isn't expected anyway
1184 1.25 tsutsui * so just ignore it.
1185 1.25 tsutsui */
1186 1.25 tsutsui return 0;
1187 1.25 tsutsui }
1188 1.1 jkunz cmapp = (struct wsdisplay_cmap *)data;
1189 1.1 jkunz idx = cmapp->index;
1190 1.1 jkunz count = cmapp->count;
1191 1.19 spz if (idx >= STI_NCMAP || count > STI_NCMAP - idx)
1192 1.1 jkunz return EINVAL;
1193 1.13 skrll if ((ret = copyin(cmapp->red, &scr->scr_rcmap[idx], count)))
1194 1.1 jkunz break;
1195 1.13 skrll if ((ret = copyin(cmapp->green, &scr->scr_gcmap[idx], count)))
1196 1.1 jkunz break;
1197 1.13 skrll if ((ret = copyin(cmapp->blue, &scr->scr_bcmap[idx], count)))
1198 1.1 jkunz break;
1199 1.23 tsutsui ret = scr->putcmap(scr, idx, count);
1200 1.1 jkunz break;
1201 1.1 jkunz
1202 1.1 jkunz case WSDISPLAYIO_SVIDEO:
1203 1.1 jkunz case WSDISPLAYIO_GVIDEO:
1204 1.1 jkunz case WSDISPLAYIO_GCURPOS:
1205 1.1 jkunz case WSDISPLAYIO_SCURPOS:
1206 1.1 jkunz case WSDISPLAYIO_GCURMAX:
1207 1.1 jkunz case WSDISPLAYIO_GCURSOR:
1208 1.1 jkunz case WSDISPLAYIO_SCURSOR:
1209 1.1 jkunz default:
1210 1.13 skrll return ENOTTY; /* not supported yet */
1211 1.1 jkunz }
1212 1.1 jkunz
1213 1.13 skrll return ret;
1214 1.1 jkunz }
1215 1.1 jkunz
1216 1.1 jkunz paddr_t
1217 1.6 jmmv sti_mmap(void *v, void *vs, off_t offset, int prot)
1218 1.1 jkunz {
1219 1.23 tsutsui struct sti_screen *scr = (struct sti_screen *)v;
1220 1.23 tsutsui struct sti_rom *rom = scr->scr_rom;
1221 1.23 tsutsui paddr_t pa;
1222 1.23 tsutsui
1223 1.23 tsutsui if ((offset & PAGE_MASK) != 0)
1224 1.23 tsutsui return -1;
1225 1.23 tsutsui
1226 1.23 tsutsui if (offset < 0 || offset >= scr->fblen)
1227 1.23 tsutsui return -1;
1228 1.23 tsutsui
1229 1.27 skrll if (scr->scr_wsmode != WSDISPLAYIO_MODE_DUMBFB)
1230 1.27 skrll return -1;
1231 1.27 skrll
1232 1.23 tsutsui pa = bus_space_mmap(rom->memt, scr->fbaddr, offset, prot,
1233 1.23 tsutsui BUS_SPACE_MAP_LINEAR);
1234 1.27 skrll
1235 1.27 skrll if (pa == -1)
1236 1.27 skrll pa = scr->fbaddr + offset;
1237 1.23 tsutsui
1238 1.23 tsutsui return pa;
1239 1.1 jkunz }
1240 1.1 jkunz
1241 1.1 jkunz int
1242 1.3 perry sti_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep,
1243 1.1 jkunz int *cxp, int *cyp, long *defattr)
1244 1.1 jkunz {
1245 1.13 skrll struct sti_screen *scr = (struct sti_screen *)v;
1246 1.1 jkunz
1247 1.13 skrll if (scr->scr_nscreens > 0)
1248 1.1 jkunz return ENOMEM;
1249 1.1 jkunz
1250 1.13 skrll *cookiep = scr;
1251 1.1 jkunz *cxp = 0;
1252 1.1 jkunz *cyp = 0;
1253 1.13 skrll sti_alloc_attr(scr, 0, 0, 0, defattr);
1254 1.13 skrll scr->scr_nscreens++;
1255 1.1 jkunz return 0;
1256 1.1 jkunz }
1257 1.1 jkunz
1258 1.1 jkunz void
1259 1.1 jkunz sti_free_screen(void *v, void *cookie)
1260 1.1 jkunz {
1261 1.13 skrll struct sti_screen *scr = (struct sti_screen *)v;
1262 1.1 jkunz
1263 1.13 skrll scr->scr_nscreens--;
1264 1.1 jkunz }
1265 1.1 jkunz
1266 1.1 jkunz int
1267 1.13 skrll sti_show_screen(void *v, void *cookie, int waitok, void (*cb)(void *, int, int),
1268 1.13 skrll void *cbarg)
1269 1.1 jkunz {
1270 1.13 skrll #if 0
1271 1.13 skrll struct sti_screen *scr = (struct sti_screen *)v;
1272 1.13 skrll #endif
1273 1.13 skrll
1274 1.1 jkunz return 0;
1275 1.1 jkunz }
1276 1.1 jkunz
1277 1.1 jkunz int
1278 1.1 jkunz sti_load_font(void *v, void *cookie, struct wsdisplay_font *font)
1279 1.1 jkunz {
1280 1.13 skrll #if 0
1281 1.13 skrll struct sti_screen *scr = (struct sti_screen *)v;
1282 1.13 skrll #endif
1283 1.13 skrll
1284 1.1 jkunz return -1;
1285 1.1 jkunz }
1286 1.1 jkunz
1287 1.13 skrll /*
1288 1.13 skrll * wsdisplay emulops
1289 1.13 skrll */
1290 1.1 jkunz void
1291 1.1 jkunz sti_cursor(void *v, int on, int row, int col)
1292 1.1 jkunz {
1293 1.13 skrll struct sti_screen *scr = (struct sti_screen *)v;
1294 1.13 skrll struct sti_font *fp = &scr->scr_curfont;
1295 1.1 jkunz
1296 1.23 tsutsui sti_bmove(scr,
1297 1.23 tsutsui col * fp->width, row * fp->height,
1298 1.23 tsutsui col * fp->width, row * fp->height,
1299 1.23 tsutsui fp->height, fp->width, bmf_invert);
1300 1.1 jkunz }
1301 1.1 jkunz
1302 1.13 skrll /*
1303 1.13 skrll * ISO 8859-1 part of Unicode to HP Roman font index conversion array.
1304 1.13 skrll */
1305 1.43 macallan const uint8_t
1306 1.13 skrll sti_unitoroman[0x100 - 0xa0] = {
1307 1.13 skrll 0xa0, 0xb8, 0xbf, 0xbb, 0xba, 0xbc, 0, 0xbd,
1308 1.13 skrll 0xab, 0, 0xf9, 0xfb, 0, 0xf6, 0, 0xb0,
1309 1.26 skrll
1310 1.13 skrll 0xb3, 0xfe, 0, 0, 0xa8, 0xf3, 0xf4, 0xf2,
1311 1.13 skrll 0, 0, 0xfa, 0xfd, 0xf7, 0xf8, 0, 0xb9,
1312 1.13 skrll
1313 1.13 skrll 0xa1, 0xe0, 0xa2, 0xe1, 0xd8, 0xd0, 0xd3, 0xb4,
1314 1.13 skrll 0xa3, 0xdc, 0xa4, 0xa5, 0xe6, 0xe5, 0xa6, 0xa7,
1315 1.13 skrll
1316 1.13 skrll 0xe3, 0xb6, 0xe8, 0xe7, 0xdf, 0xe9, 0xda, 0,
1317 1.13 skrll 0xd2, 0xad, 0xed, 0xae, 0xdb, 0xb1, 0xf0, 0xde,
1318 1.13 skrll
1319 1.13 skrll 0xc8, 0xc4, 0xc0, 0xe2, 0xcc, 0xd4, 0xd7, 0xb5,
1320 1.13 skrll 0xc9, 0xc5, 0xc1, 0xcd, 0xd9, 0xd5, 0xd1, 0xdd,
1321 1.13 skrll
1322 1.13 skrll 0xe4, 0xb7, 0xca, 0xc6, 0xc2, 0xea, 0xce, 0,
1323 1.13 skrll 0xd6, 0xcb, 0xc7, 0xc3, 0xcf, 0xb2, 0xf1, 0xef
1324 1.13 skrll };
1325 1.13 skrll
1326 1.1 jkunz int
1327 1.1 jkunz sti_mapchar(void *v, int uni, u_int *index)
1328 1.1 jkunz {
1329 1.13 skrll struct sti_screen *scr = (struct sti_screen *)v;
1330 1.13 skrll struct sti_font *fp = &scr->scr_curfont;
1331 1.13 skrll int c;
1332 1.13 skrll
1333 1.13 skrll switch (fp->type) {
1334 1.13 skrll case STI_FONT_HPROMAN8:
1335 1.13 skrll if (uni >= 0x80 && uni < 0xa0)
1336 1.13 skrll c = -1;
1337 1.13 skrll else if (uni >= 0xa0 && uni < 0x100) {
1338 1.13 skrll c = (int)sti_unitoroman[uni - 0xa0];
1339 1.13 skrll if (c == 0)
1340 1.13 skrll c = -1;
1341 1.13 skrll } else
1342 1.13 skrll c = uni;
1343 1.13 skrll break;
1344 1.13 skrll default:
1345 1.13 skrll c = uni;
1346 1.13 skrll break;
1347 1.13 skrll }
1348 1.1 jkunz
1349 1.13 skrll if (c == -1 || c < fp->first || c > fp->last) {
1350 1.13 skrll *index = ' ';
1351 1.13 skrll return 0;
1352 1.13 skrll }
1353 1.13 skrll
1354 1.13 skrll *index = c;
1355 1.13 skrll return 5;
1356 1.1 jkunz }
1357 1.1 jkunz
1358 1.1 jkunz void
1359 1.1 jkunz sti_putchar(void *v, int row, int col, u_int uc, long attr)
1360 1.1 jkunz {
1361 1.13 skrll struct sti_screen *scr = (struct sti_screen *)v;
1362 1.13 skrll struct sti_rom *rom = scr->scr_rom;
1363 1.13 skrll struct sti_font *fp = &scr->scr_curfont;
1364 1.24 tsutsui int bg, fg;
1365 1.24 tsutsui
1366 1.24 tsutsui fg = WSATTR_UNPACK_FG(attr);
1367 1.24 tsutsui bg = WSATTR_UNPACK_BG(attr);
1368 1.1 jkunz
1369 1.13 skrll if (scr->scr_romfont != NULL) {
1370 1.1 jkunz /*
1371 1.1 jkunz * Font is in memory, use unpmv
1372 1.1 jkunz */
1373 1.1 jkunz struct {
1374 1.1 jkunz struct sti_unpmvflags flags;
1375 1.1 jkunz struct sti_unpmvin in;
1376 1.1 jkunz struct sti_unpmvout out;
1377 1.1 jkunz } a;
1378 1.1 jkunz
1379 1.1 jkunz memset(&a, 0, sizeof(a));
1380 1.1 jkunz
1381 1.1 jkunz a.flags.flags = STI_UNPMVF_WAIT;
1382 1.24 tsutsui a.in.fg_colour = fg;
1383 1.24 tsutsui a.in.bg_colour = bg;
1384 1.1 jkunz a.in.x = col * fp->width;
1385 1.1 jkunz a.in.y = row * fp->height;
1386 1.13 skrll a.in.font_addr = scr->scr_romfont;
1387 1.1 jkunz a.in.index = uc;
1388 1.1 jkunz
1389 1.13 skrll (*rom->unpmv)(&a.flags, &a.in, &a.out, &scr->scr_cfg);
1390 1.1 jkunz } else {
1391 1.1 jkunz /*
1392 1.1 jkunz * Font is in frame buffer, use blkmv
1393 1.1 jkunz */
1394 1.1 jkunz struct {
1395 1.1 jkunz struct sti_blkmvflags flags;
1396 1.1 jkunz struct sti_blkmvin in;
1397 1.1 jkunz struct sti_blkmvout out;
1398 1.1 jkunz } a;
1399 1.1 jkunz
1400 1.1 jkunz memset(&a, 0, sizeof(a));
1401 1.1 jkunz
1402 1.1 jkunz a.flags.flags = STI_BLKMVF_WAIT;
1403 1.24 tsutsui a.in.fg_colour = fg;
1404 1.24 tsutsui a.in.bg_colour = bg;
1405 1.1 jkunz
1406 1.13 skrll a.in.srcx = ((uc - fp->first) / scr->scr_fontmaxcol) *
1407 1.13 skrll fp->width + scr->scr_fontbase;
1408 1.13 skrll a.in.srcy = ((uc - fp->first) % scr->scr_fontmaxcol) *
1409 1.1 jkunz fp->height;
1410 1.1 jkunz a.in.dstx = col * fp->width;
1411 1.1 jkunz a.in.dsty = row * fp->height;
1412 1.1 jkunz a.in.height = fp->height;
1413 1.1 jkunz a.in.width = fp->width;
1414 1.1 jkunz
1415 1.13 skrll (*rom->blkmv)(&a.flags, &a.in, &a.out, &scr->scr_cfg);
1416 1.1 jkunz }
1417 1.1 jkunz }
1418 1.1 jkunz
1419 1.1 jkunz void
1420 1.1 jkunz sti_copycols(void *v, int row, int srccol, int dstcol, int ncols)
1421 1.1 jkunz {
1422 1.13 skrll struct sti_screen *scr = (struct sti_screen *)v;
1423 1.13 skrll struct sti_font *fp = &scr->scr_curfont;
1424 1.1 jkunz
1425 1.23 tsutsui sti_bmove(scr,
1426 1.23 tsutsui srccol * fp->width, row * fp->height,
1427 1.23 tsutsui dstcol * fp->width, row * fp->height,
1428 1.23 tsutsui fp->height, ncols * fp->width, bmf_copy);
1429 1.1 jkunz }
1430 1.1 jkunz
1431 1.1 jkunz void
1432 1.1 jkunz sti_erasecols(void *v, int row, int startcol, int ncols, long attr)
1433 1.1 jkunz {
1434 1.13 skrll struct sti_screen *scr = (struct sti_screen *)v;
1435 1.13 skrll struct sti_font *fp = &scr->scr_curfont;
1436 1.1 jkunz
1437 1.23 tsutsui sti_bmove(scr,
1438 1.23 tsutsui startcol * fp->width, row * fp->height,
1439 1.23 tsutsui startcol * fp->width, row * fp->height,
1440 1.23 tsutsui fp->height, ncols * fp->width, bmf_clear);
1441 1.1 jkunz }
1442 1.1 jkunz
1443 1.1 jkunz void
1444 1.1 jkunz sti_copyrows(void *v, int srcrow, int dstrow, int nrows)
1445 1.1 jkunz {
1446 1.13 skrll struct sti_screen *scr = (struct sti_screen *)v;
1447 1.13 skrll struct sti_font *fp = &scr->scr_curfont;
1448 1.1 jkunz
1449 1.13 skrll sti_bmove(scr, 0, srcrow * fp->height, 0, dstrow * fp->height,
1450 1.13 skrll nrows * fp->height, scr->scr_cfg.scr_width, bmf_copy);
1451 1.1 jkunz }
1452 1.1 jkunz
1453 1.1 jkunz void
1454 1.1 jkunz sti_eraserows(void *v, int srcrow, int nrows, long attr)
1455 1.1 jkunz {
1456 1.13 skrll struct sti_screen *scr = (struct sti_screen *)v;
1457 1.13 skrll struct sti_font *fp = &scr->scr_curfont;
1458 1.1 jkunz
1459 1.13 skrll sti_bmove(scr, 0, srcrow * fp->height, 0, srcrow * fp->height,
1460 1.13 skrll nrows * fp->height, scr->scr_cfg.scr_width, bmf_clear);
1461 1.1 jkunz }
1462 1.1 jkunz
1463 1.1 jkunz int
1464 1.1 jkunz sti_alloc_attr(void *v, int fg, int bg, int flags, long *pattr)
1465 1.1 jkunz {
1466 1.13 skrll #if 0
1467 1.13 skrll struct sti_screen *scr = (struct sti_screen *)v;
1468 1.13 skrll #endif
1469 1.1 jkunz
1470 1.24 tsutsui if ((flags & (WSATTR_HILIT | WSATTR_BLINK |
1471 1.24 tsutsui WSATTR_UNDERLINE | WSATTR_WSCOLORS)) != 0)
1472 1.24 tsutsui return EINVAL;
1473 1.24 tsutsui if ((flags & WSATTR_REVERSE) != 0) {
1474 1.26 skrll fg = STI_COLOUR_BLACK;
1475 1.24 tsutsui bg = STI_COLOUR_WHITE;
1476 1.24 tsutsui } else {
1477 1.24 tsutsui fg = STI_COLOUR_WHITE;
1478 1.26 skrll bg = STI_COLOUR_BLACK;
1479 1.24 tsutsui }
1480 1.1 jkunz
1481 1.24 tsutsui *pattr = WSATTR_PACK(fg, bg, flags);
1482 1.1 jkunz return 0;
1483 1.1 jkunz }
1484 1.17 tsutsui
1485 1.17 tsutsui /*
1486 1.29 skrll * Early console support. Only used on hp300, currently
1487 1.17 tsutsui */
1488 1.17 tsutsui int
1489 1.17 tsutsui sti_cnattach(struct sti_rom *rom, struct sti_screen *scr, bus_space_tag_t memt,
1490 1.17 tsutsui bus_addr_t *bases, u_int codebase)
1491 1.17 tsutsui {
1492 1.17 tsutsui bus_space_handle_t romh;
1493 1.17 tsutsui u_int romend;
1494 1.17 tsutsui int error;
1495 1.17 tsutsui long defattr;
1496 1.17 tsutsui
1497 1.17 tsutsui if ((error = bus_space_map(memt, bases[0], PAGE_SIZE, 0, &romh)) != 0)
1498 1.17 tsutsui return error;
1499 1.17 tsutsui
1500 1.17 tsutsui /*
1501 1.17 tsutsui * Compute real PROM size
1502 1.17 tsutsui */
1503 1.17 tsutsui romend = sti_rom_size(memt, romh);
1504 1.17 tsutsui
1505 1.17 tsutsui bus_space_unmap(memt, romh, PAGE_SIZE);
1506 1.17 tsutsui
1507 1.17 tsutsui if ((error = bus_space_map(memt, bases[0], romend, 0, &romh)) != 0)
1508 1.17 tsutsui return error;
1509 1.17 tsutsui
1510 1.17 tsutsui bases[0] = romh;
1511 1.17 tsutsui if (sti_rom_setup(rom, memt, memt, romh, bases, codebase) != 0)
1512 1.17 tsutsui return -1;
1513 1.17 tsutsui scr->scr_rom = rom;
1514 1.17 tsutsui if (sti_screen_setup(scr, STI_CLEARSCR) != 0)
1515 1.17 tsutsui return -1;
1516 1.17 tsutsui
1517 1.17 tsutsui sti_alloc_attr(scr, 0, 0, 0, &defattr);
1518 1.17 tsutsui wsdisplay_cnattach(&scr->scr_wsd, scr, 0, 0, defattr);
1519 1.17 tsutsui
1520 1.17 tsutsui return 0;
1521 1.17 tsutsui }
1522 1.23 tsutsui
1523 1.23 tsutsui int
1524 1.23 tsutsui ngle_default_putcmap(struct sti_screen *scr, u_int idx, u_int count)
1525 1.23 tsutsui {
1526 1.23 tsutsui int i, ret;
1527 1.23 tsutsui
1528 1.23 tsutsui for (i = idx + count - 1; i >= (int)idx; i--)
1529 1.23 tsutsui if ((ret = sti_setcment(scr, i, scr->scr_rcmap[i],
1530 1.23 tsutsui scr->scr_gcmap[i], scr->scr_bcmap[i])))
1531 1.23 tsutsui return EINVAL;
1532 1.23 tsutsui
1533 1.23 tsutsui return 0;
1534 1.23 tsutsui }
1535 1.23 tsutsui
1536 1.23 tsutsui #ifndef SMALL_KERNEL
1537 1.23 tsutsui
1538 1.23 tsutsui void ngle_setup_hw(bus_space_tag_t, bus_space_handle_t);
1539 1.23 tsutsui void ngle_setup_fb(bus_space_tag_t, bus_space_handle_t, uint32_t);
1540 1.23 tsutsui void ngle_setup_attr_planes(struct sti_screen *scr);
1541 1.23 tsutsui void ngle_setup_bt458(struct sti_screen *scr);
1542 1.23 tsutsui
1543 1.23 tsutsui #define ngle_bt458_write(memt, memh, r, v) \
1544 1.32 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_RAMDAC + ((r) << 2), (v) << 24)
1545 1.23 tsutsui
1546 1.23 tsutsui void
1547 1.23 tsutsui ngle_artist_setupfb(struct sti_screen *scr)
1548 1.23 tsutsui {
1549 1.23 tsutsui struct sti_rom *rom = scr->scr_rom;
1550 1.23 tsutsui bus_space_tag_t memt = rom->memt;
1551 1.23 tsutsui bus_space_handle_t memh = rom->regh[2];
1552 1.23 tsutsui
1553 1.23 tsutsui ngle_setup_bt458(scr);
1554 1.23 tsutsui
1555 1.23 tsutsui ngle_setup_hw(memt, memh);
1556 1.23 tsutsui ngle_setup_fb(memt, memh, scr->reg10_value);
1557 1.23 tsutsui
1558 1.23 tsutsui ngle_setup_attr_planes(scr);
1559 1.23 tsutsui
1560 1.23 tsutsui ngle_setup_hw(memt, memh);
1561 1.32 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_21,
1562 1.32 macallan bus_space_read_stream_4(memt, memh, NGLE_REG_21) | 0x0a000000);
1563 1.32 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_27,
1564 1.32 macallan bus_space_read_stream_4(memt, memh, NGLE_REG_27) | 0x00800000);
1565 1.23 tsutsui }
1566 1.23 tsutsui
1567 1.23 tsutsui void
1568 1.23 tsutsui ngle_elk_setupfb(struct sti_screen *scr)
1569 1.23 tsutsui {
1570 1.23 tsutsui struct sti_rom *rom = scr->scr_rom;
1571 1.23 tsutsui bus_space_tag_t memt = rom->memt;
1572 1.23 tsutsui bus_space_handle_t memh = rom->regh[2];
1573 1.23 tsutsui
1574 1.23 tsutsui ngle_setup_bt458(scr);
1575 1.23 tsutsui
1576 1.23 tsutsui ngle_setup_hw(memt, memh);
1577 1.23 tsutsui ngle_setup_fb(memt, memh, scr->reg10_value);
1578 1.23 tsutsui
1579 1.23 tsutsui ngle_setup_attr_planes(scr);
1580 1.23 tsutsui
1581 1.23 tsutsui ngle_setup_hw(memt, memh);
1582 1.23 tsutsui /* enable overlay planes in Bt458 command register */
1583 1.23 tsutsui ngle_bt458_write(memt, memh, 0x0c, 0x06);
1584 1.23 tsutsui ngle_bt458_write(memt, memh, 0x0e, 0x43);
1585 1.23 tsutsui }
1586 1.23 tsutsui
1587 1.23 tsutsui void
1588 1.23 tsutsui ngle_timber_setupfb(struct sti_screen *scr)
1589 1.23 tsutsui {
1590 1.23 tsutsui struct sti_rom *rom = scr->scr_rom;
1591 1.23 tsutsui bus_space_tag_t memt = rom->memt;
1592 1.23 tsutsui bus_space_handle_t memh = rom->regh[2];
1593 1.23 tsutsui
1594 1.23 tsutsui ngle_setup_bt458(scr);
1595 1.23 tsutsui
1596 1.23 tsutsui ngle_setup_hw(memt, memh);
1597 1.23 tsutsui /* enable overlay planes in Bt458 command register */
1598 1.23 tsutsui ngle_bt458_write(memt, memh, 0x0c, 0x06);
1599 1.23 tsutsui ngle_bt458_write(memt, memh, 0x0e, 0x43);
1600 1.23 tsutsui }
1601 1.23 tsutsui
1602 1.40 macallan static void
1603 1.40 macallan summit_wait(struct sti_screen *scr)
1604 1.40 macallan {
1605 1.40 macallan struct sti_rom *rom = scr->scr_rom;
1606 1.40 macallan bus_space_tag_t memt = rom->memt;
1607 1.40 macallan bus_space_handle_t memh = rom->regh[0];
1608 1.40 macallan
1609 1.40 macallan while (bus_space_read_stream_4(memt, memh, VISFX_STATUS) != 0)
1610 1.40 macallan continue;
1611 1.40 macallan }
1612 1.40 macallan
1613 1.40 macallan void
1614 1.40 macallan summit_setupfb(struct sti_screen *scr)
1615 1.40 macallan {
1616 1.40 macallan struct sti_rom *rom = scr->scr_rom;
1617 1.40 macallan bus_space_tag_t memt = rom->memt;
1618 1.40 macallan bus_space_handle_t memh = rom->regh[0];
1619 1.40 macallan
1620 1.40 macallan summit_wait(scr);
1621 1.40 macallan bus_space_write_stream_4(memt, memh, 0xb08044, 0x1b);
1622 1.40 macallan bus_space_write_stream_4(memt, memh, 0xb08048, 0x1b);
1623 1.40 macallan bus_space_write_stream_4(memt, memh, 0x920860, 0xe4);
1624 1.40 macallan bus_space_write_stream_4(memt, memh, 0xa00818, 0);
1625 1.40 macallan bus_space_write_stream_4(memt, memh, 0xa00404, 0);
1626 1.40 macallan bus_space_write_stream_4(memt, memh, 0x921110, 0);
1627 1.40 macallan bus_space_write_stream_4(memt, memh, 0x9211d8, 0);
1628 1.40 macallan bus_space_write_stream_4(memt, memh, 0xa0086c, 0);
1629 1.40 macallan bus_space_write_stream_4(memt, memh, 0x921114, 0);
1630 1.40 macallan bus_space_write_stream_4(memt, memh, 0xac1050, 0);
1631 1.41 macallan
1632 1.41 macallan bus_space_write_stream_4(memt, memh, VISFX_APERTURE_ACCESS,
1633 1.41 macallan VISFX_DEPTH_8);
1634 1.40 macallan
1635 1.40 macallan bus_space_write_stream_4(memt, memh, VISFX_PIXEL_MASK, 0xffffffff);
1636 1.40 macallan bus_space_write_stream_4(memt, memh, VISFX_PLANE_MASK, 0xffffffff);
1637 1.40 macallan bus_space_write_stream_4(memt, memh, VISFX_VRAM_WRITE_MODE,
1638 1.40 macallan VISFX_WRITE_MODE_PLAIN);
1639 1.41 macallan bus_space_write_stream_4(memt, memh, VISFX_VRAM_READ_MODE,
1640 1.41 macallan VISFX_READ_MODE_COPY);
1641 1.40 macallan }
1642 1.40 macallan
1643 1.23 tsutsui void
1644 1.23 tsutsui ngle_setup_bt458(struct sti_screen *scr)
1645 1.23 tsutsui {
1646 1.23 tsutsui struct sti_rom *rom = scr->scr_rom;
1647 1.23 tsutsui bus_space_tag_t memt = rom->memt;
1648 1.23 tsutsui bus_space_handle_t memh = rom->regh[2];
1649 1.23 tsutsui
1650 1.23 tsutsui ngle_setup_hw(memt, memh);
1651 1.23 tsutsui /* set Bt458 read mask register to all planes */
1652 1.23 tsutsui ngle_bt458_write(memt, memh, 0x08, 0x04);
1653 1.23 tsutsui ngle_bt458_write(memt, memh, 0x0a, 0xff);
1654 1.23 tsutsui }
1655 1.23 tsutsui
1656 1.23 tsutsui void
1657 1.23 tsutsui ngle_setup_attr_planes(struct sti_screen *scr)
1658 1.23 tsutsui {
1659 1.23 tsutsui struct sti_rom *rom = scr->scr_rom;
1660 1.23 tsutsui bus_space_tag_t memt = rom->memt;
1661 1.23 tsutsui bus_space_handle_t memh = rom->regh[2];
1662 1.23 tsutsui
1663 1.23 tsutsui ngle_setup_hw(memt, memh);
1664 1.32 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_11, 0x2ea0d000);
1665 1.32 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_14, 0x23000302);
1666 1.32 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_12, scr->reg12_value);
1667 1.32 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_8, 0xffffffff);
1668 1.23 tsutsui
1669 1.32 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_6, 0x00000000);
1670 1.32 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_9,
1671 1.23 tsutsui (scr->scr_cfg.scr_width << 16) | scr->scr_cfg.scr_height);
1672 1.32 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_6, 0x05000000);
1673 1.32 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_9, 0x00040001);
1674 1.23 tsutsui
1675 1.23 tsutsui ngle_setup_hw(memt, memh);
1676 1.32 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_12, 0x00000000);
1677 1.23 tsutsui
1678 1.23 tsutsui ngle_setup_fb(memt, memh, scr->reg10_value);
1679 1.23 tsutsui }
1680 1.23 tsutsui
1681 1.23 tsutsui int
1682 1.23 tsutsui ngle_putcmap(struct sti_screen *scr, u_int idx, u_int count)
1683 1.23 tsutsui {
1684 1.23 tsutsui struct sti_rom *rom = scr->scr_rom;
1685 1.23 tsutsui bus_space_tag_t memt = rom->memt;
1686 1.23 tsutsui bus_space_handle_t memh = rom->regh[2];
1687 1.23 tsutsui uint8_t *r, *g, *b;
1688 1.23 tsutsui uint32_t cmap_finish;
1689 1.23 tsutsui
1690 1.23 tsutsui if (scr->scr_bpp > 8)
1691 1.23 tsutsui cmap_finish = 0x83000100;
1692 1.23 tsutsui else
1693 1.23 tsutsui cmap_finish = 0x80000100;
1694 1.23 tsutsui
1695 1.23 tsutsui r = scr->scr_rcmap + idx;
1696 1.23 tsutsui g = scr->scr_gcmap + idx;
1697 1.23 tsutsui b = scr->scr_bcmap + idx;
1698 1.23 tsutsui
1699 1.23 tsutsui ngle_setup_hw(memt, memh);
1700 1.32 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_10, 0xbbe0f000);
1701 1.32 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_14, 0x03000300);
1702 1.32 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_13, 0xffffffff);
1703 1.23 tsutsui
1704 1.23 tsutsui while (count-- != 0) {
1705 1.23 tsutsui ngle_setup_hw(memt, memh);
1706 1.32 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_3,
1707 1.32 macallan 0x400 | (idx << 2));
1708 1.32 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_4,
1709 1.23 tsutsui (*r << 16) | (*g << 8) | *b);
1710 1.23 tsutsui
1711 1.23 tsutsui idx++;
1712 1.23 tsutsui r++, g++, b++;
1713 1.23 tsutsui }
1714 1.23 tsutsui
1715 1.37 macallan
1716 1.32 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_2, 0x400);
1717 1.32 macallan bus_space_write_stream_4(memt, memh, scr->cmap_finish_register,
1718 1.32 macallan cmap_finish);
1719 1.23 tsutsui ngle_setup_fb(memt, memh, scr->reg10_value);
1720 1.23 tsutsui
1721 1.23 tsutsui
1722 1.23 tsutsui return 0;
1723 1.23 tsutsui }
1724 1.23 tsutsui
1725 1.37 macallan int
1726 1.37 macallan ngle_hcrx_putcmap(struct sti_screen *scr, u_int idx, u_int count)
1727 1.37 macallan {
1728 1.37 macallan struct sti_rom *rom = scr->scr_rom;
1729 1.37 macallan bus_space_tag_t memt = rom->memt;
1730 1.37 macallan bus_space_handle_t memh = rom->regh[2];
1731 1.37 macallan uint8_t *r, *g, *b;
1732 1.37 macallan uint32_t cmap_finish;
1733 1.37 macallan
1734 1.37 macallan if (scr->scr_bpp > 8)
1735 1.37 macallan cmap_finish = 0x80000100;
1736 1.37 macallan else
1737 1.37 macallan cmap_finish = 0x82000100;
1738 1.37 macallan
1739 1.37 macallan r = scr->scr_rcmap + idx;
1740 1.37 macallan g = scr->scr_gcmap + idx;
1741 1.37 macallan b = scr->scr_bcmap + idx;
1742 1.37 macallan
1743 1.37 macallan ngle_setup_hw(memt, memh);
1744 1.37 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_10, 0xbbe0f000);
1745 1.37 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_14, 0x03000300);
1746 1.37 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_13, 0xffffffff);
1747 1.37 macallan
1748 1.37 macallan while (count-- != 0) {
1749 1.37 macallan ngle_setup_hw(memt, memh);
1750 1.37 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_3,
1751 1.37 macallan 0x400 | (idx << 2));
1752 1.37 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_4,
1753 1.37 macallan (*r << 16) | (*g << 8) | *b);
1754 1.37 macallan
1755 1.37 macallan idx++;
1756 1.37 macallan r++, g++, b++;
1757 1.37 macallan }
1758 1.37 macallan
1759 1.37 macallan
1760 1.37 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_2, 0x400);
1761 1.37 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_38, cmap_finish);
1762 1.37 macallan ngle_setup_fb(memt, memh, scr->reg10_value);
1763 1.37 macallan
1764 1.37 macallan
1765 1.37 macallan return 0;
1766 1.37 macallan }
1767 1.37 macallan
1768 1.40 macallan int
1769 1.40 macallan summit_putcmap(struct sti_screen *scr, u_int idx, u_int count)
1770 1.40 macallan {
1771 1.40 macallan struct sti_rom *rom = scr->scr_rom;
1772 1.40 macallan bus_space_tag_t memt = rom->memt;
1773 1.40 macallan bus_space_handle_t memh = rom->regh[0];
1774 1.40 macallan uint8_t *r, *g, *b;
1775 1.40 macallan
1776 1.40 macallan r = scr->scr_rcmap + idx;
1777 1.40 macallan g = scr->scr_gcmap + idx;
1778 1.40 macallan b = scr->scr_bcmap + idx;
1779 1.40 macallan
1780 1.42 macallan if (rom->rom_dd.dd_grid[0] == STI_DD_LEGO) {
1781 1.42 macallan bus_space_write_stream_4(memt, memh, VISFX_COLOR_INDEX, idx);
1782 1.42 macallan } else
1783 1.42 macallan bus_space_write_stream_4(memt, memh, VISFX_COLOR_INDEX,
1784 1.42 macallan 0xc0005100 + idx);
1785 1.40 macallan
1786 1.40 macallan while (count-- != 0) {
1787 1.40 macallan bus_space_write_stream_4(memt, memh,
1788 1.40 macallan VISFX_COLOR_VALUE, (*r << 16) | (*g << 8) | *b);
1789 1.40 macallan r++, g++, b++;
1790 1.40 macallan }
1791 1.40 macallan bus_space_write_stream_4(memt, memh, VISFX_COLOR_MASK, 0xff);
1792 1.40 macallan bus_space_write_stream_4(memt, memh, 0x80004c, 0xc);
1793 1.40 macallan bus_space_write_stream_4(memt, memh, 0x800000, 0);
1794 1.40 macallan
1795 1.40 macallan return 0;
1796 1.40 macallan }
1797 1.40 macallan
1798 1.23 tsutsui void
1799 1.23 tsutsui ngle_setup_hw(bus_space_tag_t memt, bus_space_handle_t memh)
1800 1.23 tsutsui {
1801 1.23 tsutsui uint8_t stat;
1802 1.23 tsutsui
1803 1.23 tsutsui do {
1804 1.23 tsutsui stat = bus_space_read_1(memt, memh, NGLE_REG_15b0);
1805 1.23 tsutsui if (stat == 0)
1806 1.23 tsutsui stat = bus_space_read_1(memt, memh, NGLE_REG_15b0);
1807 1.23 tsutsui } while (stat != 0);
1808 1.23 tsutsui }
1809 1.23 tsutsui
1810 1.23 tsutsui void
1811 1.23 tsutsui ngle_setup_fb(bus_space_tag_t memt, bus_space_handle_t memh, uint32_t reg10)
1812 1.23 tsutsui {
1813 1.23 tsutsui
1814 1.23 tsutsui ngle_setup_hw(memt, memh);
1815 1.32 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_10, reg10);
1816 1.32 macallan bus_space_write_stream_4(memt, memh, NGLE_REG_14, 0x83000300);
1817 1.23 tsutsui ngle_setup_hw(memt, memh);
1818 1.23 tsutsui bus_space_write_1(memt, memh, NGLE_REG_16b1, 1);
1819 1.23 tsutsui }
1820 1.23 tsutsui #endif /* SMALL_KERNEL */
1821