newport.c revision 1.9 1 1.9 rumble /* $NetBSD: newport.c,v 1.9 2006/12/29 05:26:30 rumble Exp $ */
2 1.1 lonewolf
3 1.1 lonewolf /*
4 1.1 lonewolf * Copyright (c) 2003 Ilpo Ruotsalainen
5 1.1 lonewolf * All rights reserved.
6 1.1 lonewolf *
7 1.1 lonewolf * Redistribution and use in source and binary forms, with or without
8 1.1 lonewolf * modification, are permitted provided that the following conditions
9 1.1 lonewolf * are met:
10 1.1 lonewolf * 1. Redistributions of source code must retain the above copyright
11 1.1 lonewolf * notice, this list of conditions and the following disclaimer.
12 1.1 lonewolf * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 lonewolf * notice, this list of conditions and the following disclaimer in the
14 1.1 lonewolf * documentation and/or other materials provided with the distribution.
15 1.1 lonewolf * 3. The name of the author may not be used to endorse or promote products
16 1.1 lonewolf * derived from this software without specific prior written permission.
17 1.1 lonewolf *
18 1.1 lonewolf * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 1.1 lonewolf * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 1.1 lonewolf * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 1.1 lonewolf * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 1.1 lonewolf * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 1.1 lonewolf * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 1.1 lonewolf * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 1.1 lonewolf * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 1.1 lonewolf * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 1.1 lonewolf * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 1.1 lonewolf *
29 1.1 lonewolf * <<Id: LICENSE_GC,v 1.1 2001/10/01 23:24:05 cgd Exp>>
30 1.1 lonewolf */
31 1.1 lonewolf
32 1.1 lonewolf #include <sys/cdefs.h>
33 1.9 rumble __KERNEL_RCSID(0, "$NetBSD: newport.c,v 1.9 2006/12/29 05:26:30 rumble Exp $");
34 1.1 lonewolf
35 1.1 lonewolf #include <sys/param.h>
36 1.1 lonewolf #include <sys/systm.h>
37 1.1 lonewolf #include <sys/device.h>
38 1.1 lonewolf #include <sys/malloc.h>
39 1.1 lonewolf
40 1.9 rumble #include <machine/sysconf.h>
41 1.9 rumble
42 1.1 lonewolf #include <dev/wscons/wsconsio.h>
43 1.1 lonewolf #include <dev/wscons/wsdisplayvar.h>
44 1.1 lonewolf #include <dev/wsfont/wsfont.h>
45 1.1 lonewolf
46 1.1 lonewolf #include <sgimips/gio/giovar.h>
47 1.1 lonewolf #include <sgimips/gio/newportvar.h>
48 1.1 lonewolf #include <sgimips/gio/newportreg.h>
49 1.1 lonewolf
50 1.1 lonewolf struct newport_softc {
51 1.1 lonewolf struct device sc_dev;
52 1.1 lonewolf
53 1.1 lonewolf struct newport_devconfig *sc_dc;
54 1.1 lonewolf };
55 1.1 lonewolf
56 1.1 lonewolf struct newport_devconfig {
57 1.1 lonewolf uint32_t dc_addr;
58 1.1 lonewolf
59 1.1 lonewolf bus_space_tag_t dc_st;
60 1.1 lonewolf bus_space_handle_t dc_sh;
61 1.1 lonewolf
62 1.1 lonewolf int dc_boardrev;
63 1.5 sekiya int dc_vc2rev;
64 1.3 sekiya int dc_cmaprev;
65 1.3 sekiya int dc_xmaprev;
66 1.3 sekiya int dc_rexrev;
67 1.1 lonewolf int dc_xres;
68 1.1 lonewolf int dc_yres;
69 1.3 sekiya int dc_depth;
70 1.1 lonewolf
71 1.1 lonewolf int dc_font;
72 1.1 lonewolf struct wsdisplay_font *dc_fontdata;
73 1.1 lonewolf };
74 1.1 lonewolf
75 1.1 lonewolf static int newport_match(struct device *, struct cfdata *, void *);
76 1.1 lonewolf static void newport_attach(struct device *, struct device *, void *);
77 1.1 lonewolf
78 1.1 lonewolf CFATTACH_DECL(newport, sizeof(struct newport_softc),
79 1.1 lonewolf newport_match, newport_attach, NULL, NULL);
80 1.1 lonewolf
81 1.1 lonewolf /* textops */
82 1.1 lonewolf static void newport_cursor(void *, int, int, int);
83 1.1 lonewolf static int newport_mapchar(void *, int, unsigned int *);
84 1.1 lonewolf static void newport_putchar(void *, int, int, u_int, long);
85 1.1 lonewolf static void newport_copycols(void *, int, int, int, int);
86 1.1 lonewolf static void newport_erasecols(void *, int, int, int, long);
87 1.1 lonewolf static void newport_copyrows(void *, int, int, int);
88 1.1 lonewolf static void newport_eraserows(void *, int, int, long);
89 1.1 lonewolf static int newport_allocattr(void *, int, int, int, long *);
90 1.1 lonewolf
91 1.1 lonewolf /* accessops */
92 1.7 jmmv static int newport_ioctl(void *, void *, u_long, caddr_t, int,
93 1.7 jmmv struct lwp *);
94 1.7 jmmv static paddr_t newport_mmap(void *, void *, off_t, int);
95 1.1 lonewolf static int newport_alloc_screen(void *, const struct wsscreen_descr *,
96 1.1 lonewolf void **, int *, int *, long *);
97 1.1 lonewolf static void newport_free_screen(void *, void *);
98 1.1 lonewolf static int newport_show_screen(void *, void *, int,
99 1.1 lonewolf void (*)(void *, int, int), void *);
100 1.1 lonewolf
101 1.1 lonewolf static const struct wsdisplay_emulops newport_textops = {
102 1.1 lonewolf .cursor = newport_cursor,
103 1.1 lonewolf .mapchar = newport_mapchar,
104 1.1 lonewolf .putchar = newport_putchar,
105 1.1 lonewolf .copycols = newport_copycols,
106 1.1 lonewolf .erasecols = newport_erasecols,
107 1.1 lonewolf .copyrows = newport_copyrows,
108 1.1 lonewolf .eraserows = newport_eraserows,
109 1.1 lonewolf .allocattr = newport_allocattr
110 1.1 lonewolf };
111 1.1 lonewolf
112 1.1 lonewolf static const struct wsdisplay_accessops newport_accessops = {
113 1.1 lonewolf .ioctl = newport_ioctl,
114 1.1 lonewolf .mmap = newport_mmap,
115 1.1 lonewolf .alloc_screen = newport_alloc_screen,
116 1.1 lonewolf .free_screen = newport_free_screen,
117 1.1 lonewolf .show_screen = newport_show_screen,
118 1.1 lonewolf };
119 1.1 lonewolf
120 1.1 lonewolf static const struct wsscreen_descr newport_screen_1024x768 = {
121 1.1 lonewolf .name = "1024x768",
122 1.1 lonewolf .ncols = 128,
123 1.1 lonewolf .nrows = 48,
124 1.1 lonewolf .textops = &newport_textops,
125 1.1 lonewolf .fontwidth = 8,
126 1.1 lonewolf .fontheight = 16,
127 1.1 lonewolf .capabilities = WSSCREEN_WSCOLORS | WSSCREEN_HILIT | WSSCREEN_REVERSE
128 1.1 lonewolf };
129 1.1 lonewolf
130 1.1 lonewolf static const struct wsscreen_descr newport_screen_1280x1024 = {
131 1.1 lonewolf .name = "1280x1024",
132 1.1 lonewolf .ncols = 160,
133 1.1 lonewolf .nrows = 64,
134 1.1 lonewolf .textops = &newport_textops,
135 1.1 lonewolf .fontwidth = 8,
136 1.1 lonewolf .fontheight = 16,
137 1.1 lonewolf .capabilities = WSSCREEN_WSCOLORS | WSSCREEN_HILIT | WSSCREEN_REVERSE
138 1.1 lonewolf };
139 1.1 lonewolf
140 1.1 lonewolf static const struct wsscreen_descr *_newport_screenlist[] = {
141 1.1 lonewolf &newport_screen_1024x768,
142 1.1 lonewolf &newport_screen_1280x1024
143 1.1 lonewolf };
144 1.1 lonewolf
145 1.1 lonewolf static const struct wsscreen_list newport_screenlist = {
146 1.1 lonewolf sizeof(_newport_screenlist) / sizeof(struct wsscreen_descr *),
147 1.1 lonewolf _newport_screenlist
148 1.1 lonewolf };
149 1.1 lonewolf
150 1.1 lonewolf static struct newport_devconfig newport_console_dc;
151 1.1 lonewolf static int newport_is_console = 0;
152 1.1 lonewolf
153 1.1 lonewolf #define NEWPORT_ATTR_ENCODE(fg,bg) (((fg) << 8) | (bg))
154 1.1 lonewolf #define NEWPORT_ATTR_BG(a) ((a) & 0xff)
155 1.1 lonewolf #define NEWPORT_ATTR_FG(a) (((a) >> 8) & 0xff)
156 1.1 lonewolf
157 1.1 lonewolf static const uint16_t newport_cursor_data[128] = {
158 1.1 lonewolf /* Bit 0 */
159 1.1 lonewolf 0xff00, 0x0000,
160 1.1 lonewolf 0xff00, 0x0000,
161 1.1 lonewolf 0xff00, 0x0000,
162 1.1 lonewolf 0xff00, 0x0000,
163 1.1 lonewolf 0xff00, 0x0000,
164 1.1 lonewolf 0xff00, 0x0000,
165 1.1 lonewolf 0xff00, 0x0000,
166 1.1 lonewolf 0xff00, 0x0000,
167 1.1 lonewolf 0xff00, 0x0000,
168 1.1 lonewolf 0xff00, 0x0000,
169 1.1 lonewolf 0xff00, 0x0000,
170 1.1 lonewolf 0xff00, 0x0000,
171 1.1 lonewolf 0xff00, 0x0000,
172 1.1 lonewolf 0xff00, 0x0000,
173 1.1 lonewolf 0xff00, 0x0000,
174 1.1 lonewolf 0xff00, 0x0000,
175 1.1 lonewolf 0x0000, 0x0000,
176 1.1 lonewolf 0x0000, 0x0000,
177 1.1 lonewolf 0x0000, 0x0000,
178 1.1 lonewolf 0x0000, 0x0000,
179 1.1 lonewolf 0x0000, 0x0000,
180 1.1 lonewolf 0x0000, 0x0000,
181 1.1 lonewolf 0x0000, 0x0000,
182 1.1 lonewolf 0x0000, 0x0000,
183 1.1 lonewolf 0x0000, 0x0000,
184 1.1 lonewolf 0x0000, 0x0000,
185 1.1 lonewolf 0x0000, 0x0000,
186 1.1 lonewolf 0x0000, 0x0000,
187 1.1 lonewolf 0x0000, 0x0000,
188 1.1 lonewolf 0x0000, 0x0000,
189 1.1 lonewolf 0x0000, 0x0000,
190 1.1 lonewolf 0x0000, 0x0000,
191 1.1 lonewolf
192 1.1 lonewolf /* Bit 1 */
193 1.1 lonewolf 0x0000, 0x0000,
194 1.1 lonewolf 0x0000, 0x0000,
195 1.1 lonewolf 0x0000, 0x0000,
196 1.1 lonewolf 0x0000, 0x0000,
197 1.1 lonewolf 0x0000, 0x0000,
198 1.1 lonewolf 0x0000, 0x0000,
199 1.1 lonewolf 0x0000, 0x0000,
200 1.1 lonewolf 0x0000, 0x0000,
201 1.1 lonewolf 0x0000, 0x0000,
202 1.1 lonewolf 0x0000, 0x0000,
203 1.1 lonewolf 0x0000, 0x0000,
204 1.1 lonewolf 0x0000, 0x0000,
205 1.1 lonewolf 0x0000, 0x0000,
206 1.1 lonewolf 0x0000, 0x0000,
207 1.1 lonewolf 0x0000, 0x0000,
208 1.1 lonewolf 0x0000, 0x0000,
209 1.1 lonewolf 0x0000, 0x0000,
210 1.1 lonewolf 0x0000, 0x0000,
211 1.1 lonewolf 0x0000, 0x0000,
212 1.1 lonewolf 0x0000, 0x0000,
213 1.1 lonewolf 0x0000, 0x0000,
214 1.1 lonewolf 0x0000, 0x0000,
215 1.1 lonewolf 0x0000, 0x0000,
216 1.1 lonewolf 0x0000, 0x0000,
217 1.1 lonewolf 0x0000, 0x0000,
218 1.1 lonewolf 0x0000, 0x0000,
219 1.1 lonewolf 0x0000, 0x0000,
220 1.1 lonewolf 0x0000, 0x0000,
221 1.1 lonewolf 0x0000, 0x0000,
222 1.1 lonewolf 0x0000, 0x0000,
223 1.1 lonewolf 0x0000, 0x0000,
224 1.1 lonewolf 0x0000, 0x0000,
225 1.1 lonewolf };
226 1.1 lonewolf
227 1.1 lonewolf static const uint8_t newport_defcmap[16*3] = {
228 1.1 lonewolf /* Normal colors */
229 1.1 lonewolf 0x00, 0x00, 0x00, /* black */
230 1.1 lonewolf 0x7f, 0x00, 0x00, /* red */
231 1.1 lonewolf 0x00, 0x7f, 0x00, /* green */
232 1.1 lonewolf 0x7f, 0x7f, 0x00, /* brown */
233 1.1 lonewolf 0x00, 0x00, 0x7f, /* blue */
234 1.1 lonewolf 0x7f, 0x00, 0x7f, /* magenta */
235 1.1 lonewolf 0x00, 0x7f, 0x7f, /* cyan */
236 1.1 lonewolf 0xc7, 0xc7, 0xc7, /* white - XXX too dim? */
237 1.1 lonewolf
238 1.1 lonewolf /* Hilite colors */
239 1.1 lonewolf 0x7f, 0x7f, 0x7f, /* black */
240 1.1 lonewolf 0xff, 0x00, 0x00, /* red */
241 1.1 lonewolf 0x00, 0xff, 0x00, /* green */
242 1.1 lonewolf 0xff, 0xff, 0x00, /* brown */
243 1.1 lonewolf 0x00, 0x00, 0xff, /* blue */
244 1.1 lonewolf 0xff, 0x00, 0xff, /* magenta */
245 1.1 lonewolf 0x00, 0xff, 0xff, /* cyan */
246 1.1 lonewolf 0xff, 0xff, 0xff, /* white */
247 1.1 lonewolf };
248 1.1 lonewolf
249 1.1 lonewolf /**** Low-level hardware register groveling functions ****/
250 1.1 lonewolf static void
251 1.1 lonewolf rex3_write(struct newport_devconfig *dc, bus_size_t rexreg, uint32_t val)
252 1.1 lonewolf {
253 1.1 lonewolf bus_space_write_4(dc->dc_st, dc->dc_sh, NEWPORT_REX3_OFFSET + rexreg,
254 1.1 lonewolf val);
255 1.1 lonewolf }
256 1.1 lonewolf
257 1.1 lonewolf static void
258 1.1 lonewolf rex3_write_go(struct newport_devconfig *dc, bus_size_t rexreg, uint32_t val)
259 1.1 lonewolf {
260 1.1 lonewolf rex3_write(dc, rexreg + REX3_REG_GO, val);
261 1.1 lonewolf }
262 1.1 lonewolf
263 1.1 lonewolf static uint32_t
264 1.1 lonewolf rex3_read(struct newport_devconfig *dc, bus_size_t rexreg)
265 1.1 lonewolf {
266 1.1 lonewolf return bus_space_read_4(dc->dc_st, dc->dc_sh, NEWPORT_REX3_OFFSET +
267 1.1 lonewolf rexreg);
268 1.1 lonewolf }
269 1.1 lonewolf
270 1.1 lonewolf static void
271 1.1 lonewolf rex3_wait_gfifo(struct newport_devconfig *dc)
272 1.1 lonewolf {
273 1.1 lonewolf while (rex3_read(dc, REX3_REG_STATUS) & REX3_STATUS_GFXBUSY)
274 1.1 lonewolf ;
275 1.1 lonewolf }
276 1.1 lonewolf
277 1.1 lonewolf static void
278 1.1 lonewolf vc2_write_ireg(struct newport_devconfig *dc, uint8_t ireg, uint16_t val)
279 1.1 lonewolf {
280 1.1 lonewolf rex3_write(dc, REX3_REG_DCBMODE,
281 1.1 lonewolf REX3_DCBMODE_DW_3 |
282 1.1 lonewolf REX3_DCBMODE_ENCRSINC |
283 1.1 lonewolf (NEWPORT_DCBADDR_VC2 << REX3_DCBMODE_DCBADDR_SHIFT) |
284 1.1 lonewolf (VC2_DCBCRS_INDEX << REX3_DCBMODE_DCBCRS_SHIFT) |
285 1.1 lonewolf REX3_DCBMODE_ENASYNCACK |
286 1.1 lonewolf (1 << REX3_DCBMODE_CSSETUP_SHIFT));
287 1.1 lonewolf
288 1.1 lonewolf rex3_write(dc, REX3_REG_DCBDATA0, (ireg << 24) | (val << 8));
289 1.1 lonewolf }
290 1.1 lonewolf
291 1.1 lonewolf static uint16_t
292 1.1 lonewolf vc2_read_ireg(struct newport_devconfig *dc, uint8_t ireg)
293 1.1 lonewolf {
294 1.1 lonewolf rex3_write(dc, REX3_REG_DCBMODE,
295 1.1 lonewolf REX3_DCBMODE_DW_1 |
296 1.1 lonewolf REX3_DCBMODE_ENCRSINC |
297 1.1 lonewolf (NEWPORT_DCBADDR_VC2 << REX3_DCBMODE_DCBADDR_SHIFT) |
298 1.1 lonewolf (VC2_DCBCRS_INDEX << REX3_DCBMODE_DCBCRS_SHIFT) |
299 1.1 lonewolf REX3_DCBMODE_ENASYNCACK |
300 1.1 lonewolf (1 << REX3_DCBMODE_CSSETUP_SHIFT));
301 1.1 lonewolf
302 1.1 lonewolf rex3_write(dc, REX3_REG_DCBDATA0, ireg << 24);
303 1.1 lonewolf
304 1.1 lonewolf rex3_write(dc, REX3_REG_DCBMODE,
305 1.1 lonewolf REX3_DCBMODE_DW_2 |
306 1.1 lonewolf REX3_DCBMODE_ENCRSINC |
307 1.1 lonewolf (NEWPORT_DCBADDR_VC2 << REX3_DCBMODE_DCBADDR_SHIFT) |
308 1.1 lonewolf (VC2_DCBCRS_IREG << REX3_DCBMODE_DCBCRS_SHIFT) |
309 1.1 lonewolf REX3_DCBMODE_ENASYNCACK |
310 1.1 lonewolf (1 << REX3_DCBMODE_CSSETUP_SHIFT));
311 1.1 lonewolf
312 1.1 lonewolf return (uint16_t)(rex3_read(dc, REX3_REG_DCBDATA0) >> 16);
313 1.1 lonewolf }
314 1.1 lonewolf
315 1.1 lonewolf static uint16_t
316 1.1 lonewolf vc2_read_ram(struct newport_devconfig *dc, uint16_t addr)
317 1.1 lonewolf {
318 1.1 lonewolf vc2_write_ireg(dc, VC2_IREG_RAM_ADDRESS, addr);
319 1.1 lonewolf
320 1.1 lonewolf rex3_write(dc, REX3_REG_DCBMODE,
321 1.1 lonewolf REX3_DCBMODE_DW_2 |
322 1.1 lonewolf (NEWPORT_DCBADDR_VC2 << REX3_DCBMODE_DCBADDR_SHIFT) |
323 1.1 lonewolf (VC2_DCBCRS_RAM << REX3_DCBMODE_DCBCRS_SHIFT) |
324 1.1 lonewolf REX3_DCBMODE_ENASYNCACK |
325 1.1 lonewolf (1 << REX3_DCBMODE_CSSETUP_SHIFT));
326 1.1 lonewolf
327 1.1 lonewolf return (uint16_t)(rex3_read(dc, REX3_REG_DCBDATA0) >> 16);
328 1.1 lonewolf }
329 1.1 lonewolf
330 1.1 lonewolf static void
331 1.1 lonewolf vc2_write_ram(struct newport_devconfig *dc, uint16_t addr, uint16_t val)
332 1.1 lonewolf {
333 1.1 lonewolf vc2_write_ireg(dc, VC2_IREG_RAM_ADDRESS, addr);
334 1.1 lonewolf
335 1.1 lonewolf rex3_write(dc, REX3_REG_DCBMODE,
336 1.1 lonewolf REX3_DCBMODE_DW_2 |
337 1.1 lonewolf (NEWPORT_DCBADDR_VC2 << REX3_DCBMODE_DCBADDR_SHIFT) |
338 1.1 lonewolf (VC2_DCBCRS_RAM << REX3_DCBMODE_DCBCRS_SHIFT) |
339 1.1 lonewolf REX3_DCBMODE_ENASYNCACK |
340 1.1 lonewolf (1 << REX3_DCBMODE_CSSETUP_SHIFT));
341 1.1 lonewolf
342 1.1 lonewolf rex3_write(dc, REX3_REG_DCBDATA0, val << 16);
343 1.1 lonewolf }
344 1.1 lonewolf
345 1.3 sekiya static u_int32_t
346 1.3 sekiya xmap9_read(struct newport_devconfig *dc, int crs)
347 1.3 sekiya {
348 1.3 sekiya rex3_write(dc, REX3_REG_DCBMODE,
349 1.3 sekiya REX3_DCBMODE_DW_1 |
350 1.3 sekiya (NEWPORT_DCBADDR_XMAP_0 << REX3_DCBMODE_DCBADDR_SHIFT) |
351 1.3 sekiya (crs << REX3_DCBMODE_DCBCRS_SHIFT) |
352 1.3 sekiya (3 << REX3_DCBMODE_CSWIDTH_SHIFT) |
353 1.3 sekiya (2 << REX3_DCBMODE_CSHOLD_SHIFT) |
354 1.3 sekiya (1 << REX3_DCBMODE_CSSETUP_SHIFT));
355 1.3 sekiya return rex3_read(dc, REX3_REG_DCBDATA0);
356 1.3 sekiya }
357 1.3 sekiya
358 1.1 lonewolf static void
359 1.1 lonewolf xmap9_write(struct newport_devconfig *dc, int crs, uint8_t val)
360 1.1 lonewolf {
361 1.1 lonewolf rex3_write(dc, REX3_REG_DCBMODE,
362 1.1 lonewolf REX3_DCBMODE_DW_1 |
363 1.1 lonewolf (NEWPORT_DCBADDR_XMAP_BOTH << REX3_DCBMODE_DCBADDR_SHIFT) |
364 1.1 lonewolf (crs << REX3_DCBMODE_DCBCRS_SHIFT) |
365 1.1 lonewolf (3 << REX3_DCBMODE_CSWIDTH_SHIFT) |
366 1.1 lonewolf (2 << REX3_DCBMODE_CSHOLD_SHIFT) |
367 1.1 lonewolf (1 << REX3_DCBMODE_CSSETUP_SHIFT));
368 1.1 lonewolf
369 1.1 lonewolf rex3_write(dc, REX3_REG_DCBDATA0, val << 24);
370 1.1 lonewolf }
371 1.1 lonewolf
372 1.1 lonewolf static void
373 1.1 lonewolf xmap9_write_mode(struct newport_devconfig *dc, uint8_t index, uint32_t mode)
374 1.1 lonewolf {
375 1.1 lonewolf rex3_write(dc, REX3_REG_DCBMODE,
376 1.1 lonewolf REX3_DCBMODE_DW_4 |
377 1.1 lonewolf (NEWPORT_DCBADDR_XMAP_BOTH << REX3_DCBMODE_DCBADDR_SHIFT) |
378 1.1 lonewolf (XMAP9_DCBCRS_MODE_SETUP << REX3_DCBMODE_DCBCRS_SHIFT) |
379 1.1 lonewolf (3 << REX3_DCBMODE_CSWIDTH_SHIFT) |
380 1.1 lonewolf (2 << REX3_DCBMODE_CSHOLD_SHIFT) |
381 1.1 lonewolf (1 << REX3_DCBMODE_CSSETUP_SHIFT));
382 1.1 lonewolf
383 1.1 lonewolf rex3_write(dc, REX3_REG_DCBDATA0, (index << 24) | mode);
384 1.1 lonewolf }
385 1.1 lonewolf
386 1.1 lonewolf /**** Helper functions ****/
387 1.1 lonewolf static void
388 1.1 lonewolf newport_fill_rectangle(struct newport_devconfig *dc, int x1, int y1, int x2,
389 1.1 lonewolf int y2, uint8_t color)
390 1.1 lonewolf {
391 1.1 lonewolf rex3_wait_gfifo(dc);
392 1.1 lonewolf
393 1.1 lonewolf rex3_write(dc, REX3_REG_DRAWMODE0, REX3_DRAWMODE0_OPCODE_DRAW |
394 1.1 lonewolf REX3_DRAWMODE0_ADRMODE_BLOCK | REX3_DRAWMODE0_DOSETUP |
395 1.1 lonewolf REX3_DRAWMODE0_STOPONX | REX3_DRAWMODE0_STOPONY);
396 1.3 sekiya rex3_write(dc, REX3_REG_WRMASK, 0xffffffff);
397 1.1 lonewolf rex3_write(dc, REX3_REG_COLORI, color);
398 1.1 lonewolf rex3_write(dc, REX3_REG_XYSTARTI, (x1 << REX3_XYSTARTI_XSHIFT) | y1);
399 1.1 lonewolf
400 1.1 lonewolf rex3_write_go(dc, REX3_REG_XYENDI, (x2 << REX3_XYENDI_XSHIFT) | y2);
401 1.1 lonewolf }
402 1.1 lonewolf
403 1.1 lonewolf static void
404 1.1 lonewolf newport_copy_rectangle(struct newport_devconfig *dc, int x1, int y1, int x2,
405 1.1 lonewolf int y2, int dx, int dy)
406 1.1 lonewolf {
407 1.1 lonewolf uint32_t tmp;
408 1.1 lonewolf
409 1.1 lonewolf rex3_wait_gfifo(dc);
410 1.1 lonewolf
411 1.1 lonewolf rex3_write(dc, REX3_REG_DRAWMODE0, REX3_DRAWMODE0_OPCODE_SCR2SCR |
412 1.1 lonewolf REX3_DRAWMODE0_ADRMODE_BLOCK | REX3_DRAWMODE0_DOSETUP |
413 1.1 lonewolf REX3_DRAWMODE0_STOPONX | REX3_DRAWMODE0_STOPONY);
414 1.1 lonewolf rex3_write(dc, REX3_REG_XYSTARTI, (x1 << REX3_XYSTARTI_XSHIFT) | y1);
415 1.1 lonewolf rex3_write(dc, REX3_REG_XYENDI, (x2 << REX3_XYENDI_XSHIFT) | y2);
416 1.1 lonewolf
417 1.1 lonewolf tmp = (dy - y1) & 0xffff;
418 1.1 lonewolf tmp |= (dx - x1) << REX3_XYMOVE_XSHIFT;
419 1.1 lonewolf
420 1.1 lonewolf rex3_write_go(dc, REX3_REG_XYMOVE, tmp);
421 1.1 lonewolf }
422 1.1 lonewolf
423 1.1 lonewolf static void
424 1.1 lonewolf newport_cmap_setrgb(struct newport_devconfig *dc, int index, uint8_t r,
425 1.1 lonewolf uint8_t g, uint8_t b)
426 1.1 lonewolf {
427 1.1 lonewolf rex3_write(dc, REX3_REG_DCBMODE,
428 1.1 lonewolf REX3_DCBMODE_DW_2 |
429 1.1 lonewolf REX3_DCBMODE_ENCRSINC |
430 1.1 lonewolf (NEWPORT_DCBADDR_CMAP_BOTH << REX3_DCBMODE_DCBADDR_SHIFT) |
431 1.1 lonewolf (CMAP_DCBCRS_ADDRESS_LOW << REX3_DCBMODE_DCBCRS_SHIFT) |
432 1.1 lonewolf (1 << REX3_DCBMODE_CSWIDTH_SHIFT) |
433 1.1 lonewolf (1 << REX3_DCBMODE_CSHOLD_SHIFT) |
434 1.1 lonewolf (1 << REX3_DCBMODE_CSSETUP_SHIFT) |
435 1.1 lonewolf REX3_DCBMODE_SWAPENDIAN);
436 1.1 lonewolf
437 1.1 lonewolf rex3_write(dc, REX3_REG_DCBDATA0, index << 16);
438 1.1 lonewolf
439 1.1 lonewolf rex3_write(dc, REX3_REG_DCBMODE,
440 1.1 lonewolf REX3_DCBMODE_DW_3 |
441 1.1 lonewolf (NEWPORT_DCBADDR_CMAP_BOTH << REX3_DCBMODE_DCBADDR_SHIFT) |
442 1.1 lonewolf (CMAP_DCBCRS_PALETTE << REX3_DCBMODE_DCBCRS_SHIFT) |
443 1.1 lonewolf (1 << REX3_DCBMODE_CSWIDTH_SHIFT) |
444 1.1 lonewolf (1 << REX3_DCBMODE_CSHOLD_SHIFT) |
445 1.1 lonewolf (1 << REX3_DCBMODE_CSSETUP_SHIFT));
446 1.1 lonewolf
447 1.1 lonewolf rex3_write(dc, REX3_REG_DCBDATA0, (r << 24) + (g << 16) + (b << 8));
448 1.1 lonewolf }
449 1.1 lonewolf
450 1.1 lonewolf static void
451 1.1 lonewolf newport_get_resolution(struct newport_devconfig *dc)
452 1.1 lonewolf {
453 1.1 lonewolf uint16_t vep,lines;
454 1.1 lonewolf uint16_t linep,cols;
455 1.1 lonewolf uint16_t data;
456 1.1 lonewolf
457 1.1 lonewolf vep = vc2_read_ireg(dc, VC2_IREG_VIDEO_ENTRY);
458 1.1 lonewolf
459 1.1 lonewolf dc->dc_xres = 0;
460 1.1 lonewolf dc->dc_yres = 0;
461 1.1 lonewolf
462 1.1 lonewolf for (;;) {
463 1.1 lonewolf /* Iterate over runs in video timing table */
464 1.1 lonewolf
465 1.1 lonewolf cols = 0;
466 1.1 lonewolf
467 1.1 lonewolf linep = vc2_read_ram(dc, vep++);
468 1.1 lonewolf lines = vc2_read_ram(dc, vep++);
469 1.1 lonewolf
470 1.1 lonewolf if (lines == 0)
471 1.1 lonewolf break;
472 1.1 lonewolf
473 1.1 lonewolf do {
474 1.1 lonewolf /* Iterate over state runs in line sequence table */
475 1.1 lonewolf
476 1.1 lonewolf data = vc2_read_ram(dc, linep++);
477 1.1 lonewolf
478 1.1 lonewolf if ((data & 0x0001) == 0)
479 1.1 lonewolf cols += (data >> 7) & 0xfe;
480 1.1 lonewolf
481 1.1 lonewolf if ((data & 0x0080) == 0)
482 1.1 lonewolf data = vc2_read_ram(dc, linep++);
483 1.1 lonewolf } while ((data & 0x8000) == 0);
484 1.1 lonewolf
485 1.1 lonewolf if (cols != 0) {
486 1.1 lonewolf if (cols > dc->dc_xres)
487 1.1 lonewolf dc->dc_xres = cols;
488 1.1 lonewolf
489 1.1 lonewolf dc->dc_yres += lines;
490 1.1 lonewolf }
491 1.1 lonewolf }
492 1.1 lonewolf }
493 1.1 lonewolf
494 1.1 lonewolf static void
495 1.1 lonewolf newport_setup_hw(struct newport_devconfig *dc)
496 1.1 lonewolf {
497 1.1 lonewolf uint16_t curp,tmp;
498 1.1 lonewolf int i;
499 1.3 sekiya uint32_t scratch;
500 1.1 lonewolf
501 1.3 sekiya /* Get various revisions */
502 1.1 lonewolf rex3_write(dc, REX3_REG_DCBMODE,
503 1.1 lonewolf REX3_DCBMODE_DW_1 |
504 1.1 lonewolf (NEWPORT_DCBADDR_CMAP_0 << REX3_DCBMODE_DCBADDR_SHIFT) |
505 1.1 lonewolf (CMAP_DCBCRS_REVISION << REX3_DCBMODE_DCBCRS_SHIFT) |
506 1.1 lonewolf (1 << REX3_DCBMODE_CSWIDTH_SHIFT) |
507 1.1 lonewolf (1 << REX3_DCBMODE_CSHOLD_SHIFT) |
508 1.1 lonewolf (1 << REX3_DCBMODE_CSSETUP_SHIFT));
509 1.1 lonewolf
510 1.5 sekiya scratch = vc2_read_ireg(dc, VC2_IREG_CONFIG);
511 1.5 sekiya dc->dc_vc2rev = (scratch & VC2_IREG_CONFIG_REVISION) >> 5;
512 1.5 sekiya
513 1.3 sekiya scratch = rex3_read(dc, REX3_REG_DCBDATA0);
514 1.3 sekiya
515 1.3 sekiya dc->dc_boardrev = (scratch >> 28) & 0x07;
516 1.3 sekiya dc->dc_cmaprev = scratch & 0x07;
517 1.3 sekiya dc->dc_xmaprev = xmap9_read(dc, XMAP9_DCBCRS_REVISION) & 0x07;
518 1.5 sekiya dc->dc_depth = ( (dc->dc_boardrev > 1) && (scratch & 0x80)) ? 8 : 24;
519 1.1 lonewolf
520 1.1 lonewolf /* Setup cursor glyph */
521 1.1 lonewolf curp = vc2_read_ireg(dc, VC2_IREG_CURSOR_ENTRY);
522 1.1 lonewolf
523 1.1 lonewolf for (i=0; i<128; i++)
524 1.1 lonewolf vc2_write_ram(dc, curp + i, newport_cursor_data[i]);
525 1.1 lonewolf
526 1.1 lonewolf /* Setup VC2 to a known state */
527 1.1 lonewolf tmp = vc2_read_ireg(dc, VC2_IREG_CONTROL) & VC2_CONTROL_INTERLACE;
528 1.1 lonewolf vc2_write_ireg(dc, VC2_IREG_CONTROL, tmp |
529 1.1 lonewolf VC2_CONTROL_DISPLAY_ENABLE |
530 1.1 lonewolf VC2_CONTROL_VTIMING_ENABLE |
531 1.1 lonewolf VC2_CONTROL_DID_ENABLE |
532 1.1 lonewolf VC2_CONTROL_CURSORFUNC_ENABLE |
533 1.1 lonewolf VC2_CONTROL_CURSOR_ENABLE);
534 1.1 lonewolf
535 1.1 lonewolf /* Setup XMAP9s */
536 1.1 lonewolf xmap9_write(dc, XMAP9_DCBCRS_CONFIG,
537 1.1 lonewolf XMAP9_CONFIG_8BIT_SYSTEM | XMAP9_CONFIG_RGBMAP_CI);
538 1.1 lonewolf
539 1.1 lonewolf xmap9_write(dc, XMAP9_DCBCRS_CURSOR_CMAP, 0);
540 1.1 lonewolf
541 1.1 lonewolf xmap9_write_mode(dc, 0,
542 1.1 lonewolf XMAP9_MODE_GAMMA_BYPASS |
543 1.1 lonewolf XMAP9_MODE_PIXSIZE_8BPP);
544 1.1 lonewolf xmap9_write(dc, XMAP9_DCBCRS_MODE_SELECT, 0);
545 1.1 lonewolf
546 1.1 lonewolf /* Setup REX3 */
547 1.1 lonewolf rex3_write(dc, REX3_REG_DRAWMODE1,
548 1.1 lonewolf REX3_DRAWMODE1_PLANES_CI |
549 1.1 lonewolf REX3_DRAWMODE1_DD_DD8 |
550 1.1 lonewolf REX3_DRAWMODE1_RWPACKED |
551 1.1 lonewolf REX3_DRAWMODE1_HD_HD8 |
552 1.1 lonewolf REX3_DRAWMODE1_COMPARE_LT |
553 1.1 lonewolf REX3_DRAWMODE1_COMPARE_EQ |
554 1.1 lonewolf REX3_DRAWMODE1_COMPARE_GT |
555 1.1 lonewolf REX3_DRAWMODE1_LO_SRC);
556 1.1 lonewolf rex3_write(dc, REX3_REG_XYWIN, (4096 << 16) | 4096);
557 1.1 lonewolf rex3_write(dc, REX3_REG_TOPSCAN, 0x3ff); /* XXX Why? XXX */
558 1.1 lonewolf
559 1.1 lonewolf /* Setup CMAP */
560 1.1 lonewolf for (i=0; i<16; i++)
561 1.1 lonewolf newport_cmap_setrgb(dc, i, newport_defcmap[i*3],
562 1.1 lonewolf newport_defcmap[i*3 + 1], newport_defcmap[i*3 + 2]);
563 1.1 lonewolf }
564 1.1 lonewolf
565 1.1 lonewolf /**** Attach routines ****/
566 1.1 lonewolf static int
567 1.1 lonewolf newport_match(struct device *parent, struct cfdata *self, void *aux)
568 1.1 lonewolf {
569 1.1 lonewolf struct gio_attach_args *ga = aux;
570 1.1 lonewolf
571 1.1 lonewolf /* newport doesn't decode all addresses */
572 1.1 lonewolf if (ga->ga_addr != 0x1f000000 && ga->ga_addr != 0x1f400000 &&
573 1.1 lonewolf ga->ga_addr != 0x1f800000 && ga->ga_addr != 0x1fc00000)
574 1.1 lonewolf return 0;
575 1.1 lonewolf
576 1.1 lonewolf /* Don't do the destructive probe if we're already attached */
577 1.1 lonewolf if (newport_is_console && ga->ga_addr == newport_console_dc.dc_addr)
578 1.1 lonewolf return 1;
579 1.1 lonewolf
580 1.9 rumble if (platform.badaddr(
581 1.8 rumble (void *)(ga->ga_ioh + NEWPORT_REX3_OFFSET + REX3_REG_XSTARTI),
582 1.8 rumble sizeof(uint32_t)))
583 1.8 rumble return 0;
584 1.9 rumble if (platform.badaddr(
585 1.8 rumble (void *)(ga->ga_ioh + NEWPORT_REX3_OFFSET + REX3_REG_XSTART),
586 1.8 rumble sizeof(uint32_t)))
587 1.8 rumble return 0;
588 1.8 rumble
589 1.1 lonewolf /* Ugly, this probe is destructive, blame SGI... */
590 1.1 lonewolf /* XXX Should be bus_space_peek/bus_space_poke XXX */
591 1.1 lonewolf bus_space_write_4(ga->ga_iot, ga->ga_ioh,
592 1.1 lonewolf NEWPORT_REX3_OFFSET + REX3_REG_XSTARTI, 0x12345678);
593 1.1 lonewolf if (bus_space_read_4(ga->ga_iot, ga->ga_ioh,
594 1.1 lonewolf NEWPORT_REX3_OFFSET + REX3_REG_XSTART)
595 1.1 lonewolf != ((0x12345678 & 0xffff) << 11))
596 1.1 lonewolf return 0;
597 1.1 lonewolf
598 1.1 lonewolf return 1;
599 1.1 lonewolf }
600 1.1 lonewolf
601 1.1 lonewolf static void
602 1.1 lonewolf newport_attach_common(struct newport_devconfig *dc, struct gio_attach_args *ga)
603 1.1 lonewolf {
604 1.1 lonewolf dc->dc_addr = ga->ga_addr;
605 1.1 lonewolf
606 1.1 lonewolf dc->dc_st = ga->ga_iot;
607 1.1 lonewolf dc->dc_sh = ga->ga_ioh;
608 1.1 lonewolf
609 1.1 lonewolf wsfont_init();
610 1.1 lonewolf
611 1.1 lonewolf dc->dc_font = wsfont_find(NULL, 8, 16, 0, WSDISPLAY_FONTORDER_L2R,
612 1.1 lonewolf WSDISPLAY_FONTORDER_L2R);
613 1.1 lonewolf if (dc->dc_font < 0)
614 1.1 lonewolf panic("newport_attach_common: no suitable fonts");
615 1.1 lonewolf
616 1.1 lonewolf if (wsfont_lock(dc->dc_font, &dc->dc_fontdata))
617 1.1 lonewolf panic("newport_attach_common: unable to lock font data");
618 1.1 lonewolf
619 1.1 lonewolf newport_setup_hw(dc);
620 1.1 lonewolf
621 1.1 lonewolf newport_get_resolution(dc);
622 1.1 lonewolf
623 1.1 lonewolf newport_fill_rectangle(dc, 0, 0, dc->dc_xres, dc->dc_yres, 0);
624 1.1 lonewolf }
625 1.1 lonewolf
626 1.1 lonewolf static void
627 1.1 lonewolf newport_attach(struct device *parent, struct device *self, void *aux)
628 1.1 lonewolf {
629 1.1 lonewolf struct gio_attach_args *ga = aux;
630 1.1 lonewolf struct newport_softc *sc = (void *)self;
631 1.1 lonewolf struct wsemuldisplaydev_attach_args wa;
632 1.1 lonewolf
633 1.1 lonewolf if (newport_is_console && ga->ga_addr == newport_console_dc.dc_addr) {
634 1.1 lonewolf wa.console = 1;
635 1.1 lonewolf sc->sc_dc = &newport_console_dc;
636 1.1 lonewolf } else {
637 1.1 lonewolf wa.console = 0;
638 1.1 lonewolf sc->sc_dc = malloc(sizeof(struct newport_devconfig),
639 1.1 lonewolf M_DEVBUF, M_WAITOK | M_ZERO);
640 1.1 lonewolf if (sc->sc_dc == NULL)
641 1.1 lonewolf panic("newport_attach: out of memory");
642 1.1 lonewolf
643 1.1 lonewolf newport_attach_common(sc->sc_dc, ga);
644 1.1 lonewolf }
645 1.1 lonewolf
646 1.1 lonewolf aprint_naive(": Display adapter\n");
647 1.1 lonewolf
648 1.5 sekiya aprint_normal(": SGI NG1 (board revision %d, cmap revision %d, xmap revision %d, vc2 revision %d), depth %d\n",
649 1.3 sekiya sc->sc_dc->dc_boardrev, sc->sc_dc->dc_cmaprev,
650 1.5 sekiya sc->sc_dc->dc_xmaprev, sc->sc_dc->dc_vc2rev, sc->sc_dc->dc_depth);
651 1.1 lonewolf
652 1.1 lonewolf wa.scrdata = &newport_screenlist;
653 1.1 lonewolf wa.accessops = &newport_accessops;
654 1.1 lonewolf wa.accesscookie = sc->sc_dc;
655 1.1 lonewolf
656 1.1 lonewolf config_found(&sc->sc_dev, &wa, wsemuldisplaydevprint);
657 1.1 lonewolf }
658 1.1 lonewolf
659 1.1 lonewolf int
660 1.1 lonewolf newport_cnattach(struct gio_attach_args *ga)
661 1.1 lonewolf {
662 1.1 lonewolf long defattr = NEWPORT_ATTR_ENCODE(WSCOL_WHITE, WSCOL_BLACK);
663 1.1 lonewolf const struct wsscreen_descr *screen;
664 1.1 lonewolf
665 1.1 lonewolf if (!newport_match(NULL, NULL, ga)) {
666 1.1 lonewolf return ENXIO;
667 1.1 lonewolf }
668 1.1 lonewolf
669 1.1 lonewolf newport_attach_common(&newport_console_dc, ga);
670 1.1 lonewolf
671 1.1 lonewolf if (newport_console_dc.dc_xres >= 1280 &&
672 1.1 lonewolf newport_console_dc.dc_yres >= 1024)
673 1.1 lonewolf screen = &newport_screen_1280x1024;
674 1.1 lonewolf else
675 1.1 lonewolf screen = &newport_screen_1024x768;
676 1.1 lonewolf
677 1.1 lonewolf wsdisplay_cnattach(screen, &newport_console_dc, 0, 0, defattr);
678 1.1 lonewolf
679 1.1 lonewolf newport_is_console = 1;
680 1.1 lonewolf
681 1.1 lonewolf return 0;
682 1.1 lonewolf }
683 1.1 lonewolf
684 1.1 lonewolf /**** wsdisplay textops ****/
685 1.1 lonewolf static void
686 1.1 lonewolf newport_cursor(void *c, int on, int row, int col)
687 1.1 lonewolf {
688 1.1 lonewolf struct newport_devconfig *dc = (void *)c;
689 1.1 lonewolf uint16_t control;
690 1.1 lonewolf int x_offset;
691 1.1 lonewolf
692 1.1 lonewolf control = vc2_read_ireg(dc, VC2_IREG_CONTROL);
693 1.1 lonewolf
694 1.1 lonewolf if (!on) {
695 1.1 lonewolf vc2_write_ireg(dc, VC2_IREG_CONTROL,
696 1.1 lonewolf control & ~VC2_CONTROL_CURSOR_ENABLE);
697 1.1 lonewolf } else {
698 1.1 lonewolf /* Work around bug in some board revisions */
699 1.1 lonewolf if (dc->dc_boardrev < 6)
700 1.1 lonewolf x_offset = 21;
701 1.5 sekiya else if (dc->dc_vc2rev == 0)
702 1.5 sekiya x_offset = 29;
703 1.1 lonewolf else
704 1.1 lonewolf x_offset = 31;
705 1.1 lonewolf
706 1.1 lonewolf vc2_write_ireg(dc, VC2_IREG_CURSOR_X,
707 1.1 lonewolf col * dc->dc_fontdata->fontwidth + x_offset);
708 1.1 lonewolf vc2_write_ireg(dc, VC2_IREG_CURSOR_Y,
709 1.1 lonewolf row * dc->dc_fontdata->fontheight + 31);
710 1.1 lonewolf
711 1.1 lonewolf vc2_write_ireg(dc, VC2_IREG_CONTROL,
712 1.1 lonewolf control | VC2_CONTROL_CURSOR_ENABLE);
713 1.1 lonewolf }
714 1.1 lonewolf }
715 1.1 lonewolf
716 1.1 lonewolf static int
717 1.1 lonewolf newport_mapchar(void *c, int ch, unsigned int *cp)
718 1.1 lonewolf {
719 1.1 lonewolf struct newport_devconfig *dc = (void *)c;
720 1.1 lonewolf
721 1.1 lonewolf if (dc->dc_fontdata->encoding != WSDISPLAY_FONTENC_ISO) {
722 1.1 lonewolf ch = wsfont_map_unichar(dc->dc_fontdata, ch);
723 1.1 lonewolf
724 1.1 lonewolf if (ch < 0)
725 1.1 lonewolf goto fail;
726 1.1 lonewolf }
727 1.1 lonewolf
728 1.1 lonewolf if (ch < dc->dc_fontdata->firstchar ||
729 1.1 lonewolf ch >= dc->dc_fontdata->firstchar + dc->dc_fontdata->numchars)
730 1.1 lonewolf goto fail;
731 1.1 lonewolf
732 1.1 lonewolf *cp = ch;
733 1.1 lonewolf return 5;
734 1.1 lonewolf
735 1.1 lonewolf fail:
736 1.1 lonewolf *cp = ' ';
737 1.1 lonewolf return 0;
738 1.1 lonewolf }
739 1.1 lonewolf
740 1.1 lonewolf static void
741 1.1 lonewolf newport_putchar(void *c, int row, int col, u_int ch, long attr)
742 1.1 lonewolf {
743 1.1 lonewolf struct newport_devconfig *dc = (void *)c;
744 1.1 lonewolf struct wsdisplay_font *font = dc->dc_fontdata;
745 1.1 lonewolf uint8_t *bitmap = (u_int8_t *)font->data + (ch - font->firstchar) *
746 1.1 lonewolf font->fontheight * font->stride;
747 1.1 lonewolf uint32_t pattern;
748 1.1 lonewolf int i;
749 1.1 lonewolf int x = col * font->fontwidth;
750 1.1 lonewolf int y = row * font->fontheight;
751 1.1 lonewolf
752 1.1 lonewolf rex3_wait_gfifo(dc);
753 1.1 lonewolf
754 1.1 lonewolf rex3_write(dc, REX3_REG_DRAWMODE0, REX3_DRAWMODE0_OPCODE_DRAW |
755 1.1 lonewolf REX3_DRAWMODE0_ADRMODE_BLOCK | REX3_DRAWMODE0_STOPONX |
756 1.1 lonewolf REX3_DRAWMODE0_ENZPATTERN | REX3_DRAWMODE0_ZPOPAQUE);
757 1.1 lonewolf
758 1.1 lonewolf rex3_write(dc, REX3_REG_XYSTARTI, (x << REX3_XYSTARTI_XSHIFT) | y);
759 1.1 lonewolf rex3_write(dc, REX3_REG_XYENDI,
760 1.1 lonewolf (x + font->fontwidth - 1) << REX3_XYENDI_XSHIFT);
761 1.1 lonewolf
762 1.1 lonewolf rex3_write(dc, REX3_REG_COLORI, NEWPORT_ATTR_FG(attr));
763 1.1 lonewolf rex3_write(dc, REX3_REG_COLORBACK, NEWPORT_ATTR_BG(attr));
764 1.1 lonewolf
765 1.3 sekiya rex3_write(dc, REX3_REG_WRMASK, 0xffffffff);
766 1.1 lonewolf
767 1.1 lonewolf for (i=0; i<font->fontheight; i++) {
768 1.1 lonewolf /* XXX Works only with font->fontwidth == 8 XXX */
769 1.1 lonewolf pattern = *bitmap << 24;
770 1.1 lonewolf
771 1.1 lonewolf rex3_write_go(dc, REX3_REG_ZPATTERN, pattern);
772 1.1 lonewolf
773 1.1 lonewolf bitmap += font->stride;
774 1.1 lonewolf }
775 1.1 lonewolf }
776 1.1 lonewolf
777 1.1 lonewolf static void
778 1.1 lonewolf newport_copycols(void *c, int row, int srccol, int dstcol, int ncols)
779 1.1 lonewolf {
780 1.1 lonewolf struct newport_devconfig *dc = (void *)c;
781 1.1 lonewolf struct wsdisplay_font *font = dc->dc_fontdata;
782 1.1 lonewolf
783 1.1 lonewolf newport_copy_rectangle(dc,
784 1.1 lonewolf srccol * font->fontwidth, /* x1 */
785 1.1 lonewolf row * font->fontheight, /* y1 */
786 1.1 lonewolf (srccol + ncols + 1) * font->fontwidth - 1, /* x2 */
787 1.1 lonewolf (row + 1) * font->fontheight - 1, /* y2 */
788 1.1 lonewolf dstcol * font->fontheight, /* dx */
789 1.1 lonewolf row * font->fontheight); /* dy */
790 1.1 lonewolf }
791 1.1 lonewolf
792 1.1 lonewolf static void
793 1.1 lonewolf newport_erasecols(void *c, int row, int startcol, int ncols,
794 1.1 lonewolf long attr)
795 1.1 lonewolf {
796 1.1 lonewolf struct newport_devconfig *dc = (void *)c;
797 1.1 lonewolf struct wsdisplay_font *font = dc->dc_fontdata;
798 1.1 lonewolf
799 1.1 lonewolf newport_fill_rectangle(dc,
800 1.1 lonewolf startcol * font->fontwidth, /* x1 */
801 1.1 lonewolf row * font->fontheight, /* y1 */
802 1.1 lonewolf (startcol + ncols + 1) * font->fontwidth - 1, /* x2 */
803 1.1 lonewolf (row + 1) * font->fontheight - 1, /* y2 */
804 1.1 lonewolf NEWPORT_ATTR_BG(attr));
805 1.1 lonewolf }
806 1.1 lonewolf
807 1.1 lonewolf static void
808 1.1 lonewolf newport_copyrows(void *c, int srcrow, int dstrow, int nrows)
809 1.1 lonewolf {
810 1.1 lonewolf struct newport_devconfig *dc = (void *)c;
811 1.1 lonewolf struct wsdisplay_font *font = dc->dc_fontdata;
812 1.1 lonewolf
813 1.1 lonewolf newport_copy_rectangle(dc,
814 1.1 lonewolf 0, /* x1 */
815 1.1 lonewolf srcrow * font->fontheight, /* y1 */
816 1.1 lonewolf dc->dc_xres, /* x2 */
817 1.1 lonewolf (srcrow + nrows + 1) * font->fontheight - 1, /* y2 */
818 1.1 lonewolf 0, /* dx */
819 1.1 lonewolf dstrow * font->fontheight); /* dy */
820 1.1 lonewolf }
821 1.1 lonewolf
822 1.1 lonewolf static void
823 1.1 lonewolf newport_eraserows(void *c, int startrow, int nrows, long attr)
824 1.1 lonewolf {
825 1.1 lonewolf struct newport_devconfig *dc = (void *)c;
826 1.1 lonewolf struct wsdisplay_font *font = dc->dc_fontdata;
827 1.1 lonewolf
828 1.1 lonewolf newport_fill_rectangle(dc,
829 1.1 lonewolf 0, /* x1 */
830 1.1 lonewolf startrow * font->fontheight, /* y1 */
831 1.1 lonewolf dc->dc_xres, /* x2 */
832 1.1 lonewolf (startrow + nrows + 1) * font->fontheight - 1, /* y2 */
833 1.1 lonewolf NEWPORT_ATTR_BG(attr));
834 1.1 lonewolf }
835 1.1 lonewolf
836 1.1 lonewolf static int
837 1.1 lonewolf newport_allocattr(void *c, int fg, int bg, int flags, long *attr)
838 1.1 lonewolf {
839 1.1 lonewolf if (flags & WSATTR_BLINK)
840 1.1 lonewolf return EINVAL;
841 1.1 lonewolf
842 1.1 lonewolf if ((flags & WSATTR_WSCOLORS) == 0) {
843 1.1 lonewolf fg = WSCOL_WHITE;
844 1.1 lonewolf bg = WSCOL_BLACK;
845 1.1 lonewolf }
846 1.1 lonewolf
847 1.1 lonewolf if (flags & WSATTR_HILIT)
848 1.1 lonewolf fg += 8;
849 1.1 lonewolf
850 1.1 lonewolf if (flags & WSATTR_REVERSE) {
851 1.1 lonewolf int tmp = fg;
852 1.1 lonewolf fg = bg;
853 1.1 lonewolf bg = tmp;
854 1.1 lonewolf }
855 1.1 lonewolf
856 1.1 lonewolf *attr = NEWPORT_ATTR_ENCODE(fg, bg);
857 1.1 lonewolf
858 1.1 lonewolf return 0;
859 1.1 lonewolf }
860 1.1 lonewolf
861 1.1 lonewolf /**** wsdisplay accessops ****/
862 1.1 lonewolf
863 1.1 lonewolf static int
864 1.7 jmmv newport_ioctl(void *c, void *vs, u_long cmd, caddr_t data, int flag,
865 1.7 jmmv struct lwp *l)
866 1.1 lonewolf {
867 1.3 sekiya struct newport_softc *sc = c;
868 1.3 sekiya
869 1.3 sekiya #define FBINFO (*(struct wsdisplay_fbinfo*)data)
870 1.3 sekiya
871 1.3 sekiya switch (cmd) {
872 1.3 sekiya case WSDISPLAYIO_GINFO:
873 1.3 sekiya FBINFO.width = sc->sc_dc->dc_xres;
874 1.3 sekiya FBINFO.height = sc->sc_dc->dc_yres;
875 1.3 sekiya FBINFO.depth = sc->sc_dc->dc_depth;
876 1.3 sekiya FBINFO.cmsize = 1 << FBINFO.depth;
877 1.3 sekiya return 0;
878 1.3 sekiya case WSDISPLAYIO_GTYPE:
879 1.3 sekiya *(u_int *)data = WSDISPLAY_TYPE_NEWPORT;
880 1.3 sekiya return 0;
881 1.3 sekiya }
882 1.1 lonewolf return EPASSTHROUGH;
883 1.1 lonewolf }
884 1.1 lonewolf
885 1.1 lonewolf static paddr_t
886 1.7 jmmv newport_mmap(void *c, void *vs, off_t offset, int prot)
887 1.1 lonewolf {
888 1.5 sekiya struct newport_devconfig *dc = c;
889 1.5 sekiya
890 1.5 sekiya if ( offset >= 0xfffff)
891 1.5 sekiya return -1;
892 1.5 sekiya
893 1.5 sekiya return mips_btop(dc->dc_addr + offset);
894 1.1 lonewolf }
895 1.1 lonewolf
896 1.1 lonewolf static int
897 1.1 lonewolf newport_alloc_screen(void *c, const struct wsscreen_descr *type, void **cookiep,
898 1.1 lonewolf int *cursxp, int *cursyp, long *attrp)
899 1.1 lonewolf {
900 1.1 lonewolf /* This won't get called for console screen and we don't support
901 1.1 lonewolf * virtual screens */
902 1.1 lonewolf
903 1.1 lonewolf return ENOMEM;
904 1.1 lonewolf }
905 1.1 lonewolf
906 1.1 lonewolf static void
907 1.1 lonewolf newport_free_screen(void *c, void *cookie)
908 1.1 lonewolf {
909 1.1 lonewolf panic("newport_free_screen");
910 1.1 lonewolf }
911 1.1 lonewolf static int
912 1.1 lonewolf newport_show_screen(void *c, void *cookie, int waitok,
913 1.1 lonewolf void (*cb)(void *, int, int), void *cbarg)
914 1.1 lonewolf {
915 1.1 lonewolf return 0;
916 1.1 lonewolf }
917