1 /* $NetBSD: voyagerfb.c,v 1.1 2009/08/12 19:28:00 macallan Exp $ */
4 * Copyright (c) 2009 Michael Lorenz
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 * A console driver for Silicon Motion SM502 / Voyager GX graphics controllers
30 * tested on GDIUM only so far
33 #include <sys/cdefs.h>
34 __KERNEL_RCSID(0, "$NetBSD: voyagerfb.c,v 1.1 2009/08/12 19:28:00 macallan Exp $");
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/kernel.h>
39 #include <sys/device.h>
40 #include <sys/malloc.h>
42 #include <sys/kauth.h>
44 #include <uvm/uvm_extern.h>
46 #include <dev/videomode/videomode.h>
48 #include <dev/pci/pcivar.h>
49 #include <dev/pci/pcireg.h>
50 #include <dev/pci/pcidevs.h>
51 #include <dev/pci/pciio.h>
52 #include <dev/ic/sm502reg.h>
54 #include <dev/wscons/wsdisplayvar.h>
55 #include <dev/wscons/wsconsio.h>
56 #include <dev/wsfont/wsfont.h>
57 #include <dev/rasops/rasops.h>
58 #include <dev/wscons/wsdisplay_vconsvar.h>
60 #include <dev/i2c/i2cvar.h>
62 struct voyagerfb_softc
{
65 pci_chipset_tag_t sc_pc
;
68 bus_space_tag_t sc_memt
;
69 bus_space_tag_t sc_iot
;
71 bus_space_handle_t sc_fbh
;
72 bus_space_handle_t sc_regh
;
73 bus_addr_t sc_fb
, sc_reg
;
74 bus_size_t sc_fbsize
, sc_regsize
;
76 int sc_width
, sc_height
, sc_depth
, sc_stride
;
79 struct vcons_screen sc_console_screen
;
80 struct wsscreen_descr sc_defaultscreen_descr
;
81 const struct wsscreen_descr
*sc_screens
[1];
82 struct wsscreen_list sc_screenlist
;
86 u_char sc_cmap_red
[256];
87 u_char sc_cmap_green
[256];
88 u_char sc_cmap_blue
[256];
91 static int voyagerfb_match(device_t
, cfdata_t
, void *);
92 static void voyagerfb_attach(device_t
, device_t
, void *);
94 CFATTACH_DECL_NEW(voyagerfb
, sizeof(struct voyagerfb_softc
),
95 voyagerfb_match
, voyagerfb_attach
, NULL
, NULL
);
97 extern const u_char rasops_cmap
[768];
99 static int voyagerfb_ioctl(void *, void *, u_long
, void *, int,
101 static paddr_t
voyagerfb_mmap(void *, void *, off_t
, int);
102 static void voyagerfb_init_screen(void *, struct vcons_screen
*, int,
105 static int voyagerfb_putcmap(struct voyagerfb_softc
*,
106 struct wsdisplay_cmap
*);
107 static int voyagerfb_getcmap(struct voyagerfb_softc
*,
108 struct wsdisplay_cmap
*);
109 static void voyagerfb_restore_palette(struct voyagerfb_softc
*);
110 static int voyagerfb_putpalreg(struct voyagerfb_softc
*, int, uint8_t,
113 static void voyagerfb_init(struct voyagerfb_softc
*);
115 static void voyagerfb_rectfill(struct voyagerfb_softc
*, int, int, int, int,
117 static void voyagerfb_bitblt(struct voyagerfb_softc
*, int, int, int, int,
120 static void voyagerfb_cursor(void *, int, int, int);
121 static void voyagerfb_putchar(void *, int, int, u_int
, long);
122 static void voyagerfb_copycols(void *, int, int, int, int);
123 static void voyagerfb_erasecols(void *, int, int, int, long);
124 static void voyagerfb_copyrows(void *, int, int, int);
125 static void voyagerfb_eraserows(void *, int, int, long);
127 struct wsdisplay_accessops voyagerfb_accessops
= {
130 NULL
, /* alloc_screen */
131 NULL
, /* free_screen */
132 NULL
, /* show_screen */
133 NULL
, /* load_font */
138 /* wait for FIFO empty so we can feed it another command */
140 voyagerfb_ready(struct voyagerfb_softc
*sc
)
142 do {} while ((bus_space_read_4(sc
->sc_memt
, sc
->sc_regh
,
143 SM502_SYSTEM_CTRL
) & SM502_SYSCTL_FIFO_EMPTY
) == 0);
146 /* wait for the drawing engine to be idle */
148 voyagerfb_wait(struct voyagerfb_softc
*sc
)
150 do {} while ((bus_space_read_4(sc
->sc_memt
, sc
->sc_regh
,
151 SM502_SYSTEM_CTRL
) & SM502_SYSCTL_ENGINE_BUSY
) != 0);
155 voyagerfb_match(device_t parent
, cfdata_t match
, void *aux
)
157 struct pci_attach_args
*pa
= (struct pci_attach_args
*)aux
;
159 if (PCI_CLASS(pa
->pa_class
) != PCI_CLASS_DISPLAY
)
161 if (PCI_VENDOR(pa
->pa_id
) != PCI_VENDOR_SILMOTION
)
164 /* only chip tested on so far - may need a list */
165 if (PCI_PRODUCT(pa
->pa_id
) == PCI_PRODUCT_SILMOTION_SM502
)
171 voyagerfb_attach(device_t parent
, device_t self
, void *aux
)
173 struct voyagerfb_softc
*sc
= device_private(self
);
174 struct pci_attach_args
*pa
= aux
;
175 struct rasops_info
*ri
;
177 struct wsemuldisplaydev_attach_args aa
;
178 prop_dictionary_t dict
;
179 unsigned long defattr
;
184 sc
->sc_pc
= pa
->pa_pc
;
185 sc
->sc_pcitag
= pa
->pa_tag
;
186 sc
->sc_memt
= pa
->pa_memt
;
187 sc
->sc_iot
= pa
->pa_iot
;
190 pci_devinfo(pa
->pa_id
, pa
->pa_class
, 0, devinfo
, sizeof(devinfo
));
191 aprint_normal(": %s\n", devinfo
);
193 dict
= device_properties(self
);
194 prop_dictionary_get_bool(dict
, "is_console", &is_console
);
196 if (pci_mapreg_map(pa
, 0x10, PCI_MAPREG_TYPE_MEM
,
197 BUS_SPACE_MAP_LINEAR
,
198 &sc
->sc_memt
, &sc
->sc_fbh
, &sc
->sc_fb
, &sc
->sc_fbsize
)) {
199 aprint_error("%s: failed to map the frame buffer.\n",
200 device_xname(sc
->sc_dev
));
202 sc
->sc_fbaddr
= bus_space_vaddr(sc
->sc_memt
, sc
->sc_fbh
);
204 if (pci_mapreg_map(pa
, 0x14, PCI_MAPREG_TYPE_MEM
, 0,
205 &sc
->sc_memt
, &sc
->sc_regh
, &sc
->sc_reg
, &sc
->sc_regsize
)) {
206 aprint_error("%s: failed to map registers.\n",
207 device_xname(sc
->sc_dev
));
209 sc
->sc_dataport
= bus_space_vaddr(sc
->sc_memt
, sc
->sc_regh
);
210 sc
->sc_dataport
+= SM502_DATAPORT
;
212 reg
= bus_space_read_8(sc
->sc_memt
, sc
->sc_regh
, SM502_PANEL_DISP_CRTL
);
213 switch (reg
& SM502_PDC_DEPTH_MASK
) {
217 case SM502_PDC_16BIT
:
220 case SM502_PDC_32BIT
:
224 panic("%s: unsupported depth", device_xname(self
));
226 sc
->sc_stride
= (bus_space_read_4(sc
->sc_memt
, sc
->sc_regh
,
227 SM502_PANEL_FB_OFFSET
) & SM502_FBA_WIN_STRIDE_MASK
) >> 16;
228 sc
->sc_width
= (bus_space_read_4(sc
->sc_memt
, sc
->sc_regh
,
229 SM502_PANEL_FB_WIDTH
) & SM502_FBW_WIN_WIDTH_MASK
) >> 16;
230 sc
->sc_height
= (bus_space_read_4(sc
->sc_memt
, sc
->sc_regh
,
231 SM502_PANEL_FB_HEIGHT
) & SM502_FBH_WIN_HEIGHT_MASK
) >> 16;
233 printf("%s: %d x %d, %d bit, stride %d\n", device_xname(self
),
234 sc
->sc_width
, sc
->sc_height
, sc
->sc_depth
, sc
->sc_stride
);
236 * XXX yeah, casting the fb address to uint32_t is formally wrong
237 * but as far as I know there are no SM502 with 64bit BARs
239 aprint_normal("%s: %d MB aperture at 0x%08x\n", device_xname(self
),
240 (int)(sc
->sc_fbsize
>> 20), (uint32_t)sc
->sc_fb
);
242 sc
->sc_defaultscreen_descr
= (struct wsscreen_descr
){
247 WSSCREEN_WSCOLORS
| WSSCREEN_HILIT
,
250 sc
->sc_screens
[0] = &sc
->sc_defaultscreen_descr
;
251 sc
->sc_screenlist
= (struct wsscreen_list
){1, sc
->sc_screens
};
252 sc
->sc_mode
= WSDISPLAYIO_MODE_EMUL
;
255 vcons_init(&sc
->vd
, sc
, &sc
->sc_defaultscreen_descr
,
256 &voyagerfb_accessops
);
257 sc
->vd
.init_screen
= voyagerfb_init_screen
;
259 /* init engine here */
262 ri
= &sc
->sc_console_screen
.scr_ri
;
265 vcons_init_screen(&sc
->vd
, &sc
->sc_console_screen
, 1,
267 sc
->sc_console_screen
.scr_flags
|= VCONS_SCREEN_IS_STATIC
;
269 sc
->sc_defaultscreen_descr
.textops
= &ri
->ri_ops
;
270 sc
->sc_defaultscreen_descr
.capabilities
= ri
->ri_caps
;
271 sc
->sc_defaultscreen_descr
.nrows
= ri
->ri_rows
;
272 sc
->sc_defaultscreen_descr
.ncols
= ri
->ri_cols
;
273 wsdisplay_cnattach(&sc
->sc_defaultscreen_descr
, ri
, 0, 0,
277 * since we're not the console we can postpone the rest
278 * until someone actually allocates a screen for us
280 (*ri
->ri_ops
.allocattr
)(ri
, 0, 0, 0, &defattr
);
284 if (sc
->sc_depth
<= 8) {
285 for (i
= 0; i
< (1 << sc
->sc_depth
); i
++) {
287 sc
->sc_cmap_red
[i
] = rasops_cmap
[j
];
288 sc
->sc_cmap_green
[i
] = rasops_cmap
[j
+ 1];
289 sc
->sc_cmap_blue
[i
] = rasops_cmap
[j
+ 2];
290 voyagerfb_putpalreg(sc
, i
, rasops_cmap
[j
],
291 rasops_cmap
[j
+ 1], rasops_cmap
[j
+ 2]);
296 voyagerfb_rectfill(sc
, 0, 0, sc
->sc_width
, sc
->sc_height
,
297 ri
->ri_devcmap
[(defattr
>> 16) & 0xff]);
300 vcons_replay_msgbuf(&sc
->sc_console_screen
);
302 aa
.console
= is_console
;
303 aa
.scrdata
= &sc
->sc_screenlist
;
304 aa
.accessops
= &voyagerfb_accessops
;
305 aa
.accesscookie
= &sc
->vd
;
307 config_found(sc
->sc_dev
, &aa
, wsemuldisplaydevprint
);
311 voyagerfb_ioctl(void *v
, void *vs
, u_long cmd
, void *data
, int flag
,
314 struct vcons_data
*vd
= v
;
315 struct voyagerfb_softc
*sc
= vd
->cookie
;
316 struct wsdisplay_fbinfo
*wdf
;
317 struct vcons_screen
*ms
= vd
->active
;
321 case WSDISPLAYIO_GTYPE
:
322 *(u_int
*)data
= WSDISPLAY_TYPE_PCIMISC
;
325 /* PCI config read/write passthrough. */
326 case PCI_IOC_CFGREAD
:
327 case PCI_IOC_CFGWRITE
:
328 return (pci_devioctl(sc
->sc_pc
, sc
->sc_pcitag
,
329 cmd
, data
, flag
, l
));
331 case WSDISPLAYIO_GINFO
:
335 wdf
->height
= ms
->scr_ri
.ri_height
;
336 wdf
->width
= ms
->scr_ri
.ri_width
;
337 wdf
->depth
= ms
->scr_ri
.ri_depth
;
341 case WSDISPLAYIO_GETCMAP
:
342 return voyagerfb_getcmap(sc
,
343 (struct wsdisplay_cmap
*)data
);
345 case WSDISPLAYIO_PUTCMAP
:
346 return voyagerfb_putcmap(sc
,
347 (struct wsdisplay_cmap
*)data
);
349 case WSDISPLAYIO_LINEBYTES
:
350 *(u_int
*)data
= sc
->sc_stride
;
353 case WSDISPLAYIO_SMODE
:
355 int new_mode
= *(int*)data
;
357 if (new_mode
!= sc
->sc_mode
) {
358 sc
->sc_mode
= new_mode
;
359 if(new_mode
== WSDISPLAYIO_MODE_EMUL
) {
360 voyagerfb_restore_palette(sc
);
361 vcons_redraw_screen(ms
);
371 voyagerfb_mmap(void *v
, void *vs
, off_t offset
, int prot
)
373 struct vcons_data
*vd
= v
;
374 struct voyagerfb_softc
*sc
= vd
->cookie
;
377 /* 'regular' framebuffer mmap()ing */
378 if (offset
< sc
->sc_fbsize
) {
379 pa
= bus_space_mmap(sc
->sc_memt
, sc
->sc_fb
+ offset
, 0, prot
,
380 BUS_SPACE_MAP_LINEAR
);
385 * restrict all other mappings to processes with superuser privileges
386 * or the kernel itself
388 if (kauth_authorize_generic(kauth_cred_get(), KAUTH_GENERIC_ISSUSER
,
390 aprint_normal("%s: mmap() rejected.\n",
391 device_xname(sc
->sc_dev
));
395 if ((offset
>= sc
->sc_fb
) && (offset
< (sc
->sc_fb
+ sc
->sc_fbsize
))) {
396 pa
= bus_space_mmap(sc
->sc_memt
, offset
, 0, prot
,
397 BUS_SPACE_MAP_LINEAR
);
401 if ((offset
>= sc
->sc_reg
) &&
402 (offset
< (sc
->sc_reg
+ sc
->sc_regsize
))) {
403 pa
= bus_space_mmap(sc
->sc_memt
, offset
, 0, prot
,
404 BUS_SPACE_MAP_LINEAR
);
412 voyagerfb_init_screen(void *cookie
, struct vcons_screen
*scr
,
413 int existing
, long *defattr
)
415 struct voyagerfb_softc
*sc
= cookie
;
416 struct rasops_info
*ri
= &scr
->scr_ri
;
418 ri
->ri_depth
= sc
->sc_depth
;
419 ri
->ri_width
= sc
->sc_width
;
420 ri
->ri_height
= sc
->sc_height
;
421 ri
->ri_stride
= sc
->sc_stride
;
422 ri
->ri_flg
= RI_CENTER
| RI_FULLCLEAR
;
424 ri
->ri_bits
= (char *)sc
->sc_fbaddr
;
427 ri
->ri_flg
|= RI_CLEAR
;
430 rasops_init(ri
, sc
->sc_height
/ 8, sc
->sc_width
/ 8);
431 ri
->ri_caps
= WSSCREEN_WSCOLORS
;
433 rasops_reconfig(ri
, sc
->sc_height
/ ri
->ri_font
->fontheight
,
434 sc
->sc_width
/ ri
->ri_font
->fontwidth
);
437 ri
->ri_ops
.copyrows
= voyagerfb_copyrows
;
438 ri
->ri_ops
.copycols
= voyagerfb_copycols
;
439 ri
->ri_ops
.eraserows
= voyagerfb_eraserows
;
440 ri
->ri_ops
.erasecols
= voyagerfb_erasecols
;
441 ri
->ri_ops
.cursor
= voyagerfb_cursor
;
442 ri
->ri_ops
.putchar
= voyagerfb_putchar
;
446 voyagerfb_putcmap(struct voyagerfb_softc
*sc
, struct wsdisplay_cmap
*cm
)
449 u_int index
= cm
->index
;
450 u_int count
= cm
->count
;
452 u_char rbuf
[256], gbuf
[256], bbuf
[256];
454 #ifdef VOYAGERFB_DEBUG
455 aprint_debug("putcmap: %d %d\n",index
, count
);
457 if (cm
->index
>= 256 || cm
->count
> 256 ||
458 (cm
->index
+ cm
->count
) > 256)
460 error
= copyin(cm
->red
, &rbuf
[index
], count
);
463 error
= copyin(cm
->green
, &gbuf
[index
], count
);
466 error
= copyin(cm
->blue
, &bbuf
[index
], count
);
470 memcpy(&sc
->sc_cmap_red
[index
], &rbuf
[index
], count
);
471 memcpy(&sc
->sc_cmap_green
[index
], &gbuf
[index
], count
);
472 memcpy(&sc
->sc_cmap_blue
[index
], &bbuf
[index
], count
);
474 r
= &sc
->sc_cmap_red
[index
];
475 g
= &sc
->sc_cmap_green
[index
];
476 b
= &sc
->sc_cmap_blue
[index
];
478 for (i
= 0; i
< count
; i
++) {
479 voyagerfb_putpalreg(sc
, index
, *r
, *g
, *b
);
487 voyagerfb_getcmap(struct voyagerfb_softc
*sc
, struct wsdisplay_cmap
*cm
)
489 u_int index
= cm
->index
;
490 u_int count
= cm
->count
;
493 if (index
>= 255 || count
> 256 || index
+ count
> 256)
496 error
= copyout(&sc
->sc_cmap_red
[index
], cm
->red
, count
);
499 error
= copyout(&sc
->sc_cmap_green
[index
], cm
->green
, count
);
502 error
= copyout(&sc
->sc_cmap_blue
[index
], cm
->blue
, count
);
510 voyagerfb_restore_palette(struct voyagerfb_softc
*sc
)
514 for (i
= 0; i
< (1 << sc
->sc_depth
); i
++) {
515 voyagerfb_putpalreg(sc
, i
, sc
->sc_cmap_red
[i
],
516 sc
->sc_cmap_green
[i
], sc
->sc_cmap_blue
[i
]);
521 voyagerfb_putpalreg(struct voyagerfb_softc
*sc
, int idx
, uint8_t r
,
522 uint8_t g
, uint8_t b
)
526 reg
= (r
<< 16) | (g
<< 8) | b
;
527 /* XXX we should probably write the CRT palette too */
528 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
,
529 SM502_PALETTE_PANEL
+ (idx
<< 2), reg
);
534 voyagerfb_init(struct voyagerfb_softc
*sc
)
538 /* disable colour compare */
539 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, SM502_COLOR_COMP_MASK
, 0);
540 /* allow writes to all planes */
541 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, SM502_PLANEMASK
,
543 /* disable clipping */
544 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, SM502_CLIP_TOP_LEFT
, 0);
545 /* source and destination in local memory, no offset */
546 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, SM502_SRC_BASE
, 0);
547 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, SM502_DST_BASE
, 0);
548 /* pitch is screen stride */
549 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, SM502_PITCH
,
550 sc
->sc_width
| (sc
->sc_width
<< 16));
551 /* window is screen width */
552 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, SM502_WINDOW_WIDTH
,
553 sc
->sc_width
| (sc
->sc_width
<< 16));
554 switch (sc
->sc_depth
) {
556 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
,
557 SM502_STRETCH
, SM502_STRETCH_8BIT
);
560 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
,
561 SM502_STRETCH
, SM502_STRETCH_16BIT
);
565 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
,
566 SM502_STRETCH
, SM502_STRETCH_32BIT
);
572 voyagerfb_rectfill(struct voyagerfb_softc
*sc
, int x
, int y
, int wi
, int he
,
577 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, SM502_CONTROL
,
579 SM502_CTRL_USE_ROP2
|
580 SM502_CTRL_CMD_RECTFILL
|
581 SM502_CTRL_QUICKSTART_E
);
582 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, SM502_FOREGROUND
,
584 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, SM502_DST
,
586 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, SM502_DIMENSION
,
591 voyagerfb_bitblt(struct voyagerfb_softc
*sc
, int xs
, int ys
, int xd
, int yd
,
592 int wi
, int he
, int rop
)
596 cmd
= (rop
& 0xf) | SM502_CTRL_USE_ROP2
| SM502_CTRL_CMD_BITBLT
|
597 SM502_CTRL_QUICKSTART_E
;
604 cmd
|= SM502_CTRL_R_TO_L
;
609 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, SM502_CONTROL
, cmd
);
610 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, SM502_SRC
,
612 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, SM502_DST
,
614 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
, SM502_DIMENSION
,
619 voyagerfb_cursor(void *cookie
, int on
, int row
, int col
)
621 struct rasops_info
*ri
= cookie
;
622 struct vcons_screen
*scr
= ri
->ri_hw
;
623 struct voyagerfb_softc
*sc
= scr
->scr_cookie
;
626 wi
= ri
->ri_font
->fontwidth
;
627 he
= ri
->ri_font
->fontheight
;
629 if (sc
->sc_mode
== WSDISPLAYIO_MODE_EMUL
) {
630 x
= ri
->ri_ccol
* wi
+ ri
->ri_xorigin
;
631 y
= ri
->ri_crow
* he
+ ri
->ri_yorigin
;
632 if (ri
->ri_flg
& RI_CURSOR
) {
633 voyagerfb_bitblt(sc
, x
, y
, x
, y
, wi
, he
, ROP_INVERT
);
634 ri
->ri_flg
&= ~RI_CURSOR
;
639 x
= ri
->ri_ccol
* wi
+ ri
->ri_xorigin
;
640 y
= ri
->ri_crow
* he
+ ri
->ri_yorigin
;
641 voyagerfb_bitblt(sc
, x
, y
, x
, y
, wi
, he
, ROP_INVERT
);
642 ri
->ri_flg
|= RI_CURSOR
;
645 scr
->scr_ri
.ri_crow
= row
;
646 scr
->scr_ri
.ri_ccol
= col
;
647 scr
->scr_ri
.ri_flg
&= ~RI_CURSOR
;
653 voyagerfb_feed8(struct voyagerfb_softc
*sc
, uint8_t *data
, int len
)
655 uint32_t *port
= (uint32_t *)sc
->sc_dataport
;
658 for (i
= 0; i
< ((len
+ 3) & 0xfffc); i
++) {
665 voyagerfb_feed16(struct voyagerfb_softc
*sc
, uint16_t *data
, int len
)
667 uint32_t *port
= (uint32_t *)sc
->sc_dataport
;
671 for (i
= 0; i
< ((len
+ 1) & 0xfffe); i
++) {
679 voyagerfb_putchar(void *cookie
, int row
, int col
, u_int c
, long attr
)
681 struct rasops_info
*ri
= cookie
;
682 struct vcons_screen
*scr
= ri
->ri_hw
;
683 struct voyagerfb_softc
*sc
= scr
->scr_cookie
;
686 if (sc
->sc_mode
== WSDISPLAYIO_MODE_EMUL
) {
690 wi
= ri
->ri_font
->fontwidth
;
691 he
= ri
->ri_font
->fontheight
;
693 if (!CHAR_IN_FONT(c
, ri
->ri_font
))
695 bg
= ri
->ri_devcmap
[(attr
>> 16) & 0x0f];
696 fg
= ri
->ri_devcmap
[(attr
>> 24) & 0x0f];
697 x
= ri
->ri_xorigin
+ col
* wi
;
698 y
= ri
->ri_yorigin
+ row
* he
;
700 voyagerfb_rectfill(sc
, x
, y
, wi
, he
, bg
);
702 uc
= c
- ri
->ri_font
->firstchar
;
703 data
= (uint8_t *)ri
->ri_font
->data
+ uc
*
706 SM502_CTRL_USE_ROP2
|
707 SM502_CTRL_CMD_HOSTWRT
|
708 SM502_CTRL_HOSTBLT_MONO
|
709 SM502_CTRL_QUICKSTART_E
|
710 SM502_CTRL_MONO_PACK_32BIT
;
712 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
,
714 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
,
715 SM502_FOREGROUND
, fg
);
716 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
,
717 SM502_BACKGROUND
, bg
);
718 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
,
720 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
,
721 SM502_DST
, (x
<< 16) | y
);
722 bus_space_write_4(sc
->sc_memt
, sc
->sc_regh
,
723 SM502_DIMENSION
, (wi
<< 16) | he
);
724 /* now feed the data, padded to 32bit */
725 switch (ri
->ri_font
->stride
) {
727 voyagerfb_feed8(sc
, data
, ri
->ri_fontscale
);
730 voyagerfb_feed16(sc
, (uint16_t *)data
,
740 voyagerfb_copycols(void *cookie
, int row
, int srccol
, int dstcol
, int ncols
)
742 struct rasops_info
*ri
= cookie
;
743 struct vcons_screen
*scr
= ri
->ri_hw
;
744 struct voyagerfb_softc
*sc
= scr
->scr_cookie
;
745 int32_t xs
, xd
, y
, width
, height
;
747 if ((sc
->sc_locked
== 0) && (sc
->sc_mode
== WSDISPLAYIO_MODE_EMUL
)) {
748 xs
= ri
->ri_xorigin
+ ri
->ri_font
->fontwidth
* srccol
;
749 xd
= ri
->ri_xorigin
+ ri
->ri_font
->fontwidth
* dstcol
;
750 y
= ri
->ri_yorigin
+ ri
->ri_font
->fontheight
* row
;
751 width
= ri
->ri_font
->fontwidth
* ncols
;
752 height
= ri
->ri_font
->fontheight
;
753 voyagerfb_bitblt(sc
, xs
, y
, xd
, y
, width
, height
, ROP_COPY
);
758 voyagerfb_erasecols(void *cookie
, int row
, int startcol
, int ncols
,
761 struct rasops_info
*ri
= cookie
;
762 struct vcons_screen
*scr
= ri
->ri_hw
;
763 struct voyagerfb_softc
*sc
= scr
->scr_cookie
;
764 int32_t x
, y
, width
, height
, fg
, bg
, ul
;
766 if ((sc
->sc_locked
== 0) && (sc
->sc_mode
== WSDISPLAYIO_MODE_EMUL
)) {
767 x
= ri
->ri_xorigin
+ ri
->ri_font
->fontwidth
* startcol
;
768 y
= ri
->ri_yorigin
+ ri
->ri_font
->fontheight
* row
;
769 width
= ri
->ri_font
->fontwidth
* ncols
;
770 height
= ri
->ri_font
->fontheight
;
771 rasops_unpack_attr(fillattr
, &fg
, &bg
, &ul
);
773 voyagerfb_rectfill(sc
, x
, y
, width
, height
, ri
->ri_devcmap
[bg
]);
778 voyagerfb_copyrows(void *cookie
, int srcrow
, int dstrow
, int nrows
)
780 struct rasops_info
*ri
= cookie
;
781 struct vcons_screen
*scr
= ri
->ri_hw
;
782 struct voyagerfb_softc
*sc
= scr
->scr_cookie
;
783 int32_t x
, ys
, yd
, width
, height
;
786 if ((sc
->sc_locked
== 0) && (sc
->sc_mode
== WSDISPLAYIO_MODE_EMUL
)) {
788 ys
= ri
->ri_yorigin
+ ri
->ri_font
->fontheight
* srcrow
;
789 yd
= ri
->ri_yorigin
+ ri
->ri_font
->fontheight
* dstrow
;
790 width
= ri
->ri_emuwidth
;
791 height
= ri
->ri_font
->fontheight
* nrows
;
792 if ((nrows
> 1) && (dstrow
> srcrow
)) {
794 * the blitter can't do bottom-up copies so we have
795 * to copy line by line here
796 * should probably use a command sequence
798 for (i
= 0; i
< nrows
; i
++) {
799 voyagerfb_bitblt(sc
, x
, ys
, x
, yd
, width
,
800 ri
->ri_font
->fontheight
, ROP_COPY
);
801 ys
+= ri
->ri_font
->fontheight
;
802 yd
+= ri
->ri_font
->fontheight
;
805 voyagerfb_bitblt(sc
, x
, ys
, x
, yd
, width
, height
,
811 voyagerfb_eraserows(void *cookie
, int row
, int nrows
, long fillattr
)
813 struct rasops_info
*ri
= cookie
;
814 struct vcons_screen
*scr
= ri
->ri_hw
;
815 struct voyagerfb_softc
*sc
= scr
->scr_cookie
;
816 int32_t x
, y
, width
, height
, fg
, bg
, ul
;
818 if ((sc
->sc_locked
== 0) && (sc
->sc_mode
== WSDISPLAYIO_MODE_EMUL
)) {
820 y
= ri
->ri_yorigin
+ ri
->ri_font
->fontheight
* row
;
821 width
= ri
->ri_emuwidth
;
822 height
= ri
->ri_font
->fontheight
* nrows
;
823 rasops_unpack_attr(fillattr
, &fg
, &bg
, &ul
);
825 voyagerfb_rectfill(sc
, x
, y
, width
, height
, ri
->ri_devcmap
[bg
]);