1 /* $NetBSD: cgtwelve.c,v 1.8 2021/08/07 16:19:15 thorpej Exp $ */
2
3 /*-
4 * Copyright (c) 2010 Michael Lorenz
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 /* a console driver for the Sun CG12 / Matrox SG3 graphics board */
30
31 #include <sys/cdefs.h>
32 __KERNEL_RCSID(0, "$NetBSD: cgtwelve.c,v 1.8 2021/08/07 16:19:15 thorpej Exp $");
33
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/buf.h>
37 #include <sys/device.h>
38 #include <sys/ioctl.h>
39 #include <sys/conf.h>
40 #include <sys/kmem.h>
41
42 #include <sys/bus.h>
43 #include <machine/autoconf.h>
44
45 #include <dev/sbus/sbusvar.h>
46 #include <dev/sun/fbio.h>
47 #include <dev/sun/fbvar.h>
48
49 #include <dev/wscons/wsdisplayvar.h>
50 #include <dev/wscons/wsconsio.h>
51 #include <dev/wsfont/wsfont.h>
52 #include <dev/rasops/rasops.h>
53
54 #include <dev/wscons/wsdisplay_vconsvar.h>
55
56 #include <dev/sbus/cgtwelvereg.h>
57 #include <dev/ic/bt462reg.h>
58
59 #include "opt_wsemul.h"
60 #include "opt_cgtwelve.h"
61
62
63 struct cgtwelve_softc {
64 device_t sc_dev;
65 bus_space_tag_t sc_tag;
66 bus_space_handle_t sc_regh;
67 bus_addr_t sc_paddr;
68 void *sc_fbaddr;
69 void *sc_shadow;
70 uint8_t *sc_wids;
71 void *sc_int;
72 int sc_width;
73 int sc_height;
74 int sc_stride;
75 int sc_fbsize;
76 int sc_mode;
77 struct vcons_data vd;
78 };
79
80 static int cgtwelve_match(device_t, cfdata_t, void *);
81 static void cgtwelve_attach(device_t, device_t, void *);
82 static int cgtwelve_ioctl(void *, void *, u_long, void *, int,
83 struct lwp*);
84 static paddr_t cgtwelve_mmap(void *, void *, off_t, int);
85 static void cgtwelve_init_screen(void *, struct vcons_screen *, int,
86 long *);
87 static void cgtwelve_write_wid(struct cgtwelve_softc *, int, uint8_t);
88 static void cgtwelve_select_ovl(struct cgtwelve_softc *, int);
89 #define CG12_SEL_OVL 0
90 #define CG12_SEL_ENABLE 1
91 #define CG12_SEL_8BIT 2
92 #define CG12_SEL_24BIT 3
93 #define CG12_SEL_WID 4
94 static void cgtwelve_write_dac(struct cgtwelve_softc *, int, int, int, int);
95 static void cgtwelve_setup(struct cgtwelve_softc *, int);
96
97 CFATTACH_DECL_NEW(cgtwelve, sizeof(struct cgtwelve_softc),
98 cgtwelve_match, cgtwelve_attach, NULL, NULL);
99
100 struct wsscreen_descr cgtwelve_defscreendesc = {
101 "default",
102 0, 0,
103 NULL,
104 8, 16,
105 0,
106 };
107
108 static struct vcons_screen cgtwelve_console_screen;
109
110 const struct wsscreen_descr *_cgtwelve_scrlist[] = {
111 &cgtwelve_defscreendesc,
112 /* XXX other formats, graphics screen? */
113 };
114
115 struct wsscreen_list cgtwelve_screenlist = {
116 sizeof(_cgtwelve_scrlist) / sizeof(struct wsscreen_descr *),
117 _cgtwelve_scrlist
118 };
119
120 struct wsdisplay_accessops cgtwelve_accessops = {
121 cgtwelve_ioctl,
122 cgtwelve_mmap,
123 NULL, /* vcons_alloc_screen */
124 NULL, /* vcons_free_screen */
125 NULL, /* vcons_show_screen */
126 NULL, /* load_font */
127 NULL, /* polls */
128 NULL, /* scroll */
129 };
130
131 extern const u_char rasops_cmap[768];
132
133 static int
cgtwelve_match(device_t parent,cfdata_t cf,void * aux)134 cgtwelve_match(device_t parent, cfdata_t cf, void *aux)
135 {
136 struct sbus_attach_args *sa = aux;
137
138 if (strcmp("cgtwelve", sa->sa_name) == 0)
139 return 100;
140 return 0;
141 }
142
143 /*
144 * Attach a display. We need to notice if it is the console, too.
145 */
146 static void
cgtwelve_attach(device_t parent,device_t self,void * args)147 cgtwelve_attach(device_t parent, device_t self, void *args)
148 {
149 struct cgtwelve_softc *sc = device_private(self);
150 struct sbus_attach_args *sa = args;
151 struct wsemuldisplaydev_attach_args aa;
152 struct rasops_info *ri;
153 unsigned long defattr;
154 bus_space_handle_t bh;
155 int node = sa->sa_node;
156 int isconsole;
157
158 aprint_normal("\n");
159 sc->sc_dev = self;
160 sc->sc_tag = sa->sa_bustag;
161
162 sc->sc_paddr = sbus_bus_addr(sa->sa_bustag, sa->sa_slot, sa->sa_offset);
163
164 /* read geometry information from the device tree */
165 sc->sc_width = prom_getpropint(sa->sa_node, "width", 1152);
166 sc->sc_height = prom_getpropint(sa->sa_node, "height", 900);
167 #ifdef CG12_COLOR
168 sc->sc_stride = sc->sc_width;
169 #else
170 sc->sc_stride = (sc->sc_width + 7) >> 3;
171 #endif
172 sc->sc_fbsize = sc->sc_height * sc->sc_stride;
173
174 sc->sc_fbaddr = (void *)prom_getpropint(sa->sa_node, "address", 0);
175 if (sc->sc_fbaddr == NULL) {
176 if (sbus_bus_map(sa->sa_bustag,
177 sa->sa_slot,
178 sa->sa_offset + CG12_FB_MONO,
179 sc->sc_fbsize,
180 BUS_SPACE_MAP_LINEAR, &bh) != 0) {
181 aprint_error_dev(self, "cannot map framebuffer\n");
182 return;
183 }
184 sc->sc_fbaddr = bus_space_vaddr(sa->sa_bustag, bh);
185 }
186
187 aprint_normal_dev(self, "%d x %d\n", sc->sc_width, sc->sc_height);
188
189 if (sbus_bus_map(sa->sa_bustag,
190 sa->sa_slot,
191 sa->sa_offset + CG12_OFF_REGISTERS,
192 0xc0000, 0, &sc->sc_regh) != 0) {
193 aprint_error("%s: couldn't map registers\n",
194 device_xname(sc->sc_dev));
195 return;
196 }
197
198 if (sbus_bus_map(sa->sa_bustag,
199 sa->sa_slot,
200 sa->sa_offset + CG12_OFF_WID, 0x100000,
201 BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_LARGE,
202 &bh) != 0) {
203 aprint_error("%s: couldn't map WID\n",
204 device_xname(sc->sc_dev));
205 return;
206 }
207 sc->sc_wids = bus_space_vaddr(sa->sa_bustag, bh);
208
209 if (sbus_bus_map(sa->sa_bustag,
210 sa->sa_slot,
211 sa->sa_offset + CG12_OFF_INTEN, 0x400000,
212 BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_LARGE,
213 &bh) != 0) {
214 aprint_error("%s: couldn't map colour fb\n",
215 device_xname(sc->sc_dev));
216 return;
217 }
218 sc->sc_int = bus_space_vaddr(sa->sa_bustag, bh);
219
220 #ifdef CG12_COLOR
221 cgtwelve_setup(sc, 8);
222 #else
223 cgtwelve_setup(sc, 1);
224 #endif
225 #ifdef CG12_SHADOW
226 sc->sc_shadow = kmem_alloc(sc->sc_fbsize, KM_SLEEP);
227 #else
228 sc->sc_shadow = NULL;
229 #endif
230
231 isconsole = fb_is_console(node);
232
233 sc->sc_mode = WSDISPLAYIO_MODE_EMUL;
234 wsfont_init();
235
236 vcons_init(&sc->vd, sc, &cgtwelve_defscreendesc, &cgtwelve_accessops);
237 sc->vd.init_screen = cgtwelve_init_screen;
238
239 vcons_init_screen(&sc->vd, &cgtwelve_console_screen, 1, &defattr);
240 cgtwelve_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC;
241
242 ri = &cgtwelve_console_screen.scr_ri;
243
244 cgtwelve_defscreendesc.nrows = ri->ri_rows;
245 cgtwelve_defscreendesc.ncols = ri->ri_cols;
246 cgtwelve_defscreendesc.textops = &ri->ri_ops;
247 cgtwelve_defscreendesc.capabilities = ri->ri_caps;
248
249 if(isconsole) {
250 wsdisplay_cnattach(&cgtwelve_defscreendesc, ri, 0, 0, defattr);
251 vcons_replay_msgbuf(&cgtwelve_console_screen);
252 }
253
254 aa.console = isconsole;
255 aa.scrdata = &cgtwelve_screenlist;
256 aa.accessops = &cgtwelve_accessops;
257 aa.accesscookie = &sc->vd;
258
259 config_found(self, &aa, wsemuldisplaydevprint, CFARGS_NONE);
260 #ifdef CG12_DEBUG
261 {
262 int i;
263 for (i = 0; i < 0x10; i++) {
264 bus_space_write_4(sc->sc_tag, sc->sc_regh,
265 CG12DAC_ADDR0, (i << 16) | (i << 8) | i);
266 bus_space_write_4(sc->sc_tag, sc->sc_regh,
267 CG12DAC_ADDR1, 0x010101);
268 printf("%02x: %08x\n", i, bus_space_read_4(sc->sc_tag,
269 sc->sc_regh, CG12DAC_CTRL));
270 }
271 }
272 #endif
273 }
274
275 /* 0 - overlay plane, 1 - enable plane, 2 - 8bit fb, 3 - 24bit fb, 4 - WIDs */
276 static void
cgtwelve_select_ovl(struct cgtwelve_softc * sc,int which)277 cgtwelve_select_ovl(struct cgtwelve_softc *sc, int which)
278 {
279 switch(which) {
280 case 0:
281 bus_space_write_4(sc->sc_tag, sc->sc_regh,
282 CG12DPU_PLN_RDMSK_HOST, CG12_PLN_RD_OVERLAY);
283 bus_space_write_4(sc->sc_tag, sc->sc_regh,
284 CG12DPU_PLN_WRMSK_HOST, CG12_PLN_WR_OVERLAY);
285 bus_space_write_4(sc->sc_tag, sc->sc_regh,
286 CG12DPU_PLN_SL_HOST, CG12_PLN_SL_OVERLAY);
287 bus_space_write_4(sc->sc_tag, sc->sc_regh,
288 CG12APU_HPAGE, CG12_HPAGE_OVERLAY);
289 bus_space_write_4(sc->sc_tag, sc->sc_regh,
290 CG12APU_HACCESS, CG12_HACCESS_OVERLAY);
291 break;
292 case 1:
293 bus_space_write_4(sc->sc_tag, sc->sc_regh,
294 CG12DPU_PLN_RDMSK_HOST, CG12_PLN_RD_ENABLE);
295 bus_space_write_4(sc->sc_tag, sc->sc_regh,
296 CG12DPU_PLN_WRMSK_HOST, CG12_PLN_WR_ENABLE);
297 bus_space_write_4(sc->sc_tag, sc->sc_regh,
298 CG12DPU_PLN_SL_HOST, CG12_PLN_SL_ENABLE);
299 bus_space_write_4(sc->sc_tag, sc->sc_regh,
300 CG12APU_HPAGE, CG12_HPAGE_ENABLE);
301 bus_space_write_4(sc->sc_tag, sc->sc_regh,
302 CG12APU_HACCESS, CG12_HACCESS_ENABLE);
303 break;
304 case 2:
305 bus_space_write_4(sc->sc_tag, sc->sc_regh,
306 CG12DPU_PLN_RDMSK_HOST, CG12_PLN_RD_8BIT);
307 bus_space_write_4(sc->sc_tag, sc->sc_regh,
308 CG12DPU_PLN_WRMSK_HOST, CG12_PLN_WR_8BIT);
309 bus_space_write_4(sc->sc_tag, sc->sc_regh,
310 CG12DPU_PLN_SL_HOST, CG12_PLN_SL_8BIT);
311 bus_space_write_4(sc->sc_tag, sc->sc_regh,
312 CG12APU_HPAGE, CG12_HPAGE_8BIT);
313 bus_space_write_4(sc->sc_tag, sc->sc_regh,
314 CG12APU_HACCESS, CG12_HACCESS_8BIT);
315 break;
316 case 3:
317 bus_space_write_4(sc->sc_tag, sc->sc_regh,
318 CG12DPU_PLN_RDMSK_HOST, CG12_PLN_RD_24BIT);
319 bus_space_write_4(sc->sc_tag, sc->sc_regh,
320 CG12DPU_PLN_WRMSK_HOST, CG12_PLN_WR_24BIT);
321 bus_space_write_4(sc->sc_tag, sc->sc_regh,
322 CG12DPU_PLN_SL_HOST, CG12_PLN_SL_24BIT);
323 bus_space_write_4(sc->sc_tag, sc->sc_regh,
324 CG12APU_HPAGE, CG12_HPAGE_24BIT);
325 bus_space_write_4(sc->sc_tag, sc->sc_regh,
326 CG12APU_HACCESS, CG12_HACCESS_24BIT);
327 break;
328 case 4:
329 bus_space_write_4(sc->sc_tag, sc->sc_regh,
330 CG12DPU_PLN_RDMSK_HOST, CG12_PLN_RD_WID);
331 bus_space_write_4(sc->sc_tag, sc->sc_regh,
332 CG12DPU_PLN_WRMSK_HOST, CG12_PLN_WR_WID);
333 bus_space_write_4(sc->sc_tag, sc->sc_regh,
334 CG12DPU_PLN_SL_HOST, CG12_PLN_SL_WID);
335 bus_space_write_4(sc->sc_tag, sc->sc_regh,
336 CG12APU_HPAGE, CG12_HPAGE_WID);
337 bus_space_write_4(sc->sc_tag, sc->sc_regh,
338 CG12APU_HACCESS, CG12_HACCESS_WID);
339 break;
340 }
341 }
342
343 static void
cgtwelve_write_wid(struct cgtwelve_softc * sc,int idx,uint8_t wid)344 cgtwelve_write_wid(struct cgtwelve_softc *sc, int idx, uint8_t wid)
345 {
346 bus_space_write_4(sc->sc_tag, sc->sc_regh, CG12_WSC_ADDR, idx << 16);
347 bus_space_write_4(sc->sc_tag, sc->sc_regh, CG12_WSC_DATA,
348 ((uint32_t)wid) << 16);
349 }
350
351 static void
cgtwelve_write_dac(struct cgtwelve_softc * sc,int idx,int r,int g,int b)352 cgtwelve_write_dac(struct cgtwelve_softc *sc, int idx, int r, int g, int b)
353 {
354 uint32_t lo = (idx & 0xff);
355 uint32_t hi = (idx >> 8) & 0xff;
356
357 lo |= lo << 8 | lo << 16;
358 hi |= hi << 8 | hi << 16;
359 bus_space_write_4(sc->sc_tag, sc->sc_regh, CG12DAC_ADDR0, lo);
360 bus_space_write_4(sc->sc_tag, sc->sc_regh, CG12DAC_ADDR1, hi);
361 bus_space_write_4(sc->sc_tag, sc->sc_regh, CG12DAC_DATA,
362 b << 16 | g << 8 | r);
363 }
364
365 static void
cgtwelve_setup(struct cgtwelve_softc * sc,int depth)366 cgtwelve_setup(struct cgtwelve_softc *sc, int depth)
367 {
368 int i, j;
369
370 /* first let's put some stuff into the WID table */
371 cgtwelve_write_wid(sc, 0, CG12_WID_8_BIT);
372 cgtwelve_write_wid(sc, 1, CG12_WID_24_BIT);
373
374 /* a linear ramp for the gamma table */
375 for (i = 0; i < 256; i++)
376 cgtwelve_write_dac(sc, i + 0x100, i, i, i);
377
378 j = 0;
379 /* rasops' ANSI colour map */
380 for (i = 0; i < 256; i++) {
381 cgtwelve_write_dac(sc, i,
382 rasops_cmap[j],
383 rasops_cmap[j + 1],
384 rasops_cmap[j + 2]);
385 j += 3;
386 }
387
388 switch(depth) {
389 case 1:
390 /* setup the console */
391
392 /* first, make the overlay all opaque */
393 cgtwelve_select_ovl(sc, CG12_SEL_ENABLE);
394 memset(sc->sc_fbaddr, 0xff, 0x20000);
395
396 /* now write the right thing into the WID plane */
397 cgtwelve_select_ovl(sc, CG12_SEL_WID);
398 memset(sc->sc_wids, 0, 0x100000);
399
400 /* now clean the plane */
401 cgtwelve_select_ovl(sc, CG12_SEL_OVL);
402 memset(sc->sc_fbaddr, 0, 0x20000);
403 break;
404 case 8:
405 /* setup the 8bit fb */
406 /*
407 * first clean the 8bit fb - for aesthetic reasons do it while
408 * it's still not visible ( we hope... )
409 */
410 cgtwelve_select_ovl(sc, CG12_SEL_8BIT);
411 memset(sc->sc_int, 0x00, 0x100000);
412
413 /* now write the right thing into the WID plane */
414 cgtwelve_select_ovl(sc, CG12_SEL_WID);
415 memset(sc->sc_wids, 0, 0x100000);
416
417 /* hide the overlay */
418 cgtwelve_select_ovl(sc, CG12_SEL_ENABLE);
419 memset(sc->sc_fbaddr, 0, 0x20000);
420
421 /* now clean the plane */
422 cgtwelve_select_ovl(sc, CG12_SEL_OVL);
423 memset(sc->sc_fbaddr, 0, 0x20000);
424
425 /* and make sure we can write the 8bit fb */
426 cgtwelve_select_ovl(sc, CG12_SEL_8BIT);
427 break;
428 case 24:
429 case 32:
430 /* setup the 24bit fb for X */
431 /*
432 * first clean the 24bit fb - for aesthetic reasons do it while
433 * it's still not visible ( we hope... )
434 */
435 cgtwelve_select_ovl(sc, CG12_SEL_24BIT);
436 memset(sc->sc_int, 0x80, 0x400000);
437
438 /* now write the right thing into the WID plane */
439 cgtwelve_select_ovl(sc, CG12_SEL_WID);
440 memset(sc->sc_wids, 1, 0x100000);
441
442 /* hide the overlay */
443 cgtwelve_select_ovl(sc, CG12_SEL_ENABLE);
444 memset(sc->sc_fbaddr, 0, 0x20000);
445
446 /* now clean the plane */
447 cgtwelve_select_ovl(sc, CG12_SEL_OVL);
448 memset(sc->sc_fbaddr, 0, 0x20000);
449
450 /* and make sure we can write the 24bit fb */
451 cgtwelve_select_ovl(sc, CG12_SEL_24BIT);
452 break;
453 }
454 }
455
456 static void
cgtwelve_init_screen(void * cookie,struct vcons_screen * scr,int existing,long * defattr)457 cgtwelve_init_screen(void *cookie, struct vcons_screen *scr,
458 int existing, long *defattr)
459 {
460 struct cgtwelve_softc *sc = cookie;
461 struct rasops_info *ri = &scr->scr_ri;
462
463 #ifdef CG12_COLOR
464 ri->ri_depth = 8;
465 #else
466 ri->ri_depth = 1;
467 #endif
468 ri->ri_width = sc->sc_width;
469 ri->ri_height = sc->sc_height;
470 ri->ri_stride = sc->sc_stride;
471 ri->ri_flg = RI_CENTER;
472
473 if (sc->sc_shadow == NULL) {
474 #ifdef CG12_COLOR
475 ri->ri_bits = sc->sc_int;
476 #else
477 ri->ri_bits = sc->sc_fbaddr;
478 #endif
479 scr->scr_flags |= VCONS_DONT_READ;
480 } else {
481 #ifdef CG12_COLOR
482 ri->ri_hwbits = sc->sc_int;
483 #else
484 ri->ri_hwbits = sc->sc_fbaddr;
485 #endif
486 ri->ri_bits = sc->sc_shadow;
487 }
488
489 rasops_init(ri, 0, 0);
490 #ifdef CG12_COLOR
491 ri->ri_caps = WSSCREEN_REVERSE | WSSCREEN_WSCOLORS;
492 #else
493 ri->ri_caps = WSSCREEN_REVERSE;
494 #endif
495 rasops_reconfig(ri, ri->ri_height / ri->ri_font->fontheight,
496 ri->ri_width / ri->ri_font->fontwidth);
497 }
498
499 static int
cgtwelve_ioctl(void * v,void * vs,u_long cmd,void * data,int flag,struct lwp * l)500 cgtwelve_ioctl(void *v, void *vs, u_long cmd, void *data, int flag,
501 struct lwp *l)
502 {
503 struct vcons_data *vd = v;
504 struct cgtwelve_softc *sc = vd->cookie;
505 struct wsdisplay_fbinfo *wdf;
506 struct vcons_screen *ms = vd->active;
507
508 switch (cmd) {
509 case WSDISPLAYIO_GTYPE:
510 *(u_int *)data = WSDISPLAY_TYPE_SUNCG12;
511 return 0;
512
513 case WSDISPLAYIO_GINFO:
514 wdf = (void *)data;
515 wdf->height = sc->sc_height;
516 wdf->width = sc->sc_width;
517 wdf->depth = 32;
518 wdf->cmsize = 256;
519 return 0;
520
521 case FBIOGVIDEO:
522 case WSDISPLAYIO_GVIDEO:
523 *(int *)data = 1;
524 return 0;
525
526 case WSDISPLAYIO_SVIDEO:
527 case FBIOSVIDEO:
528 /* when we figure out how to do this... */
529 /*cgtwelve_set_video(sc, *(int *)data);*/
530 return 0;
531
532 case WSDISPLAYIO_LINEBYTES:
533 {
534 int *ret = (int *)data;
535 *ret = sc->sc_width << 2;
536 }
537 return 0;
538
539 case WSDISPLAYIO_SMODE:
540 {
541 int new_mode = *(int*)data;
542 if (new_mode != sc->sc_mode)
543 {
544 sc->sc_mode = new_mode;
545 if (new_mode == WSDISPLAYIO_MODE_EMUL)
546 {
547 #ifdef CG12_COLOR
548 cgtwelve_setup(sc, 8);
549 #else
550 cgtwelve_setup(sc, 1);
551 #endif
552 vcons_redraw_screen(ms);
553 } else {
554 cgtwelve_setup(sc, 32);
555 }
556 }
557 }
558 }
559
560 return EPASSTHROUGH;
561 }
562
563 static paddr_t
cgtwelve_mmap(void * v,void * vs,off_t offset,int prot)564 cgtwelve_mmap(void *v, void *vs, off_t offset, int prot)
565 {
566 struct vcons_data *vd = v;
567 struct cgtwelve_softc *sc = vd->cookie;
568
569 /* regular fb mapping at 0 */
570 if ((offset >= 0) && (offset < 0x400000)) {
571 return bus_space_mmap(sc->sc_tag, sc->sc_paddr + CG12_OFF_INTEN,
572 offset, prot, BUS_SPACE_MAP_LINEAR);
573 }
574
575 return -1;
576 }
577